From ce03293128d555b70e2bd5fd33c5dd70c322f79b Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 15 Sep 2022 19:43:56 +0100 Subject: [PATCH] Generate AstNode accessors via astgen Introduce the @astgen directives parsed by astgen, currently used for the generation child node (operand) accessors. Please see the updated internal documentation for details. --- docs/internals.rst | 100 +++- src/V3Active.cpp | 14 +- src/V3Assert.cpp | 20 +- src/V3AssertPre.cpp | 2 +- src/V3AstInlines.h | 21 +- src/V3AstNodeDType.h | 149 ++---- src/V3AstNodeMath.h | 469 +++++++---------- src/V3AstNodeOther.h | 1057 ++++++++++++++++----------------------- src/V3AstNodes.cpp | 56 +-- src/V3Begin.cpp | 10 +- src/V3Branch.cpp | 2 +- src/V3Broken.cpp | 4 +- src/V3CCtors.cpp | 6 +- src/V3CUse.cpp | 2 +- src/V3Case.cpp | 10 +- src/V3Changed.cpp | 8 +- src/V3Class.cpp | 16 +- src/V3Clean.cpp | 6 +- src/V3Clock.cpp | 16 +- src/V3Common.cpp | 6 +- src/V3Config.cpp | 4 +- src/V3Const.cpp | 105 ++-- src/V3Coverage.cpp | 46 +- src/V3Delayed.cpp | 8 +- src/V3DepthBlock.cpp | 2 +- src/V3Descope.cpp | 2 +- src/V3EmitCFunc.h | 20 +- src/V3EmitV.cpp | 26 +- src/V3Expand.cpp | 4 +- src/V3Force.cpp | 4 +- src/V3Gate.cpp | 4 +- src/V3GenClk.cpp | 6 +- src/V3Inline.cpp | 30 +- src/V3InstrCount.cpp | 12 +- src/V3Life.cpp | 4 +- src/V3LinkCells.cpp | 4 +- src/V3LinkDot.cpp | 8 +- src/V3LinkInc.cpp | 6 +- src/V3LinkJump.cpp | 14 +- src/V3LinkLevel.cpp | 10 +- src/V3LinkParse.cpp | 4 +- src/V3LinkResolve.cpp | 4 +- src/V3MergeCond.cpp | 16 +- src/V3Order.cpp | 12 +- src/V3Param.cpp | 12 +- src/V3ParseImp.cpp | 2 +- src/V3Partition.cpp | 6 +- src/V3Premit.cpp | 4 +- src/V3ProtectLib.cpp | 66 +-- src/V3Randomize.cpp | 2 +- src/V3Reloop.cpp | 2 +- src/V3Scope.cpp | 30 +- src/V3SenTree.h | 2 +- src/V3Simulate.h | 18 +- src/V3Slice.cpp | 4 +- src/V3Split.cpp | 18 +- src/V3SplitVar.cpp | 10 +- src/V3Stats.cpp | 4 +- src/V3Table.cpp | 8 +- src/V3Task.cpp | 32 +- src/V3Trace.cpp | 12 +- src/V3TraceDecl.cpp | 6 +- src/V3Tristate.cpp | 40 +- src/V3Unknown.cpp | 10 +- src/V3Unroll.cpp | 14 +- src/V3VariableOrder.cpp | 2 +- src/V3Width.cpp | 46 +- src/astgen | 146 +++++- src/bisonpre | 5 +- src/verilog.y | 86 ++-- 70 files changed, 1386 insertions(+), 1530 deletions(-) diff --git a/docs/internals.rst b/docs/internals.rst index c9e00d7dd..c62881026 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -96,10 +96,11 @@ this. Each ``AstNode`` has pointers to up to four children, accessed by the ``op1p`` through ``op4p`` methods. These methods are then abstracted in a specific Ast\* node class to a more specific name. For example with the -``AstIf`` node (for ``if`` statements), ``ifsp`` calls ``op2p`` to give the +``AstIf`` node (for ``if`` statements), ``thensp`` calls ``op2p`` to give the pointer to the AST for the "then" block, while ``elsesp`` calls ``op3p`` to give the pointer to the AST for the "else" block, or NULL if there is not -one. +one. These accessors are automatically generated by ``astgen`` after +parsing the ``@astgen`` directives in the specific ``AstNode`` subclasses. ``AstNode`` has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these @@ -501,22 +502,99 @@ code: The ``astgen`` Script --------------------- -Some of the code implementing passes is extremely repetitive, and must be -implemented for each sub-class of ``AstNode``. However, while repetitive, -there is more variability than can be handled in C++ macros. +The ``astgen`` script is used to generate some of the repetitive C++ code +related to the ``AstNode`` type hierarchy. An example is the abstract ``visit`` +methods in ``VNVisitor``. There are other uses, please see the ``*__gen*`` +files in the bulid directories and the ``astgen`` script itself for details. A +description of the more advanced features of ``astgen`` are provided here. -In Verilator this is implemented by using a script, ``astgen`` to -pre-process the C++ code. For example in ``V3Const.cpp`` this is used to -implement the ``visit()`` functions for each binary operation using the -``TREEOP`` macro. -The original C source code is transformed into C code in the ``obj_opt`` +Generating ``AstNode`` members +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some of the member s of ``AstNode`` sub-classes are generated by ``astgen``. +These are emitted as pre-processor macro definitions, which then need to be +added to the ``AstNode`` sub-classes they correspond to. Specifically ``class +AstFoo`` should contain an instance of ``ASTGEN_MEMBERS_Foo;`` at class scope. +The ``astgen`` script checks and errors if this is not present. The method +generated depends on whether the class is a concrete final class, or an +abstract ``AstNode*`` base-class, and on ``@astgen`` directives present in +comment sections in the body of the ``AstNode`` sub-class definitions. + + +List of ``@astgen`` directives +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``@astgen`` directives in comments contained in the body of ``AstNode`` +sub-class definitions are parsed and contribute to the code generated by +``astgen``. The general syntax is ``@astgen := ``, +where ```` determines what is being defined, and ```` is +a ```` dependent description of the definition. The list of +``@astgen`` directives is as follows: + + +``op`` operand directives +""""""""""""""""""""""""""""" + +The ``op1``, ``op2``, ``op3`` and ``op4`` directives are used to describe the +name and type of the up to 4 child operands of a node. The syntax of the +```` field is `` : ``, where ```` +will be used as the base name of the generated operand accessors, and +```` is one of: + +1. An ``AstNode`` sub-class, defining the operand to be of that type, always + no-null, and with an always null ``nextp()``. That is, the child node is + always present, and is a single ``AstNode`` (as opposed to a list). + +2. ``Optional[]``. This is just like in point 1 above, but + defines the child node to be optional, meaning it may be null. + +3. ``List[AstNode sub-class]`` describes a list operand, which means the child + node may have a non-null ``nextp()`` and in addition the child itself may be + null, representing an empty list. + + +An example of the full syntax of the directive is +``@astgen op1 := lhsp : AstNodeMath``. + +``astnode`` generates accessors for the child nodes based on these directives. +For non-list children, the names of the getter and setter both are that of the +given ````. For list type children, the getter is ````, +and instead of the setter, there an ``add`` method is generated +that appends new nodes (or lists of nodes) to the child list. + +``alias op`` operand alias directives +"""""""""""""""""""""""""""""""""""""""" + +If a super-class already defined a name and type for a child node using the +``op`` directive, but a more appropriate name exists in the context of a +sub-class, then the alias directive can be used to introduce an additional name +for the child node. The is ``alias op := `` where +```` is the new name. ``op`` must have been defined in some +super-class of the current node. + +Example: ``@astgen alias op1 := condp`` + + +Additional features of ``astgen`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to generating ``AstNode`` members as described above, +``astgen`` is also use to handle some of the repetitive implementation code +that is still variable enough not to be handled in C++ macros. + +In particular, ``astgen`` is used to pre-process some of the C++ source +files. For example in ``V3Const.cpp``, it is used to implement the +``visit()`` functions for each binary operation using the ``TREEOP`` macro. + +The original C++ source code is transformed into C++ code in the ``obj_opt`` and ``obj_dbg`` sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example ``V3Const.cpp`` into ``V3Const__gen.cpp``. -Visitor Functions ----------------- +Visitor Functions +----------------- Verilator uses the "Visitor" design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the diff --git a/src/V3Active.cpp b/src/V3Active.cpp index f1b325eac..b85de968e 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -216,7 +216,7 @@ private: // METHODS void addActive(AstActive* nodep) { UASSERT_OBJ(m_scopep, nodep, "nullptr scope"); - m_scopep->addActivep(nodep); + m_scopep->addBlocksp(nodep); } // VISITORS void visit(AstScope* nodep) override { @@ -302,7 +302,7 @@ private: LatchDetectGraphVertex* const parentp = m_graph.currentp(); LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true); m_graph.addPathVertex(branchp, "IF"); - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); m_graph.addPathVertex(branchp, "ELSE"); iterateAndNextNull(nodep->elsesp()); m_graph.currentp(parentp); @@ -458,7 +458,7 @@ private: void visit(AstFinal* nodep) override { // Relink to CFUNC for the final UINFO(4, " FINAL " << nodep << endl); - if (!nodep->bodysp()) { // Empty, Kill it. + if (!nodep->stmtsp()) { // Empty, Kill it. VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } @@ -471,10 +471,10 @@ private: m_scopeFinalp->isStatic(false); m_scopeFinalp->isLoose(true); m_scopeFinalp->slow(true); - m_namer.scopep()->addActivep(m_scopeFinalp); + m_namer.scopep()->addBlocksp(m_scopeFinalp); } nodep->unlinkFrBack(); - m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext()); + m_scopeFinalp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext()); VL_DO_DANGLING(nodep->deleteTree(), nodep); } @@ -542,7 +542,7 @@ private: UINFO(4, " ALW " << nodep << endl); // if (debug() >= 9) nodep->dumpTree(cout, " Alw: "); - if (!nodep->bodysp()) { + if (!nodep->stmtsp()) { // Empty always. Kill it. VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; @@ -551,7 +551,7 @@ private: } void visit(AstAlwaysPostponed* nodep) override { UINFO(4, " ALW " << nodep << endl); - if (!nodep->bodysp()) { + if (!nodep->stmtsp()) { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 59158a07b..2577963f9 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -70,7 +70,7 @@ private: if (!m_monitorNumVarp) { m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum", nodep->findUInt64DType()}; - v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorNumVarp); + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorNumVarp); } const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorNumVarp, access); varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); @@ -80,7 +80,7 @@ private: if (!m_monitorOffVarp) { m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff", nodep->findBitDType()}; - v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorOffVarp); + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorOffVarp); } const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorOffVarp, access); varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); @@ -147,7 +147,7 @@ private: selfDestruct = true; } else { // V3Coverage assigned us a bucket to increment. - AstCoverInc* const covincp = VN_AS(snodep->coverincp(), CoverInc); + AstCoverInc* const covincp = VN_AS(snodep->coverincsp(), CoverInc); UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion"); covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace if (message != "") covincp->declp()->comment(message); @@ -209,7 +209,7 @@ private: iterateAndNextNull(ifp->condp()); // Recurse into the true case. - iterateAndNextNull(ifp->ifsp()); + iterateAndNextNull(ifp->thensp()); // If the last else is not an else if, recurse into that too. if (ifp->elsesp() && !nextifp) { // @@ -338,15 +338,15 @@ private: sentreep->unlinkFrBack(); AstAlways* const alwaysp = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, nullptr); - m_modp->addStmtp(alwaysp); + m_modp->addStmtsp(alwaysp); for (uint32_t i = 0; i < ticks; ++i) { AstVar* const outvarp = new AstVar( nodep->fileline(), VVarType::MODULETEMP, "_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep()); - m_modp->addStmtp(outvarp); + m_modp->addStmtsp(outvarp); AstNode* const assp = new AstAssignDly( nodep->fileline(), new AstVarRef(nodep->fileline(), outvarp, VAccess::WRITE), inp); - alwaysp->addStmtp(assp); + alwaysp->addStmtsp(assp); // if (debug() >= 9) assp->dumpTree(cout, "-ass: "); invarp = outvarp; inp = new AstVarRef(nodep->fileline(), invarp, VAccess::READ); @@ -387,7 +387,7 @@ private: stmtsp}; ifp->branchPred(VBranchPred::BP_UNLIKELY); AstNode* const newp = new AstAlwaysPostponed{fl, ifp}; - m_modp->addStmtp(newp); + m_modp->addStmtsp(newp); } else if (nodep->displayType() == VDisplayType::DT_STROBE) { nodep->displayType(VDisplayType::DT_DISPLAY); // Need one-shot @@ -395,7 +395,7 @@ private: const auto varp = new AstVar{fl, VVarType::MODULETEMP, "__Vstrobe" + cvtToStr(m_modStrobeNum++), nodep->findBitDType()}; - m_modp->addStmtp(varp); + m_modp->addStmtsp(varp); // Where $strobe was we do "__Vstrobe = '1;" const auto newsetp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, new AstConst{fl, AstConst::BitTrue{}}}; @@ -407,7 +407,7 @@ private: AstNode* const newp = new AstAlwaysPostponed{fl, ifp}; stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, new AstConst{fl, AstConst::BitFalse{}}}); - m_modp->addStmtp(newp); + m_modp->addStmtsp(newp); } } void visit(AstMonitorOff* nodep) override { diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index e993bd432..cdbcec1a4 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -84,7 +84,7 @@ private: void visit(AstAlways* nodep) override { iterateAndNextNull(nodep->sensesp()); if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp(); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); m_seniAlwaysp = nullptr; } diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 2deceda22..107579b69 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -61,7 +61,6 @@ bool AstNode::sameGateTree(const AstNode* node2p) const { return sameTreeIter(this, node2p, true, true); } -void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); } int AstNodeArrayDType::left() const { return rangep()->leftConst(); } int AstNodeArrayDType::right() const { return rangep()->rightConst(); } int AstNodeArrayDType::hi() const { return rangep()->hiConst(); } @@ -71,13 +70,13 @@ VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right( AstRange::AstRange(FileLine* fl, int left, int right) : ASTGEN_SUPER_Range(fl) { - setOp2p(new AstConst{fl, static_cast(left)}); - setOp3p(new AstConst{fl, static_cast(right)}); + leftp(new AstConst{fl, static_cast(left)}); + rightp(new AstConst{fl, static_cast(right)}); } AstRange::AstRange(FileLine* fl, const VNumRange& range) : ASTGEN_SUPER_Range(fl) { - setOp2p(new AstConst{fl, static_cast(range.left())}); - setOp3p(new AstConst{fl, static_cast(range.right())}); + leftp(new AstConst{fl, static_cast(range.left())}); + rightp(new AstConst{fl, static_cast(range.right())}); } int AstRange::leftConst() const { AstConst* const constp = VN_CAST(leftp(), Const); @@ -97,7 +96,7 @@ AstPin::AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp) : ASTGEN_SUPER_Pin(fl) , m_pinNum{pinNum} , m_name{varname->name()} { - setNOp1p(exprp); + this->exprp(exprp); } AstDpiExportUpdated::AstDpiExportUpdated(FileLine* fl, AstVarScope* varScopep) @@ -112,7 +111,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType : ASTGEN_SUPER_PackArrayDType(fl) { childDTypep(dtp); // Only for parser refDTypep(nullptr); - setOp2p(rangep); + this->rangep(rangep); dtypep(nullptr); // V3Width will resolve const int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width, width); @@ -120,7 +119,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : ASTGEN_SUPER_PackArrayDType(fl) { refDTypep(dtp); - setOp2p(rangep); + this->rangep(rangep); dtypep(this); const int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width, width); @@ -141,20 +140,20 @@ bool AstActive::hasClocked() const { return m_sensesp->hasClocked(); } AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp) : ASTGEN_SUPER_ElabDisplay(fl) { - setOp1p(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp}); + addFmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp}); m_displayType = dispType; } AstCStmt::AstCStmt(FileLine* fl, const string& textStmt) : ASTGEN_SUPER_CStmt(fl) { - addNOp1p(new AstText{fl, textStmt, true}); + addExprsp(new AstText{fl, textStmt, true}); } AstCMath::AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut) : ASTGEN_SUPER_CMath(fl) , m_cleanOut{cleanOut} , m_pure{true} { - addNOp1p(new AstText{fl, textStmt, true}); + addExprsp(new AstText{fl, textStmt, true}); if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED); } diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 02d45f31e..c1af84cc3 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -132,11 +132,13 @@ private: }; class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType { // Array data type, ie "some_dtype var_name [2:0]" - // Children: DTYPE (moved to refDTypep() in V3Width) - // Children: RANGE (array bounds) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width + // @astgen op2 := rangep : Optional[AstRange] // array bounds private: AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) - AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable + + AstNode* rangenp() const { return reinterpret_cast(rangep()); } + protected: AstNodeArrayDType(VNType t, FileLine* fl) : AstNodeDType{t, fl} {} @@ -165,14 +167,10 @@ public: && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } - AstRange* rangep() const { return VN_AS(op2p(), Range); } // op2 = Array(s) of variable - inline void rangep(AstRange* nodep); // METHODS AstBasicDType* basicp() const override { return subDTypep()->basicp(); @@ -193,6 +191,7 @@ public: }; class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType { // A struct or union; common handling + // @astgen op1 := membersp : List[AstMemberDType] private: // TYPES using MemberNameMap = std::map; @@ -233,16 +232,11 @@ public: int widthAlignBytes() const override; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... int widthTotalBytes() const override; - // op1 = members bool similarDType(AstNodeDType* samep) const override { return this == samep; // We don't compare members, require exact equivalence } string name() const override { return m_name; } void name(const string& flag) override { m_name = flag; } - AstMemberDType* membersp() const { - return VN_AS(op1p(), MemberDType); - } // op1 = AstMember list - void addMembersp(AstNode* nodep) { addNOp1p(nodep); } bool packed() const { return m_packed; } // packed() but as don't support unpacked, presently all structs static bool packedUnsup() { return true; } @@ -263,33 +257,31 @@ public: // === AstNode === class AstEnumItem final : public AstNode { + // @astgen op1 := rangep : Optional[AstRange] // Range for name appending + // @astgen op2 := valuep : Optional[AstNode] private: string m_name; public: // Parents: ENUM - AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp) + AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNode* valuep) : ASTGEN_SUPER_EnumItem(fl) , m_name{name} { - addNOp1p(rangep); - addNOp2p(initp); + this->rangep(rangep); + this->valuep(valuep); } ASTGEN_MEMBERS_EnumItem; string name() const override { return m_name; } bool maybePointedTo() const override { return true; } bool hasDType() const override { return true; } void name(const string& flag) override { m_name = flag; } - AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range for name appending - void rangep(AstRange* nodep) { addOp1p((AstNode*)nodep); } - AstNode* valuep() const { return op2p(); } // op2 = Value - void valuep(AstNode* nodep) { addOp2p(nodep); } }; // === AstNodeDType === class AstAssocArrayDType final : public AstNodeDType { // Associative array data type, ie "[some_dtype]" - // Children: DTYPE (moved to refDTypep() in V3Width) - // Children: DTYPE (the key, which remains here as a pointer) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width + // @astgen op2 := keyChildDTypep : AstNodeDType // the key, which remains here as a pointer private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNodeDType* m_keyDTypep; // Keys of this type (after widthing) @@ -335,9 +327,6 @@ public: void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -347,9 +336,6 @@ public: // AstNodeDType* keyDTypep() const { return m_keyDTypep ? m_keyDTypep : keyChildDTypep(); } void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; } - // op1 = Range of variable - AstNodeDType* keyChildDTypep() const { return VN_AS(op2p(), NodeDType); } - void keyChildDTypep(AstNodeDType* nodep) { setOp2p(nodep); } // METHODS AstBasicDType* basicp() const override { return nullptr; } AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; } @@ -361,7 +347,7 @@ public: }; class AstBasicDType final : public AstNodeDType { // Builtin atomic/vectored data type - // Children: RANGE (converted to constant in V3Width) + // @astgen op1 := rangep : Optional[AstRange] // Range of variable private: struct Members { VBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type @@ -415,8 +401,6 @@ public: BROKEN_RTN(dtypep() != this); return nullptr; } - AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range of variable - void rangep(AstRange* nodep) { setNOp1p((AstNode*)nodep); } void setSignedState(const VSigning& signst) { // Note NOSIGN does NOT change the state; this is required by the parser if (signst == VSigning::UNSIGNED) { @@ -470,21 +454,18 @@ public: class AstBracketArrayDType final : public AstNodeDType { // Associative/Queue/Normal array data type, ie "[dtype_or_expr]" // only for early parsing then becomes another data type - // Children: DTYPE (moved to refDTypep() in V3Width) - // Children: DTYPE (the key) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width + // @astgen op2 := elementsp : AstNode // ??? key dtype ??? public: - AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* elementsp) + AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* childDTypep, + AstNode* elementsp) : ASTGEN_SUPER_BracketArrayDType(fl) { - setOp1p(dtp); // Only for parser - setOp2p(elementsp); // Only for parser + this->childDTypep(childDTypep); + this->elementsp(elementsp); } ASTGEN_MEMBERS_BracketArrayDType; bool similarDType(AstNodeDType* samep) const override { V3ERROR_NA_RETURN(false); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } AstNodeDType* subDTypep() const override { return childDTypep(); } - // op2 = Range of variable - AstNode* elementsp() const { return op2p(); } // METHODS // Will be removed in V3Width, which relies on this // being a child not a dtype pointed node @@ -499,16 +480,16 @@ public: }; class AstClassRefDType final : public AstNodeDType { // Reference to a class - // Children: PINs (for parameter settings) + // @astgen op1 := paramsp: List[AstPin] private: AstClass* m_classp; // data type pointed to, BELOW the AstTypedef AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy public: - AstClassRefDType(FileLine* fl, AstClass* classp, AstNode* paramsp) + AstClassRefDType(FileLine* fl, AstClass* classp, AstPin* paramsp) : ASTGEN_SUPER_ClassRefDType(fl) , m_classp{classp} { - dtypep(this); - addNOp4p(paramsp); + this->dtypep(this); + this->addParamsp(paramsp); } ASTGEN_MEMBERS_ClassRefDType; // METHODS @@ -537,13 +518,13 @@ public: void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } AstClass* classp() const { return m_classp; } void classp(AstClass* nodep) { m_classp = nodep; } - AstPin* paramsp() const { return VN_AS(op4p(), Pin); } bool isCompound() const override { return true; } }; class AstConstDType final : public AstNodeDType { // const data type, ie "const some_dtype var_name [2:0]" // ConstDType are removed in V3LinkLValue and become AstVar::isConst. // When more generic types are supported AstConstDType will be propagated further. + // @astgen op1 := childDTypep : Optional[AstNodeDType] private: AstNodeDType* m_refDTypep = nullptr; // Inherit from this base data type public: @@ -571,9 +552,6 @@ public: return skipRefp()->similarDType(samep->skipRefp()); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -594,6 +572,7 @@ class AstDefImplicitDType final : public AstNodeDType { // For parsing enum/struct/unions that are declared with a variable rather than typedef // This allows "var enum {...} a,b" to share the enum definition for both variables // After link, these become typedefs + // @astgen op1 := childDTypep : Optional[AstNodeDType] private: string m_name; void* m_containerp; // In what scope is the name unique, so we can know what are duplicate @@ -620,9 +599,6 @@ public: return type() == samep->type() && same(samep); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); } void* containerp() const { return m_containerp; } // METHODS @@ -640,7 +616,7 @@ public: }; class AstDynArrayDType final : public AstNodeDType { // Dynamic array data type, ie "[]" - // Children: DTYPE (moved to refDTypep() in V3Width) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width private: AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) public: @@ -677,9 +653,6 @@ public: string prettyDTypeName() const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -722,19 +695,20 @@ public: }; class AstEnumDType final : public AstNodeDType { // Parents: TYPEDEF/MODULE - // Children: ENUMVALUEs + // @astgen op1 := childDTypep : Optional[AstNodeDType] + // @astgen op2 := itemsp : List[AstEnumItem] private: string m_name; // Name from upper typedef, if any AstNodeDType* m_refDTypep = nullptr; // Elements are of this type after V3Width const int m_uniqueNum = 0; public: - AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp) + AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstEnumItem* itemsp) : ASTGEN_SUPER_EnumDType(fl) , m_uniqueNum{uniqueNumInc()} { childDTypep(dtp); // Only for parser refDTypep(nullptr); - addNOp2p(itemsp); + addItemsp(itemsp); dtypep(nullptr); // V3Width will resolve widthFromSub(subDTypep()); } @@ -754,16 +728,12 @@ public: } bool similarDType(AstNodeDType* samep) const override { return this == samep; } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } // op1 = Data type - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } - // op1 = Range of variable AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } string name() const override { return m_name; } void name(const string& flag) override { m_name = flag; } - AstEnumItem* itemsp() const { return VN_AS(op2p(), EnumItem); } // op2 = AstEnumItem's // METHODS AstBasicDType* basicp() const override { return subDTypep()->basicp(); } AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); } @@ -835,6 +805,7 @@ public: class AstMemberDType final : public AstNodeDType { // A member of a struct/union // PARENT: AstNodeUOrStructDType + // @astgen op1 := childDTypep : Optional[AstNodeDType] private: AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) string m_name; // Name of variable @@ -869,9 +840,6 @@ public: if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -904,6 +872,7 @@ public: class AstParamTypeDType final : public AstNodeDType { // Parents: MODULE // A parameter type statement; much like a var or typedef + // @astgen op1 := childDTypep : Optional[AstNodeDType] private: const VVarType m_varType; // Type of variable (for localparam vs. param) string m_name; // Name of variable @@ -918,9 +887,6 @@ public: } ASTGEN_MEMBERS_ParamTypeDType; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Type assigning to - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); } AstBasicDType* basicp() const override { return subDTypep()->basicp(); } AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); } @@ -972,20 +938,21 @@ public: }; class AstQueueDType final : public AstNodeDType { // Queue array data type, ie "[ $ ]" - // Children: DTYPE (moved to refDTypep() in V3Width) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width + // @astgen op2 := boundp : Optional[AstNode] private: AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) public: AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp) : ASTGEN_SUPER_QueueDType(fl) { - setNOp2p(boundp); - childDTypep(dtp); // Only for parser + this->childDTypep(dtp); + this->boundp(boundp); refDTypep(nullptr); dtypep(nullptr); // V3Width will resolve } AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp) : ASTGEN_SUPER_QueueDType(fl) { - setNOp2p(boundp); + this->boundp(boundp); refDTypep(dtp); dtypep(dtp); } @@ -1011,13 +978,8 @@ public: void dumpSmall(std::ostream& str) const override; string prettyDTypeName() const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } - AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none - void boundp(AstNode* nodep) { setNOp2p(nodep); } inline int boundConst() const; AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } @@ -1034,6 +996,9 @@ public: bool isCompound() const override { return true; } }; class AstRefDType final : public AstNodeDType { + // @astgen op1 := typeofp : AstNode + // @astgen op2 := classOrPackageOpp : Optional[AstNode] + // @astgen op3 := paramsp : List[AstPin] private: // Pre-Width must reference the Typeref, not what it points to, as some child // types like AstBracketArrayType will disappear and can't lose the handle @@ -1046,16 +1011,16 @@ public: AstRefDType(FileLine* fl, const string& name) : ASTGEN_SUPER_RefDType(fl) , m_name{name} {} - AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstNode* paramsp) + AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstPin* paramsp) : ASTGEN_SUPER_RefDType(fl) , m_name{name} { - setNOp3p(classOrPackagep); - addNOp4p(paramsp); + this->classOrPackageOpp(classOrPackagep); + addParamsp(paramsp); } class FlagTypeOfExpr {}; // type(expr) for parser only AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp) : ASTGEN_SUPER_RefDType(fl) { - setOp2p(typeofp); + this->typeofp(typeofp); } ASTGEN_MEMBERS_RefDType; // METHODS @@ -1106,7 +1071,6 @@ public: int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); } int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) override { m_name = flag; } - // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } AstTypedef* typedefp() const { return m_typedefp; } void typedefp(AstTypedef* nodep) { m_typedefp = nodep; } @@ -1116,9 +1080,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } AstNodeModule* classOrPackagep() const { return m_classOrPackagep; } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } - AstNode* typeofp() const { return op2p(); } - AstNode* classOrPackageOpp() const { return op3p(); } - AstPin* paramsp() const { return VN_AS(op4p(), Pin); } bool isCompound() const override { v3fatalSrc("call isCompound on subdata type, not reference"); return false; @@ -1126,7 +1087,7 @@ public: }; class AstUnsizedArrayDType final : public AstNodeDType { // Unsized/open-range Array data type, ie "some_dtype var_name []" - // Children: DTYPE (moved to refDTypep() in V3Width) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) public: @@ -1149,9 +1110,6 @@ public: bool similarDType(AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -1194,7 +1152,7 @@ public: }; class AstWildcardArrayDType final : public AstNodeDType { // Wildcard index type associative array data type, ie "some_dtype var_name [*]" - // Children: DTYPE (moved to refDTypep() in V3Width) + // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) public: @@ -1217,9 +1175,6 @@ public: bool similarDType(AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } @@ -1237,8 +1192,6 @@ public: // === AstNodeArrayDType === class AstPackArrayDType final : public AstNodeArrayDType { // Packed array data type, ie "some_dtype [2:0] var_name" - // Children: DTYPE (moved to refDTypep() in V3Width) - // Children: RANGE (array bounds) public: inline AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep); inline AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep); @@ -1248,15 +1201,13 @@ public: }; class AstUnpackArrayDType final : public AstNodeArrayDType { // Array data type, ie "some_dtype var_name [2:0]" - // Children: DTYPE (moved to refDTypep() in V3Width) - // Children: RANGE (array bounds) bool m_isCompound = false; // Non-POD subDType, or parent requires compound public: AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) : ASTGEN_SUPER_UnpackArrayDType(fl) { - childDTypep(dtp); // Only for parser + this->childDTypep(dtp); // Only for parser + this->rangep(rangep); refDTypep(nullptr); - setOp2p((AstNode*)rangep); dtypep(nullptr); // V3Width will resolve // For backward compatibility AstNodeArrayDType and others inherit // width and signing from the subDType/base type @@ -1264,8 +1215,8 @@ public: } AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : ASTGEN_SUPER_UnpackArrayDType(fl) { + this->rangep(rangep); refDTypep(dtp); - setOp2p((AstNode*)rangep); dtypep(this); // For backward compatibility AstNodeArrayDType and others inherit // width and signing from the subDType/base type diff --git a/src/V3AstNodeMath.h b/src/V3AstNodeMath.h index 14e9bd2ab..2d5a6f57f 100644 --- a/src/V3AstNodeMath.h +++ b/src/V3AstNodeMath.h @@ -59,23 +59,20 @@ public: bool isOpaque() const { return VN_IS(this, CvtPackString); } }; class AstNodeBiop VL_NOT_FINAL : public AstNodeMath { - // Binary math + // Binary expression + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode protected: - AstNodeBiop(VNType t, FileLine* fl, AstNode* lhs, AstNode* rhs) + AstNodeBiop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeMath{t, fl} { - setOp1p(lhs); - setOp2p(rhs); + this->lhsp(lhsp); + this->rhsp(rhsp); } public: ASTGEN_MEMBERS_NodeBiop; // Clone single node, just get same type back. virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) = 0; - // ACCESSORS - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } - void lhsp(AstNode* nodep) { return setOp1p(nodep); } - void rhsp(AstNode* nodep) { return setOp2p(nodep); } // METHODS // Set out to evaluation of a AstConst'ed virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) = 0; @@ -110,18 +107,14 @@ public: }; class AstNodeSel VL_NOT_FINAL : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection + // @astgen alias op1 := fromp // Expression we are indexing into + // @astgen alias op2 := bitp // The index // TOOD: rename to idxp protected: AstNodeSel(VNType t, FileLine* fl, AstNode* fromp, AstNode* bitp) : AstNodeBiop{t, fl, fromp, bitp} {} public: ASTGEN_MEMBERS_NodeSel; - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) - void fromp(AstNode* nodep) { setOp1p(nodep); } - AstNode* bitp() const { return op2p(); } // op2 = Msb selection expression - void bitp(AstNode* nodep) { setOp2p(nodep); } int bitConst() const; bool hasDType() const override { return true; } }; @@ -152,26 +145,23 @@ public: bool doubleFlavor() const override { return true; } }; class AstNodeQuadop VL_NOT_FINAL : public AstNodeMath { - // Quaternary math + // 4-ary expression + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode + // @astgen op3 := thsp : AstNode + // @astgen op4 := fhsp : AstNode protected: - AstNodeQuadop(VNType t, FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths, AstNode* fhs) + AstNodeQuadop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp, + AstNode* fhsp) : AstNodeMath{t, fl} { - setOp1p(lhs); - setOp2p(rhs); - setOp3p(ths); - setOp4p(fhs); + this->lhsp(lhsp); + this->rhsp(rhsp); + this->thsp(thsp); + this->fhsp(fhsp); } public: ASTGEN_MEMBERS_NodeQuadop; - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } - AstNode* thsp() const { return op3p(); } - AstNode* fhsp() const { return op4p(); } - void lhsp(AstNode* nodep) { return setOp1p(nodep); } - void rhsp(AstNode* nodep) { return setOp2p(nodep); } - void thsp(AstNode* nodep) { return setOp3p(nodep); } - void fhsp(AstNode* nodep) { return setOp4p(nodep); } // METHODS // Set out to evaluation of a AstConst'ed virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, @@ -203,23 +193,20 @@ public: void dump(std::ostream& str) const override; }; class AstNodeTriop VL_NOT_FINAL : public AstNodeMath { - // Trinary math + // Ternary expression + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode + // @astgen op3 := thsp : AstNode protected: - AstNodeTriop(VNType t, FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths) + AstNodeTriop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) : AstNodeMath{t, fl} { - setOp1p(lhs); - setOp2p(rhs); - setOp3p(ths); + this->lhsp(lhsp); + this->rhsp(rhsp); + this->thsp(thsp); } public: ASTGEN_MEMBERS_NodeTriop; - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } - AstNode* thsp() const { return op3p(); } - void lhsp(AstNode* nodep) { return setOp1p(nodep); } - void rhsp(AstNode* nodep) { return setOp2p(nodep); } - void thsp(AstNode* nodep) { return setOp3p(nodep); } // METHODS void dump(std::ostream& str) const override; // Set out to evaluation of a AstConst'ed @@ -236,13 +223,16 @@ public: bool same(const AstNode*) const override { return true; } }; class AstNodeCond VL_NOT_FINAL : public AstNodeTriop { + // @astgen alias op1 := condp + // @astgen alias op2 := thenp + // @astgen alias op3 := elsep protected: - AstNodeCond(VNType t, FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) - : AstNodeTriop{t, fl, condp, expr1p, expr2p} { - if (expr1p) { - dtypeFrom(expr1p); - } else if (expr2p) { - dtypeFrom(expr2p); + AstNodeCond(VNType t, FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + : AstNodeTriop{t, fl, condp, thenp, elsep} { + if (thenp) { + dtypeFrom(thenp); + } else if (elsep) { + dtypeFrom(elsep); } } @@ -250,9 +240,6 @@ public: ASTGEN_MEMBERS_NodeCond; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) override; - AstNode* condp() const { return op1p(); } // op1 = Condition - AstNode* expr1p() const { return op2p(); } // op2 = If true... - AstNode* expr2p() const { return op3p(); } // op3 = If false... string emitVerilog() override { return "%k(%l %f? %r %k: %t)"; } string emitC() override { return "VL_COND_%nq%lq%rq%tq(%nw, %P, %li, %ri, %ti)"; } bool cleanOut() const override { return false; } // clean if e1 & e2 clean @@ -263,21 +250,20 @@ public: bool sizeMattersRhs() const override { return false; } bool sizeMattersThs() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) = 0; + virtual AstNode* cloneType(AstNode* condp, AstNode* thenp, AstNode* elsep) = 0; }; class AstNodeUniop VL_NOT_FINAL : public AstNodeMath { - // Unary math + // Unary expression + // @astgen op1 := lhsp : AstNode protected: AstNodeUniop(VNType t, FileLine* fl, AstNode* lhsp) : AstNodeMath{t, fl} { dtypeFrom(lhsp); - setOp1p(lhsp); + this->lhsp(lhsp); } public: ASTGEN_MEMBERS_NodeUniop; - AstNode* lhsp() const { return op1p(); } - void lhsp(AstNode* nodep) { return setOp1p(nodep); } // METHODS void dump(std::ostream& str) const override; // Set out to evaluation of a AstConst'ed lhs @@ -383,6 +369,7 @@ public: AstCFunc* funcp() const { return m_funcp; } }; class AstCMath final : public AstNodeMath { + // @astgen op1 := exprsp : List[AstNode] // Expressions to print private: const bool m_cleanOut; bool m_pure; // Pure optimizable @@ -392,7 +379,7 @@ public: : ASTGEN_SUPER_CMath(fl) , m_cleanOut{true} , m_pure{false} { - addOp1p(exprsp); + addExprsp(exprsp); dtypeFrom(exprsp); } inline AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut = true); @@ -403,19 +390,16 @@ public: string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } bool same(const AstNode* /*samep*/) const override { return true; } - void addBodysp(AstNode* nodep) { addNOp1p(nodep); } - AstNode* bodysp() const { return op1p(); } // op1 = expressions to print bool pure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } }; class AstConsAssoc final : public AstNodeMath { // Construct an assoc array and return object, '{} - // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := defaultp : Optional[AstNode] public: AstConsAssoc(FileLine* fl, AstNode* defaultp) : ASTGEN_SUPER_ConsAssoc(fl) { - setNOp1p(defaultp); + this->defaultp(defaultp); } ASTGEN_MEMBERS_ConsAssoc; string emitVerilog() override { return "'{}"; } @@ -423,18 +407,17 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* defaultp() const { return op1p(); } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstConsDynArray final : public AstNodeMath { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} - // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := lhsp : Optional[AstNode] + // @astgen op2 := rhsp : Optional[AstNode] public: explicit AstConsDynArray(FileLine* fl, AstNode* lhsp = nullptr, AstNode* rhsp = nullptr) : ASTGEN_SUPER_ConsDynArray(fl) { - setNOp1p(lhsp); - setNOp2p(rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_ConsDynArray; string emitVerilog() override { return "'{%l, %r}"; } @@ -442,19 +425,17 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* lhsp() const { return op1p(); } // op1 = expression - AstNode* rhsp() const { return op2p(); } // op2 = expression bool same(const AstNode* /*samep*/) const override { return true; } }; class AstConsQueue final : public AstNodeMath { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} - // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := lhsp : Optional[AstNode] + // @astgen op2 := rhsp : Optional[AstNode] public: explicit AstConsQueue(FileLine* fl, AstNode* lhsp = nullptr, AstNode* rhsp = nullptr) : ASTGEN_SUPER_ConsQueue(fl) { - setNOp1p(lhsp); - setNOp2p(rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_ConsQueue; string emitVerilog() override { return "'{%l, %r}"; } @@ -462,18 +443,15 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* lhsp() const { return op1p(); } // op1 = expression - AstNode* rhsp() const { return op2p(); } // op2 = expression bool same(const AstNode* /*samep*/) const override { return true; } }; class AstConsWildcard final : public AstNodeMath { // Construct a wildcard assoc array and return object, '{} - // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := defaultp : Optional[AstNode] public: AstConsWildcard(FileLine* fl, AstNode* defaultp) : ASTGEN_SUPER_ConsWildcard(fl) { - setNOp1p(defaultp); + this->defaultp(defaultp); } ASTGEN_MEMBERS_ConsWildcard; string emitVerilog() override { return "'{}"; } @@ -481,7 +459,6 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* defaultp() const { return op1p(); } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstConst final : public AstNodeMath { @@ -662,18 +639,16 @@ class AstExprStmt final : public AstNodeMath { // Perform a statement, often assignment inside an expression/math node, // the parent gets passed the 'resultp()'. // resultp is evaluated AFTER the statement(s). + // @astgen op1 := stmtsp : List[AstNode] + // @astgen op2 := resultp : AstNode public: AstExprStmt(FileLine* fl, AstNode* stmtsp, AstNode* resultp) : ASTGEN_SUPER_ExprStmt(fl) { - addOp1p(stmtsp); - setOp2p(resultp); // Possibly in future nullptr could mean return rhsp() + addStmtsp(stmtsp); + this->resultp(resultp); dtypeFrom(resultp); } ASTGEN_MEMBERS_ExprStmt; - // ACCESSORS - AstNode* stmtsp() const { return op1p(); } - void addStmtsp(AstNode* nodep) { addOp1p(nodep); } - AstNode* resultp() const { return op2p(); } // METHODS string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } @@ -681,11 +656,13 @@ public: bool same(const AstNode*) const override { return true; } }; class AstFError final : public AstNodeMath { + // @astgen op1 := filep : AstNode + // @astgen op2 := strp : AstNode public: AstFError(FileLine* fl, AstNode* filep, AstNode* strp) : ASTGEN_SUPER_FError(fl) { - setOp1p(filep); - setOp2p(strp); + this->filep(filep); + this->strp(strp); } ASTGEN_MEMBERS_FError; string emitVerilog() override { return "%f$ferror(%l, %r)"; } @@ -695,25 +672,20 @@ public: virtual bool sizeMattersLhs() const { return false; } int instrCount() const override { return widthInstrs() * 64; } bool isPure() const override { return false; } // SPECIAL: $display has 'visual' ordering - void filep(AstNode* nodep) { setOp1p(nodep); } - AstNode* filep() const { return op1p(); } - void strp(AstNode* nodep) { setOp2p(nodep); } - AstNode* strp() const { return op2p(); } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstFRead final : public AstNodeMath { - // Parents: expr - // Children: varrefs to load - // Children: file which must be a varref - // Children: low index - // Children: count + // @astgen op1 := memp : AstNode // VarRef for result + // @astgen op2 := filep : AstNode // file (must be a VarRef) + // @astgen op3 := startp : Optional[AstNode] // Offset + // @astgen op4 := countp : Optional[AstNode] // Size public: AstFRead(FileLine* fl, AstNode* memp, AstNode* filep, AstNode* startp, AstNode* countp) : ASTGEN_SUPER_FRead(fl) { - setOp1p(memp); - setOp2p(filep); - setNOp3p(startp); - setNOp4p(countp); + this->memp(memp); + this->filep(filep); + this->startp(startp); + this->countp(countp); } ASTGEN_MEMBERS_FRead; string verilogKwd() const override { return "$fread"; } @@ -725,22 +697,14 @@ public: bool isOutputter() const override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* memp() const { return op1p(); } - void memp(AstNode* nodep) { setOp1p(nodep); } - AstNode* filep() const { return op2p(); } - void filep(AstNode* nodep) { setOp2p(nodep); } - AstNode* startp() const { return op3p(); } - void startp(AstNode* nodep) { setNOp3p(nodep); } - AstNode* countp() const { return op4p(); } - void countp(AstNode* nodep) { setNOp4p(nodep); } }; class AstFRewind final : public AstNodeMath { // Parents: stmtlist - // Children: file which must be a varref + // @astgen op1 := filep : Optional[AstNode] public: AstFRewind(FileLine* fl, AstNode* filep) : ASTGEN_SUPER_FRewind(fl) { - setNOp2p(filep); + this->filep(filep); } ASTGEN_MEMBERS_FRewind; string verilogKwd() const override { return "$frewind"; } @@ -753,13 +717,10 @@ public: bool isUnlikely() const override { return true; } bool cleanOut() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op2p(); } - void filep(AstNodeVarRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstFScanF final : public AstNodeMath { - // Parents: expr - // Children: file which must be a varref - // Children: varrefs to load + // @astgen op1 := exprsp : List[AstNode] // VarRefs for results + // @astgen op2 := filep : Optional[AstNode] // file (must be a VarRef) private: string m_text; @@ -767,8 +728,8 @@ public: AstFScanF(FileLine* fl, const string& text, AstNode* filep, AstNode* exprsp) : ASTGEN_SUPER_FScanF(fl) , m_text{text} { - addNOp1p(exprsp); - setNOp2p(filep); + addExprsp(exprsp); + this->filep(filep); } ASTGEN_MEMBERS_FScanF; string name() const override { return m_text; } @@ -783,24 +744,19 @@ public: bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); } - AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output - void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text = text; } - AstNode* filep() const { return op2p(); } - void filep(AstNodeVarRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstFSeek final : public AstNodeMath { - // Parents: expr - // Children: file which must be a varref - // Children: offset - // Children: operation + // @astgen op1 := filep : AstNode // file (must be a VarRef) + // @astgen op2 := offset : Optional[AstNode] + // @astgen op3 := operation : Optional[AstNode] public: AstFSeek(FileLine* fl, AstNode* filep, AstNode* offset, AstNode* operation) : ASTGEN_SUPER_FSeek(fl) { - setOp2p(filep); - setNOp3p(offset); - setNOp4p(operation); + this->filep(filep); + this->offset(offset); + this->operation(operation); } ASTGEN_MEMBERS_FSeek; string verilogKwd() const override { return "$fseek"; } @@ -812,20 +768,14 @@ public: bool isOutputter() const override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op2p(); } - void filep(AstNode* nodep) { setOp2p(nodep); } - AstNode* offset() const { return op3p(); } - void offset(AstNode* nodep) { setNOp3p(nodep); } - AstNode* operation() const { return op4p(); } - void operation(AstNode* nodep) { setNOp4p(nodep); } }; class AstFTell final : public AstNodeMath { // Parents: stmtlist - // Children: file which must be a varref + // @astgen op1 := filep : AstNode // file (must be a VarRef) public: AstFTell(FileLine* fl, AstNode* filep) : ASTGEN_SUPER_FTell(fl) { - setNOp2p(filep); + this->filep(filep); } ASTGEN_MEMBERS_FTell; string verilogKwd() const override { return "$ftell"; } @@ -838,17 +788,15 @@ public: bool isUnlikely() const override { return true; } bool cleanOut() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op2p(); } - void filep(AstNodeVarRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstFell final : public AstNodeMath { // Verilog $fell - // Parents: math - // Children: expression + // @astgen op1 := exprp : AstNode + // @astgen op2 := sentreep : Optional[AstSenTree] public: AstFell(FileLine* fl, AstNode* exprp) : ASTGEN_SUPER_Fell(fl) { - addOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_Fell; string emitVerilog() override { return "$fell(%l)"; } @@ -856,35 +804,33 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - AstNode* exprp() const { return op1p(); } // op1 = expression - AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain - void sentreep(AstSenTree* sentreep) { addOp2p((AstNode*)sentreep); } // op2 = clock domain bool same(const AstNode* /*samep*/) const override { return true; } }; class AstGatePin final : public AstNodeMath { // Possibly expand a gate primitive input pin value to match the range of the gate primitive + // @astgen op1 := exprp : AstNode // Pin expression + // @astgen op2 := rangep : AstRange // Range of pin public: - AstGatePin(FileLine* fl, AstNode* lhsp, AstRange* rangep) + AstGatePin(FileLine* fl, AstNode* exprp, AstRange* rangep) : ASTGEN_SUPER_GatePin(fl) { - setOp1p(lhsp); - setOp2p((AstNode*)rangep); + this->exprp(exprp); + this->rangep(rangep); } ASTGEN_MEMBERS_GatePin; string emitVerilog() override { return "%l"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - AstNode* exprp() const { return op1p(); } // op1 = Pin expression - AstRange* rangep() const { return VN_AS(op2p(), Range); } // op2 = Range of pin }; class AstImplication final : public AstNodeMath { // Verilog |-> |=> - // Parents: math - // Children: expression + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode + // @astgen op3 := sentreep : AstSenTree public: - AstImplication(FileLine* fl, AstNode* lhs, AstNode* rhs) + AstImplication(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_Implication(fl) { - setOp1p(lhs); - setOp2p(rhs); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_Implication; string emitVerilog() override { V3ERROR_NA_RETURN(""); } @@ -892,40 +838,33 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } - void lhsp(AstNode* nodep) { return setOp1p(nodep); } - void rhsp(AstNode* nodep) { return setOp2p(nodep); } - AstSenTree* sentreep() const { return VN_AS(op4p(), SenTree); } // op4 = clock domain - void sentreep(AstSenTree* sentreep) { addOp4p((AstNode*)sentreep); } // op4 = clock domain bool same(const AstNode* /*samep*/) const override { return true; } }; class AstInside final : public AstNodeMath { + // @astgen op1 := exprp : AstNode + // @astgen op2 := itemsp : List[AstNode] public: AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp) : ASTGEN_SUPER_Inside(fl) { - addOp1p(exprp); - addOp2p(itemsp); + this->exprp(exprp); + this->addItemsp(itemsp); dtypeSetBit(); } ASTGEN_MEMBERS_Inside; - AstNode* exprp() const { return op1p(); } // op1 = LHS expression to compare with - // op2 = RHS, possibly a list of expr or AstInsideRange - AstNode* itemsp() const { return op2p(); } string emitVerilog() override { return "%l inside { %r }"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return false; } // NA }; class AstInsideRange final : public AstNodeMath { + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode public: AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_InsideRange(fl) { - addOp1p(lhsp); - addOp2p(rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_InsideRange; - AstNode* lhsp() const { return op1p(); } // op1 = LHS - AstNode* rhsp() const { return op2p(); } // op2 = RHS string emitVerilog() override { return "[%l:%r]"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return false; } // NA @@ -958,7 +897,7 @@ public: }; class AstMemberSel final : public AstNodeMath { // Parents: math|stmt - // Children: varref|arraysel, math + // @astgen op1 := fromp : AstNode private: // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it string m_name; @@ -967,13 +906,13 @@ public: AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name) : ASTGEN_SUPER_MemberSel(fl) , m_name{name} { - setOp1p(fromp); + this->fromp(fromp); dtypep(nullptr); // V3Width will resolve } AstMemberSel(FileLine* fl, AstNode* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_MemberSel(fl) , m_name{dtp->name()} { - setOp1p(fromp); + this->fromp(fromp); dtypep(dtp); } ASTGEN_MEMBERS_MemberSel; @@ -986,22 +925,18 @@ public: bool cleanOut() const override { return false; } bool same(const AstNode* samep) const override { return true; } // dtype comparison does it int instrCount() const override { return widthInstrs(); } - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) - void fromp(AstNode* nodep) { setOp1p(nodep); } AstVar* varp() const { return m_varp; } void varp(AstVar* nodep) { m_varp = nodep; } }; class AstNewCopy final : public AstNodeMath { // New as shallow copy // Parents: math|stmt - // Children: varref|arraysel, math + // @astgen op1 := rhsp : AstNode public: AstNewCopy(FileLine* fl, AstNode* rhsp) : ASTGEN_SUPER_NewCopy(fl) { dtypeFrom(rhsp); // otherwise V3Width will resolve - setNOp1p(rhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_NewCopy; string emitVerilog() override { return "new"; } @@ -1009,18 +944,18 @@ public: bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* rhsp() const { return op1p(); } }; class AstNewDynamic final : public AstNodeMath { // New for dynamic array // Parents: math|stmt - // Children: varref|arraysel, math + // @astgen op1 := sizep : AstNode + // @astgen op2 := rhsp : Optional[AstNode] public: AstNewDynamic(FileLine* fl, AstNode* sizep, AstNode* rhsp) : ASTGEN_SUPER_NewDynamic(fl) { dtypeFrom(rhsp); // otherwise V3Width will resolve - setNOp1p(sizep); - setNOp2p(rhsp); + this->sizep(sizep); + this->rhsp(rhsp); } ASTGEN_MEMBERS_NewDynamic; string emitVerilog() override { return "new"; } @@ -1028,18 +963,17 @@ public: bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* sizep() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } }; class AstPast final : public AstNodeMath { // Verilog $past - // Parents: math - // Children: expression + // @astgen op1 := exprp : AstNode + // @astgen op2 := ticksp : Optional[AstNode] + // @astgen op3 := sentreep : Optional[AstSenTree] public: AstPast(FileLine* fl, AstNode* exprp, AstNode* ticksp) : ASTGEN_SUPER_Past(fl) { - addOp1p(exprp); - addNOp2p(ticksp); + this->exprp(exprp); + this->ticksp(ticksp); } ASTGEN_MEMBERS_Past; string emitVerilog() override { V3ERROR_NA_RETURN(""); } @@ -1047,23 +981,25 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - AstNode* exprp() const { return op1p(); } // op1 = expression - AstNode* ticksp() const { return op2p(); } // op2 = ticks or nullptr means 1 - AstSenTree* sentreep() const { return VN_AS(op4p(), SenTree); } // op4 = clock domain - void sentreep(AstSenTree* sentreep) { addOp4p((AstNode*)sentreep); } // op4 = clock domain bool same(const AstNode* /*samep*/) const override { return true; } }; class AstPatMember final : public AstNodeMath { // Verilog '{a} or '{a{b}} // Parents: AstPattern // Children: expression, AstPattern, replication count + // Expression to assign or another AstPattern (list if replicated) + // @astgen op1 := lhssp : List[AstNode] + // @astgen op2 := keyp : Optional[AstNode] + // @astgen op3 := repp : Optional[AstNode] // replication count, or nullptr for count 1 private: bool m_default = false; public: - AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp) + AstPatMember(FileLine* fl, AstNode* lhssp, AstNode* keyp, AstNode* repp) : ASTGEN_SUPER_PatMember(fl) { - addOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); + this->addLhssp(lhssp); + this->keyp(keyp); + this->repp(repp); } ASTGEN_MEMBERS_PatMember; string emitVerilog() override { return lhssp() ? "%f{%r{%k%l}}" : "%l"; } @@ -1072,10 +1008,6 @@ public: bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs() * 2; } void dump(std::ostream& str = std::cout) const override; - // op1 = expression to assign or another AstPattern (list if replicated) - AstNode* lhssp() const { return op1p(); } - AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text) - AstNode* repp() const { return op3p(); } // op3 = replication count, or nullptr for count 1 bool isDefault() const { return m_default; } void isDefault(bool flag) { m_default = flag; } }; @@ -1083,10 +1015,12 @@ class AstPattern final : public AstNodeMath { // Verilog '{a,b,c,d...} // Parents: AstNodeAssign, AstPattern, ... // Children: expression, AstPattern, AstPatReplicate + // @astgen op1 := childDTypep : Optional[AstNodeDType] + // @astgen op2 := itemsp : List[AstNode] // AstPatReplicate, AstPatMember, etc public: AstPattern(FileLine* fl, AstNode* itemsp) : ASTGEN_SUPER_Pattern(fl) { - addNOp2p(itemsp); + addItemsp(itemsp); } ASTGEN_MEMBERS_Pattern; string emitVerilog() override { V3ERROR_NA_RETURN(""); } @@ -1096,15 +1030,11 @@ public: int instrCount() const override { return widthInstrs(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } - // op1 = Type assigning to - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } - AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc - void addItemsp(AstNode* nodep) { addOp2p(nodep); } }; class AstRand final : public AstNodeMath { // $random/$random(seed) or $urandom/$urandom(seed) // Return a random number, based upon width() + // @astgen op1 := seedp : Optional[AstNode] private: const bool m_urandom = false; // $urandom vs $random const bool m_reset = false; // Random reset, versus always random @@ -1118,7 +1048,7 @@ public: AstRand(FileLine* fl, AstNode* seedp, bool urandom) : ASTGEN_SUPER_Rand(fl) , m_urandom{urandom} { - setNOp1p(seedp); + this->seedp(seedp); } ASTGEN_MEMBERS_Rand; string emitVerilog() override { @@ -1141,18 +1071,17 @@ public: return !seedp() && !samep->seedp() && reset() == samep->reset() && urandom() == samep->urandom(); } - AstNode* seedp() const { return op1p(); } bool reset() const { return m_reset; } bool urandom() const { return m_urandom; } }; class AstRose final : public AstNodeMath { // Verilog $rose - // Parents: math - // Children: expression + // @astgen op1 := exprp : AstNode + // @astgen op2 := sentreep : Optional[AstSenTree] public: AstRose(FileLine* fl, AstNode* exprp) : ASTGEN_SUPER_Rose(fl) { - addOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_Rose; string emitVerilog() override { return "$rose(%l)"; } @@ -1160,15 +1089,11 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - AstNode* exprp() const { return op1p(); } // op1 = expression - AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain - void sentreep(AstSenTree* sentreep) { addOp2p((AstNode*)sentreep); } // op2 = clock domain bool same(const AstNode* /*samep*/) const override { return true; } }; class AstSScanF final : public AstNodeMath { - // Parents: expr - // Children: file which must be a varref - // Children: varrefs to load + // @astgen op1 := exprsp : List[AstNode] // VarRefs for results + // @astgen op2 := fromp : AstNode private: string m_text; @@ -1176,8 +1101,8 @@ public: AstSScanF(FileLine* fl, const string& text, AstNode* fromp, AstNode* exprsp) : ASTGEN_SUPER_SScanF(fl) , m_text{text} { - addNOp1p(exprsp); - setOp2p(fromp); + this->addExprsp(exprsp); + this->fromp(fromp); } ASTGEN_MEMBERS_SScanF; string name() const override { return m_text; } @@ -1192,21 +1117,16 @@ public: bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); } - AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output - void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text = text; } - AstNode* fromp() const { return op2p(); } - void fromp(AstNode* nodep) { setOp2p(nodep); } }; class AstSampled final : public AstNodeMath { // Verilog $sampled - // Parents: math - // Children: expression + // @astgen op1 := exprp : AstNode public: AstSampled(FileLine* fl, AstNode* exprp) : ASTGEN_SUPER_Sampled(fl) { - addOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_Sampled; string emitVerilog() override { return "$sampled(%l)"; } @@ -1214,13 +1134,13 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return 0; } - AstNode* exprp() const { return op1p(); } // op1 = expression bool same(const AstNode* /*samep*/) const override { return true; } }; class AstScopeName final : public AstNodeMath { // For display %m and DPI context imports // Parents: DISPLAY - // Children: TEXT + // @astgen op1 := scopeAttrp : List[AstText] + // @astgen op2 := scopeEntrp : List[AstText] private: bool m_dpiExport = false; // Is for dpiExport const bool m_forFormat = false; // Is for a format %m @@ -1243,10 +1163,6 @@ public: string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } void dump(std::ostream& str = std::cout) const override; - AstText* scopeAttrp() const { return VN_AS(op1p(), Text); } - void scopeAttrp(AstNode* nodep) { addOp1p(nodep); } - AstText* scopeEntrp() const { return VN_AS(op2p(), Text); } - void scopeEntrp(AstNode* nodep) { addOp2p(nodep); } string scopeSymName() const { // Name for __Vscope variable including children return scopeNameFormatter(scopeAttrp()); } @@ -1266,13 +1182,15 @@ public: class AstSetAssoc final : public AstNodeMath { // Set an assoc array element and return object, '{} // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := lhsp : AstNode + // @astgen op2 := keyp : Optional[AstNode] + // @astgen op3 := valuep : AstNode public: AstSetAssoc(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* valuep) : ASTGEN_SUPER_SetAssoc(fl) { - setOp1p(lhsp); - setNOp2p(keyp); - setOp3p(valuep); + this->lhsp(lhsp); + this->keyp(keyp); + this->valuep(valuep); } ASTGEN_MEMBERS_SetAssoc; string emitVerilog() override { return "'{}"; } @@ -1280,21 +1198,20 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* lhsp() const { return op1p(); } - AstNode* keyp() const { return op2p(); } - AstNode* valuep() const { return op3p(); } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstSetWildcard final : public AstNodeMath { // Set a wildcard assoc array element and return object, '{} // Parents: math - // Children: expression (elements or other queues) + // @astgen op1 := lhsp : AstNode + // @astgen op2 := keyp : Optional[AstNode] + // @astgen op3 := valuep : AstNode public: AstSetWildcard(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* valuep) : ASTGEN_SUPER_SetWildcard(fl) { - setOp1p(lhsp); - setNOp2p(keyp); - setOp3p(valuep); + this->lhsp(lhsp); + this->keyp(keyp); + this->valuep(valuep); } ASTGEN_MEMBERS_SetWildcard; string emitVerilog() override { return "'{}"; } @@ -1302,19 +1219,16 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - AstNode* lhsp() const { return op1p(); } - AstNode* keyp() const { return op2p(); } - AstNode* valuep() const { return op3p(); } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstStable final : public AstNodeMath { // Verilog $stable - // Parents: math - // Children: expression + // @astgen op1 := exprp : AstNode + // @astgen op2 := sentreep : Optional[AstSenTree] public: AstStable(FileLine* fl, AstNode* exprp) : ASTGEN_SUPER_Stable(fl) { - addOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_Stable; string emitVerilog() override { return "$stable(%l)"; } @@ -1322,17 +1236,15 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - AstNode* exprp() const { return op1p(); } // op1 = expression - AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain - void sentreep(AstSenTree* sentreep) { addOp2p((AstNode*)sentreep); } // op2 = clock domain bool same(const AstNode* /*samep*/) const override { return true; } }; class AstSystemF final : public AstNodeMath { // $system used as function + // @astgen op1 := lhsp : AstNode public: AstSystemF(FileLine* fl, AstNode* lhsp) : ASTGEN_SUPER_SystemF(fl) { - setOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_SystemF; string verilogKwd() const override { return "$system"; } @@ -1345,15 +1257,14 @@ public: bool isUnlikely() const override { return true; } bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* lhsp() const { return op1p(); } }; class AstTestPlusArgs final : public AstNodeMath { - // Parents: expr - // Child: variable to set. If nullptr then this is a $test$plusargs instead of $value$plusargs + // Search expression. If nullptr then this is a $test$plusargs instead of $value$plusargs. + // @astgen op1 := searchp : Optional[AstNode] public: AstTestPlusArgs(FileLine* fl, AstNode* searchp) : ASTGEN_SUPER_TestPlusArgs(fl) { - setOp1p(searchp); + this->searchp(searchp); } ASTGEN_MEMBERS_TestPlusArgs; string verilogKwd() const override { return "$test$plusargs"; } @@ -1363,22 +1274,20 @@ public: bool isPredictOptimizable() const override { return false; } bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* searchp() const { return op1p(); } // op1 = Search expression - void searchp(AstNode* nodep) { setOp1p(nodep); } }; class AstUCFunc final : public AstNodeMath { // User's $c function // Perhaps this should be an AstNodeListop; but there's only one list math right now + // @astgen op1 := exprsp : List[AstNode] // Expressions to print public: AstUCFunc(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_UCFunc(fl) { - addNOp1p(exprsp); + this->addExprsp(exprsp); } ASTGEN_MEMBERS_UCFunc; bool cleanOut() const override { return false; } string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } - AstNode* bodysp() const { return op1p(); } // op1 = expressions to print bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs bool isOutputter() const override { return true; } bool isGateOptimizable() const override { return false; } @@ -1401,13 +1310,14 @@ public: bool cleanOut() const override { return true; } }; class AstValuePlusArgs final : public AstNodeMath { - // Parents: expr - // Child: variable to set. If nullptr then this is a $test$plusargs instead of $value$plusargs + // Search expression. If nullptr then this is a $test$plusargs instead of $value$plusargs. + // @astgen op1 := searchp : Optional[AstNode] + // @astgen op2 := outp : AstNode // VarRef for result public: AstValuePlusArgs(FileLine* fl, AstNode* searchp, AstNode* outp) : ASTGEN_SUPER_ValuePlusArgs(fl) { - setOp1p(searchp); - setOp2p(outp); + this->searchp(searchp); + this->outp(outp); } ASTGEN_MEMBERS_ValuePlusArgs; string verilogKwd() const override { return "$value$plusargs"; } @@ -1418,10 +1328,6 @@ public: bool isPure() const override { return !outp(); } bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* searchp() const { return op1p(); } // op1 = Search expression - void searchp(AstNode* nodep) { setOp1p(nodep); } - AstNode* outp() const { return op2p(); } // op2 = Expressions to output - void outp(AstNode* nodep) { setOp2p(nodep); } }; // === AstNodeBiop === @@ -2396,6 +2302,8 @@ public: class AstReplicate final : public AstNodeBiop { // Also used as a "Uniop" flavor of Concat, e.g. "{a}" // Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp() + // @astgen alias op1 := srcp + // @astgen alias op2 := countp public: AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) { @@ -3407,8 +3315,9 @@ class AstSel final : public AstNodeTriop { // Multiple bit range extraction // Parents: math|stmt // Children: varref|arraysel, math, constant math - // Tempting to have an access() style method here as LHS selects are quite - // different, but that doesn't play well with V3Inst and bidirects which don't know direction + // @astgen alias op1 := fromp + // @astgen alias op2 := lsbp + // @astgen alias op3 := widthp private: VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid int m_declElWidth; // If a packed array, the number of bits per element @@ -3446,11 +3355,6 @@ public: bool sizeMattersThs() const override { return false; } bool same(const AstNode*) const override { return true; } int instrCount() const override { return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10); } - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) - AstNode* lsbp() const { return op2p(); } // op2 = Msb selection expression - AstNode* widthp() const { return op3p(); } // op3 = Width int widthConst() const { return VN_AS(widthp(), Const)->toSInt(); } int lsbConst() const { return VN_AS(lsbp(), Const)->toSInt(); } int msbConst() const { return lsbConst() + widthConst() - 1; } @@ -3463,7 +3367,7 @@ public: class AstSliceSel final : public AstNodeTriop { // Multiple array element extraction // Parents: math|stmt - // Children: varref|arraysel, math, constant math + // @astgen alias op1 := fromp private: VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid public: @@ -3488,9 +3392,6 @@ public: bool sizeMattersThs() const override { return false; } bool same(const AstNode*) const override { return true; } int instrCount() const override { return 10; } // Removed before matters - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) // For widthConst()/loConst etc, see declRange().elements() and other VNumRange methods VNumRange& declRange() { return m_declRange; } const VNumRange& declRange() const { return m_declRange; } @@ -3527,11 +3428,11 @@ class AstCond final : public AstNodeCond { // Parents: MATH // Children: MATH public: - AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) - : ASTGEN_SUPER_Cond(fl, condp, expr1p, expr2p) {} + AstCond(FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + : ASTGEN_SUPER_Cond(fl, condp, thenp, elsep) {} ASTGEN_MEMBERS_Cond; - AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) override { - return new AstCond(this->fileline(), condp, expr1p, expr2p); + AstNode* cloneType(AstNode* condp, AstNode* thenp, AstNode* elsep) override { + return new AstCond(this->fileline(), condp, thenp, elsep); } }; class AstCondBound final : public AstNodeCond { @@ -3539,11 +3440,11 @@ class AstCondBound final : public AstNodeCond { // Parents: MATH // Children: MATH public: - AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) - : ASTGEN_SUPER_CondBound(fl, condp, expr1p, expr2p) {} + AstCondBound(FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + : ASTGEN_SUPER_CondBound(fl, condp, thenp, elsep) {} ASTGEN_MEMBERS_CondBound; - AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) override { - return new AstCondBound(this->fileline(), condp, expr1p, expr2p); + AstNode* cloneType(AstNode* condp, AstNode* thenp, AstNode* elsep) override { + return new AstCondBound(this->fileline(), condp, thenp, elsep); } }; diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index e3d56b736..12b832507 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -32,8 +32,8 @@ class AstNodeBlock VL_NOT_FINAL : public AstNode { // A Begin/fork block + // @astgen op1 := stmtsp : List[AstNode] // Parents: statement - // Children: statements private: string m_name; // Name of block bool m_unnamed; // Originally unnamed (name change does not affect this) @@ -41,7 +41,7 @@ protected: AstNodeBlock(VNType t, FileLine* fl, const string& name, AstNode* stmtsp) : AstNode{t, fl} , m_name{name} { - addNOp1p(stmtsp); + addStmtsp(stmtsp); m_unnamed = (name == ""); } @@ -50,13 +50,18 @@ public: void dump(std::ostream& str) const override; string name() const override { return m_name; } // * = Block name void name(const string& name) override { m_name = name; } - // op1 = Statements - AstNode* stmtsp() const { return op1p(); } // op1 = List of statements - void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } bool unnamed() const { return m_unnamed; } bool isFirstInMyListOfStatements(AstNode* nodep) const override { return nodep == stmtsp(); } }; class AstNodeFTask VL_NOT_FINAL : public AstNode { + // Output variable in functions, nullptr in tasks + // @astgen op1 := fvarp : Optional[AstNode] + // Class/package scope + // @astgen op2 := classOrPackagep : Optional[AstNode] + // Statements/Ports/Vars + // @astgen op3 := stmtsp : List[AstNode] + // Scope name + // @astgen op4 := scopeNamep : Optional[AstScopeName] private: string m_name; // Name of task string m_cname; // Name of task if DPI import @@ -106,7 +111,7 @@ protected: , m_recursive{false} , m_underGenerate{false} , m_virtual{false} { - addNOp3p(stmtsp); + addStmtsp(stmtsp); cname(name); // Might be overridden by dpi import/export } @@ -120,23 +125,11 @@ public: void name(const string& name) override { m_name = name; } string cname() const { return m_cname; } void cname(const string& cname) { m_cname = cname; } - // op1 = Output variable (functions only, nullptr for tasks) - AstNode* fvarp() const { return op1p(); } - void addFvarp(AstNode* nodep) { addNOp1p(nodep); } bool isFunction() const { return fvarp() != nullptr; } - // op2 = Class/package scope - AstNode* classOrPackagep() const { return op2p(); } - void classOrPackagep(AstNode* nodep) { setNOp2p(nodep); } - // op3 = Statements/Ports/Vars - AstNode* stmtsp() const { return op3p(); } // op3 = List of statements - void addStmtsp(AstNode* nodep) { addNOp3p(nodep); } - // op4 = scope name - AstScopeName* scopeNamep() const { return VN_AS(op4p(), ScopeName); } // MORE ACCESSORS void dpiOpenParentInc() { ++m_dpiOpenParent; } void dpiOpenParentClear() { m_dpiOpenParent = 0; } uint64_t dpiOpenParent() const { return m_dpiOpenParent; } - void scopeNamep(AstNode* nodep) { setNOp4p(nodep); } void taskPublic(bool flag) { m_taskPublic = flag; } bool taskPublic() const { return m_taskPublic; } void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } @@ -184,7 +177,7 @@ public: class AstNodeFile VL_NOT_FINAL : public AstNode { // Emitted Otput file // Parents: NETLIST - // Children: AstTextBlock + // @astgen op1 := tblockp : Optional[AstTextBlock] private: string m_name; ///< Filename public: @@ -195,13 +188,14 @@ public: void dump(std::ostream& str) const override; string name() const override { return m_name; } bool same(const AstNode* /*samep*/) const override { return true; } - void tblockp(AstTextBlock* tblockp) { setOp1p((AstNode*)tblockp); } - AstTextBlock* tblockp() { return VN_AS(op1p(), TextBlock); } }; class AstNodeModule VL_NOT_FINAL : public AstNode { // A module, package, program or interface declaration; // something that can live directly under the TOP, // excluding $unit package stuff + // @astgen op1 := inlinesp : List[AstNode] + // @astgen op2 := stmtsp : List[AstNode] + // @astgen op3 := activesp : List[AstActive] private: string m_name; // Name of the module const string m_origName; // Name of the module, ignoring name() changes, for dot lookup @@ -239,12 +233,6 @@ public: bool maybePointedTo() const override { return true; } string name() const override { return m_name; } virtual bool timescaleMatters() const = 0; - AstNode* stmtsp() const { return op2p(); } // op2 = List of statements - AstActive* activesp() const { return VN_AS(op3p(), Active); } // op3 = List of i/sblocks - // METHODS - void addInlinesp(AstNode* nodep) { addOp1p(nodep); } - void addStmtp(AstNode* nodep) { addNOp2p(nodep); } - void addActivep(AstNode* nodep) { addOp3p(nodep); } // ACCESSORS void name(const string& name) override { m_name = name; } string origName() const override { return m_origName; } @@ -278,42 +266,37 @@ public: }; class AstNodePreSel VL_NOT_FINAL : public AstNode { // Something that becomes an AstSel + // @astgen op1 := fromp : AstNode + // @astgen op2 := rhsp : AstNode + // @astgen op3 := thsp : Optional[AstNode] + // @astgen op4 := attrp : Optional[AstAttrOf] protected: - AstNodePreSel(VNType t, FileLine* fl, AstNode* fromp, AstNode* rhs, AstNode* ths) + AstNodePreSel(VNType t, FileLine* fl, AstNode* fromp, AstNode* rhsp, AstNode* thsp) : AstNode{t, fl} { - setOp1p(fromp); - setOp2p(rhs); - setNOp3p(ths); + this->fromp(fromp); + this->rhsp(rhsp); + this->thsp(thsp); } public: ASTGEN_MEMBERS_NodePreSel; - AstNode* fromp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } - AstNode* thsp() const { return op3p(); } - AstAttrOf* attrp() const { return VN_AS(op4p(), AttrOf); } - void fromp(AstNode* nodep) { return setOp1p(nodep); } - void rhsp(AstNode* nodep) { return setOp2p(nodep); } - void thsp(AstNode* nodep) { return setOp3p(nodep); } - void attrp(AstAttrOf* nodep) { return setOp4p(reinterpret_cast(nodep)); } // METHODS bool same(const AstNode*) const override { return true; } }; class AstNodeProcedure VL_NOT_FINAL : public AstNode { // IEEE procedure: initial, final, always + // @astgen op2 := stmtsp : List[AstNode] // Note: op1 is used in some sub-types only protected: - AstNodeProcedure(VNType t, FileLine* fl, AstNode* bodysp) + AstNodeProcedure(VNType t, FileLine* fl, AstNode* stmtsp) : AstNode{t, fl} { - addNOp2p(bodysp); + addStmtsp(stmtsp); } public: ASTGEN_MEMBERS_NodeProcedure; // METHODS void dump(std::ostream& str) const override; - AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate - void addStmtp(AstNode* nodep) { addOp2p(nodep); } - bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } + bool isJustOneBodyStmt() const { return stmtsp() && !stmtsp()->nextp(); } }; class AstNodeRange VL_NOT_FINAL : public AstNode { // A range, sized or unsized @@ -345,13 +328,17 @@ public: void dump(std::ostream& str = std::cout) const override; }; class AstNodeAssign VL_NOT_FINAL : public AstNodeStmt { + // Iteration is in order, and we want rhsp to be visited first (which is the execution order) + // @astgen op1 := rhsp : AstNode + // @astgen op2 := lhsp : AstNode + // @astgen op3 := timingControlp : Optional[AstNode] protected: AstNodeAssign(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* timingControlp = nullptr) : AstNodeStmt{t, fl} { - setOp1p(rhsp); - setOp2p(lhsp); - addNOp3p(timingControlp); + this->rhsp(rhsp); + this->lhsp(lhsp); + this->timingControlp(timingControlp); dtypeFrom(lhsp); } @@ -359,14 +346,6 @@ public: ASTGEN_MEMBERS_NodeAssign; // Clone single node, just get same type back. virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) = 0; - // So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2 - AstNode* rhsp() const { return op1p(); } // op1 = Assign from - AstNode* lhsp() const { return op2p(); } // op2 = Assign to - // op3 = Timing controls (delays, event controls) - AstNode* timingControlp() const { return op3p(); } - void addTimingControlp(AstNode* const np) { addNOp3p(np); } - void rhsp(AstNode* np) { setOp1p(np); } - void lhsp(AstNode* np) { setOp2p(np); } bool hasDType() const override { return true; } virtual bool cleanRhs() const { return true; } int instrCount() const override { return widthInstrs(); } @@ -376,6 +355,8 @@ public: }; class AstNodeCCall VL_NOT_FINAL : public AstNodeStmt { // A call of a C++ function, perhaps a AstCFunc or perhaps globally named + // @astgen op2 := argsp : List[AstNode] // Note: op1 used by some sub-types only + // // Functions are not statements, while tasks are. AstNodeStmt needs isStatement() to deal. AstCFunc* m_funcp; string m_argTypes; @@ -384,7 +365,7 @@ protected: AstNodeCCall(VNType t, FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr) : AstNodeStmt{t, fl, true} , m_funcp{funcp} { - addNOp2p(argsp); + addArgsp(argsp); } public: @@ -397,7 +378,6 @@ public: const AstNodeCCall* const asamep = static_cast(samep); return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes()); } - AstNode* exprsp() const { return op2p(); } // op2 = expressions to print bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool isPure() const override; @@ -406,34 +386,29 @@ public: void funcp(AstCFunc* funcp) { m_funcp = funcp; } void argTypes(const string& str) { m_argTypes = str; } string argTypes() const { return m_argTypes; } - // op1p reserved for AstCMethodCall - AstNode* argsp() const { return op2p(); } - void addArgsp(AstNode* nodep) { addOp2p(nodep); } }; class AstNodeCase VL_NOT_FINAL : public AstNodeStmt { + // @astgen op1 := exprp : AstNode // Condition (scurtinee) expression + // @astgen op2 := itemsp : List[AstCaseItem] + // @astgen op3 := notParallelp : List[AstNode] // assertion code for non-full case's protected: - AstNodeCase(VNType t, FileLine* fl, AstNode* exprp, AstNode* casesp) + AstNodeCase(VNType t, FileLine* fl, AstNode* exprp, AstCaseItem* itemsp) : AstNodeStmt{t, fl} { - setOp1p(exprp); - addNOp2p(casesp); + this->exprp(exprp); + this->addItemsp(itemsp); } public: ASTGEN_MEMBERS_NodeCase; int instrCount() const override { return INSTR_COUNT_BRANCH; } - AstNode* exprp() const { return op1p(); } // op1 = case condition - AstCaseItem* itemsp() const { - return VN_AS(op2p(), CaseItem); - } // op2 = list of case expressions - AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's - void addItemsp(AstNode* nodep) { addOp2p(nodep); } - void addNotParallelp(AstNode* nodep) { setOp3p(nodep); } }; class AstNodeCoverOrAssert VL_NOT_FINAL : public AstNodeStmt { // Cover or Assert // Parents: {statement list} - // Children: expression, report string -private: + // @astgen op1 := propp : AstNode + // @astgen op2 := sentreep : Optional[AstSenTree] + // op3 used by some sub-types only + // @astgen op4 := passsp: List[AstNode] // Statments when propp is passing/truthly const bool m_immediate; // Immediate assertion/cover string m_name; // Name to report public: @@ -442,22 +417,23 @@ public: : AstNodeStmt{t, fl} , m_immediate{immediate} , m_name{name} { - addOp1p(propp); - addNOp4p(passsp); + this->propp(propp); + this->addPasssp(passsp); } ASTGEN_MEMBERS_NodeCoverOrAssert; string name() const override { return m_name; } // * = Var name bool same(const AstNode* samep) const override { return samep->name() == name(); } void name(const string& name) override { m_name = name; } void dump(std::ostream& str = std::cout) const override; - AstNode* propp() const { return op1p(); } // op1 = property - AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain - void sentreep(AstSenTree* sentreep) { addOp2p((AstNode*)sentreep); } // op2 = clock domain - AstNode* passsp() const { return op4p(); } // op4 = statements (assert/cover passes) bool immediate() const { return m_immediate; } }; class AstNodeFTaskRef VL_NOT_FINAL : public AstNodeStmt { // A reference to a task (or function) + // @astgen op1 := namep : AstNode + // op2 used by some sub-types only + // @astgen op3 := pinsp : List[AstNode] + // @astgen op4 := scopeNamep : Optional[AstScopeName] + // // Functions are not statements, while tasks are. AstNodeStmt needs isStatement() to deal. private: AstNodeFTask* m_taskp = nullptr; // [AfterLink] Pointer to task referenced @@ -469,13 +445,13 @@ private: protected: AstNodeFTaskRef(VNType t, FileLine* fl, bool statement, AstNode* namep, AstNode* pinsp) : AstNodeStmt{t, fl, statement} { - setOp1p(namep); - addNOp3p(pinsp); + this->namep(namep); + this->addPinsp(pinsp); } AstNodeFTaskRef(VNType t, FileLine* fl, bool statement, const string& name, AstNode* pinsp) : AstNodeStmt{t, fl, statement} , m_name{name} { - addNOp3p(pinsp); + this->addPinsp(pinsp); } public: @@ -496,58 +472,46 @@ public: void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } bool pli() const { return m_pli; } void pli(bool flag) { m_pli = flag; } - // op1 = namep - AstNode* namep() const { return op1p(); } - // op2 = reserved for AstMethodCall - // op3 = Pin interconnection list - AstNode* pinsp() const { return op3p(); } - void addPinsp(AstNode* nodep) { addOp3p(nodep); } - // op4 = scope tracking - AstScopeName* scopeNamep() const { return VN_AS(op4p(), ScopeName); } - void scopeNamep(AstNode* nodep) { setNOp4p(nodep); } }; class AstNodeFor VL_NOT_FINAL : public AstNodeStmt { + // @astgen op1 := initsp : List[AstNode] + // @astgen op2 := condp : AstNode + // @astgen op3 := incsp : List[AstNode] + // @astgen op4 := stmtsp : List[AstNode] protected: AstNodeFor(VNType t, FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, - AstNode* bodysp) + AstNode* stmtsp) : AstNodeStmt{t, fl} { - addNOp1p(initsp); - setOp2p(condp); - addNOp3p(incsp); - addNOp4p(bodysp); + this->addInitsp(initsp); + this->condp(condp); + this->addIncsp(incsp); + this->addStmtsp(stmtsp); } public: ASTGEN_MEMBERS_NodeFor; - AstNode* initsp() const { return op1p(); } // op1 = initial statements - AstNode* condp() const { return op2p(); } // op2 = condition to continue - AstNode* incsp() const { return op3p(); } // op3 = increment statements - AstNode* bodysp() const { return op4p(); } // op4 = body of loop bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } bool same(const AstNode* /*samep*/) const override { return true; } }; class AstNodeIf VL_NOT_FINAL : public AstNodeStmt { + // @astgen op1 := condp : AstNode + // @astgen op2 := thensp : List[AstNode] + // @astgen op3 := elsesp : List[AstNode] private: VBranchPred m_branchPred; // Branch prediction as taken/untaken? bool m_isBoundsCheck; // True if this if node was inserted for array bounds checking protected: - AstNodeIf(VNType t, FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp) + AstNodeIf(VNType t, FileLine* fl, AstNode* condp, AstNode* thensp, AstNode* elsesp) : AstNodeStmt{t, fl} { - setOp1p(condp); - addNOp2p(ifsp); - addNOp3p(elsesp); + this->condp(condp); + this->addThensp(thensp); + this->addElsesp(elsesp); isBoundsCheck(false); } public: ASTGEN_MEMBERS_NodeIf; - AstNode* condp() const { return op1p(); } // op1 = condition - AstNode* ifsp() const { return op2p(); } // op2 = list of true statements - AstNode* elsesp() const { return op3p(); } // op3 = list of false statements - void condp(AstNode* newp) { setOp1p(newp); } - void addIfsp(AstNode* newp) { addOp2p(newp); } - void addElsesp(AstNode* newp) { addOp3p(newp); } bool isGateOptimizable() const override { return false; } bool isGateDedupable() const override { return true; } int instrCount() const override { return INSTR_COUNT_BRANCH; } @@ -557,21 +521,25 @@ public: void isBoundsCheck(bool flag) { m_isBoundsCheck = flag; } bool isBoundsCheck() const { return m_isBoundsCheck; } bool isFirstInMyListOfStatements(AstNode* n) const override { - return n == ifsp() || n == elsesp(); + return n == thensp() || n == elsesp(); } }; class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt { -private: + // @astgen op1 := filenamep : AstNode + // @astgen op2 := memp : AstNode + // @astgen op3 := lsbp : Optional[AstNode] + // @astgen op4 := msbp : Optional[AstNode] + const bool m_isHex; // readmemh, not readmemb public: AstNodeReadWriteMem(VNType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp) : AstNodeStmt(t, fl) , m_isHex(hex) { - setOp1p(filenamep); - setOp2p(memp); - setNOp3p(lsbp); - setNOp4p(msbp); + this->filenamep(filenamep); + this->memp(memp); + this->lsbp(lsbp); + this->msbp(msbp); } ASTGEN_MEMBERS_NodeReadWriteMem; bool isGateOptimizable() const override { return false; } @@ -583,10 +551,6 @@ public: return isHex() == static_cast(samep)->isHex(); } bool isHex() const { return m_isHex; } - AstNode* filenamep() const { return op1p(); } - AstNode* memp() const { return op2p(); } - AstNode* lsbp() const { return op3p(); } - AstNode* msbp() const { return op4p(); } virtual const char* cFuncPrefixp() const = 0; }; class AstNodeText VL_NOT_FINAL : public AstNode { @@ -626,7 +590,8 @@ public: class AstActive final : public AstNode { // Block of code with sensitivity activation // Parents: MODULE | CFUNC - // Children: SENTREE, statements + // @astgen op1 := sensesStorep : Optional[AstSenTree] // Moved into m_sensesp in V3Active + // @astgen op2 := stmtsp : List[AstNode] // Logic private: string m_name; AstSenTree* m_sensesp; @@ -646,12 +611,6 @@ public: // Statements are broken into pieces, as some must come before others. void sensesp(AstSenTree* nodep) { m_sensesp = nodep; } AstSenTree* sensesp() const { return m_sensesp; } - // op1 = Sensitivity tree, if a clocked block in early stages - void sensesStorep(AstSenTree* nodep) { addOp1p((AstNode*)nodep); } - AstSenTree* sensesStorep() const { return VN_AS(op1p(), SenTree); } - // op2 = Combo logic - AstNode* stmtsp() const { return op2p(); } - void addStmtsp(AstNode* nodep) { addOp2p(nodep); } // METHODS inline bool hasInitial() const; inline bool hasSettle() const; @@ -659,42 +618,39 @@ public: }; class AstArg final : public AstNode { // An argument to a function/task -private: + // @astgen op1 := exprp : Optional[AstNode] // nullptr if omitted string m_name; // Pin name, or "" for number based interconnect public: AstArg(FileLine* fl, const string& name, AstNode* exprp) : ASTGEN_SUPER_Arg(fl) , m_name{name} { - setNOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_Arg; string name() const override { return m_name; } // * = Pin name, ""=go by number void name(const string& name) override { m_name = name; } - void exprp(AstNode* nodep) { addOp1p(nodep); } - // op1 = Expression connected to pin, nullptr if unconnected - AstNode* exprp() const { return op1p(); } bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); } }; class AstAttrOf final : public AstNode { -private: // Return a value of a attribute, for example a LSB or array LSB of a signal + // @astgen op1 := fromp : Optional[AstNode] + // @astgen op2 := dimp : Optional[AstNode] VAttrType m_attrType; // What sort of extraction public: AstAttrOf(FileLine* fl, VAttrType attrtype, AstNode* fromp = nullptr, AstNode* dimp = nullptr) : ASTGEN_SUPER_AttrOf(fl) { - setNOp1p(fromp); - setNOp2p(dimp); + this->fromp(fromp); + this->dimp(dimp); m_attrType = attrtype; } ASTGEN_MEMBERS_AttrOf; - AstNode* fromp() const { return op1p(); } - AstNode* dimp() const { return op2p(); } VAttrType attrType() const { return m_attrType; } void dump(std::ostream& str = std::cout) const override; }; class AstBind final : public AstNode { // Parents: MODULE // Children: CELL + // @astgen op1 := cellsp : List[AstNode] private: string m_name; // Binding to name public: @@ -702,18 +658,21 @@ public: : ASTGEN_SUPER_Bind(fl) , m_name{name} { UASSERT_OBJ(VN_IS(cellsp, Cell), cellsp, "Only instances allowed to be bound"); - addNOp1p(cellsp); + this->addCellsp(cellsp); } ASTGEN_MEMBERS_Bind; // ACCESSORS string name() const override { return m_name; } // * = Bind Target name void name(const string& name) override { m_name = name; } - AstNode* cellsp() const { return op1p(); } // op1 = cells }; class AstCFunc final : public AstNode { // C++ function // Parents: MODULE/SCOPE - // Children: VAR/statements + // If adding node accessors, see below emptyBody + // @astgen op1 := argsp : List[AstNode] + // @astgen op2 := initsp : List[AstNode] + // @astgen op3 := stmtsp : List[AstNode] + // @astgen op4 := finalsp : List[AstNode] private: AstScope* m_scopep; string m_name; @@ -850,16 +809,6 @@ public: void dpiImportWrapper(bool flag) { m_dpiImportWrapper = flag; } void dpiTraceInit(bool flag) { m_dpiTraceInit = flag; } bool dpiTraceInit() const { return m_dpiTraceInit; } - // - // If adding node accessors, see below emptyBody - AstNode* argsp() const { return op1p(); } - void addArgsp(AstNode* nodep) { addOp1p(nodep); } - AstNode* initsp() const { return op2p(); } - void addInitsp(AstNode* nodep) { addOp2p(nodep); } - AstNode* stmtsp() const { return op3p(); } - void addStmtsp(AstNode* nodep) { addOp3p(nodep); } - AstNode* finalsp() const { return op4p(); } - void addFinalsp(AstNode* nodep) { addOp4p(nodep); } // Special methods bool emptyBody() const { return argsp() == nullptr && initsp() == nullptr && stmtsp() == nullptr @@ -885,36 +834,33 @@ public: }; class AstCaseItem final : public AstNode { // Single item of a case statement - // Parents: CASE - // condsp Children: MATH (Null condition used for default block) - // bodysp Children: Statements + // @astgen op1 := condsp : List[AstNode] + // @astgen op2 := stmtsp : List[AstNode] public: - AstCaseItem(FileLine* fl, AstNode* condsp, AstNode* bodysp) + AstCaseItem(FileLine* fl, AstNode* condsp, AstNode* stmtsp) : ASTGEN_SUPER_CaseItem(fl) { - addNOp1p(condsp); - addNOp2p(bodysp); + this->addCondsp(condsp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_CaseItem; int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; } - AstNode* condsp() const { return op1p(); } // op1 = list of possible matching expressions - AstNode* bodysp() const { return op2p(); } // op2 = what to do - void condsp(AstNode* nodep) { setOp1p(nodep); } - void addBodysp(AstNode* newp) { addOp2p(newp); } bool isDefault() const { return condsp() == nullptr; } - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstCast final : public AstNode { - // Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc + // Cast to appropriate data type + // @astgen op1 := fromp : AstNode + // @astgen op2 := childDTypep : Optional[AstNodeDType] public: - AstCast(FileLine* fl, AstNode* lhsp, VFlagChildDType, AstNodeDType* dtp) + AstCast(FileLine* fl, AstNode* fromp, VFlagChildDType, AstNodeDType* dtp) : ASTGEN_SUPER_Cast(fl) { - setOp1p(lhsp); - setOp2p(dtp); + this->fromp(fromp); + this->childDTypep(dtp); dtypeFrom(dtp); } - AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtp) + AstCast(FileLine* fl, AstNode* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_Cast(fl) { - setOp1p(lhsp); + this->fromp(fromp); dtypeFrom(dtp); } ASTGEN_MEMBERS_Cast; @@ -923,20 +869,18 @@ public: virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); } virtual bool cleanLhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } - AstNode* lhsp() const { return op1p(); } - AstNode* fromp() const { return lhsp(); } - void lhsp(AstNode* nodep) { setOp1p(nodep); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - AstNodeDType* childDTypep() const { return VN_AS(op2p(), NodeDType); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } }; class AstCastParse final : public AstNode { // Cast to appropriate type, where we haven't determined yet what the data type is + // @astgen op1 := lhsp : AstNode + // @astgen op2 := dtp : AstNode public: AstCastParse(FileLine* fl, AstNode* lhsp, AstNode* dtp) : ASTGEN_SUPER_CastParse(fl) { - setOp1p(lhsp); - setOp2p(dtp); + this->lhsp(lhsp); + this->dtp(dtp); } ASTGEN_MEMBERS_CastParse; virtual string emitVerilog() { return "((%d)'(%l))"; } @@ -944,16 +888,16 @@ public: virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); } virtual bool cleanLhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } - AstNode* lhsp() const { return op1p(); } - AstNode* dtp() const { return op2p(); } }; class AstCastSize final : public AstNode { // Cast to specific size; signed/twostate inherited from lower element per IEEE + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode public: AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp) : ASTGEN_SUPER_CastSize(fl) { - setOp1p(lhsp); - setOp2p((AstNode*)rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_CastSize; // No hasDType because widthing removes this node before the hasDType check @@ -961,12 +905,13 @@ public: virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); } virtual bool cleanLhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } }; class AstCell final : public AstNode { // A instantiation cell or interface call (don't know which until link) -private: + // @astgen op1 := pinsp : List[AstPin] // List of port assignments + // @astgen op2 := paramsp : List[AstPin] // List of parameter assignments + // @astgen op3 := rangep : Optional[AstRange] // Range for arrayed instances + // @astgen op4 := intfRefsp : List[AstIntfRef] // List of interface references FileLine* m_modNameFileline; // Where module the cell instances token was string m_name; // Cell name string m_origName; // Original name before dot addition @@ -986,9 +931,9 @@ public: , m_hasIfaceVar{false} , m_recursive{false} , m_trace{true} { - addNOp1p((AstNode*)pinsp); - addNOp2p((AstNode*)paramsp); - setNOp3p((AstNode*)rangep); + this->addPinsp(pinsp); + this->addParamsp(paramsp); + this->rangep(rangep); } ASTGEN_MEMBERS_Cell; // No cloneRelink, we presume cloneee's want the same module linkages @@ -1003,17 +948,7 @@ public: string modName() const { return m_modName; } // * = Instance name void modName(const string& name) { m_modName = name; } FileLine* modNameFileline() const { return m_modNameFileline; } - AstPin* pinsp() const { return VN_AS(op1p(), Pin); } // op1 = List of cell ports - // op2 = List of parameter #(##) values - AstPin* paramsp() const { return VN_AS(op2p(), Pin); } - // op3 = Range of arrayed instants (nullptr=not ranged) - AstRange* rangep() const { return VN_AS(op3p(), Range); } - // op4 = List of interface references - AstIntfRef* intfRefp() const { return VN_AS(op4p(), IntfRef); } AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated - void addPinsp(AstPin* nodep) { addOp1p((AstNode*)nodep); } - void addParamsp(AstPin* nodep) { addOp2p((AstNode*)nodep); } - void addIntfRefp(AstIntfRef* nodep) { addOp4p((AstNode*)nodep); } void modp(AstNodeModule* nodep) { m_modp = nodep; } bool hasIfaceVar() const { return m_hasIfaceVar; } void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; } @@ -1024,18 +959,17 @@ public: }; class AstCellArrayRef final : public AstNode { // As-of-yet unlinkable reference into an array of cells -private: + // @astgen op1 := selp : List[AstNode] // Select expression string m_name; // Array name public: - AstCellArrayRef(FileLine* fl, const string& name, AstNode* selectExprp) + AstCellArrayRef(FileLine* fl, const string& name, AstNode* selp) : ASTGEN_SUPER_CellArrayRef(fl) , m_name{name} { - addNOp1p(selectExprp); + this->addSelp(selp); } ASTGEN_MEMBERS_CellArrayRef; // ACCESSORS string name() const override { return m_name; } // * = Array name - AstNode* selp() const { return op1p(); } // op1 = Select expression }; class AstCellInline final : public AstNode { // A instantiation cell that was removed by inlining @@ -1070,49 +1004,49 @@ public: }; class AstCellRef final : public AstNode { // As-of-yet unlinkable reference into a cell + // @astgen op1 := cellp : AstNode + // @astgen op2 := exprp : AstNode private: string m_name; // Cell name public: AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp) : ASTGEN_SUPER_CellRef(fl) , m_name{name} { - addNOp1p(cellp); - addNOp2p(exprp); + this->cellp(cellp); + this->exprp(exprp); } ASTGEN_MEMBERS_CellRef; // ACCESSORS string name() const override { return m_name; } // * = Array name - AstNode* cellp() const { return op1p(); } // op1 = Cell - AstNode* exprp() const { return op2p(); } // op2 = Expression }; class AstClassExtends final : public AstNode { // Children: List of AstParseRef for packages/classes // during early parse, then moves to dtype + // @astgen op1 := childDTypep : Optional[AstNodeDType] + // @astgen op2 := classOrPkgsp : Optional[AstNode] public: AstClassExtends(FileLine* fl, AstNode* classOrPkgsp) : ASTGEN_SUPER_ClassExtends(fl) { - setNOp2p(classOrPkgsp); // Only for parser + this->classOrPkgsp(classOrPkgsp); // Only for parser } ASTGEN_MEMBERS_ClassExtends; bool hasDType() const override { return true; } string verilogKwd() const override { return "extends"; } - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } - AstNode* classOrPkgsp() const { return op2p(); } AstClass* classp() const; // Class being extended (after link) }; class AstClassOrPackageRef final : public AstNode { + // @astgen op1 := paramsp : List[AstPin] private: string m_name; // Node not NodeModule to appease some early parser usage AstNode* m_classOrPackageNodep; // Package hierarchy public: AstClassOrPackageRef(FileLine* fl, const string& name, AstNode* classOrPackageNodep, - AstNode* paramsp) + AstPin* paramsp) : ASTGEN_SUPER_ClassOrPackageRef(fl) , m_name{name} , m_classOrPackageNodep{classOrPackageNodep} { - addNOp4p(paramsp); + this->addParamsp(paramsp); } ASTGEN_MEMBERS_ClassOrPackageRef; // METHODS @@ -1136,25 +1070,23 @@ public: AstNodeModule* classOrPackagep() const; AstPackage* packagep() const { return VN_CAST(classOrPackageNodep(), Package); } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackageNodep = (AstNode*)nodep; } - AstPin* paramsp() const { return VN_AS(op4p(), Pin); } }; class AstClocking final : public AstNode { // Set default clock region // Parents: MODULE - // Children: Assertions + // @astgen op1 := sensesp : List[AstSenItem] + // @astgen op2 := bodysp : List[AstNode] public: AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp) : ASTGEN_SUPER_Clocking(fl) { - addOp1p((AstNode*)sensesp); - addNOp2p(bodysp); + this->addSensesp(sensesp); + this->addBodysp(bodysp); } ASTGEN_MEMBERS_Clocking; - // op1 = Sensitivity list - AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); } - AstNode* bodysp() const { return op2p(); } // op2 = Body }; class AstConstPool final : public AstNode { // Container for const static data + // @astgen op1 := modulep : AstModule // m_modp below TODO: fix this mess std::unordered_multimap m_tables; // Constant tables (unpacked arrays) std::unordered_multimap m_consts; // Constant tables (scalars) AstModule* const m_modp; // The Module holding the Scope below ... @@ -1186,8 +1118,7 @@ public: class AstDefParam final : public AstNode { // A defparam assignment // Parents: MODULE - // Children: math -private: + // @astgen op1 := rhsp : AstNode string m_name; // Name of variable getting set string m_path; // Dotted cellname to set parameter of public: @@ -1195,24 +1126,25 @@ public: : ASTGEN_SUPER_DefParam(fl) , m_name{name} , m_path{path} { - setOp1p(rhsp); + this->rhsp(rhsp); } string name() const override { return m_name; } // * = Scope name ASTGEN_MEMBERS_DefParam; bool same(const AstNode*) const override { return true; } - AstNode* rhsp() const { return op1p(); } // op1 = Assign from string path() const { return m_path; } }; class AstDot final : public AstNode { // A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef // These are eliminated in the link stage + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) public: AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_Dot(fl) , m_colon{colon} { - setOp1p(lhsp); - setOp2p(rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_Dot; // For parser, make only if non-null package @@ -1221,9 +1153,6 @@ public: return new AstDot(fl, true, packageOrClassp, rhsp); } void dump(std::ostream& str) const override; - AstNode* lhsp() const { return op1p(); } - void rhsp(AstNode* nodep) { setOp2p(nodep); } - AstNode* rhsp() const { return op2p(); } bool colon() const { return m_colon; } }; class AstDpiExport final : public AstNode { @@ -1246,7 +1175,7 @@ public: }; class AstElabDisplay final : public AstNode { // Parents: stmtlist - // Children: SFORMATF to generate print string + // @astgen op1 := fmtp : List[AstSFormatF] private: VDisplayType m_displayType; @@ -1269,8 +1198,6 @@ public: int instrCount() const override { return INSTR_COUNT_PLI; } VDisplayType displayType() const { return m_displayType; } void displayType(VDisplayType type) { m_displayType = type; } - void fmtp(AstSFormatF* nodep) { addOp1p((AstNode*)nodep); } // op1 = To-String formatter - AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); } }; class AstEmpty final : public AstNode { // Represents something missing, e.g. a missing argument in FOREACH @@ -1287,7 +1214,10 @@ class AstExecGraph final : public AstNode { // // The AstMTaskBody nodes are also children of this node, so we can visit // them without traversing the graph. -private: + // + // @astgen op1 := mTaskBodiesp : List[AstMTaskBody] + // In later phases, the statements that start the parallel execution + // @astgen op2 := stmtsp : List[AstNode] V3Graph* const m_depGraphp; // contains ExecMTask vertices const string m_name; // Name of this AstExecGraph (for uniqueness at code generation) @@ -1302,22 +1232,17 @@ public: string name() const override { return m_name; } V3Graph* depGraphp() { return m_depGraphp; } const V3Graph* depGraphp() const { return m_depGraphp; } - // op1: The mtask bodies - AstMTaskBody* mTaskBodiesp() const { return VN_AS(op1p(), MTaskBody); } - void addMTaskBodyp(AstMTaskBody* bodyp) { addOp1p((AstNode*)bodyp); } - // op2: In later phases, the statements that start the parallel execution - void addStmtsp(AstNode* stmtp) { addOp2p(stmtp); } }; class AstImplicit final : public AstNode { // Create implicit wires and do nothing else, for gates that are ignored // Parents: MODULE + // @astgen op1 := exprsp : List[AstNode] public: AstImplicit(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_Implicit(fl) { - addNOp1p(exprsp); + this->addExprsp(exprsp); } ASTGEN_MEMBERS_Implicit; - AstNode* exprsp() const { return op1p(); } // op1 = Assign from }; class AstInitArray final : public AstNode { // Set a var to a map of values @@ -1325,7 +1250,9 @@ class AstInitArray final : public AstNode { // If default is specified, the vector may be sparse, and not provide each value. // Key values are C++ array style, with lo() at index 0 // Parents: ASTVAR::init() - // Children: AstInitItem + // @astgen op1 := defaultp : Optional[AstNode] // Default, if sparse + // @astgen op2 := initsp : List[AstNode] // Initial value expressions + // public: using KeyItemMap = std::map; @@ -1335,7 +1262,7 @@ public: AstInitArray(FileLine* fl, AstNodeDType* newDTypep, AstNode* defaultp) : ASTGEN_SUPER_InitArray(fl) { dtypep(newDTypep); - addNOp1p(defaultp); + this->defaultp(defaultp); } ASTGEN_MEMBERS_InitArray; void dump(std::ostream& str) const override; @@ -1347,12 +1274,9 @@ public: // of children list, and instead use map-vs-map key/value compare return m_map == static_cast(samep)->m_map; } - AstNode* defaultp() const { return op1p(); } // op1 = Default if sparse - void defaultp(AstNode* newp) { setOp1p(newp); } - AstNode* initsp() const { return op2p(); } // op2 = Initial value expressions void addValuep(AstNode* newp) { addIndexValuep(m_map.size(), newp); } const KeyItemMap& map() const { return m_map; } - AstNode* addIndexValuep(uint64_t index, AstNode* newp); + void addIndexValuep(uint64_t index, AstNode* newp); AstNode* getIndexValuep(uint64_t index) const; AstNode* getIndexDefaultedValuep(uint64_t index) const; }; @@ -1360,17 +1284,16 @@ class AstInitItem final : public AstNode { // Container for a item in an init array // This container is present so that the value underneath may get replaced with a new nodep // and the upper AstInitArray's map will remain correct (pointing to this InitItem) + // @astgen op1 := valuep : AstNode public: // Parents: INITARRAY AstInitItem(FileLine* fl, AstNode* valuep) : ASTGEN_SUPER_InitItem(fl) { - addOp1p(valuep); + this->valuep(valuep); } ASTGEN_MEMBERS_InitItem; bool maybePointedTo() const override { return true; } bool hasDType() const override { return false; } // See valuep()'s dtype instead - AstNode* valuep() const { return op1p(); } // op1 = Value - void valuep(AstNode* nodep) { addOp1p(nodep); } }; class AstIntfRef final : public AstNode { // An interface reference @@ -1385,7 +1308,7 @@ public: }; class AstMTaskBody final : public AstNode { // Hold statements for each MTask -private: + // @astgen op1 := stmtsp : List[AstNode] ExecMTask* m_execMTaskp = nullptr; public: @@ -1396,8 +1319,6 @@ public: BROKEN_RTN(!m_execMTaskp); return nullptr; } - AstNode* stmtsp() const { return op1p(); } - void addStmtsp(AstNode* nodep) { addOp1p(nodep); } void addStmtsFirstp(AstNode* nodep) { if (stmtsp()) { stmtsp()->addHereThisAsNext(nodep); @@ -1411,18 +1332,17 @@ public: }; class AstModport final : public AstNode { // A modport in an interface -private: + // @astgen op1 := varsp : List[AstNode] string m_name; // Name of the modport public: AstModport(FileLine* fl, const string& name, AstNode* varsp) : ASTGEN_SUPER_Modport(fl) , m_name{name} { - addNOp1p(varsp); + this->addVarsp(varsp); } string name() const override { return m_name; } bool maybePointedTo() const override { return true; } ASTGEN_MEMBERS_Modport; - AstNode* varsp() const { return op1p(); } // op1 = List of Vars }; class AstModportFTaskRef final : public AstNode { // An import/export referenced under a modport @@ -1475,7 +1395,10 @@ class AstNetlist final : public AstNode { // All modules are under this single top node. // Parents: none // Children: MODULEs & CFILEs -private: + // @astgen op1 := modulesp : List[AstNodeModule] + // @astgen op2 := filesp : List[AstNodeFile] + // @astgen op3 := miscsp : List[AstNode] + AstTypeTable* const m_typeTablep; // Reference to top type table, for faster lookup AstConstPool* const m_constPoolp; // Reference to constant pool, for faster lookup AstPackage* m_dollarUnitPkgp = nullptr; // $unit @@ -1496,16 +1419,9 @@ public: void cloneRelink() override { V3ERROR_NA; } string name() const override { return "$root"; } void dump(std::ostream& str) const override; - AstNodeModule* modulesp() const { // op1 = List of modules - return VN_AS(op1p(), NodeModule); - } AstNodeModule* topModulep() const { // Top module in hierarchy return modulesp(); // First one in the list, for now } - void addModulep(AstNodeModule* modulep) { addOp1p((AstNode*)modulep); } - AstNodeFile* filesp() const { return VN_AS(op2p(), NodeFile); } // op2 = List of files - void addFilesp(AstNodeFile* filep) { addOp2p((AstNode*)filep); } - void addMiscsp(AstNode* nodep) { addOp3p(nodep); } AstTypeTable* typeTablep() { return m_typeTablep; } void changeRequest(bool specified) { m_changeRequest = specified; } bool changeRequest() const { return m_changeRequest; } @@ -1581,8 +1497,9 @@ class AstParseRef final : public AstNode { // We don't know which at parse time due to bison constraints // The link stages will replace this with AstVarRef, or AstTaskRef, etc. // Parents: math|stmt - // Children: TEXT|DOT|SEL*|TASK|FUNC (or expression under sel) -private: + // @astgen op1 := lhsp : Optional[AstNode] + // @astgen op2 := ftaskrefp : Optional[AstNodeFTaskRef] + VParseRefExp m_expect; // Type we think it should resolve to string m_name; @@ -1592,8 +1509,8 @@ public: : ASTGEN_SUPER_ParseRef(fl) , m_expect{expect} , m_name{name} { - setNOp1p(lhsp); - setNOp2p((AstNode*)ftaskrefp); + this->lhsp(lhsp); + this->ftaskrefp(ftaskrefp); } ASTGEN_MEMBERS_ParseRef; void dump(std::ostream& str) const override; @@ -1605,14 +1522,10 @@ public: void name(const string& name) override { m_name = name; } VParseRefExp expect() const { return m_expect; } void expect(VParseRefExp exp) { m_expect = exp; } - // op1 = Components - AstNode* lhsp() const { return op1p(); } // op1 = List of statements - AstNode* ftaskrefp() const { return op2p(); } // op2 = Function/task reference - // op2 = Function/task reference - void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstPin final : public AstNode { - // A pin on a cell + // A port or parameter assignment on an instantiaton + // @astgen op1 := exprp : Optional[AstNode] // Expression connected (nullptr if unconnected) private: int m_pinNum; // Pin number string m_name; // Pin name, or "" for number based interconnect @@ -1625,7 +1538,7 @@ public: : ASTGEN_SUPER_Pin(fl) , m_pinNum{pinNum} , m_name{name} { - setNOp1p(exprp); + this->exprp(exprp); } inline AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp); ASTGEN_MEMBERS_Pin; @@ -1636,9 +1549,6 @@ public: string prettyOperatorName() const override; bool dotStar() const { return name() == ".*"; } // Fake name for .* connections until linked int pinNum() const { return m_pinNum; } - void exprp(AstNode* nodep) { addOp1p(nodep); } - // op1 = Expression connected to pin, nullptr if unconnected - AstNode* exprp() const { return op1p(); } AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable void modVarp(AstVar* nodep) { m_modVarp = nodep; } // [After Link] Pointer to variable @@ -1651,9 +1561,9 @@ public: }; class AstPort final : public AstNode { // A port (in/out/inout) on a module -private: - int m_pinNum; // Pin number - string m_name; // Name of pin + // @astgen op1 := exprp : Optional[AstNode] // Expression connected to port + const int m_pinNum; // Pin number + const string m_name; // Name of pin public: AstPort(FileLine* fl, int pinnum, const string& name) : ASTGEN_SUPER_Port(fl) @@ -1662,10 +1572,8 @@ public: ASTGEN_MEMBERS_Port; string name() const override { return m_name; } // * = Port name int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation - AstNode* exprp() const { return op1p(); } // op1 = Expression connected to port }; class AstPragma final : public AstNode { -private: const VPragmaType m_pragType; // Type of pragma public: // Pragmas don't result in any output code, they're just flags that affect @@ -1684,42 +1592,43 @@ class AstPropClocked final : public AstNode { // A clocked property // Parents: ASSERT|COVER (property) // Children: SENITEM, Properties + // @astgen op1 := sensesp : Optional[AstSenItem] + // @astgen op2 := disablep : Optional[AstNode] + // @astgen op3 := propp : AstNode public: AstPropClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp) : ASTGEN_SUPER_PropClocked(fl) { - addNOp1p((AstNode*)sensesp); - addNOp2p(disablep); - addOp3p(propp); + this->sensesp(sensesp); + this->disablep(disablep); + this->propp(propp); } ASTGEN_MEMBERS_PropClocked; bool hasDType() const override { return true; } // Used under Cover, which expects a bool child - AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); } // op1 = Sensitivity list - AstNode* disablep() const { return op2p(); } // op2 = disable - AstNode* propp() const { return op3p(); } // op3 = property }; class AstPull final : public AstNode { -private: - bool m_direction; + // @astgen op1 := lhsp : AstNode + + const bool m_direction; public: AstPull(FileLine* fl, AstNode* lhsp, bool direction) : ASTGEN_SUPER_Pull(fl) , m_direction{direction} { - setOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_Pull; bool same(const AstNode* samep) const override { return direction() == static_cast(samep)->direction(); } - void lhsp(AstNode* np) { setOp1p(np); } - AstNode* lhsp() const { return op1p(); } // op1 = Assign to uint32_t direction() const { return (uint32_t)m_direction; } }; class AstSFormatF final : public AstNode { // Convert format to string, generally under an AstDisplay or AstSFormat // Also used as "real" function for /*verilator sformat*/ functions + // @astgen op1 := exprsp : List[AstNode] + // @astgen op2 := scopeNamep : Optional[AstScopeName] string m_text; const bool m_hidden; // Under display, etc bool m_hasFormat; // Has format code @@ -1735,8 +1644,7 @@ public: , m_hasFormat{true} , m_missingArgChar{missingArgChar} { dtypeSetString(); - addNOp1p(exprsp); - addNOp2p(nullptr); + addExprsp(exprsp); } AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp, char missingArgChar = 'd', bool hidden = true) @@ -1746,8 +1654,7 @@ public: , m_hasFormat{false} , m_missingArgChar{missingArgChar} { dtypeSetString(); - addNOp1p(exprsp); - addNOp2p(nullptr); + addExprsp(exprsp); } ASTGEN_MEMBERS_SFormatF; string name() const override { return m_text; } @@ -1757,12 +1664,8 @@ public: return text() == static_cast(samep)->text(); } string verilogKwd() const override { return "$sformatf"; } - void addExprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output - AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text = text; } - AstScopeName* scopeNamep() const { return VN_AS(op2p(), ScopeName); } - void scopeNamep(AstNode* nodep) { setNOp2p(nodep); } bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive return (name().find("%m") != string::npos || name().find("%M") != string::npos); } @@ -1777,7 +1680,10 @@ class AstScope final : public AstNode { // A particular usage of a cell // Parents: MODULE // Children: NODEBLOCK -private: + // @astgen op1 := varsp : List[AstVarScope] + // @astgen op2 := blocksp : List[AstNode] // Logic blocks/AstActive/AstCFunc + // @astgen op3 := finalClksp : List[AstNode] + // An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope string m_name; // Name AstScope* const m_aboveScopep; // Scope above this one in the hierarchy (nullptr if top) @@ -1801,12 +1707,6 @@ public: string nameDotless() const; string nameVlSym() const { return ((string("vlSymsp->")) + nameDotless()); } AstNodeModule* modp() const { return m_modp; } - void addVarp(AstVarScope* nodep) { addOp1p((AstNode*)nodep); } - AstVarScope* varsp() const { return VN_AS(op1p(), VarScope); } // op1 = AstVarScope's - void addActivep(AstNode* nodep) { addOp2p(nodep); } - AstNode* blocksp() const { return op2p(); } // op2 = Block names - void addFinalClkp(AstNode* nodep) { addOp3p(nodep); } - AstNode* finalClksp() const { return op3p(); } // op3 = Final assigns for clock correction AstScope* aboveScopep() const { return m_aboveScopep; } AstCell* aboveCellp() const { return m_aboveCellp; } bool isTop() const { return aboveScopep() == nullptr; } // At top of hierarchy @@ -1814,23 +1714,21 @@ public: class AstSelLoopVars final : public AstNode { // Parser only concept "[id, id, id]" for a foreach statement // Unlike normal selects elements is a list + // @astgen op1 := fromp : AstNode + // @astgen op2 := elementsp : List[AstNode] public: AstSelLoopVars(FileLine* fl, AstNode* fromp, AstNode* elementsp) : ASTGEN_SUPER_SelLoopVars(fl) { - setOp1p(fromp); - addNOp2p(elementsp); + this->fromp(fromp); + this->addElementsp(elementsp); } ASTGEN_MEMBERS_SelLoopVars; bool same(const AstNode* /*samep*/) const override { return true; } bool maybePointedTo() const override { return false; } - AstNode* fromp() const { return op1p(); } - void fromp(AstNode* nodep) { setOp1p(nodep); } - AstNode* elementsp() const { return op2p(); } }; class AstSenItem final : public AstNode { // Parents: SENTREE - // Children: (optional) VARREF -private: + // @astgen op1 := sensp : AstNode // Sensitivity expression VEdgeType m_edgeType; // Edge type public: class Combo {}; // for creator type-overload selection @@ -1838,10 +1736,10 @@ public: class Initial {}; // for creator type-overload selection class Settle {}; // for creator type-overload selection class Never {}; // for creator type-overload selection - AstSenItem(FileLine* fl, VEdgeType edgeType, AstNode* varrefp) + AstSenItem(FileLine* fl, VEdgeType edgeType, AstNode* senp) : ASTGEN_SUPER_SenItem(fl) , m_edgeType{edgeType} { - setOp1p(varrefp); + this->sensp(senp); } AstSenItem(FileLine* fl, Combo) : ASTGEN_SUPER_SenItem(fl) @@ -1867,11 +1765,8 @@ public: void edgeType(VEdgeType type) { m_edgeType = type; editCountInc(); - } // * = Posedge/negedge - AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized - AstNodeVarRef* varrefp() const { - return VN_CAST(op1p(), NodeVarRef); - } // op1 = Signal sensitized + } + AstNodeVarRef* varrefp() const { return VN_CAST(sensp(), NodeVarRef); } // bool isClocked() const { return edgeType().clockedStmt(); } bool isCombo() const { return edgeType() == VEdgeType::ET_COMBO; } @@ -1882,23 +1777,18 @@ public: bool hasVar() const { return !(isCombo() || isInitial() || isSettle() || isNever()); } }; class AstSenTree final : public AstNode { - // A list of senitems - // Parents: MODULE | SBLOCK - // Children: SENITEM list -private: + // A sensitivity list + // @astgen op1 := sensesp : List[AstSenItem] bool m_multi = false; // Created from combo logic by ORing multiple clock domains public: AstSenTree(FileLine* fl, AstSenItem* sensesp) : ASTGEN_SUPER_SenTree(fl) { - addNOp1p(sensesp); + this->addSensesp(sensesp); } ASTGEN_MEMBERS_SenTree; void dump(std::ostream& str) const override; bool maybePointedTo() const override { return true; } bool isMulti() const { return m_multi; } - // op1 = Sensitivity list - AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); } - void addSensesp(AstSenItem* nodep) { addOp1p(nodep); } void multi(bool flag) { m_multi = true; } // METHODS bool hasClocked() const; // Includes a clocked statement @@ -1930,26 +1820,26 @@ public: void dump(std::ostream& str) const override; }; class AstTopScope final : public AstNode { - // A singleton, held under the top level AstModule. Holds the top level AstScope, - // and after V3ActiveTop, the global list of AstSenTrees (list of unique sensitivity lists). - // Parent: Top level AstModule - // Children: AstSenTree, AstScope + // A singleton, held under the top level AstModule. Holds the top level + // AstScope, and after V3ActiveTop, the global list of AstSenTrees (list of + // unique sensitivity lists). + // + // @astgen op1 := senTreesp : List[AstSenTree] // Globally unique sensitivity lists + // @astgen op2 := scopep : AstScope // The AstScope of the top-leveL + friend class AstNetlist; // Only the AstNetlist can create one AstTopScope(FileLine* fl, AstScope* ascopep) : ASTGEN_SUPER_TopScope(fl) { - addOp2p(ascopep); + this->scopep(ascopep); } public: ASTGEN_MEMBERS_TopScope; bool maybePointedTo() const override { return true; } - AstSenTree* senTreesp() const { return VN_AS(op1p(), SenTree); } - void addSenTreep(AstSenTree* nodep) { addOp1p((AstNode*)nodep); } - AstScope* scopep() const { return VN_AS(op2p(), Scope); } }; class AstTypeTable final : public AstNode { // Container for hash of standard data types - // Children: NODEDTYPEs + // @astgen op1 := typesp : List[AstNodeDType] AstEmptyQueueDType* m_emptyQueuep = nullptr; AstQueueDType* m_queueIndexp = nullptr; AstVoidDType* m_voidp = nullptr; @@ -1969,8 +1859,6 @@ public: return nullptr; } void cloneRelink() override { V3ERROR_NA; } - AstNodeDType* typesp() const { return VN_AS(op1p(), NodeDType); } // op1 = List of dtypes - void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); } AstBasicDType* findBasicDType(FileLine* fl, VBasicDTypeKwd kwd); AstBasicDType* findLogicBitDType(FileLine* fl, VBasicDTypeKwd kwd, int width, int widthMin, VSigning numeric); @@ -1985,7 +1873,9 @@ public: void dump(std::ostream& str = std::cout) const override; }; class AstTypedef final : public AstNode { -private: + // @astgen op1 := childDTypep : Optional[AstNodeDType] + // @astgen op4 := attrsp : List[AstNode] // Attributes during early parse + string m_name; bool m_attrPublic = false; string m_tag; // Holds the string of the verilator tag -- used in XML output. @@ -2001,12 +1891,7 @@ public: ASTGEN_MEMBERS_Typedef; void dump(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Type assigning to - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } - void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } - AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse // METHODS string name() const override { return m_name; } bool maybePointedTo() const override { return true; } @@ -2032,14 +1917,13 @@ public: bool maybePointedTo() const override { return true; } }; class AstUdpTable final : public AstNode { + // @astgen op1 := linesp : List[AstUdpTableLine] public: - AstUdpTable(FileLine* fl, AstNode* bodysp) + AstUdpTable(FileLine* fl, AstUdpTableLine* linesp) : ASTGEN_SUPER_UdpTable(fl) { - addNOp1p(bodysp); + this->addLinesp(linesp); } ASTGEN_MEMBERS_UdpTable; - // op1 = List of UdpTableLines - AstUdpTableLine* bodysp() const { return VN_AS(op1p(), UdpTableLine); } }; class AstUdpTableLine final : public AstNode { string m_text; @@ -2054,24 +1938,29 @@ public: }; class AstUnlinkedRef final : public AstNode { // As-of-yet unlinkable Ref -private: - string m_name; // Var name + // @astgen op1 := refp : AstNode + // @astgen op2 := cellrefp : AstNode + + string m_name; // Var name // TODO: There is no way to access this, fix or remove public: - AstUnlinkedRef(FileLine* fl, AstNode* refp, const string& name, AstNode* crp) + AstUnlinkedRef(FileLine* fl, AstNode* refp, const string& name, AstNode* cellrefp) : ASTGEN_SUPER_UnlinkedRef(fl) , m_name{name} { - addNOp1p(refp); - addNOp2p(crp); + this->refp(refp); + this->cellrefp(cellrefp); } ASTGEN_MEMBERS_UnlinkedRef; - // ACCESSORS - string name() const override { return m_name; } // * = Var name - AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef - AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef }; class AstVar final : public AstNode { // A variable (in/out/wire/reg/param) inside a module -private: + // + // @astgen op1 := childDTypep : Optional[AstNodeDType] + // @astgen op2 := delayp : Optional[AstNode] // Net delay + // Initial value that never changes (static const), or constructor argument for + // MTASKSTATE variables + // @astgen op3 := valuep : Optional[AstNode] + // @astgen op4 := attrsp : List[AstNode] // Attributes during early parse + string m_name; // Name of variable string m_origName; // Original name before dot addition string m_tag; // Holds the string of the verilator tag -- used in XML output. @@ -2262,23 +2151,10 @@ public: string vlPropDecl(const string& propName) const; // Return VerilatorVarProps declaration void combineType(VVarType type); AstNodeDType* getChildDTypep() const override { return childDTypep(); } - // op1 = Range of variable - AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } - // op2 = Net delay - AstNode* delayp() const { return op2p(); } - void delayp(AstNode* const nodep) { setNOp2p(nodep); } AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - // AstVar isn't a NodeDType) AstBasicDType* basicp() const { return subDTypep()->basicp(); } - // op3 = Initial value that never changes (static const), or constructor argument for - // MTASKSTATE variables - AstNode* valuep() const { return op3p(); } - // It's valuep(), not constp(), as may be more complicated than an AstConst - void valuep(AstNode* nodep) { setOp3p(nodep); } - void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } - AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void ansi(bool flag) { m_ansi = flag; } void declTyped(bool flag) { m_declTyped = flag; } @@ -2490,8 +2366,8 @@ public: class AstBegin final : public AstNodeBlock { // A Begin/end named block, only exists shortly after parsing until linking // Parents: statement - // Children: statements -private: + // @astgen op2 := genforp : Optional[AstNode] + bool m_generate; // Underneath a generate const bool m_implied; // Not inserted by user public: @@ -2503,10 +2379,6 @@ public: , m_implied{implied} {} ASTGEN_MEMBERS_Begin; void dump(std::ostream& str) const override; - // op1p is statements in NodeBlock - AstNode* genforp() const { return op2p(); } // op2 = GENFOR, if applicable, - // might NOT be a GenFor, as loop unrolling replaces with Begin - void addGenforp(AstGenFor* nodep) { addOp2p((AstNode*)nodep); } void generate(bool flag) { m_generate = flag; } bool generate() const { return m_generate; } bool implied() const { return m_implied; } @@ -2531,9 +2403,9 @@ public: class AstFunc final : public AstNodeFTask { // A function inside a module public: - AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp) + AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarp) : ASTGEN_SUPER_Func(fl, name, stmtp) { - addNOp1p(fvarsp); + this->fvarp(fvarp); } ASTGEN_MEMBERS_Func; bool hasDType() const override { return true; } @@ -2581,6 +2453,7 @@ public: // === AstNodeModule === class AstClass final : public AstNodeModule { + // @astgen op4 := extendsp : Optional[AstClassExtends] // TYPES using MemberNameMap = std::map; // MEMBERS @@ -2600,16 +2473,13 @@ public: const char* broken() const override; void cloneRelink() override; bool timescaleMatters() const override { return false; } - // op1/op2/op3 in AstNodeModule AstClassPackage* classOrPackagep() const { return m_classOrPackagep; } void classOrPackagep(AstClassPackage* classpackagep) { m_classOrPackagep = classpackagep; } - AstNode* membersp() const { return stmtsp(); } // op2 = List of statements + AstNode* membersp() const { return stmtsp(); } void addMembersp(AstNode* nodep) { insertCache(nodep); - addStmtp(nodep); + addStmtsp(nodep); } - AstClassExtends* extendsp() const { return VN_AS(op4p(), ClassExtends); } - void extendsp(AstNode* nodep) { addNOp4p(nodep); } void clearCache() { m_members.clear(); } void repairCache(); AstNode* findMember(const string& name) const { @@ -2737,27 +2607,27 @@ public: // === AstNodeProcedure === class AstAlways final : public AstNodeProcedure { + // @astgen op1 := sensesp : Optional[AstSenTree] // Sensitivity list iff clocked const VAlwaysKwd m_keyword; public: - AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp) - : ASTGEN_SUPER_Always(fl, bodysp) + AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* stmtsp) + : ASTGEN_SUPER_Always(fl, stmtsp) , m_keyword{keyword} { - addNOp1p(sensesp); + this->sensesp(sensesp); } ASTGEN_MEMBERS_Always; // void dump(std::ostream& str) const override; - AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); } // op1 = Sensitivity list - void sensesp(AstSenTree* nodep) { setOp1p(nodep); } VAlwaysKwd keyword() const { return m_keyword; } }; class AstAlwaysPost final : public AstNodeProcedure { // Like always but post assignments for memory assignment IFs + // @astgen op1 := sensesp : Optional[AstSenTree] // Sensitivity list iff clocked public: - AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) - : ASTGEN_SUPER_AlwaysPost(fl, bodysp) { - addNOp1p(sensesp); + AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp) + : ASTGEN_SUPER_AlwaysPost(fl, stmtsp) { + this->sensesp(sensesp); } ASTGEN_MEMBERS_AlwaysPost; }; @@ -2765,36 +2635,36 @@ class AstAlwaysPostponed final : public AstNodeProcedure { // Like always but postponement scheduling region public: - AstAlwaysPostponed(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER_AlwaysPostponed(fl, bodysp) {} + AstAlwaysPostponed(FileLine* fl, AstNode* stmtsp) + : ASTGEN_SUPER_AlwaysPostponed(fl, stmtsp) {} ASTGEN_MEMBERS_AlwaysPostponed; }; class AstFinal final : public AstNodeProcedure { public: - AstFinal(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER_Final(fl, bodysp) {} + AstFinal(FileLine* fl, AstNode* stmtsp) + : ASTGEN_SUPER_Final(fl, stmtsp) {} ASTGEN_MEMBERS_Final; }; class AstInitial final : public AstNodeProcedure { public: - AstInitial(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER_Initial(fl, bodysp) {} + AstInitial(FileLine* fl, AstNode* stmtsp) + : ASTGEN_SUPER_Initial(fl, stmtsp) {} ASTGEN_MEMBERS_Initial; }; class AstInitialAutomatic final : public AstNodeProcedure { // Automatic variable initialization // That is, it runs every function start, or class construction public: - AstInitialAutomatic(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER_InitialAutomatic(fl, bodysp) {} + AstInitialAutomatic(FileLine* fl, AstNode* stmtsp) + : ASTGEN_SUPER_InitialAutomatic(fl, stmtsp) {} ASTGEN_MEMBERS_InitialAutomatic; }; class AstInitialStatic final : public AstNodeProcedure { // Static variable initialization // That is, it runs at the beginning of simulation, before 'initial' blocks public: - AstInitialStatic(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER_InitialStatic(fl, bodysp) {} + AstInitialStatic(FileLine* fl, AstNode* stmtsp) + : ASTGEN_SUPER_InitialStatic(fl, stmtsp) {} ASTGEN_MEMBERS_InitialStatic; }; @@ -2802,10 +2672,11 @@ public: class AstBracketRange final : public AstNodeRange { // Parser only concept "[lhsp]", a AstUnknownRange, QueueRange or Range, // unknown until lhsp type is determined + // @astgen op1 := elementsp : AstNode public: AstBracketRange(FileLine* fl, AstNode* elementsp) : ASTGEN_SUPER_BracketRange(fl) { - setOp1p(elementsp); + this->elementsp(elementsp); } ASTGEN_MEMBERS_BracketRange; virtual string emitC() { V3ERROR_NA_RETURN(""); } @@ -2814,21 +2685,20 @@ public: // Will be removed in V3Width, which relies on this // being a child not a dtype pointed node bool maybePointedTo() const override { return false; } - AstNode* elementsp() const { return op1p(); } }; class AstRange final : public AstNodeRange { // Range specification, for use under variables and cells + // @astgen op1 := leftp : AstNode + // @astgen op2 := rightp : AstNode public: AstRange(FileLine* fl, AstNode* leftp, AstNode* rightp) : ASTGEN_SUPER_Range(fl) { - setOp2p(leftp); - setOp3p(rightp); + this->leftp(leftp); + this->rightp(rightp); } inline AstRange(FileLine* fl, int left, int right); inline AstRange(FileLine* fl, const VNumRange& range); ASTGEN_MEMBERS_Range; - AstNode* leftp() const { return op2p(); } - AstNode* rightp() const { return op3p(); } inline int leftConst() const; inline int rightConst() const; int hiConst() const { @@ -2872,21 +2742,19 @@ public: class AstAlwaysPublic final : public AstNodeStmt { // "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/ // Body statements are just AstVarRefs to the public signals + // @astgen op1 := sensesp : List[AstSenTree] + // @astgen op2 := stmtsp : List[AstNode] public: - AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) + AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp) : ASTGEN_SUPER_AlwaysPublic(fl) { - addNOp1p(sensesp); - addNOp2p(bodysp); + addSensesp(sensesp); + addStmtsp(stmtsp); } ASTGEN_MEMBERS_AlwaysPublic; bool same(const AstNode* /*samep*/) const override { return true; } - // - AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); } // op1 = Sensitivity list - AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate - void addStmtp(AstNode* nodep) { addOp2p(nodep); } // Special accessors - bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isJustOneBodyStmt() const { return stmtsp() && !stmtsp()->nextp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstBreak final : public AstNodeStmt { public: @@ -2902,6 +2770,8 @@ class AstCMethodHard final : public AstNodeStmt { // A reference to a "C" hardcoded member task (or function) // PARENTS: stmt/math // Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal. + // @astgen op1 := fromp : AstNode // Subject of method call + // @astgen op2 := pinsp : List[AstNode] // Arguments private: string m_name; // Name of method bool m_pure = false; // Pure optimizable @@ -2910,15 +2780,16 @@ public: AstNode* pinsp = nullptr) : ASTGEN_SUPER_CMethodHard(fl, false) , m_name{name} { - setOp1p(fromp); + // TODO: this constructor is exactly the same as the other, bar the ignored tag argument + this->fromp(fromp); + this->addPinsp(pinsp); dtypep(nullptr); // V3Width will resolve - addNOp2p(pinsp); } AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp = nullptr) : ASTGEN_SUPER_CMethodHard(fl, false) , m_name{name} { - setOp1p(fromp); - addNOp2p(pinsp); + this->fromp(fromp); + this->addPinsp(pinsp); } ASTGEN_MEMBERS_CMethodHard; string name() const override { return m_name; } // * = Var name @@ -2934,68 +2805,58 @@ public: statement(true); dtypeSetVoid(); } - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) - void fromp(AstNode* nodep) { setOp1p(nodep); } - AstNode* pinsp() const { return op2p(); } // op2 = Pin interconnection list - void addPinsp(AstNode* nodep) { addOp2p(nodep); } }; class AstCReset final : public AstNodeStmt { // Reset variable at startup + // @astgen op1 := varrefp : AstVarRef public: - AstCReset(FileLine* fl, AstVarRef* exprsp) + AstCReset(FileLine* fl, AstVarRef* varrefp) : ASTGEN_SUPER_CReset(fl) { - addNOp1p((AstNode*)exprsp); + this->varrefp(varrefp); } ASTGEN_MEMBERS_CReset; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - AstVarRef* varrefp() const { return VN_AS(op1p(), VarRef); } // op1 = varref to reset }; class AstCReturn final : public AstNodeStmt { // C++ return from a function - // Parents: CFUNC/statement - // Children: Math + // @astgen op1 := lhsp : AstNode public: AstCReturn(FileLine* fl, AstNode* lhsp) : ASTGEN_SUPER_CReturn(fl) { - setOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_CReturn; int instrCount() const override { return widthInstrs(); } bool same(const AstNode* /*samep*/) const override { return true; } - // - AstNode* lhsp() const { return op1p(); } }; class AstCStmt final : public AstNodeStmt { // Emit C statement + // @astgen op1 := exprsp : List[AstNode] public: AstCStmt(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_CStmt(fl) { - addNOp1p(exprsp); + this->addExprsp(exprsp); } inline AstCStmt(FileLine* fl, const string& textStmt); ASTGEN_MEMBERS_CStmt; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } - void addBodysp(AstNode* nodep) { addNOp1p(nodep); } - AstNode* bodysp() const { return op1p(); } // op1 = expressions to print }; class AstChangeDet final : public AstNodeStmt { // A comparison to determine change detection, common & must be fast. + // @astgen op1 := lhsp : Optional[AstNode] + // @astgen op2 := rhsp : Optional[AstNode] public: // Null lhs+rhs used to indicate change needed with no spec vars AstChangeDet(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_ChangeDet(fl) { - setNOp1p(lhsp); - setNOp2p(rhsp); + this->lhsp(lhsp); + this->rhsp(rhsp); } ASTGEN_MEMBERS_ChangeDet; - AstNode* lhsp() const { return op1p(); } - AstNode* rhsp() const { return op2p(); } bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return widthInstrs() * 2; } // xor, or/logor @@ -3004,8 +2865,6 @@ public: class AstComment final : public AstNodeStmt { // Some comment to put into the output stream // Parents: {statement list} - // Children: none -private: const bool m_showAt; // Show "at " const string m_name; // Text of comment public: @@ -3116,13 +2975,15 @@ public: class AstCoverToggle final : public AstNodeStmt { // Toggle analysis of given signal // Parents: MODULE - // Children: AstCoverInc, orig var, change det var + // @astgen op1 := incp : AstCoverInc + // @astgen op2 := origp : AstNode + // @astgen op3 := changep : AstNode public: AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep) : ASTGEN_SUPER_CoverToggle(fl) { - setOp1p(incp); - setOp2p(origp); - setOp3p(changep); + this->incp(incp); + this->origp(origp); + this->changep(changep); } ASTGEN_MEMBERS_CoverToggle; int instrCount() const override { return 3 + INSTR_COUNT_BRANCH + INSTR_COUNT_LD; } @@ -3133,26 +2994,19 @@ public: return false; // Though the AstCoverInc under this is an outputter } // but isPure() true - AstCoverInc* incp() const { return VN_AS(op1p(), CoverInc); } - void incp(AstCoverInc* nodep) { setOp1p(nodep); } - AstNode* origp() const { return op2p(); } - AstNode* changep() const { return op3p(); } }; class AstDelay final : public AstNodeStmt { // Delay statement + // @astgen op1 := lhsp : AstNode // Delay value + // @astgen op2 := stmtsp : List[AstNode] // Statements under delay public: AstDelay(FileLine* fl, AstNode* lhsp, AstNode* stmtsp) : ASTGEN_SUPER_Delay(fl) { - setOp1p(lhsp); - setNOp2p(stmtsp); + this->lhsp(lhsp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_Delay; bool same(const AstNode* /*samep*/) const override { return true; } - // - AstNode* lhsp() const { return op1p(); } // op1 = delay value - void lhsp(AstNode* nodep) { setOp1p(nodep); } - void stmtsp(AstNode* nodep) { setOp2p(nodep); } // op2 = statements under delay - AstNode* stmtsp() const { return op2p(); } }; class AstDisable final : public AstNodeStmt { private: @@ -3177,8 +3031,8 @@ public: }; class AstDisplay final : public AstNodeStmt { // Parents: stmtlist - // Children: file which must be a varref - // Children: SFORMATF to generate print string + // @astgen op1 := fmtp : AstSFormatF + // @astgen op2 := filep : Optional[AstNode] // file (must be a VarRef) private: VDisplayType m_displayType; @@ -3187,15 +3041,15 @@ public: AstNode* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_Display(fl) , m_displayType{dispType} { - setOp1p(new AstSFormatF{fl, text, true, exprsp, missingArgChar}); - setNOp3p(filep); + this->fmtp(new AstSFormatF{fl, text, true, exprsp, missingArgChar}); + this->filep(filep); } AstDisplay(FileLine* fl, VDisplayType dispType, AstNode* filep, AstNode* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_Display(fl) , m_displayType{dispType} { - setOp1p(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp, missingArgChar}); - setNOp3p(filep); + this->fmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp, missingArgChar}); + this->filep(filep); } ASTGEN_MEMBERS_Display; void dump(std::ostream& str) const override; @@ -3220,10 +3074,6 @@ public: void displayType(VDisplayType type) { m_displayType = type; } // * = Add a newline for $display bool addNewline() const { return displayType().addNewline(); } - void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter - AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); } - AstNode* filep() const { return op3p(); } - void filep(AstNodeVarRef* nodep) { setNOp3p((AstNode*)nodep); } }; class AstDpiExportUpdated final : public AstNodeStmt { // Denotes that the referenced variable may have been updated via a DPI Export @@ -3235,13 +3085,13 @@ public: class AstDumpCtl final : public AstNodeStmt { // $dumpon etc // Parents: expr - // Child: expr based on type of control statement + // @astgen op1 := exprp : Optional[AstNode] // Expression based on type of control statement const VDumpCtlType m_ctlType; // Type of operation public: AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr) : ASTGEN_SUPER_DumpCtl(fl) , m_ctlType{ctlType} { - setNOp1p(exprp); + this->exprp(exprp); } ASTGEN_MEMBERS_DumpCtl; string verilogKwd() const override { return ctlType().ascii(); } @@ -3251,16 +3101,16 @@ public: virtual bool cleanOut() const { return true; } bool same(const AstNode* /*samep*/) const override { return true; } VDumpCtlType ctlType() const { return m_ctlType; } - AstNode* exprp() const { return op1p(); } // op2 = Expressions to output - void exprp(AstNode* nodep) { setOp1p(nodep); } }; class AstEventControl final : public AstNodeStmt { // Parents: stmtlist + // @astgen op1 := sensesp : Optional[AstSenTree] + // @astgen op2 := stmtsp : List[AstNode] public: AstEventControl(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp) : ASTGEN_SUPER_EventControl(fl) { - setNOp1p(sensesp); - setNOp2p(stmtsp); + this->sensesp(sensesp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_EventControl; string verilogKwd() const override { return "@(%l) %r"; } @@ -3269,16 +3119,14 @@ public: bool isPure() const override { return false; } bool isOutputter() const override { return false; } int instrCount() const override { return 0; } - AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); } - AstNode* stmtsp() const { return op2p(); } }; class AstFClose final : public AstNodeStmt { // Parents: stmtlist - // Children: file which must be a varref + // @astgen op1 := filep : AstNode // file (must be a VarRef) public: AstFClose(FileLine* fl, AstNode* filep) : ASTGEN_SUPER_FClose(fl) { - setNOp2p(filep); + this->filep(filep); } ASTGEN_MEMBERS_FClose; string verilogKwd() const override { return "$fclose"; } @@ -3288,16 +3136,14 @@ public: bool isOutputter() const override { return true; } bool isUnlikely() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op2p(); } - void filep(AstNodeVarRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstFFlush final : public AstNodeStmt { // Parents: stmtlist - // Children: file which must be a varref + // @astgen op1 := filep : Optional[AstNode] // file (must be a VarRef) public: AstFFlush(FileLine* fl, AstNode* filep) : ASTGEN_SUPER_FFlush(fl) { - setNOp2p(filep); + this->filep(filep); } ASTGEN_MEMBERS_FFlush; string verilogKwd() const override { return "$fflush"; } @@ -3307,17 +3153,18 @@ public: bool isOutputter() const override { return true; } bool isUnlikely() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op2p(); } - void filep(AstNodeVarRef* nodep) { setNOp2p((AstNode*)nodep); } }; class AstFOpen final : public AstNodeStmt { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) + // @astgen op1 := filep : AstNode + // @astgen op2 := filenamep : AstNode + // @astgen op3 := modep : AstNode public: AstFOpen(FileLine* fl, AstNode* filep, AstNode* filenamep, AstNode* modep) : ASTGEN_SUPER_FOpen(fl) { - setOp1p(filep); - setOp2p(filenamep); - setOp3p(modep); + this->filep(filep); + this->filenamep(filenamep); + this->modep(modep); } ASTGEN_MEMBERS_FOpen; string verilogKwd() const override { return "$fopen"; } @@ -3327,17 +3174,16 @@ public: bool isOutputter() const override { return true; } bool isUnlikely() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op1p(); } - AstNode* filenamep() const { return op2p(); } - AstNode* modep() const { return op3p(); } }; class AstFOpenMcd final : public AstNodeStmt { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) + // @astgen op1 := filep : AstNode + // @astgen op2 := filenamep : AstNode public: AstFOpenMcd(FileLine* fl, AstNode* filep, AstNode* filenamep) : ASTGEN_SUPER_FOpenMcd(fl) { - setOp1p(filep); - setOp2p(filenamep); + this->filep(filep); + this->filenamep(filenamep); } ASTGEN_MEMBERS_FOpenMcd; string verilogKwd() const override { return "$fopen"; } @@ -3347,8 +3193,6 @@ public: bool isOutputter() const override { return true; } bool isUnlikely() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* filep() const { return op1p(); } - AstNode* filenamep() const { return op2p(); } }; class AstFinish final : public AstNodeStmt { public: @@ -3364,24 +3208,26 @@ public: bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } }; class AstForeach final : public AstNodeStmt { + // @astgen op1 := arrayp : AstNode + // @astgen op2 := stmtsp : List[AstNode] public: - AstForeach(FileLine* fl, AstNode* arrayp, AstNode* bodysp) + AstForeach(FileLine* fl, AstNode* arrayp, AstNode* stmtsp) : ASTGEN_SUPER_Foreach(fl) { - setOp1p(arrayp); - addNOp4p(bodysp); + this->arrayp(arrayp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_Foreach; - AstNode* arrayp() const { return op1p(); } // op1 = array and index vars - AstNode* bodysp() const { return op4p(); } // op4 = body of loop bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } bool same(const AstNode* /*samep*/) const override { return true; } - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstJumpBlock final : public AstNodeStmt { // Block of code including a JumpGo and JumpLabel // Parents: {statement list} // Children: {statement list, with JumpGo and JumpLabel below} + // @astgen op1 := stmtsp : List[AstNode] + // @astgen op2 := endStmtsp : List[AstNode] private: AstJumpLabel* m_labelp = nullptr; // [After V3Jump] Pointer to declaration int m_labelNum = 0; // Set by V3EmitCSyms to tell final V3Emit what to increment @@ -3389,7 +3235,7 @@ public: // After construction must call ->labelp to associate with appropriate label AstJumpBlock(FileLine* fl, AstNode* stmtsp) : ASTGEN_SUPER_JumpBlock(fl) { - addNOp1p(stmtsp); + this->addStmtsp(stmtsp); } const char* broken() const override; void cloneRelink() override; @@ -3397,11 +3243,6 @@ public: int instrCount() const override { return 0; } bool maybePointedTo() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - // op1 = Statements - AstNode* stmtsp() const { return op1p(); } // op1 = List of statements - void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } - AstNode* endStmtsp() const { return op2p(); } // op1 = List of end-of-block - void addEndStmtsp(AstNode* nodep) { addNOp2p(nodep); } int labelNum() const { return m_labelNum; } void labelNum(int flag) { m_labelNum = flag; } AstJumpLabel* labelp() const { return m_labelp; } @@ -3500,57 +3341,57 @@ public: }; class AstRelease final : public AstNodeStmt { // Procedural 'release' statement + // @astgen op1 := lhsp : AstNode public: AstRelease(FileLine* fl, AstNode* lhsp) : ASTGEN_SUPER_Release(fl) { - setOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_Release; - AstNode* lhsp() const { return op1p(); } }; class AstRepeat final : public AstNodeStmt { + // @astgen op1 := countp : AstNode + // @astgen op2 := stmtsp : List[AstNode] public: - AstRepeat(FileLine* fl, AstNode* countp, AstNode* bodysp) + AstRepeat(FileLine* fl, AstNode* countp, AstNode* stmtsp) : ASTGEN_SUPER_Repeat(fl) { - setOp2p(countp); - addNOp3p(bodysp); + this->countp(countp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_Repeat; - AstNode* countp() const { return op2p(); } // op2 = condition to continue - AstNode* bodysp() const { return op3p(); } // op3 = body of loop bool isGateOptimizable() const override { return false; } // Not relevant - converted to FOR int instrCount() const override { return INSTR_COUNT_BRANCH; } bool same(const AstNode* /*samep*/) const override { return true; } - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstReturn final : public AstNodeStmt { + // @astgen op1 := lhsp : Optional[AstNode] public: explicit AstReturn(FileLine* fl, AstNode* lhsp = nullptr) : ASTGEN_SUPER_Return(fl) { - setNOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_Return; string verilogKwd() const override { return "return"; } - AstNode* lhsp() const { return op1p(); } bool isBrancher() const override { return true; // SPECIAL: We don't process code after breaks } }; class AstSFormat final : public AstNodeStmt { // Parents: statement container - // Children: string to load - // Children: SFORMATF to generate print string + // @astgen op1 := fmtp : AstSFormatF + // @astgen op2 := lhsp : AstNode public: AstSFormat(FileLine* fl, AstNode* lhsp, const string& text, AstNode* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_SFormat(fl) { - setOp1p(new AstSFormatF(fl, text, true, exprsp, missingArgChar)); - setOp3p(lhsp); + this->fmtp(new AstSFormatF{fl, text, true, exprsp, missingArgChar}); + this->lhsp(lhsp); } AstSFormat(FileLine* fl, AstNode* lhsp, AstNode* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_SFormat(fl) { - setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp, missingArgChar)); - setOp3p(lhsp); + this->fmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp, missingArgChar}); + this->lhsp(lhsp); } ASTGEN_MEMBERS_SFormat; const char* broken() const override { @@ -3565,10 +3406,6 @@ public: virtual bool cleanOut() const { return false; } int instrCount() const override { return INSTR_COUNT_PLI; } bool same(const AstNode* /*samep*/) const override { return true; } - void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter - AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); } - AstNode* lhsp() const { return op3p(); } - void lhsp(AstNode* nodep) { setOp3p(nodep); } }; class AstStop final : public AstNodeStmt { public: @@ -3585,12 +3422,11 @@ public: }; class AstSysFuncAsTask final : public AstNodeStmt { // Call what is normally a system function (with a return) in a non-return context - // Parents: stmtlist - // Children: a system function + // @astgen op1 := lhsp : AstNode public: - AstSysFuncAsTask(FileLine* fl, AstNode* exprsp) + AstSysFuncAsTask(FileLine* fl, AstNode* lhsp) : ASTGEN_SUPER_SysFuncAsTask(fl) { - addNOp1p(exprsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_SysFuncAsTask; string verilogKwd() const override { return ""; } @@ -3600,16 +3436,13 @@ public: bool isOutputter() const override { return false; } int instrCount() const override { return 0; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* lhsp() const { return op1p(); } // op1 = Expressions to eval - void lhsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to eval }; class AstSysIgnore final : public AstNodeStmt { - // Parents: stmtlist - // Children: varrefs or exprs + // @astgen op1 := exprsp : List[AstNode] // Expressions to output (???) public: AstSysIgnore(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_SysIgnore(fl) { - addNOp1p(exprsp); + this->addExprsp(exprsp); } ASTGEN_MEMBERS_SysIgnore; string verilogKwd() const override { return "$ignored"; } @@ -3618,15 +3451,14 @@ public: bool isPure() const override { return false; } // Though deleted before opt bool isOutputter() const override { return true; } // Though deleted before opt int instrCount() const override { return INSTR_COUNT_PLI; } - AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output - void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output }; class AstSystemT final : public AstNodeStmt { // $system used as task + // @astgen op1 := lhsp : AstNode public: AstSystemT(FileLine* fl, AstNode* lhsp) : ASTGEN_SUPER_SystemT(fl) { - setOp1p(lhsp); + this->lhsp(lhsp); } ASTGEN_MEMBERS_SystemT; string verilogKwd() const override { return "$system"; } @@ -3636,18 +3468,21 @@ public: bool isOutputter() const override { return true; } bool isUnlikely() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } - AstNode* lhsp() const { return op1p(); } }; class AstTimeFormat final : public AstNodeStmt { // Parents: stmtlist + // @astgen op1 := unitsp : AstNode + // @astgen op2 := precisionp : AstNode + // @astgen op3 := suffixp : AstNode + // @astgen op4 := widthp : AstNode public: AstTimeFormat(FileLine* fl, AstNode* unitsp, AstNode* precisionp, AstNode* suffixp, AstNode* widthp) : ASTGEN_SUPER_TimeFormat(fl) { - setOp1p(unitsp); - setOp2p(precisionp); - setOp3p(suffixp); - setOp4p(widthp); + this->unitsp(unitsp); + this->precisionp(precisionp); + this->suffixp(suffixp); + this->widthp(widthp); } ASTGEN_MEMBERS_TimeFormat; string verilogKwd() const override { return "$timeformat"; } @@ -3656,16 +3491,12 @@ public: bool isPure() const override { return false; } bool isOutputter() const override { return true; } int instrCount() const override { return INSTR_COUNT_PLI; } - AstNode* unitsp() const { return op1p(); } - AstNode* precisionp() const { return op2p(); } - AstNode* suffixp() const { return op3p(); } - AstNode* widthp() const { return op4p(); } }; class AstTraceDecl final : public AstNodeStmt { // Trace point declaration // Separate from AstTraceInc; as a declaration can't be deleted // Parents: {statement list} - // Children: expression being traced + // @astgen op1 := valuep : AstNode // Expressio being traced private: uint32_t m_code = 0; // Trace identifier code; converted to ASCII by trace routines const string m_showname; // Name of variable @@ -3690,7 +3521,7 @@ public: , m_declKwd{varp->declKwd()} , m_declDirection{varp->declDirection()} { dtypeFrom(valuep); - addNOp1p(valuep); + this->valuep(valuep); } void dump(std::ostream& str) const override; int instrCount() const override { return 100; } // Large... @@ -3709,13 +3540,11 @@ public: VVarType varType() const { return m_varType; } VBasicDTypeKwd declKwd() const { return m_declKwd; } VDirection declDirection() const { return m_declDirection; } - AstNode* valuep() const { return op1p(); } }; class AstTraceInc final : public AstNodeStmt { // Trace point dump - // Parents: {statement list} - // Children: op1: things to emit before this node, - // op2: expression being traced (from decl) + // @astgen op1 := precondsp : List[AstNode] // Statements to emit before this node + // @astgen op2 := valuep : AstNode // Expression being traced (from decl) private: AstTraceDecl* m_declp; // Pointer to declaration @@ -3729,7 +3558,8 @@ public: , m_full{full} , m_baseCode{baseCode} { dtypeFrom(declp); - addOp2p(declp->valuep()->cloneTree(true)); + this->valuep( + declp->valuep()->cloneTree(true)); // TODO: maybe use reference to TraceDecl instead? } ASTGEN_MEMBERS_TraceInc; const char* broken() const override { @@ -3749,10 +3579,6 @@ public: bool isPredictOptimizable() const override { return false; } bool isOutputter() const override { return true; } // but isPure() true - // op1 = Statements before the value - AstNode* precondsp() const { return op1p(); } - void addPrecondsp(AstNode* newp) { addOp1p(newp); } - AstNode* valuep() const { return op2p(); } AstTraceDecl* declp() const { return m_declp; } bool full() const { return m_full; } uint32_t baseCode() const { return m_baseCode; } @@ -3779,13 +3605,13 @@ public: }; class AstUCStmt final : public AstNodeStmt { // User $c statement + // @astgen op1 := exprsp : List[AstNode] public: AstUCStmt(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_UCStmt(fl) { - addNOp1p(exprsp); + this->addExprsp(exprsp); } ASTGEN_MEMBERS_UCStmt; - AstNode* bodysp() const { return op1p(); } // op1 = expressions to print bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool isPure() const override { return false; } @@ -3793,15 +3619,16 @@ public: bool same(const AstNode* /*samep*/) const override { return true; } }; class AstWait final : public AstNodeStmt { + // @astgen op1 := condp : AstNode + // @astgen op2 := stmtsp : List[AstNode] public: - AstWait(FileLine* fl, AstNode* condp, AstNode* bodysp) + AstWait(FileLine* fl, AstNode* condp, AstNode* stmtsp) : ASTGEN_SUPER_Wait(fl) { - setOp2p(condp); - addNOp3p(bodysp); + this->condp(condp); + this->addStmtsp(stmtsp); } ASTGEN_MEMBERS_Wait; - AstNode* bodysp() const { return op3p(); } // op3 = body of loop - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstWaitFork final : public AstNodeStmt { // A "wait fork" statement @@ -3811,22 +3638,18 @@ public: ASTGEN_MEMBERS_WaitFork; }; class AstWhile final : public AstNodeStmt { + // @astgen op1 := precondsp : List[AstNode] + // @astgen op2 := condp : AstNode + // @astgen op3 := stmtsp : List[AstNode] + // @astgen op4 := incsp : List[AstNode] public: - AstWhile(FileLine* fl, AstNode* condp, AstNode* bodysp = nullptr, AstNode* incsp = nullptr) + AstWhile(FileLine* fl, AstNode* condp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr) : ASTGEN_SUPER_While(fl) { - setOp2p(condp); - addNOp3p(bodysp); - addNOp4p(incsp); + this->condp(condp); + this->addStmtsp(stmtsp); + this->addIncsp(incsp); } ASTGEN_MEMBERS_While; - // op1 = prepare statements for condition (exec every loop) - AstNode* precondsp() const { return op1p(); } - AstNode* condp() const { return op2p(); } // op2 = condition to continue - AstNode* bodysp() const { return op3p(); } // op3 = body of loop - AstNode* incsp() const { return op4p(); } // op4 = increment (if from a FOR loop) - void addPrecondsp(AstNode* newp) { addOp1p(newp); } - void addBodysp(AstNode* newp) { addOp3p(newp); } - void addIncsp(AstNode* newp) { addOp4p(newp); } bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } bool same(const AstNode* /*samep*/) const override { return true; } @@ -3834,7 +3657,7 @@ public: void addBeforeStmt(AstNode* newp, AstNode* belowp) override; // Stop statement searchback here void addNextStmt(AstNode* newp, AstNode* belowp) override; - bool isFirstInMyListOfStatements(AstNode* n) const override { return n == bodysp(); } + bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstWith final : public AstNodeStmt { // Used as argument to method, then to AstCMethodHard @@ -3843,13 +3666,16 @@ class AstWith final : public AstNodeStmt { // Children: LambdaArgRef that declares the item variable // Children: LambdaArgRef that declares the item.index variable // Children: math (equation establishing the with) + // @astgen op1 := indexArgRefp : AstLambdaArgRef + // @astgen op2 := valueArgRefp : AstLambdaArgRef + // @astgen op3 := exprp : AstNode public: AstWith(FileLine* fl, AstLambdaArgRef* indexArgRefp, AstLambdaArgRef* valueArgRefp, AstNode* exprp) : ASTGEN_SUPER_With(fl) { - addOp1p((AstNode*)indexArgRefp); - addOp2p((AstNode*)valueArgRefp); - addNOp3p(exprp); + this->indexArgRefp(indexArgRefp); + this->valueArgRefp(valueArgRefp); + this->exprp(exprp); } ASTGEN_MEMBERS_With; bool same(const AstNode* /*samep*/) const override { return true; } @@ -3859,28 +3685,23 @@ public: BROKEN_RTN(!valueArgRefp()); // varp needed to know lambda's arg dtype return nullptr; } - // - AstLambdaArgRef* indexArgRefp() const { return VN_AS(op1p(), LambdaArgRef); } - AstLambdaArgRef* valueArgRefp() const { return VN_AS(op2p(), LambdaArgRef); } - AstNode* exprp() const { return op3p(); } }; class AstWithParse final : public AstNodeStmt { // In early parse, FUNC(index) WITH equation-using-index // Replaced with AstWith // Parents: math|stmt // Children: funcref, math + // @astgen op1 := funcrefp : AstNode + // @astgen op2 := exprp : Optional[AstNode] public: AstWithParse(FileLine* fl, bool stmt, AstNode* funcrefp, AstNode* exprp) : ASTGEN_SUPER_WithParse(fl) { statement(stmt); - setOp1p(funcrefp); - addNOp2p(exprp); + this->funcrefp(funcrefp); + this->exprp(exprp); } ASTGEN_MEMBERS_WithParse; bool same(const AstNode* /*samep*/) const override { return true; } - // - AstNode* funcrefp() const { return op1p(); } - AstNode* exprp() const { return op2p(); } }; // === AstNodeAssign === @@ -3966,12 +3787,11 @@ public: }; class AstAssignW final : public AstNodeAssign { // Like assign, but wire/assign's in verilog, the only setting of the specified variable + // @astgen op4 := strengthSpecp : Optional[AstStrengthSpec] public: AstAssignW(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : ASTGEN_SUPER_AssignW(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AssignW; - AstStrengthSpec* strengthSpecp() const { return VN_AS(op4p(), StrengthSpec); } - void strengthSpecp(AstStrengthSpec* const strengthSpecp) { setOp4p((AstNode*)strengthSpecp); } AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { return new AstAssignW(this->fileline(), lhsp, rhsp); } @@ -4006,11 +3826,11 @@ public: class AstCMethodCall final : public AstNodeCCall { // C++ method call // Parents: Anything above a statement - // Children: Args to the function + // @astgen op1 := fromp : AstNode public: AstCMethodCall(FileLine* fl, AstNode* fromp, AstCFunc* funcp, AstNode* argsp = nullptr) : ASTGEN_SUPER_CMethodCall(fl, funcp, argsp) { - setOp1p(fromp); + this->fromp(fromp); } ASTGEN_MEMBERS_CMethodCall; const char* broken() const override { @@ -4018,10 +3838,6 @@ public: BROKEN_RTN(!fromp()); return nullptr; } - AstNode* fromp() const { - return op1p(); - } // op1 = Extracting what (nullptr=TBD during parsing) - void fromp(AstNode* nodep) { setOp1p(nodep); } }; class AstCNew final : public AstNodeCCall { // C++ new() call @@ -4040,8 +3856,6 @@ public: class AstCase final : public AstNodeCase { // Case statement // Parents: {statement list} - // exprp Children: MATHs - // casesp Children: CASEITEMs private: VCaseType m_casex; // 0=case, 1=casex, 2=casez bool m_fullPragma = false; // Synthesis full_case @@ -4050,8 +3864,8 @@ private: bool m_unique0Pragma = false; // unique0 case bool m_priorityPragma = false; // priority case public: - AstCase(FileLine* fl, VCaseType casex, AstNode* exprp, AstNode* casesp) - : ASTGEN_SUPER_Case(fl, exprp, casesp) + AstCase(FileLine* fl, VCaseType casex, AstNode* exprp, AstCaseItem* itemsp) + : ASTGEN_SUPER_Case(fl, exprp, itemsp) , m_casex{casex} {} ASTGEN_MEMBERS_Case; string verilogKwd() const override { return casez() ? "casez" : casex() ? "casex" : "case"; } @@ -4077,44 +3891,41 @@ public: class AstGenCase final : public AstNodeCase { // Generate Case statement // Parents: {statement list} - // exprp Children: MATHs - // casesp Children: CASEITEMs public: - AstGenCase(FileLine* fl, AstNode* exprp, AstNode* casesp) - : ASTGEN_SUPER_GenCase(fl, exprp, casesp) {} + AstGenCase(FileLine* fl, AstNode* exprp, AstCaseItem* itemsp) + : ASTGEN_SUPER_GenCase(fl, exprp, itemsp) {} ASTGEN_MEMBERS_GenCase; }; // === AstNodeCoverOrAssert === class AstAssert final : public AstNodeCoverOrAssert { + // @astgen op3 := failsp: List[AstNode] // Statments when propp is failing/falsey public: ASTGEN_MEMBERS_Assert; AstAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp, bool immediate, const string& name = "") : ASTGEN_SUPER_Assert(fl, propp, passsp, immediate, name) { - addNOp3p(failsp); + this->addFailsp(failsp); } - AstNode* failsp() const { return op3p(); } // op3 = if assertion fails }; class AstAssertIntrinsic final : public AstNodeCoverOrAssert { // A $cast or other compiler inserted assert, that must run even without --assert option + // @astgen op3 := failsp: List[AstNode] // Statments when propp is failing/falsey public: ASTGEN_MEMBERS_AssertIntrinsic; AstAssertIntrinsic(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp, bool immediate, const string& name = "") : ASTGEN_SUPER_AssertIntrinsic(fl, propp, passsp, immediate, name) { - addNOp3p(failsp); + this->addFailsp(failsp); } - AstNode* failsp() const { return op3p(); } // op3 = if assertion fails }; class AstCover final : public AstNodeCoverOrAssert { + // @astgen op3 := coverincsp: List[AstNode] // Coverage node public: ASTGEN_MEMBERS_Cover; AstCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, bool immediate, const string& name = "") : ASTGEN_SUPER_Cover(fl, propp, stmtsp, immediate, name) {} - AstNode* coverincp() const { return op3p(); } // op3 = coverage node - void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node virtual bool immediate() const { return false; } }; class AstRestrict final : public AstNodeCoverOrAssert { @@ -4140,16 +3951,18 @@ class AstMethodCall final : public AstNodeFTaskRef { // PARENTS: stmt/math // Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal. // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it + // @astgen op2 := fromp : AstNode + // public: AstMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp) : ASTGEN_SUPER_MethodCall(fl, false, name, pinsp) { - setOp2p(fromp); + this->fromp(fromp); dtypep(nullptr); // V3Width will resolve } AstMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) : ASTGEN_SUPER_MethodCall(fl, false, name, pinsp) { - setOp2p(fromp); + this->fromp(fromp); } ASTGEN_MEMBERS_MethodCall; const char* broken() const override { @@ -4163,10 +3976,6 @@ public: statement(true); dtypeSetVoid(); } - AstNode* fromp() const { - return op2p(); - } // op2 = Extracting what (nullptr=TBD during parsing) - void fromp(AstNode* nodep) { setOp2p(nodep); } }; class AstNew final : public AstNodeFTaskRef { // New as constructor @@ -4197,16 +4006,16 @@ public: // === AstNodeFor === class AstGenFor final : public AstNodeFor { public: - AstGenFor(FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) - : ASTGEN_SUPER_GenFor(fl, initsp, condp, incsp, bodysp) {} + AstGenFor(FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* stmtsp) + : ASTGEN_SUPER_GenFor(fl, initsp, condp, incsp, stmtsp) {} ASTGEN_MEMBERS_GenFor; }; // === AstNodeIf === class AstGenIf final : public AstNodeIf { public: - AstGenIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp) - : ASTGEN_SUPER_GenIf(fl, condp, ifsp, elsesp) {} + AstGenIf(FileLine* fl, AstNode* condp, AstNode* thensp, AstNode* elsesp) + : ASTGEN_SUPER_GenIf(fl, condp, thensp, elsesp) {} ASTGEN_MEMBERS_GenIf; }; class AstIf final : public AstNodeIf { @@ -4215,8 +4024,8 @@ private: bool m_unique0Pragma = false; // unique0 case bool m_priorityPragma = false; // priority case public: - AstIf(FileLine* fl, AstNode* condp, AstNode* ifsp = nullptr, AstNode* elsesp = nullptr) - : ASTGEN_SUPER_If(fl, condp, ifsp, elsesp) {} + AstIf(FileLine* fl, AstNode* condp, AstNode* thensp = nullptr, AstNode* elsesp = nullptr) + : ASTGEN_SUPER_If(fl, condp, thensp, elsesp) {} ASTGEN_MEMBERS_If; bool uniquePragma() const { return m_uniquePragma; } void uniquePragma(bool flag) { m_uniquePragma = flag; } @@ -4304,7 +4113,7 @@ public: ASTGEN_MEMBERS_Text; }; class AstTextBlock final : public AstNodeSimpleText { -private: + // @astgen op1 := nodesp : List[AstNode] bool m_commas; // Comma separate emitted children public: explicit AstTextBlock(FileLine* fl, const string& textp = "", bool tracking = false, @@ -4314,10 +4123,8 @@ public: ASTGEN_MEMBERS_TextBlock; void commas(bool flag) { m_commas = flag; } bool commas() const { return m_commas; } - AstNode* nodesp() const { return op1p(); } - void addNodep(AstNode* nodep) { addOp1p(nodep); } void addText(FileLine* fl, const string& textp, bool tracking = false) { - addNodep(new AstText(fl, textp, tracking)); + addNodesp(new AstText(fl, textp, tracking)); } }; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 5bbc6bf42..172b4cec1 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -188,8 +188,8 @@ void AstBasicDType::init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int widthForce(rangep->elementsConst(), rangep->elementsConst()); // Maybe unknown if parameters underneath it } - setNOp1p(rangep); - dtypep(this); + this->rangep(rangep); + this->dtypep(this); } void AstBasicDType::cvtRangeConst() { @@ -660,25 +660,15 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) { } else { return nullptr; } - } else if (VN_IS(nodep, VarRef)) { - if (VN_AS(nodep, VarRef)->varp()->isSc()) { - return VN_AS(nodep, VarRef)->varp(); + } else if (AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) { + if (vrefp->varp()->isSc()) { + return vrefp->varp(); } else { return nullptr; } - } else if (VN_IS(nodep, ArraySel)) { - if (nodep->op1p()) { - if (AstVar* p = scVarRecurse(nodep->op1p())) return p; - } - if (nodep->op2p()) { - if (AstVar* p = scVarRecurse(nodep->op2p())) return p; - } - if (nodep->op3p()) { - if (AstVar* p = scVarRecurse(nodep->op3p())) return p; - } - if (nodep->op4p()) { - if (AstVar* p = scVarRecurse(nodep->op4p())) return p; - } + } else if (AstArraySel* const arraySelp = VN_CAST(nodep, ArraySel)) { + if (AstVar* const p = scVarRecurse(arraySelp->fromp())) return p; + if (AstVar* const p = scVarRecurse(arraySelp->bitp())) return p; } return nullptr; } @@ -1070,8 +1060,8 @@ AstConstPool::AstConstPool(FileLine* fl) : ASTGEN_SUPER_ConstPool(fl) , m_modp{new AstModule(fl, "@CONST-POOL@")} , m_scopep{new AstScope(fl, m_modp, "@CONST-POOL@", nullptr, nullptr)} { - addOp1p(m_modp); - m_modp->addStmtp(m_scopep); + this->modulep(m_modp); + m_modp->addStmtsp(m_scopep); } const char* AstConstPool::broken() const { BROKEN_RTN(m_modp && !m_modp->brokeExists()); @@ -1085,9 +1075,9 @@ AstVarScope* AstConstPool::createNewEntry(const string& name, AstNode* initp) { varp->isConst(true); varp->isStatic(true); varp->valuep(initp->cloneTree(false)); - m_modp->addStmtp(varp); + m_modp->addStmtsp(varp); AstVarScope* const varScopep = new AstVarScope(fl, m_scopep, varp); - m_scopep->addVarp(varScopep); + m_scopep->addVarsp(varScopep); return varScopep; } @@ -1233,7 +1223,7 @@ void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) { } else if (belowp == condp()) { // Goes before condition, IE in preconditions addPrecondsp(newp); - } else if (belowp == bodysp()) { + } else if (belowp == stmtsp()) { // Was first statement in body, so new front belowp->addHereThisAsNext(newp); } else { @@ -1250,12 +1240,12 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) { belowp->addNextHere(newp); } else if (belowp == condp()) { // Becomes first statement in body, body may have been empty - if (bodysp()) { - bodysp()->addHereThisAsNext(newp); + if (stmtsp()) { + stmtsp()->addHereThisAsNext(newp); } else { - addBodysp(newp); + addStmtsp(newp); } - } else if (belowp == bodysp()) { + } else if (belowp == stmtsp()) { // Next statement in body belowp->addNextHere(newp); } else { @@ -1521,19 +1511,15 @@ void AstInitArray::cloneRelink() { if (it->second->clonep()) it->second = it->second->clonep(); } } -AstNode* AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) { - // Returns old value, caller must garbage collect - AstNode* oldp = nullptr; +void AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) { const auto it = m_map.find(index); if (it != m_map.end()) { - oldp = it->second->valuep(); it->second->valuep(newp); } else { AstInitItem* const itemp = new AstInitItem(fileline(), newp); m_map.emplace(index, itemp); - addOp2p(itemp); + addInitsp(itemp); } - return oldp; } AstNode* AstInitArray::getIndexValuep(uint64_t index) const { const auto it = m_map.find(index); @@ -1808,7 +1794,7 @@ AstPackage* AstNetlist::dollarUnitPkgAddp() { m_dollarUnitPkgp->inLibrary(true); m_dollarUnitPkgp->modTrace(false); // may reconsider later m_dollarUnitPkgp->internal(true); - addModulep(m_dollarUnitPkgp); + addModulesp(m_dollarUnitPkgp); } return m_dollarUnitPkgp; } @@ -1816,7 +1802,7 @@ void AstNetlist::createTopScope(AstScope* scopep) { UASSERT(scopep, "Must not be nullptr"); UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits"); m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep}; - scopep->modp()->addStmtp(v3Global.rootp()->topScopep()); + scopep->modp()->addStmtsp(v3Global.rootp()->topScopep()); } void AstNodeModule::dump(std::ostream& str) const { this->AstNode::dump(str); diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index c9ceec09e..1f5abb9ce 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -115,7 +115,7 @@ private: } } else { // Move to module - m_modp->addStmtp(nodep); + m_modp->addStmtsp(nodep); } } @@ -214,7 +214,7 @@ private: UINFO(8, " rename to " << nodep->name() << endl); // Move to module nodep->unlinkFrBack(); - m_modp->addStmtp(nodep); + m_modp->addStmtsp(nodep); } iterateChildren(nodep); } @@ -233,10 +233,10 @@ private: const string scname = nodep->forFormat() ? m_displayScope : m_namedScope; if (!scname.empty()) { // To keep correct visual order, must add before other Text's - AstNode* const afterp = nodep->scopeAttrp(); + AstText* const afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); - nodep->scopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname}); - if (afterp) nodep->scopeAttrp(afterp); + nodep->addScopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname}); + if (afterp) nodep->addScopeAttrp(afterp); } iterateChildren(nodep); } diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp index eed4e49fc..8cd525687 100644 --- a/src/V3Branch.cpp +++ b/src/V3Branch.cpp @@ -70,7 +70,7 @@ private: { // Do if reset(); - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); const int ifLikely = m_likely; const int ifUnlikely = m_unlikely; // Do else diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index dd4978eca..2be4316d6 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -275,9 +275,9 @@ private: pushLocalScope(); processEnter(nodep); processAndIterate(nodep->condp()); - if (AstNode* const ifsp = nodep->ifsp()) { + if (AstNode* const thensp = nodep->thensp()) { pushLocalScope(); - processAndIterateList(ifsp); + processAndIterateList(thensp); popLocalScope(); } if (AstNode* const elsesp = nodep->elsesp()) { diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index 090009c24..e37b4e884 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -77,7 +77,7 @@ private: if (!preventUnusedStmt.empty()) { funcp->addStmtsp(new AstCStmt{m_modp->fileline(), preventUnusedStmt}); } - m_modp->addStmtp(funcp); + m_modp->addStmtsp(funcp); m_numStmts = 0; return funcp; } @@ -136,7 +136,7 @@ void V3CCtors::evalAsserts() { funcp->isLoose(true); funcp->slow(false); funcp->ifdef("VL_DEBUG"); - modp->addStmtp(funcp); + modp->addStmtsp(funcp); for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { if (AstVar* const varp = VN_CAST(np, Var)) { if (varp->isPrimaryInish() && !varp->isSc()) { @@ -209,7 +209,7 @@ void V3CCtors::cctorsAll() { // If can be referred to by base pointer, need virtual delete funcp->isVirtual(classp->isExtended()); funcp->slow(false); - modp->addStmtp(funcp); + modp->addStmtsp(funcp); } } } diff --git a/src/V3CUse.cpp b/src/V3CUse.cpp index 5bf6bfe69..adc33fccd 100644 --- a/src/V3CUse.cpp +++ b/src/V3CUse.cpp @@ -51,7 +51,7 @@ class CUseVisitor final : public VNVisitor { void addNewUse(AstNode* nodep, VUseType useType, const string& name) { if (m_didUse.emplace(useType, name).second) { AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name}; - m_modp->addStmtp(newp); + m_modp->addStmtsp(newp); UINFO(8, "Insert " << newp << endl); } } diff --git a/src/V3Case.cpp b/src/V3Case.cpp index 58a160301..d469978e2 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -245,7 +245,7 @@ private: // Convert valueItem from AstCaseItem* to the expression // Not done earlier, as we may now have a nullptr because it's just a ";" NOP branch for (uint32_t i = 0; i < numCases; ++i) { - m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->bodysp(); + m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->stmtsp(); } return true; // All is fine } @@ -346,7 +346,7 @@ private: itemp = VN_AS(itemp->nextp(), CaseItem)) { if (!itemp->condsp()) { // Default clause. Just make true, we'll optimize it away later - itemp->condsp(new AstConst(itemp->fileline(), AstConst::BitTrue())); + itemp->addCondsp(new AstConst(itemp->fileline(), AstConst::BitTrue())); hadDefault = true; } else { // Expressioned clause @@ -397,7 +397,7 @@ private: } } // Replace expression in tree - itemp->condsp(ifexprp); + itemp->addCondsp(ifexprp); } } VL_DO_DANGLING(cexprp->deleteTree(), cexprp); @@ -420,7 +420,7 @@ private: AstIf* itemnextp = nullptr; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) { - AstNode* const istmtsp = itemp->bodysp(); // Maybe null -- no action. + AstNode* const istmtsp = itemp->stmtsp(); // Maybe null -- no action. if (istmtsp) istmtsp->unlinkFrBackWithNext(); // Expressioned clause AstNode* const ifexprp = itemp->condsp()->unlinkFrBack(); @@ -452,7 +452,7 @@ private: if (itemnextp) { itemnextp->addElsesp(newp); } else { - groupnextp->addIfsp(newp); // First in a new group + groupnextp->addThensp(newp); // First in a new group } itemnextp = newp; } diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index f99b40284..067d0d0a7 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -67,7 +67,7 @@ public: m_tlChgFuncp->isStatic(false); m_tlChgFuncp->isLoose(true); m_tlChgFuncp->declPrivate(true); - m_scopetopp->addActivep(m_tlChgFuncp); + m_scopetopp->addBlocksp(m_tlChgFuncp); // Each change detection function needs at least one AstChangeDet // to ensure that V3EmitC outputs the necessary code. maybeCreateMidChg(); @@ -86,7 +86,7 @@ public: m_chgFuncp->isStatic(false); m_chgFuncp->isLoose(true); m_chgFuncp->declPrivate(true); - m_scopetopp->addActivep(m_chgFuncp); + m_scopetopp->addBlocksp(m_chgFuncp); // Add a top call to it AstCCall* const callp = new AstCCall{m_scopetopp->fileline(), m_chgFuncp}; @@ -218,9 +218,9 @@ public: // CHANGEDET(VARREF(_last), VARREF(var)) AstVar* const newvarp = new AstVar{varp->fileline(), VVarType::MODULETEMP, newvarname, varp}; - m_state.m_topModp->addStmtp(newvarp); + m_state.m_topModp->addStmtsp(newvarp); m_newvscp = new AstVarScope{m_vscp->fileline(), m_state.m_scopetopp, newvarp}; - m_state.m_scopetopp->addVarp(m_newvscp); + m_state.m_scopetopp->addVarsp(m_newvscp); m_varEqnp = new AstVarRef{m_vscp->fileline(), m_vscp, VAccess::READ}; m_newLvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::WRITE}; diff --git a/src/V3Class.cpp b/src/V3Class.cpp index 52a7c0f1f..f89be682d 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -54,7 +54,7 @@ private: // Move this class nodep->name(m_prefix + nodep->name()); nodep->unlinkFrBack(); - v3Global.rootp()->addModulep(nodep); + v3Global.rootp()->addModulesp(nodep); // Make containing package // Note origName is the same as the class origName so errors look correct AstClassPackage* const packagep @@ -62,7 +62,7 @@ private: packagep->name(nodep->name() + "__Vclpkg"); nodep->classOrPackagep(packagep); packagep->classp(nodep); - v3Global.rootp()->addModulep(packagep); + v3Global.rootp()->addModulesp(packagep); // Add package to hierarchy AstCell* const cellp = new AstCell{packagep->fileline(), packagep->fileline(), @@ -72,7 +72,7 @@ private: nullptr, nullptr}; cellp->modp(packagep); - v3Global.rootp()->topModulep()->addStmtp(cellp); + v3Global.rootp()->topModulep()->addStmtsp(cellp); // Find class's scope // Alternative would be to move this and related to V3Scope const AstScope* classScopep = nullptr; @@ -85,7 +85,7 @@ private: AstScope* const scopep = new AstScope{nodep->fileline(), packagep, classScopep->name(), classScopep->aboveScopep(), classScopep->aboveCellp()}; - packagep->addStmtp(scopep); + packagep->addStmtsp(scopep); // Iterate VL_RESTORER(m_prefix); VL_RESTORER(m_classPackagep); @@ -178,15 +178,15 @@ public: AstScope* const scopep = moved.second; UINFO(9, "moving " << nodep << " to " << scopep << endl); if (VN_IS(nodep, NodeFTask)) { - scopep->addActivep(nodep->unlinkFrBack()); + scopep->addBlocksp(nodep->unlinkFrBack()); } else if (VN_IS(nodep, Var)) { AstVarScope* const vscp = VN_AS(nodep->user1p(), VarScope); vscp->scopep(scopep); vscp->unlinkFrBack(); - scopep->addVarp(vscp); + scopep->addVarsp(vscp); } else if (VN_IS(nodep, Initial) || VN_IS(nodep, InitialStatic)) { nodep->unlinkFrBack(); - scopep->addActivep(nodep); + scopep->addBlocksp(nodep); } else { nodep->v3fatalSrc("Bad case"); } @@ -196,7 +196,7 @@ public: AstNodeModule* const modp = moved.second; UINFO(9, "moving " << nodep << " to " << modp << endl); nodep->unlinkFrBack(); - modp->addStmtp(nodep); + modp->addStmtsp(nodep); } } }; diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 64fa0dcba..7817304a2 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -236,7 +236,7 @@ private: setClean(nodep, false); // We always clean, as we don't trust those pesky users. if (!VN_IS(nodep->backp(), And)) insertClean(nodep); - ensureCleanAndNext(nodep->bodysp()); + ensureCleanAndNext(nodep->exprsp()); } void visit(AstTraceDecl* nodep) override { // No cleaning, or would loose pointer to enum @@ -259,7 +259,7 @@ private: void visit(AstNodeCond* nodep) override { iterateChildren(nodep); ensureClean(nodep->condp()); - setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p())); + setClean(nodep, isClean(nodep->thenp()) && isClean(nodep->elsep())); } void visit(AstWhile* nodep) override { iterateChildren(nodep); @@ -276,7 +276,7 @@ private: } void visit(AstUCStmt* nodep) override { iterateChildren(nodep); - ensureCleanAndNext(nodep->bodysp()); + ensureCleanAndNext(nodep->exprsp()); } void visit(AstNodeCCall* nodep) override { iterateChildren(nodep); diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 95e10270d..ed6f5cc1f 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -102,10 +102,10 @@ private: AstVar* const newvarp = new AstVar(vscp->fileline(), VVarType::MODULETEMP, newvarname, VFlagLogicPacked{}, 1); newvarp->noReset(true); // Reset by below assign - m_modp->addStmtp(newvarp); + m_modp->addStmtsp(newvarp); AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp); vscp->user1p(newvscp); - m_scopep->addVarp(newvscp); + m_scopep->addVarsp(newvscp); // Add init AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, VAccess::READ); if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp); @@ -202,7 +202,7 @@ private: funcp->slow(slow); funcp->isConst(false); funcp->declPrivate(true); - m_topScopep->scopep()->addActivep(funcp); + m_topScopep->scopep()->addBlocksp(funcp); return funcp; } void splitCheck(AstCFunc* ofuncp) { @@ -229,7 +229,7 @@ private: funcp->isStatic(false); funcp->isLoose(true); funcp->slow(ofuncp->slow()); - m_topScopep->scopep()->addActivep(funcp); + m_topScopep->scopep()->addBlocksp(funcp); // AstCCall* const callp = new AstCCall{funcp->fileline(), funcp}; ofuncp->addStmtsp(callp); @@ -297,7 +297,7 @@ private: m_scopep = nullptr; } void visit(AstNodeProcedure* nodep) override { - if (AstNode* const stmtsp = nodep->bodysp()) { + if (AstNode* const stmtsp = nodep->stmtsp()) { stmtsp->unlinkFrBackWithNext(); nodep->addNextHere(stmtsp); } @@ -316,7 +316,7 @@ private: // We could add another IF to detect posedges, and only increment if so. // It's another whole branch though versus a potential memory miss. // We'll go with the miss. - newp->addIfsp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false))); + newp->addThensp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false))); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } @@ -367,7 +367,7 @@ private: m_mtaskBodyp->addStmtsp(m_lastIfp); } // Move statements to if - m_lastIfp->addIfsp(stmtsp); + m_lastIfp->addThensp(stmtsp); } else if (nodep->hasInitial() || nodep->hasSettle()) { nodep->v3fatalSrc("MTask should not include initial/settle logic."); } else { @@ -393,7 +393,7 @@ private: addToEvalLoop(m_lastIfp); } // Move statements to if - m_lastIfp->addIfsp(stmtsp); + m_lastIfp->addThensp(stmtsp); } else if (nodep->hasInitial()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function diff --git a/src/V3Common.cpp b/src/V3Common.cpp index 76521a3fd..f64018c5b 100644 --- a/src/V3Common.cpp +++ b/src/V3Common.cpp @@ -43,7 +43,7 @@ static void makeVlToString(AstClass* nodep) { AstNode* const exprp = new AstCMath{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0}; exprp->dtypeSetString(); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); - nodep->addStmtp(funcp); + nodep->addStmtsp(funcp); } static void makeToString(AstClass* nodep) { AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "to_string", nullptr, "std::string"}; @@ -54,7 +54,7 @@ static void makeToString(AstClass* nodep) { = new AstCMath{nodep->fileline(), R"(std::string{"'{"} + to_string_middle() + "}")", 0}; exprp->dtypeSetString(); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); - nodep->addStmtp(funcp); + nodep->addStmtsp(funcp); } static void makeToStringMiddle(AstClass* nodep) { AstCFunc* const funcp @@ -96,7 +96,7 @@ static void makeToStringMiddle(AstClass* nodep) { funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt}); } funcp->addStmtsp(new AstCStmt{nodep->fileline(), "return out;\n"}); - nodep->addStmtp(funcp); + nodep->addStmtsp(funcp); } //###################################################################### diff --git a/src/V3Config.cpp b/src/V3Config.cpp index f716bba2b..5c6d77acf 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -193,11 +193,11 @@ public: const VPragmaType type = m_inlineValue ? VPragmaType::INLINE_MODULE : VPragmaType::NO_INLINE_MODULE; AstNode* const nodep = new AstPragma(modp->fileline(), type); - modp->addStmtp(nodep); + modp->addStmtsp(nodep); } for (const auto& itr : m_modPragmas) { AstNode* const nodep = new AstPragma{modp->fileline(), itr}; - modp->addStmtp(nodep); + modp->addStmtsp(nodep); } } diff --git a/src/V3Const.cpp b/src/V3Const.cpp index ba3b75edb..b94f49373 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1042,20 +1042,19 @@ private: // as high as possible, which is usally the right choice, except for this. AstNodeCond* const condp = VN_CAST(nodep->rhsp(), NodeCond); if (!condp) return false; - if (!VN_IS(condp->expr1p(), Const) && !VN_IS(condp->expr2p(), Const)) return false; + if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false; AstConst* const maskp = VN_CAST(nodep->lhsp(), Const); if (!maskp) return false; UINFO(4, "AND(CONSTm, CONDcond(c, i, e))->CONDcond(c, AND(m,i), AND(m, e)) " << nodep << endl); - AstNodeCond* const newp = static_cast( - condp->cloneType(condp->condp()->unlinkFrBack(), - new AstAnd(nodep->fileline(), maskp->cloneTree(false), - condp->expr1p()->unlinkFrBack()), - new AstAnd(nodep->fileline(), maskp->cloneTree(false), - condp->expr2p()->unlinkFrBack()))); + AstNodeCond* const newp = static_cast(condp->cloneType( + condp->condp()->unlinkFrBack(), + new AstAnd(nodep->fileline(), maskp->cloneTree(false), condp->thenp()->unlinkFrBack()), + new AstAnd(nodep->fileline(), maskp->cloneTree(false), + condp->elsep()->unlinkFrBack()))); newp->dtypeFrom(nodep); - newp->expr1p()->dtypeFrom(nodep); // As And might have been to change widths - newp->expr2p()->dtypeFrom(nodep); + newp->thenp()->dtypeFrom(nodep); // As And might have been to change widths + newp->elsep()->dtypeFrom(nodep); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; @@ -1443,19 +1442,19 @@ private: } } bool ifSameAssign(const AstNodeIf* nodep) { - const AstNodeAssign* const ifp = VN_CAST(nodep->ifsp(), NodeAssign); - const AstNodeAssign* const elsep = VN_CAST(nodep->elsesp(), NodeAssign); - if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement - if (!elsep || elsep->nextp()) return false; - if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign - if (!ifp->lhsp()->sameGateTree(elsep->lhsp())) return false; - if (!ifp->rhsp()->gateTree()) return false; - if (!elsep->rhsp()->gateTree()) return false; + const AstNodeAssign* const thensp = VN_CAST(nodep->thensp(), NodeAssign); + const AstNodeAssign* const elsesp = VN_CAST(nodep->elsesp(), NodeAssign); + if (!thensp || thensp->nextp()) return false; // Must be SINGLE statement + if (!elsesp || elsesp->nextp()) return false; + if (thensp->type() != elsesp->type()) return false; // Can't mix an assigndly with assign + if (!thensp->lhsp()->sameGateTree(elsesp->lhsp())) return false; + if (!thensp->rhsp()->gateTree()) return false; + if (!elsesp->rhsp()->gateTree()) return false; return true; } bool operandIfIf(const AstNodeIf* nodep) { if (nodep->elsesp()) return false; - const AstNodeIf* const lowerIfp = VN_CAST(nodep->ifsp(), NodeIf); + const AstNodeIf* const lowerIfp = VN_CAST(nodep->thensp(), NodeIf); if (!lowerIfp || lowerIfp->nextp()) return false; if (nodep->type() != lowerIfp->type()) return false; if (afterComment(lowerIfp->elsesp())) return false; @@ -2097,8 +2096,8 @@ private: AstVar* const temp2p = new AstVar(sel2p->fileline(), VVarType::BLOCKTEMP, m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1); - m_modp->addStmtp(temp1p); - m_modp->addStmtp(temp2p); + m_modp->addStmtsp(temp1p); + m_modp->addStmtsp(temp2p); AstNodeAssign* const asn1ap = VN_AS(nodep->cloneType( new AstVarRef(sel1p->fileline(), temp1p, VAccess::WRITE), sel1p), @@ -2862,7 +2861,7 @@ private: varrefp->unlinkFrBack(); AstInitial* const newinitp = new AstInitial( nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp)); - m_modp->addStmtp(newinitp); + m_modp->addStmtsp(newinitp); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); // Set the initial value right in the variable so we can constant propagate AstNode* const initvaluep = exprp->cloneTree(false); @@ -2892,7 +2891,7 @@ private: keepp = nodep->elsesp(); } else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl); - keepp = nodep->ifsp(); + keepp = nodep->thensp(); } else { UINFO(4, "IF condition is X, retaining: " << nodep << endl); return; @@ -2904,7 +2903,7 @@ private: nodep->unlinkFrBack(); } VL_DO_DANGLING(nodep->deleteTree(), nodep); - } else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) { + } else if (!afterComment(nodep->thensp()) && !afterComment(nodep->elsesp())) { if (!isTreePureRecurse(nodep->condp())) { // Condition has side effect - leave - perhaps in // future simplify to remove all but side effect terms @@ -2912,27 +2911,27 @@ private: // Empty block, remove it VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } - } else if (!afterComment(nodep->ifsp())) { + } else if (!afterComment(nodep->thensp())) { UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl); AstNode* const condp = nodep->condp(); AstNode* const elsesp = nodep->elsesp(); condp->unlinkFrBackWithNext(); elsesp->unlinkFrBackWithNext(); - if (nodep->ifsp()) { // Must have been comment - nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); + if (nodep->thensp()) { // Must have been comment + nodep->thensp()->unlinkFrBackWithNext()->deleteTree(); } nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible - nodep->addIfsp(elsesp); + nodep->addThensp(elsesp); } else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1) || VN_IS(nodep->condp(), LogNot)) - && nodep->ifsp() && nodep->elsesp()) { + && nodep->thensp() && nodep->elsesp()) { UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl); AstNode* const condp = VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext(); - AstNode* const ifsp = nodep->ifsp()->unlinkFrBackWithNext(); + AstNode* const thensp = nodep->thensp()->unlinkFrBackWithNext(); AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext(); - AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp); + AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, thensp); ifp->branchPred(nodep->branchPred().invert()); nodep->replaceWith(ifp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -2940,25 +2939,25 @@ private: UINFO( 4, "IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})\n"); - AstNodeAssign* const ifp = VN_AS(nodep->ifsp(), NodeAssign); - AstNodeAssign* const elsep = VN_AS(nodep->elsesp(), NodeAssign); - ifp->unlinkFrBack(); + AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign); + AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign); + thensp->unlinkFrBack(); AstNode* const condp = nodep->condp()->unlinkFrBack(); - AstNode* const truep = ifp->rhsp()->unlinkFrBack(); - AstNode* const falsep = elsep->rhsp()->unlinkFrBack(); - ifp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); - nodep->replaceWith(ifp); + AstNode* const truep = thensp->rhsp()->unlinkFrBack(); + AstNode* const falsep = elsesp->rhsp()->unlinkFrBack(); + thensp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); + nodep->replaceWith(thensp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (false // Disabled, as vpm assertions are faster // without due to short-circuiting && operandIfIf(nodep)) { UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl); - AstNodeIf* const lowerIfp = VN_AS(nodep->ifsp(), NodeIf); + AstNodeIf* const lowerIfp = VN_AS(nodep->thensp(), NodeIf); AstNode* const condp = nodep->condp()->unlinkFrBack(); - AstNode* const lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext(); + AstNode* const lowerThensp = lowerIfp->thensp()->unlinkFrBackWithNext(); AstNode* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext(); nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp)); - lowerIfp->replaceWith(lowerIfsp); + lowerIfp->replaceWith(lowerThensp); VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp); } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); @@ -3015,8 +3014,10 @@ private: pformatp->text(pformatp->text() + nformatp->text()); if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n"); if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext()); - if (nformatp->scopeNamep()) - pformatp->scopeNamep(nformatp->scopeNamep()->unlinkFrBackWithNext()); + if (AstScopeName* const scopeNamep = nformatp->scopeNamep()) { + scopeNamep->unlinkFrBackWithNext(); + pformatp->scopeNamep(scopeNamep); + } VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return true; } @@ -3300,19 +3301,19 @@ private: TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b) // Trinary ops // Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump! - TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)"); - TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)"); - TREEOPA("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)"); - TREEOPA("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)"); - TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)"); + TREEOP ("AstNodeCond{$condp.isZero, $thenp, $elsep}", "replaceWChild(nodep,$elsep)"); + TREEOP ("AstNodeCond{$condp.isNeqZero, $thenp, $elsep}", "replaceWChild(nodep,$thenp)"); + TREEOPA("AstNodeCond{$condp.isZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$elsep)"); + TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)"); + TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)"); // This visit function here must allow for short-circuiting. TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)"); TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)"); - TREEOP ("AstCond{$condp.castNot, $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}"); - TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b - TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b - TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b - TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b + TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->op1p(), $elsep, $thenp}"); + TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}"); // a?1:b == a||b + TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b + TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes}", "AstLogOr {AstNot{$condp}, $thenp}"); // a?b:1 == ~a||b + TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isZero, $elsep}", "AstLogAnd{AstNot{$condp}, $elsep}"); // a?0:b == ~a&&b TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())"); // Prefer constants on left, since that often needs a shift, it lets // constant red remove the shift diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 04266c492..1a87bb02f 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -119,7 +119,7 @@ private: AstCoverDecl* const declp = new AstCoverDecl(fl, page, comment, linescov, offset); declp->hier(hier); - m_modp->addStmtp(declp); + m_modp->addStmtsp(declp); UINFO(9, "new " << declp << endl); AstCoverInc* const incp = new AstCoverInc(fl, declp); @@ -128,7 +128,7 @@ private: incp->findUInt32DType()); varp->trace(true); varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); - m_modp->addStmtp(varp); + m_modp->addStmtsp(varp); UINFO(5, "New coverage trace: " << varp << endl); AstAssign* const assp = new AstAssign( incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::WRITE), @@ -245,11 +245,11 @@ private: = newCoverInc(nodep->fileline(), "", "v_line", "block", linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block")); if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) { - itemp->addStmtp(newp); + itemp->addStmtsp(newp); } else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) { itemp->addStmtsp(newp); } else if (AstWhile* const itemp = VN_CAST(nodep, While)) { - itemp->addBodysp(newp); + itemp->addStmtsp(newp); } else { nodep->v3fatalSrc("Bad node type"); } @@ -283,7 +283,7 @@ private: AstVar* const chgVarp = new AstVar(nodep->fileline(), VVarType::MODULETEMP, newvarname, nodep); chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); - m_modp->addStmtp(chgVarp); + m_modp->addStmtsp(chgVarp); // Create bucket for each dimension * bit. // This is necessarily an O(n^2) expansion, which is why @@ -304,7 +304,7 @@ private: newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0, ""), above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); - m_modp->addStmtp(newp); + m_modp->addStmtsp(newp); } void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration @@ -388,7 +388,7 @@ private: if (m_state.m_on) { // An else-if. When we iterate the if, use "elsif" marking const bool elsif - = nodep->ifsp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp(); + = nodep->thensp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp(); if (elsif) VN_AS(nodep->elsesp(), If)->user1(true); const bool first_elsif = !nodep->user1() && elsif; const bool cont_elsif = nodep->user1() && elsif; @@ -403,7 +403,7 @@ private: CheckState elseState; { createHandle(nodep); - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); lineTrack(nodep); ifState = m_state; } @@ -422,9 +422,9 @@ private: // Normal if. Linecov shows what's inside the if (not condition that is // always executed) UINFO(4, " COVER-branch: " << nodep << endl); - nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_branch", "if", - linesCov(ifState, nodep), 0, - traceNameForLine(nodep, "if"))); + nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_branch", "if", + linesCov(ifState, nodep), 0, + traceNameForLine(nodep, "if"))); // The else has a column offset of 1 to uniquify it relative to the if // As "if" and "else" are more than one character wide, this won't overlap // another token @@ -436,18 +436,18 @@ private: else if (first_elsif || cont_elsif) { UINFO(4, " COVER-elsif: " << nodep << endl); if (ifState.lineCoverageOn(nodep)) { - nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif", - linesCov(ifState, nodep), 0, - traceNameForLine(nodep, "elsif"))); + nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "elsif", + linesCov(ifState, nodep), 0, + traceNameForLine(nodep, "elsif"))); } // and we don't insert the else as the child if-else will do so } else { // Cover as separate blocks (not a branch as is not two-legged) if (ifState.lineCoverageOn(nodep)) { UINFO(4, " COVER-half-if: " << nodep << endl); - nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if", - linesCov(ifState, nodep), 0, - traceNameForLine(nodep, "if"))); + nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "if", + linesCov(ifState, nodep), 0, + traceNameForLine(nodep, "if"))); } if (elseState.lineCoverageOn(nodep)) { UINFO(4, " COVER-half-el: " << nodep << endl); @@ -468,11 +468,11 @@ private: VL_RESTORER(m_state); { createHandle(nodep); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it lineTrack(nodep); UINFO(4, " COVER: " << nodep << endl); - nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", + nodep->addStmtsp(newCoverInc(nodep->fileline(), "", "v_line", "case", linesCov(m_state, nodep), 0, traceNameForLine(nodep, "case"))); } @@ -486,12 +486,12 @@ private: m_state.m_on = true; // Always do cover blocks, even if there's a $stop createHandle(nodep); iterateChildren(nodep); - if (!nodep->coverincp() && v3Global.opt.coverageUser()) { + if (!nodep->coverincsp() && v3Global.opt.coverageUser()) { // Note the name may be overridden by V3Assert processing lineTrack(nodep); - nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", - linesCov(m_state, nodep), 0, - m_beginHier + "_vlCoverageUserTrace")); + nodep->addCoverincsp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", + linesCov(m_state, nodep), 0, + m_beginHier + "_vlCoverageUserTrace")); } } } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index f7d928d33..f95ad8f0d 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -153,13 +153,13 @@ private: varp = new AstVar(oldvarscp->fileline(), VVarType::BLOCKTEMP, name, VFlagBitPacked(), width); } - addmodp->addStmtp(varp); + addmodp->addStmtsp(varp); m_modVarMap.emplace(std::make_pair(addmodp, name), varp); } AstVarScope* const varscp = new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp); - oldvarscp->scopep()->addVarp(varscp); + oldvarscp->scopep()->addVarsp(varscp); return varscp; } @@ -356,11 +356,11 @@ private: postLogicp = new AstIf(nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, VAccess::READ)); UINFO(9, " Created " << postLogicp << endl); - finalp->addStmtp(postLogicp); + finalp->addStmtsp(postLogicp); finalp->user3p(setvscp); // Remember IF's vset variable finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it } - postLogicp->addIfsp(new AstAssign(nodep->fileline(), selectsp, valreadp)); + postLogicp->addThensp(new AstAssign(nodep->fileline(), selectsp, valreadp)); return newlhsp; } diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index c4cde8287..89bd99669 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -57,7 +57,7 @@ private: funcp->isStatic(m_cfuncp->isStatic()); funcp->isLoose(m_cfuncp->isLoose()); funcp->addStmtsp(nodep); - scopep->addActivep(funcp); + scopep->addBlocksp(funcp); // Call sub function at the point where the body was removed from AstCCall* const callp = new AstCCall(nodep->fileline(), funcp); if (VN_IS(m_modp, Class)) { diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 835294f74..fbf39da8b 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -257,7 +257,7 @@ private: // If it's under a scope, move it up to the top if (m_scopep) { nodep->unlinkFrBack(); - m_modp->addStmtp(nodep); + m_modp->addStmtsp(nodep); if (nodep->funcPublic()) { // There may be multiple public functions by the same name; diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 71d636cf9..47c219da6 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -828,7 +828,7 @@ public: puts("while ("); iterateAndNextNull(nodep->condp()); puts(") {\n"); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop puts("}\n"); @@ -842,7 +842,7 @@ public: iterateAndNextNull(nodep->condp()); if (!nodep->branchPred().unknown()) puts(")"); puts(") {\n"); - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); puts("}"); if (!nodep->elsesp()) { puts("\n"); @@ -935,17 +935,17 @@ public: } void visit(AstCStmt* nodep) override { putbs(""); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->exprsp()); } void visit(AstCMath* nodep) override { putbs(""); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->exprsp()); } void visit(AstUCStmt* nodep) override { VL_RESTORER(m_inUC); m_inUC = true; putsDecoration(ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n")); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->exprsp()); puts("\n"); } void visit(AstUCFunc* nodep) override { @@ -953,7 +953,7 @@ public: m_inUC = true; puts("\n"); putsDecoration(ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n")); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->exprsp()); puts("\n"); } @@ -1033,15 +1033,15 @@ public: } void visit(AstNodeCond* nodep) override { // Widths match up already, so we'll just use C++'s operator w/o any temps. - if (nodep->expr1p()->isWide()) { - emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p()); + if (nodep->thenp()->isWide()) { + emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->thenp(), nodep->elsep()); } else { putbs("("); iterateAndNextNull(nodep->condp()); putbs(" ? "); - iterateAndNextNull(nodep->expr1p()); + iterateAndNextNull(nodep->thenp()); putbs(" : "); - iterateAndNextNull(nodep->expr2p()); + iterateAndNextNull(nodep->elsep()); puts(")"); } } diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 76144011b..9e7d015da 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -110,7 +110,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { iterateAndNextConstNull(nodep->sensesp()); } putbs(" begin\n"); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); putqs(nodep, "end\n"); } void visit(AstAlwaysPublic* nodep) override { @@ -122,7 +122,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { iterateAndNextConstNull(nodep->sensesp()); } putqs(nodep, " "); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); putqs(nodep, "*/\n"); } void visit(AstNodeAssign* nodep) override { @@ -204,7 +204,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { putbs("default"); } putfs(nodep, ": begin "); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); putqs(nodep, "end\n"); } void visit(AstComment* nodep) override { @@ -326,14 +326,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { iterateAndNextConstNull(nodep->incsp()); } puts(") begin\n"); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); putqs(nodep, "end\n"); } void visit(AstRepeat* nodep) override { putfs(nodep, "repeat ("); iterateAndNextConstNull(nodep->countp()); puts(") begin\n"); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); putfs(nodep, "end\n"); } void visit(AstWhile* nodep) override { @@ -341,7 +341,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { putfs(nodep, "while ("); iterateAndNextConstNull(nodep->condp()); puts(") begin\n"); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->stmtsp()); iterateAndNextConstNull(nodep->incsp()); iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop putfs(nodep, "end\n"); @@ -356,7 +356,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { puts("if ("); iterateAndNextConstNull(nodep->condp()); puts(") begin\n"); - iterateAndNextConstNull(nodep->ifsp()); + iterateAndNextConstNull(nodep->thensp()); if (nodep->elsesp()) { putqs(nodep, "end\n"); putqs(nodep, "else begin\n"); @@ -401,22 +401,22 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { void visit(AstScopeName* nodep) override {} void visit(AstCStmt* nodep) override { putfs(nodep, "$_CSTMT("); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->exprsp()); puts(");\n"); } void visit(AstCMath* nodep) override { putfs(nodep, "$_CMATH("); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->exprsp()); puts(");\n"); } void visit(AstUCStmt* nodep) override { putfs(nodep, "$c("); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->exprsp()); puts(");\n"); } void visit(AstUCFunc* nodep) override { putfs(nodep, "$c("); - iterateAndNextConstNull(nodep->bodysp()); + iterateAndNextConstNull(nodep->exprsp()); puts(")"); } @@ -521,9 +521,9 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { putbs("("); iterateAndNextConstNull(nodep->condp()); putfs(nodep, " ? "); - iterateAndNextConstNull(nodep->expr1p()); + iterateAndNextConstNull(nodep->thenp()); putbs(" : "); - iterateAndNextConstNull(nodep->expr2p()); + iterateAndNextConstNull(nodep->elsep()); puts(")"); } void visit(AstRange* nodep) override { diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 85635e31a..9eea581ae 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -306,8 +306,8 @@ private: for (int w = 0; w < nodep->widthWords(); ++w) { addWordAssign(nodep, w, new AstCond{fl, rhsp->condp()->cloneTree(true), - newAstWordSelClone(rhsp->expr1p(), w), - newAstWordSelClone(rhsp->expr2p(), w)}); + newAstWordSelClone(rhsp->thenp(), w), + newAstWordSelClone(rhsp->elsep(), w)}); } return true; } diff --git a/src/V3Force.cpp b/src/V3Force.cpp index ea4c61a02..446869208 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -109,7 +109,7 @@ class ForceConvertVisitor final : public VNVisitor { new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Initial{}}}}; activep->sensesStorep(activep->sensesp()); activep->addStmtsp(new AstInitial{flp, assignp}); - vscp->scopep()->addActivep(activep); + vscp->scopep()->addBlocksp(activep); } { // Add the combinational override @@ -127,7 +127,7 @@ class ForceConvertVisitor final : public VNVisitor { new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Combo{}}}}; activep->sensesStorep(activep->sensesp()); activep->addStmtsp(new AstAssignW{flp, lhsp, rhsp}); - vscp->scopep()->addActivep(activep); + vscp->scopep()->addBlocksp(activep); } } }; diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index c65e1d3fe..c4695ec28 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -921,7 +921,7 @@ private: if (m_dedupable) { if (!m_always) { m_always = true; - iterateAndNextNull(alwaysp->bodysp()); + iterateAndNextNull(alwaysp->stmtsp()); } else { m_dedupable = false; } @@ -936,7 +936,7 @@ private: if (m_always && !m_ifCondp && !ifp->elsesp()) { // we're under an always, this is the first IF, and there's no else m_ifCondp = ifp->condp(); - iterateAndNextNull(ifp->ifsp()); + iterateAndNextNull(ifp->thensp()); } else { m_dedupable = false; } diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 40327384b..d6d4d11f5 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -76,13 +76,13 @@ private: // ASSIGN(VARREF(inpclk), VARREF(var)) AstVar* const newvarp = new AstVar(varp->fileline(), VVarType::MODULETEMP, newvarname, varp); - m_topModp->addStmtp(newvarp); + m_topModp->addStmtsp(newvarp); AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp); - m_scopetopp->addVarp(newvscp); + m_scopetopp->addVarsp(newvscp); AstAssign* const asninitp = new AstAssign( vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE), new AstVarRef(vscp->fileline(), vscp, VAccess::READ)); - m_scopetopp->addFinalClkp(asninitp); + m_scopetopp->addFinalClksp(asninitp); // vscp->user2p(newvscp); } diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 277531647..cacca2901 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -294,15 +294,15 @@ private: UASSERT_OBJ(exprconstp || exprvarrefp, nodep, "Unknown interconnect type; pinReconnectSimple should have cleared up"); if (exprconstp) { - m_modp->addStmtp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE), - exprconstp->cloneTree(false))); + m_modp->addStmtsp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE), + exprconstp->cloneTree(false))); } else if (nodep->user3()) { // Public variable at the lower module end - we need to make sure we propagate // the logic changes up and down; if we aliased, we might // remove the change detection on the output variable. UINFO(9, "public pin assign: " << exprvarrefp << endl); UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias"); - m_modp->addStmtp( + m_modp->addStmtsp( new AstAssignW(flp, new AstVarRef(flp, exprvarrefp->varp(), VAccess::WRITE), new AstVarRef(flp, nodep, VAccess::READ))); } else if (nodep->isSigPublic() && VN_IS(nodep->dtypep(), UnpackArrayDType)) { @@ -310,11 +310,11 @@ private: // instead of aliased, because otherwise it will pass V3Slice and invalid // code will be emitted. UINFO(9, "assign to public and unpacked: " << nodep << endl); - m_modp->addStmtp( + m_modp->addStmtsp( new AstAssignW{flp, new AstVarRef{flp, nodep, VAccess::WRITE}, new AstVarRef{flp, exprvarrefp->varp(), VAccess::READ}}); } else if (nodep->isIfaceRef()) { - m_modp->addStmtp( + m_modp->addStmtsp( new AstAssignVarScope(flp, new AstVarRef(flp, nodep, VAccess::WRITE), new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ))); FileLine* const flbp = exprvarrefp->varp()->fileline(); @@ -323,7 +323,7 @@ private: } else { // Do to inlining child's variable now within the same // module, so a AstVarRef not AstVarXRef below - m_modp->addStmtp( + m_modp->addStmtsp( new AstAssignAlias(flp, new AstVarRef(flp, nodep, VAccess::WRITE), new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ))); FileLine* const flbp = exprvarrefp->varp()->fileline(); @@ -423,16 +423,16 @@ private: // If there's a %m in the display text, we add a special node that will contain the name() // Similar code in V3Begin // To keep correct visual order, must add before other Text's - AstNode* afterp = nodep->scopeAttrp(); + AstText* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); - nodep->scopeAttrp( + nodep->addScopeAttrp( new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()}); - if (afterp) nodep->scopeAttrp(afterp); + if (afterp) nodep->addScopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); - nodep->scopeEntrp( + nodep->addScopeEntrp( new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()}); - if (afterp) nodep->scopeEntrp(afterp); + if (afterp) nodep->addScopeEntrp(afterp); iterateChildren(nodep); } void visit(AstCoverDecl* nodep) override { @@ -566,7 +566,7 @@ private: // Move statements under the module we are inlining into if (AstNode* const stmtsp = newmodp->stmtsp()) { stmtsp->unlinkFrBackWithNext(); - m_modp->addStmtp(stmtsp); + m_modp->addStmtsp(stmtsp); } // Clear any leftover ports, etc VL_DO_DANGLING(newmodp->deleteTree(), newmodp); @@ -649,7 +649,7 @@ private: } if (VN_IS(nodep->modp(), Iface)) { - nodep->addIntfRefp(new AstIntfRef{nodep->fileline(), m_scope}); + nodep->addIntfRefsp(new AstIntfRef{nodep->fileline(), m_scope}); } { AstNodeModule* const modp = nodep->modp(); @@ -666,7 +666,7 @@ private: if ((cellp = VN_CAST(fromVarp->user1p(), Cell)) || (cellp = irdtp->cellp())) { varp->user1p(cellp); const string alias = m_scope + "__DOT__" + pinp->name(); - cellp->addIntfRefp(new AstIntfRef(pinp->fileline(), alias)); + cellp->addIntfRefsp(new AstIntfRef(pinp->fileline(), alias)); } } @@ -695,7 +695,7 @@ private: string alias; if (!m_scope.empty()) alias = m_scope + "__DOT__"; alias += varlp->name(); - cellp->addIntfRefp(new AstIntfRef(varlp->fileline(), alias)); + cellp->addIntfRefsp(new AstIntfRef(varlp->fileline(), alias)); } //-------------------- void visit(AstNodeMath*) override {} // Accelerate diff --git a/src/V3InstrCount.cpp b/src/V3InstrCount.cpp index 41a0e9ef2..4a394fe80 100644 --- a/src/V3InstrCount.cpp +++ b/src/V3InstrCount.cpp @@ -170,7 +170,7 @@ private: UINFO(8, "ifsp:\n"); m_instrCount = 0; - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); uint32_t ifCount = m_instrCount; if (nodep->branchPred().unlikely()) ifCount = 0; @@ -185,7 +185,7 @@ private: if (nodep->elsesp()) nodep->elsesp()->user4(0); // Don't dump it } else { m_instrCount = savedCount + elseCount; - if (nodep->ifsp()) nodep->ifsp()->user4(0); // Don't dump it + if (nodep->thensp()) nodep->thensp()->user4(0); // Don't dump it } } void visit(AstNodeCond* nodep) override { @@ -197,20 +197,20 @@ private: UINFO(8, "?\n"); m_instrCount = 0; - iterateAndNextNull(nodep->expr1p()); + iterateAndNextNull(nodep->thenp()); const uint32_t ifCount = m_instrCount; UINFO(8, ":\n"); m_instrCount = 0; - iterateAndNextNull(nodep->expr2p()); + iterateAndNextNull(nodep->elsep()); const uint32_t elseCount = m_instrCount; if (ifCount < elseCount) { m_instrCount = savedCount + elseCount; - if (nodep->expr1p()) nodep->expr1p()->user4(0); // Don't dump it + if (nodep->thenp()) nodep->thenp()->user4(0); // Don't dump it } else { m_instrCount = savedCount + ifCount; - if (nodep->expr2p()) nodep->expr2p()->user4(0); // Don't dump it + if (nodep->elsep()) nodep->elsep()->user4(0); // Don't dump it } } void visit(AstActive* nodep) override { diff --git a/src/V3Life.cpp b/src/V3Life.cpp index 5ae48ebd4..62459ba84 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -340,7 +340,7 @@ private: LifeBlock* const elseLifep = new LifeBlock(prevLifep, m_statep); { m_lifep = ifLifep; - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); } { m_lifep = elseLifep; @@ -375,7 +375,7 @@ private: } { m_lifep = bodyLifep; - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); } m_lifep = prevLifep; diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 393013026..5057a4090 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -268,7 +268,7 @@ private: { m_modp = modp; // Important that this adds to end, as next iterate assumes does all cells - modp->addStmtp(cellsp); + modp->addStmtsp(cellsp); iterateAndNextNull(cellsp); } } @@ -321,7 +321,7 @@ private: otherModp->recursiveClone(true); // user1 etc will retain its pre-clone value cellmodp->user2p(otherModp); - v3Global.rootp()->addModulep(otherModp); + v3Global.rootp()->addModulesp(otherModp); new V3GraphEdge(&m_graph, vertex(cellmodp), vertex(otherModp), 1, false); } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 2825daaf7..57f9fca83 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -994,7 +994,7 @@ class LinkDotFindVisitor final : public VNVisitor { if (!nodep->isExternDef()) { // Move it to proper spot under the target class nodep->unlinkFrBack(); - classp->addStmtp(nodep); + classp->addStmtsp(nodep); nodep->isExternDef(true); // So we check there's a matching extern nodep->classOrPackagep()->unlinkFrBack()->deleteTree(); } @@ -1030,7 +1030,7 @@ class LinkDotFindVisitor final : public VNVisitor { newvarp->funcReturn(true); newvarp->trace(false); // Not user visible newvarp->attrIsolateAssign(nodep->attrIsolateAssign()); - nodep->addFvarp(newvarp); + nodep->fvarp(newvarp); // Explicit insert required, as the var name shadows the upper level's task name m_statep->insertSym(m_curSymp, newvarp->name(), newvarp, nullptr /*classOrPackagep*/); @@ -1938,7 +1938,7 @@ private: VFlagLogicPacked{}, 1); newp->trace(modp->modTrace()); nodep->varp(newp); - modp->addStmtp(newp); + modp->addStmtsp(newp); // Link it to signal list, must add the variable under the module; // current scope might be lower now m_statep->insertSym(moduleSymp, newp->name(), newp, nullptr /*classOrPackagep*/); @@ -3097,7 +3097,7 @@ private: nodep->classOrPackagep(foundp->classOrPackagep()); } } else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) { - AstNode* const paramsp = nodep->paramsp(); + AstPin* const paramsp = nodep->paramsp(); if (paramsp) paramsp->unlinkFrBackWithNext(); AstClassRefDType* const newp = new AstClassRefDType{nodep->fileline(), defp, paramsp}; diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index a19b1e282..d0e852849 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -106,7 +106,7 @@ private: iterateAndNextNull(nodep->condp()); // Body insert just before themselves m_insStmtp = nullptr; // First thing should be new statement - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); // Done the loop m_insStmtp = nullptr; // Next thing should be new statement @@ -131,7 +131,7 @@ private: m_insStmtp = nodep; iterateAndNextNull(nodep->condp()); m_insStmtp = nullptr; - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); iterateAndNextNull(nodep->elsesp()); m_insStmtp = nullptr; } @@ -143,7 +143,7 @@ private: iterateAndNextNull(nodep->condsp()); } m_insStmtp = nullptr; // Next thing should be new statement - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); } void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE nodep->v3fatalSrc( diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index ef40653a8..2c5802704 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -69,7 +69,7 @@ private: underp = VN_AS(nodep, NodeFTask)->stmtsp(); } else if (VN_IS(nodep, Foreach)) { if (endOfIter) { - underp = VN_AS(nodep, Foreach)->bodysp(); + underp = VN_AS(nodep, Foreach)->stmtsp(); } else { underp = nodep; under_and_next = false; // IE we skip the entire foreach @@ -78,7 +78,7 @@ private: if (endOfIter) { // Note we jump to end of bodysp; a FOR loop has its // increment under incsp() which we don't skip - underp = VN_AS(nodep, While)->bodysp(); + underp = VN_AS(nodep, While)->stmtsp(); } else { underp = nodep; under_and_next = false; // IE we skip the entire while @@ -157,7 +157,7 @@ private: AstVar* const varp = new AstVar(nodep->fileline(), VVarType::BLOCKTEMP, name, nodep->findSigned32DType()); varp->usedLoopIdx(true); - m_modp->addStmtp(varp); + m_modp->addStmtsp(varp); AstNode* initsp = new AstAssign( nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), countp); AstNode* const decp = new AstAssign( @@ -167,7 +167,7 @@ private: AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); AstNode* const condp = new AstGtS( nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp); - AstNode* const bodysp = nodep->bodysp(); + AstNode* const bodysp = nodep->stmtsp(); if (bodysp) bodysp->unlinkFrBackWithNext(); AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp); initsp = initsp->addNext(newp); @@ -178,7 +178,7 @@ private: void visit(AstWait* nodep) override { nodep->v3warn(E_UNSUPPORTED, "Unsupported: wait statements"); // Statements we'll just execute immediately; equivalent to if they followed this - if (AstNode* const bodysp = nodep->bodysp()) { + if (AstNode* const bodysp = nodep->stmtsp()) { bodysp->unlinkFrBackWithNext(); nodep->replaceWith(bodysp); } else { @@ -195,7 +195,7 @@ private: m_loopInc = false; iterateAndNextNull(nodep->precondsp()); iterateAndNextNull(nodep->condp()); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); m_loopInc = true; iterateAndNextNull(nodep->incsp()); } @@ -204,7 +204,7 @@ private: VL_RESTORER(m_loopp); { m_loopp = nodep; - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); } } void visit(AstReturn* nodep) override { diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 3e9130ed3..9c88973f6 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -76,7 +76,7 @@ void V3LinkLevel::modSortByLevel() { UINFO(9, "modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666 for (AstNodeModule* nodep : mods) nodep->unlinkFrBack(); UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work"); - for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulep(nodep); + for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulesp(nodep); UINFO(9, "modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } @@ -154,7 +154,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) { newmodp->modPublic(true); newmodp->protect(false); newmodp->timeunit(oldmodp->timeunit()); - rootp->addModulep(newmodp); + rootp->addModulesp(newmodp); // TODO the module creation above could be done after linkcells, but // the rest must be done after data type resolution @@ -170,7 +170,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) { // with module names/"v" modp->name(), modp->name(), nullptr, nullptr, nullptr); cellp->modp(modp); - newmodp->addStmtp(cellp); + newmodp->addStmtsp(cellp); } } @@ -213,7 +213,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) { (!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()), oldmodp->name(), nullptr, nullptr, nullptr); cellp->modp(oldmodp); - newmodp->addStmtp(cellp); + newmodp->addStmtsp(cellp); // Add pins for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { @@ -229,7 +229,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) { AstVar* const varp = oldvarp->cloneTree(false); varp->name(name); varp->protect(false); - newmodp->addStmtp(varp); + newmodp->addStmtsp(varp); varp->sigPublic(true); // User needs to be able to get to it... if (oldvarp->isIO()) { oldvarp->primaryIO(false); diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index b0a8e4001..1fff33a56 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -372,7 +372,7 @@ private: // lvalue is true, because we know we have a verilator public_flat_rw // but someday we may be more general const bool lvalue = m_varp->isSigUserRWPublic(); - nodep->addStmtp( + nodep->addStmtsp( new AstVarRef(nodep->fileline(), m_varp, lvalue ? VAccess::WRITE : VAccess::READ)); } } @@ -596,7 +596,7 @@ private: sensesp->unlinkFrBackWithNext(); alwaysp->sensesp(sensesp); } - if (nodep->stmtsp()) alwaysp->addStmtp(nodep->stmtsp()->unlinkFrBackWithNext()); + if (nodep->stmtsp()) alwaysp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext()); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index c7dc0ef6f..d5157b0c9 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -86,7 +86,7 @@ private: // Initial assignments under function/tasks can just be simple // assignments without the initial if (m_ftaskp) { - VL_DO_DANGLING(nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()), nodep); + VL_DO_DANGLING(nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext()), nodep); } } void visit(AstNodeCoverOrAssert* nodep) override { @@ -483,7 +483,7 @@ private: } varoutp = varp; // Tie off - m_modp->addStmtp( + m_modp->addStmtsp( new AstAssignW(varp->fileline(), new AstVarRef(varp->fileline(), varp, VAccess::WRITE), new AstConst(varp->fileline(), AstConst::BitFalse()))); diff --git a/src/V3MergeCond.cpp b/src/V3MergeCond.cpp index 3dd8fe02e..1f99e4570 100644 --- a/src/V3MergeCond.cpp +++ b/src/V3MergeCond.cpp @@ -565,7 +565,7 @@ private: return false; } if (const AstNodeCond* const condp = VN_CAST(nodep, NodeCond)) { - return yieldsOneOrZero(condp->expr1p()) && yieldsOneOrZero(condp->expr2p()); + return yieldsOneOrZero(condp->thenp()) && yieldsOneOrZero(condp->elsep()); } if (const AstCCast* const castp = VN_CAST(nodep, CCast)) { // Cast never sign extends @@ -593,7 +593,7 @@ private: return new AstConst{rhsp->fileline(), AstConst::BitTrue{}, condTrue}; } else if (const AstNodeCond* const condp = extractCondFromRhs(rhsp)) { AstNode* const resp - = condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack(); + = condTrue ? condp->thenp()->unlinkFrBack() : condp->elsep()->unlinkFrBack(); if (condp == rhsp) return resp; if (const AstAnd* const andp = VN_CAST(rhsp, And)) { UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this"); @@ -676,7 +676,7 @@ private: // Construct the new RHSs and add to branches thenp->rhsp(foldAndUnlink(rhsp, true)); elsep->rhsp(foldAndUnlink(rhsp, false)); - resultp->addIfsp(thenp); + resultp->addThensp(thenp); resultp->addElsesp(elsep); // Cleanup VL_DO_DANGLING(rhsp->deleteTree(), rhsp); @@ -684,8 +684,8 @@ private: AstNodeIf* const ifp = VN_AS(currp, NodeIf); UASSERT_OBJ(ifp, currp, "Must be AstNodeIf"); // Move branch contents under new if - if (AstNode* const listp = ifp->ifsp()) { - resultp->addIfsp(listp->unlinkFrBackWithNext()); + if (AstNode* const listp = ifp->thensp()) { + resultp->addThensp(listp->unlinkFrBackWithNext()); } if (AstNode* const listp = ifp->elsesp()) { resultp->addElsesp(listp->unlinkFrBackWithNext()); @@ -695,7 +695,7 @@ private: } } while (nextp); // Merge the branches of the resulting AstIf after re-analysis - if (resultp->ifsp()) m_workQueuep->push(resultp->ifsp()); + if (resultp->thensp()) m_workQueuep->push(resultp->thensp()); if (resultp->elsesp()) m_workQueuep->push(resultp->elsesp()); } else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) { // There was nothing to merge this AstNodeIf with, so try to merge its branches. @@ -711,7 +711,7 @@ private: AstNode::user2ClearTree(); // Merge recursively within the branches of an un-merged AstNodeIF if (recursivep) { - iterateAndNextNull(recursivep->ifsp()); + iterateAndNextNull(recursivep->thensp()); iterateAndNextNull(recursivep->elsesp()); // Close a pending merge to ensure merge state is // reset as expected at the end of this function @@ -840,7 +840,7 @@ private: // Check if mergeable if (!checkOrMakeMergeable(nodep)) { // If not mergeable, try to merge the branches - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); iterateAndNextNull(nodep->elsesp()); return; } diff --git a/src/V3Order.cpp b/src/V3Order.cpp index 539d6b6fa..5bbb46a68 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1789,7 +1789,7 @@ void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d << " s=" << cvtToHex(scopep) << " " << lvertexp << endl); AstActive* const newActivep = processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/); - if (newActivep) m_scopetop.addActivep(newActivep); + if (newActivep) m_scopetop.addBlocksp(newActivep); processMoveDoneOne(vertexp); } @@ -1811,7 +1811,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp, // procedures. Everything else is handled in one go AstNodeProcedure* const procp = VN_CAST(nodep, NodeProcedure); if (procp && !v3Global.opt.profCFuncs()) { - nodep = procp->bodysp(); + nodep = procp->stmtsp(); pushDeletep(procp); } @@ -1831,7 +1831,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp, newFuncpr->isLoose(true); newStmtsr = 0; if (domainp->hasInitial() || domainp->hasSettle()) newFuncpr->slow(true); - scopep->addActivep(newFuncpr); + scopep->addBlocksp(newFuncpr); // Create top call to it AstCCall* const callp = new AstCCall(nodep->fileline(), newFuncpr); // Where will we be adding the call? @@ -1886,7 +1886,7 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) { } AstActive* const newActivep = processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/); - if (newActivep) m_scopetop.addActivep(newActivep); + if (newActivep) m_scopetop.addBlocksp(newActivep); } } @@ -1966,7 +1966,7 @@ void OrderProcess::processMTasks() { // of the MTask graph. FileLine* const rootFlp = v3Global.rootp()->fileline(); AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, "eval"}; - m_scopetop.addActivep(execGraphp); + m_scopetop.addBlocksp(execGraphp); // Create CFuncs and bodies for each MTask. GraphStream emit_mtasks(&mtasks); @@ -2018,7 +2018,7 @@ void OrderProcess::processMTasks() { const MTaskState& fromState = mtaskStates[fromp->id()]; new V3GraphEdge(depGraphp, fromState.m_execMTaskp, state.m_execMTaskp, 1); } - execGraphp->addMTaskBodyp(bodyp); + execGraphp->addMTaskBodiesp(bodyp); } } diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 3a21266fc..4c372895e 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -1132,7 +1132,7 @@ class ParamVisitor final : public VNVisitor { // NOT recurse the body. V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) { - if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->ifsp())) { + if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->thensp())) { keepp->unlinkFrBackWithNext(); nodep->replaceWith(keepp); } else { @@ -1150,9 +1150,7 @@ class ParamVisitor final : public VNVisitor { //! expression, since this is currently restricted to simple comparisons. If we ever do //! move to more generic constant expressions, such code will be needed here. void visit(AstBegin* nodep) override { - if (nodep->genforp()) { - AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor); - UASSERT_OBJ(forp, nodep, "Non-GENFOR under generate-for BEGIN"); + if (AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor)) { // We should have a GENFOR under here. We will be replacing the begin, // so process here rather than at the generate to avoid iteration problems UINFO(9, " BEGIN " << nodep << endl); @@ -1211,7 +1209,7 @@ class ParamVisitor final : public VNVisitor { if (const AstConst* const ccondp = VN_CAST(ep, Const)) { V3Number match(nodep, 1); match.opEq(ccondp->num(), exprp->num()); - if (!keepp && match.isNeqZero()) keepp = itemp->bodysp(); + if (!keepp && match.isNeqZero()) keepp = itemp->stmtsp(); } else { itemp->v3error("Generate Case item does not evaluate to constant"); } @@ -1222,7 +1220,7 @@ class ParamVisitor final : public VNVisitor { for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) { if (itemp->isDefault()) { - if (!keepp) keepp = itemp->bodysp(); + if (!keepp) keepp = itemp->stmtsp(); } } // Replace @@ -1269,7 +1267,7 @@ public: }); // Re-insert modules - for (AstNodeModule* const modp : modps) netlistp->addModulep(modp); + for (AstNodeModule* const modp : modps) netlistp->addModulesp(modp); } } ~ParamVisitor() override = default; diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 37da5a1fc..db0a0f422 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -283,7 +283,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i if (errmsg != "") return; // Threw error already // Create fake node for later error reporting AstNodeModule* const nodep = new AstNotFoundModule(fileline, modname); - v3Global.rootp()->addModulep(nodep); + v3Global.rootp()->addModulesp(nodep); return; } diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index f3ffaf56b..ea3855ddd 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -3051,7 +3051,7 @@ static void addMTaskToFunction(const ThreadSchedule& schedule, const uint32_t th AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, name, mtaskStateDtypep); varp->valuep(new AstConst(fl, nDependencies)); varp->protect(false); // Do not protect as we still have references in AstText - modp->addStmtp(varp); + modp->addStmtsp(varp); // For now, reference is still via text bashing addStrStmt("vlSelf->" + name + +".waitUntilUpstreamDone(even_cycle);\n"); } @@ -3112,7 +3112,7 @@ static const std::vector createThreadFunctions(const ThreadSchedule& const uint32_t threadId = schedule.threadId(thread.front()); const string name{"__Vthread__" + tag + "__" + cvtToStr(threadId)}; AstCFunc* const funcp = new AstCFunc(fl, name, nullptr, "void"); - modp->addStmtp(funcp); + modp->addStmtsp(funcp); funcps.push_back(funcp); funcp->isStatic(true); // Uses void self pointer, so static and hand rolled funcp->isLoose(true); @@ -3140,7 +3140,7 @@ static const std::vector createThreadFunctions(const ThreadSchedule& = new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final", mtaskStateDtypep); varp->valuep(new AstConst(fl, funcps.size())); varp->protect(false); // Do not protect as we still have references in AstText - modp->addStmtp(varp); + modp->addStmtsp(varp); return funcps; } diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 842b8d720..54b1324c4 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -176,7 +176,7 @@ private: iterateAndNextNull(nodep->condp()); m_inWhilep = nullptr; startStatement(nodep); - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); m_stmtp = nullptr; } @@ -329,7 +329,7 @@ private: } void visit(AstNodeCond* nodep) override { iterateChildren(nodep); - if (nodep->expr1p()->isWide() && !VN_IS(nodep->condp(), Const) + if (nodep->thenp()->isWide() && !VN_IS(nodep->condp(), Const) && !VN_IS(nodep->condp(), VarRef)) { // We're going to need the expression several times in the expanded code, // so might as well make it a common expression diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 21abed5a7..734695c2f 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -95,7 +95,7 @@ private: } void addComment(AstTextBlock* txtp, FileLine* fl, const string& comment) { - txtp->addNodep(new AstComment{fl, comment}); + txtp->addNodesp(new AstComment{fl, comment}); } void hashComment(AstTextBlock* txtp, FileLine* fl) { @@ -143,7 +143,7 @@ private: // Module declaration m_modPortsp = new AstTextBlock{fl, "module " + m_libName + " (\n", false, true}; - txtp->addNodep(m_modPortsp); + txtp->addNodesp(m_modPortsp); txtp->addText(fl, ");\n\n"); // Timescale @@ -177,7 +177,7 @@ private: "(\n", false, true}; m_comboPortsp->addText(fl, "chandle handle__V\n"); - txtp->addNodep(m_comboPortsp); + txtp->addNodesp(m_comboPortsp); txtp->addText(fl, ");\n\n"); seqComment(txtp, fl); if (m_hasClk) { @@ -187,7 +187,7 @@ private: "(\n", false, true}; m_seqPortsp->addText(fl, "chandle handle__V\n"); - txtp->addNodep(m_seqPortsp); + txtp->addNodesp(m_seqPortsp); txtp->addText(fl, ");\n\n"); } comboIgnoreComment(txtp, fl); @@ -197,7 +197,7 @@ private: "(\n", false, true}; m_comboIgnorePortsp->addText(fl, "chandle handle__V\n"); - txtp->addNodep(m_comboIgnorePortsp); + txtp->addNodesp(m_comboIgnorePortsp); txtp->addText(fl, ");\n\n"); finalComment(txtp, fl); @@ -227,17 +227,17 @@ private: txtp->addText(fl, "\n"); m_comboDeclsp = new AstTextBlock{fl}; - txtp->addNodep(m_comboDeclsp); + txtp->addNodesp(m_comboDeclsp); m_seqDeclsp = new AstTextBlock{fl}; - txtp->addNodep(m_seqDeclsp); + txtp->addNodesp(m_seqDeclsp); m_tmpDeclsp = new AstTextBlock{fl}; - txtp->addNodep(m_tmpDeclsp); + txtp->addNodesp(m_tmpDeclsp); // CPP hash value addComment(txtp, fl, "Hash value to make sure this file and the corresponding"); addComment(txtp, fl, "library agree"); m_hashValuep = new AstTextBlock{fl, "localparam int protectlib_hash__V = 32'd"}; - txtp->addNodep(m_hashValuep); + txtp->addNodesp(m_hashValuep); txtp->addText(fl, "\n"); // Initial @@ -256,7 +256,7 @@ private: + m_libName + "_protectlib_combo_update(\n", false, true}; m_comboParamsp->addText(fl, "handle__V\n"); - txtp->addNodep(m_comboParamsp); + txtp->addNodesp(m_comboParamsp); txtp->addText(fl, ");\n"); txtp->addText(fl, "end\n\n"); @@ -264,21 +264,21 @@ private: if (m_hasClk) { addComment(txtp, fl, "Evaluate clock edges"); m_clkSensp = new AstTextBlock{fl, "always @(", false, true}; - txtp->addNodep(m_clkSensp); + txtp->addNodesp(m_clkSensp); txtp->addText(fl, ") begin\n"); m_comboIgnoreParamsp = new AstTextBlock{fl, m_libName + "_protectlib_combo_ignore(\n", false, true}; m_comboIgnoreParamsp->addText(fl, "handle__V\n"); - txtp->addNodep(m_comboIgnoreParamsp); + txtp->addNodesp(m_comboIgnoreParamsp); txtp->addText(fl, ");\n"); m_seqParamsp = new AstTextBlock{ fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false, true}; m_seqParamsp->addText(fl, "handle__V\n"); - txtp->addNodep(m_seqParamsp); + txtp->addNodesp(m_seqParamsp); txtp->addText(fl, ");\n"); m_nbAssignsp = new AstTextBlock{fl}; - txtp->addNodep(m_nbAssignsp); + txtp->addNodesp(m_nbAssignsp); txtp->addText(fl, "end\n\n"); } @@ -288,13 +288,13 @@ private: if (m_hasClk) { m_seqAssignsp = new AstTextBlock{fl, "if (last_seq_seqnum__V > " "last_combo_seqnum__V) begin\n"}; - txtp->addNodep(m_seqAssignsp); + txtp->addNodesp(m_seqAssignsp); m_comboAssignsp = new AstTextBlock{fl, "end\nelse begin\n"}; - txtp->addNodep(m_comboAssignsp); + txtp->addNodesp(m_comboAssignsp); txtp->addText(fl, "end\n"); } else { m_comboAssignsp = new AstTextBlock{fl, ""}; - txtp->addNodep(m_comboAssignsp); + txtp->addNodesp(m_comboAssignsp); } txtp->addText(fl, "end\n\n"); @@ -341,7 +341,7 @@ private: + "_protectlib_check_hash" "(int protectlib_hash__V) {\n"); m_cHashValuep = new AstTextBlock{fl, "const int expected_hash__V = "}; - txtp->addNodep(m_cHashValuep); + txtp->addNodesp(m_cHashValuep); txtp->addText(fl, /**/ "if (protectlib_hash__V != expected_hash__V) {\n"); txtp->addText(fl, /****/ "fprintf(stderr, \"%%Error: cannot use " + m_libName + " library, " @@ -364,13 +364,13 @@ private: m_cComboParamsp = new AstTextBlock{ fl, "long long " + m_libName + "_protectlib_combo_update(\n", false, true}; m_cComboParamsp->addText(fl, "void* vhandlep__V\n"); - txtp->addNodep(m_cComboParamsp); + txtp->addNodesp(m_cComboParamsp); txtp->addText(fl, ")\n"); m_cComboInsp = new AstTextBlock{fl, "{\n"}; castPtr(fl, m_cComboInsp); - txtp->addNodep(m_cComboInsp); + txtp->addNodesp(m_cComboInsp); m_cComboOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"}; - txtp->addNodep(m_cComboOutsp); + txtp->addNodesp(m_cComboOutsp); txtp->addText(fl, "return handlep__V->m_seqnum++;\n"); txtp->addText(fl, "}\n\n"); @@ -379,13 +379,13 @@ private: m_cSeqParamsp = new AstTextBlock{ fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true}; m_cSeqParamsp->addText(fl, "void* vhandlep__V\n"); - txtp->addNodep(m_cSeqParamsp); + txtp->addNodesp(m_cSeqParamsp); txtp->addText(fl, ")\n"); m_cSeqClksp = new AstTextBlock{fl, "{\n"}; castPtr(fl, m_cSeqClksp); - txtp->addNodep(m_cSeqClksp); + txtp->addNodesp(m_cSeqClksp); m_cSeqOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"}; - txtp->addNodep(m_cSeqOutsp); + txtp->addNodesp(m_cSeqOutsp); txtp->addText(fl, "return handlep__V->m_seqnum++;\n"); txtp->addText(fl, "}\n\n"); } @@ -394,7 +394,7 @@ private: m_cIgnoreParamsp = new AstTextBlock{ fl, "void " + m_libName + "_protectlib_combo_ignore(\n", false, true}; m_cIgnoreParamsp->addText(fl, "void* vhandlep__V\n"); - txtp->addNodep(m_cIgnoreParamsp); + txtp->addNodesp(m_cIgnoreParamsp); txtp->addText(fl, ")\n"); txtp->addText(fl, "{ }\n\n"); @@ -448,7 +448,7 @@ private: void handleClock(AstVar* varp) { FileLine* const fl = varp->fileline(); handleInput(varp); - m_seqPortsp->addNodep(varp->cloneTree(false)); + m_seqPortsp->addNodesp(varp->cloneTree(false)); if (m_hasClk) { m_seqParamsp->addText(fl, varp->name() + "\n"); m_clkSensp->addText(fl, "posedge " + varp->name() + " or negedge " + varp->name()); @@ -460,30 +460,30 @@ private: void handleDataInput(AstVar* varp) { FileLine* const fl = varp->fileline(); handleInput(varp); - m_comboPortsp->addNodep(varp->cloneTree(false)); + m_comboPortsp->addNodesp(varp->cloneTree(false)); m_comboParamsp->addText(fl, varp->name() + "\n"); - m_comboIgnorePortsp->addNodep(varp->cloneTree(false)); + m_comboIgnorePortsp->addNodesp(varp->cloneTree(false)); if (m_hasClk) m_comboIgnoreParamsp->addText(fl, varp->name() + "\n"); m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n"); m_cComboInsp->addText(fl, cInputConnection(varp)); m_cIgnoreParamsp->addText(fl, varp->dpiArgType(true, false) + "\n"); } - void handleInput(AstVar* varp) { m_modPortsp->addNodep(varp->cloneTree(false)); } + void handleInput(AstVar* varp) { m_modPortsp->addNodesp(varp->cloneTree(false)); } static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) { AstVar* const newVarp = new AstVar{varp->fileline(), VVarType::VAR, varp->name() + suffix, varp->dtypep()}; - textp->addNodep(newVarp); + textp->addNodesp(newVarp); } void handleOutput(AstVar* varp) { FileLine* const fl = varp->fileline(); - m_modPortsp->addNodep(varp->cloneTree(false)); - m_comboPortsp->addNodep(varp->cloneTree(false)); + m_modPortsp->addNodesp(varp->cloneTree(false)); + m_comboPortsp->addNodesp(varp->cloneTree(false)); m_comboParamsp->addText(fl, varp->name() + "_combo__V\n"); if (m_hasClk) { - m_seqPortsp->addNodep(varp->cloneTree(false)); + m_seqPortsp->addNodesp(varp->cloneTree(false)); m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n"); } diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 448623a08..7efc30c0f 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -144,7 +144,7 @@ private: varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing - v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items"); for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), EnumItem)) { diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index e163bdf8c..4e8690b3e 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -114,7 +114,7 @@ private: AstWhile* const whilep = new AstWhile(fl, condp, nullptr, incp); initp->addNext(whilep); bodyp->replaceWith(initp); - whilep->addBodysp(bodyp); + whilep->addStmtsp(bodyp); // Replace constant index with new loop index AstNode* const offsetp diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 0c4bad466..8077d2959 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -135,7 +135,7 @@ private: if (m_modp->isTop()) { v3Global.rootp()->createTopScope(m_scopep); } else { - m_modp->addStmtp(m_scopep); + m_modp->addStmtsp(m_scopep); } // Copy blocks into this scope @@ -188,7 +188,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstAssignAlias* nodep) override { @@ -196,7 +196,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstAssignVarScope* nodep) override { @@ -204,7 +204,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstAssignW* nodep) override { @@ -212,7 +212,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstAlwaysPublic* nodep) override { @@ -220,7 +220,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstCoverToggle* nodep) override { @@ -228,7 +228,7 @@ private: UINFO(4, " Move " << nodep << endl); AstNode* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); iterateChildren(clonep); // We iterate under the *clone* } void visit(AstCFunc* nodep) override { @@ -236,7 +236,7 @@ private: UINFO(4, " CFUNC " << nodep << endl); AstCFunc* const clonep = nodep->cloneTree(false); nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); clonep->scopep(m_scopep); // We iterate under the *clone* iterateChildren(clonep); @@ -253,7 +253,7 @@ private: clonep = nodep->cloneTree(false); } nodep->user2p(clonep); - m_scopep->addActivep(clonep); + m_scopep->addBlocksp(clonep); // We iterate under the *clone* iterateChildren(clonep); } @@ -272,7 +272,7 @@ private: } UASSERT_OBJ(m_scopep, nodep, "No scope for var"); m_varScopes.emplace(std::make_pair(nodep, m_scopep), varscp); - m_scopep->addVarp(varscp); + m_scopep->addVarsp(varscp); } } void visit(AstVarRef* nodep) override { @@ -295,14 +295,14 @@ private: // TOP and above will be the user's name(). // Note 'TOP.' is stripped by scopePrettyName // To keep correct visual order, must add before other Text's - AstNode* afterp = nodep->scopeAttrp(); + AstText* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); - nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); - if (afterp) nodep->scopeAttrp(afterp); + nodep->addScopeAttrp(new AstText(nodep->fileline(), prefix)); + if (afterp) nodep->addScopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); - nodep->scopeEntrp(new AstText(nodep->fileline(), prefix)); - if (afterp) nodep->scopeEntrp(afterp); + nodep->addScopeEntrp(new AstText(nodep->fileline(), prefix)); + if (afterp) nodep->addScopeEntrp(afterp); iterateChildren(nodep); } void visit(AstScope* nodep) override { diff --git a/src/V3SenTree.h b/src/V3SenTree.h index c140580a0..636476b6f 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -64,7 +64,7 @@ public: // Not found, create a new one AstSenTree* const newSenTreep = senTreep->cloneTree(false); - m_topScopep->addSenTreep(newSenTreep); + m_topScopep->addSenTreesp(newSenTreep); m_trees.emplace(*newSenTreep); return newSenTreep; } diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 98d44a3c8..ee4b23caf 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -513,7 +513,7 @@ private: iterateAndNextNull(nodep->condp()); if (optimizable()) { if (fetchConst(nodep->condp())->num().isNeqZero()) { - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); } else { iterateAndNextNull(nodep->elsesp()); } @@ -647,11 +647,11 @@ private: iterate(nodep->condp()); if (optimizable()) { if (fetchConst(nodep->condp())->num().isNeqZero()) { - iterate(nodep->expr1p()); - newValue(nodep, fetchValue(nodep->expr1p())); + iterate(nodep->thenp()); + newValue(nodep, fetchValue(nodep->thenp())); } else { - iterate(nodep->expr2p()); - newValue(nodep, fetchValue(nodep->expr2p())); + iterate(nodep->elsep()); + newValue(nodep, fetchValue(nodep->elsep())); } } } @@ -835,7 +835,7 @@ private: V3Number match{nodep, 1}; match.opEq(fetchConst(nodep->exprp())->num(), fetchConst(ep)->num()); if (match.isNeqZero()) { - iterateAndNextNull(itemp->bodysp()); + iterateAndNextNull(itemp->stmtsp()); hit = true; } } @@ -847,7 +847,7 @@ private: itemp = VN_AS(itemp->nextp(), CaseItem)) { if (hit) break; if (!hit && itemp->isDefault()) { - iterateAndNextNull(itemp->bodysp()); + iterateAndNextNull(itemp->stmtsp()); hit = true; } } @@ -917,7 +917,7 @@ private: if (!fetchConst(nodep->condp())->num().isNeqZero()) { // break; } - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); if (loops++ > unrollCount() * 16) { clearOptimizable(nodep, "Loop unrolling took too long; probably this is an" @@ -952,7 +952,7 @@ private: if (!fetchConst(nodep->condp())->num().isNeqZero()) { // break; } - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); if (jumpingOver(nodep)) break; iterateAndNextNull(nodep->incsp()); if (jumpingOver(nodep)) break; diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index f362c3cb7..cd977626f 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -101,8 +101,8 @@ class SliceVisitor final : public VNVisitor { } else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) { UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl); return snodep->cloneType(snodep->condp()->cloneTree(false), - cloneAndSel(snodep->expr1p(), elements, offset), - cloneAndSel(snodep->expr2p(), elements, offset)); + cloneAndSel(snodep->thenp(), elements, offset), + cloneAndSel(snodep->elsep(), elements, offset)); } else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) { UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl); const int leOffset = (snodep->declRange().lo() diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 3e9f4e9ec..b3fd07314 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -601,14 +601,14 @@ protected: UINFO(4, " ALW " << nodep << endl); if (debug() >= 9) nodep->dumpTree(cout, " alwIn:: "); scoreboardClear(); - processBlock(nodep->bodysp()); + processBlock(nodep->stmtsp()); if (debug() >= 9) nodep->dumpTree(cout, " alwOut: "); } void visit(AstNodeIf* nodep) override { UINFO(4, " IF " << nodep << endl); iterateAndNextNull(nodep->condp()); - processBlock(nodep->ifsp()); + processBlock(nodep->thensp()); processBlock(nodep->elsesp()); } @@ -713,14 +713,14 @@ public: // Put a placeholder node into stmtp to track our position. // We'll strip these out after the blocks are fully cloned. AstSplitPlaceholder* const placeholderp = makePlaceholderp(); - alwaysp->addStmtp(placeholderp); + alwaysp->addStmtsp(placeholderp); m_addAfter[color] = placeholderp; m_newBlocksp->push_back(alwaysp); } // Scan the body of the always. We'll handle if/else // specially, everything else is a leaf node that we can // just clone into one of the split always blocks. - iterateAndNextNull(m_origAlwaysp->bodysp()); + iterateAndNextNull(m_origAlwaysp->stmtsp()); } protected: @@ -776,7 +776,7 @@ protected: m_addAfter[color] = if_placeholderp; } - iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->thensp()); for (const auto& color : colors) m_addAfter[color] = clones[color]->elsesp(); @@ -804,7 +804,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor { VL_RESTORER(m_isPure); m_isPure = true; iterateChildren(nodep); - if (!nodep->ifsp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack()); + if (!nodep->thensp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack()); } void visit(AstAlways* nodep) override { VL_RESTORER(m_isPure); @@ -812,7 +812,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor { iterateChildren(nodep); if (m_isPure) { bool emptyOrCommentOnly = true; - for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { + for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) { // If this always block contains only AstComment, remove here. // V3Gate will remove anyway. if (!VN_IS(bodysp, Comment)) { @@ -955,7 +955,7 @@ protected: void visit(AstAlways* nodep) override { // build the scoreboard scoreboardClear(); - scanBlock(nodep->bodysp()); + scanBlock(nodep->stmtsp()); if (m_noReorderWhy != "") { // We saw a jump or something else rare that we don't handle. @@ -989,7 +989,7 @@ protected: m_curIfConditional = nodep; iterateAndNextNull(nodep->condp()); m_curIfConditional = nullptr; - scanBlock(nodep->ifsp()); + scanBlock(nodep->thensp()); scanBlock(nodep->elsesp()); } diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 47dc0e006..502058e37 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -191,16 +191,16 @@ struct SplitVarImpl { template void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) { - if (ap->isJustOneBodyStmt() && ap->bodysp() == stmtp) { + if (ap->isJustOneBodyStmt() && ap->stmtsp() == stmtp) { stmtp->unlinkFrBack(); // Insert begin-end because temp value may be inserted to this block later. const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1)); - ap->addStmtp(new AstBegin{ap->fileline(), name, stmtp}); + ap->addStmtsp(new AstBegin{ap->fileline(), name, stmtp}); } } void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) { - if (initp->isJustOneBodyStmt() && initp->bodysp() == stmtp) { + if (initp->isJustOneBodyStmt() && initp->stmtsp() == stmtp) { stmtp->unlinkFrBack(); // Insert begin-end because temp value may be inserted to this block later. FileLine* const fl = initp->fileline(); @@ -477,7 +477,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { if (nodep->sensesp()) { // When visiting sensitivity list, always is the context setContextAndIterate(nodep, nodep->sensesp()); } - for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { + for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) { iterate(bodysp); } }; @@ -485,7 +485,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { if (nodep->sensesp()) { // When visiting sensitivity list, always is the context setContextAndIterate(nodep, nodep->sensesp()); } - for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { + for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) { iterate(bodysp); } } diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index 01d3ec2f2..5ec58dfdc 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -141,7 +141,7 @@ private: { m_counting = false; m_instrs = 0.0; - iterateAndNextConstNull(nodep->ifsp()); + iterateAndNextConstNull(nodep->thensp()); ifInstrs = m_instrs; } } @@ -158,7 +158,7 @@ private: // Now collect the stats if (m_counting) { if (ifInstrs >= elseInstrs) { - iterateAndNextConstNull(nodep->ifsp()); + iterateAndNextConstNull(nodep->thensp()); } else { iterateAndNextConstNull(nodep->elsesp()); } diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 76fcb3711..1e829f32e 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -253,9 +253,9 @@ private: AstVar* const indexVarp = new AstVar{fl, VVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables), VFlagBitPacked{}, static_cast(m_inWidthBits)}; - m_modp->addStmtp(indexVarp); + m_modp->addStmtsp(indexVarp); AstVarScope* const indexVscp = new AstVarScope{indexVarp->fileline(), m_scopep, indexVarp}; - m_scopep->addVarp(indexVscp); + m_scopep->addVarsp(indexVscp); // The 'output assigned' table builder TableBuilder outputAssignedTableBuilder{fl}; @@ -274,8 +274,8 @@ private: // Link it in. // Keep sensitivity list, but delete all else - nodep->bodysp()->unlinkFrBackWithNext()->deleteTree(); - nodep->addStmtp(stmtsp); + nodep->stmtsp()->unlinkFrBackWithNext()->deleteTree(); + nodep->addStmtsp(stmtsp); if (debug() >= 6) nodep->dumpTree(cout, " table_new: "); } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 0ab7392fd..332550798 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -250,7 +250,7 @@ private: } UASSERT_OBJ(m_ctorp, nodep, "class constructor missing"); // LinkDot always makes it for (AstInitialAutomatic* initialp : m_initialps) { - if (AstNode* const newp = initialp->bodysp()) { + if (AstNode* const newp = initialp->stmtsp()) { newp->unlinkFrBackWithNext(); if (!m_ctorp->stmtsp()) { m_ctorp->addStmtsp(newp); @@ -371,7 +371,7 @@ private: newvarp->funcLocal(true); funcp->addInitsp(newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); - m_scopep->addVarp(newvscp); + m_scopep->addVarsp(newvscp); return newvscp; } AstVarScope* createInputVar(AstCFunc* funcp, const string& name, VBasicDTypeKwd kwd) { @@ -381,7 +381,7 @@ private: newvarp->direction(VDirection::INPUT); funcp->addArgsp(newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); - m_scopep->addVarp(newvscp); + m_scopep->addVarsp(newvscp); return newvscp; } AstVarScope* createVarScope(AstVar* invarp, const string& name) { @@ -397,9 +397,9 @@ private: = new AstVar{invarp->fileline(), VVarType::BLOCKTEMP, name, invarp}; newvarp->funcLocal(false); newvarp->propagateAttrFrom(invarp); - m_modp->addStmtp(newvarp); + m_modp->addStmtsp(newvarp); AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp}; - m_scopep->addVarp(newvscp); + m_scopep->addVarsp(newvscp); return newvscp; } } @@ -766,7 +766,7 @@ private: funcp->protect(false); funcp->cname(nodep->cname()); // Add DPI Export to top, since it's a global function - m_topScopep->scopep()->addActivep(funcp); + m_topScopep->scopep()->addBlocksp(funcp); { // Create dispatch wrapper // Note this function may dispatch to myfunc on a different class. @@ -855,9 +855,9 @@ private: // doesn't rip up the variables on us args += ");\n"; AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)("); - newp->addBodysp(argnodesp); + newp->addExprsp(argnodesp); VL_DANGLING(argnodesp); - newp->addBodysp(new AstText(nodep->fileline(), args, true)); + newp->addExprsp(new AstText(nodep->fileline(), args, true)); funcp->addStmtsp(newp); } @@ -899,7 +899,7 @@ private: funcp->protect(false); funcp->pure(nodep->pure()); // Add DPI Import to top, since it's a global function - m_topScopep->scopep()->addActivep(funcp); + m_topScopep->scopep()->addBlocksp(funcp); makePortList(nodep, funcp); return funcp; } @@ -1064,9 +1064,9 @@ private: FileLine* const fl = m_topScopep->fileline(); AstVar* const varp = new AstVar{fl, VVarType::VAR, "__Vdpi_export_trigger", VFlagBitPacked{}, 1}; - m_topScopep->scopep()->modp()->addStmtp(varp); + m_topScopep->scopep()->modp()->addStmtsp(varp); dpiExportTriggerp = new AstVarScope{fl, m_topScopep->scopep(), varp}; - m_topScopep->scopep()->addVarp(dpiExportTriggerp); + m_topScopep->scopep()->addVarsp(dpiExportTriggerp); v3Global.rootp()->dpiExportTriggerp(dpiExportTriggerp); } return dpiExportTriggerp; @@ -1134,7 +1134,7 @@ private: AstVarScope* rtnvscp = nullptr; if (rtnvarp) { rtnvscp = new AstVarScope(rtnvarp->fileline(), m_scopep, rtnvarp); - m_scopep->addVarp(rtnvscp); + m_scopep->addVarsp(rtnvscp); rtnvarp->user2p(rtnvscp); } @@ -1228,7 +1228,7 @@ private: } AstVarScope* const newvscp = new AstVarScope{portp->fileline(), m_scopep, portp}; - m_scopep->addVarp(newvscp); + m_scopep->addVarsp(newvscp); portp->user2p(newvscp); } } @@ -1314,9 +1314,9 @@ private: new AstVarRef{fl, dpiExportTriggerp, VAccess::READ}}}, nullptr}; for (AstVarScope* const varScopep : writtenps) { - alwaysp->addStmtp(new AstDpiExportUpdated{fl, varScopep}); + alwaysp->addStmtsp(new AstDpiExportUpdated{fl, varScopep}); } - m_scopep->addActivep(alwaysp); + m_scopep->addBlocksp(alwaysp); } } @@ -1516,7 +1516,7 @@ private: iterateAndNextNull(nodep->condp()); // Body insert just before themselves m_insStmtp = nullptr; // First thing should be new statement - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); iterateAndNextNull(nodep->incsp()); // Done the loop m_insStmtp = nullptr; // Next thing should be new statement diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index c98a120a3..328e913ad 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -454,9 +454,9 @@ private: v3Global.rootp()->typeTablep()->addTypesp(newArrDtp); AstVar* const newvarp = new AstVar(flp, VVarType::MODULETEMP, "__Vm_traceActivity", newArrDtp); - m_topModp->addStmtp(newvarp); + m_topModp->addStmtsp(newvarp); AstVarScope* const newvscp = new AstVarScope(flp, m_topScopep, newvarp); - m_topScopep->addVarp(newvscp); + m_topScopep->addVarsp(newvscp); m_activityVscp = newvscp; // Insert activity setters @@ -493,7 +493,7 @@ private: funcp->slow(full); funcp->isStatic(isTopFunc); // Add it to top scope - m_topScopep->addActivep(funcp); + m_topScopep->addBlocksp(funcp); const auto addInitStr = [funcp, flp](const string& str) -> void { funcp->addInitsp(new AstCStmt(flp, str)); }; @@ -676,7 +676,7 @@ private: // Add TraceInc node AstTraceInc* const incp = new AstTraceInc(declp->fileline(), declp, /* full: */ false, baseCode); - ifp->addIfsp(incp); + ifp->addThensp(incp); subStmts += incp->nodeCount(); // Track partitioning @@ -698,7 +698,7 @@ private: cleanupFuncp->slow(false); cleanupFuncp->isStatic(true); cleanupFuncp->isLoose(true); - m_topScopep->addActivep(cleanupFuncp); + m_topScopep->addBlocksp(cleanupFuncp); cleanupFuncp->addInitsp(new AstCStmt(fl, voidSelfAssign(m_topModp))); cleanupFuncp->addInitsp(new AstCStmt(fl, symClassAssign())); @@ -755,7 +755,7 @@ private: m_regFuncp->slow(true); m_regFuncp->isStatic(false); m_regFuncp->isLoose(true); - m_topScopep->addActivep(m_regFuncp); + m_topScopep->addBlocksp(m_regFuncp); // Create the full dump functions, also allocates signal numbers createFullTraceFunction(traces, nFullCodes, m_parallelism); diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 4c8cae3a8..9df50a158 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -162,7 +162,7 @@ private: funcp->isStatic(false); funcp->isLoose(true); funcp->slow(true); - topScopep->addActivep(funcp); + topScopep->addBlocksp(funcp); return funcp; } @@ -303,8 +303,8 @@ private: scopeName = scopeName.substr(0, lastDot + 1); const size_t scopeLen = scopeName.length(); - UASSERT_OBJ(cellp->intfRefp(), cellp, "Interface without tracing reference"); - for (AstIntfRef *irp = cellp->intfRefp(), *nextIrp; irp; irp = nextIrp) { + UASSERT_OBJ(cellp->intfRefsp(), cellp, "Interface without tracing reference"); + for (AstIntfRef *irp = cellp->intfRefsp(), *nextIrp; irp; irp = nextIrp) { nextIrp = VN_AS(irp->nextp(), IntfRef); const string irpName = irp->prettyName(); diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index f88908f62..613983a02 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -422,7 +422,7 @@ class TristateVisitor final : public TristateBaseVisitor { "Unsupported: Creating tristate signal not underneath a module: " << nodep->prettyNameQ()); } else { - m_modp->addStmtp(newp); + m_modp->addStmtsp(newp); } } void associateLogic(AstNode* fromp, AstNode* top) { @@ -554,7 +554,7 @@ class TristateVisitor final : public TristateBaseVisitor { AstNode* const newp = new AstAssignW(varp->fileline(), varrefp, constp); UINFO(9, " newoev " << newp << endl); varrefp->user1p(newAllZerosOrOnes(varp, false)); - nodep->addStmtp(newp); + nodep->addStmtsp(newp); mapInsertLhsVarRef(varrefp); // insertTristates will convert // // to a varref to the __out# variable } @@ -627,7 +627,7 @@ class TristateVisitor final : public TristateBaseVisitor { lhsp->name() + "__out" + cvtToStr(m_unique), VFlagBitPacked(), w); // 2-state ok; sep enable UINFO(9, " newout " << newlhsp << endl); - nodep->addStmtp(newlhsp); + nodep->addStmtsp(newlhsp); refp->varp(newlhsp); // assign the new var to the varref refp->name(newlhsp->name()); @@ -636,13 +636,13 @@ class TristateVisitor final : public TristateBaseVisitor { lhsp->name() + "__en" + cvtToStr(m_unique++), VFlagBitPacked(), w); // 2-state ok UINFO(9, " newenp " << newenp << endl); - nodep->addStmtp(newenp); + nodep->addStmtsp(newenp); AstNode* const enassp = new AstAssignW( refp->fileline(), new AstVarRef(refp->fileline(), newenp, VAccess::WRITE), getEnp(refp)); UINFO(9, " newass " << enassp << endl); - nodep->addStmtp(enassp); + nodep->addStmtsp(enassp); // now append this driver to the driver logic. AstNode* const ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ); @@ -675,7 +675,7 @@ class TristateVisitor final : public TristateBaseVisitor { VL_DO_DANGLING(undrivenp->deleteTree(), undrivenp); } if (envarp) { - nodep->addStmtp(new AstAssignW( + nodep->addStmtsp(new AstAssignW( enp->fileline(), new AstVarRef(envarp->fileline(), envarp, VAccess::WRITE), enp)); } // __out (child) or (parent) = drive-value expression @@ -683,7 +683,7 @@ class TristateVisitor final : public TristateBaseVisitor { lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, VAccess::WRITE), orp); assp->user2(U2_BOTH); // Don't process further; already resolved if (debug() >= 9) assp->dumpTree(cout, "-lhsp-eqn: "); - nodep->addStmtp(assp); + nodep->addStmtsp(assp); } void addToAssignmentList(AstAssignW* nodep) { @@ -864,11 +864,11 @@ class TristateVisitor final : public TristateBaseVisitor { if (m_graphing) { iterateChildren(nodep); if (m_alhs) { - associateLogic(nodep, nodep->expr1p()); - associateLogic(nodep, nodep->expr2p()); + associateLogic(nodep, nodep->thenp()); + associateLogic(nodep, nodep->elsep()); } else { - associateLogic(nodep->expr1p(), nodep); - associateLogic(nodep->expr2p(), nodep); + associateLogic(nodep->thenp(), nodep); + associateLogic(nodep->elsep(), nodep); } } else { if (m_alhs && nodep->user1p()) { @@ -887,20 +887,20 @@ class TristateVisitor final : public TristateBaseVisitor { condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with " "tristate logic in the conditional expression"); } - AstNode* const expr1p = nodep->expr1p(); - AstNode* const expr2p = nodep->expr2p(); - if (expr1p->user1p() || expr2p->user1p()) { // else no tristates + AstNode* const thenp = nodep->thenp(); + AstNode* const elsep = nodep->elsep(); + if (thenp->user1p() || elsep->user1p()) { // else no tristates m_tgraph.didProcess(nodep); - AstNode* const en1p = getEnp(expr1p); - AstNode* const en2p = getEnp(expr2p); + AstNode* const en1p = getEnp(thenp); + AstNode* const en2p = getEnp(elsep); // The output enable of a cond is a cond of the output enable of the // two expressions with the same conditional. AstNode* const enp = new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p); UINFO(9, " newcond " << enp << endl); nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable) - expr1p->user1p(nullptr); - expr2p->user1p(nullptr); + thenp->user1p(nullptr); + elsep->user1p(nullptr); } } } @@ -1391,7 +1391,7 @@ class TristateVisitor final : public TristateBaseVisitor { UINFO(9, " newpin " << enpinp << endl); enpinp->user2(U2_BOTH); // don't iterate the pin later nodep->addNextHere(enpinp); - m_modp->addStmtp(enVarp); + m_modp->addStmtsp(enVarp); enrefp = new AstVarRef(nodep->fileline(), enVarp, VAccess::READ); UINFO(9, " newvrf " << enrefp << endl); if (debug() >= 9) enpinp->dumpTree(cout, "-pin-ena: "); @@ -1608,7 +1608,7 @@ class TristateVisitor final : public TristateBaseVisitor { void visit(AstCaseItem* nodep) override { // don't deal with casez compare '???? values - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); } void visit(AstCell* nodep) override { diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index bd91ad005..df468c70f 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -120,7 +120,7 @@ private: } else { AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep()); - m_modp->addStmtp(varp); + m_modp->addStmtsp(varp); AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep' prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE)); AstIf* const newp = new AstIf( @@ -173,7 +173,7 @@ private: m_constXCvt = false; // Avoid losing the X's in casex iterateAndNextNull(nodep->condsp()); m_constXCvt = true; - iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->stmtsp()); } } void visit(AstNodeDType* nodep) override { @@ -353,9 +353,9 @@ private: // Add inits in front of other statement. // In the future, we should stuff the initp into the module's constructor. AstNode* const afterp = m_modp->stmtsp()->unlinkFrBackWithNext(); - m_modp->addStmtp(newvarp); - m_modp->addStmtp(newinitp); - m_modp->addStmtp(afterp); + m_modp->addStmtsp(newvarp); + m_modp->addStmtsp(newinitp); + m_modp->addStmtsp(afterp); if (debug() >= 9) newref1p->dumpTree(cout, " _new: "); if (debug() >= 9) newvarp->dumpTree(cout, " _new: "); if (debug() >= 9) newinitp->dumpTree(cout, " _new: "); diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 1efbef18b..2ffef6176 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -387,21 +387,21 @@ private: if (nodep->backp()->nextp() == nodep) initp = nodep->backp(); // Grab assignment AstNode* incp = nullptr; // Should be last statement - AstNode* bodysp = nodep->bodysp(); + AstNode* stmtsp = nodep->stmtsp(); if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp()); // cppcheck-suppress duplicateCondition if (nodep->incsp()) { incp = nodep->incsp(); } else { - for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} + for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {} if (incp) VL_DO_DANGLING(V3Const::constifyEdit(incp), incp); // Again, as may have changed - bodysp = nodep->bodysp(); - for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} - if (incp == bodysp) bodysp = nullptr; + stmtsp = nodep->stmtsp(); + for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {} + if (incp == stmtsp) stmtsp = nullptr; } // And check it - if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, bodysp)) { + if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, stmtsp)) { VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement } } @@ -426,7 +426,7 @@ private: // deleted by V3Const. VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } else if (forUnrollCheck(nodep, nodep->initsp(), nullptr, nodep->condp(), - nodep->incsp(), nodep->bodysp())) { + nodep->incsp(), nodep->stmtsp())) { VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement } else { nodep->v3error("For loop doesn't have genvar index, or is malformed"); diff --git a/src/V3VariableOrder.cpp b/src/V3VariableOrder.cpp index 53e53788e..ad98ec081 100644 --- a/src/V3VariableOrder.cpp +++ b/src/V3VariableOrder.cpp @@ -188,7 +188,7 @@ class VariableOrder final { stmtsp->unlinkFrBackWithNext(); AstNode::addNext(firstp, stmtsp); } - modp->addStmtp(firstp); + modp->addStmtsp(firstp); } } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 57fad0d7f..c2f77042d 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -462,22 +462,22 @@ private: iterateCheckBool(nodep, "Conditional Test", nodep->condp(), BOTH); // Determine sub expression widths only relying on what's in the subops // CONTEXT determined, but need data type for pattern assignments - userIterateAndNext(nodep->expr1p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); - userIterateAndNext(nodep->expr2p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); + userIterateAndNext(nodep->thenp(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); + userIterateAndNext(nodep->elsep(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); // Calculate width of this expression. // First call (prelim()) m_vup->width() is probably zero, so we'll return // the size of this subexpression only. // Second call (final()) m_vup->width() is probably the expression size, so // the expression includes the size of the output too. - if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) { + if (nodep->thenp()->isDouble() || nodep->elsep()->isDouble()) { nodep->dtypeSetDouble(); - } else if (nodep->expr1p()->isString() || nodep->expr2p()->isString()) { + } else if (nodep->thenp()->isString() || nodep->elsep()->isString()) { nodep->dtypeSetString(); } else { - const int width = std::max(nodep->expr1p()->width(), nodep->expr2p()->width()); + const int width = std::max(nodep->thenp()->width(), nodep->elsep()->width()); const int mwidth - = std::max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin()); - const bool issigned = nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned(); + = std::max(nodep->thenp()->widthMin(), nodep->elsep()->widthMin()); + const bool issigned = nodep->thenp()->isSigned() && nodep->elsep()->isSigned(); nodep->dtypeSetLogicUnsized(width, mwidth, VSigning::fromBool(issigned)); } } @@ -486,9 +486,9 @@ private: AstNodeDType* const subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. - iterateCheck(nodep, "Conditional True", nodep->expr1p(), CONTEXT, FINAL, subDTypep, + iterateCheck(nodep, "Conditional True", nodep->thenp(), CONTEXT, FINAL, subDTypep, EXTEND_EXP); - iterateCheck(nodep, "Conditional False", nodep->expr2p(), CONTEXT, FINAL, subDTypep, + iterateCheck(nodep, "Conditional False", nodep->elsep(), CONTEXT, FINAL, subDTypep, EXTEND_EXP); } } @@ -1834,7 +1834,7 @@ private: castSized(nodep, nodep->fromp(), width); // Note castSized might modify nodep->fromp() } else { - iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, fromDtp, EXTEND_EXP, + iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, fromDtp, EXTEND_EXP, false); } if (basicp->isDouble() && !nodep->fromp()->isDouble()) { @@ -1866,14 +1866,14 @@ private: << toDtp->prettyDTypeNameQ()); } if (!newp) newp = nodep->fromp()->unlinkFrBack(); - nodep->lhsp(newp); + nodep->fromp(newp); // if (debug()) nodep->dumpTree(cout, " CastOut: "); // if (debug()) nodep->backp()->dumpTree(cout, " CastOutUpUp: "); } if (m_vup->final()) { - iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(), + iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(), EXTEND_EXP, false); - AstNode* const underp = nodep->lhsp()->unlinkFrBack(); + AstNode* const underp = nodep->fromp()->unlinkFrBack(); // if (debug()) underp->dumpTree(cout, " CastRep: "); nodep->replaceWith(underp); VL_DO_DANGLING(pushDeletep(nodep), nodep); @@ -3972,7 +3972,7 @@ private: userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT, PRELIM).p()); for (AstCaseItem *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) { nextip = VN_AS(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced - if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), nullptr); + if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->stmtsp(), nullptr); for (AstNode *nextcp, *condp = itemp->condsp(); condp; condp = nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced VL_DO_DANGLING(userIterate(condp, WidthVP(CONTEXT, PRELIM).p()), condp); @@ -4015,27 +4015,27 @@ private: userIterateAndNext(nodep->initsp(), nullptr); iterateCheckBool(nodep, "For Test Condition", nodep->condp(), BOTH); // it's like an if() condition. - if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->bodysp(), nullptr); + if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->stmtsp(), nullptr); userIterateAndNext(nodep->incsp(), nullptr); } void visit(AstRepeat* nodep) override { assertAtStatement(nodep); userIterateAndNext(nodep->countp(), WidthVP(SELF, BOTH).p()); - userIterateAndNext(nodep->bodysp(), nullptr); + userIterateAndNext(nodep->stmtsp(), nullptr); } void visit(AstWhile* nodep) override { assertAtStatement(nodep); userIterateAndNext(nodep->precondsp(), nullptr); iterateCheckBool(nodep, "For Test Condition", nodep->condp(), BOTH); // it's like an if() condition. - userIterateAndNext(nodep->bodysp(), nullptr); + userIterateAndNext(nodep->stmtsp(), nullptr); userIterateAndNext(nodep->incsp(), nullptr); } void visit(AstNodeIf* nodep) override { assertAtStatement(nodep); // if (debug()) nodep->dumpTree(cout, " IfPre: "); if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly - userIterateAndNext(nodep->ifsp(), nullptr); + userIterateAndNext(nodep->thensp(), nullptr); userIterateAndNext(nodep->elsesp(), nullptr); } iterateCheckBool(nodep, "If", nodep->condp(), BOTH); // it's like an if() condition. @@ -4056,7 +4056,7 @@ private: UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type"); AstNodeDType* fromDtp = fromp->dtypep()->skipRefp(); // Split into for loop - AstNode* bodyp = nodep->bodysp(); // Might be null + AstNode* bodyp = nodep->stmtsp(); // Might be null if (bodyp) bodyp->unlinkFrBackWithNext(); // We record where the body needs to eventually go with bodyPointp // (Can't use bodyp as might be null) @@ -4348,8 +4348,8 @@ private: argp->unlinkFrBack(&handle); AstCMath* const newp = new AstCMath(nodep->fileline(), "VL_TO_STRING(", 0, true); - newp->addBodysp(argp); - newp->addBodysp(new AstText(nodep->fileline(), ")", true)); + newp->addExprsp(argp); + newp->addExprsp(new AstText(nodep->fileline(), ")", true)); newp->dtypeSetString(); newp->pure(true); newp->protect(false); @@ -6356,7 +6356,7 @@ private: varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing - v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); // Element 0 is a non-index and has speced values initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0)); for (unsigned i = 1; i < msbdim + 1; ++i) { @@ -6421,7 +6421,7 @@ private: varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing - v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); // Default for all unspecified values if (attrType == VAttrType::ENUM_NAME) { diff --git a/src/astgen b/src/astgen index 19a6d0b19..56956768d 100755 --- a/src/astgen +++ b/src/astgen @@ -24,6 +24,8 @@ class Node: self._file = file # File this class is defined in self._lineno = lineno # Line this class is defined on self._ordIdx = None # Ordering index of this class + self._arity = -1 # Arity of node + self._ops = {} # Operands of node @property def name(self): @@ -33,6 +35,10 @@ class Node: def superClass(self): return self._superClass + @property + def isRoot(self): + return self.superClass is None + @property def isCompleted(self): return isinstance(self._subClasses, tuple) @@ -50,6 +56,20 @@ class Node: assert not self.isCompleted self._subClasses.append(subClass) + def addOp(self, n, name, monad, kind): + assert 1 <= n <= 4 + self._ops[n] = (name, monad, kind) + self._arity = max(self._arity, n) + + def getOp(self, n): + assert 1 <= n <= 4 + op = self._ops.get(n, None) + if op is not None: + return op + if not self.isRoot: + return self.superClass.getOp(n) + return None + # Computes derived properties over entire class hierarchy. # No more changes to the hierarchy are allowed once this was called def complete(self, typeId=0, ordIdx=0): @@ -62,6 +82,11 @@ class Node: self._ordIdx = ordIdx ordIdx = ordIdx + 1 + if self.isRoot: + self._arity = 0 + else: + self._arity = max(self._arity, self._superClass.arity) + # Leaves if self.isLeaf: self._typeId = typeId @@ -78,11 +103,6 @@ class Node: assert self.isCompleted return self._subClasses - @property - def isRoot(self): - assert self.isCompleted - return self.superClass is None - @property def isLeaf(self): assert self.isCompleted @@ -140,6 +160,11 @@ class Node: assert self.isCompleted return self._ordIdx + @property + def arity(self): + assert self.isCompleted + return self._arity + def isSubClassOf(self, other): assert self.isCompleted if self is other: @@ -495,6 +520,25 @@ class Cpt: ###################################################################### +def partitionAndStrip(string, separator): + return map(lambda _: _.strip(), string.partition(separator)) + + +def parseOpType(string): + match = re.match(r'^(\w+)\[(\w+)\]$', string) + if match: + monad, kind = match.groups() + if monad not in ("Optional", "List"): + return None + kind = parseOpType(kind) + if not kind or kind[0]: + return None + return monad, kind[1] + if re.match(r'^Ast(\w+)$', string): + return "", string[3:] + return None + + def read_types(filename): hasErrors = False @@ -539,12 +583,65 @@ def read_types(filename): node = Node(classn, superClass, filename, lineno) superClass.addSubClass(node) Nodes[classn] = node - if not node: continue if re.match(r'^\s*ASTGEN_MEMBERS_' + node.name + ';', line): hasAstgenMembers = True + match = re.match(r'^\s*//\s*@astgen\s+(.*)$', line) + if match: + decl = re.sub(r'//.*$', '', match.group(1)) + what, sep, rest = partitionAndStrip(decl, ":=") + what = re.sub(r'\s+', ' ', what) + if not sep: + error( + lineno, + "Malformed '@astgen' directive (expecting ' := '): " + + decl) + elif what in ("op1", "op2", "op3", "op4"): + n = int(what[-1]) + ident, sep, kind = partitionAndStrip(rest, ":") + ident = ident.strip() + if not sep or not re.match(r'^\w+$', ident): + error( + lineno, "Malformed '@astgen " + what + + "' directive (expecting '" + what + + " := : ': " + decl) + else: + kind = parseOpType(kind) + if not kind: + error( + lineno, "Bad type for '@astgen " + what + + "' (expecting Ast*, Optional[Ast*], or List[Ast*]):" + + decl) + elif node.getOp(n) is not None: + error( + lineno, "Already defined " + what + " for " + + node.name) + else: + node.addOp(n, ident, *kind) + elif what in ("alias op1", "alias op2", "alias op3", + "alias op4"): + n = int(what[-1]) + ident = rest.strip() + if not re.match(r'^\w+$', ident): + error( + lineno, "Malformed '@astgen " + what + + "' directive (expecting '" + what + + " := ': " + decl) + else: + op = node.getOp(n) + if op is None: + error(lineno, + "Alaised op" + str(n) + " is not defined") + else: + node.addOp(n, ident, *op[1:]) + else: + line = re.sub(r'//.*$', '', line) + if re.match(r'.*[Oo]p[1-9].*', line): + error(lineno, + "Use generated accessors to access op operands") + checkFinishedNode(node) if hasErrors: sys.exit("%Error: Stopping due to errors reported above") @@ -614,6 +711,7 @@ def write_report(filename): fh.write("\nClasses:\n") for node in SortedNodes: fh.write(" class Ast%-17s\n" % node.name) + fh.write(" arity: {}\n".format(node.arity)) fh.write(" parent: ") for superClass in node.allSuperClasses: if not superClass.isRoot: @@ -759,6 +857,42 @@ def write_macros(filename): ''', t=node.name) + for n in (1, 2, 3, 4): + op = node.getOp(n) + if not op: + continue + name, monad, kind = op + retrieve = ("VN_AS(op{n}p(), {kind})" if kind != "Node" else + "op{n}p()").format(n=n, kind=kind) + if monad == "List": + emitBlock('''\ + Ast{kind}* {name}() const {{ return {retrieve}; }} + void add{Name}(Ast{kind}* nodep) {{ addNOp{n}p(reinterpret_cast(nodep)); }} + ''', + kind=kind, + name=name, + Name=name[0].upper() + name[1:], + n=n, + retrieve=retrieve) + elif monad == "Optional": + emitBlock('''\ + Ast{kind}* {name}() const {{ return {retrieve}; }} + void {name}(Ast{kind}* nodep) {{ setNOp{n}p(reinterpret_cast(nodep)); }} + ''', + kind=kind, + name=name, + n=n, + retrieve=retrieve) + else: + emitBlock('''\ + Ast{kind}* {name}() const {{ return {retrieve}; }} + void {name}(Ast{kind}* nodep) {{ setOp{n}p(reinterpret_cast(nodep)); }} + ''', + kind=kind, + name=name, + n=n, + retrieve=retrieve) + fh.write( " static_assert(true, \"\")\n") # Swallowing the semicolon diff --git a/src/bisonpre b/src/bisonpre index e03a7e41e..c60e3575d 100755 --- a/src/bisonpre +++ b/src/bisonpre @@ -391,9 +391,8 @@ def clean_input(filename, outname): if not re.match(r'^\s*$', line): sys.exit( "%Error: " + filename + ":" + str(lineno) + ": Need " + - needmore + - " more blank lines to keep line numbers are constant\n" - ) + str(needmore) + + " more blank lines to keep line numbers constant\n") needmore -= 1 else: lines.append(line) diff --git a/src/verilog.y b/src/verilog.y index 4d3c38bc3..c2b17e25c 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1068,6 +1068,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion +// Blank lines for type insertion %start source_text @@ -1092,8 +1093,8 @@ description: // ==IEEE: description | interface_declaration { } | program_declaration { } | package_declaration { } - | package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); } - | bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); } + | package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); } + | bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); } // unsupported // IEEE: config_declaration // // Verilator only | yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3 @@ -1119,7 +1120,7 @@ timeunits_declaration: // ==IEEE: timeunits_declaration package_declaration: // ==IEEE: package_declaration packageFront package_itemListE yENDPACKAGE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc - if ($2) $1->addStmtp($2); + if ($2) $1->addStmtsp($2); GRAMMARP->m_modp = nullptr; SYMP->popScope($1); GRAMMARP->endLabel($4,$1,$4); } @@ -1132,7 +1133,7 @@ packageFront: $$->lifetime($2); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->timeunit(PARSEP->timeLastUnit()); - PARSEP->rootp()->addModulep($$); + PARSEP->rootp()->addModulesp($$); SYMP->pushNew($$); GRAMMARP->m_modp = $$; } ; @@ -1228,18 +1229,18 @@ module_declaration: // ==IEEE: module_declaration modFront importsAndParametersE portsStarE ';' /*cont*/ module_itemListE yENDMODULE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc - if ($2) $1->addStmtp($2); - if ($3) $1->addStmtp($3); - if ($5) $1->addStmtp($5); + if ($2) $1->addStmtsp($2); + if ($3) $1->addStmtsp($3); + if ($5) $1->addStmtsp($5); GRAMMARP->m_modp = nullptr; SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } | udpFront parameter_port_listE portsStarE ';' /*cont*/ module_itemListE yENDPRIMITIVE endLabelE { $1->modTrace(false); // Stash for implicit wires, etc - if ($2) $1->addStmtp($2); - if ($3) $1->addStmtp($3); - if ($5) $1->addStmtp($5); + if ($2) $1->addStmtsp($2); + if ($3) $1->addStmtsp($3); + if ($5) $1->addStmtsp($5); GRAMMARP->m_tracingParse = true; GRAMMARP->m_modp = nullptr; SYMP->popScope($1); @@ -1259,7 +1260,7 @@ modFront: $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->timeunit(PARSEP->timeLastUnit()); $$->unconnectedDrive(PARSEP->unconnectedDrive()); - PARSEP->rootp()->addModulep($$); + PARSEP->rootp()->addModulesp($$); SYMP->pushNew($$); GRAMMARP->m_modp = $$; } ; @@ -1275,9 +1276,9 @@ udpFront: { $$ = new AstPrimitive($3, *$3); $$->inLibrary(true); $$->lifetime($2); $$->modTrace(false); - $$->addStmtp(new AstPragma($3, VPragmaType::INLINE_MODULE)); + $$->addStmtsp(new AstPragma($3, VPragmaType::INLINE_MODULE)); GRAMMARP->m_tracingParse = false; - PARSEP->rootp()->addModulep($$); + PARSEP->rootp()->addModulesp($$); SYMP->pushNew($$); } ; @@ -1489,9 +1490,9 @@ interface_declaration: // IEEE: interface_declaration + interface_nonan // // timeunits_delcarationE is instead in interface_item intFront importsAndParametersE portsStarE ';' interface_itemListE yENDINTERFACE endLabelE - { if ($2) $1->addStmtp($2); - if ($3) $1->addStmtp($3); - if ($5) $1->addStmtp($5); + { if ($2) $1->addStmtsp($2); + if ($3) $1->addStmtsp($3); + if ($5) $1->addStmtsp($5); SYMP->popScope($1); } | yEXTERN intFront parameter_port_listE portsStarE ';' { BBUNSUP($1, "Unsupported: extern interface"); } @@ -1502,7 +1503,7 @@ intFront: { $$ = new AstIface($3, *$3); $$->inLibrary(true); $$->lifetime($2); - PARSEP->rootp()->addModulep($$); + PARSEP->rootp()->addModulesp($$); SYMP->pushNew($$); } ; @@ -1578,9 +1579,9 @@ program_declaration: // IEEE: program_declaration + program_nonansi_h pgmFront parameter_port_listE portsStarE ';' /*cont*/ program_itemListE yENDPROGRAM endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc - if ($2) $1->addStmtp($2); - if ($3) $1->addStmtp($3); - if ($5) $1->addStmtp($5); + if ($2) $1->addStmtsp($2); + if ($3) $1->addStmtsp($3); + if ($5) $1->addStmtsp($5); GRAMMARP->m_modp = nullptr; SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } @@ -1596,7 +1597,7 @@ pgmFront: $$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn()); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->timeunit(PARSEP->timeLastUnit()); - PARSEP->rootp()->addModulep($$); + PARSEP->rootp()->addModulesp($$); SYMP->pushNew($$); GRAMMARP->m_modp = $$; } ; @@ -2008,12 +2009,13 @@ struct_unionDecl: // IEEE: part of data_type { $$ = $5; $$->addMembersp($6); SYMP->popScope($$); } ; -struct_union_memberList: // IEEE: { struct_union_member } +struct_union_memberList: // IEEE: { struct_union_member } struct_union_member { $$ = $1; } + | struct_union_memberList struct_union_member { $$ = addNextNull($1, $2); } ; -struct_union_member: // ==IEEE: struct_union_member +struct_union_member: // ==IEEE: struct_union_member // // UNSUP random_qualifer not propagagted until have randomize support random_qualifierE data_type_or_void /*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. @@ -2021,7 +2023,7 @@ struct_union_member: // ==IEEE: struct_union_member | vlTag { $$ = nullptr; } ; -list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments +list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments member_decl_assignment { $$ = $1; } | list_of_member_decl_assignments ',' member_decl_assignment { $$ = addNextNull($1, $3); } ; @@ -2177,17 +2179,17 @@ enum_base_typeE: // IEEE: enum_base_type $$ = GRAMMARP->createArray(refp, $3, true); } ; -enum_nameList: +enum_nameList: enum_name_declaration { $$ = $1; } | enum_nameList ',' enum_name_declaration { $$ = addNextNull($1, $3); } ; -enum_name_declaration: // ==IEEE: enum_name_declaration +enum_name_declaration: // ==IEEE: enum_name_declaration idAny/*enum_identifier*/ enumNameRangeE enumNameStartE { $$ = new AstEnumItem($1, *$1, $2, $3); } ; -enumNameRangeE: // IEEE: second part of enum_name_declaration +enumNameRangeE: // IEEE: second part of enum_name_declaration /* empty */ { $$ = nullptr; } | '[' intnumAsConst ']' @@ -2472,7 +2474,7 @@ continuous_assign: // IEEE: continuous_assign if ($3) for (auto* nodep = $$; nodep; nodep = nodep->nextp()) { auto* const assignp = VN_AS(nodep, NodeAssign); - assignp->addTimingControlp(nodep == $$ ? $3 : $3->cloneTree(false)); + assignp->timingControlp(nodep == $$ ? $3 : $3->cloneTree(false)); } } ; @@ -2634,7 +2636,7 @@ loop_generate_construct: // ==IEEE: loop_generate_construct } // Statements are under 'genforp' as cells under this // for loop won't get an extra layer of hierarchy tacked on - blkp->addGenforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp)); + blkp->genforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp)); $$ = blkp; VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp); } @@ -2679,12 +2681,12 @@ genvar_iteration: // ==IEEE: genvar_iteration new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; } ; -case_generate_itemListE: // IEEE: [{ case_generate_itemList }] +case_generate_itemListE: // IEEE: [{ case_generate_itemList }] /* empty */ { $$ = nullptr; } | case_generate_itemList { $$ = $1; } ; -case_generate_itemList: // IEEE: { case_generate_itemList } +case_generate_itemList: // IEEE: { case_generate_itemList } ~c~case_generate_item { $$ = $1; } | ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); } ; @@ -2693,7 +2695,7 @@ case_generate_itemList: // IEEE: { case_generate_itemList } //UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied} //UNSUP ; -case_generate_item: // ==IEEE: case_generate_item +case_generate_item: // ==IEEE: case_generate_item caseCondList colon generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; } | yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; } | yDEFAULT generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; } @@ -2768,7 +2770,7 @@ netSig: // IEEE: net_decl_assignment - one element from { $$ = VARDONEA($1, *$1, nullptr, $2); auto* const assignp = new AstAssignW{$3, new AstVarRef{$1, *$1, VAccess::WRITE}, $4}; if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false)); - if ($$->delayp()) assignp->addTimingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3 + if ($$->delayp()) assignp->timingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3 AstNode::addNext($$, assignp); } | netId variable_dimensionList sigAttrListE { $$ = VARDONEA($1,*$1, $2, $3); } ; @@ -4110,19 +4112,19 @@ funcId: // IEEE: function_data_type_or_implicit // // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID /**/ fIdScoped { $$ = $1; - $$->addFvarp(new AstBasicDType($1, LOGIC_IMPLICIT)); + $$->fvarp(new AstBasicDType($1, LOGIC_IMPLICIT)); SYMP->pushNewUnderNodeOrCurrent($$, $1); } | signingE rangeList fIdScoped { $$ = $3; - $$->addFvarp(GRAMMARP->addRange(new AstBasicDType($3, LOGIC_IMPLICIT, $1), $2,true)); + $$->fvarp(GRAMMARP->addRange(new AstBasicDType($3, LOGIC_IMPLICIT, $1), $2,true)); SYMP->pushNewUnderNodeOrCurrent($$, $3); } | signing fIdScoped { $$ = $2; - $$->addFvarp(new AstBasicDType($2, LOGIC_IMPLICIT, $1)); + $$->fvarp(new AstBasicDType($2, LOGIC_IMPLICIT, $1)); SYMP->pushNewUnderNodeOrCurrent($$, $2); } | data_type fIdScoped { $$ = $2; - $$->addFvarp($1); + $$->fvarp($1); SYMP->pushNewUnderNodeOrCurrent($$, $2); } // // To verilator tasks are the same as void functions (we separately detect time passing) | yVOID taskId @@ -4992,12 +4994,12 @@ combinational_body: // IEEE: combinational_body + sequential_body yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); } ; -tableEntryList: // IEEE: { combinational_entry | sequential_entry } +tableEntryList: // IEEE: { combinational_entry | sequential_entry } tableEntry { $$ = $1; } | tableEntryList tableEntry { $$ = addNextNull($1, $2); } ; -tableEntry: // IEEE: combinational_entry + sequential_entry +tableEntry: // IEEE: combinational_entry + sequential_entry yaTABLELINE { $$ = new AstUdpTableLine($1,*$1); } | error { $$ = nullptr; } ; @@ -6227,14 +6229,14 @@ classVirtualE: | yVIRTUAL__CLASS { $$ = true; } ; -classExtendsE: // IEEE: part of class_declaration +classExtendsE: // IEEE: part of class_declaration // // The classExtendsE rule relys on classFront having the // // new class scope correct via classFront /* empty */ { $$ = nullptr; $$ = nullptr; } | yEXTENDS classExtendsList { $$ = $2; $$ = $2; } ; -classExtendsList: // IEEE: part of class_declaration +classExtendsList: // IEEE: part of class_declaration classExtendsOne { $$ = $1; $$ = $1; } | classExtendsList ',' classExtendsOne { $$ = $3; $$ = $3; @@ -6242,7 +6244,7 @@ classExtendsList: // IEEE: part of class_declaration "and unsupported for interface classes."); } ; -classExtendsOne: // IEEE: part of class_declaration +classExtendsOne: // IEEE: part of class_declaration class_typeExtImpList { $$ = new AstClassExtends($1->fileline(), $1); $$ = $1; }