diff --git a/PScope.h b/PScope.h index aa0eddf84..21f751601 100644 --- a/PScope.h +++ b/PScope.h @@ -73,6 +73,12 @@ class LexicalScope { // explicit imports (IEEE 1800-2012 26.3). std::setpotential_imports; + // A task or function call may reference a task or function defined + // later in the scope. So here we stash the potential imports for + // task and function calls. They will be added to the explicit + // imports if we don't find a local definition. + std::mappossible_imports; + struct range_t { // True if this is an exclude bool exclude_flag; diff --git a/pform.cc b/pform.cc index 5f3f342fa..3b9259b5b 100644 --- a/pform.cc +++ b/pform.cc @@ -407,8 +407,17 @@ LexicalScope* pform_peek_scope(void) void pform_pop_scope() { - assert(lexical_scope); - lexical_scope = lexical_scope->parent_scope(); + LexicalScope*scope = lexical_scope; + assert(scope); + + map::const_iterator cur; + for (cur = scope->possible_imports.begin(); cur != scope->possible_imports.end(); ++cur) { + if (scope->local_symbols.find(cur->first) == scope->local_symbols.end()) + scope->explicit_imports[cur->first] = cur->second; + } + scope->possible_imports.clear(); + + lexical_scope = scope->parent_scope(); assert(lexical_scope); } @@ -464,7 +473,7 @@ static void add_local_symbol(LexicalScope*scope, perm_string name, PNamedItem*it } static PPackage*find_potential_import(const struct vlltype&loc, LexicalScope*scope, - perm_string name, bool make_explicit) + perm_string name, bool tf_call, bool make_explicit) { assert(scope); @@ -486,15 +495,19 @@ static PPackage*find_potential_import(const struct vlltype&loc, LexicalScope*sco error_count += 1; } else { found_pkg = search_pkg; - if (make_explicit) - scope->explicit_imports[name] = found_pkg; + if (make_explicit) { + if (tf_call) + scope->possible_imports[name] = found_pkg; + else + scope->explicit_imports[name] = found_pkg; + } } } } return found_pkg; } -static void check_potential_imports(const struct vlltype&loc, perm_string name) +static void check_potential_imports(const struct vlltype&loc, perm_string name, bool tf_call) { LexicalScope*scope = lexical_scope; while (scope) { @@ -502,7 +515,7 @@ static void check_potential_imports(const struct vlltype&loc, perm_string name) return; if (scope->explicit_imports.find(name) != scope->explicit_imports.end()) return; - if (find_potential_import(loc, scope, name, true)) + if (find_potential_import(loc, scope, name, tf_call, true)) return; scope = scope->parent_scope(); @@ -723,7 +736,7 @@ PBlock* pform_push_block_scope(const struct vlltype&loc, char*name, PEIdent* pform_new_ident(const struct vlltype&loc, const pform_name_t&name) { if (gn_system_verilog() && name.size() == 1) - check_potential_imports(loc, name.back().name); + check_potential_imports(loc, name.back().name, false); return new PEIdent(name); } @@ -732,7 +745,7 @@ PTrigger* pform_new_trigger(const struct vlltype&loc, PPackage*pkg, const pform_name_t&name) { if (gn_system_verilog() && pkg == 0 && name.size() == 1) - check_potential_imports(loc, name.back().name); + check_potential_imports(loc, name.back().name, false); PTrigger*tmp = new PTrigger(pkg, name); FILE_NAME(tmp, loc); @@ -862,7 +875,7 @@ void pform_set_typedef(perm_string name, data_type_t*data_type, std::listtypedefs.end()) return cur->second; - PPackage*pkg = find_potential_import(loc, cur_scope, name, false); + PPackage*pkg = find_potential_import(loc, cur_scope, name, false, false); if (pkg) { cur = pkg->typedefs.find(name); if (cur != cur_scope->typedefs.end()) @@ -934,7 +947,7 @@ PECallFunction* pform_make_call_function(const struct vlltype&loc, const list&parms) { if (gn_system_verilog() && name.size() == 1) - check_potential_imports(loc, name.back().name); + check_potential_imports(loc, name.back().name, true); PECallFunction*tmp = new PECallFunction(name, parms); FILE_NAME(tmp, loc); @@ -946,7 +959,7 @@ PCallTask* pform_make_call_task(const struct vlltype&loc, const list&parms) { if (gn_system_verilog() && name.size() == 1) - check_potential_imports(loc, name.back().name); + check_potential_imports(loc, name.back().name, true); PCallTask*tmp = new PCallTask(name, parms); FILE_NAME(tmp, loc);