|
6 | 6 | import api.errmsg |
7 | 7 | from api.errmsg import warning |
8 | 8 | import api.check as chk |
9 | | -from api.constants import TYPE, SCOPE |
| 9 | +from api.constants import TYPE, SCOPE, CLASS |
10 | 10 | import api.global_ as gl |
11 | 11 | import symbols |
12 | 12 | import types |
@@ -128,6 +128,7 @@ def visit_FUNCCALL(self, node): |
128 | 128 |
|
129 | 129 | def visit_CALL(self, node): |
130 | 130 | node.args = (yield self.generic_visit(node.args)) # Avoid infinite recursion not visiting node.entry |
| 131 | + self._check_if_any_arg_is_an_array_and_needs_lbound_or_ubound(node.entry.params, node.args) |
131 | 132 | yield node |
132 | 133 |
|
133 | 134 | def visit_FUNCDECL(self, node): |
@@ -251,3 +252,25 @@ def generic_visit(node): |
251 | 252 | for i in range(len(node.children)): |
252 | 253 | node.children[i] = (yield ToVisit(node.children[i])) |
253 | 254 | yield node |
| 255 | + |
| 256 | + def _check_if_any_arg_is_an_array_and_needs_lbound_or_ubound(self, params: symbols.PARAMLIST, |
| 257 | + args: symbols.ARGLIST): |
| 258 | + """ Given a list of params and a list of args, traverse them to check if any arg is a byRef array parameter, |
| 259 | + and if so, whether it's use_lbound or use_ubound flag is updated to True and if it's a local var. If so, it's |
| 260 | + offset size has changed and must be reevaluated! |
| 261 | + """ |
| 262 | + for arg, param in zip(args, params): |
| 263 | + if not param.byref or param.class_ != CLASS.array: |
| 264 | + continue |
| 265 | + |
| 266 | + if arg.value.lbound_used and arg.value.ubound_used: |
| 267 | + continue |
| 268 | + |
| 269 | + self._update_bound_status(arg.value, param) |
| 270 | + |
| 271 | + def _update_bound_status(self, arg: symbols.VARARRAY, param: symbols.PARAMDECL): |
| 272 | + arg.lbound_used = arg.lbound_used or param.lbound_used |
| 273 | + arg.ubound_used = arg.ubound_used or param.ubound_used |
| 274 | + |
| 275 | + if arg.lbound_used and arg.ubound_used: |
| 276 | + return |
0 commit comments