diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index ab3ead042..798dd23c8 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -363,7 +363,8 @@ public: UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9, " INSERTblk se" << cvtToHex(symp) << " above=se" << cvtToHex(abovep) - << " node=" << nodep << endl); + << " pkg=" << cvtToHex(classOrPackagep) << " node=" << nodep + << endl); symp->parentp(abovep); symp->classOrPackagep(classOrPackagep); symp->fallbackp(abovep); @@ -378,7 +379,8 @@ public: UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9, " INSERTsym se" << cvtToHex(symp) << " name='" << name << "' above=se" - << cvtToHex(abovep) << " node=" << nodep << endl); + << cvtToHex(abovep) << " pkg=" << cvtToHex(classOrPackagep) + << " node=" << nodep << endl); // We don't remember the ent associated with each node, because we // need a unique scope entry for each instantiation symp->classOrPackagep(classOrPackagep); @@ -981,6 +983,7 @@ class LinkDotFindVisitor final : public AstNVisitor { UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Function/Task not under module?"); if (nodep->name() == "new") m_explicitNew = true; // Remember the existing symbol table scope + VL_RESTORER(m_classOrPackagep); VL_RESTORER(m_curSymp); VSymEnt* const oldCurSymp = m_curSymp; { @@ -1007,14 +1010,13 @@ class LinkDotFindVisitor final : public AstNVisitor { } } } + // Set the class as package for iteration + if (VN_IS(m_curSymp->nodep(), Class)) { + m_classOrPackagep = VN_CAST(m_curSymp->nodep(), Class); + } // Create symbol table for the task's vars string name = string{nodep->isExternProto() ? "extern " : ""} + nodep->name(); - auto pkgp = m_classOrPackagep; - // Set the class as package for static class methods - if (nodep->lifetime().isStatic() && VN_IS(m_curSymp->nodep(), Class)) { - pkgp = VN_CAST(m_curSymp->nodep(), Class); - } - m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, pkgp); + m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_classOrPackagep); m_curSymp->fallbackp(oldCurSymp); // Convert the func's range to the output variable // This should probably be done in the Parser instead, as then we could diff --git a/test_regress/t/t_class_extern.v b/test_regress/t/t_class_extern.v index eb15c625b..ba96dc70e 100644 --- a/test_regress/t/t_class_extern.v +++ b/test_regress/t/t_class_extern.v @@ -5,23 +5,44 @@ // SPDX-License-Identifier: CC0-1.0 class Cls; - extern task extcls(); - extern function int extone(); + extern function int ext_f_np; + extern function int ext_f_p(); + extern function int ext_f_i(int in); + extern task ext_t_np; + extern task ext_t_p(); + extern task ext_t_i(int in); endclass -function int Cls::extone(); +function int Cls::ext_f_np; return 1; endfunction -task Cls::extcls(); +function int Cls::ext_f_p(); + return 2; +endfunction + +function int Cls::ext_f_i(int in); + return in+1; +endfunction + +task Cls::ext_t_np(); $write("*-* All Finished *-*\n"); +endtask +task Cls::ext_t_p(); $finish; endtask +task Cls::ext_t_i(int in); + if (in != 2) $stop; +endtask module t (/*AUTOARG*/); initial begin Cls c = new; - if (c.extone() != 1) $stop; - c.extcls(); + if (c.ext_f_np() != 1) $stop; + if (c.ext_f_p() != 2) $stop; + if (c.ext_f_i(10) != 11) $stop; + c.ext_t_i(2); + c.ext_t_np(); + c.ext_t_p(); end endmodule