diff --git a/net_scope.cc b/net_scope.cc index be9d1c4c6..13a31ed80 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -239,28 +239,39 @@ void NetScope::add_typedefs(const map*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; } /* diff --git a/netlist.h b/netlist.h index 0af9d7ad9..8643158c2 100644 --- a/netlist.h +++ b/netlist.h @@ -1002,7 +1002,7 @@ class NetScope : public Definitions, public Attrib { void add_typedefs(const std::map*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