diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 81c93c04c..376b30011 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -666,16 +666,12 @@ class AstDefImplicitDType final : public AstNodeDType { // After link, these become typedefs // @astgen op1 := childDTypep : Optional[AstNodeDType] string m_name; - void* m_containerp; // In what scope is the name unique, so we can know what are duplicate - // definitions (arbitrary value) const int m_uniqueNum; public: - AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType, - AstNodeDType* dtp) + AstDefImplicitDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp) : ASTGEN_SUPER_DefImplicitDType(fl) , m_name{name} - , m_containerp{containerp} , m_uniqueNum{uniqueNumInc()} { childDTypep(dtp); // Only for parser dtypep(nullptr); // V3Width will resolve @@ -683,7 +679,6 @@ public: AstDefImplicitDType(const AstDefImplicitDType& other) : AstNodeDType(other) , m_name(other.m_name) - , m_containerp(other.m_containerp) , m_uniqueNum(uniqueNumInc()) {} ASTGEN_MEMBERS_AstDefImplicitDType; int uniqueNum() const { return m_uniqueNum; } @@ -696,7 +691,6 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return dtypep() ? dtypep() : childDTypep(); } - void* containerp() const { return m_containerp; } // METHODS // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index d2860ff58..c48830a09 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -42,7 +42,7 @@ class LinkParseVisitor final : public VNVisitor { const VNUser2InUse m_inuser2; // TYPES - using ImplTypedefMap = std::map, AstTypedef*>; + using ImplTypedefMap = std::map; // STATE AstVar* m_varp = nullptr; // Variable we're under @@ -498,14 +498,14 @@ class LinkParseVisitor final : public VNVisitor { cleanFileline(nodep); UINFO(8, " DEFIMPLICIT " << nodep << endl); // Must remember what names we've already created, and combine duplicates - // so that for "var enum {...} a,b" a & b will share a common typedef - // Unique name space under each containerp() so that an addition of + // so that for "var enum {...} a,b" a & b will share a common typedef. + // Change to unique name space per module so that an addition of // a new type won't change every verilated module. AstTypedef* defp = nullptr; - const ImplTypedefMap::iterator it - = m_implTypedef.find(std::make_pair(nodep->containerp(), nodep->name())); + const ImplTypedefMap::iterator it = m_implTypedef.find(nodep->name()); if (it != m_implTypedef.end()) { defp = it->second; + UINFO(9, "Reused impltypedef " << nodep << " --> " << defp << endl); } else { // Definition must be inserted right after the variable (etc) that needed it // AstVar, AstTypedef, AstNodeFTask are common containers @@ -526,7 +526,11 @@ class LinkParseVisitor final : public VNVisitor { } else { defp = new AstTypedef{nodep->fileline(), nodep->name(), nullptr, VFlagChildDType{}, dtypep}; - m_implTypedef.emplace(std::make_pair(nodep->containerp(), defp->name()), defp); + m_implTypedef.emplace(defp->name(), defp); + // Rename so that name doesn't change if a type is added/removed elsewhere + // But the m_implTypedef is stil by old name so we can find it for next new lookups + defp->name("__typeimpmod" + cvtToStr(m_implTypedef.size())); + UINFO(9, "New impltypedef " << defp << endl); backp->addNextHere(defp); } } @@ -618,6 +622,7 @@ class LinkParseVisitor final : public VNVisitor { VL_RESTORER(m_genblkAbove); VL_RESTORER(m_genblkNum); VL_RESTORER(m_beginDepth); + VL_RESTORER(m_implTypedef); VL_RESTORER(m_lifetime); VL_RESTORER(m_lifetimeAllowed); { @@ -630,6 +635,7 @@ class LinkParseVisitor final : public VNVisitor { m_genblkAbove = 0; m_genblkNum = 0; m_beginDepth = 0; + m_implTypedef.clear(); m_valueModp = nodep; m_lifetime = nodep->lifetime(); m_lifetimeAllowed = VN_IS(nodep, Class); diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 8e6613fe1..b33972145 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -749,7 +749,12 @@ int V3ParseImp::tokenToBison() { // V3ParseBisonYYSType functions std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs) { - os << "TOKEN {" << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol() << "}"; + os << "TOKEN {"; + if (VL_UNCOVERABLE(!rhs.fl)) + os << "%E-null-fileline"; + else + os << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol(); + os << "}"; os << "=" << rhs.token << " " << V3ParseImp::tokenName(rhs.token); if (rhs.token == yaID__ETC // || rhs.token == yaID__CC // diff --git a/src/verilog.y b/src/verilog.y index 5c69afffb..08025f727 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -108,7 +108,7 @@ public: int m_pinNum = -1; // Pin number currently parsing std::stack m_pinStack; // Queue of pin numbers being parsed - static int s_modTypeImpNum; // Implicit type number, incremented each module + static int s_typeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS V3ParseGrammar() {} @@ -300,7 +300,7 @@ public: const VBasicDTypeKwd LOGIC = VBasicDTypeKwd::LOGIC; // Shorthand "LOGIC" const VBasicDTypeKwd LOGIC_IMPLICIT = VBasicDTypeKwd::LOGIC_IMPLICIT; -int V3ParseGrammar::s_modTypeImpNum = 0; +int V3ParseGrammar::s_typeImpNum = 0; //====================================================================== // Macro functions @@ -2233,12 +2233,12 @@ data_typeNoRef: // ==IEEE: data_type, excluding class_ty | struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray( new AstDefImplicitDType{$1->fileline(), - "__typeimpsu" + cvtToStr(GRAMMARP->s_modTypeImpNum++), - SYMP, VFlagChildDType{}, $1}, $2, true); } + "__typeimpsu" + cvtToStr(GRAMMARP->s_typeImpNum++), + VFlagChildDType{}, $1}, $2, true); } | enumDecl { $$ = new AstDefImplicitDType{$1->fileline(), - "__typeimpenum" + cvtToStr(GRAMMARP->s_modTypeImpNum++), - SYMP, VFlagChildDType{}, $1}; } + "__typeimpenum" + cvtToStr(GRAMMARP->s_typeImpNum++), + VFlagChildDType{}, $1}; } | ySTRING { $$ = new AstBasicDType{$1, VBasicDTypeKwd::STRING}; } | yCHANDLE diff --git a/test_regress/t/t_typename.out b/test_regress/t/t_typename.out index 133f56582..f8ebfd10d 100644 --- a/test_regress/t/t_typename.out +++ b/test_regress/t/t_typename.out @@ -20,7 +20,7 @@ "int$[$:3]" ==? "int$[$:3]" "bit$[]" ==? "bit$[]" -"enum{A=32'h0;B=32'h1;C=32'h63;}A::__typeimpenum1" ==? "enum{A=32'sd0,B=32'sd1,C=32'sd99}A::" +"enum{A=32'h0;B=32'h1;C=32'h63;}A::__typeimpmod1" ==? "enum{A=32'sd0,B=32'sd1,C=32'sd99}A::" "struct{bit A;bit B;}t.AB_t" ==? "struct{bit A;bit B;}" "struct{bit A;bit B;}t.AB_t$[0:9]" ==? "struct{bit A;bit B;}top.AB_t$[0:9]" "union{bit A;bit B;}t.UAB_t" ==? "union{bit A;bit B;}" diff --git a/test_regress/t/t_typename.py b/test_regress/t/t_typename.py index ab5dca066..1a1bebba6 100755 --- a/test_regress/t/t_typename.py +++ b/test_regress/t/t_typename.py @@ -9,7 +9,7 @@ import vltest_bootstrap -test.scenarios('simulator') +test.scenarios('simulator_st') test.compile()