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 <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2023-06-02 18:58:42 -07:00
parent edaa6e6c76
commit c1c4c28313
3 changed files with 21 additions and 4 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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<perm_string,PPackage*>::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);
}