From 60a1d25a96dfa5990c04e7728ee0578bbc60ba16 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 26 Nov 2020 08:55:32 -0500 Subject: [PATCH] Fix extern function member references. --- src/V3LinkDot.cpp | 5 +++-- test_regress/t/t_class_extern.v | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index a0cb84763..45c949149 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -985,7 +985,7 @@ class LinkDotFindVisitor final : public AstNVisitor { // Remember the existing symbol table scope VL_RESTORER(m_classOrPackagep); VL_RESTORER(m_curSymp); - VSymEnt* const oldCurSymp = m_curSymp; + VSymEnt* upSymp = m_curSymp; { // Change to appropriate package if extern declaration (vs definition) if (nodep->classOrPackagep()) { @@ -1000,6 +1000,7 @@ class LinkDotFindVisitor final : public AstNVisitor { nodep->v3error("Extern declaration's scope is not a defined class"); } else { m_curSymp = m_statep->getNodeSym(classp); + upSymp = m_curSymp; if (!nodep->isExternDef()) { // Move it to proper spot under the target class nodep->unlinkFrBack(); @@ -1017,7 +1018,7 @@ class LinkDotFindVisitor final : public AstNVisitor { // Create symbol table for the task's vars string name = string{nodep->isExternProto() ? "extern " : ""} + nodep->name(); m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_classOrPackagep); - m_curSymp->fallbackp(oldCurSymp); + m_curSymp->fallbackp(upSymp); // Convert the func's range to the output variable // This should probably be done in the Parser instead, as then we could // just attach normal signal attributes to it. diff --git a/test_regress/t/t_class_extern.v b/test_regress/t/t_class_extern.v index ba96dc70e..94a71825f 100644 --- a/test_regress/t/t_class_extern.v +++ b/test_regress/t/t_class_extern.v @@ -5,6 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 class Cls; + int value; extern function int ext_f_np; extern function int ext_f_p(); extern function int ext_f_i(int in); @@ -18,7 +19,7 @@ function int Cls::ext_f_np; endfunction function int Cls::ext_f_p(); - return 2; + return value; endfunction function int Cls::ext_f_i(int in); @@ -33,16 +34,17 @@ task Cls::ext_t_p(); endtask task Cls::ext_t_i(int in); if (in != 2) $stop; + value = in; endtask module t (/*AUTOARG*/); initial begin Cls c = new; - 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(); + if (c.ext_f_np() != 1) $stop; + if (c.ext_f_p() != 2) $stop; + if (c.ext_f_i(10) != 11) $stop; end endmodule