diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index b7707754d..960d2e780 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -40,6 +40,39 @@ VL_DEFINE_DEBUG_FUNCTIONS; //###################################################################### +class RenameStaticVisitor final : public VNVisitor { +private: + // STATE + const std::set& m_staticFuncVarsr; // Static variables from m_ftaskp + AstNodeFTask* const m_ftaskp; // Current function/task + + // VISITORS + void visit(AstVarRef* nodep) override { + const auto it = m_staticFuncVarsr.find(nodep->varp()); + if (it != m_staticFuncVarsr.end()) nodep->name((*it)->name()); + iterateChildren(nodep); + } + + void visit(AstInitialStatic* nodep) override { + iterateChildren(nodep); + nodep->unlinkFrBack(); + m_ftaskp->addHereThisAsNext(nodep); + } + + void visit(AstNode* nodep) override { iterateChildren(nodep); } + +public: + // CONSTRUCTORS + RenameStaticVisitor(std::set& staticFuncVars, AstNodeFTask* ftaskp, AstNode* nodep) + : m_staticFuncVarsr(staticFuncVars) + , m_ftaskp(ftaskp) { + iterateChildren(nodep); + } + ~RenameStaticVisitor() override = default; +}; + +//###################################################################### + class BeginState final { private: // NODE STATE @@ -123,25 +156,6 @@ private: } } - void renameAndStaticsRecurse(AstNode* const nodep) { - // Rename references and move InitialStatic items - if (AstVarRef* const varrefp = VN_CAST(nodep, VarRef)) { - const auto it = m_staticFuncVars.find(varrefp->varp()); - if (it != m_staticFuncVars.end()) varrefp->name((*it)->name()); - } - - if (nodep->op1p()) renameAndStaticsRecurse(nodep->op1p()); - if (nodep->op2p()) renameAndStaticsRecurse(nodep->op2p()); - if (nodep->op3p()) renameAndStaticsRecurse(nodep->op3p()); - if (nodep->op4p()) renameAndStaticsRecurse(nodep->op4p()); - if (nodep->nextp()) renameAndStaticsRecurse(nodep->nextp()); - - if (VN_IS(nodep, InitialStatic)) { - nodep->unlinkFrBack(); - m_ftaskp->addHereThisAsNext(nodep); - } - } - // VISITORS void visit(AstFork* nodep) override { // Keep begins in forks to group their statements together @@ -197,7 +211,7 @@ private: m_ftaskp = nodep; m_liftedp = nullptr; iterateChildren(nodep); - renameAndStaticsRecurse(nodep); + RenameStaticVisitor{m_staticFuncVars, m_ftaskp, nodep}; if (m_liftedp) { // Place lifted nodes at beginning of stmtsp, so Var nodes appear before referenced if (AstNode* const stmtsp = nodep->stmtsp()) { diff --git a/test_regress/t/t_var_static.pl b/test_regress/t/t_var_static.pl index 93a3a1be3..efb3d2dfc 100755 --- a/test_regress/t/t_var_static.pl +++ b/test_regress/t/t_var_static.pl @@ -16,6 +16,7 @@ compile( execute( check_finished => 1, + all_run_flags => ['+plusarg=value'], ); ok(1); diff --git a/test_regress/t/t_var_static.v b/test_regress/t/t_var_static.v index cb54f6a0c..7eec192a5 100644 --- a/test_regress/t/t_var_static.v +++ b/test_regress/t/t_var_static.v @@ -52,10 +52,17 @@ module t (/*AUTOARG*/ function automatic int f_au_au (); automatic int au = 2; au++; return au; endfunction + string plusarg = ""; + bit has_plusarg = |($value$plusargs("plusarg=%s", plusarg)); int v; initial begin + if (has_plusarg) begin + if (plusarg == "") begin + $fatal(1, "%m: +plusarg must not be empty"); + end + end v = f_no_no(); `checkh(v, 3); v = f_no_no(); `checkh(v, 4); v = f_no_st(); `checkh(v, 3);