Use the bound typedef to find its declaration scope

Type names are resolved to `typedef_t` objects during parsing. During
elaboration `find_typedef_scope()` currently resolves the name again through
the completed import table. An import appearing after the original reference
can therefore redirect it to a different typedef with the same name.

Search the enclosing and package scopes for the exact `typedef_t` object
instead. This preserves the parsing-time binding and returns the scope that
owns the selected typedef.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2026-07-26 12:06:55 -07:00
parent 8df804c273
commit 41f4ff0fbc
2 changed files with 21 additions and 10 deletions

View File

@ -239,28 +239,39 @@ void NetScope::add_typedefs(const map<perm_string,typedef_t*>*typedefs)
typedefs_ = *typedefs;
}
/*
* Type names are resolved to typedef_t objects during parsing. Locate the
* scope that owns that exact object instead of resolving its name again
* during elaboration. A name lookup here could follow an import that appears
* after the original type reference and select a different typedef.
*/
NetScope*NetScope::find_typedef_scope(const Design*des, const typedef_t*type_i)
{
ivl_assert(*this, type_i);
// First check the enclosing lexical scopes and compilation unit.
NetScope *cur_scope = this;
while (cur_scope) {
auto it = cur_scope->typedefs_.find(type_i->name);
if (it != cur_scope->typedefs_.end() && it->second == type_i)
return cur_scope;
NetScope*import_scope = cur_scope->find_import(des, type_i->name);
if (import_scope)
cur_scope = import_scope;
else if (cur_scope == unit_)
return 0;
else
cur_scope = cur_scope->parent();
if (cur_scope == 0)
if (cur_scope == unit_)
break;
cur_scope = cur_scope->parent();
if (!cur_scope)
cur_scope = unit_;
}
return 0;
// Imported typedefs are owned by package scopes outside that chain.
for (auto package : des->find_package_scopes()) {
auto it = package->typedefs_.find(type_i->name);
if (it != package->typedefs_.end() && it->second == type_i)
return package;
}
return nullptr;
}
/*

View File

@ -1002,7 +1002,7 @@ class NetScope : public Definitions, public Attrib {
void add_typedefs(const std::map<perm_string,typedef_t*>*typedefs);
/* Search the scope hierarchy for the scope where 'type' was defined. */
/* Locate the scope that owns the resolved typedef object. */
NetScope*find_typedef_scope(const Design*des, const typedef_t*type_i);
/* Parameters exist within a scope, and these methods allow