@@ -133,6 +133,91 @@ void extract_module_python(const ASR::TranslationUnit_t &m,
133
133
}
134
134
}
135
135
136
+ void update_call_args (Allocator &al, SymbolTable *current_scope, bool implicit_interface) {
137
+ /*
138
+ Iterate over body of program, check if there are any subroutine calls if yes, iterate over its args
139
+ and update the args if they are equal to the old symbol
140
+ For example:
141
+ function func(f)
142
+ double precision c
143
+ call sub2(c)
144
+ print *, c(d)
145
+ end function
146
+ This function updates `sub2` to use the new symbol `c` that is now a function, not a variable.
147
+ Along with this, it also updates the args of `sub2` to use the new symbol `c` instead of the old one.
148
+ */
149
+ class UpdateArgsVisitor : public PassUtils ::PassVisitor<UpdateArgsVisitor>
150
+ {
151
+ public:
152
+ SymbolTable* scope = current_scope;
153
+ UpdateArgsVisitor (Allocator &al) : PassVisitor(al, nullptr ) {}
154
+
155
+ ASR::symbol_t * fetch_sym (ASR::symbol_t * arg_sym_underlying) {
156
+ ASR::symbol_t * sym = nullptr ;
157
+ if (ASR::is_a<ASR::Variable_t>(*arg_sym_underlying)) {
158
+ ASR::Variable_t* arg_variable = ASR::down_cast<ASR::Variable_t>(arg_sym_underlying);
159
+ std::string arg_variable_name = std::string (arg_variable->m_name );
160
+ sym = arg_variable->m_parent_symtab ->get_symbol (arg_variable_name);
161
+ } else if (ASR::is_a<ASR::Function_t>(*arg_sym_underlying)) {
162
+ ASR::Function_t* arg_function = ASR::down_cast<ASR::Function_t>(arg_sym_underlying);
163
+ std::string arg_function_name = std::string (arg_function->m_name );
164
+ sym = arg_function->m_symtab ->parent ->get_symbol (arg_function_name);
165
+ }
166
+ return sym;
167
+ }
168
+
169
+ void visit_SubroutineCall (const ASR::SubroutineCall_t& x) {
170
+ ASR::SubroutineCall_t* subrout_call = (ASR::SubroutineCall_t*)(&x);
171
+ for (size_t j = 0 ; j < subrout_call->n_args ; j++) {
172
+ ASR::call_arg_t arg = subrout_call->m_args [j];
173
+ ASR::expr_t * arg_expr = arg.m_value ;
174
+ if (ASR::is_a<ASR::Var_t>(*arg_expr)) {
175
+ ASR::Var_t* arg_var = ASR::down_cast<ASR::Var_t>(arg_expr);
176
+ ASR::symbol_t * arg_sym = arg_var->m_v ;
177
+ ASR::symbol_t * arg_sym_underlying = ASRUtils::symbol_get_past_external (arg_sym);
178
+ ASR::symbol_t * sym = fetch_sym (arg_sym_underlying);
179
+ if (sym != arg_sym) {
180
+ subrout_call->m_args [j].m_value = ASRUtils::EXPR (ASR::make_Var_t (al, arg_expr->base .loc , sym));
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ void visit_Function (const ASR::Function_t& x) {
187
+ ASR::Function_t* func = (ASR::Function_t*)(&x);
188
+ for (size_t i = 0 ; i < func->n_args ; i++) {
189
+ ASR::expr_t * arg_expr = func->m_args [i];
190
+ if (ASR::is_a<ASR::Var_t>(*arg_expr)) {
191
+ ASR::Var_t* arg_var = ASR::down_cast<ASR::Var_t>(arg_expr);
192
+ ASR::symbol_t * arg_sym = arg_var->m_v ;
193
+ ASR::symbol_t * arg_sym_underlying = ASRUtils::symbol_get_past_external (arg_sym);
194
+ ASR::symbol_t * sym = fetch_sym (arg_sym_underlying);
195
+ if (sym != arg_sym) {
196
+ func->m_args [i] = ASRUtils::EXPR (ASR::make_Var_t (al, arg_expr->base .loc , sym));
197
+ }
198
+ }
199
+ }
200
+ scope = func->m_symtab ;
201
+ for (auto &it: scope->get_scope ()) {
202
+ visit_symbol (*it.second );
203
+ }
204
+ scope = func->m_symtab ;
205
+ for (size_t i = 0 ; i < func->n_body ; i++) {
206
+ visit_stmt (*func->m_body [i]);
207
+ }
208
+ scope = func->m_symtab ;
209
+ }
210
+ };
211
+
212
+ if (implicit_interface) {
213
+ UpdateArgsVisitor v (al);
214
+ SymbolTable *tu_symtab = ASRUtils::get_tu_symtab (current_scope);
215
+ ASR::asr_t * asr_ = tu_symtab->asr_owner ;
216
+ ASR::TranslationUnit_t* tu = ASR::down_cast2<ASR::TranslationUnit_t>(asr_);
217
+ v.visit_TranslationUnit (*tu);
218
+ }
219
+ }
220
+
136
221
ASR::Module_t* extract_module (const ASR::TranslationUnit_t &m) {
137
222
LCOMPILERS_ASSERT (m.m_global_scope ->get_scope ().size ()== 1 );
138
223
for (auto &a : m.m_global_scope ->get_scope ()) {
@@ -368,7 +453,7 @@ ASR::asr_t* getStructInstanceMember_t(Allocator& al, const Location& loc,
368
453
}
369
454
std::string mangled_name = current_scope->get_unique_name (
370
455
std::string (module_name) + " _" +
371
- std::string (der_type_name));
456
+ std::string (der_type_name), false );
372
457
char * mangled_name_char = s2c (al, mangled_name);
373
458
if ( current_scope->get_symbol (mangled_name) == nullptr ) {
374
459
bool make_new_ext_sym = true ;
@@ -789,7 +874,7 @@ void process_overloaded_assignment_function(ASR::symbol_t* proc, ASR::expr_t* ta
789
874
ASRUtils::insert_module_dependency (a_name, al, current_module_dependencies);
790
875
ASRUtils::set_absent_optional_arguments_to_null (a_args, subrout, al);
791
876
asr = ASRUtils::make_SubroutineCall_t_util (al, loc, a_name, sym,
792
- a_args.p , 2 , nullptr );
877
+ a_args.p , 2 , nullptr , nullptr , false );
793
878
}
794
879
}
795
880
}
@@ -1129,7 +1214,7 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval(
1129
1214
}
1130
1215
return ASRUtils::make_SubroutineCall_t_util (al, loc, final_sym,
1131
1216
v, args.p , args.size (),
1132
- nullptr );
1217
+ nullptr , nullptr , false );
1133
1218
} else {
1134
1219
if ( func ) {
1135
1220
ASRUtils::set_absent_optional_arguments_to_null (args, func, al);
0 commit comments