From c1c4c2831300d7d269bd4133679317190b67dc8b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 2 Jun 2023 18:58:42 -0700 Subject: [PATCH] Handle implicit task/function imports in the unit scope SystemVerilog requires that functions and tasks are not implicitly imported if a symbol with the same name appears in the scope, even if it the symbol is declared after its usage. To support this a list of potential imports is collected while parsing a scope and only when the end of the scope is reached it is evaluated whether the symbol should be imported or not based on whether it already exists in the scope. This currently works fine for all scopes except for the unit scope. Since the unit scope might span multiple files it is never explicitly closed and the potential imports are never checked. Make sure that after parsing all files is done the potential imports for the unit scope are checked. Signed-off-by: Lars-Peter Clausen --- main.cc | 2 ++ parse_api.h | 2 ++ pform.cc | 21 +++++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/main.cc b/main.cc index 8b93f1c62..057b70ac2 100644 --- a/main.cc +++ b/main.cc @@ -1126,6 +1126,8 @@ int main(int argc, char*argv[]) rc += pform_parse(source_files[idx]); } + pform_finish(); + if (pf_path) { ofstream out (pf_path); out << "PFORM DUMP NATURES:" << endl; diff --git a/parse_api.h b/parse_api.h index d95420916..da43030e1 100644 --- a/parse_api.h +++ b/parse_api.h @@ -58,6 +58,8 @@ extern void pform_dump(std::ostream&out, const PTaskFunc*tf); */ extern int pform_parse(const char*path); +extern void pform_finish(); + extern std::string vl_file; extern void pform_set_timescale(int units, int prec, const char*file, diff --git a/pform.cc b/pform.cc index e8aac1089..9b19f9dba 100644 --- a/pform.cc +++ b/pform.cc @@ -405,17 +405,22 @@ LexicalScope* pform_peek_scope(void) return lexical_scope; } -void pform_pop_scope() +static void pform_check_possible_imports(LexicalScope *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(); +} + +void pform_pop_scope() +{ + LexicalScope*scope = lexical_scope; + assert(scope); + + pform_check_possible_imports(scope); lexical_scope = scope->parent_scope(); assert(lexical_scope); @@ -3406,3 +3411,11 @@ int pform_parse(const char*path) destroy_lexor(); return error_count; } + +void pform_finish() +{ + // Wait until all parsing is done and all symbols in the unit scope are + // known before importing possible imports. + for (auto unit : pform_units) + pform_check_possible_imports(unit); +}