From 3abb65d732f228cfeb16561b2cf081e68c652423 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 13 Nov 2022 20:33:11 +0000 Subject: [PATCH] Strengthen AstNode types to AstNodeExpr Declare every AstNode children and variables as AstNodeExpr where we statically know this is the appropriate sub-type. --- src/V3Assert.cpp | 58 +- src/V3AssertPre.cpp | 28 +- src/V3Ast.h | 4 +- src/V3AstInlines.h | 2 +- src/V3AstNodeDType.h | 14 +- src/V3AstNodeExpr.h | 922 ++++++++++++++--------- src/V3AstNodeOther.h | 429 +++-------- src/V3AstNodes.cpp | 28 +- src/V3CCtors.cpp | 5 +- src/V3Case.cpp | 34 +- src/V3Cast.cpp | 9 +- src/V3Clean.cpp | 18 +- src/V3Clock.cpp | 22 +- src/V3Common.cpp | 7 +- src/V3Const.cpp | 370 +++++---- src/V3Const.h | 12 +- src/V3Coverage.cpp | 6 +- src/V3Delayed.cpp | 24 +- src/V3Depth.cpp | 2 +- src/V3DfgDfgToAst.cpp | 2 +- src/V3Expand.cpp | 170 ++--- src/V3Force.cpp | 6 +- src/V3Inst.cpp | 26 +- src/V3LinkDot.cpp | 21 +- src/V3LinkInc.cpp | 6 +- src/V3LinkJump.cpp | 8 +- src/V3LinkParse.cpp | 10 +- src/V3MergeCond.cpp | 24 +- src/V3ParseGrammar.cpp | 6 +- src/V3Premit.cpp | 15 +- src/V3Randomize.cpp | 6 +- src/V3Reloop.cpp | 14 +- src/V3SenExprBuilder.h | 14 +- src/V3Simulate.h | 40 +- src/V3Slice.cpp | 23 +- src/V3SplitVar.cpp | 29 +- src/V3Subst.cpp | 12 +- src/V3Table.cpp | 8 +- src/V3Task.cpp | 18 +- src/V3Timing.cpp | 26 +- src/V3Trace.cpp | 6 +- src/V3TraceDecl.cpp | 2 +- src/V3Tristate.cpp | 122 +-- src/V3Unknown.cpp | 52 +- src/V3Width.cpp | 299 ++++---- src/V3WidthSel.cpp | 59 +- src/astgen | 15 +- src/verilog.y | 113 +-- test_regress/t/t_stream_bad.out | 15 + test_regress/t/t_stream_bad.pl | 19 + test_regress/t/t_stream_bad.v | 14 + test_regress/t/t_stream_integer_type.out | 120 ++- 52 files changed, 1742 insertions(+), 1572 deletions(-) create mode 100644 test_regress/t/t_stream_bad.out create mode 100755 test_regress/t/t_stream_bad.pl create mode 100644 test_regress/t/t_stream_bad.v diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 62976a59a..4c37f2f76 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -59,8 +59,8 @@ private: nodep->displayType(VDisplayType::DT_WRITE); nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text())); // cppcheck-suppress nullPointer - AstNode* const timenewp = new AstTime{nodep->fileline(), m_modp->timeunit()}; - if (AstNode* const timesp = nodep->fmtp()->exprsp()) { + AstNodeExpr* const timenewp = new AstTime{nodep->fileline(), m_modp->timeunit()}; + if (AstNodeExpr* const timesp = nodep->fmtp()->exprsp()) { timesp->unlinkFrBackWithNext(); timenewp->addNext(timesp); } @@ -69,7 +69,7 @@ private: nodep->fmtp()->scopeNamep(new AstScopeName{nodep->fileline(), true}); } } - AstSampled* newSampledExpr(AstNode* nodep) { + AstSampled* newSampledExpr(AstNodeExpr* nodep) { const auto sampledp = new AstSampled{nodep->fileline(), nodep}; sampledp->dtypeFrom(nodep); return sampledp; @@ -98,16 +98,16 @@ private: // Add a internal if to check assertions are on. // Don't make this a AND term, as it's unlikely to need to test this. FileLine* const fl = nodep->fileline(); - AstNodeIf* const newp = new AstIf{ - fl, - (force ? new AstConst{fl, AstConst::BitTrue{}} - : // If assertions are off, have constant propagation rip them out later - // This allows syntax errors and such to be detected normally. - (v3Global.opt.assertOn() - ? static_cast( - new AstCExpr{fl, "vlSymsp->_vm_contextp__->assertOn()", 1}) - : static_cast(new AstConst{fl, AstConst::BitFalse{}}))), - nodep}; + + // If assertions are off, have constant propagation rip them out later + // This allows syntax errors and such to be detected normally. + AstNodeExpr* const condp + = force ? static_cast(new AstConst{fl, AstConst::BitTrue{}}) + : v3Global.opt.assertOn() + ? static_cast( + new AstCExpr{fl, "vlSymsp->_vm_contextp__->assertOn()", 1}) + : static_cast(new AstConst{fl, AstConst::BitFalse{}}); + AstNodeIf* const newp = new AstIf{fl, condp, nodep}; newp->isBoundsCheck(true); // To avoid LATCH warning newp->user1(true); // Don't assert/cover this if return newp; @@ -133,7 +133,7 @@ private: void newPslAssertion(AstNodeCoverOrAssert* nodep, AstNode* failsp) { if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name()); - AstNode* const propp = nodep->propp()->unlinkFrBackWithNext(); + AstNodeExpr* const propp = VN_AS(nodep->propp()->unlinkFrBackWithNext(), NodeExpr); AstSenTree* const sentreep = nodep->sentreep(); const string& message = nodep->name(); AstNode* passsp = nodep->passsp(); @@ -211,7 +211,7 @@ private: if (nodep->user1SetOnce()) return; if (nodep->uniquePragma() || nodep->unique0Pragma()) { const AstNodeIf* ifp = nodep; - AstNode* propp = nullptr; + AstNodeExpr* propp = nullptr; bool hasDefaultElse = false; do { // If this statement ends with 'else if', then nextIf will point to the @@ -228,7 +228,7 @@ private: } // Build a bitmask of the true predicates - AstNode* const predp = ifp->condp()->cloneTree(false); + AstNodeExpr* const predp = ifp->condp()->cloneTree(false); if (propp) { propp = new AstConcat{nodep->fileline(), predp, propp}; } else { @@ -249,10 +249,10 @@ private: // Note: if this ends with an 'else', then we don't need to validate that one of the // predicates evaluates to true. - AstNode* const ohot + AstNodeExpr* const ohot = ((allow_none || hasDefaultElse) - ? static_cast(new AstOneHot0{nodep->fileline(), propp}) - : static_cast(new AstOneHot{nodep->fileline(), propp})); + ? static_cast(new AstOneHot0{nodep->fileline(), propp}) + : static_cast(new AstOneHot{nodep->fileline(), propp})); AstIf* const checkifp = new AstIf{nodep->fileline(), new AstLogNot{nodep->fileline(), ohot}, newFireAssert(nodep, "'unique if' statement violated"), newifp}; @@ -290,11 +290,12 @@ private: if (!has_default && !nodep->itemsp()) { // Not parallel, but harmlessly so. } else { - AstNode* propp = nullptr; + AstNodeExpr* propp = nullptr; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) { - for (AstNode* icondp = itemp->condsp(); icondp; icondp = icondp->nextp()) { - AstNode* onep; + for (AstNodeExpr* icondp = itemp->condsp(); icondp; + icondp = VN_AS(icondp->nextp(), NodeExpr)) { + AstNodeExpr* onep; if (AstInsideRange* const rcondp = VN_CAST(icondp, InsideRange)) { onep = rcondp->newAndFromInside(nodep->exprp(), rcondp->lhsp()->cloneTree(true), @@ -319,10 +320,11 @@ private: if (!propp) propp = new AstConst{nodep->fileline(), AstConst::BitFalse{}}; const bool allow_none = has_default || nodep->unique0Pragma(); - AstNode* const ohot - = (allow_none - ? static_cast(new AstOneHot0{nodep->fileline(), propp}) - : static_cast(new AstOneHot{nodep->fileline(), propp})); + AstNodeExpr* const ohot + = (allow_none ? static_cast( + new AstOneHot0{nodep->fileline(), propp}) + : static_cast( + new AstOneHot{nodep->fileline(), propp})); AstIf* const ifp = new AstIf{ nodep->fileline(), new AstLogNot{nodep->fileline(), ohot}, newFireAssert(nodep, @@ -345,8 +347,8 @@ private: ticks = VN_AS(nodep->ticksp(), Const)->toUInt(); } UASSERT_OBJ(ticks >= 1, nodep, "0 tick should have been checked in V3Width"); - AstNode* const exprp = nodep->exprp()->unlinkFrBack(); - AstNode* inp = newSampledExpr(exprp); + AstNodeExpr* const exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* inp = newSampledExpr(exprp); AstVar* invarp = nullptr; AstSenTree* const sentreep = nodep->sentreep(); sentreep->unlinkFrBack(); diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 0cd4a9a00..43d5f6e32 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -46,7 +46,7 @@ private: // Reset each always: AstSenItem* m_seniAlwaysp = nullptr; // Last sensitivity in always // Reset each assertion: - AstNode* m_disablep = nullptr; // Last disable + AstNodeExpr* m_disablep = nullptr; // Last disable // METHODS @@ -113,7 +113,7 @@ private: } // If disable iff is in outer property, move it to inner if (nodep->disablep()) { - AstNode* const disablep = nodep->disablep()->unlinkFrBack(); + AstNodeExpr* const disablep = nodep->disablep()->unlinkFrBack(); propExprp->disablep(disablep); } @@ -170,9 +170,9 @@ private: if (nodep->sentreep()) return; // Already processed iterateChildren(nodep); FileLine* const fl = nodep->fileline(); - AstNode* exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* exprp = nodep->exprp()->unlinkFrBack(); if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1); - AstNode* const past = new AstPast(fl, exprp, nullptr); + AstNodeExpr* const past = new AstPast(fl, exprp, nullptr); past->dtypeFrom(exprp); exprp = new AstAnd(fl, past, new AstNot(fl, exprp->cloneTree(false))); exprp->dtypeSetBit(); @@ -189,9 +189,9 @@ private: if (nodep->sentreep()) return; // Already processed iterateChildren(nodep); FileLine* const fl = nodep->fileline(); - AstNode* exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* exprp = nodep->exprp()->unlinkFrBack(); if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1); - AstNode* const past = new AstPast(fl, exprp, nullptr); + AstNodeExpr* const past = new AstPast(fl, exprp, nullptr); past->dtypeFrom(exprp); exprp = new AstAnd(fl, new AstNot(fl, past), exprp->cloneTree(false)); exprp->dtypeSetBit(); @@ -203,8 +203,8 @@ private: if (nodep->sentreep()) return; // Already processed iterateChildren(nodep); FileLine* const fl = nodep->fileline(); - AstNode* exprp = nodep->exprp()->unlinkFrBack(); - AstNode* const past = new AstPast(fl, exprp, nullptr); + AstNodeExpr* exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* const past = new AstPast(fl, exprp, nullptr); past->dtypeFrom(exprp); exprp = new AstEq(fl, past, exprp->cloneTree(false)); exprp->dtypeSetBit(); @@ -217,14 +217,14 @@ private: if (nodep->sentreep()) return; // Already processed FileLine* const fl = nodep->fileline(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack(); if (m_disablep) lhsp = new AstAnd(fl, new AstNot(fl, m_disablep), lhsp); - AstNode* const past = new AstPast(fl, lhsp, nullptr); + AstNodeExpr* const past = new AstPast(fl, lhsp, nullptr); past->dtypeFrom(lhsp); - AstNode* const exprp = new AstOr(fl, new AstNot(fl, past), rhsp); + AstNodeExpr* const exprp = new AstOr(fl, new AstNot(fl, past), rhsp); exprp->dtypeSetBit(); nodep->replaceWith(exprp); nodep->sentreep(newSenTree(nodep)); @@ -238,8 +238,8 @@ private: if (m_senip) nodep->v3warn(E_UNSUPPORTED, "Unsupported: Only one PSL clock allowed per assertion"); // Block is the new expression to evaluate - AstNode* blockp = nodep->propp()->unlinkFrBack(); - if (AstNode* const disablep = nodep->disablep()) { + AstNodeExpr* blockp = VN_AS(nodep->propp()->unlinkFrBack(), NodeExpr); + if (AstNodeExpr* const disablep = nodep->disablep()) { m_disablep = disablep->cloneTree(false); if (VN_IS(nodep->backp(), Cover)) { blockp = new AstAnd(disablep->fileline(), diff --git a/src/V3Ast.h b/src/V3Ast.h index 778b8f252..486daa879 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1877,8 +1877,8 @@ public: void addNextHere(AstNode* newp); // Insert newp at this->nextp void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next void replaceWith(AstNode* newp); // Replace current node in tree with new node - AstNode* unlinkFrBack(VNRelinker* linkerp - = nullptr); // Unlink this from whoever points to it. + // Unlink this from whoever points to it. + AstNode* unlinkFrBack(VNRelinker* linkerp = nullptr); // Unlink this from whoever points to it, keep entire next list with unlinked node AstNode* unlinkFrBackWithNext(VNRelinker* linkerp = nullptr); void swapWith(AstNode* bp); diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 3793225c0..c4f574412 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -130,7 +130,7 @@ bool AstBasicDType::littleEndian() const { bool AstActive::hasClocked() const { return m_sensesp->hasClocked(); } bool AstActive::hasCombo() const { return m_sensesp->hasCombo(); } -AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp) +AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNodeExpr* exprsp) : ASTGEN_SUPER_ElabDisplay(fl) { addFmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp}); m_displayType = dispType; diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 8bb23b9f1..2e76588bd 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -261,13 +261,13 @@ public: // === AstNode === class AstEnumItem final : public AstNode { // @astgen op1 := rangep : Optional[AstRange] // Range for name appending - // @astgen op2 := valuep : Optional[AstNode] + // @astgen op2 := valuep : Optional[AstNodeExpr] private: string m_name; public: // Parents: ENUM - AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNode* valuep) + AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNodeExpr* valuep) : ASTGEN_SUPER_EnumItem(fl) , m_name{name} { this->rangep(rangep); @@ -972,18 +972,18 @@ public: class AstQueueDType final : public AstNodeDType { // Queue array data type, ie "[ $ ]" // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width - // @astgen op2 := boundp : Optional[AstNode] + // @astgen op2 := boundp : Optional[AstNodeExpr] private: AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) public: - AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp) + AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeExpr* boundp) : ASTGEN_SUPER_QueueDType(fl) { this->childDTypep(dtp); this->boundp(boundp); refDTypep(nullptr); dtypep(nullptr); // V3Width will resolve } - AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp) + AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNodeExpr* boundp) : ASTGEN_SUPER_QueueDType(fl) { this->boundp(boundp); refDTypep(dtp); @@ -1032,7 +1032,7 @@ public: }; class AstRefDType final : public AstNodeDType { // @astgen op1 := typeofp : Optional[AstNode] - // @astgen op2 := classOrPackageOpp : Optional[AstNode] + // @astgen op2 := classOrPackageOpp : Optional[AstNodeExpr] // @astgen op3 := paramsp : List[AstPin] private: // Pre-Width must reference the Typeref, not what it points to, as some child @@ -1046,7 +1046,7 @@ public: AstRefDType(FileLine* fl, const string& name) : ASTGEN_SUPER_RefDType(fl) , m_name{name} {} - AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstPin* paramsp) + AstRefDType(FileLine* fl, const string& name, AstNodeExpr* classOrPackagep, AstPin* paramsp) : ASTGEN_SUPER_RefDType(fl) , m_name{name} { this->classOrPackageOpp(classOrPackagep); diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index b44af081a..ab1fad6e5 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -6,10 +6,9 @@ // //************************************************************************* // -// Copyright 2003-2022 by Wilson Snyder. This program is free software; you -// can redistribute it and/or modify it under the terms of either the GNU -// Lesser General Public License Version 3 or the Perl Artistic License -// Version 2.0. +// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU Lesser +// General Public License Version 3 or the Perl Artistic License Version 2.0. // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // //************************************************************************* @@ -18,6 +17,16 @@ // i.e.: those constructs that represent, or evaluate to [a possible void] // value. The root of the hierarchy is 'AstNodeExpr'. // +// Think of expressions in a very general sense as constructs that "name +// things". The "thing" can be considered the value, but can be highly +// structured. For example, an AstConst can name the value '1', which is +// hopefully familiar. On the opposite end of the spectrum of "things" named by +// expressions, consider AstClassOrPackageRef, that can name a collection of +// pairs (specifically the collection of ('member name', 'member thing') +// pairs). Nevertheless, that collection itself can be considered a value. The +// valid composition of expressions then defines the calculus of values in the +// language. +// //************************************************************************* #ifndef VERILATOR_V3ASTNODEEXPR_H_ @@ -41,7 +50,8 @@ public: ASTGEN_MEMBERS_AstNodeExpr; // METHODS void dump(std::ostream& str) const override; - bool hasDType() const final override { return true; } + // TODO: The only AstNodeExpr without dtype is AstArg. Otherwise this could be final. + bool hasDType() const override { return true; } virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV // For documentation on emitC format see EmitCFunc::emitOpName virtual string emitC() = 0; @@ -57,10 +67,10 @@ public: }; class AstNodeBiop VL_NOT_FINAL : public AstNodeExpr { // Binary expression - // @astgen op1 := lhsp : AstNode - // @astgen op2 := rhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr protected: - AstNodeBiop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNodeBiop(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : AstNodeExpr{t, fl} { this->lhsp(lhsp); this->rhsp(rhsp); @@ -69,7 +79,7 @@ protected: public: ASTGEN_MEMBERS_AstNodeBiop; // Clone single node, just get same type back. - virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) = 0; + virtual AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) = 0; // METHODS // Set out to evaluation of a AstConst'ed virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) = 0; @@ -87,7 +97,7 @@ public: class AstNodeBiCom VL_NOT_FINAL : public AstNodeBiop { // Binary expr with commutative properties protected: - AstNodeBiCom(VNType t, FileLine* fl, AstNode* lhs, AstNode* rhs) + AstNodeBiCom(VNType t, FileLine* fl, AstNodeExpr* lhs, AstNodeExpr* rhs) : AstNodeBiop{t, fl, lhs, rhs} {} public: @@ -96,7 +106,7 @@ public: class AstNodeBiComAsv VL_NOT_FINAL : public AstNodeBiCom { // Binary expr with commutative & associative properties protected: - AstNodeBiComAsv(VNType t, FileLine* fl, AstNode* lhs, AstNode* rhs) + AstNodeBiComAsv(VNType t, FileLine* fl, AstNodeExpr* lhs, AstNodeExpr* rhs) : AstNodeBiCom{t, fl, lhs, rhs} {} public: @@ -107,7 +117,7 @@ class AstNodeSel VL_NOT_FINAL : public AstNodeBiop { // @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) + AstNodeSel(VNType t, FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : AstNodeBiop{t, fl, fromp, bitp} {} public: @@ -117,7 +127,7 @@ public: class AstNodeStream VL_NOT_FINAL : public AstNodeBiop { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() protected: - AstNodeStream(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNodeStream(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : AstNodeBiop{t, fl, lhsp, rhsp} { if (lhsp->dtypep()) dtypeSetLogicSized(lhsp->dtypep()->width(), VSigning::UNSIGNED); } @@ -127,7 +137,7 @@ public: }; class AstNodeSystemBiop VL_NOT_FINAL : public AstNodeBiop { public: - AstNodeSystemBiop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNodeSystemBiop(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : AstNodeBiop(t, fl, lhsp, rhsp) { dtypeSetDouble(); } @@ -142,12 +152,12 @@ public: }; class AstNodeCCall VL_NOT_FINAL : public AstNodeExpr { // 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 + // @astgen op2 := argsp : List[AstNodeExpr] // Note: op1 used by some sub-types only AstCFunc* m_funcp; string m_argTypes; protected: - AstNodeCCall(VNType t, FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr) + AstNodeCCall(VNType t, FileLine* fl, AstCFunc* funcp, AstNodeExpr* argsp = nullptr) : AstNodeExpr{t, fl} , m_funcp{funcp} { addArgsp(argsp); @@ -180,7 +190,7 @@ class AstNodeFTaskRef VL_NOT_FINAL : public AstNodeExpr { // A reference to a task (or function) // @astgen op1 := namep : Optional[AstNode] // op2 used by some sub-types only - // @astgen op3 := pinsp : List[AstNode] + // @astgen op3 := pinsp : List[AstNodeExpr] // @astgen op4 := scopeNamep : Optional[AstScopeName] AstNodeFTask* m_taskp = nullptr; // [AfterLink] Pointer to task referenced AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy @@ -189,12 +199,12 @@ class AstNodeFTaskRef VL_NOT_FINAL : public AstNodeExpr { string m_inlinedDots; // Dotted hierarchy flattened out bool m_pli = false; // Pli system call ($name) protected: - AstNodeFTaskRef(VNType t, FileLine* fl, AstNode* namep, AstNode* pinsp) + AstNodeFTaskRef(VNType t, FileLine* fl, AstNode* namep, AstNodeExpr* pinsp) : AstNodeExpr{t, fl} { this->namep(namep); this->addPinsp(pinsp); } - AstNodeFTaskRef(VNType t, FileLine* fl, const string& name, AstNode* pinsp) + AstNodeFTaskRef(VNType t, FileLine* fl, const string& name, AstNodeExpr* pinsp) : AstNodeExpr{t, fl} , m_name{name} { this->addPinsp(pinsp); @@ -225,12 +235,12 @@ public: }; class AstNodePreSel VL_NOT_FINAL : public AstNodeExpr { // Something that becomes an AstSel - // @astgen op1 := fromp : AstNode - // @astgen op2 := rhsp : AstNode - // @astgen op3 := thsp : Optional[AstNode] + // @astgen op1 := fromp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr + // @astgen op3 := thsp : Optional[AstNodeExpr] // @astgen op4 := attrp : Optional[AstAttrOf] protected: - AstNodePreSel(VNType t, FileLine* fl, AstNode* fromp, AstNode* rhsp, AstNode* thsp) + AstNodePreSel(VNType t, FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : AstNodeExpr{t, fl} { this->fromp(fromp); this->rhsp(rhsp); @@ -248,13 +258,13 @@ public: }; class AstNodeQuadop VL_NOT_FINAL : public AstNodeExpr { // 4-ary expression - // @astgen op1 := lhsp : AstNode - // @astgen op2 := rhsp : AstNode - // @astgen op3 := thsp : AstNode - // @astgen op4 := fhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr + // @astgen op3 := thsp : AstNodeExpr + // @astgen op4 := fhsp : AstNodeExpr protected: - AstNodeQuadop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp, - AstNode* fhsp) + AstNodeQuadop(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp, + AstNodeExpr* fhsp) : AstNodeExpr{t, fl} { this->lhsp(lhsp); this->rhsp(rhsp); @@ -295,11 +305,11 @@ public: }; class AstNodeTriop VL_NOT_FINAL : public AstNodeExpr { // Ternary expression - // @astgen op1 := lhsp : AstNode - // @astgen op2 := rhsp : AstNode - // @astgen op3 := thsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr + // @astgen op3 := thsp : AstNodeExpr protected: - AstNodeTriop(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + AstNodeTriop(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : AstNodeExpr{t, fl} { this->lhsp(lhsp); this->rhsp(rhsp); @@ -328,7 +338,7 @@ class AstNodeCond VL_NOT_FINAL : public AstNodeTriop { // @astgen alias op2 := thenp // @astgen alias op3 := elsep protected: - AstNodeCond(VNType t, FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + AstNodeCond(VNType t, FileLine* fl, AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) : AstNodeTriop{t, fl, condp, thenp, elsep} { if (thenp) { dtypeFrom(thenp); @@ -351,13 +361,13 @@ 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* thenp, AstNode* elsep) = 0; + virtual AstNodeExpr* cloneType(AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) = 0; }; class AstNodeUniop VL_NOT_FINAL : public AstNodeExpr { // Unary expression - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr protected: - AstNodeUniop(VNType t, FileLine* fl, AstNode* lhsp) + AstNodeUniop(VNType t, FileLine* fl, AstNodeExpr* lhsp) : AstNodeExpr{t, fl} { dtypeFrom(lhsp); this->lhsp(lhsp); @@ -380,7 +390,7 @@ public: }; class AstNodeSystemUniop VL_NOT_FINAL : public AstNodeUniop { public: - AstNodeSystemUniop(VNType t, FileLine* fl, AstNode* lhsp) + AstNodeSystemUniop(VNType t, FileLine* fl, AstNodeExpr* lhsp) : AstNodeUniop(t, fl, lhsp) { dtypeSetDouble(); } @@ -465,13 +475,36 @@ public: bool cleanOut() const override { return true; } AstCFunc* funcp() const { return m_funcp; } }; +class AstArg final : public AstNodeExpr { + // An argument to a function/task, which is either an expression, or is a placeholder for an + // omitted argument. + // TODO: AstArg should not be AstNodeExpr, but is currently used as such widely. Fix later. + // @astgen op1 := exprp : Optional[AstNodeExpr] // nullptr if omitted + string m_name; // Pin name, or "" for number based interconnect +public: + AstArg(FileLine* fl, const string& name, AstNodeExpr* exprp) + : ASTGEN_SUPER_Arg(fl) + , m_name{name} { + this->exprp(exprp); + } + ASTGEN_MEMBERS_AstArg; + bool hasDType() const override { return false; } + string name() const override { return m_name; } // * = Pin name, ""=go by number + void name(const string& name) override { m_name = name; } + bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); } + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; class AstAttrOf final : public AstNodeExpr { // 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] + // @astgen op1 := fromp : Optional[AstNode] // Expr or DType + // @astgen op2 := dimp : Optional[AstNodeExpr] VAttrType m_attrType; // What sort of extraction public: - AstAttrOf(FileLine* fl, VAttrType attrtype, AstNode* fromp = nullptr, AstNode* dimp = nullptr) + AstAttrOf(FileLine* fl, VAttrType attrtype, AstNode* fromp = nullptr, + AstNodeExpr* dimp = nullptr) : ASTGEN_SUPER_AttrOf(fl) { this->fromp(fromp); this->dimp(dimp); @@ -512,13 +545,13 @@ public: class AstCMethodHard final : public AstNodeExpr { // A reference to a "C" hardcoded member task (or function) // PARENTS: stmt/expr - // @astgen op1 := fromp : AstNode // Subject of method call - // @astgen op2 := pinsp : List[AstNode] // Arguments + // @astgen op1 := fromp : AstNodeExpr // Subject of method call + // @astgen op2 := pinsp : List[AstNodeExpr] // Arguments string m_name; // Name of method bool m_pure = false; // Pure optimizable public: - AstCMethodHard(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, - AstNode* pinsp = nullptr) + AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, VFlagChildDType, const string& name, + AstNodeExpr* pinsp = nullptr) : ASTGEN_SUPER_CMethodHard(fl) , m_name{name} { // TODO: this constructor is exactly the same as the other, bar the ignored tag argument @@ -526,7 +559,8 @@ public: this->addPinsp(pinsp); dtypep(nullptr); // V3Width will resolve } - AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp = nullptr) + AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, const string& name, + AstNodeExpr* pinsp = nullptr) : ASTGEN_SUPER_CMethodHard(fl) , m_name{name} { this->fromp(fromp); @@ -548,16 +582,16 @@ public: }; class AstCast final : public AstNodeExpr { // Cast to appropriate data type - // @astgen op1 := fromp : AstNode + // @astgen op1 := fromp : AstNodeExpr // @astgen op2 := childDTypep : Optional[AstNodeDType] public: - AstCast(FileLine* fl, AstNode* fromp, VFlagChildDType, AstNodeDType* dtp) + AstCast(FileLine* fl, AstNodeExpr* fromp, VFlagChildDType, AstNodeDType* dtp) : ASTGEN_SUPER_Cast(fl) { this->fromp(fromp); this->childDTypep(dtp); dtypeFrom(dtp); } - AstCast(FileLine* fl, AstNode* fromp, AstNodeDType* dtp) + AstCast(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_Cast(fl) { this->fromp(fromp); dtypeFrom(dtp); @@ -571,10 +605,10 @@ public: }; class AstCastParse final : public AstNodeExpr { // Cast to appropriate type, where we haven't determined yet what the data type is - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr // @astgen op2 := dtp : AstNode public: - AstCastParse(FileLine* fl, AstNode* lhsp, AstNode* dtp) + AstCastParse(FileLine* fl, AstNodeExpr* lhsp, AstNode* dtp) : ASTGEN_SUPER_CastParse(fl) { this->lhsp(lhsp); this->dtp(dtp); @@ -584,6 +618,102 @@ public: string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(true); } }; +class AstCastSize final : public AstNodeExpr { + // Cast to specific size; signed/twostate inherited from lower element per IEEE + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstConst +public: + AstCastSize(FileLine* fl, AstNodeExpr* lhsp, AstConst* rhsp) + : ASTGEN_SUPER_CastSize(fl) { + this->lhsp(lhsp); + this->rhsp(rhsp); + } + ASTGEN_MEMBERS_AstCastSize; + // No hasDType because widthing removes this node before the hasDType check + string emitVerilog() override { return "((%r)'(%l))"; } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; +class AstCellArrayRef final : public AstNodeExpr { + // As-of-yet unlinkable reference into an array of cells + // @astgen op1 := selp : List[AstNodeExpr] // Select expression + string m_name; // Array name +public: + AstCellArrayRef(FileLine* fl, const string& name, AstNodeExpr* selp) + : ASTGEN_SUPER_CellArrayRef(fl) + , m_name{name} { + this->addSelp(selp); + } + ASTGEN_MEMBERS_AstCellArrayRef; + // ACCESSORS + string name() const override { return m_name; } // * = Array name + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; +class AstCellRef final : public AstNodeExpr { + // As-of-yet unlinkable reference into a cell + // @astgen op1 := cellp : AstNode + // @astgen op2 := exprp : AstNodeExpr +private: + string m_name; // Cell name +public: + AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNodeExpr* exprp) + : ASTGEN_SUPER_CellRef(fl) + , m_name{name} { + this->cellp(cellp); + this->exprp(exprp); + } + ASTGEN_MEMBERS_AstCellRef; + // ACCESSORS + string name() const override { return m_name; } // * = Array name + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; +class AstClassOrPackageRef final : public AstNodeExpr { + // @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, + AstPin* paramsp) + : ASTGEN_SUPER_ClassOrPackageRef(fl) + , m_name{name} + , m_classOrPackageNodep{classOrPackageNodep} { + this->addParamsp(paramsp); + } + ASTGEN_MEMBERS_AstClassOrPackageRef; + // METHODS + const char* broken() const override { + BROKEN_RTN(m_classOrPackageNodep && !m_classOrPackageNodep->brokeExists()); + return nullptr; + } + void cloneRelink() override { + if (m_classOrPackageNodep && m_classOrPackageNodep->clonep()) { + m_classOrPackageNodep = m_classOrPackageNodep->clonep(); + } + } + bool same(const AstNode* samep) const override { + return (m_classOrPackageNodep + == static_cast(samep)->m_classOrPackageNodep); + } + void dump(std::ostream& str = std::cout) const override; + string name() const override { return m_name; } // * = Var name + AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; } + void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; } + AstNodeModule* classOrPackagep() const; + AstPackage* packagep() const { return VN_CAST(classOrPackageNodep(), Package); } + void classOrPackagep(AstNodeModule* nodep) { m_classOrPackageNodep = (AstNode*)nodep; } + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; class AstConsAssoc final : public AstNodeExpr { // Construct an assoc array and return object, '{} // @astgen op1 := defaultp : Optional[AstNode] @@ -788,11 +918,11 @@ public: class AstDot final : public AstNodeExpr { // 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 + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) public: - AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp) + AstDot(FileLine* fl, bool colon, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Dot(fl) , m_colon{colon} { this->lhsp(lhsp); @@ -800,7 +930,7 @@ public: } ASTGEN_MEMBERS_AstDot; // For parser, make only if non-null package - static AstNodeExpr* newIfPkg(FileLine* fl, AstNode* packageOrClassp, AstNodeExpr* rhsp) { + static AstNodeExpr* newIfPkg(FileLine* fl, AstNodeExpr* packageOrClassp, AstNodeExpr* rhsp) { if (!packageOrClassp) return rhsp; return new AstDot{fl, true, packageOrClassp, rhsp}; } @@ -855,9 +985,9 @@ class AstExprStmt final : public AstNodeExpr { // the parent gets passed the 'resultp()'. // resultp is evaluated AFTER the statement(s). // @astgen op1 := stmtsp : List[AstNode] - // @astgen op2 := resultp : AstNode + // @astgen op2 := resultp : AstNodeExpr public: - AstExprStmt(FileLine* fl, AstNode* stmtsp, AstNode* resultp) + AstExprStmt(FileLine* fl, AstNode* stmtsp, AstNodeExpr* resultp) : ASTGEN_SUPER_ExprStmt(fl) { addStmtsp(stmtsp); this->resultp(resultp); @@ -1001,10 +1131,10 @@ public: }; class AstFell final : public AstNodeExpr { // Verilog $fell - // @astgen op1 := exprp : AstNode + // @astgen op1 := exprp : AstNodeExpr // @astgen op2 := sentreep : Optional[AstSenTree] public: - AstFell(FileLine* fl, AstNode* exprp) + AstFell(FileLine* fl, AstNodeExpr* exprp) : ASTGEN_SUPER_Fell(fl) { this->exprp(exprp); } @@ -1018,10 +1148,10 @@ public: }; class AstGatePin final : public AstNodeExpr { // Possibly expand a gate primitive input pin value to match the range of the gate primitive - // @astgen op1 := exprp : AstNode // Pin expression + // @astgen op1 := exprp : AstNodeExpr // Pin expression // @astgen op2 := rangep : AstRange // Range of pin public: - AstGatePin(FileLine* fl, AstNode* exprp, AstRange* rangep) + AstGatePin(FileLine* fl, AstNodeExpr* exprp, AstRange* rangep) : ASTGEN_SUPER_GatePin(fl) { this->exprp(exprp); this->rangep(rangep); @@ -1033,11 +1163,11 @@ public: }; class AstImplication final : public AstNodeExpr { // Verilog |-> |=> - // @astgen op1 := lhsp : AstNode - // @astgen op2 := rhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr // @astgen op3 := sentreep : Optional[AstSenTree] public: - AstImplication(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstImplication(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Implication(fl) { this->lhsp(lhsp); this->rhsp(rhsp); @@ -1050,11 +1180,51 @@ public: int instrCount() const override { return widthInstrs(); } bool same(const AstNode* /*samep*/) const override { return true; } }; -class AstInside final : public AstNodeExpr { - // @astgen op1 := exprp : AstNode - // @astgen op2 := itemsp : List[AstNode] +class AstInitArray final : public AstNodeExpr { + // This is also used as an array value in V3Simulate/const prop. + // Would be better called as 'AstConstArray' + // Set a var to a map of values + // The list of initsp() is not relevant + // 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() + // @astgen op1 := defaultp : Optional[AstNodeExpr] // Default, if sparse + // @astgen op2 := initsp : List[AstNode] // Initial value expressions + // public: - AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp) + using KeyItemMap = std::map; + +private: + KeyItemMap m_map; // Node value for each array index +public: + AstInitArray(FileLine* fl, AstNodeDType* newDTypep, AstNodeExpr* defaultp) + : ASTGEN_SUPER_InitArray(fl) { + dtypep(newDTypep); + this->defaultp(defaultp); + } + ASTGEN_MEMBERS_AstInitArray; + void dump(std::ostream& str) const override; + const char* broken() const override; + void cloneRelink() override; + bool same(const AstNode* samep) const override { + // Only works if exact same children, instead should override comparison + // of children list, and instead use map-vs-map key/value compare + return m_map == static_cast(samep)->m_map; + } + void addValuep(AstNodeExpr* newp) { addIndexValuep(m_map.size(), newp); } + const KeyItemMap& map() const { return m_map; } + void addIndexValuep(uint64_t index, AstNodeExpr* newp); + AstNodeExpr* getIndexValuep(uint64_t index) const; + AstNodeExpr* getIndexDefaultedValuep(uint64_t index) const; + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { return true; } +}; +class AstInside final : public AstNodeExpr { + // @astgen op1 := exprp : AstNodeExpr + // @astgen op2 := itemsp : List[AstNodeExpr] +public: + AstInside(FileLine* fl, AstNodeExpr* exprp, AstNodeExpr* itemsp) : ASTGEN_SUPER_Inside(fl) { this->exprp(exprp); this->addItemsp(itemsp); @@ -1066,10 +1236,10 @@ public: bool cleanOut() const override { return false; } // NA }; class AstInsideRange final : public AstNodeExpr { - // @astgen op1 := lhsp : AstNode - // @astgen op2 := rhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr + // @astgen op2 := rhsp : AstNodeExpr public: - AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstInsideRange(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_InsideRange(fl) { this->lhsp(lhsp); this->rhsp(rhsp); @@ -1079,7 +1249,7 @@ public: string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return false; } // NA // Create AstAnd(AstGte(...), AstLte(...)) - AstNode* newAndFromInside(AstNode* exprp, AstNode* lhsp, AstNode* rhsp); + AstNodeExpr* newAndFromInside(AstNodeExpr* exprp, AstNodeExpr* lhsp, AstNodeExpr* rhsp); }; class AstLambdaArgRef final : public AstNodeExpr { // Lambda argument usage @@ -1104,18 +1274,18 @@ public: bool index() const { return m_index; } }; class AstMemberSel final : public AstNodeExpr { - // @astgen op1 := fromp : AstNode + // @astgen op1 := fromp : AstNodeExpr // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it string m_name; AstVar* m_varp = nullptr; // Post link, variable within class that is target of selection public: - AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name) + AstMemberSel(FileLine* fl, AstNodeExpr* fromp, VFlagChildDType, const string& name) : ASTGEN_SUPER_MemberSel(fl) , m_name{name} { this->fromp(fromp); dtypep(nullptr); // V3Width will resolve } - AstMemberSel(FileLine* fl, AstNode* fromp, AstNodeDType* dtp) + AstMemberSel(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_MemberSel(fl) , m_name{dtp->name()} { this->fromp(fromp); @@ -1136,9 +1306,9 @@ public: }; class AstNewCopy final : public AstNodeExpr { // New as shallow copy - // @astgen op1 := rhsp : AstNode + // @astgen op1 := rhsp : AstNodeExpr public: - AstNewCopy(FileLine* fl, AstNode* rhsp) + AstNewCopy(FileLine* fl, AstNodeExpr* rhsp) : ASTGEN_SUPER_NewCopy(fl) { dtypeFrom(rhsp); // otherwise V3Width will resolve this->rhsp(rhsp); @@ -1152,10 +1322,10 @@ public: }; class AstNewDynamic final : public AstNodeExpr { // New for dynamic array - // @astgen op1 := sizep : AstNode - // @astgen op2 := rhsp : Optional[AstNode] + // @astgen op1 := sizep : AstNodeExpr + // @astgen op2 := rhsp : Optional[AstNodeExpr] public: - AstNewDynamic(FileLine* fl, AstNode* sizep, AstNode* rhsp) + AstNewDynamic(FileLine* fl, AstNodeExpr* sizep, AstNodeExpr* rhsp) : ASTGEN_SUPER_NewDynamic(fl) { dtypeFrom(rhsp); // otherwise V3Width will resolve this->sizep(sizep); @@ -1204,11 +1374,11 @@ public: }; class AstPast final : public AstNodeExpr { // Verilog $past - // @astgen op1 := exprp : AstNode + // @astgen op1 := exprp : AstNodeExpr // @astgen op2 := ticksp : Optional[AstNode] // @astgen op3 := sentreep : Optional[AstSenTree] public: - AstPast(FileLine* fl, AstNode* exprp, AstNode* ticksp) + AstPast(FileLine* fl, AstNodeExpr* exprp, AstNode* ticksp) : ASTGEN_SUPER_Past(fl) { this->exprp(exprp); this->ticksp(ticksp); @@ -1226,13 +1396,13 @@ class AstPatMember final : public AstNodeExpr { // Parents: AstPattern // Children: expression, AstPattern, replication count // Expression to assign or another AstPattern (list if replicated) - // @astgen op1 := lhssp : List[AstNode] + // @astgen op1 := lhssp : List[AstNodeExpr] // @astgen op2 := keyp : Optional[AstNode] - // @astgen op3 := repp : Optional[AstNode] // replication count, or nullptr for count 1 + // @astgen op3 := repp : Optional[AstNodeExpr] // replication count, or nullptr for count 1 bool m_default = false; public: - AstPatMember(FileLine* fl, AstNode* lhssp, AstNode* keyp, AstNode* repp) + AstPatMember(FileLine* fl, AstNodeExpr* lhssp, AstNode* keyp, AstNodeExpr* repp) : ASTGEN_SUPER_PatMember(fl) { this->addLhssp(lhssp); this->keyp(keyp); @@ -1312,10 +1482,10 @@ public: }; class AstRose final : public AstNodeExpr { // Verilog $rose - // @astgen op1 := exprp : AstNode + // @astgen op1 := exprp : AstNodeExpr // @astgen op2 := sentreep : Optional[AstSenTree] public: - AstRose(FileLine* fl, AstNode* exprp) + AstRose(FileLine* fl, AstNodeExpr* exprp) : ASTGEN_SUPER_Rose(fl) { this->exprp(exprp); } @@ -1330,7 +1500,7 @@ public: class AstSFormatF final : public AstNodeExpr { // 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 op1 := exprsp : List[AstNodeExpr] // @astgen op2 := scopeNamep : Optional[AstScopeName] string m_text; const bool m_hidden; // Under display, etc @@ -1339,7 +1509,7 @@ class AstSFormatF final : public AstNodeExpr { VTimescale m_timeunit; // Parent module time unit public: class NoFormat {}; - AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp, + AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNodeExpr* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_SFormatF(fl) , m_text{text} @@ -1349,7 +1519,7 @@ public: dtypeSetString(); addExprsp(exprsp); } - AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp, char missingArgChar = 'd', + AstSFormatF(FileLine* fl, NoFormat, AstNodeExpr* exprsp, char missingArgChar = 'd', bool hidden = true) : ASTGEN_SUPER_SFormatF(fl) , m_text{""} @@ -1412,7 +1582,7 @@ public: }; class AstSampled final : public AstNodeExpr { // Verilog $sampled - // @astgen op1 := exprp : AstNode + // @astgen op1 := exprp : AstNode // AstNodeExpr or AstPropSpec public: AstSampled(FileLine* fl, AstNode* exprp) : ASTGEN_SUPER_Sampled(fl) { @@ -1468,13 +1638,33 @@ public: void dpiExport(bool flag) { m_dpiExport = flag; } bool forFormat() const { return m_forFormat; } }; +class AstSelLoopVars final : public AstNodeExpr { + // Parser only concept "[id, id, id]" for a foreach statement + // Unlike normal selects elements is a list + // TODO: Should not be an AstNodeExpr, model foreach better + // @astgen op1 := fromp : AstNodeExpr + // @astgen op2 := elementsp : List[AstNode] +public: + AstSelLoopVars(FileLine* fl, AstNodeExpr* fromp, AstNode* elementsp) + : ASTGEN_SUPER_SelLoopVars(fl) { + this->fromp(fromp); + this->addElementsp(elementsp); + } + ASTGEN_MEMBERS_AstSelLoopVars; + bool same(const AstNode* /*samep*/) const override { return true; } + bool maybePointedTo() const override { return false; } + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; class AstSetAssoc final : public AstNodeExpr { // Set an assoc array element and return object, '{} // @astgen op1 := lhsp : AstNode // @astgen op2 := keyp : Optional[AstNode] - // @astgen op3 := valuep : AstNode + // @astgen op3 := valuep : AstNodeExpr public: - AstSetAssoc(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* valuep) + AstSetAssoc(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNodeExpr* valuep) : ASTGEN_SUPER_SetAssoc(fl) { this->lhsp(lhsp); this->keyp(keyp); @@ -1492,9 +1682,9 @@ class AstSetWildcard final : public AstNodeExpr { // Set a wildcard assoc array element and return object, '{} // @astgen op1 := lhsp : AstNode // @astgen op2 := keyp : Optional[AstNode] - // @astgen op3 := valuep : AstNode + // @astgen op3 := valuep : AstNodeExpr public: - AstSetWildcard(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* valuep) + AstSetWildcard(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNodeExpr* valuep) : ASTGEN_SUPER_SetWildcard(fl) { this->lhsp(lhsp); this->keyp(keyp); @@ -1510,10 +1700,10 @@ public: }; class AstStable final : public AstNodeExpr { // Verilog $stable - // @astgen op1 := exprp : AstNode + // @astgen op1 := exprp : AstNodeExpr // @astgen op2 := sentreep : Optional[AstSenTree] public: - AstStable(FileLine* fl, AstNode* exprp) + AstStable(FileLine* fl, AstNodeExpr* exprp) : ASTGEN_SUPER_Stable(fl) { this->exprp(exprp); } @@ -1651,8 +1841,7 @@ public: }; class AstUCFunc final : public AstNodeExpr { // 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 + // @astgen op1 := exprsp : List[AstNode] // Expressions to print (some are AstText) public: AstUCFunc(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_UCFunc(fl) { @@ -1722,15 +1911,45 @@ public: bool cleanOut() const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; } }; +class AstWith final : public AstNodeExpr { + // Used as argument to method, then to AstCMethodHard + // dtypep() contains the with lambda's return dtype + // Parents: funcref (similar to AstArg) + // Children: LambdaArgRef that declares the item variable + // Children: LambdaArgRef that declares the item.index variable + // Children: expression (equation establishing the with) + // @astgen op1 := indexArgRefp : AstLambdaArgRef + // @astgen op2 := valueArgRefp : AstLambdaArgRef + // @astgen op3 := exprp : AstNodeExpr +public: + AstWith(FileLine* fl, AstLambdaArgRef* indexArgRefp, AstLambdaArgRef* valueArgRefp, + AstNodeExpr* exprp) + : ASTGEN_SUPER_With(fl) { + this->indexArgRefp(indexArgRefp); + this->valueArgRefp(valueArgRefp); + this->exprp(exprp); + } + ASTGEN_MEMBERS_AstWith; + bool same(const AstNode* /*samep*/) const override { return true; } + const char* broken() const override { + BROKEN_RTN(!indexArgRefp()); // varp needed to know lambda's arg dtype + BROKEN_RTN(!valueArgRefp()); // varp needed to know lambda's arg dtype + return nullptr; + } + + string emitVerilog() override { V3ERROR_NA_RETURN(""); } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { V3ERROR_NA_RETURN(true); } +}; class AstWithParse final : public AstNodeExpr { // In early parse, FUNC(index) WITH equation-using-index // Replaced with AstWith // Parents: expr|stmt // Children: funcref, expr // @astgen op1 := funcrefp : AstNode - // @astgen op2 := exprp : Optional[AstNode] + // @astgen op2 := exprp : Optional[AstNodeExpr] public: - AstWithParse(FileLine* fl, AstNode* funcrefp, AstNode* exprp) + AstWithParse(FileLine* fl, AstNode* funcrefp, AstNodeExpr* exprp) : ASTGEN_SUPER_WithParse(fl) { this->funcrefp(funcrefp); this->exprp(exprp); @@ -1749,12 +1968,12 @@ class AstBufIf1 final : public AstNodeBiop { // Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp // bit enables respective rhsp bit public: - AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstBufIf1(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_BufIf1(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstBufIf1; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstBufIf1{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1775,14 +1994,16 @@ class AstCastDynamic final : public AstNodeBiop { // lhsp() is value (we are converting FROM) to match AstCCast etc, this // is opposite of $cast's order, because the first access is to the // value reading from. Suggest use fromp()/top() instead of lhsp/rhsp(). + // @astgen alias op1 := fromp + // @astgen alias op2 := top public: - AstCastDynamic(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstCastDynamic(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_CastDynamic(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstCastDynamic; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { V3ERROR_NA; } - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstCastDynamic{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f$cast(%r, %l)"; } @@ -1794,20 +2015,18 @@ public: bool sizeMattersRhs() const override { return false; } int instrCount() const override { return widthInstrs() * 20; } bool isPure() const override { return true; } - AstNode* fromp() const { return lhsp(); } - AstNode* top() const { return rhsp(); } }; class AstCompareNN final : public AstNodeBiop { // Verilog str.compare() and str.icompare() const bool m_ignoreCase; // True for str.icompare() public: - AstCompareNN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool ignoreCase) + AstCompareNN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, bool ignoreCase) : ASTGEN_SUPER_CompareNN(fl, lhsp, rhsp) , m_ignoreCase{ignoreCase} { dtypeSetUInt32(); } ASTGEN_MEMBERS_AstCompareNN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstCompareNN{fileline(), lhsp, rhsp, m_ignoreCase}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1830,7 +2049,7 @@ public: class AstConcat final : public AstNodeBiop { // If you're looking for {#{}}, see AstReplicate public: - AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstConcat(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Concat(fl, lhsp, rhsp) { if (lhsp->dtypep() && rhsp->dtypep()) { dtypeSetLogicSized(lhsp->dtypep()->width() + rhsp->dtypep()->width(), @@ -1838,7 +2057,7 @@ public: } } ASTGEN_MEMBERS_AstConcat; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstConcat{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f{%l, %k%r}"; } @@ -1856,12 +2075,12 @@ public: class AstConcatN final : public AstNodeBiop { // String concatenate public: - AstConcatN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstConcatN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_ConcatN(fl, lhsp, rhsp) { dtypeSetString(); } ASTGEN_MEMBERS_AstConcatN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstConcatN{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f{%l, %k%r}"; } @@ -1879,12 +2098,12 @@ public: }; class AstDiv final : public AstNodeBiop { public: - AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstDiv(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Div(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstDiv; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstDiv{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1901,12 +2120,12 @@ public: }; class AstDivD final : public AstNodeBiop { public: - AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstDivD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_DivD(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTGEN_MEMBERS_AstDivD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstDivD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1925,12 +2144,12 @@ public: }; class AstDivS final : public AstNodeBiop { public: - AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstDivS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_DivS(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstDivS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstDivS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1949,16 +2168,16 @@ public: class AstEqWild final : public AstNodeBiop { // Note wildcard operator rhs differs from lhs public: - AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstEqWild(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_EqWild(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstEqWild; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstEqWild{fileline(), lhsp, rhsp}; } - static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, - AstNode* rhsp); // Return AstEqWild/AstEqD + // Return AstEqWild/AstEqD + static AstNodeBiop* newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp); void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { out.opWildEq(lhs, rhs); } @@ -1973,10 +2192,10 @@ public: }; class AstFGetS final : public AstNodeBiop { public: - AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstFGetS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_FGetS(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstFGetS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstFGetS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -1998,13 +2217,13 @@ public: }; class AstFUngetC final : public AstNodeBiop { public: - AstFUngetC(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstFUngetC(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_FUngetC(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstFUngetC; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { V3ERROR_NA; } - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstFUngetC{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f$ungetc(%r, %l)"; } @@ -2025,12 +2244,12 @@ public: class AstGetcN final : public AstNodeBiop { // Verilog string.getc() public: - AstGetcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGetcN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GetcN(fl, lhsp, rhsp) { dtypeSetBitSized(8, VSigning::UNSIGNED); } ASTGEN_MEMBERS_AstGetcN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGetcN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2050,12 +2269,12 @@ class AstGetcRefN final : public AstNodeBiop { // Verilog string[#] on the left-hand-side of assignment // Spec says is of type byte (not string of single character) public: - AstGetcRefN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGetcRefN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GetcRefN(fl, lhsp, rhsp) { dtypeSetBitSized(8, VSigning::UNSIGNED); } ASTGEN_MEMBERS_AstGetcRefN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGetcRefN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2072,12 +2291,12 @@ public: }; class AstGt final : public AstNodeBiop { public: - AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGt(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Gt(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGt; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGt{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2094,12 +2313,12 @@ public: }; class AstGtD final : public AstNodeBiop { public: - AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGtD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GtD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGtD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGtD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2118,12 +2337,12 @@ public: }; class AstGtN final : public AstNodeBiop { public: - AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGtN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GtN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGtN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGtN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2142,12 +2361,12 @@ public: }; class AstGtS final : public AstNodeBiop { public: - AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGtS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GtS(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGtS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGtS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2165,12 +2384,12 @@ public: }; class AstGte final : public AstNodeBiop { public: - AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGte(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Gte(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGte; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGte{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2187,12 +2406,12 @@ public: }; class AstGteD final : public AstNodeBiop { public: - AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGteD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GteD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGteD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGteD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2211,12 +2430,12 @@ public: }; class AstGteN final : public AstNodeBiop { public: - AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGteN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GteN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGteN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGteN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2235,12 +2454,12 @@ public: }; class AstGteS final : public AstNodeBiop { public: - AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstGteS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_GteS(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstGteS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstGteS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2258,12 +2477,12 @@ public: }; class AstLogAnd final : public AstNodeBiop { public: - AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLogAnd(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LogAnd(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLogAnd; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLogAnd{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2281,12 +2500,12 @@ public: }; class AstLogIf final : public AstNodeBiop { public: - AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLogIf(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LogIf(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLogIf; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLogIf{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2309,12 +2528,12 @@ class AstLogOr final : public AstNodeBiop { // versus V3Const tracking it itself bool m_sideEffect = false; // Has side effect, relies on short-circuiting public: - AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLogOr(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LogOr(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLogOr; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLogOr{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2340,12 +2559,12 @@ public: }; class AstLt final : public AstNodeBiop { public: - AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLt(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Lt(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLt; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLt{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2362,12 +2581,12 @@ public: }; class AstLtD final : public AstNodeBiop { public: - AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLtD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LtD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLtD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLtD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2386,12 +2605,12 @@ public: }; class AstLtN final : public AstNodeBiop { public: - AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLtN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LtN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLtN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLtN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2410,12 +2629,12 @@ public: }; class AstLtS final : public AstNodeBiop { public: - AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLtS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LtS(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLtS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLtS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2433,12 +2652,12 @@ public: }; class AstLte final : public AstNodeBiop { public: - AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLte(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Lte(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLte; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLte{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2455,12 +2674,12 @@ public: }; class AstLteD final : public AstNodeBiop { public: - AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLteD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LteD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLteD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLteD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2479,12 +2698,12 @@ public: }; class AstLteN final : public AstNodeBiop { public: - AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLteN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LteN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLteN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLteN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2503,12 +2722,12 @@ public: }; class AstLteS final : public AstNodeBiop { public: - AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLteS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LteS(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLteS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLteS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2526,12 +2745,12 @@ public: }; class AstModDiv final : public AstNodeBiop { public: - AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstModDiv(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_ModDiv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstModDiv; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstModDiv{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2548,12 +2767,12 @@ public: }; class AstModDivS final : public AstNodeBiop { public: - AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstModDivS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_ModDivS(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstModDivS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstModDivS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2571,12 +2790,12 @@ public: }; class AstNeqWild final : public AstNodeBiop { public: - AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNeqWild(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_NeqWild(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstNeqWild; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstNeqWild{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2593,12 +2812,12 @@ public: }; class AstPow final : public AstNodeBiop { public: - AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstPow(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Pow(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstPow; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstPow{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2616,12 +2835,12 @@ public: }; class AstPowD final : public AstNodeBiop { public: - AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstPowD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_PowD(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTGEN_MEMBERS_AstPowD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstPowD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2639,12 +2858,12 @@ public: }; class AstPowSS final : public AstNodeBiop { public: - AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstPowSS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_PowSS(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstPowSS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstPowSS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2663,12 +2882,12 @@ public: }; class AstPowSU final : public AstNodeBiop { public: - AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstPowSU(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_PowSU(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstPowSU; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstPowSU{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2687,12 +2906,12 @@ public: }; class AstPowUS final : public AstNodeBiop { public: - AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstPowUS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_PowUS(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstPowUS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstPowUS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2715,7 +2934,7 @@ class AstReplicate final : public AstNodeBiop { // @astgen alias op1 := srcp // @astgen alias op2 := countp public: - AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstReplicate(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) { if (lhsp) { if (const AstConst* const constp = VN_CAST(rhsp, Const)) { @@ -2723,10 +2942,10 @@ public: } } } - AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount) + AstReplicate(FileLine* fl, AstNodeExpr* lhsp, uint32_t repCount) : AstReplicate{fl, lhsp, new AstConst{fl, repCount}} {} ASTGEN_MEMBERS_AstReplicate; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstReplicate{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2744,14 +2963,14 @@ public: class AstReplicateN final : public AstNodeBiop { // String replicate public: - AstReplicateN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstReplicateN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_ReplicateN(fl, lhsp, rhsp) { dtypeSetString(); } - AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount) + AstReplicateN(FileLine* fl, AstNodeExpr* lhsp, uint32_t repCount) : AstReplicateN{fl, lhsp, new AstConst{fl, repCount}} {} ASTGEN_MEMBERS_AstReplicateN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstReplicateN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2769,12 +2988,12 @@ public: }; class AstShiftL final : public AstNodeBiop { public: - AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0) + AstShiftL(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, int setwidth = 0) : ASTGEN_SUPER_ShiftL(fl, lhsp, rhsp) { if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED); } ASTGEN_MEMBERS_AstShiftL; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstShiftL{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2793,12 +3012,12 @@ public: }; class AstShiftR final : public AstNodeBiop { public: - AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0) + AstShiftR(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, int setwidth = 0) : ASTGEN_SUPER_ShiftR(fl, lhsp, rhsp) { if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED); } ASTGEN_MEMBERS_AstShiftR; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstShiftR{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2820,13 +3039,13 @@ class AstShiftRS final : public AstNodeBiop { // Shift right with sign extension, >>> operator // Output data type's width determines which bit is used for sign extension public: - AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0) + AstShiftRS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, int setwidth = 0) : ASTGEN_SUPER_ShiftRS(fl, lhsp, rhsp) { // Important that widthMin be correct, as opExtend requires it after V3Expand if (setwidth) dtypeSetLogicSized(setwidth, VSigning::SIGNED); } ASTGEN_MEMBERS_AstShiftRS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstShiftRS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2844,12 +3063,12 @@ public: }; class AstSub final : public AstNodeBiop { public: - AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstSub(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Sub(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstSub; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstSub{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2866,12 +3085,12 @@ public: }; class AstSubD final : public AstNodeBiop { public: - AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstSubD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_SubD(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTGEN_MEMBERS_AstSubD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstSubD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2891,12 +3110,12 @@ public: class AstURandomRange final : public AstNodeBiop { // $urandom_range public: - AstURandomRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstURandomRange(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_URandomRange(fl, lhsp, rhsp) { dtypeSetUInt32(); // Says IEEE } ASTGEN_MEMBERS_AstURandomRange; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstURandomRange{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2917,16 +3136,16 @@ public: // === AstNodeBiCom === class AstEq final : public AstNodeBiCom { public: - AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstEq(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Eq(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstEq; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstEq{fileline(), lhsp, rhsp}; } - static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, - AstNode* rhsp); // Return AstEq/AstEqD + // Return AstEq/AstEqD + static AstNodeBiop* newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp); void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { out.opEq(lhs, rhs); } @@ -2941,12 +3160,12 @@ public: }; class AstEqCase final : public AstNodeBiCom { public: - AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstEqCase(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_EqCase(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstEqCase; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstEqCase{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2963,12 +3182,12 @@ public: }; class AstEqD final : public AstNodeBiCom { public: - AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstEqD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_EqD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstEqD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstEqD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -2987,12 +3206,12 @@ public: }; class AstEqN final : public AstNodeBiCom { public: - AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstEqN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_EqN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstEqN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstEqN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3011,12 +3230,12 @@ public: }; class AstLogEq final : public AstNodeBiCom { public: - AstLogEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstLogEq(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_LogEq(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstLogEq; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstLogEq{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3034,12 +3253,12 @@ public: }; class AstNeq final : public AstNodeBiCom { public: - AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNeq(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Neq(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstNeq; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstNeq{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3056,12 +3275,12 @@ public: }; class AstNeqCase final : public AstNodeBiCom { public: - AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNeqCase(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_NeqCase(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstNeqCase; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstNeqCase{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3078,12 +3297,12 @@ public: }; class AstNeqD final : public AstNodeBiCom { public: - AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNeqD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_NeqD(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstNeqD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstNeqD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3102,12 +3321,12 @@ public: }; class AstNeqN final : public AstNodeBiCom { public: - AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstNeqN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_NeqN(fl, lhsp, rhsp) { dtypeSetBit(); } ASTGEN_MEMBERS_AstNeqN; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstNeqN{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3128,12 +3347,12 @@ public: // === AstNodeBiComAsv === class AstAdd final : public AstNodeBiComAsv { public: - AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAdd(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Add(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstAdd; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAdd{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3150,12 +3369,12 @@ public: }; class AstAddD final : public AstNodeBiComAsv { public: - AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAddD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_AddD(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTGEN_MEMBERS_AstAddD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAddD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3174,12 +3393,12 @@ public: }; class AstAnd final : public AstNodeBiComAsv { public: - AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAnd(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_And(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstAnd; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAnd{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3196,12 +3415,12 @@ public: }; class AstMul final : public AstNodeBiComAsv { public: - AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstMul(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Mul(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstMul; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstMul{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3219,12 +3438,12 @@ public: }; class AstMulD final : public AstNodeBiComAsv { public: - AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstMulD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_MulD(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTGEN_MEMBERS_AstMulD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstMulD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3243,12 +3462,12 @@ public: }; class AstMulS final : public AstNodeBiComAsv { public: - AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstMulS(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_MulS(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstMulS; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstMulS{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3268,12 +3487,12 @@ public: }; class AstOr final : public AstNodeBiComAsv { public: - AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstOr(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Or(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstOr; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstOr{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3290,12 +3509,12 @@ public: }; class AstXor final : public AstNodeBiComAsv { public: - AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstXor(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Xor(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstXor; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstXor{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3321,16 +3540,16 @@ class AstArraySel final : public AstNodeSel { } public: - AstArraySel(FileLine* fl, AstNode* fromp, AstNode* bitp) + AstArraySel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : ASTGEN_SUPER_ArraySel(fl, fromp, bitp) { init(fromp); } - AstArraySel(FileLine* fl, AstNode* fromp, int bit) + AstArraySel(FileLine* fl, AstNodeExpr* fromp, int bit) : ASTGEN_SUPER_ArraySel(fl, fromp, new AstConst(fl, bit)) { // Need () constructor init(fromp); } ASTGEN_MEMBERS_AstArraySel; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstArraySel{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3360,12 +3579,12 @@ class AstAssocSel final : public AstNodeSel { } public: - AstAssocSel(FileLine* fl, AstNode* fromp, AstNode* bitp) + AstAssocSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : ASTGEN_SUPER_AssocSel(fl, fromp, bitp) { init(fromp); } ASTGEN_MEMBERS_AstAssocSel; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAssocSel{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3392,12 +3611,12 @@ class AstWildcardSel final : public AstNodeSel { } public: - AstWildcardSel(FileLine* fl, AstNode* fromp, AstNode* bitp) + AstWildcardSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : ASTGEN_SUPER_WildcardSel(fl, fromp, bitp) { init(fromp); } ASTGEN_MEMBERS_AstWildcardSel; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstWildcardSel{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3418,12 +3637,12 @@ public: class AstWordSel final : public AstNodeSel { // Select a single word from a multi-word wide value public: - AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp) + AstWordSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : ASTGEN_SUPER_WordSel(fl, fromp, bitp) { dtypeSetUInt32(); // Always used on WData arrays so returns edata size } ASTGEN_MEMBERS_AstWordSel; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstWordSel{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) override { @@ -3445,10 +3664,10 @@ public: class AstStreamL final : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: - AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstStreamL(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_StreamL(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstStreamL; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeStream* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstStreamL{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f{ << %r %k{%l} }"; } @@ -3466,10 +3685,10 @@ public: class AstStreamR final : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: - AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstStreamR(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_StreamR(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstStreamR; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeStream* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstStreamR{fileline(), lhsp, rhsp}; } string emitVerilog() override { return "%f{ >> %r %k{%l} }"; } @@ -3488,10 +3707,10 @@ public: // === AstNodeSystemBiop === class AstAtan2D final : public AstNodeSystemBiop { public: - AstAtan2D(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAtan2D(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_Atan2D(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstAtan2D; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAtan2D{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3502,10 +3721,10 @@ public: }; class AstHypotD final : public AstNodeSystemBiop { public: - AstHypotD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstHypotD(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_HypotD(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstHypotD; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstHypotD{fileline(), lhsp, rhsp}; } void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { @@ -3521,7 +3740,7 @@ class AstCCall final : public AstNodeCCall { string m_selfPointer; // Output code object pointer (e.g.: 'this') public: - AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr) + AstCCall(FileLine* fl, AstCFunc* funcp, AstNodeExpr* argsp = nullptr) : ASTGEN_SUPER_CCall(fl, funcp, argsp) {} ASTGEN_MEMBERS_AstCCall; @@ -3531,9 +3750,9 @@ public: }; class AstCMethodCall final : public AstNodeCCall { // C++ method call - // @astgen op1 := fromp : AstNode + // @astgen op1 := fromp : AstNodeExpr public: - AstCMethodCall(FileLine* fl, AstNode* fromp, AstCFunc* funcp, AstNode* argsp = nullptr) + AstCMethodCall(FileLine* fl, AstNodeExpr* fromp, AstCFunc* funcp, AstNodeExpr* argsp = nullptr) : ASTGEN_SUPER_CMethodCall(fl, funcp, argsp) { this->fromp(fromp); } @@ -3547,7 +3766,7 @@ public: class AstCNew final : public AstNodeCCall { // C++ new() call public: - AstCNew(FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr) + AstCNew(FileLine* fl, AstCFunc* funcp, AstNodeExpr* argsp = nullptr) : ASTGEN_SUPER_CNew(fl, funcp, argsp) {} ASTGEN_MEMBERS_AstCNew; }; @@ -3556,25 +3775,25 @@ public: class AstFuncRef final : public AstNodeFTaskRef { // A reference to a function public: - AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) + AstFuncRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp) : ASTGEN_SUPER_FuncRef(fl, (AstNode*)namep, pinsp) {} - AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp) + AstFuncRef(FileLine* fl, const string& name, AstNodeExpr* pinsp) : ASTGEN_SUPER_FuncRef(fl, name, pinsp) {} ASTGEN_MEMBERS_AstFuncRef; }; class AstMethodCall final : public AstNodeFTaskRef { // A reference to a member task (or function) // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it - // @astgen op2 := fromp : AstNode + // @astgen op2 := fromp : AstNodeExpr // public: - AstMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, - AstNode* pinsp) + AstMethodCall(FileLine* fl, AstNodeExpr* fromp, VFlagChildDType, const string& name, + AstNodeExpr* pinsp) : ASTGEN_SUPER_MethodCall(fl, name, pinsp) { this->fromp(fromp); dtypep(nullptr); // V3Width will resolve } - AstMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) + AstMethodCall(FileLine* fl, AstNodeExpr* fromp, const string& name, AstNodeExpr* pinsp) : ASTGEN_SUPER_MethodCall(fl, name, pinsp) { this->fromp(fromp); } @@ -3590,7 +3809,7 @@ class AstNew final : public AstNodeFTaskRef { // New as constructor // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it public: - AstNew(FileLine* fl, AstNode* pinsp) + AstNew(FileLine* fl, AstNodeExpr* pinsp) : ASTGEN_SUPER_New(fl, "new", pinsp) {} ASTGEN_MEMBERS_AstNew; bool same(const AstNode* /*samep*/) const override { return true; } @@ -3599,11 +3818,11 @@ public: class AstTaskRef final : public AstNodeFTaskRef { // A reference to a task public: - AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) + AstTaskRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp) : ASTGEN_SUPER_TaskRef(fl, (AstNode*)namep, pinsp) { dtypeSetVoid(); } - AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp) + AstTaskRef(FileLine* fl, const string& name, AstNodeExpr* pinsp) : ASTGEN_SUPER_TaskRef(fl, name, pinsp) { dtypeSetVoid(); } @@ -3614,55 +3833,56 @@ public: class AstSelBit final : public AstNodePreSel { // Single bit range extraction, perhaps with non-constant selection or array selection // Gets replaced during link with AstArraySel or AstSel + // @astgen alias op2 := bitp public: - AstSelBit(FileLine* fl, AstNode* fromp, AstNode* bitp) + AstSelBit(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp) : ASTGEN_SUPER_SelBit(fl, fromp, bitp, nullptr) { UASSERT_OBJ(!v3Global.assertDTypesResolved(), this, "not coded to create after dtypes resolved"); } ASTGEN_MEMBERS_AstSelBit; - AstNode* bitp() const { return rhsp(); } }; class AstSelExtract final : public AstNodePreSel { // Range extraction, gets replaced with AstSel + // @astgen alias op2 := leftp + // @astgen alias op3 := rightp public: - AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp) + AstSelExtract(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* msbp, AstNodeExpr* lsbp) : ASTGEN_SUPER_SelExtract(fl, fromp, msbp, lsbp) {} ASTGEN_MEMBERS_AstSelExtract; - AstNode* leftp() const { return rhsp(); } - AstNode* rightp() const { return thsp(); } }; class AstSelMinus final : public AstNodePreSel { // -: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel + // @astgen alias op2 := bitp + // @astgen alias op3 := widtph public: - AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) + AstSelMinus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp) : ASTGEN_SUPER_SelMinus(fl, fromp, bitp, widthp) {} ASTGEN_MEMBERS_AstSelMinus; - AstNode* bitp() const { return rhsp(); } - AstNode* widthp() const { return thsp(); } }; class AstSelPlus final : public AstNodePreSel { // +: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel + // @astgen alias op2 := bitp + // @astgen alias op3 := widtph public: - AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) + AstSelPlus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp) : ASTGEN_SUPER_SelPlus(fl, fromp, bitp, widthp) {} ASTGEN_MEMBERS_AstSelPlus; - AstNode* bitp() const { return rhsp(); } - AstNode* widthp() const { return thsp(); } }; // === AstNodeQuadop === class AstCountBits final : public AstNodeQuadop { // Number of bits set in vector public: - AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p) + AstCountBits(FileLine* fl, AstNodeExpr* exprp, AstNodeExpr* ctrl1p) : ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl1p->cloneTree(false), ctrl1p->cloneTree(false)) {} - AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p) + AstCountBits(FileLine* fl, AstNodeExpr* exprp, AstNodeExpr* ctrl1p, AstNodeExpr* ctrl2p) : ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl2p, ctrl2p->cloneTree(false)) {} - AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p, AstNode* ctrl3p) + AstCountBits(FileLine* fl, AstNodeExpr* exprp, AstNodeExpr* ctrl1p, AstNodeExpr* ctrl2p, + AstNodeExpr* ctrl3p) : ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl2p, ctrl3p) {} ASTGEN_MEMBERS_AstCountBits; void numberOperate(V3Number& out, const V3Number& expr, const V3Number& ctrl1, @@ -3732,7 +3952,7 @@ class AstPostAdd final : public AstNodeTriop { // Children: rhsp: tree with AstVarRef that is value to read before operation // Children: thsp: tree with AstVarRef LValue that is stored after operation public: - AstPostAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + AstPostAdd(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : ASTGEN_SUPER_PostAdd(fl, lhsp, rhsp, thsp) {} ASTGEN_MEMBERS_AstPostAdd; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, @@ -3756,7 +3976,7 @@ class AstPostSub final : public AstNodeTriop { // Children: rhsp: tree with AstVarRef that is value to read before operation // Children: thsp: tree with AstVarRef LValue that is stored after operation public: - AstPostSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + AstPostSub(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : ASTGEN_SUPER_PostSub(fl, lhsp, rhsp, thsp) {} ASTGEN_MEMBERS_AstPostSub; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, @@ -3780,7 +4000,7 @@ class AstPreAdd final : public AstNodeTriop { // Children: rhsp: tree with AstVarRef that is value to read before operation // Children: thsp: tree with AstVarRef LValue that is stored after operation public: - AstPreAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + AstPreAdd(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : ASTGEN_SUPER_PreAdd(fl, lhsp, rhsp, thsp) {} ASTGEN_MEMBERS_AstPreAdd; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, @@ -3804,7 +4024,7 @@ class AstPreSub final : public AstNodeTriop { // Children: rhsp: tree with AstVarRef that is value to read before operation // Children: thsp: tree with AstVarRef LValue that is stored after operation public: - AstPreSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + AstPreSub(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* thsp) : ASTGEN_SUPER_PreSub(fl, lhsp, rhsp, thsp) {} ASTGEN_MEMBERS_AstPreSub; void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, @@ -3825,7 +4045,7 @@ public: class AstPutcN final : public AstNodeTriop { // Verilog string.putc() public: - AstPutcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) + AstPutcN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* ths) : ASTGEN_SUPER_PutcN(fl, lhsp, rhsp, ths) { dtypeSetString(); } @@ -3854,14 +4074,14 @@ class AstSel final : public AstNodeTriop { 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 public: - AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp) + AstSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* lsbp, AstNodeExpr* widthp) : ASTGEN_SUPER_Sel(fl, fromp, lsbp, widthp) , m_declElWidth{1} { if (VN_IS(widthp, Const)) { dtypeSetLogicSized(VN_AS(widthp, Const)->toUInt(), VSigning::UNSIGNED); } } - AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth) + AstSel(FileLine* fl, AstNodeExpr* fromp, int lsb, int bitwidth) : ASTGEN_SUPER_Sel(fl, fromp, new AstConst(fl, lsb), // Need () constructor new AstConst(fl, bitwidth)) // Need () constructor , m_declElWidth{1} { @@ -3902,7 +4122,7 @@ class AstSliceSel final : public AstNodeTriop { // @astgen alias op1 := fromp VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid public: - AstSliceSel(FileLine* fl, AstNode* fromp, const VNumRange& declRange) + AstSliceSel(FileLine* fl, AstNodeExpr* fromp, const VNumRange& declRange) : ASTGEN_SUPER_SliceSel(fl, fromp, new AstConst(fl, declRange.lo()), // Need () constructor new AstConst(fl, declRange.elements())) // Need () constructor @@ -3932,7 +4152,7 @@ public: class AstSubstrN final : public AstNodeTriop { // Verilog string.substr() public: - AstSubstrN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) + AstSubstrN(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNodeExpr* ths) : ASTGEN_SUPER_SubstrN(fl, lhsp, rhsp, ths) { dtypeSetString(); } @@ -3958,20 +4178,20 @@ public: class AstCond final : public AstNodeCond { // Conditional ?: expressoin public: - AstCond(FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + AstCond(FileLine* fl, AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) : ASTGEN_SUPER_Cond(fl, condp, thenp, elsep) {} ASTGEN_MEMBERS_AstCond; - AstNode* cloneType(AstNode* condp, AstNode* thenp, AstNode* elsep) override { + AstNodeExpr* cloneType(AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) override { return new AstCond{fileline(), condp, thenp, elsep}; } }; class AstCondBound final : public AstNodeCond { // Conditional ?: expression, specially made for safety checking of array bounds public: - AstCondBound(FileLine* fl, AstNode* condp, AstNode* thenp, AstNode* elsep) + AstCondBound(FileLine* fl, AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) : ASTGEN_SUPER_CondBound(fl, condp, thenp, elsep) {} ASTGEN_MEMBERS_AstCondBound; - AstNode* cloneType(AstNode* condp, AstNode* thenp, AstNode* elsep) override { + AstNodeExpr* cloneType(AstNodeExpr* condp, AstNodeExpr* thenp, AstNodeExpr* elsep) override { return new AstCondBound{fileline(), condp, thenp, elsep}; } }; @@ -3985,7 +4205,7 @@ public: private: const FmtType m_fmt; // Operation type public: - AstAtoN(FileLine* fl, AstNode* lhsp, FmtType fmt) + AstAtoN(FileLine* fl, AstNodeExpr* lhsp, FmtType fmt) : ASTGEN_SUPER_AtoN(fl, lhsp) , m_fmt{fmt} { fmt == ATOREAL ? dtypeSetDouble() : dtypeSetSigned32(); @@ -4020,7 +4240,7 @@ public: }; class AstBitsToRealD final : public AstNodeUniop { public: - AstBitsToRealD(FileLine* fl, AstNode* lhsp) + AstBitsToRealD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_BitsToRealD(fl, lhsp) { dtypeSetDouble(); } @@ -4038,7 +4258,7 @@ class AstCAwait final : public AstNodeUniop { // @astgen alias op1 := exprp AstSenTree* m_sensesp; // Sentree related to this await public: - AstCAwait(FileLine* fl, AstNode* exprp, AstSenTree* sensesp = nullptr) + AstCAwait(FileLine* fl, AstNodeExpr* exprp, AstSenTree* sensesp = nullptr) : ASTGEN_SUPER_CAwait(fl, exprp) , m_sensesp{sensesp} {} ASTGEN_MEMBERS_AstCAwait; @@ -4060,7 +4280,7 @@ class AstCCast final : public AstNodeUniop { int m_size; public: - AstCCast(FileLine* fl, AstNode* lhsp, int setwidth, int minwidth = -1) + AstCCast(FileLine* fl, AstNodeExpr* lhsp, int setwidth, int minwidth = -1) : ASTGEN_SUPER_CCast(fl, lhsp) { m_size = setwidth; if (setwidth) { @@ -4068,7 +4288,7 @@ public: dtypeSetLogicUnsized(setwidth, minwidth, VSigning::UNSIGNED); } } - AstCCast(FileLine* fl, AstNode* lhsp, AstNode* typeFromp) + AstCCast(FileLine* fl, AstNodeExpr* lhsp, AstNode* typeFromp) : ASTGEN_SUPER_CCast(fl, lhsp) { dtypeFrom(typeFromp); m_size = width(); @@ -4089,7 +4309,7 @@ public: }; class AstCLog2 final : public AstNodeUniop { public: - AstCLog2(FileLine* fl, AstNode* lhsp) + AstCLog2(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CLog2(fl, lhsp) { dtypeSetSigned32(); } @@ -4105,7 +4325,7 @@ public: class AstCountOnes final : public AstNodeUniop { // Number of bits set in vector public: - AstCountOnes(FileLine* fl, AstNode* lhsp) + AstCountOnes(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CountOnes(fl, lhsp) {} ASTGEN_MEMBERS_AstCountOnes; void numberOperate(V3Number& out, const V3Number& lhs) override { out.opCountOnes(lhs); } @@ -4119,7 +4339,7 @@ public: class AstCvtPackString final : public AstNodeUniop { // Convert to Verilator Packed String (aka verilog "string") public: - AstCvtPackString(FileLine* fl, AstNode* lhsp) + AstCvtPackString(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CvtPackString(fl, lhsp) { dtypeSetString(); } @@ -4135,9 +4355,9 @@ public: class AstExtend final : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() public: - AstExtend(FileLine* fl, AstNode* lhsp) + AstExtend(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Extend(fl, lhsp) {} - AstExtend(FileLine* fl, AstNode* lhsp, int width) + AstExtend(FileLine* fl, AstNodeExpr* lhsp, int width) : ASTGEN_SUPER_Extend(fl, lhsp) { dtypeSetLogicSized(width, VSigning::UNSIGNED); } @@ -4155,9 +4375,9 @@ public: class AstExtendS final : public AstNodeUniop { // Expand a value into a wider entity by sign extension. Width is implied from nodep->width() public: - AstExtendS(FileLine* fl, AstNode* lhsp) + AstExtendS(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_ExtendS(fl, lhsp) {} - AstExtendS(FileLine* fl, AstNode* lhsp, int width) + AstExtendS(FileLine* fl, AstNodeExpr* lhsp, int width) // Important that widthMin be correct, as opExtend requires it after V3Expand : ASTGEN_SUPER_ExtendS(fl, lhsp) { dtypeSetLogicSized(width, VSigning::UNSIGNED); @@ -4178,7 +4398,7 @@ public: }; class AstFEof final : public AstNodeUniop { public: - AstFEof(FileLine* fl, AstNode* lhsp) + AstFEof(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_FEof(fl, lhsp) {} ASTGEN_MEMBERS_AstFEof; void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; } @@ -4193,7 +4413,7 @@ public: }; class AstFGetC final : public AstNodeUniop { public: - AstFGetC(FileLine* fl, AstNode* lhsp) + AstFGetC(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_FGetC(fl, lhsp) {} ASTGEN_MEMBERS_AstFGetC; void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; } @@ -4210,7 +4430,7 @@ public: class AstISToRD final : public AstNodeUniop { // $itor where lhs is signed public: - AstISToRD(FileLine* fl, AstNode* lhsp) + AstISToRD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_ISToRD(fl, lhsp) { dtypeSetDouble(); } @@ -4227,7 +4447,7 @@ public: class AstIToRD final : public AstNodeUniop { // $itor where lhs is unsigned public: - AstIToRD(FileLine* fl, AstNode* lhsp) + AstIToRD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_IToRD(fl, lhsp) { dtypeSetDouble(); } @@ -4243,7 +4463,7 @@ public: class AstIsUnbounded final : public AstNodeUniop { // True if is unmbounded ($) public: - AstIsUnbounded(FileLine* fl, AstNode* lhsp) + AstIsUnbounded(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_IsUnbounded(fl, lhsp) { dtypeSetBit(); } @@ -4261,7 +4481,7 @@ public: class AstIsUnknown final : public AstNodeUniop { // True if any unknown bits public: - AstIsUnknown(FileLine* fl, AstNode* lhsp) + AstIsUnknown(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_IsUnknown(fl, lhsp) { dtypeSetBit(); } @@ -4276,7 +4496,7 @@ public: class AstLenN final : public AstNodeUniop { // Length of a string public: - AstLenN(FileLine* fl, AstNode* lhsp) + AstLenN(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_LenN(fl, lhsp) { dtypeSetSigned32(); } @@ -4290,7 +4510,7 @@ public: }; class AstLogNot final : public AstNodeUniop { public: - AstLogNot(FileLine* fl, AstNode* lhsp) + AstLogNot(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_LogNot(fl, lhsp) { dtypeSetBit(); } @@ -4305,7 +4525,7 @@ public: }; class AstNegate final : public AstNodeUniop { public: - AstNegate(FileLine* fl, AstNode* lhsp) + AstNegate(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Negate(fl, lhsp) { dtypeFrom(lhsp); } @@ -4320,7 +4540,7 @@ public: }; class AstNegateD final : public AstNodeUniop { public: - AstNegateD(FileLine* fl, AstNode* lhsp) + AstNegateD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_NegateD(fl, lhsp) { dtypeSetDouble(); } @@ -4337,7 +4557,7 @@ public: }; class AstNot final : public AstNodeUniop { public: - AstNot(FileLine* fl, AstNode* lhsp) + AstNot(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Not(fl, lhsp) { dtypeFrom(lhsp); } @@ -4353,7 +4573,7 @@ public: class AstNullCheck final : public AstNodeUniop { // Return LHS after checking that LHS is non-null public: - AstNullCheck(FileLine* fl, AstNode* lhsp) + AstNullCheck(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_NullCheck(fl, lhsp) { dtypeFrom(lhsp); } @@ -4371,7 +4591,7 @@ public: class AstOneHot final : public AstNodeUniop { // True if only single bit set in vector public: - AstOneHot(FileLine* fl, AstNode* lhsp) + AstOneHot(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_OneHot(fl, lhsp) { dtypeSetBit(); } @@ -4387,7 +4607,7 @@ public: class AstOneHot0 final : public AstNodeUniop { // True if only single bit, or no bits set in vector public: - AstOneHot0(FileLine* fl, AstNode* lhsp) + AstOneHot0(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_OneHot0(fl, lhsp) { dtypeSetBit(); } @@ -4403,7 +4623,7 @@ public: class AstRToIRoundS final : public AstNodeUniop { // Convert real to integer, with arbitrary sized output (not just "integer" format) public: - AstRToIRoundS(FileLine* fl, AstNode* lhsp) + AstRToIRoundS(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RToIRoundS(fl, lhsp) { dtypeSetSigned32(); } @@ -4421,7 +4641,7 @@ public: class AstRToIS final : public AstNodeUniop { // $rtoi(lhs) public: - AstRToIS(FileLine* fl, AstNode* lhsp) + AstRToIS(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RToIS(fl, lhsp) { dtypeSetSigned32(); } @@ -4436,7 +4656,7 @@ public: }; class AstRealToBits final : public AstNodeUniop { public: - AstRealToBits(FileLine* fl, AstNode* lhsp) + AstRealToBits(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RealToBits(fl, lhsp) { dtypeSetUInt64(); } @@ -4451,7 +4671,7 @@ public: }; class AstRedAnd final : public AstNodeUniop { public: - AstRedAnd(FileLine* fl, AstNode* lhsp) + AstRedAnd(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RedAnd(fl, lhsp) { dtypeSetBit(); } @@ -4465,7 +4685,7 @@ public: }; class AstRedOr final : public AstNodeUniop { public: - AstRedOr(FileLine* fl, AstNode* lhsp) + AstRedOr(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RedOr(fl, lhsp) { dtypeSetBit(); } @@ -4479,7 +4699,7 @@ public: }; class AstRedXor final : public AstNodeUniop { public: - AstRedXor(FileLine* fl, AstNode* lhsp) + AstRedXor(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_RedXor(fl, lhsp) { dtypeSetBit(); } @@ -4498,7 +4718,7 @@ public: class AstSigned final : public AstNodeUniop { // $signed(lhs) public: - AstSigned(FileLine* fl, AstNode* lhsp) + AstSigned(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Signed(fl, lhsp) { UASSERT_OBJ(!v3Global.assertDTypesResolved(), this, "not coded to create after dtypes resolved"); @@ -4519,7 +4739,7 @@ class AstTimeImport final : public AstNodeUniop { // Take a constant that represents a time and needs conversion based on time units VTimescale m_timeunit; // Parent module time unit public: - AstTimeImport(FileLine* fl, AstNode* lhsp) + AstTimeImport(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_TimeImport(fl, lhsp) {} ASTGEN_MEMBERS_AstTimeImport; void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; } @@ -4535,7 +4755,7 @@ public: class AstToLowerN final : public AstNodeUniop { // string.tolower() public: - AstToLowerN(FileLine* fl, AstNode* lhsp) + AstToLowerN(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_ToLowerN(fl, lhsp) { dtypeSetString(); } @@ -4550,7 +4770,7 @@ public: class AstToUpperN final : public AstNodeUniop { // string.toupper() public: - AstToUpperN(FileLine* fl, AstNode* lhsp) + AstToUpperN(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_ToUpperN(fl, lhsp) { dtypeSetString(); } @@ -4565,7 +4785,7 @@ public: class AstUnsigned final : public AstNodeUniop { // $unsigned(lhs) public: - AstUnsigned(FileLine* fl, AstNode* lhsp) + AstUnsigned(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Unsigned(fl, lhsp) { UASSERT_OBJ(!v3Global.assertDTypesResolved(), this, "not coded to create after dtypes resolved"); @@ -4586,7 +4806,7 @@ public: // === AstNodeSystemUniop === class AstAcosD final : public AstNodeSystemUniop { public: - AstAcosD(FileLine* fl, AstNode* lhsp) + AstAcosD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AcosD(fl, lhsp) {} ASTGEN_MEMBERS_AstAcosD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4597,7 +4817,7 @@ public: }; class AstAcoshD final : public AstNodeSystemUniop { public: - AstAcoshD(FileLine* fl, AstNode* lhsp) + AstAcoshD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AcoshD(fl, lhsp) {} ASTGEN_MEMBERS_AstAcoshD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4608,7 +4828,7 @@ public: }; class AstAsinD final : public AstNodeSystemUniop { public: - AstAsinD(FileLine* fl, AstNode* lhsp) + AstAsinD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AsinD(fl, lhsp) {} ASTGEN_MEMBERS_AstAsinD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4619,7 +4839,7 @@ public: }; class AstAsinhD final : public AstNodeSystemUniop { public: - AstAsinhD(FileLine* fl, AstNode* lhsp) + AstAsinhD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AsinhD(fl, lhsp) {} ASTGEN_MEMBERS_AstAsinhD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4630,7 +4850,7 @@ public: }; class AstAtanD final : public AstNodeSystemUniop { public: - AstAtanD(FileLine* fl, AstNode* lhsp) + AstAtanD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AtanD(fl, lhsp) {} ASTGEN_MEMBERS_AstAtanD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4641,7 +4861,7 @@ public: }; class AstAtanhD final : public AstNodeSystemUniop { public: - AstAtanhD(FileLine* fl, AstNode* lhsp) + AstAtanhD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_AtanhD(fl, lhsp) {} ASTGEN_MEMBERS_AstAtanhD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4652,7 +4872,7 @@ public: }; class AstCeilD final : public AstNodeSystemUniop { public: - AstCeilD(FileLine* fl, AstNode* lhsp) + AstCeilD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CeilD(fl, lhsp) {} ASTGEN_MEMBERS_AstCeilD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4663,7 +4883,7 @@ public: }; class AstCosD final : public AstNodeSystemUniop { public: - AstCosD(FileLine* fl, AstNode* lhsp) + AstCosD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CosD(fl, lhsp) {} ASTGEN_MEMBERS_AstCosD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4674,7 +4894,7 @@ public: }; class AstCoshD final : public AstNodeSystemUniop { public: - AstCoshD(FileLine* fl, AstNode* lhsp) + AstCoshD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CoshD(fl, lhsp) {} ASTGEN_MEMBERS_AstCoshD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4685,7 +4905,7 @@ public: }; class AstExpD final : public AstNodeSystemUniop { public: - AstExpD(FileLine* fl, AstNode* lhsp) + AstExpD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_ExpD(fl, lhsp) {} ASTGEN_MEMBERS_AstExpD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4696,7 +4916,7 @@ public: }; class AstFloorD final : public AstNodeSystemUniop { public: - AstFloorD(FileLine* fl, AstNode* lhsp) + AstFloorD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_FloorD(fl, lhsp) {} ASTGEN_MEMBERS_AstFloorD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4707,7 +4927,7 @@ public: }; class AstLog10D final : public AstNodeSystemUniop { public: - AstLog10D(FileLine* fl, AstNode* lhsp) + AstLog10D(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Log10D(fl, lhsp) {} ASTGEN_MEMBERS_AstLog10D; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4718,7 +4938,7 @@ public: }; class AstLogD final : public AstNodeSystemUniop { public: - AstLogD(FileLine* fl, AstNode* lhsp) + AstLogD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_LogD(fl, lhsp) {} ASTGEN_MEMBERS_AstLogD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4729,7 +4949,7 @@ public: }; class AstSinD final : public AstNodeSystemUniop { public: - AstSinD(FileLine* fl, AstNode* lhsp) + AstSinD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_SinD(fl, lhsp) {} ASTGEN_MEMBERS_AstSinD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4740,7 +4960,7 @@ public: }; class AstSinhD final : public AstNodeSystemUniop { public: - AstSinhD(FileLine* fl, AstNode* lhsp) + AstSinhD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_SinhD(fl, lhsp) {} ASTGEN_MEMBERS_AstSinhD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4751,7 +4971,7 @@ public: }; class AstSqrtD final : public AstNodeSystemUniop { public: - AstSqrtD(FileLine* fl, AstNode* lhsp) + AstSqrtD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_SqrtD(fl, lhsp) {} ASTGEN_MEMBERS_AstSqrtD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4762,7 +4982,7 @@ public: }; class AstTanD final : public AstNodeSystemUniop { public: - AstTanD(FileLine* fl, AstNode* lhsp) + AstTanD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_TanD(fl, lhsp) {} ASTGEN_MEMBERS_AstTanD; void numberOperate(V3Number& out, const V3Number& lhs) override { @@ -4773,7 +4993,7 @@ public: }; class AstTanhD final : public AstNodeSystemUniop { public: - AstTanhD(FileLine* fl, AstNode* lhsp) + AstTanhD(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_TanhD(fl, lhsp) {} ASTGEN_MEMBERS_AstTanhD; void numberOperate(V3Number& out, const V3Number& lhs) override { diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index deb657f65..b5e164c4b 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -310,11 +310,11 @@ public: }; 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 op1 := rhsp : AstNodeExpr + // @astgen op2 := lhsp : AstNodeExpr // @astgen op3 := timingControlp : Optional[AstNode] protected: - AstNodeAssign(VNType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp, + AstNodeAssign(VNType t, FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, AstNode* timingControlp = nullptr) : AstNodeStmt{t, fl} { this->rhsp(rhsp); @@ -326,7 +326,7 @@ protected: public: ASTGEN_MEMBERS_AstNodeAssign; // Clone single node, just get same type back. - virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) = 0; + virtual AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) = 0; bool hasDType() const override { return true; } virtual bool cleanRhs() const { return true; } int instrCount() const override { return widthInstrs(); } @@ -336,11 +336,11 @@ public: virtual bool brokeLhsMustBeLvalue() const = 0; }; class AstNodeCase VL_NOT_FINAL : public AstNodeStmt { - // @astgen op1 := exprp : AstNode // Condition (scurtinee) expression + // @astgen op1 := exprp : AstNodeExpr // 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, AstCaseItem* itemsp) + AstNodeCase(VNType t, FileLine* fl, AstNodeExpr* exprp, AstCaseItem* itemsp) : AstNodeStmt{t, fl} { this->exprp(exprp); this->addItemsp(itemsp); @@ -377,11 +377,11 @@ public: }; class AstNodeFor VL_NOT_FINAL : public AstNodeStmt { // @astgen op1 := initsp : List[AstNode] - // @astgen op2 := condp : AstNode + // @astgen op2 := condp : AstNodeExpr // @astgen op3 := incsp : List[AstNode] // @astgen op4 := stmtsp : List[AstNode] protected: - AstNodeFor(VNType t, FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, + AstNodeFor(VNType t, FileLine* fl, AstNode* initsp, AstNodeExpr* condp, AstNode* incsp, AstNode* stmtsp) : AstNodeStmt{t, fl} { this->addInitsp(initsp); @@ -397,14 +397,14 @@ public: bool same(const AstNode* /*samep*/) const override { return true; } }; class AstNodeIf VL_NOT_FINAL : public AstNodeStmt { - // @astgen op1 := condp : AstNode + // @astgen op1 := condp : AstNodeExpr // @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 is for assertion/bounds checking protected: - AstNodeIf(VNType t, FileLine* fl, AstNode* condp, AstNode* thensp, AstNode* elsesp) + AstNodeIf(VNType t, FileLine* fl, AstNodeExpr* condp, AstNode* thensp, AstNode* elsesp) : AstNodeStmt{t, fl} { this->condp(condp); this->addThensp(thensp); @@ -427,15 +427,15 @@ public: } }; class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt { - // @astgen op1 := filenamep : AstNode - // @astgen op2 := memp : AstNode - // @astgen op3 := lsbp : Optional[AstNode] - // @astgen op4 := msbp : Optional[AstNode] + // @astgen op1 := filenamep : AstNodeExpr + // @astgen op2 := memp : AstNodeExpr + // @astgen op3 := lsbp : Optional[AstNodeExpr] + // @astgen op4 := msbp : Optional[AstNodeExpr] const bool m_isHex; // readmemh, not readmemb public: - AstNodeReadWriteMem(VNType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, - AstNode* lsbp, AstNode* msbp) + AstNodeReadWriteMem(VNType t, FileLine* fl, bool hex, AstNodeExpr* filenamep, + AstNodeExpr* memp, AstNodeExpr* lsbp, AstNodeExpr* msbp) : AstNodeStmt(t, fl) , m_isHex(hex) { this->filenamep(filenamep); @@ -518,21 +518,6 @@ public: inline bool hasClocked() const; inline bool hasCombo() const; }; -class AstArg final : public AstNode { - // An argument to a function/task - // @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} { - this->exprp(exprp); - } - ASTGEN_MEMBERS_AstArg; - string name() const override { return m_name; } // * = Pin name, ""=go by number - void name(const string& name) override { m_name = name; } - bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); } -}; class AstBind final : public AstNode { // Parents: MODULE // Children: CELL @@ -718,10 +703,10 @@ public: }; class AstCaseItem final : public AstNode { // Single item of a case statement - // @astgen op1 := condsp : List[AstNode] + // @astgen op1 := condsp : List[AstNodeExpr] // @astgen op2 := stmtsp : List[AstNode] public: - AstCaseItem(FileLine* fl, AstNode* condsp, AstNode* stmtsp) + AstCaseItem(FileLine* fl, AstNodeExpr* condsp, AstNode* stmtsp) : ASTGEN_SUPER_CaseItem(fl) { this->addCondsp(condsp); this->addStmtsp(stmtsp); @@ -731,23 +716,6 @@ public: bool isDefault() const { return condsp() == nullptr; } bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; -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) { - this->lhsp(lhsp); - this->rhsp(rhsp); - } - ASTGEN_MEMBERS_AstCastSize; - // No hasDType because widthing removes this node before the hasDType check - virtual string emitVerilog() { return "((%r)'(%l))"; } - virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); } - virtual bool cleanLhs() const { return true; } - virtual bool sizeMattersLhs() const { return false; } -}; class AstCell final : public AstNode { // A instantiation cell or interface call (don't know which until link) // @astgen op1 := pinsp : List[AstPin] // List of port assignments @@ -799,20 +767,6 @@ public: void recursive(bool flag) { m_recursive = flag; } bool recursive() const { return m_recursive; } }; -class AstCellArrayRef final : public AstNode { - // As-of-yet unlinkable reference into an array of cells - // @astgen op1 := selp : List[AstNode] // Select expression - string m_name; // Array name -public: - AstCellArrayRef(FileLine* fl, const string& name, AstNode* selp) - : ASTGEN_SUPER_CellArrayRef(fl) - , m_name{name} { - this->addSelp(selp); - } - ASTGEN_MEMBERS_AstCellArrayRef; - // ACCESSORS - string name() const override { return m_name; } // * = Array name -}; class AstCellInline final : public AstNode { // A instantiation cell that was removed by inlining // For communication between V3Inline and V3LinkDot, @@ -844,23 +798,6 @@ public: void timeunit(const VTimescale& flag) { m_timeunit = flag; } VTimescale timeunit() const { return m_timeunit; } }; -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} { - this->cellp(cellp); - this->exprp(exprp); - } - ASTGEN_MEMBERS_AstCellRef; - // ACCESSORS - string name() const override { return m_name; } // * = Array name -}; class AstClassExtends final : public AstNode { // Children: List of AstParseRef for packages/classes // during early parse, then moves to dtype @@ -876,43 +813,6 @@ public: string verilogKwd() const override { return "extends"; } 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, - AstPin* paramsp) - : ASTGEN_SUPER_ClassOrPackageRef(fl) - , m_name{name} - , m_classOrPackageNodep{classOrPackageNodep} { - this->addParamsp(paramsp); - } - ASTGEN_MEMBERS_AstClassOrPackageRef; - // METHODS - const char* broken() const override { - BROKEN_RTN(m_classOrPackageNodep && !m_classOrPackageNodep->brokeExists()); - return nullptr; - } - void cloneRelink() override { - if (m_classOrPackageNodep && m_classOrPackageNodep->clonep()) { - m_classOrPackageNodep = m_classOrPackageNodep->clonep(); - } - } - bool same(const AstNode* samep) const override { - return (m_classOrPackageNodep - == static_cast(samep)->m_classOrPackageNodep); - } - void dump(std::ostream& str = std::cout) const override; - string name() const override { return m_name; } // * = Var name - AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; } - void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; } - AstNodeModule* classOrPackagep() const; - AstPackage* packagep() const { return VN_CAST(classOrPackageNodep(), Package); } - void classOrPackagep(AstNodeModule* nodep) { m_classOrPackageNodep = (AstNode*)nodep; } -}; class AstClocking final : public AstNode { // Set default clock region // Parents: MODULE @@ -934,7 +834,7 @@ class AstConstPool final : public AstNode { AstModule* const m_modp; // The Module holding the Scope below ... AstScope* const m_scopep; // Scope holding the constant variables - AstVarScope* createNewEntry(const string& name, AstNode* initp); + AstVarScope* createNewEntry(const string& name, AstNodeExpr* initp); public: explicit AstConstPool(FileLine* fl); @@ -960,11 +860,11 @@ public: class AstDefParam final : public AstNode { // A defparam assignment // Parents: MODULE - // @astgen op1 := rhsp : AstNode + // @astgen op1 := rhsp : AstNodeExpr string m_name; // Name of variable getting set string m_path; // Dotted cellname to set parameter of public: - AstDefParam(FileLine* fl, const string& path, const string& name, AstNode* rhsp) + AstDefParam(FileLine* fl, const string& path, const string& name, AstNodeExpr* rhsp) : ASTGEN_SUPER_DefParam(fl) , m_name{name} , m_path{path} { @@ -1000,7 +900,7 @@ private: VDisplayType m_displayType; public: - inline AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp); + inline AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNodeExpr* exprsp); ASTGEN_MEMBERS_AstElabDisplay; const char* broken() const override { BROKEN_RTN(!fmtp()); @@ -1064,50 +964,14 @@ public: } ASTGEN_MEMBERS_AstImplicit; }; -class AstInitArray final : public AstNode { - // Set a var to a map of values - // The list of initsp() is not relevant - // 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() - // @astgen op1 := defaultp : Optional[AstNode] // Default, if sparse - // @astgen op2 := initsp : List[AstNode] // Initial value expressions - // -public: - using KeyItemMap = std::map; - -private: - KeyItemMap m_map; // Node value for each array index -public: - AstInitArray(FileLine* fl, AstNodeDType* newDTypep, AstNode* defaultp) - : ASTGEN_SUPER_InitArray(fl) { - dtypep(newDTypep); - this->defaultp(defaultp); - } - ASTGEN_MEMBERS_AstInitArray; - void dump(std::ostream& str) const override; - const char* broken() const override; - void cloneRelink() override; - bool hasDType() const override { return true; } - bool same(const AstNode* samep) const override { - // Only works if exact same children, instead should override comparison - // of children list, and instead use map-vs-map key/value compare - return m_map == static_cast(samep)->m_map; - } - void addValuep(AstNode* newp) { addIndexValuep(m_map.size(), newp); } - const KeyItemMap& map() const { return m_map; } - void addIndexValuep(uint64_t index, AstNode* newp); - AstNode* getIndexValuep(uint64_t index) const; - AstNode* getIndexDefaultedValuep(uint64_t index) const; -}; 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 + // @astgen op1 := valuep : AstNodeExpr public: // Parents: INITARRAY - AstInitItem(FileLine* fl, AstNode* valuep) + AstInitItem(FileLine* fl, AstNodeExpr* valuep) : ASTGEN_SUPER_InitItem(fl) { this->valuep(valuep); } @@ -1317,7 +1181,7 @@ public: }; class AstPin final : public AstNode { // A port or parameter assignment on an instantiaton - // @astgen op1 := exprp : Optional[AstNode] // Expression connected (nullptr if unconnected) + // @astgen op1 := exprp : Optional[AstNode] // NodeExpr or NodeDType (nullptr if unconnected) private: int m_pinNum; // Pin number string m_name; // Pin name, or "" for number based interconnect @@ -1353,7 +1217,7 @@ public: }; class AstPort final : public AstNode { // A port (in/out/inout) on a module - // @astgen op1 := exprp : Optional[AstNode] // Expression connected to port + // @astgen op1 := exprp : Optional[AstNodeExpr] // Expression connected to port const int m_pinNum; // Pin number const string m_name; // Name of pin public: @@ -1385,10 +1249,10 @@ class AstPropSpec final : public AstNode { // Parents: ASSERT|COVER (property) // Children: SENITEM, Properties // @astgen op1 := sensesp : Optional[AstSenItem] - // @astgen op2 := disablep : Optional[AstNode] + // @astgen op2 := disablep : Optional[AstNodeExpr] // @astgen op3 := propp : AstNode public: - AstPropSpec(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp) + AstPropSpec(FileLine* fl, AstSenItem* sensesp, AstNodeExpr* disablep, AstNode* propp) : ASTGEN_SUPER_PropSpec(fl) { this->sensesp(sensesp); this->disablep(disablep); @@ -1400,12 +1264,12 @@ public: } // Used under Cover, which expects a bool child }; class AstPull final : public AstNode { - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr const bool m_direction; public: - AstPull(FileLine* fl, AstNode* lhsp, bool direction) + AstPull(FileLine* fl, AstNodeExpr* lhsp, bool direction) : ASTGEN_SUPER_Pull(fl) , m_direction{direction} { this->lhsp(lhsp); @@ -1455,24 +1319,9 @@ public: AstVarScope* createTemp(const string& name, AstNodeDType* dtypep); AstVarScope* createTempLike(const string& name, AstVarScope* vscp); }; -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) { - this->fromp(fromp); - this->addElementsp(elementsp); - } - ASTGEN_MEMBERS_AstSelLoopVars; - bool same(const AstNode* /*samep*/) const override { return true; } - bool maybePointedTo() const override { return false; } -}; class AstSenItem final : public AstNode { // Parents: SENTREE - // @astgen op1 := sensp : Optional[AstNode] // Sensitivity expression + // @astgen op1 := sensp : Optional[AstNodeExpr] // Sensitivity expression VEdgeType m_edgeType; // Edge type public: class Combo {}; // for constructor type-overload selection @@ -1481,7 +1330,7 @@ public: class Initial {}; // for constructor type-overload selection class Final {}; // for constructor type-overload selection class Never {}; // for constructor type-overload selection - AstSenItem(FileLine* fl, VEdgeType edgeType, AstNode* senp) + AstSenItem(FileLine* fl, VEdgeType edgeType, AstNodeExpr* senp) : ASTGEN_SUPER_SenItem(fl) , m_edgeType{edgeType} { this->sensp(senp); @@ -1695,7 +1544,7 @@ class AstVar final : public AstNode { // @astgen op2 := delayp : Optional[AstDelay] // Net delay // Initial value that never changes (static const), or constructor argument for // MTASKSTATE variables - // @astgen op3 := valuep : Optional[AstNode] + // @astgen op3 := valuep : Optional[AstNode] // May be a DType for type parameter defaults // @astgen op4 := attrsp : List[AstNode] // Attributes during early parse string m_name; // Name of variable @@ -2381,7 +2230,7 @@ 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 + // @astgen op1 := elementsp : AstNode // Expr or DType public: AstBracketRange(FileLine* fl, AstNode* elementsp) : ASTGEN_SUPER_BracketRange(fl) { @@ -2397,10 +2246,10 @@ public: }; class AstRange final : public AstNodeRange { // Range specification, for use under variables and cells - // @astgen op1 := leftp : AstNode - // @astgen op2 := rightp : AstNode + // @astgen op1 := leftp : AstNodeExpr + // @astgen op2 := rightp : AstNodeExpr public: - AstRange(FileLine* fl, AstNode* leftp, AstNode* rightp) + AstRange(FileLine* fl, AstNodeExpr* leftp, AstNodeExpr* rightp) : ASTGEN_SUPER_Range(fl) { this->leftp(leftp); this->rightp(rightp); @@ -2490,9 +2339,9 @@ public: }; class AstCReturn final : public AstNodeStmt { // C++ return from a function - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr public: - AstCReturn(FileLine* fl, AstNode* lhsp) + AstCReturn(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_CReturn(fl) { this->lhsp(lhsp); } @@ -2516,7 +2365,6 @@ public: }; class AstComment final : public AstNodeStmt { // Some comment to put into the output stream - // Parents: {statement list} const string m_name; // Text of comment const bool m_showAt; // Show "at " public: @@ -2541,9 +2389,6 @@ public: }; class AstCoverDecl final : public AstNodeStmt { // Coverage analysis point declaration - // Parents: {statement list} - // Children: none -private: AstCoverDecl* m_dataDeclp = nullptr; // [After V3CoverageJoin] Pointer to duplicate // declaration to get data from instead string m_page; @@ -2597,9 +2442,6 @@ public: }; class AstCoverInc final : public AstNodeStmt { // Coverage analysis point; increment coverage count - // Parents: {statement list} - // Children: none -private: AstCoverDecl* m_declp; // [After V3Coverage] Pointer to declaration public: AstCoverInc(FileLine* fl, AstCoverDecl* declp) @@ -2628,10 +2470,10 @@ class AstCoverToggle final : public AstNodeStmt { // Toggle analysis of given signal // Parents: MODULE // @astgen op1 := incp : AstCoverInc - // @astgen op2 := origp : AstNode - // @astgen op3 := changep : AstNode + // @astgen op2 := origp : AstNodeExpr + // @astgen op3 := changep : AstNodeExpr public: - AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep) + AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNodeExpr* origp, AstNodeExpr* changep) : ASTGEN_SUPER_CoverToggle(fl) { this->incp(incp); this->origp(origp); @@ -2649,10 +2491,10 @@ public: }; class AstDelay final : public AstNodeStmt { // Delay statement - // @astgen op1 := lhsp : AstNode // Delay value + // @astgen op1 := lhsp : AstNodeExpr // Delay value // @astgen op2 := stmtsp : List[AstNode] // Statements under delay public: - AstDelay(FileLine* fl, AstNode* lhsp) + AstDelay(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Delay(fl) { this->lhsp(lhsp); } @@ -2661,7 +2503,6 @@ public: bool same(const AstNode* /*samep*/) const override { return true; } }; class AstDisable final : public AstNodeStmt { -private: string m_name; // Name of block public: AstDisable(FileLine* fl, const string& name) @@ -2684,19 +2525,19 @@ public: class AstDisplay final : public AstNodeStmt { // Parents: stmtlist // @astgen op1 := fmtp : AstSFormatF - // @astgen op2 := filep : Optional[AstNode] // file (must be a VarRef) + // @astgen op2 := filep : Optional[AstNodeExpr] // file (must resolve to a VarRef) private: VDisplayType m_displayType; public: - AstDisplay(FileLine* fl, VDisplayType dispType, const string& text, AstNode* filep, - AstNode* exprsp, char missingArgChar = 'd') + AstDisplay(FileLine* fl, VDisplayType dispType, const string& text, AstNodeExpr* filep, + AstNodeExpr* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_Display(fl) , m_displayType{dispType} { this->fmtp(new AstSFormatF{fl, text, true, exprsp, missingArgChar}); this->filep(filep); } - AstDisplay(FileLine* fl, VDisplayType dispType, AstNode* filep, AstNode* exprsp, + AstDisplay(FileLine* fl, VDisplayType dispType, AstNodeExpr* filep, AstNodeExpr* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_Display(fl) , m_displayType{dispType} { @@ -2729,11 +2570,11 @@ public: }; class AstDoWhile final : public AstNodeStmt { // @astgen op1 := precondsp : List[AstNode] - // @astgen op2 := condp : AstNode + // @astgen op2 := condp : AstNodeExpr // @astgen op3 := stmtsp : List[AstNode] // @astgen op4 := incsp : List[AstNode] public: - AstDoWhile(FileLine* fl, AstNode* conditionp, AstNode* stmtsp = nullptr, + AstDoWhile(FileLine* fl, AstNodeExpr* conditionp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr) : ASTGEN_SUPER_DoWhile(fl) { condp(conditionp); @@ -2750,10 +2591,10 @@ public: class AstDumpCtl final : public AstNodeStmt { // $dumpon etc // Parents: expr - // @astgen op1 := exprp : Optional[AstNode] // Expression based on type of control statement + // @astgen op1 := exprp : Optional[AstNodeExpr] // Expression based on type of statement const VDumpCtlType m_ctlType; // Type of operation public: - AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr) + AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNodeExpr* exprp = nullptr) : ASTGEN_SUPER_DumpCtl(fl) , m_ctlType{ctlType} { this->exprp(exprp); @@ -2784,9 +2625,9 @@ public: }; class AstFClose final : public AstNodeStmt { // Parents: stmtlist - // @astgen op1 := filep : AstNode // file (must be a VarRef) + // @astgen op1 := filep : AstNodeExpr // file (must be a VarRef) public: - AstFClose(FileLine* fl, AstNode* filep) + AstFClose(FileLine* fl, AstNodeExpr* filep) : ASTGEN_SUPER_FClose(fl) { this->filep(filep); } @@ -2801,9 +2642,9 @@ public: }; class AstFFlush final : public AstNodeStmt { // Parents: stmtlist - // @astgen op1 := filep : Optional[AstNode] // file (must be a VarRef) + // @astgen op1 := filep : Optional[AstNodeExpr] // file (must be a VarRef) public: - AstFFlush(FileLine* fl, AstNode* filep) + AstFFlush(FileLine* fl, AstNodeExpr* filep) : ASTGEN_SUPER_FFlush(fl) { this->filep(filep); } @@ -2818,11 +2659,11 @@ public: }; 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 + // @astgen op1 := filep : AstNodeExpr + // @astgen op2 := filenamep : AstNodeExpr + // @astgen op3 := modep : AstNodeExpr public: - AstFOpen(FileLine* fl, AstNode* filep, AstNode* filenamep, AstNode* modep) + AstFOpen(FileLine* fl, AstNodeExpr* filep, AstNodeExpr* filenamep, AstNodeExpr* modep) : ASTGEN_SUPER_FOpen(fl) { this->filep(filep); this->filenamep(filenamep); @@ -2839,10 +2680,10 @@ public: }; 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 + // @astgen op1 := filep : AstNodeExpr + // @astgen op2 := filenamep : AstNodeExpr public: - AstFOpenMcd(FileLine* fl, AstNode* filep, AstNode* filenamep) + AstFOpenMcd(FileLine* fl, AstNodeExpr* filep, AstNodeExpr* filenamep) : ASTGEN_SUPER_FOpenMcd(fl) { this->filep(filep); this->filenamep(filenamep); @@ -2871,10 +2712,10 @@ public: }; class AstFireEvent final : public AstNodeStmt { // '-> _' and '->> _' event trigger statements - // @astgen op1 := operandp : AstNode + // @astgen op1 := operandp : AstNodeExpr const bool m_delayed; // Delayed (->>) vs non-delayed (->) public: - AstFireEvent(FileLine* fl, AstNode* operandp, bool delayed) + AstFireEvent(FileLine* fl, AstNodeExpr* operandp, bool delayed) : ASTGEN_SUPER_FireEvent(fl) , m_delayed{delayed} { this->operandp(operandp); @@ -3026,19 +2867,19 @@ public: }; class AstRelease final : public AstNodeStmt { // Procedural 'release' statement - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr public: - AstRelease(FileLine* fl, AstNode* lhsp) + AstRelease(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_Release(fl) { this->lhsp(lhsp); } ASTGEN_MEMBERS_AstRelease; }; class AstRepeat final : public AstNodeStmt { - // @astgen op1 := countp : AstNode + // @astgen op1 := countp : AstNodeExpr // @astgen op2 := stmtsp : List[AstNode] public: - AstRepeat(FileLine* fl, AstNode* countp, AstNode* stmtsp) + AstRepeat(FileLine* fl, AstNodeExpr* countp, AstNode* stmtsp) : ASTGEN_SUPER_Repeat(fl) { this->countp(countp); this->addStmtsp(stmtsp); @@ -3050,9 +2891,9 @@ public: bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstReturn final : public AstNodeStmt { - // @astgen op1 := lhsp : Optional[AstNode] + // @astgen op1 := lhsp : Optional[AstNodeExpr] public: - explicit AstReturn(FileLine* fl, AstNode* lhsp = nullptr) + explicit AstReturn(FileLine* fl, AstNodeExpr* lhsp = nullptr) : ASTGEN_SUPER_Return(fl) { this->lhsp(lhsp); } @@ -3065,15 +2906,15 @@ public: class AstSFormat final : public AstNodeStmt { // Parents: statement container // @astgen op1 := fmtp : AstSFormatF - // @astgen op2 := lhsp : AstNode + // @astgen op2 := lhsp : AstNodeExpr public: - AstSFormat(FileLine* fl, AstNode* lhsp, const string& text, AstNode* exprsp, + AstSFormat(FileLine* fl, AstNodeExpr* lhsp, const string& text, AstNodeExpr* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_SFormat(fl) { this->fmtp(new AstSFormatF{fl, text, true, exprsp, missingArgChar}); this->lhsp(lhsp); } - AstSFormat(FileLine* fl, AstNode* lhsp, AstNode* exprsp, char missingArgChar = 'd') + AstSFormat(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* exprsp, char missingArgChar = 'd') : ASTGEN_SUPER_SFormat(fl) { this->fmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp, missingArgChar}); this->lhsp(lhsp); @@ -3130,10 +2971,11 @@ public: bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } }; class AstSysFuncAsTask final : public AstNodeStmt { + // TODO: This is superseded by AstStmtExpr, remove // Call what is normally a system function (with a return) in a non-return context - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr public: - AstSysFuncAsTask(FileLine* fl, AstNode* lhsp) + AstSysFuncAsTask(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_SysFuncAsTask(fl) { this->lhsp(lhsp); } @@ -3148,9 +2990,9 @@ public: }; class AstSystemT final : public AstNodeStmt { // $system used as task - // @astgen op1 := lhsp : AstNode + // @astgen op1 := lhsp : AstNodeExpr public: - AstSystemT(FileLine* fl, AstNode* lhsp) + AstSystemT(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_SystemT(fl) { this->lhsp(lhsp); } @@ -3165,13 +3007,13 @@ public: }; class AstTimeFormat final : public AstNodeStmt { // Parents: stmtlist - // @astgen op1 := unitsp : AstNode - // @astgen op2 := precisionp : AstNode - // @astgen op3 := suffixp : AstNode - // @astgen op4 := widthp : AstNode + // @astgen op1 := unitsp : AstNodeExpr + // @astgen op2 := precisionp : AstNodeExpr + // @astgen op3 := suffixp : AstNodeExpr + // @astgen op4 := widthp : AstNodeExpr public: - AstTimeFormat(FileLine* fl, AstNode* unitsp, AstNode* precisionp, AstNode* suffixp, - AstNode* widthp) + AstTimeFormat(FileLine* fl, AstNodeExpr* unitsp, AstNodeExpr* precisionp, AstNodeExpr* suffixp, + AstNodeExpr* widthp) : ASTGEN_SUPER_TimeFormat(fl) { this->unitsp(unitsp); this->precisionp(precisionp); @@ -3191,7 +3033,7 @@ class AstTraceDecl final : public AstNodeStmt { // Separate from AstTraceInc; as a declaration can't be deleted // Parents: {statement list} // Expression being traced - Moved to AstTraceInc by V3Trace - // @astgen op1 := valuep : Optional[AstNode] + // @astgen op1 := valuep : Optional[AstNodeExpr] private: uint32_t m_code = 0; // Trace identifier code; converted to ASCII by trace routines const string m_showname; // Name of variable @@ -3204,7 +3046,7 @@ private: public: AstTraceDecl(FileLine* fl, const string& showname, AstVar* varp, // For input/output state etc - AstNode* valuep, const VNumRange& bitRange, const VNumRange& arrayRange) + AstNodeExpr* valuep, const VNumRange& bitRange, const VNumRange& arrayRange) : ASTGEN_SUPER_TraceDecl(fl) , m_showname{showname} , m_bitRange{bitRange} @@ -3239,7 +3081,7 @@ public: class AstTraceInc final : public AstNodeStmt { // Trace point dump // @astgen op1 := precondsp : List[AstNode] // Statements to emit before this node - // @astgen op2 := valuep : AstNode // Expression being traced (from decl) + // @astgen op2 := valuep : AstNodeExpr // Expression being traced (from decl) private: AstTraceDecl* m_declp; // Pointer to declaration @@ -3300,7 +3142,7 @@ public: }; class AstUCStmt final : public AstNodeStmt { // User $c statement - // @astgen op1 := exprsp : List[AstNode] + // @astgen op1 := exprsp : List[AstNode] // (some are AstText) public: AstUCStmt(FileLine* fl, AstNode* exprsp) : ASTGEN_SUPER_UCStmt(fl) { @@ -3314,10 +3156,10 @@ public: bool same(const AstNode* /*samep*/) const override { return true; } }; class AstWait final : public AstNodeStmt { - // @astgen op1 := condp : AstNode + // @astgen op1 := condp : AstNodeExpr // @astgen op2 := stmtsp : List[AstNode] public: - AstWait(FileLine* fl, AstNode* condp, AstNode* stmtsp) + AstWait(FileLine* fl, AstNodeExpr* condp, AstNode* stmtsp) : ASTGEN_SUPER_Wait(fl) { this->condp(condp); this->addStmtsp(stmtsp); @@ -3335,11 +3177,11 @@ public: }; class AstWhile final : public AstNodeStmt { // @astgen op1 := precondsp : List[AstNode] - // @astgen op2 := condp : AstNode + // @astgen op2 := condp : AstNodeExpr // @astgen op3 := stmtsp : List[AstNode] // @astgen op4 := incsp : List[AstNode] public: - AstWhile(FileLine* fl, AstNode* condp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr) + AstWhile(FileLine* fl, AstNodeExpr* condp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr) : ASTGEN_SUPER_While(fl) { this->condp(condp); this->addStmtsp(stmtsp); @@ -3355,43 +3197,17 @@ public: void addNextStmt(AstNode* newp, AstNode* belowp) override; bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; -class AstWith final : public AstNodeStmt { - // Used as argument to method, then to AstCMethodHard - // dtypep() contains the with lambda's return dtype - // Parents: funcref (similar to AstArg) - // Children: LambdaArgRef that declares the item variable - // Children: LambdaArgRef that declares the item.index variable - // Children: expression (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) { - this->indexArgRefp(indexArgRefp); - this->valueArgRefp(valueArgRefp); - this->exprp(exprp); - } - ASTGEN_MEMBERS_AstWith; - bool same(const AstNode* /*samep*/) const override { return true; } - bool hasDType() const override { return true; } - const char* broken() const override { - BROKEN_RTN(!indexArgRefp()); // varp needed to know lambda's arg dtype - BROKEN_RTN(!valueArgRefp()); // varp needed to know lambda's arg dtype - return nullptr; - } -}; // === AstNodeAssign === class AstAssign final : public AstNodeAssign { public: - AstAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* timingControlp = nullptr) + AstAssign(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, + AstNode* timingControlp = nullptr) : ASTGEN_SUPER_Assign(fl, lhsp, rhsp, timingControlp) { dtypeFrom(lhsp); } ASTGEN_MEMBERS_AstAssign; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { AstNode* const controlp = timingControlp() ? timingControlp()->cloneTree(false) : nullptr; return new AstAssign{fileline(), lhsp, rhsp, controlp}; } @@ -3402,17 +3218,20 @@ class AstAssignAlias final : public AstNodeAssign { // If both sides are wires, there's no LHS vs RHS, public: AstAssignAlias(FileLine* fl, AstVarRef* lhsp, AstVarRef* rhsp) - : ASTGEN_SUPER_AssignAlias(fl, (AstNode*)lhsp, (AstNode*)rhsp) {} + : ASTGEN_SUPER_AssignAlias(fl, (AstNodeExpr*)lhsp, (AstNodeExpr*)rhsp) {} ASTGEN_MEMBERS_AstAssignAlias; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { V3ERROR_NA_RETURN(nullptr); } + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { + V3ERROR_NA_RETURN(nullptr); + } bool brokeLhsMustBeLvalue() const override { return false; } }; class AstAssignDly final : public AstNodeAssign { public: - AstAssignDly(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* timingControlp = nullptr) + AstAssignDly(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, + AstNode* timingControlp = nullptr) : ASTGEN_SUPER_AssignDly(fl, lhsp, rhsp, timingControlp) {} ASTGEN_MEMBERS_AstAssignDly; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { AstNode* const controlp = timingControlp() ? timingControlp()->cloneTree(false) : nullptr; return new AstAssignDly{fileline(), lhsp, rhsp, controlp}; } @@ -3423,10 +3242,10 @@ public: class AstAssignForce final : public AstNodeAssign { // Procedural 'force' statement public: - AstAssignForce(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAssignForce(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_AssignForce(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstAssignForce; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAssignForce{fileline(), lhsp, rhsp}; } bool brokeLhsMustBeLvalue() const override { return true; } @@ -3434,10 +3253,10 @@ public: class AstAssignPost final : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: - AstAssignPost(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAssignPost(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_AssignPost(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstAssignPost; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAssignPost{fileline(), lhsp, rhsp}; } bool brokeLhsMustBeLvalue() const override { return true; } @@ -3445,10 +3264,10 @@ public: class AstAssignPre final : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: - AstAssignPre(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAssignPre(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_AssignPre(fl, lhsp, rhsp) {} ASTGEN_MEMBERS_AstAssignPre; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAssignPre{fileline(), lhsp, rhsp}; } bool brokeLhsMustBeLvalue() const override { return true; } @@ -3456,12 +3275,12 @@ public: class AstAssignVarScope final : public AstNodeAssign { // Assign two VarScopes to each other public: - AstAssignVarScope(FileLine* fl, AstNode* lhsp, AstNode* rhsp) + AstAssignVarScope(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) : ASTGEN_SUPER_AssignVarScope(fl, lhsp, rhsp) { dtypeFrom(rhsp); } ASTGEN_MEMBERS_AstAssignVarScope; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { return new AstAssignVarScope{fileline(), lhsp, rhsp}; } bool brokeLhsMustBeLvalue() const override { return false; } @@ -3470,10 +3289,11 @@ 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, AstNode* timingControlp = nullptr) + AstAssignW(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, + AstNode* timingControlp = nullptr) : ASTGEN_SUPER_AssignW(fl, lhsp, rhsp, timingControlp) {} ASTGEN_MEMBERS_AstAssignW; - AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override { + AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override { AstNode* const controlp = timingControlp() ? timingControlp()->cloneTree(false) : nullptr; return new AstAssignW{fileline(), lhsp, rhsp, controlp}; } @@ -3489,8 +3309,6 @@ public: // === AstNodeCase === class AstCase final : public AstNodeCase { // Case statement - // Parents: {statement list} -private: VCaseType m_casex; // 0=case, 1=casex, 2=casez bool m_fullPragma = false; // Synthesis full_case bool m_parallelPragma = false; // Synthesis parallel_case @@ -3498,7 +3316,7 @@ private: bool m_unique0Pragma = false; // unique0 case bool m_priorityPragma = false; // priority case public: - AstCase(FileLine* fl, VCaseType casex, AstNode* exprp, AstCaseItem* itemsp) + AstCase(FileLine* fl, VCaseType casex, AstNodeExpr* exprp, AstCaseItem* itemsp) : ASTGEN_SUPER_Case(fl, exprp, itemsp) , m_casex{casex} {} ASTGEN_MEMBERS_AstCase; @@ -3524,9 +3342,8 @@ public: }; class AstGenCase final : public AstNodeCase { // Generate Case statement - // Parents: {statement list} public: - AstGenCase(FileLine* fl, AstNode* exprp, AstCaseItem* itemsp) + AstGenCase(FileLine* fl, AstNodeExpr* exprp, AstCaseItem* itemsp) : ASTGEN_SUPER_GenCase(fl, exprp, itemsp) {} ASTGEN_MEMBERS_AstGenCase; }; @@ -3572,7 +3389,7 @@ public: // === AstNodeFor === class AstGenFor final : public AstNodeFor { public: - AstGenFor(FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* stmtsp) + AstGenFor(FileLine* fl, AstNode* initsp, AstNodeExpr* condp, AstNode* incsp, AstNode* stmtsp) : ASTGEN_SUPER_GenFor(fl, initsp, condp, incsp, stmtsp) {} ASTGEN_MEMBERS_AstGenFor; }; @@ -3580,7 +3397,7 @@ public: // === AstNodeIf === class AstGenIf final : public AstNodeIf { public: - AstGenIf(FileLine* fl, AstNode* condp, AstNode* thensp, AstNode* elsesp) + AstGenIf(FileLine* fl, AstNodeExpr* condp, AstNode* thensp, AstNode* elsesp) : ASTGEN_SUPER_GenIf(fl, condp, thensp, elsesp) {} ASTGEN_MEMBERS_AstGenIf; }; @@ -3590,7 +3407,7 @@ private: bool m_unique0Pragma = false; // unique0 case bool m_priorityPragma = false; // priority case public: - AstIf(FileLine* fl, AstNode* condp, AstNode* thensp = nullptr, AstNode* elsesp = nullptr) + AstIf(FileLine* fl, AstNodeExpr* condp, AstNode* thensp = nullptr, AstNode* elsesp = nullptr) : ASTGEN_SUPER_If(fl, condp, thensp, elsesp) {} ASTGEN_MEMBERS_AstIf; bool uniquePragma() const { return m_uniquePragma; } @@ -3604,8 +3421,8 @@ public: // === AstNodeReadWriteMem === class AstReadMem final : public AstNodeReadWriteMem { public: - AstReadMem(FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp, - AstNode* msbp) + AstReadMem(FileLine* fl, bool hex, AstNodeExpr* filenamep, AstNodeExpr* memp, + AstNodeExpr* lsbp, AstNodeExpr* msbp) : ASTGEN_SUPER_ReadMem(fl, hex, filenamep, memp, lsbp, msbp) {} ASTGEN_MEMBERS_AstReadMem; string verilogKwd() const override { return (isHex() ? "$readmemh" : "$readmemb"); } @@ -3613,8 +3430,8 @@ public: }; class AstWriteMem final : public AstNodeReadWriteMem { public: - AstWriteMem(FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp, - AstNode* msbp) + AstWriteMem(FileLine* fl, bool hex, AstNodeExpr* filenamep, AstNodeExpr* memp, + AstNodeExpr* lsbp, AstNodeExpr* msbp) : ASTGEN_SUPER_WriteMem(fl, hex, filenamep, memp, lsbp, msbp) {} ASTGEN_MEMBERS_AstWriteMem; string verilogKwd() const override { return (isHex() ? "$writememh" : "$writememb"); } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index c3083a152..9c84cdb2d 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -252,7 +252,7 @@ int AstNodeUOrStructDType::widthAlignBytes() const { } } -AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { +AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) { if (lhsp->isString() && rhsp->isString()) { return new AstEqN(fl, lhsp, rhsp); } else if (lhsp->isDouble() && rhsp->isDouble()) { @@ -262,7 +262,7 @@ AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { } } -AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { +AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) { if (lhsp->isString() && rhsp->isString()) { return new AstEqN(fl, lhsp, rhsp); } else if (lhsp->isDouble() && rhsp->isDouble()) { @@ -279,13 +279,13 @@ AstExecGraph::AstExecGraph(FileLine* fileline, const string& name) AstExecGraph::~AstExecGraph() { VL_DO_DANGLING(delete m_depGraphp, m_depGraphp); } -AstNode* AstInsideRange::newAndFromInside(AstNode* exprp, AstNode* lhsp, AstNode* rhsp) { - AstNode* const ap = new AstGte(fileline(), exprp->cloneTree(true), lhsp); - AstNode* const bp = new AstLte(fileline(), exprp->cloneTree(true), rhsp); +AstNodeExpr* AstInsideRange::newAndFromInside(AstNodeExpr* exprp, AstNodeExpr* lhsp, + AstNodeExpr* rhsp) { + AstNodeExpr* const ap = new AstGte{fileline(), exprp->cloneTree(true), lhsp}; + AstNodeExpr* const bp = new AstLte{fileline(), exprp->cloneTree(true), rhsp}; ap->fileline()->modifyWarnOff(V3ErrorCode::UNSIGNED, true); bp->fileline()->modifyWarnOff(V3ErrorCode::CMPCONST, true); - AstNode* const newp = new AstAnd(fileline(), ap, bp); - return newp; + return new AstAnd(fileline(), ap, bp); } AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) { @@ -1122,7 +1122,7 @@ const char* AstConstPool::broken() const { return nullptr; } -AstVarScope* AstConstPool::createNewEntry(const string& name, AstNode* initp) { +AstVarScope* AstConstPool::createNewEntry(const string& name, AstNodeExpr* initp) { FileLine* const fl = initp->fileline(); AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, name, initp->dtypep()); varp->isConst(true); @@ -1575,7 +1575,7 @@ void AstInitArray::cloneRelink() { if (it->second->clonep()) it->second = it->second->clonep(); } } -void AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) { +void AstInitArray::addIndexValuep(uint64_t index, AstNodeExpr* newp) { const auto it = m_map.find(index); if (it != m_map.end()) { it->second->valuep(newp); @@ -1585,7 +1585,7 @@ void AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) { addInitsp(itemp); } } -AstNode* AstInitArray::getIndexValuep(uint64_t index) const { +AstNodeExpr* AstInitArray::getIndexValuep(uint64_t index) const { const auto it = m_map.find(index); if (it == m_map.end()) { return nullptr; @@ -1593,8 +1593,8 @@ AstNode* AstInitArray::getIndexValuep(uint64_t index) const { return it->second->valuep(); } } -AstNode* AstInitArray::getIndexDefaultedValuep(uint64_t index) const { - AstNode* valuep = getIndexValuep(index); +AstNodeExpr* AstInitArray::getIndexDefaultedValuep(uint64_t index) const { + AstNodeExpr* valuep = getIndexValuep(index); if (!valuep) valuep = defaultp(); return valuep; } @@ -2302,8 +2302,8 @@ void AstCUse::dump(std::ostream& str) const { AstAlways* AstAssignW::convertToAlways() { const bool hasTimingControl = isTimingControl(); - AstNode* const lhs1p = lhsp()->unlinkFrBack(); - AstNode* const rhs1p = rhsp()->unlinkFrBack(); + AstNodeExpr* const lhs1p = lhsp()->unlinkFrBack(); + AstNodeExpr* const rhs1p = rhsp()->unlinkFrBack(); AstNode* const controlp = timingControlp() ? timingControlp()->unlinkFrBack() : nullptr; FileLine* const flp = fileline(); AstNode* bodysp = new AstAssign{flp, lhs1p, rhs1p, controlp}; diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index f1e5b1bca..585c23a19 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -152,7 +152,7 @@ void V3CCtors::evalAsserts() { AstVarRef* const vrefp = new AstVarRef{varp->fileline(), varp, VAccess::READ}; vrefp->selfPointer("this"); - AstNode* newp = vrefp; + AstNodeExpr* newp = vrefp; if (varp->isWide()) { newp = new AstWordSel{ varp->fileline(), newp, @@ -167,8 +167,7 @@ void V3CCtors::evalAsserts() { new AstCStmt{varp->fileline(), "Verilated::overWidthError(\"" + varp->prettyName() + "\");"}}; ifp->branchPred(VBranchPred::BP_UNLIKELY); - newp = ifp; - funcp->addStmtsp(newp); + funcp->addStmtsp(ifp); } } } diff --git a/src/V3Case.cpp b/src/V3Case.cpp index 258f76e0d..1537a14ee 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -250,7 +250,7 @@ private: return true; // All is fine } - AstNode* replaceCaseFastRecurse(AstNode* cexprp, int msb, uint32_t upperValue) { + AstNode* replaceCaseFastRecurse(AstNodeExpr* cexprp, int msb, uint32_t upperValue) { if (msb < 0) { // There's no space for a IF. We know upperValue is thus down to a specific // exact value, so just return the tree value @@ -290,9 +290,9 @@ private: // V3Number nummask (cexprp, cexprp->width(), (1UL<fileline(), cexprp->cloneTree(false), // new AstConst(cexprp->fileline(), nummask)); - AstNode* const and1p + AstNodeExpr* const and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false), msb, 1); - AstNode* const eqp + AstNodeExpr* const eqp = new AstNeq(cexprp->fileline(), new AstConst(cexprp->fileline(), 0), and1p); AstIf* const ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p); ifp->user3(1); // So we don't bother to clone it @@ -304,7 +304,7 @@ private: // CASEx(cexpr,.... // -> tree of IF(msb, IF(msb-1, 11, 10) // IF(msb-1, 01, 00)) - AstNode* const cexprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* const cexprp = nodep->exprp()->unlinkFrBack(); if (debug() >= 9) { // LCOV_EXCL_START for (uint32_t i = 0; i < (1UL << m_caseWidth); ++i) { @@ -337,7 +337,7 @@ private: // -> IF((cexpr==icond1),istmts1, // IF((EQ (AND MASK cexpr) (AND MASK icond1) // ,istmts2, istmts3 - AstNode* const cexprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* const cexprp = nodep->exprp()->unlinkFrBack(); // We'll do this in two stages. First stage, convert the conditions to // the appropriate IF AND terms. if (debug() >= 9) nodep->dumpTree(cout, " _comp_IN: "); @@ -350,13 +350,13 @@ private: hadDefault = true; } else { // Expressioned clause - AstNode* icondNextp = nullptr; - AstNode* ifexprp = nullptr; // If expression to test - for (AstNode* icondp = itemp->condsp(); icondp; icondp = icondNextp) { - icondNextp = icondp->nextp(); + AstNodeExpr* icondNextp = nullptr; + AstNodeExpr* ifexprp = nullptr; // If expression to test + for (AstNodeExpr* icondp = itemp->condsp(); icondp; icondp = icondNextp) { + icondNextp = VN_AS(icondp->nextp(), NodeExpr); icondp->unlinkFrBack(); - AstNode* condp = nullptr; // Default is to use and1p/and2p + AstNodeExpr* condp = nullptr; // Default is to use and1p/and2p AstConst* const iconstp = VN_CAST(icondp, Const); if (iconstp && neverItem(nodep, iconstp)) { // X in casez can't ever be executed @@ -375,10 +375,10 @@ private: nummask.opBitsNonX(iconstp->num()); V3Number numval(itemp, iconstp->width()); numval.opBitsOne(iconstp->num()); - AstNode* const and1p + AstNodeExpr* const and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false), new AstConst(itemp->fileline(), nummask)); - AstNode* const and2p = new AstAnd( + AstNodeExpr* const and2p = new AstAnd( itemp->fileline(), new AstConst(itemp->fileline(), numval), new AstConst(itemp->fileline(), nummask)); VL_DO_DANGLING(icondp->deleteTree(), icondp); @@ -386,8 +386,8 @@ private: condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); } else { // Not a caseX mask, we can build CASEEQ(cexpr icond) - AstNode* const and1p = cexprp->cloneTree(false); - AstNode* const and2p = icondp; + AstNodeExpr* const and1p = cexprp->cloneTree(false); + AstNodeExpr* const and2p = icondp; condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); } if (!ifexprp) { @@ -423,7 +423,7 @@ private: AstNode* const istmtsp = itemp->stmtsp(); // Maybe null -- no action. if (istmtsp) istmtsp->unlinkFrBackWithNext(); // Expressioned clause - AstNode* const ifexprp = itemp->condsp()->unlinkFrBack(); + AstNodeExpr* const ifexprp = itemp->condsp()->unlinkFrBack(); { // Prepare for next group if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1; if (depth == 1) { // First group or starting new group @@ -436,13 +436,13 @@ private: } groupnextp = newp; } else { // Continue group, modify if condition to OR in this new condition - AstNode* const condp = groupnextp->condp()->unlinkFrBack(); + AstNodeExpr* const condp = groupnextp->condp()->unlinkFrBack(); groupnextp->condp( new AstOr(ifexprp->fileline(), condp, ifexprp->cloneTree(true))); } } { // Make the new lower IF and attach in the tree - AstNode* itemexprp = ifexprp; + AstNodeExpr* itemexprp = ifexprp; VL_DANGLING(ifexprp); if (depth == CASE_ENCODER_GROUP_DEPTH) { // End of group - can skip the condition VL_DO_DANGLING(itemexprp->deleteTree(), itemexprp); diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 0db4e7578..89563eb5c 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -63,7 +63,7 @@ private: // METHODS - void insertCast(AstNode* nodep, int needsize) { // We'll insert ABOVE passed node + void insertCast(AstNodeExpr* nodep, int needsize) { // We'll insert ABOVE passed node UINFO(4, " NeedCast " << nodep << endl); VNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); @@ -87,7 +87,7 @@ private: return VL_IDATASIZE; } } - void ensureCast(AstNode* nodep) { + void ensureCast(AstNodeExpr* nodep) { if (castSize(nodep->backp()) != castSize(nodep) || !nodep->user1()) { insertCast(nodep, castSize(nodep->backp())); } @@ -101,13 +101,12 @@ private: insertCast(nodep->lhsp(), VL_IDATASIZE); } } - void ensureNullChecked(AstNode* nodep) { + void ensureNullChecked(AstNodeExpr* nodep) { // TODO optimize to track null checked values and avoid where possible if (!VN_IS(nodep->backp(), NullCheck)) { VNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); - AstNode* const newp = new AstNullCheck{nodep->fileline(), nodep}; - relinkHandle.relink(newp); + relinkHandle.relink(new AstNullCheck{nodep->fileline(), nodep}); } } diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index db31e87fb..626a1d9ca 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -121,7 +121,7 @@ private: } // Operate on nodes - void insertClean(AstNode* nodep) { // We'll insert ABOVE passed node + void insertClean(AstNodeExpr* nodep) { // We'll insert ABOVE passed node UINFO(4, " NeedClean " << nodep << endl); VNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); @@ -134,14 +134,14 @@ private: cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS relinkHandle.relink(cleanp); } - void ensureClean(AstNode* nodep) { + void ensureClean(AstNodeExpr* nodep) { computeCppWidth(nodep); if (!isClean(nodep)) insertClean(nodep); } - void ensureCleanAndNext(AstNode* nodep) { + void ensureCleanAndNext(AstNodeExpr* nodep) { // Editing list, careful looping! - for (AstNode* exprp = nodep; exprp;) { - AstNode* const nextp = exprp->nextp(); + for (AstNodeExpr* exprp = nodep; exprp;) { + AstNodeExpr* const nextp = VN_AS(exprp->nextp(), NodeExpr); ensureClean(exprp); exprp = nextp; } @@ -237,7 +237,9 @@ 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->exprsp()); + for (AstNode* argp = nodep->exprsp(); argp; argp = argp->nextp()) { + if (AstNodeExpr* const exprp = VN_CAST(argp, NodeExpr)) ensureClean(exprp); + } } void visit(AstTraceDecl* nodep) override { // No cleaning, or would loose pointer to enum @@ -277,7 +279,9 @@ private: } void visit(AstUCStmt* nodep) override { iterateChildren(nodep); - ensureCleanAndNext(nodep->exprsp()); + for (AstNode* argp = nodep->exprsp(); argp; argp = argp->nextp()) { + if (AstNodeExpr* const exprp = VN_CAST(argp, NodeExpr)) ensureClean(exprp); + } } void visit(AstNodeCCall* nodep) override { iterateChildren(nodep); diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 501e42098..07e088140 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -46,11 +46,11 @@ VL_DEFINE_DEBUG_FUNCTIONS; class ConvertWriteRefsToRead final : public VNVisitor { private: // MEMBERS - AstNode* m_result = nullptr; + AstNodeExpr* m_result = nullptr; // CONSTRUCTORS - explicit ConvertWriteRefsToRead(AstNode* nodep) { - m_result = iterateSubtreeReturnEdits(nodep); + explicit ConvertWriteRefsToRead(AstNodeExpr* nodep) { + m_result = VN_AS(iterateSubtreeReturnEdits(nodep), NodeExpr); } // VISITORS @@ -65,7 +65,7 @@ private: void visit(AstNode* nodep) override { iterateChildren(nodep); } public: - static AstNode* main(AstNode* nodep) { return ConvertWriteRefsToRead(nodep).m_result; } + static AstNodeExpr* main(AstNodeExpr* nodep) { return ConvertWriteRefsToRead(nodep).m_result; } }; //###################################################################### @@ -82,11 +82,11 @@ private: // METHODS - AstNode* createSenseEquation(AstSenItem* nodesp) { - AstNode* senEqnp = nullptr; + AstNodeExpr* createSenseEquation(AstSenItem* nodesp) { + AstNodeExpr* senEqnp = nullptr; for (AstSenItem* senp = nodesp; senp; senp = VN_AS(senp->nextp(), SenItem)) { UASSERT_OBJ(senp->edgeType() == VEdgeType::ET_TRUE, senp, "Should have been lowered"); - AstNode* const senOnep = senp->sensp()->cloneTree(false); + AstNodeExpr* const senOnep = senp->sensp()->cloneTree(false); senEqnp = senEqnp ? new AstOr{senp->fileline(), senEqnp, senOnep} : senOnep; } return senEqnp; @@ -111,7 +111,7 @@ private: return newvscp; } AstIf* makeActiveIf(AstSenTree* sensesp) { - AstNode* const senEqnp = createSenseEquation(sensesp->sensesp()); + AstNodeExpr* const senEqnp = createSenseEquation(sensesp->sensesp()); UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation."); AstIf* const newifp = new AstIf{sensesp->fileline(), senEqnp}; return newifp; @@ -126,9 +126,9 @@ private: // COVERTOGGLE(INC, ORIG, CHANGE) -> // IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; } AstNode* const incp = nodep->incp()->unlinkFrBack(); - AstNode* const origp = nodep->origp()->unlinkFrBack(); - AstNode* const changeWrp = nodep->changep()->unlinkFrBack(); - AstNode* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false)); + AstNodeExpr* const origp = nodep->origp()->unlinkFrBack(); + AstNodeExpr* const changeWrp = nodep->changep()->unlinkFrBack(); + AstNodeExpr* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false)); AstIf* const newp = new AstIf{nodep->fileline(), new AstXor{nodep->fileline(), origp, changeRdp}, incp}; // We could add another IF to detect posedges, and only increment if so. diff --git a/src/V3Common.cpp b/src/V3Common.cpp index 9df1abc8a..a421c49f5 100644 --- a/src/V3Common.cpp +++ b/src/V3Common.cpp @@ -42,7 +42,8 @@ static void makeVlToString(AstClass* nodep) { funcp->isConst(false); funcp->isStatic(false); funcp->protect(false); - AstNode* const exprp = new AstCExpr{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0}; + AstNodeExpr* const exprp + = new AstCExpr{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0}; exprp->dtypeSetString(); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); nodep->addStmtsp(funcp); @@ -55,7 +56,7 @@ static void makeVlToString(AstIface* nodep) { funcp->isConst(false); funcp->isStatic(false); funcp->protect(false); - AstNode* const exprp = new AstCExpr{nodep->fileline(), "obj ? obj->name() : \"null\"", 0}; + AstNodeExpr* const exprp = new AstCExpr{nodep->fileline(), "obj ? obj->name() : \"null\"", 0}; exprp->dtypeSetString(); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); nodep->addStmtsp(funcp); @@ -65,7 +66,7 @@ static void makeToString(AstClass* nodep) { funcp->isConst(true); funcp->isStatic(false); funcp->protect(false); - AstNode* const exprp + AstCExpr* const exprp = new AstCExpr{nodep->fileline(), R"(std::string{"'{"} + to_string_middle() + "}")", 0}; exprp->dtypeSetString(); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 08ad3272d..173666099 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -80,7 +80,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor { // Holds a node to be added as a term in the reduction tree, it's equivalent op count, and a // bool indicating if the term is clean (0/1 value, or if the top bits might be dirty) - using ResultTerm = std::tuple; + using ResultTerm = std::tuple; class LeafInfo final { // Leaf node (either AstConst or AstVarRef) // MEMBERS @@ -243,7 +243,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor { FileLine* const fl = m_refp->fileline(); // Get the term we are referencing (the WordSel, if wide, otherwise just the VarRef) - AstNode* srcp = VN_CAST(m_refp->backp(), WordSel); + AstNodeExpr* srcp = VN_CAST(m_refp->backp(), WordSel); if (!srcp) srcp = m_refp; srcp = srcp->cloneTree(false); @@ -260,7 +260,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor { UASSERT(maskVal != 0, "Should have been recognized as having const 0 result"); // Parts of the return value - AstNode* resultp = srcp; // The tree for this term + AstNodeExpr* resultp = srcp; // The tree for this term unsigned ops = 0; // Number of ops in this term bool clean = false; // Whether the term is clean (has value 0 or 1) @@ -344,9 +344,9 @@ class ConstBitOpTreeVisitor final : public VNVisitor { unsigned m_ops; // Number of operations such as And, Or, Xor, Sel... int m_lsb = 0; // Current LSB LeafInfo* m_leafp = nullptr; // AstConst or AstVarRef that currently looking for - const AstNode* const m_rootp; // Root of this AST subtree + const AstNodeExpr* const m_rootp; // Root of this AST subtree - std::vector> + std::vector> m_frozenNodes; // Nodes that cannot be optimized std::vector m_bitPolarities; // Polarity of bits found during iterate() std::vector> m_varInfos; // VarInfo for each variable, [0] is nullptr @@ -529,7 +529,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor { Restorer restorer{*this}; LeafInfo leafInfo{m_lsb}; m_leafp = &leafInfo; - AstNode* opp = right ? nodep->rhsp() : nodep->lhsp(); + AstNodeExpr* opp = right ? nodep->rhsp() : nodep->lhsp(); const bool origFailed = m_failed; iterate(opp); if (leafInfo.constp() || m_failed) { @@ -625,7 +625,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor { } // CONSTRUCTORS - ConstBitOpTreeVisitor(AstNode* nodep, unsigned externalOps) + ConstBitOpTreeVisitor(AstNodeExpr* nodep, unsigned externalOps) : m_ops{externalOps} , m_rootp{nodep} { // Fill nullptr at [0] because AstVarScope::user4 is 0 by default @@ -656,8 +656,8 @@ public: // (3'b000 != (3'b011 & v)) | v[2] => 3'b000 != (3'b111 & v) // Reduction ops are transformed in the same way. // &{v[0], v[1]} => 2'b11 == (2'b11 & v) - static AstNode* simplify(AstNode* nodep, int resultWidth, unsigned externalOps, - VDouble0& reduction) { + static AstNodeExpr* simplify(AstNodeExpr* nodep, int resultWidth, unsigned externalOps, + VDouble0& reduction) { UASSERT_OBJ(1 <= resultWidth && resultWidth <= 64, nodep, "resultWidth out of range"); // Walk tree, gathering all terms referenced in expression @@ -673,7 +673,7 @@ public: // whether we have clean/dirty terms. visitor.m_varInfos appears in deterministic order, // so the optimized tree is deterministic as well. - std::vector termps; + std::vector termps; termps.reserve(visitor.m_varInfos.size() - 1); unsigned resultOps = 0; bool hasCleanTerm = false; @@ -683,7 +683,7 @@ public: if (!v) continue; // Skip nullptr at m_varInfos[0] if (v->hasConstResult()) { // If a constant term is known, we can either drop it or the whole tree is constant - AstNode* resultp = nullptr; + AstNodeExpr* resultp = nullptr; if (v->getConstResult()) { UASSERT_OBJ(visitor.isOrTree(), nodep, "Only OR tree can yield known 1 result"); @@ -715,10 +715,11 @@ public: } } - std::map> frozenNodes; // Group by FrozenNodeInfo + // Group by FrozenNodeInfo + std::map> frozenNodes; // Check if frozen terms are clean or not for (const auto& frozenInfo : visitor.m_frozenNodes) { - AstNode* const termp = frozenInfo.first; + AstNodeExpr* const termp = frozenInfo.first; // Comparison operators are clean if ((VN_IS(termp, Eq) || VN_IS(termp, Neq) || VN_IS(termp, Lt) || VN_IS(termp, Lte) || VN_IS(termp, Gt) || VN_IS(termp, Gte)) @@ -752,8 +753,8 @@ public: if (debug() >= 9) { // LCOV_EXCL_START cout << "Bitop tree considered: " << endl; - for (AstNode* const termp : termps) termp->dumpTree("Reduced term: "); - for (const std::pair& termp : visitor.m_frozenNodes) { + for (AstNodeExpr* const termp : termps) termp->dumpTree("Reduced term: "); + for (const std::pair& termp : visitor.m_frozenNodes) { termp.first->dumpTree("Frozen term with lsb " + std::to_string(termp.second.m_lsb) + " polarity " + std::to_string(termp.second.m_polarity) + ": "); @@ -767,8 +768,8 @@ public: // (all of which were zeroes) if (termps.empty() && visitor.m_frozenNodes.empty()) { reduction += visitor.m_ops; - AstNode* const resultp = needsFlip ? new AstConst{fl, AstConst::BitTrue{}} - : new AstConst{fl, AstConst::BitFalse{}}; + AstNodeExpr* const resultp = needsFlip ? new AstConst{fl, AstConst::BitTrue{}} + : new AstConst{fl, AstConst::BitFalse{}}; resultp->dtypeChgWidth(resultWidth, 1); return resultp; } @@ -783,7 +784,7 @@ public: reduction += visitor.m_ops - resultOps; // Reduction op to combine terms - const auto reduce = [&visitor, fl](AstNode* lhsp, AstNode* rhsp) -> AstNode* { + const auto reduce = [&visitor, fl](AstNodeExpr* lhsp, AstNodeExpr* rhsp) -> AstNodeExpr* { if (!lhsp) return rhsp; if (visitor.isAndTree()) { return new AstAnd{fl, lhsp, rhsp}; @@ -795,15 +796,15 @@ public: }; // Compute result by reducing all terms - AstNode* resultp = nullptr; - for (AstNode* const termp : termps) { // + AstNodeExpr* resultp = nullptr; + for (AstNodeExpr* const termp : termps) { // resultp = reduce(resultp, termp); } // Add any frozen terms to the reduction for (auto&& nodes : frozenNodes) { // nodes.second has same lsb and polarity - AstNode* termp = nullptr; - for (AstNode* const itemp : nodes.second) { + AstNodeExpr* termp = nullptr; + for (AstNodeExpr* const itemp : nodes.second) { termp = reduce(termp, itemp->unlinkFrBack()); } if (nodes.first.m_lsb > 0) { // LSB is not 0, so shiftR @@ -961,7 +962,7 @@ private: // When bool is casted to int, the value is either 0 or 1 AstConst* const constp = VN_AS(andp->lhsp(), Const); UASSERT_OBJ(constp && constp->isOne(), andp->lhsp(), "TRREEOPC must meet this condition"); - AstNode* const rhsp = andp->rhsp(); + AstNodeExpr* const rhsp = andp->rhsp(); AstCCast* ccastp = nullptr; const auto isEqOrNeq = [](AstNode* nodep) -> bool { return VN_IS(nodep, Eq) || VN_IS(nodep, Neq); }; @@ -999,7 +1000,7 @@ private: // Someday we'll sort the biops completely and this can be simplified // This often results from our simplified clock generation: // if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable)) - AstNode* ap; + AstNodeExpr* ap; AstNodeBiop* andp; if (VN_IS(nodep->lhsp(), And)) { andp = VN_AS(nodep->lhsp(), And); @@ -1011,7 +1012,7 @@ private: return false; } const AstNodeUniop* notp; - AstNode* cp; + AstNodeExpr* cp; if (VN_IS(andp->lhsp(), Not)) { notp = VN_AS(andp->lhsp(), Not); cp = andp->rhsp(); @@ -1021,7 +1022,7 @@ private: } else { return false; } - AstNode* const bp = notp->lhsp(); + AstNodeExpr* const bp = notp->lhsp(); if (!operandsSame(ap, bp)) return false; // Do it cp->unlinkFrBack(); @@ -1140,7 +1141,7 @@ private: return false; } - bool matchBitOpTree(AstNode* nodep) { + bool matchBitOpTree(AstNodeExpr* nodep) { if (nodep->widthMin() != 1) return false; if (!v3Global.opt.fConstBitOpTree()) return false; @@ -1277,8 +1278,8 @@ private: && nodep->lsbConst() == 0)) return false; if (debug() >= 9) nodep->dumpTree(cout, "SEL(BI)-in:"); - AstNode* const bilhsp = bip->lhsp()->unlinkFrBack(); - AstNode* const birhsp = bip->rhsp()->unlinkFrBack(); + AstNodeExpr* const bilhsp = bip->lhsp()->unlinkFrBack(); + AstNodeExpr* const birhsp = bip->rhsp()->unlinkFrBack(); bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst())); bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst())); if (debug() >= 9) bip->dumpTree(cout, "SEL(BI)-ou:"); @@ -1294,7 +1295,7 @@ private: && VN_IS(nodep->widthp(), Const))) { return false; } - AstNode* const ap = shiftp->lhsp(); + AstNodeExpr* const ap = shiftp->lhsp(); AstConst* const bp = VN_AS(shiftp->rhsp(), Const); AstConst* const lp = VN_AS(nodep->lsbp(), Const); if (bp->isWide() || bp->num().isFourState() || bp->num().isNegative() || lp->isWide() @@ -1321,7 +1322,7 @@ private: // would be incorrect. See also operandBiExtendConst AstExtend* const extendp = VN_CAST(nodep->rhsp(), Extend); if (!extendp) return false; - AstNode* const smallerp = extendp->lhsp(); + AstNodeExpr* const smallerp = extendp->lhsp(); const int subsize = smallerp->width(); AstConst* const constp = VN_CAST(nodep->lhsp(), Const); if (!constp) return false; @@ -1477,7 +1478,7 @@ private: const int rend = (rstart->toSInt() + rwidth->toSInt()); return (rend == lstart->toSInt()); } - bool ifMergeAdjacent(AstNode* lhsp, AstNode* rhsp) { + bool ifMergeAdjacent(AstNodeExpr* lhsp, AstNodeExpr* rhsp) { // called by concatmergeable to determine if {lhsp, rhsp} make sense if (!v3Global.opt.fAssemble()) return false; // opt disabled // two same varref @@ -1514,7 +1515,7 @@ private: if (rend == rfromp->width() && lstart->toSInt() == 0) return true; return false; } - bool concatMergeable(const AstNode* lhsp, const AstNode* rhsp, unsigned depth) { + bool concatMergeable(const AstNodeExpr* lhsp, const AstNodeExpr* rhsp, unsigned depth) { // determine if {a OP b, c OP d} => {a, c} OP {b, d} is advantageous if (!v3Global.opt.fAssemble()) return false; // opt disabled if (lhsp->type() != rhsp->type()) return false; @@ -1575,7 +1576,7 @@ private: VL_DO_DANGLING(replaceNum(nodep, val), nodep); } void replaceZero(AstNode* nodep) { VL_DO_DANGLING(replaceNum(nodep, 0), nodep); } - void replaceZeroChkPure(AstNode* nodep, AstNode* checkp) { + void replaceZeroChkPure(AstNode* nodep, AstNodeExpr* checkp) { // For example, "0 * n" -> 0 if n has no side effects // Else strength reduce it to 0 & n. // If ever change the operation note AstAnd rule specially ignores this created pattern @@ -1637,7 +1638,7 @@ private: // Replacement functions. // These all take a node and replace it with something else - void replaceWChild(AstNode* nodep, AstNode* childp) { + void replaceWChild(AstNode* nodep, AstNodeExpr* childp) { // NODE(..., CHILD(...)) -> CHILD(...) childp->unlinkFrBackWithNext(); // If replacing a SEL for example, the data type comes from the parent (is less wide). @@ -1646,7 +1647,7 @@ private: nodep->replaceWith(childp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } - void replaceWChildBool(AstNode* nodep, AstNode* childp) { + void replaceWChildBool(AstNode* nodep, AstNodeExpr* childp) { // NODE(..., CHILD(...)) -> REDOR(CHILD(...)) childp->unlinkFrBack(); if (childp->width1()) { @@ -1688,10 +1689,10 @@ private: // BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c) // BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c) // nodep->dumpTree(cout, " repAsvConst_old: "); - AstNode* const ap = nodep->lhsp(); + AstNodeExpr* const ap = nodep->lhsp(); AstNodeBiop* const rp = VN_AS(nodep->rhsp(), NodeBiop); - AstNode* const bp = rp->lhsp(); - AstNode* const cp = rp->rhsp(); + AstNodeExpr* const bp = rp->lhsp(); + AstNodeExpr* const cp = rp->rhsp(); ap->unlinkFrBack(); bp->unlinkFrBack(); cp->unlinkFrBack(); @@ -1706,9 +1707,9 @@ private: void replaceAsvLUp(AstNodeBiop* nodep) { // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop); - AstNode* const llp = lp->lhsp()->unlinkFrBack(); - AstNode* const lrp = lp->rhsp()->unlinkFrBack(); - AstNode* const rp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack(); + AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rp = nodep->rhsp()->unlinkFrBack(); nodep->lhsp(llp); nodep->rhsp(lp); lp->lhsp(lrp); @@ -1717,10 +1718,10 @@ private: } void replaceAsvRUp(AstNodeBiop* nodep) { // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) - AstNode* const lp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const lp = nodep->lhsp()->unlinkFrBack(); AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop); - AstNode* const rlp = rp->lhsp()->unlinkFrBack(); - AstNode* const rrp = rp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack(); + AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack(); nodep->lhsp(rlp); nodep->rhsp(rp); rp->lhsp(lp); @@ -1733,11 +1734,11 @@ private: // nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp // (Or/And may also be reversed) AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop); - AstNode* const llp = lp->lhsp()->unlinkFrBack(); - AstNode* const lrp = lp->rhsp()->unlinkFrBack(); + AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack(); + AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop); - AstNode* const rlp = rp->lhsp()->unlinkFrBack(); - AstNode* const rrp = rp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack(); + AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); if (operandsSame(llp, rlp)) { lp->lhsp(llp); @@ -1764,11 +1765,11 @@ private: // Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr) // (Or/And may also be reversed) AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop); - AstNode* const llp = lp->lhsp()->unlinkFrBack(); - AstNode* const lrp = lp->rhsp()->unlinkFrBack(); + AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack(); + AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop); - AstNode* const rlp = rp->lhsp()->unlinkFrBack(); - AstNode* const rrp = rp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack(); + AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); lp->lhsp(nodep); lp->rhsp(lrp); @@ -1803,10 +1804,10 @@ private: void replaceConcatMerge(AstConcat* nodep) { AstNodeBiop* const lp = VN_AS(nodep->lhsp(), NodeBiop); AstNodeBiop* const rp = VN_AS(nodep->rhsp(), NodeBiop); - AstNode* const llp = lp->lhsp()->cloneTree(false); - AstNode* const lrp = lp->rhsp()->cloneTree(false); - AstNode* const rlp = rp->lhsp()->cloneTree(false); - AstNode* const rrp = rp->rhsp()->cloneTree(false); + AstNodeExpr* const llp = lp->lhsp()->cloneTree(false); + AstNodeExpr* const lrp = lp->rhsp()->cloneTree(false); + AstNodeExpr* const rlp = rp->lhsp()->cloneTree(false); + AstNodeExpr* const rrp = rp->rhsp()->cloneTree(false); if (concatMergeable(lp, rp, 0)) { AstConcat* const newlp = new AstConcat(rlp->fileline(), llp, rlp); AstConcat* const newrp = new AstConcat(rrp->fileline(), lrp, rrp); @@ -1824,21 +1825,21 @@ private: nodep->v3fatalSrc("tried to merge two Concat which are not adjacent"); } } - void replaceExtend(AstNode* nodep, AstNode* arg0p) { + void replaceExtend(AstNode* nodep, AstNodeExpr* arg0p) { // -> EXTEND(nodep) // like a AstExtend{$rhsp}, but we need to set the width correctly from base node arg0p->unlinkFrBack(); - AstNode* const newp + AstNodeExpr* const newp = (VN_IS(nodep, ExtendS) - ? static_cast(new AstExtendS{nodep->fileline(), arg0p}) - : static_cast(new AstExtend{nodep->fileline(), arg0p})); + ? static_cast(new AstExtendS{nodep->fileline(), arg0p}) + : static_cast(new AstExtend{nodep->fileline(), arg0p})); newp->dtypeFrom(nodep); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replacePowShift(AstNodeBiop* nodep) { // Pow or PowS UINFO(5, "POW(2,b)->SHIFTL(1,b) " << nodep << endl); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstShiftL* const newp = new AstShiftL(nodep->fileline(), new AstConst(nodep->fileline(), 1), rhsp); newp->dtypeFrom(nodep); @@ -1849,7 +1850,7 @@ private: void replaceMulShift(AstMul* nodep) { // Mul, but not MulS as not simple shift UINFO(5, "MUL(2^n,b)->SHIFTL(b,n) " << nodep << endl); const int amount = VN_AS(nodep->lhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1 - AstNode* const opp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const opp = nodep->rhsp()->unlinkFrBack(); AstShiftL* const newp = new AstShiftL(nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); @@ -1859,7 +1860,7 @@ private: void replaceDivShift(AstDiv* nodep) { // Mul, but not MulS as not simple shift UINFO(5, "DIV(b,2^n)->SHIFTR(b,n) " << nodep << endl); const int amount = VN_AS(nodep->rhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1 - AstNode* const opp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const opp = nodep->lhsp()->unlinkFrBack(); AstShiftR* const newp = new AstShiftR(nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); @@ -1871,7 +1872,7 @@ private: const int amount = VN_AS(nodep->rhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1 V3Number mask(nodep, nodep->width()); mask.setMask(amount); - AstNode* const opp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const opp = nodep->lhsp()->unlinkFrBack(); AstAnd* const newp = new AstAnd(nodep->fileline(), opp, new AstConst(nodep->fileline(), mask)); newp->dtypeFrom(nodep); @@ -1884,9 +1885,9 @@ private: nodep->unlinkFrBack(&handle); AstNodeBiop* const lhsp = VN_AS(nodep->lhsp(), NodeBiop); lhsp->unlinkFrBack(); - AstNode* const shiftp = nodep->rhsp()->unlinkFrBack(); - AstNode* const ap = lhsp->lhsp()->unlinkFrBack(); - AstNode* const bp = lhsp->rhsp()->unlinkFrBack(); + AstNodeExpr* const shiftp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const ap = lhsp->lhsp()->unlinkFrBack(); + AstNodeExpr* const bp = lhsp->rhsp()->unlinkFrBack(); AstNodeBiop* const shift1p = nodep; AstNodeBiop* const shift2p = nodep->cloneTree(true); shift1p->lhsp(ap); @@ -1904,9 +1905,9 @@ private: if (debug() >= 9) nodep->dumpTree(cout, " repShiftShift_old: "); AstNodeBiop* const lhsp = VN_AS(nodep->lhsp(), NodeBiop); lhsp->unlinkFrBack(); - AstNode* const ap = lhsp->lhsp()->unlinkFrBack(); - AstNode* const shift1p = lhsp->rhsp()->unlinkFrBack(); - AstNode* const shift2p = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const ap = lhsp->lhsp()->unlinkFrBack(); + AstNodeExpr* const shift1p = lhsp->rhsp()->unlinkFrBack(); + AstNodeExpr* const shift2p = nodep->rhsp()->unlinkFrBack(); // Shift1p and shift2p may have different sizes, both are // self-determined so sum with infinite width if (nodep->type() == lhsp->type()) { @@ -1927,7 +1928,7 @@ private: const int newshift = shift1 + shift2; VL_DO_DANGLING(shift1p->deleteTree(), shift1p); VL_DO_DANGLING(shift2p->deleteTree(), shift2p); - AstNode* newp; + AstNodeExpr* newp; V3Number mask1(nodep, nodep->width()); V3Number ones(nodep, nodep->width()); ones.setMask(nodep->width()); @@ -1999,9 +2000,9 @@ private: UINFO(4, " && " << nextp << endl); // nodep->dumpTree(cout, "comb1: "); // nextp->dumpTree(cout, "comb2: "); - AstNode* const rhs1p = nodep->rhsp()->unlinkFrBack(); - AstNode* const rhs2p = nextp->rhsp()->unlinkFrBack(); - AstNode* newp; + AstNodeExpr* const rhs1p = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const rhs2p = nextp->rhsp()->unlinkFrBack(); + AstNodeAssign* newp; if (lsbFirstAssign) { newp = nodep->cloneType(new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(), sel1p->lsbConst(), sel1p->width() + sel2p->width()), @@ -2072,11 +2073,11 @@ private: } if (debug() >= 9) nodep->dumpTree(cout, " Ass_old: "); // Unlink the stuff - AstNode* const lc1p = VN_AS(nodep->lhsp(), Concat)->lhsp()->unlinkFrBack(); - AstNode* const lc2p = VN_AS(nodep->lhsp(), Concat)->rhsp()->unlinkFrBack(); - AstNode* const conp = VN_AS(nodep->lhsp(), Concat)->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* const rhs2p = rhsp->cloneTree(false); + AstNodeExpr* const lc1p = VN_AS(nodep->lhsp(), Concat)->lhsp()->unlinkFrBack(); + AstNodeExpr* const lc2p = VN_AS(nodep->lhsp(), Concat)->rhsp()->unlinkFrBack(); + AstNodeExpr* const conp = VN_AS(nodep->lhsp(), Concat)->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const rhs2p = rhsp->cloneTree(false); // Calc widths const int lsb2 = 0; const int msb2 = lsb2 + lc2p->width() - 1; @@ -2090,8 +2091,8 @@ private: //*** Not cloneTree; just one node. AstNodeAssign* newp = nullptr; if (!need_temp) { - AstNodeAssign* const asn1ap = VN_AS(nodep->cloneType(lc1p, sel1p), NodeAssign); - AstNodeAssign* const asn2ap = VN_AS(nodep->cloneType(lc2p, sel2p), NodeAssign); + AstNodeAssign* const asn1ap = nodep->cloneType(lc1p, sel1p); + AstNodeAssign* const asn2ap = nodep->cloneType(lc2p, sel2p); asn1ap->dtypeFrom(sel1p); asn2ap->dtypeFrom(sel2p); newp = AstNode::addNext(newp, asn1ap); @@ -2103,29 +2104,21 @@ private: // We could create just one temp variable, but we'll get better optimization // if we make one per term. AstVar* const temp1p - = new AstVar(sel1p->fileline(), VVarType::BLOCKTEMP, - m_concswapNames.get(sel1p), VFlagLogicPacked(), msb1 - lsb1 + 1); + = new AstVar{sel1p->fileline(), VVarType::BLOCKTEMP, + m_concswapNames.get(sel1p), VFlagLogicPacked(), msb1 - lsb1 + 1}; AstVar* const temp2p - = new AstVar(sel2p->fileline(), VVarType::BLOCKTEMP, - m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1); + = new AstVar{sel2p->fileline(), VVarType::BLOCKTEMP, + m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1}; m_modp->addStmtsp(temp1p); m_modp->addStmtsp(temp2p); - AstNodeAssign* const asn1ap - = VN_AS(nodep->cloneType( - new AstVarRef(sel1p->fileline(), temp1p, VAccess::WRITE), sel1p), - NodeAssign); - AstNodeAssign* const asn2ap - = VN_AS(nodep->cloneType( - new AstVarRef(sel2p->fileline(), temp2p, VAccess::WRITE), sel2p), - NodeAssign); - AstNodeAssign* const asn1bp - = VN_AS(nodep->cloneType( - lc1p, new AstVarRef(sel1p->fileline(), temp1p, VAccess::READ)), - NodeAssign); - AstNodeAssign* const asn2bp - = VN_AS(nodep->cloneType( - lc2p, new AstVarRef(sel2p->fileline(), temp2p, VAccess::READ)), - NodeAssign); + AstNodeAssign* const asn1ap = nodep->cloneType( + new AstVarRef{sel1p->fileline(), temp1p, VAccess::WRITE}, sel1p); + AstNodeAssign* const asn2ap = nodep->cloneType( + new AstVarRef{sel2p->fileline(), temp2p, VAccess::WRITE}, sel2p); + AstNodeAssign* const asn1bp = nodep->cloneType( + lc1p, new AstVarRef{sel1p->fileline(), temp1p, VAccess::READ}); + AstNodeAssign* const asn2bp = nodep->cloneType( + lc2p, new AstVarRef{sel2p->fileline(), temp2p, VAccess::READ}); asn1ap->dtypeFrom(temp1p); asn1bp->dtypeFrom(temp1p); asn2ap->dtypeFrom(temp2p); @@ -2147,9 +2140,9 @@ private: // The right-streaming operator on rhs of assignment does not // change the order of bits. Eliminate stream but keep its lhsp // Unlink the stuff - AstNode* const srcp = VN_AS(nodep->rhsp(), StreamR)->lhsp()->unlinkFrBack(); + AstNodeExpr* const srcp = VN_AS(nodep->rhsp(), StreamR)->lhsp()->unlinkFrBack(); AstNode* const sizep = VN_AS(nodep->rhsp(), StreamR)->rhsp()->unlinkFrBack(); - AstNode* const streamp = VN_AS(nodep->rhsp(), StreamR)->unlinkFrBack(); + AstNodeExpr* const streamp = VN_AS(nodep->rhsp(), StreamR)->unlinkFrBack(); nodep->rhsp(srcp); // Cleanup VL_DO_DANGLING(sizep->deleteTree(), sizep); @@ -2161,9 +2154,9 @@ private: const int dWidth = VN_AS(nodep->lhsp(), StreamL)->lhsp()->width(); const int sWidth = nodep->rhsp()->width(); // Unlink the stuff - AstNode* const dstp = VN_AS(nodep->lhsp(), StreamL)->lhsp()->unlinkFrBack(); - AstNode* streamp = VN_AS(nodep->lhsp(), StreamL)->unlinkFrBack(); - AstNode* const srcp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const dstp = VN_AS(nodep->lhsp(), StreamL)->lhsp()->unlinkFrBack(); + AstNodeExpr* streamp = VN_AS(nodep->lhsp(), StreamL)->unlinkFrBack(); + AstNodeExpr* const srcp = nodep->rhsp()->unlinkFrBack(); // Connect the rhs to the stream operator and update its width VN_AS(streamp, StreamL)->lhsp(srcp); streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED); @@ -2182,10 +2175,10 @@ private: const int dWidth = VN_AS(nodep->lhsp(), StreamR)->lhsp()->width(); const int sWidth = nodep->rhsp()->width(); // Unlink the stuff - AstNode* const dstp = VN_AS(nodep->lhsp(), StreamR)->lhsp()->unlinkFrBack(); + AstNodeExpr* const dstp = VN_AS(nodep->lhsp(), StreamR)->lhsp()->unlinkFrBack(); AstNode* const sizep = VN_AS(nodep->lhsp(), StreamR)->rhsp()->unlinkFrBack(); - AstNode* const streamp = VN_AS(nodep->lhsp(), StreamR)->unlinkFrBack(); - AstNode* srcp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const streamp = VN_AS(nodep->lhsp(), StreamR)->unlinkFrBack(); + AstNodeExpr* srcp = nodep->rhsp()->unlinkFrBack(); if (sWidth > dWidth) { srcp = new AstSel(streamp->fileline(), srcp, sWidth - dWidth, dWidth); } @@ -2218,7 +2211,8 @@ private: void replaceBoolShift(AstNode* nodep) { if (debug() >= 9) nodep->dumpTree(cout, " bshft_old: "); AstConst* const andConstp = VN_AS(VN_AS(nodep, And)->lhsp(), Const); - AstNode* const fromp = VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR)->lhsp()->unlinkFrBack(); + AstNodeExpr* const fromp + = VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR)->lhsp()->unlinkFrBack(); AstConst* const shiftConstp = VN_AS(VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR)->rhsp(), Const); V3Number val(andConstp, andConstp->width()); @@ -2296,8 +2290,8 @@ private: void swapSides(AstNodeBiCom* nodep) { // COMMUTATIVE({a},CONST) -> COMMUTATIVE(CONST,{a}) // This simplifies later optimizations - AstNode* const lhsp = nodep->lhsp()->unlinkFrBackWithNext(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBackWithNext(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBackWithNext(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBackWithNext(); nodep->lhsp(rhsp); nodep->rhsp(lhsp); iterate(nodep); // Again? @@ -2333,8 +2327,8 @@ private: const AstConcat* const bcConcp = VN_CAST(nodep->rhsp(), Concat); if (!abConcp && !bcConcp) return 0; if (bcConcp) { - AstNode* const ap = nodep->lhsp(); - AstNode* const bp = bcConcp->lhsp(); + AstNodeExpr* const ap = nodep->lhsp(); + AstNodeExpr* const bp = bcConcp->lhsp(); // If a+b == 32,64,96 etc, then we want to have a+b together on LHS if (VL_BITBIT_I(ap->width() + bp->width()) == 0) return 2; // Transform 2: to abConc } else { // abConcp @@ -2352,11 +2346,11 @@ private: // like that, so on 32 bit boundaries, we'll do the opposite form. UINFO(4, "Move concat: " << nodep << endl); if (operandConcatMove(nodep) > 1) { - AstNode* const ap = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const ap = nodep->lhsp()->unlinkFrBack(); AstConcat* const bcConcp = VN_AS(nodep->rhsp(), Concat); bcConcp->unlinkFrBack(); - AstNode* const bp = bcConcp->lhsp()->unlinkFrBack(); - AstNode* const cp = bcConcp->rhsp()->unlinkFrBack(); + AstNodeExpr* const bp = bcConcp->lhsp()->unlinkFrBack(); + AstNodeExpr* const cp = bcConcp->rhsp()->unlinkFrBack(); AstConcat* const abConcp = new AstConcat(bcConcp->fileline(), ap, bp); nodep->lhsp(abConcp); nodep->rhsp(cp); @@ -2367,9 +2361,9 @@ private: } else { AstConcat* const abConcp = VN_AS(nodep->lhsp(), Concat); abConcp->unlinkFrBack(); - AstNode* const ap = abConcp->lhsp()->unlinkFrBack(); - AstNode* const bp = abConcp->rhsp()->unlinkFrBack(); - AstNode* const cp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const ap = abConcp->lhsp()->unlinkFrBack(); + AstNodeExpr* const bp = abConcp->rhsp()->unlinkFrBack(); + AstNodeExpr* const cp = nodep->rhsp()->unlinkFrBack(); AstConcat* const bcConcp = new AstConcat(abConcp->fileline(), bp, cp); nodep->lhsp(ap); nodep->rhsp(bcConcp); @@ -2393,8 +2387,8 @@ private: void replaceLogEq(AstLogEq* nodep) { // LOGEQ(a,b) => AstLogAnd{AstLogOr{AstLogNot{a},b},AstLogOr{AstLogNot{b},a}} - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); // Do exactly as IEEE says, might result in extra terms, so in future may do differently AstLogAnd* const newp = new AstLogAnd( nodep->fileline(), @@ -2410,13 +2404,13 @@ private: void replaceSelSel(AstSel* nodep) { // SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d) AstSel* const belowp = VN_AS(nodep->fromp(), Sel); - AstNode* const fromp = belowp->fromp()->unlinkFrBack(); - AstNode* const widthp = nodep->widthp()->unlinkFrBack(); - AstNode* const lsb1p = nodep->lsbp()->unlinkFrBack(); - AstNode* const lsb2p = belowp->lsbp()->unlinkFrBack(); + AstNodeExpr* const fromp = belowp->fromp()->unlinkFrBack(); + AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack(); + AstNodeExpr* const lsb1p = nodep->lsbp()->unlinkFrBack(); + AstNodeExpr* const lsb2p = belowp->lsbp()->unlinkFrBack(); // Eliminate lower range UINFO(4, "Elim Lower range: " << nodep << endl); - AstNode* newlsbp; + AstNodeExpr* newlsbp; if (VN_IS(lsb1p, Const) && VN_IS(lsb2p, Const)) { newlsbp = new AstConst(lsb1p->fileline(), VN_AS(lsb1p, Const)->toUInt() + VN_AS(lsb2p, Const)->toUInt()); @@ -2427,13 +2421,13 @@ private: // potentially smaller lsb1p's width, but don't insert a redundant AstExtend. // Note that due to some sloppiness in earlier passes, lsb1p might actually be wider, // so extend to the wider type. - AstNode* const widep = lsb1p->width() > lsb2p->width() ? lsb1p : lsb2p; - AstNode* const lhsp = widep->width() > lsb2p->width() - ? new AstExtend{lsb2p->fileline(), lsb2p} - : lsb2p; - AstNode* const rhsp = widep->width() > lsb1p->width() - ? new AstExtend{lsb1p->fileline(), lsb1p} - : lsb1p; + AstNodeExpr* const widep = lsb1p->width() > lsb2p->width() ? lsb1p : lsb2p; + AstNodeExpr* const lhsp = widep->width() > lsb2p->width() + ? new AstExtend{lsb2p->fileline(), lsb2p} + : lsb2p; + AstNodeExpr* const rhsp = widep->width() > lsb1p->width() + ? new AstExtend{lsb1p->fileline(), lsb1p} + : lsb1p; lhsp->dtypeFrom(widep); rhsp->dtypeFrom(widep); newlsbp = new AstAdd{lsb1p->fileline(), lhsp, rhsp}; @@ -2447,8 +2441,8 @@ private: void replaceSelConcat(AstSel* nodep) { // SEL(CONCAT(a,b),c,d) => SEL(a or b, . .) AstConcat* const conp = VN_AS(nodep->fromp(), Concat); - AstNode* const conLhsp = conp->lhsp(); - AstNode* const conRhsp = conp->rhsp(); + AstNodeExpr* const conLhsp = conp->lhsp(); + AstNodeExpr* const conRhsp = conp->rhsp(); if (static_cast(nodep->lsbConst()) >= conRhsp->width()) { conLhsp->unlinkFrBack(); AstSel* const newp @@ -2478,10 +2472,10 @@ private: // SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long // as SEL's width <= b's width AstReplicate* const repp = VN_AS(nodep->fromp(), Replicate); - AstNode* const fromp = repp->lhsp(); + AstNodeExpr* const fromp = repp->lhsp(); AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const); if (!lsbp) return false; - AstNode* const widthp = nodep->widthp(); + AstNodeExpr* const widthp = nodep->widthp(); if (!VN_IS(widthp, Const)) return false; UASSERT_OBJ(fromp->width(), nodep, "Not widthed"); if ((lsbp->toUInt() / fromp->width()) @@ -2502,7 +2496,7 @@ private: bool operandRepRep(AstReplicate* nodep) { // REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2)) AstReplicate* const rep2p = VN_AS(nodep->lhsp(), Replicate); - AstNode* const from2p = rep2p->lhsp(); + AstNodeExpr* const from2p = rep2p->lhsp(); AstConst* const cnt1p = VN_CAST(nodep->rhsp(), Const); if (!cnt1p) return false; AstConst* const cnt2p = VN_CAST(rep2p->rhsp(), Const); @@ -2523,9 +2517,9 @@ private: // CONCAT(REP(fromp,cnt1),fromp) -> REPLICATE(fromp,cnt1+1) // CONCAT(fromp,REP(fromp,cnt1)) -> REPLICATE(fromp,1+cnt1) // CONCAT(REP(fromp,cnt1),REP(fromp,cnt2)) -> REPLICATE(fromp,cnt1+cnt2) - AstNode* from1p = nodep->lhsp(); + AstNodeExpr* from1p = nodep->lhsp(); uint32_t cnt1 = 1; - AstNode* from2p = nodep->rhsp(); + AstNodeExpr* from2p = nodep->rhsp(); uint32_t cnt2 = 1; if (VN_IS(from1p, Replicate)) { AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->rhsp(), Const); @@ -2552,11 +2546,11 @@ private: // SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit)) AstNodeBiop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeBiop); UASSERT_OBJ(fromp, nodep, "Called on non biop"); - AstNode* const lsbp = nodep->lsbp()->unlinkFrBack(); - AstNode* const widthp = nodep->widthp()->unlinkFrBack(); + AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack(); + AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack(); // - AstNode* const bilhsp = fromp->lhsp()->unlinkFrBack(); - AstNode* const birhsp = fromp->rhsp()->unlinkFrBack(); + AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack(); + AstNodeExpr* const birhsp = fromp->rhsp()->unlinkFrBack(); // fromp->lhsp( new AstSel(nodep->fileline(), bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true))); @@ -2569,10 +2563,10 @@ private: // SEL(NOT(a),1,bit) => NOT(SEL(a,bit)) AstNodeUniop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeUniop); UASSERT_OBJ(fromp, nodep, "Called on non biop"); - AstNode* const lsbp = nodep->lsbp()->unlinkFrBack(); - AstNode* const widthp = nodep->widthp()->unlinkFrBack(); + AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack(); + AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack(); // - AstNode* const bilhsp = fromp->lhsp()->unlinkFrBack(); + AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack(); // fromp->lhsp(new AstSel(nodep->fileline(), bilhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); @@ -2901,7 +2895,7 @@ private: // ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) ) UINFO(4, "constAssignW " << nodep << endl); // Make a initial assignment - AstNode* const exprp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const exprp = nodep->rhsp()->unlinkFrBack(); varrefp->unlinkFrBack(); AstInitial* const newinitp = new AstInitial( nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp)); @@ -2957,7 +2951,7 @@ private: } } else if (!afterComment(nodep->thensp())) { UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl); - AstNode* const condp = nodep->condp(); + AstNodeExpr* const condp = nodep->condp(); AstNode* const elsesp = nodep->elsesp(); condp->unlinkFrBackWithNext(); elsesp->unlinkFrBackWithNext(); @@ -2971,7 +2965,7 @@ private: || VN_IS(nodep->condp(), LogNot)) && nodep->thensp() && nodep->elsesp()) { UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl); - AstNode* const condp + AstNodeExpr* const condp = VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext(); AstNode* const thensp = nodep->thensp()->unlinkFrBackWithNext(); AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext(); @@ -2986,9 +2980,9 @@ private: 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 = thensp->rhsp()->unlinkFrBack(); - AstNode* const falsep = elsesp->rhsp()->unlinkFrBack(); + AstNodeExpr* const condp = nodep->condp()->unlinkFrBack(); + AstNodeExpr* const truep = thensp->rhsp()->unlinkFrBack(); + AstNodeExpr* const falsep = elsesp->rhsp()->unlinkFrBack(); thensp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); nodep->replaceWith(thensp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -2997,9 +2991,9 @@ private: && operandIfIf(nodep)) { UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl); AstNodeIf* const lowerIfp = VN_AS(nodep->thensp(), NodeIf); - AstNode* const condp = nodep->condp()->unlinkFrBack(); + AstNodeExpr* const condp = nodep->condp()->unlinkFrBack(); AstNode* const lowerThensp = lowerIfp->thensp()->unlinkFrBackWithNext(); - AstNode* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext(); + AstNodeExpr* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext(); nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp)); lowerIfp->replaceWith(lowerThensp); VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp); @@ -3355,7 +3349,7 @@ private: // 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, $thenp, $elsep}", "AstCond{$condp->op1p(), $elsep, $thenp}"); + TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->castNot()->lhsp(), $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 @@ -3386,36 +3380,36 @@ private: TREEOP1("AstLt {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)"); TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)"); // Two level bubble pushing - TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==VN_AS($lhsp,,Not)->lhsp()->width()}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x - TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // LOGNOT(LOGNOT(x))->x - TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); - TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); + TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==VN_AS($lhsp,,Not)->lhsp()->width()}", "replaceWChild(nodep, $lhsp->castNot()->lhsp())"); // NOT(NOT(x))->x + TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->castLogNot()->lhsp())"); // LOGNOT(LOGNOT(x))->x + TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase{$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild{$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}"); + TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}"); + TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}"); // Not common, but avoids compiler warnings about over shifting TREEOP ("AstShiftL{operandHugeShiftL(nodep)}", "replaceZero(nodep)"); TREEOP ("AstShiftR{operandHugeShiftR(nodep)}", "replaceZero(nodep)"); diff --git a/src/V3Const.h b/src/V3Const.h index ada396efd..8cabc60d6 100644 --- a/src/V3Const.h +++ b/src/V3Const.h @@ -20,14 +20,16 @@ #include "config_build.h" #include "verilatedos.h" -class AstNetlist; -class AstNode; +#include "V3Ast.h" //============================================================================ class V3Const final { public: static AstNode* constifyParamsEdit(AstNode* nodep); + static AstNodeExpr* constifyParamsEdit(AstNodeExpr* exprp) { + return VN_AS(constifyParamsEdit(static_cast(exprp)), NodeExpr); + } static AstNode* constifyGenerateParamsEdit(AstNode* nodep); // Only do constant pushing, without removing dead logic static void constifyAllLive(AstNetlist* nodep); @@ -40,9 +42,15 @@ public: // Only the current node and lower // Return new node that may have replaced nodep static AstNode* constifyEditCpp(AstNode* nodep); + static AstNodeExpr* constifyEditCpp(AstNodeExpr* exprp) { + return VN_AS(constifyEditCpp(static_cast(exprp)), NodeExpr); + } // Only the current node and lower // Return new node that may have replaced nodep static AstNode* constifyEdit(AstNode* nodep); + static AstNodeExpr* constifyEdit(AstNodeExpr* exprp) { + return VN_AS(constifyEdit(static_cast(exprp)), NodeExpr); + } // Only the current node and lower, with special SenTree optimization // Return new node that may have replaced nodep static AstNode* constifyExpensiveEdit(AstNode* nodep); diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 5dfb2f878..bd9d68927 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -47,9 +47,9 @@ private: struct ToggleEnt { const string m_comment; // Comment for coverage dump - AstNode* m_varRefp; // How to get to this element - AstNode* m_chgRefp; // How to get to this element - ToggleEnt(const string& comment, AstNode* vp, AstNode* cp) + AstNodeExpr* m_varRefp; // How to get to this element + AstNodeExpr* m_chgRefp; // How to get to this element + ToggleEnt(const string& comment, AstNodeExpr* vp, AstNodeExpr* cp) : m_comment{comment} , m_varRefp{vp} , m_chgRefp{cp} {} diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index db5a07182..6418f7f20 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -215,12 +215,12 @@ private: } } - AstNode* createDlyOnSet(AstAssignDly* nodep, AstNode* lhsp) { + AstNodeExpr* createDlyOnSet(AstAssignDly* nodep, AstNodeExpr* lhsp) { // Create delayed assignment // See top of this file for transformation // Return the new LHS for the assignment, Null = unlink // Find selects - AstNode* newlhsp = nullptr; // nullptr = unlink old assign + AstNodeExpr* newlhsp = nullptr; // nullptr = unlink old assign const AstSel* bitselp = nullptr; AstArraySel* arrayselp = nullptr; AstVarRef* varrefp = nullptr; @@ -242,10 +242,10 @@ private: UINFO(4, "AssignDlyOnSet: " << nodep << endl); } //=== Dimensions: __Vdlyvdim__ - std::deque dimvalp; // Assignment value for each dimension of assignment + std::deque dimvalp; // Assignment value for each dimension of assignment AstNode* dimselp = arrayselp; for (; VN_IS(dimselp, ArraySel); dimselp = VN_AS(dimselp, ArraySel)->fromp()) { - AstNode* const valp = VN_AS(dimselp, ArraySel)->bitp()->unlinkFrBack(); + AstNodeExpr* const valp = VN_AS(dimselp, ArraySel)->bitp()->unlinkFrBack(); dimvalp.push_front(valp); } if (dimselp) varrefp = VN_AS(dimselp, VarRef); @@ -255,9 +255,9 @@ private: const AstVar* const oldvarp = varrefp->varp(); const int modVecNum = m_scopeVecMap[varrefp->varScopep()]++; // - std::deque dimreadps; // Read value for each dimension of assignment + std::deque dimreadps; // Read value for each dimension of assignment for (unsigned dimension = 0; dimension < dimvalp.size(); dimension++) { - AstNode* const dimp = dimvalp[dimension]; + AstNodeExpr* const dimp = dimvalp[dimension]; if (VN_IS(dimp, Const)) { // bit = const, can just use it dimreadps.push_front(dimp); } else { @@ -274,9 +274,9 @@ private: } // //=== Bitselect: __Vdlyvlsb__ - AstNode* bitreadp = nullptr; // Code to read Vdlyvlsb + AstNodeExpr* bitreadp = nullptr; // Code to read Vdlyvlsb if (bitselp) { - AstNode* const lsbvaluep = bitselp->lsbp()->unlinkFrBack(); + AstNodeExpr* const lsbvaluep = bitselp->lsbp()->unlinkFrBack(); if (VN_IS(bitselp->fromp(), Const)) { // vlsb = constant, can just push constant into where we use it bitreadp = lsbvaluep; @@ -294,7 +294,7 @@ private: } // //=== Value: __Vdlyvval__ - AstNode* valreadp; // Code to read Vdlyvval + AstNodeExpr* valreadp; // Code to read Vdlyvval if (VN_IS(nodep->rhsp(), Const)) { // vval = constant, can just push constant into where we use it valreadp = nodep->rhsp()->unlinkFrBack(); @@ -342,7 +342,7 @@ private: // This ensures that multiple assignments to the same memory will result // in correctly ordered code - the last assignment must be last. // It also has the nice side effect of assisting cache locality. - AstNode* selectsp = varrefp; + AstNodeExpr* selectsp = varrefp; for (int dimension = int(dimreadps.size()) - 1; dimension >= 0; --dimension) { selectsp = new AstArraySel(nodep->fileline(), selectsp, dimreadps[dimension]); } @@ -519,8 +519,8 @@ private: || (VN_IS(nodep->lhsp(), Sel) && VN_IS(VN_AS(nodep->lhsp(), Sel)->fromp(), ArraySel)); if (m_procp->isSuspendable() || isArray) { - AstNode* const lhsp = nodep->lhsp(); - AstNode* const newlhsp = createDlyOnSet(nodep, lhsp); + AstNodeExpr* const lhsp = nodep->lhsp(); + AstNodeExpr* const newlhsp = createDlyOnSet(nodep, lhsp); if (m_inLoop && isArray) { nodep->v3warn(BLKLOOPINIT, "Unsupported: Delayed assignment to array inside for " "loops (non-delayed is ok - see docs)"); diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index fa1c31ea5..a9644165b 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -52,7 +52,7 @@ private: // METHODS - void createDeepTemp(AstNode* nodep) { + void createDeepTemp(AstNodeExpr* nodep) { UINFO(6, " Deep " << nodep << endl); // if (debug() >= 9) nodep->dumpTree(cout, "deep:"); AstVar* const varp = new AstVar{nodep->fileline(), VVarType::STMTTEMP, diff --git a/src/V3DfgDfgToAst.cpp b/src/V3DfgDfgToAst.cpp index 315088dec..9075858d5 100644 --- a/src/V3DfgDfgToAst.cpp +++ b/src/V3DfgDfgToAst.cpp @@ -299,7 +299,7 @@ class DfgToAstVisitor final : DfgVisitor { }); } - void addResultEquation(FileLine* flp, AstNode* lhsp, AstNode* rhsp) { + void addResultEquation(FileLine* flp, AstNodeExpr* lhsp, AstNodeExpr* rhsp) { m_modp->addStmtsp(new AstAssignW{flp, lhsp, rhsp}); ++m_ctx.m_resultEquations; } diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index d67b05d5a..9bf955dde 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -92,17 +92,19 @@ private: nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } - static AstNode* newWordAssign(AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) { + static AstNode* newWordAssign(AstNodeAssign* placep, int word, AstNodeExpr* lhsp, + AstNodeExpr* rhsp) { FileLine* const fl = placep->fileline(); return new AstAssign{fl, new AstWordSel{fl, lhsp->cloneTree(true), new AstConst{fl, static_cast(word)}}, rhsp}; } - static void addWordAssign(AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) { + static void addWordAssign(AstNodeAssign* placep, int word, AstNodeExpr* lhsp, + AstNodeExpr* rhsp) { insertBefore(placep, newWordAssign(placep, word, lhsp, rhsp)); } - static void addWordAssign(AstNodeAssign* placep, int word, AstNode* rhsp) { + static void addWordAssign(AstNodeAssign* placep, int word, AstNodeExpr* rhsp) { addWordAssign(placep, word, placep->lhsp(), rhsp); } @@ -117,7 +119,7 @@ private: if (nodep->op4p()) fixCloneLvalue(nodep->op4p()); } - static AstNode* newAstWordSelClone(AstNode* nodep, int word) { + static AstNodeExpr* newAstWordSelClone(AstNodeExpr* nodep, int word) { // Get the specified word number from a wide array // Or, if it's a long/quad, do appropriate conversion to wide // Concat may pass negative word numbers, that means it wants a zero @@ -126,11 +128,11 @@ private: return new AstWordSel{fl, nodep->cloneTree(true), new AstConst{fl, static_cast(word)}}; } else if (nodep->isQuad() && word == 0) { - AstNode* const quadfromp = nodep->cloneTree(true); + AstNodeExpr* const quadfromp = nodep->cloneTree(true); quadfromp->dtypeSetBitUnsized(VL_QUADSIZE, quadfromp->widthMin(), VSigning::UNSIGNED); return new AstCCast{fl, quadfromp, VL_EDATASIZE}; } else if (nodep->isQuad() && word == 1) { - AstNode* const quadfromp = nodep->cloneTree(true); + AstNodeExpr* const quadfromp = nodep->cloneTree(true); quadfromp->dtypeSetBitUnsized(VL_QUADSIZE, quadfromp->widthMin(), VSigning::UNSIGNED); return new AstCCast{ fl, new AstShiftR{fl, quadfromp, new AstConst{fl, VL_EDATASIZE}, VL_EDATASIZE}, @@ -142,16 +144,16 @@ private: } } - static AstNode* newWordGrabShift(FileLine* fl, int word, AstNode* lhsp, int shift) { + static AstNodeExpr* newWordGrabShift(FileLine* fl, int word, AstNodeExpr* lhsp, int shift) { // Extract the expression to grab the value for the specified word, if it's the shift // of shift bits from lhsp - AstNode* newp; + AstNodeExpr* newp; // Negative word numbers requested for lhs when it's "before" what we want. // We get a 0 then. const int othword = word - shift / VL_EDATASIZE; - AstNode* const llowp = newAstWordSelClone(lhsp, othword); + AstNodeExpr* const llowp = newAstWordSelClone(lhsp, othword); if (const int loffset = VL_BITBIT_E(shift)) { - AstNode* const lhip = newAstWordSelClone(lhsp, othword - 1); + AstNodeExpr* const lhip = newAstWordSelClone(lhsp, othword - 1); const int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword newp = new AstOr{ fl, @@ -170,8 +172,8 @@ private: return newp; } - static AstNode* newWordSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, - uint32_t wordOffset = 0) { + static AstNodeExpr* newWordSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* lsbp, + uint32_t wordOffset = 0) { // Return equation to get the VL_BITWORD of a constant or non-constant UASSERT_OBJ(fromp->isWide(), fromp, "Only need AstWordSel on wide from's"); if (wordOffset >= static_cast(fromp->widthWords())) { @@ -181,7 +183,7 @@ private: // AstCondBound is protecting above this node. return new AstConst{fl, AstConst::SizedEData(), 0}; } else { - AstNode* wordp; + AstNodeExpr* wordp; FileLine* const lfl = lsbp->fileline(); if (VN_IS(lsbp, Const)) { wordp = new AstConst{lfl, wordOffset + VL_BITWORD_E(VN_AS(lsbp, Const)->toUInt())}; @@ -197,7 +199,7 @@ private: } } - static AstNode* dropCondBound(AstNode* nodep) { + static AstNodeExpr* dropCondBound(AstNodeExpr* nodep) { // Experimental only... // If there's a CONDBOUND safety to keep arrays in bounds, // we're going to AND it to a value that always fits inside a @@ -208,7 +210,7 @@ private: return nodep; } - static AstNode* newSelBitBit(AstNode* lsbp) { + static AstNodeExpr* newSelBitBit(AstNodeExpr* lsbp) { // Return equation to get the VL_BITBIT of a constant or non-constant FileLine* const fl = lsbp->fileline(); if (VN_IS(lsbp, Const)) { @@ -320,8 +322,8 @@ private: if (nodep->isWide()) { // See under ASSIGN(EXTEND) } else { - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* newp = lhsp; + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* newp = lhsp; if (nodep->isQuad()) { if (lhsp->isQuad()) { lhsp->dtypeFrom(nodep); // Just mark it, else nop @@ -359,28 +361,29 @@ private: FileLine* const nfl = nodep->fileline(); FileLine* const lfl = nodep->lsbp()->fileline(); FileLine* const ffl = nodep->fromp()->fileline(); - AstNode* lowwordp = newWordSel(ffl, nodep->fromp()->cloneTree(true), nodep->lsbp()); + AstNodeExpr* lowwordp + = newWordSel(ffl, nodep->fromp()->cloneTree(true), nodep->lsbp()); if (nodep->isQuad() && !lowwordp->isQuad()) { lowwordp = new AstCCast{nfl, lowwordp, nodep}; } - AstNode* const lowp + AstNodeExpr* const lowp = new AstShiftR{nfl, lowwordp, newSelBitBit(nodep->lsbp()), nodep->width()}; // If > 1 bit, we might be crossing the word boundary - AstNode* midp = nullptr; + AstNodeExpr* midp = nullptr; if (nodep->widthConst() > 1) { const uint32_t midMsbOffset = std::min(nodep->widthConst(), VL_EDATASIZE) - 1; - AstNode* const midMsbp = new AstAdd{lfl, new AstConst{lfl, midMsbOffset}, - nodep->lsbp()->cloneTree(false)}; - AstNode* midwordp = // SEL(from,[midwordnum]) + AstNodeExpr* const midMsbp = new AstAdd{lfl, new AstConst{lfl, midMsbOffset}, + nodep->lsbp()->cloneTree(false)}; + AstNodeExpr* midwordp = // SEL(from,[midwordnum]) newWordSel(ffl, nodep->fromp()->cloneTree(true), midMsbp, 0); // newWordSel clones the index, so delete it VL_DO_DANGLING(midMsbp->deleteTree(), midMsbp); if (nodep->isQuad() && !midwordp->isQuad()) { midwordp = new AstCCast{nfl, midwordp, nodep}; } - AstNode* const midshiftp = new AstSub{lfl, new AstConst{lfl, VL_EDATASIZE}, - newSelBitBit(nodep->lsbp())}; + AstNodeExpr* const midshiftp = new AstSub{lfl, new AstConst{lfl, VL_EDATASIZE}, + newSelBitBit(nodep->lsbp())}; // If we're selecting bit zero, then all 32 bits in the mid word // get shifted << by 32 bits, so ignore them. const V3Number zero{nodep, longOrQuadWidth(nodep)}; @@ -395,19 +398,19 @@ private: new AstShiftL{nfl, midwordp, midshiftp, nodep->width()}}; } // If > 32 bits, we might be crossing the second word boundary - AstNode* hip = nullptr; + AstNodeExpr* hip = nullptr; if (nodep->widthConst() > VL_EDATASIZE) { const uint32_t hiMsbOffset = nodep->widthConst() - 1; - AstNode* const hiMsbp = new AstAdd{lfl, new AstConst{lfl, hiMsbOffset}, - nodep->lsbp()->cloneTree(false)}; - AstNode* hiwordp = // SEL(from,[hiwordnum]) + AstNodeExpr* const hiMsbp = new AstAdd{lfl, new AstConst{lfl, hiMsbOffset}, + nodep->lsbp()->cloneTree(false)}; + AstNodeExpr* hiwordp = // SEL(from,[hiwordnum]) newWordSel(ffl, nodep->fromp()->cloneTree(true), hiMsbp); // newWordSel clones the index, so delete it VL_DO_DANGLING(hiMsbp->deleteTree(), hiMsbp); if (nodep->isQuad() && !hiwordp->isQuad()) { hiwordp = new AstCCast{nfl, hiwordp, nodep}; } - AstNode* const hishiftp = new AstCond{ + AstNodeExpr* const hishiftp = new AstCond{ nfl, // lsb % VL_EDATASIZE == 0 ? new AstEq{nfl, new AstConst{nfl, 0}, newSelBitBit(nodep->lsbp())}, @@ -418,7 +421,7 @@ private: hip = new AstShiftL{nfl, hiwordp, hishiftp, nodep->width()}; } - AstNode* newp = lowp; + AstNodeExpr* newp = lowp; if (midp) newp = new AstOr{nfl, midp, newp}; if (hip) newp = new AstOr{nfl, hip, newp}; newp->dtypeFrom(nodep); @@ -426,11 +429,11 @@ private: } else { // Long/Quad from Long/Quad UINFO(8, " SEL->SHIFT " << nodep << endl); FileLine* const fl = nodep->fileline(); - AstNode* fromp = nodep->fromp()->unlinkFrBack(); - AstNode* const lsbp = nodep->lsbp()->unlinkFrBack(); + AstNodeExpr* fromp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack(); if (nodep->isQuad() && !fromp->isQuad()) { fromp = new AstCCast{fl, fromp, nodep}; } // {large}>>32 requires 64-bit shift operation; then cast - AstNode* newp = new AstShiftR{fl, fromp, dropCondBound(lsbp), fromp->width()}; + AstNodeExpr* newp = new AstShiftR{fl, fromp, dropCondBound(lsbp), fromp->width()}; newp->dtypeFrom(fromp); if (!nodep->isQuad() && fromp->isQuad()) { newp = new AstCCast{fl, newp, nodep}; } newp->dtypeFrom(nodep); @@ -456,21 +459,21 @@ private: FileLine* const lfl = rhsp->lsbp()->fileline(); for (int w = 0; w < nodep->widthWords(); ++w) { // Grab lowest bits - AstNode* const lowwordp + AstNodeExpr* const lowwordp = newWordSel(rfl, rhsp->fromp()->cloneTree(true), rhsp->lsbp(), w); - AstNode* const lowp + AstNodeExpr* const lowp = new AstShiftR{rfl, lowwordp, newSelBitBit(rhsp->lsbp()), VL_EDATASIZE}; // Upper bits const V3Number zero{nodep, VL_EDATASIZE, 0}; - AstNode* const midwordp = // SEL(from,[1+wordnum]) + AstNodeExpr* const midwordp = // SEL(from,[1+wordnum]) newWordSel(ffl, rhsp->fromp()->cloneTree(true), rhsp->lsbp(), w + 1); - AstNode* const midshiftp + AstNodeExpr* const midshiftp = new AstSub{lfl, new AstConst{lfl, VL_EDATASIZE}, newSelBitBit(rhsp->lsbp())}; - AstNode* const midmayp = new AstShiftL{rfl, midwordp, midshiftp, VL_EDATASIZE}; - AstNode* const midp = new AstCond{ + AstNodeExpr* const midmayp = new AstShiftL{rfl, midwordp, midshiftp, VL_EDATASIZE}; + AstNodeExpr* const midp = new AstCond{ rfl, new AstEq{rfl, new AstConst{rfl, 0}, newSelBitBit(rhsp->lsbp())}, new AstConst{rfl, zero}, midmayp}; - AstNode* const newp = new AstOr{nfl, midp, lowp}; + AstNodeExpr* const newp = new AstOr{nfl, midp, lowp}; addWordAssign(nodep, w, newp); } return true; @@ -491,8 +494,8 @@ private: if (VN_IS(lhsp->lsbp(), Const)) { // The code should work without this constant test, but it won't // constify as nicely as we'd like. - AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* const destp = lhsp->fromp()->unlinkFrBack(); + AstNodeExpr* rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const destp = lhsp->fromp()->unlinkFrBack(); const int lsb = lhsp->lsbConst(); const int msb = lhsp->msbConst(); V3Number maskset{nodep, destp->widthMin()}; @@ -504,7 +507,7 @@ private: for (int w = 0; w < destp->widthWords(); ++w) { if (w >= VL_BITWORD_E(lsb) && w <= VL_BITWORD_E(msb)) { // else we would just be setting it to the same exact value - AstNode* oldvalp = newAstWordSelClone(destp, w); + AstNodeExpr* oldvalp = newAstWordSelClone(destp, w); fixCloneLvalue(oldvalp); if (!ones) { oldvalp = new AstAnd{ @@ -514,7 +517,7 @@ private: } // Appropriate word of new value to insert: - AstNode* newp = newWordGrabShift(lfl, w, rhsp, lsb); + AstNodeExpr* newp = newWordGrabShift(lfl, w, rhsp, lsb); // Apply cleaning at the top word of the destination // (no cleaning to do if dst's width is a whole number @@ -524,7 +527,7 @@ private: cleanmask.setMask(VL_BITBIT_E(destp->widthMin())); newp = new AstAnd{lfl, newp, new AstConst{lfl, cleanmask}}; } - AstNode* const orp + AstNodeExpr* const orp = V3Const::constifyEditCpp(new AstOr{lfl, oldvalp, newp}); addWordAssign(nodep, w, destp, orp); } @@ -534,7 +537,7 @@ private: } else { UINFO(8, " ASSIGNSEL(const,narrow) " << nodep << endl); if (destp->isQuad() && !rhsp->isQuad()) { rhsp = new AstCCast{nfl, rhsp, nodep}; } - AstNode* oldvalp = destp->cloneTree(true); + AstNodeExpr* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); if (!ones) { oldvalp = new AstAnd{lfl, new AstConst{lfl, maskold}, oldvalp}; } @@ -543,20 +546,21 @@ private: // valid range of nodep which we apply to the new shifted RHS. V3Number cleanmask{nodep, destp->widthMin()}; cleanmask.setMask(destp->widthMin()); - AstNode* const shifted = new AstShiftL{ + AstNodeExpr* const shifted = new AstShiftL{ lfl, rhsp, new AstConst{lfl, static_cast(lsb)}, destp->width()}; - AstNode* const cleaned = new AstAnd{lfl, shifted, new AstConst{lfl, cleanmask}}; - AstNode* const orp = V3Const::constifyEditCpp(new AstOr{lfl, oldvalp, cleaned}); - AstNode* newp = new AstAssign{nfl, destp, orp}; - insertBefore(nodep, newp); + AstNodeExpr* const cleaned + = new AstAnd{lfl, shifted, new AstConst{lfl, cleanmask}}; + AstNodeExpr* const orp + = V3Const::constifyEditCpp(new AstOr{lfl, oldvalp, cleaned}); + insertBefore(nodep, new AstAssign{nfl, destp, orp}); } return true; } else { // non-const select offset if (destwide && lhsp->widthConst() == 1) { UINFO(8, " ASSIGNSEL(varlsb,wide,1bit) " << nodep << endl); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* const destp = lhsp->fromp()->unlinkFrBack(); - AstNode* oldvalp = newWordSel(lfl, destp->cloneTree(true), lhsp->lsbp()); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const destp = lhsp->fromp()->unlinkFrBack(); + AstNodeExpr* oldvalp = newWordSel(lfl, destp->cloneTree(true), lhsp->lsbp()); fixCloneLvalue(oldvalp); if (!ones) { oldvalp = new AstAnd{ @@ -570,8 +574,8 @@ private: oldvalp}; } // Restrict the shift amount to 0-31, see bug804. - AstNode* const shiftp = new AstAnd{nfl, lhsp->lsbp()->cloneTree(true), - new AstConst{nfl, VL_EDATASIZE - 1}}; + AstNodeExpr* const shiftp = new AstAnd{nfl, lhsp->lsbp()->cloneTree(true), + new AstConst{nfl, VL_EDATASIZE - 1}}; AstNode* const newp = new AstAssign{ nfl, newWordSel(nfl, destp, lhsp->lsbp()), new AstOr{lfl, oldvalp, new AstShiftL{lfl, rhsp, shiftp, VL_EDATASIZE}}}; @@ -592,9 +596,9 @@ private: } else { UINFO(8, " ASSIGNSEL(varlsb,narrow) " << nodep << endl); // nodep->dumpTree(cout, "- old: "); - AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* const destp = lhsp->fromp()->unlinkFrBack(); - AstNode* oldvalp = destp->cloneTree(true); + AstNodeExpr* rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const destp = lhsp->fromp()->unlinkFrBack(); + AstNodeExpr* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); V3Number maskwidth{nodep, destp->widthMin()}; @@ -609,7 +613,7 @@ private: lhsp->lsbp()->cloneTree(true), destp->width()}}, oldvalp}; } - AstNode* newp + AstNodeExpr* newp = new AstShiftL{lfl, rhsp, lhsp->lsbp()->cloneTree(true), destp->width()}; // Apply cleaning to the new value being inserted. Mask is // slightly wider than necessary to avoid an AND with all ones @@ -621,9 +625,7 @@ private: newp = new AstAnd{lfl, newp, new AstConst{lfl, cleanmask}}; } - newp = new AstAssign{nfl, destp, new AstOr{lfl, oldvalp, newp}}; - // newp->dumpTree(cout, "- new: "); - insertBefore(nodep, newp); + insertBefore(nodep, new AstAssign{nfl, destp, new AstOr{lfl, oldvalp, newp}}); return true; } } @@ -637,12 +639,12 @@ private: } else { UINFO(8, " CONCAT " << nodep << endl); FileLine* const fl = nodep->fileline(); - AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* rhsp = nodep->rhsp()->unlinkFrBack(); const uint32_t rhsshift = rhsp->widthMin(); if (nodep->isQuad() && !lhsp->isQuad()) { lhsp = new AstCCast{fl, lhsp, nodep}; } if (nodep->isQuad() && !rhsp->isQuad()) { rhsp = new AstCCast{fl, rhsp, nodep}; } - AstNode* const newp = new AstOr{ + AstNodeExpr* const newp = new AstOr{ fl, new AstShiftL{fl, lhsp, new AstConst{fl, rhsshift}, nodep->width()}, rhsp}; newp->dtypeFrom(nodep); // Unsigned VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); @@ -673,8 +675,8 @@ private: // See under ASSIGN(WIDE) } else { FileLine* const fl = nodep->fileline(); - AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* newp; + AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* newp; const int lhswidth = lhsp->widthMin(); if (lhswidth == 1) { UINFO(8, " REPLICATE(w1) " << nodep << endl); @@ -707,13 +709,13 @@ private: UINFO(8, " Wordize ASSIGN(REPLICATE) " << nodep << endl); if (!doExpand(rhsp)) return false; FileLine* const fl = nodep->fileline(); - AstNode* const lhsp = rhsp->lhsp(); + AstNodeExpr* const lhsp = rhsp->lhsp(); const int lhswidth = lhsp->widthMin(); const AstConst* const constp = VN_AS(rhsp->rhsp(), Const); UASSERT_OBJ(constp, rhsp, "Replication value isn't a constant. Checked earlier!"); const uint32_t times = constp->toUInt(); for (int w = 0; w < rhsp->widthWords(); ++w) { - AstNode* newp; + AstNodeExpr* newp; if (lhswidth == 1) { newp = new AstNegate{fl, lhsp->cloneTree(true)}; // Replicate always unsigned @@ -737,10 +739,10 @@ private: UINFO(8, " Wordize EQ/NEQ " << nodep << endl); // -> (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}} FileLine* const fl = nodep->fileline(); - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int w = 0; w < nodep->lhsp()->widthWords(); ++w) { - AstNode* const eqp = new AstXor{fl, newAstWordSelClone(nodep->lhsp(), w), - newAstWordSelClone(nodep->rhsp(), w)}; + AstNodeExpr* const eqp = new AstXor{fl, newAstWordSelClone(nodep->lhsp(), w), + newAstWordSelClone(nodep->rhsp(), w)}; newp = newp ? new AstOr{fl, newp, eqp} : eqp; } if (VN_IS(nodep, Neq)) { @@ -761,17 +763,17 @@ private: if (nodep->lhsp()->isWide()) { UINFO(8, " Wordize REDOR " << nodep << endl); // -> (0!={or{for each_word{WORDSEL(lhs,#)}}} - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int w = 0; w < nodep->lhsp()->widthWords(); ++w) { - AstNode* const eqp = newAstWordSelClone(nodep->lhsp(), w); + AstNodeExpr* const eqp = newAstWordSelClone(nodep->lhsp(), w); newp = newp ? new AstOr{fl, newp, eqp} : eqp; } newp = new AstNeq{fl, new AstConst{fl, AstConst::SizedEData(), 0}, newp}; VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { UINFO(8, " REDOR->EQ " << nodep << endl); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const newp = new AstNeq{ + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstNeq{ fl, new AstConst{fl, AstConst::WidthedValue(), longOrQuadWidth(nodep), 0}, lhsp}; VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } @@ -783,9 +785,9 @@ private: if (nodep->lhsp()->isWide()) { UINFO(8, " Wordize REDAND " << nodep << endl); // -> (0!={and{for each_word{WORDSEL(lhs,#)}}} - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int w = 0; w < nodep->lhsp()->widthWords(); ++w) { - AstNode* eqp = newAstWordSelClone(nodep->lhsp(), w); + AstNodeExpr* eqp = newAstWordSelClone(nodep->lhsp(), w); if (w == nodep->lhsp()->widthWords() - 1) { // Rather than doing a (slowish) ==##, we OR in the // bits that aren't part of the mask @@ -801,8 +803,8 @@ private: VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { UINFO(8, " REDAND->EQ " << nodep << endl); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const newp = new AstEq{fl, new AstConst{fl, wordMask(lhsp)}, lhsp}; + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstEq{fl, new AstConst{fl, wordMask(lhsp)}, lhsp}; VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } @@ -813,9 +815,9 @@ private: UINFO(8, " Wordize REDXOR " << nodep << endl); // -> (0!={redxor{for each_word{XOR(WORDSEL(lhs,#))}}} FileLine* const fl = nodep->fileline(); - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int w = 0; w < nodep->lhsp()->widthWords(); ++w) { - AstNode* const eqp = newAstWordSelClone(nodep->lhsp(), w); + AstNodeExpr* const eqp = newAstWordSelClone(nodep->lhsp(), w); newp = newp ? new AstXor{fl, newp, eqp} : eqp; } newp = new AstRedXor{fl, newp}; diff --git a/src/V3Force.cpp b/src/V3Force.cpp index 3c3b1c5de..84cdc972b 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -174,8 +174,8 @@ class ForceConvertVisitor final : public VNVisitor { pushDeletep(nodep); FileLine* const flp = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp(); // The LValue we are forcing - AstNode* const rhsp = nodep->rhsp(); // The value we are forcing it to + AstNodeExpr* const lhsp = nodep->lhsp(); // The LValue we are forcing + AstNodeExpr* const rhsp = nodep->rhsp(); // The value we are forcing it to // Set corresponding enable signals to ones V3Number ones{lhsp, lhsp->width()}; @@ -210,7 +210,7 @@ class ForceConvertVisitor final : public VNVisitor { pushDeletep(nodep); FileLine* const flp = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp(); // The LValue we are releasing + AstNodeExpr* const lhsp = nodep->lhsp(); // The LValue we are releasing // Set corresponding enable signals to zero V3Number zero{lhsp, lhsp->width()}; diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 2de50c0b6..47ca87e48 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -70,14 +70,14 @@ private: // Use user1p on the PIN to indicate we created an assign for this pin if (!nodep->user1SetOnce()) { // Make an ASSIGNW (expr, pin) - AstNode* const exprp = nodep->exprp()->cloneTree(false); + AstNodeExpr* const exprp = VN_AS(nodep->exprp(), NodeExpr)->cloneTree(false); UASSERT_OBJ(exprp->width() == nodep->modVarp()->width(), nodep, "Width mismatch, should have been handled in pinReconnectSimple"); if (nodep->modVarp()->isInoutish()) { nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator"); } else if (nodep->modVarp()->isWritable()) { - AstNode* const rhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), - m_cellp->name(), VAccess::READ); + AstNodeExpr* const rhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), + m_cellp->name(), VAccess::READ); AstAssignW* const assp = new AstAssignW(exprp->fileline(), exprp, rhsp); m_cellp->addNextHere(assp); } else if (nodep->modVarp()->isNonOutput()) { @@ -97,8 +97,8 @@ private: IfaceRefDType))) { // Create an AstAssignVarScope for Vars to Cells so we can // link with their scope later - AstNode* const lhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), - m_cellp->name(), VAccess::READ); + AstNodeExpr* const lhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), + m_cellp->name(), VAccess::READ); const AstVarRef* const refp = VN_CAST(exprp, VarRef); const AstVarXRef* const xrefp = VN_CAST(exprp, VarXRef); UASSERT_OBJ(refp || xrefp, exprp, @@ -334,7 +334,7 @@ private: const int arraySelNum = rangep->littleEndian() ? (rangep->elementsConst() - 1 - m_instSelNum) : m_instSelNum; - AstNode* exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* exprp = VN_AS(nodep->exprp(), NodeExpr)->unlinkFrBack(); exprp = new AstArraySel(exprp->fileline(), exprp, arraySelNum); nodep->exprp(exprp); } else if (expwidth == modwidth) { @@ -348,7 +348,7 @@ private: << m_cellRangep->leftConst() << ":" << m_cellRangep->rightConst() << "]"); } - AstNode* exprp = nodep->exprp()->unlinkFrBack(); + AstNodeExpr* exprp = VN_AS(nodep->exprp(), NodeExpr)->unlinkFrBack(); const bool inputPin = nodep->modVarp()->isNonOutput(); if (!inputPin && !VN_IS(exprp, VarRef) @@ -489,10 +489,10 @@ class InstStatic final { private: InstStatic() = default; // Static class - static AstNode* extendOrSel(FileLine* fl, AstNode* rhsp, AstNode* cmpWidthp) { + static AstNodeExpr* extendOrSel(FileLine* fl, AstNodeExpr* rhsp, AstNode* cmpWidthp) { if (cmpWidthp->width() > rhsp->width()) { - rhsp = (rhsp->isSigned() ? static_cast(new AstExtendS{fl, rhsp}) - : static_cast(new AstExtend{fl, rhsp})); + rhsp = (rhsp->isSigned() ? static_cast(new AstExtendS{fl, rhsp}) + : static_cast(new AstExtend{fl, rhsp})); // Need proper widthMin, which may differ from AstSel created above rhsp->dtypeFrom(cmpWidthp); } else if (cmpWidthp->width() < rhsp->width()) { @@ -553,7 +553,7 @@ public: // Make a new temp wire // if (1 || debug() >= 9) pinp->dumpTree(cout, "-in_pin:"); V3Inst::checkOutputShort(pinp); - AstNode* const pinexprp = pinp->exprp()->unlinkFrBack(); + AstNodeExpr* const pinexprp = VN_AS(pinp->exprp(), NodeExpr)->unlinkFrBack(); const string newvarname = (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp") // Prevent name conflict if both tri & non-tri add signals @@ -568,12 +568,12 @@ public: " direct one-to-one connection (without any expression)"); } else if (pinVarp->isWritable()) { // See also V3Inst - AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, VAccess::READ); + AstNodeExpr* rhsp = new AstVarRef(pinp->fileline(), newvarp, VAccess::READ); UINFO(5, "pinRecon width " << pinVarp->width() << " >? " << rhsp->width() << " >? " << pinexprp->width() << endl); rhsp = extendOrSel(pinp->fileline(), rhsp, pinVarp); pinp->exprp(new AstVarRef(newvarp->fileline(), newvarp, VAccess::WRITE)); - AstNode* const rhsSelp = extendOrSel(pinp->fileline(), rhsp, pinexprp); + AstNodeExpr* const rhsSelp = extendOrSel(pinp->fileline(), rhsp, pinexprp); assignp = new AstAssignW(pinp->fileline(), pinexprp, rhsSelp); } else { // V3 width should have range/extended to make the widths correct diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index e80ac901a..bfc1c33e8 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1223,7 +1223,7 @@ class LinkDotFindVisitor final : public VNVisitor { // new value. if (v3Global.opt.hasParameter(nodep->name())) { const string svalue = v3Global.opt.parameter(nodep->name()); - if (AstNode* const valuep + if (AstConst* const valuep = AstConst::parseParamLiteral(nodep->fileline(), svalue)) { UINFO(9, " replace parameter " << nodep << endl); UINFO(9, " with " << valuep << endl); @@ -1366,7 +1366,7 @@ class LinkDotFindVisitor final : public VNVisitor { // DOT(x, SELLOOPVARS(var, loops)) -> SELLOOPVARS(DOT(x, var), loops) if (AstDot* const dotp = VN_CAST(nodep->arrayp(), Dot)) { if (AstSelLoopVars* const loopvarsp = VN_CAST(dotp->rhsp(), SelLoopVars)) { - AstNode* const fromp = loopvarsp->fromp()->unlinkFrBack(); + AstNodeExpr* const fromp = loopvarsp->fromp()->unlinkFrBack(); loopvarsp->unlinkFrBack(); dotp->replaceWith(loopvarsp); dotp->rhsp(fromp); @@ -1540,7 +1540,7 @@ private: if (!cellp) { nodep->v3error("In defparam, instance " << nodep->path() << " never declared"); } else { - AstNode* const exprp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const exprp = nodep->rhsp()->unlinkFrBack(); UINFO(9, "Defparam cell " << nodep->path() << "." << nodep->name() << " attach-to " << cellp << " <= " << exprp << endl); // Don't need to check the name of the defparam exists. V3Param does. @@ -2295,7 +2295,7 @@ private: nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Dot midpoint - AstNode* newp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* newp = nodep->rhsp()->unlinkFrBack(); if (m_ds.m_unresolved) { AstCellRef* const crp = new AstCellRef(nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp); @@ -2358,8 +2358,8 @@ private: return; } else if (m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is membership. {scope}.{var}.HERE {member} - AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); - AstNode* const newp + AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name()); if (m_ds.m_dotErr) { nodep->unlinkFrBack(); // Avoid circular node loop on errors @@ -2545,7 +2545,8 @@ private: m_ds.m_dotPos = DP_SCOPE; UINFO(9, " modport -> iface varref " << foundp->nodep() << endl); // We lose the modport name here, so we cannot detect mismatched modports. - AstNode* newp = new AstVarRef{nodep->fileline(), ifaceRefVarp, VAccess::READ}; + AstNodeExpr* newp + = new AstVarRef{nodep->fileline(), ifaceRefVarp, VAccess::READ}; auto* const cellarrayrefp = VN_CAST(m_ds.m_unlinkedScopep, CellArrayRef); if (cellarrayrefp) { // iface[vec].modport became CellArrayRef(iface, lsb) @@ -2811,8 +2812,8 @@ private: } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is method call. // {scope}.{var}.HERE {method} ( ARGS ) - AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); - AstNode* argsp = nullptr; + AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); + AstNodeExpr* argsp = nullptr; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNode* const newp = new AstMethodCall(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp); @@ -2965,7 +2966,7 @@ private: } } if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) { - AstNode* const exprp = nodep->bitp()->unlinkFrBack(); + AstNodeExpr* const exprp = nodep->bitp()->unlinkFrBack(); AstCellArrayRef* const newp = new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp); nodep->replaceWith(newp); diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index d4b486e67..d6b152881 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -205,8 +205,8 @@ private: UASSERT_OBJ(nodep, constp, "Expecting CONST"); AstConst* const newconstp = constp->cloneTree(true); - AstNode* const storetop = nodep->thsp(); - AstNode* const valuep = nodep->rhsp(); + AstNodeExpr* const storetop = nodep->thsp(); + AstNodeExpr* const valuep = nodep->rhsp(); storetop->unlinkFrBack(); valuep->unlinkFrBack(); @@ -247,7 +247,7 @@ private: insertBeforeStmt(nodep, varp); // Define what operation will we be doing - AstNode* operp; + AstNodeExpr* operp; if (VN_IS(nodep, PostSub) || VN_IS(nodep, PreSub)) { operp = new AstSub(fl, new AstVarRef(fl, varrefp->varp(), VAccess::READ), newconstp); } else { diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index ae38c8fd5..173b90e92 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -159,7 +159,7 @@ private: // So later optimizations don't need to deal with them, // REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- } // Note var can be signed or unsigned based on original number. - AstNode* const countp = nodep->countp()->unlinkFrBackWithNext(); + AstNodeExpr* const countp = nodep->countp()->unlinkFrBackWithNext(); const string name = string("__Vrepeat") + cvtToStr(m_modRepeatNum++); // Spec says value is integral, if negative is ignored AstVar* const varp @@ -172,8 +172,8 @@ private: nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), new AstConst(nodep->fileline(), 1))); - AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); - AstNode* const condp = new AstGtS( + AstNodeExpr* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); + AstNodeExpr* const condp = new AstGtS( nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp); AstNode* const bodysp = nodep->stmtsp(); if (bodysp) bodysp->unlinkFrBackWithNext(); @@ -210,7 +210,7 @@ private: m_loopInc = true; iterateAndNextNull(nodep->incsp()); } - AstNode* const condp = nodep->condp() ? nodep->condp()->unlinkFrBack() : nullptr; + AstNodeExpr* const condp = nodep->condp() ? nodep->condp()->unlinkFrBack() : nullptr; AstNode* const bodyp = nodep->stmtsp() ? nodep->stmtsp()->unlinkFrBack() : nullptr; AstNode* const incsp = nodep->incsp() ? nodep->incsp()->unlinkFrBack() : nullptr; AstWhile* const whilep = new AstWhile{nodep->fileline(), condp, bodyp, incsp}; diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 4c8411869..ce569c707 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -181,7 +181,7 @@ private: FileLine* const flp = nodep->fileline(); for (int i = left; i != (right + increment); i += increment, offset_from_init++) { const string name = nodep->name() + cvtToStr(i); - AstNode* valuep = nullptr; + AstNodeExpr* valuep = nullptr; if (nodep->valuep()) { valuep = new AstAdd(flp, nodep->valuep()->cloneTree(true), @@ -266,7 +266,7 @@ private: newfl->warnOff(V3ErrorCode::PROCASSWIRE, true); auto* const assp = new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE), - nodep->valuep()->unlinkFrBack()); + VN_AS(nodep->valuep()->unlinkFrBack(), NodeExpr)); if (nodep->lifetime().isAutomatic()) { nodep->addNextHere(new AstInitialAutomatic{newfl, assp}); } else { @@ -274,9 +274,9 @@ private: } } // 4. Under blocks, it's an initial value to be under an assign else { - nodep->addNextHere(new AstAssign(fl, - new AstVarRef(fl, nodep->name(), VAccess::WRITE), - nodep->valuep()->unlinkFrBack())); + nodep->addNextHere( + new AstAssign(fl, new AstVarRef(fl, nodep->name(), VAccess::WRITE), + VN_AS(nodep->valuep()->unlinkFrBack(), NodeExpr))); } } if (nodep->isIfaceRef() && !nodep->isIfaceParent() && !v3Global.opt.topIfacesSupported()) { diff --git a/src/V3MergeCond.cpp b/src/V3MergeCond.cpp index fea4cae5e..ebffc3150 100644 --- a/src/V3MergeCond.cpp +++ b/src/V3MergeCond.cpp @@ -136,7 +136,7 @@ bool areDisjoint(const std::set& a, const std::set // Structure containing information required for code motion/merging struct StmtProperties { - AstNode* m_condp = nullptr; // The condition expression, if a conditional node + AstNodeExpr* m_condp = nullptr; // The condition expression, if a conditional node std::set m_rdVars; // Variables read by this statement std::set m_wrVars; // Variables writen by this statement bool m_isFence = false; // Nothing should move across this statement, nor should it be merged @@ -178,8 +178,8 @@ class CodeMotionAnalysisVisitor final : public VNVisitor { StmtProperties* m_propsp = nullptr; // StmtProperties structure of current AstNodeStmt // Extract condition expression from a megeable conditional statement, if any - static AstNode* extractCondition(const AstNodeStmt* nodep) { - AstNode* conditionp = nullptr; + static AstNodeExpr* extractCondition(const AstNodeStmt* nodep) { + AstNodeExpr* conditionp = nullptr; if (const AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) { if (AstNodeCond* const conditionalp = extractCondFromRhs(assignp->rhsp())) { conditionp = conditionalp->condp(); @@ -199,7 +199,7 @@ class CodeMotionAnalysisVisitor final : public VNVisitor { m_propsp = &m_stmtProperties(nodep); // Extract condition from statement - if (AstNode* const condp = extractCondition(nodep)) { + if (AstNodeExpr* const condp = extractCondition(nodep)) { // Remember condition node. We always need this as it is used in the later // traversal. m_propsp->m_condp = condp; @@ -447,7 +447,7 @@ private: VDouble0 m_statLongestList; // Statistic tracking AstNode* m_mgFirstp = nullptr; // First node in merged sequence - AstNode* m_mgCondp = nullptr; // The condition of the first node + AstNodeExpr* m_mgCondp = nullptr; // The condition of the first node const AstNode* m_mgLastp = nullptr; // Last node in merged sequence const AstNode* m_mgNextp = nullptr; // Next node in list being examined uint32_t m_listLenght = 0; // Length of current list @@ -578,10 +578,10 @@ private: // Apply (1'b1 & _) cleaning mask if necessary. This is required because this pass is after // V3Clean, and sometimes we have an AstAnd with a 1-bit condition on one side, but a more // than 1-bit value on the other side, so we need to keep only the LSB. - static AstNode* maskLsb(AstNode* nodep) { + static AstNodeExpr* maskLsb(AstNodeExpr* nodep) { if (yieldsOneOrZero(nodep)) return nodep; // Otherwise apply masking - AstNode* const maskp = new AstConst{nodep->fileline(), AstConst::BitTrue()}; + AstConst* const maskp = new AstConst{nodep->fileline(), AstConst::BitTrue()}; // Mask on left, as conventional return new AstAnd{nodep->fileline(), maskp, nodep}; } @@ -589,11 +589,11 @@ private: // Fold the RHS expression of an assignment assuming the given condition state. // Unlink bits from the RHS which is only used once, and can be reused (is an unomdified // sub-tree). What remains of the RHS is expected to be deleted by the caller. - AstNode* foldAndUnlink(AstNode* rhsp, bool condTrue) { + AstNodeExpr* foldAndUnlink(AstNodeExpr* rhsp, bool condTrue) { if (rhsp->sameTree(m_mgCondp)) { return new AstConst{rhsp->fileline(), AstConst::BitTrue{}, condTrue}; } else if (const AstNodeCond* const condp = extractCondFromRhs(rhsp)) { - AstNode* const resp + AstNodeExpr* const resp = condTrue ? condp->thenp()->unlinkFrBack() : condp->elsep()->unlinkFrBack(); if (condp == rhsp) return resp; if (const AstAnd* const andp = VN_CAST(rhsp, And)) { @@ -671,7 +671,7 @@ private: ++m_statMergedItems; if (AstNodeAssign* const assignp = VN_CAST(currp, NodeAssign)) { // Unlink RHS and clone to get the 2 assignments (reusing assignp) - AstNode* const rhsp = assignp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = assignp->rhsp()->unlinkFrBack(); AstNodeAssign* const thenp = assignp; AstNodeAssign* const elsep = assignp->cloneTree(false); // Construct the new RHSs and add to branches @@ -739,7 +739,7 @@ private: return false; } - bool addToList(AstNodeStmt* nodep, AstNode* condp) { + bool addToList(AstNodeStmt* nodep, AstNodeExpr* condp) { // Set up head of new list if node is first in list if (!m_mgFirstp) { UASSERT_OBJ(condp, nodep, "Cannot start new list without condition"); @@ -825,7 +825,7 @@ private: // VISITORS void visit(AstNodeAssign* nodep) override { - if (AstNode* const condp = (*m_stmtPropertiesp)(nodep).m_condp) { + if (AstNodeExpr* const condp = (*m_stmtPropertiesp)(nodep).m_condp) { // Check if mergeable if (!checkOrMakeMergeable(nodep)) return; // Close potentially incompatible pending merge diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 2c1c31e47..2d2b5d977 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -69,14 +69,14 @@ void V3ParseImp::parserClear() { //====================================================================== // V3ParseGrammar functions requiring bison state -AstArg* V3ParseGrammar::argWrapList(AstNode* nodep) { +AstArg* V3ParseGrammar::argWrapList(AstNodeExpr* nodep) { // Convert list of expressions to list of arguments if (!nodep) return nullptr; AstArg* outp = nullptr; AstBegin* const tempp = new AstBegin{nodep->fileline(), "[EditWrapper]", nodep}; while (nodep) { - AstNode* const nextp = nodep->nextp(); - AstNode* const exprp = nodep->unlinkFrBack(); + AstNodeExpr* const nextp = VN_AS(nodep->nextp(), NodeExpr); + AstNodeExpr* const exprp = nodep->unlinkFrBack(); nodep = nextp; outp = AstNode::addNext(outp, new AstArg{exprp->fileline(), "", exprp}); } diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index d38eff5e3..4c0883036 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -69,7 +69,7 @@ private: return (VN_IS(nodep->lhsp(), VarRef) && !AstVar::scVarRecurse(nodep->lhsp()) && VN_IS(nodep->rhsp(), Const)); } - void checkNode(AstNode* nodep) { + void checkNode(AstNodeExpr* nodep) { // Consider adding a temp for this expression. // We need to avoid adding temps to the following: // ASSIGN(x, *here*) @@ -116,7 +116,7 @@ private: } } - void createDeepTemp(AstNode* nodep, bool noSubst) { + void createDeepTemp(AstNodeExpr* nodep, bool noSubst) { if (nodep->user1SetOnce()) return; // Only add another assignment for this node VNRelinker relinker; @@ -236,7 +236,7 @@ private: && nodep->width() < (1LL << nodep->rhsp()->widthMin())) { VNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); - AstNode* constzerop; + AstNodeExpr* constzerop; const int m1value = nodep->widthMin() - 1; // Constant of width-1; not changing dtype width if (nodep->signedFlavor()) { @@ -253,7 +253,7 @@ private: } constzerop->dtypeFrom(nodep); // unsigned - AstNode* const constwidthp + AstNodeExpr* const constwidthp = new AstConst(nodep->fileline(), AstConst::WidthedValue(), nodep->rhsp()->widthMin(), m1value); constwidthp->dtypeFrom(nodep->rhsp()); // unsigned @@ -352,8 +352,9 @@ private: // There's another display next; we can just wait to flush } else { UINFO(4, "Autoflush " << nodep << endl); - nodep->addNextHere(new AstFFlush(nodep->fileline(), - AstNode::cloneTreeNull(nodep->filep(), true))); + nodep->addNextHere( + new AstFFlush{nodep->fileline(), + VN_AS(AstNode::cloneTreeNull(nodep->filep(), true), NodeExpr)}); } } } @@ -361,7 +362,7 @@ private: iterateChildren(nodep); // Any strings sent to a display must be var of string data type, // to avoid passing a pointer to a temporary. - for (AstNode* expp = nodep->exprsp(); expp; expp = expp->nextp()) { + for (AstNodeExpr* expp = nodep->exprsp(); expp; expp = VN_AS(expp->nextp(), NodeExpr)) { if (expp->dtypep()->basicp() && expp->dtypep()->basicp()->isString() && !VN_IS(expp, VarRef)) { createDeepTemp(expp, true); diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 99ade5062..a7e1bcc77 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -184,7 +184,7 @@ private: = new AstVarRef{fl, enumValueTabp(enumDtp), VAccess::READ}; tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); AstRand* const randp = new AstRand{fl, nullptr, false}; - AstNode* const moddivp = new AstModDiv{ + AstNodeExpr* const moddivp = new AstModDiv{ fl, randp, new AstConst{fl, static_cast(enumDtp->itemCount())}}; randp->dtypep(varrefp->findBasicDType(VBasicDTypeKwd::UINT32)); moddivp->dtypep(enumDtp); @@ -296,7 +296,7 @@ private: for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) { - AstNode* const condp = itemp->condsp()->unlinkFrBack(); + AstNodeExpr* const condp = itemp->condsp()->unlinkFrBack(); sump = new AstAdd{condp->fileline(), sump, new AstExtend{itemp->fileline(), condp, 64}}; AstNode* const stmtsp @@ -318,7 +318,7 @@ private: ifsp->addElsesp(dispp); AstNode* newp = randVarp; - AstNode* randp = new AstRand{fl, nullptr, false}; + AstNodeExpr* randp = new AstRand{fl, nullptr, false}; randp->dtypeSetUInt64(); newp->addNext(new AstAssign{fl, new AstVarRef{fl, randVarp, VAccess::WRITE}, new AstAdd{fl, new AstConst{fl, AstConst::Unsized64{}, 1}, diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index 00d3bfc68..80d9d38ce 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -107,8 +107,8 @@ private: AstNode* const initp = new AstAssign(fl, new AstVarRef(fl, itp, VAccess::WRITE), new AstConst(fl, m_mgIndexLo)); - AstNode* const condp = new AstLte(fl, new AstVarRef(fl, itp, VAccess::READ), - new AstConst(fl, m_mgIndexHi)); + AstNodeExpr* const condp = new AstLte(fl, new AstVarRef(fl, itp, VAccess::READ), + new AstConst(fl, m_mgIndexHi)); AstNode* const incp = new AstAssign( fl, new AstVarRef(fl, itp, VAccess::WRITE), new AstAdd(fl, new AstConst(fl, 1), new AstVarRef(fl, itp, VAccess::READ))); @@ -118,15 +118,15 @@ private: whilep->addStmtsp(bodyp); // Replace constant index with new loop index - AstNode* const offsetp + AstNodeExpr* const offsetp = m_mgOffset == 0 ? nullptr : new AstConst(fl, std::abs(m_mgOffset)); - AstNode* const lbitp = m_mgSelLp->bitp(); - AstNode* const lvrefp = new AstVarRef(fl, itp, VAccess::READ); + AstNodeExpr* const lbitp = m_mgSelLp->bitp(); + AstNodeExpr* const lvrefp = new AstVarRef(fl, itp, VAccess::READ); lbitp->replaceWith(m_mgOffset > 0 ? new AstAdd(fl, lvrefp, offsetp) : lvrefp); VL_DO_DANGLING(lbitp->deleteTree(), lbitp); if (m_mgSelRp) { // else constant and no replace - AstNode* const rbitp = m_mgSelRp->bitp(); - AstNode* const rvrefp = new AstVarRef(fl, itp, VAccess::READ); + AstNodeExpr* const rbitp = m_mgSelRp->bitp(); + AstNodeExpr* const rvrefp = new AstVarRef(fl, itp, VAccess::READ); rbitp->replaceWith(m_mgOffset < 0 ? new AstAdd(fl, rvrefp, offsetp) : rvrefp); VL_DO_DANGLING(rbitp->deleteTree(), lbitp); } diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 81e189d83..2634bbeec 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -64,7 +64,7 @@ class SenExprBuilder final { } // METHODS - AstNode* getCurr(AstNode* exprp) { + AstNodeExpr* getCurr(AstNodeExpr* exprp) { // For simple expressions like varrefs or selects, just use them directly if (isSimpleExpr(exprp)) return exprp->cloneTree(false); @@ -89,7 +89,7 @@ class SenExprBuilder final { } return new AstVarRef{flp, currp, VAccess::READ}; } - AstVarScope* getPrev(AstNode* exprp) { + AstVarScope* getPrev(AstNodeExpr* exprp) { FileLine* const flp = exprp->fileline(); const auto rdCurr = [=]() { return getCurr(exprp); }; @@ -150,9 +150,9 @@ class SenExprBuilder final { return prevp; } - std::pair createTerm(AstSenItem* senItemp) { + std::pair createTerm(AstSenItem* senItemp) { FileLine* const flp = senItemp->fileline(); - AstNode* const senp = senItemp->sensp(); + AstNodeExpr* const senp = senItemp->sensp(); const auto currp = [=]() { return getCurr(senp); }; const auto prevp = [=]() { return new AstVarRef{flp, getPrev(senp), VAccess::READ}; }; @@ -215,14 +215,14 @@ class SenExprBuilder final { public: // Returns the expression computing the trigger, and a bool indicating that // this trigger should be fired on the first evaluation (at initialization) - std::pair build(const AstSenTree* senTreep) { + std::pair build(const AstSenTree* senTreep) { FileLine* const flp = senTreep->fileline(); - AstNode* resultp = nullptr; + AstNodeExpr* resultp = nullptr; bool firedAtInitialization = false; for (AstSenItem* senItemp = senTreep->sensesp(); senItemp; senItemp = VN_AS(senItemp->nextp(), SenItem)) { const auto& pair = createTerm(senItemp); - if (AstNode* const termp = pair.first) { + if (AstNodeExpr* const termp = pair.first) { resultp = resultp ? new AstOr{flp, resultp, termp} : termp; firedAtInitialization |= pair.second; } diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 788d5e696..a60b5b35a 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -191,7 +191,7 @@ public: for (V3TaskConnects::iterator conIt = tconnects->begin(); conIt != tconnects->end(); ++conIt) { AstVar* const portp = conIt->first; - AstNode* const pinp = conIt->second->exprp(); + AstNodeExpr* const pinp = conIt->second->exprp(); AstNodeDType* const dtypep = pinp->dtypep(); if (AstConst* const valp = fetchConstNull(pinp)) { stack << "\n " << portp->prettyName() << " = " @@ -248,26 +248,26 @@ private: } public: - void newValue(AstNode* nodep, const AstNode* valuep) { + void newValue(AstNode* nodep, const AstNodeExpr* valuep) { if (const AstConst* const constp = VN_CAST(valuep, Const)) { newConst(nodep)->num().opAssign(constp->num()); } else if (fetchValueNull(nodep) != valuep) { // const_cast, as clonep() is set on valuep, but nothing should care - setValue(nodep, newTrackedClone(const_cast(valuep))); + setValue(nodep, newTrackedClone(const_cast(valuep))); } } - void newOutValue(AstNode* nodep, const AstNode* valuep) { + void newOutValue(AstNode* nodep, const AstNodeExpr* valuep) { if (const AstConst* const constp = VN_CAST(valuep, Const)) { newOutConst(nodep)->num().opAssign(constp->num()); } else if (fetchOutValueNull(nodep) != valuep) { // const_cast, as clonep() is set on valuep, but nothing should care - setOutValue(nodep, newTrackedClone(const_cast(valuep))); + setOutValue(nodep, newTrackedClone(const_cast(valuep))); } } private: - AstNode* newTrackedClone(AstNode* nodep) { - AstNode* const newp = nodep->cloneTree(false); + AstNodeExpr* newTrackedClone(AstNodeExpr* nodep) { + AstNodeExpr* const newp = nodep->cloneTree(false); m_reclaimValuesp.push_back(newp); return newp; } @@ -293,16 +293,16 @@ private: } public: - AstNode* fetchValueNull(AstNode* nodep) { return nodep->user3p(); } + AstNodeExpr* fetchValueNull(AstNode* nodep) { return VN_AS(nodep->user3p(), NodeExpr); } private: - AstNode* fetchOutValueNull(AstNode* nodep) { return nodep->user2p(); } + AstNodeExpr* fetchOutValueNull(AstNode* nodep) { return VN_AS(nodep->user2p(), NodeExpr); } AstConst* fetchConstNull(AstNode* nodep) { return VN_CAST(fetchValueNull(nodep), Const); } AstConst* fetchOutConstNull(AstNode* nodep) { return VN_CAST(fetchOutValueNull(nodep), Const); } - AstNode* fetchValue(AstNode* nodep) { - AstNode* const valuep = fetchValueNull(nodep); + AstNodeExpr* fetchValue(AstNode* nodep) { + AstNodeExpr* const valuep = fetchValueNull(nodep); UASSERT_OBJ(valuep, nodep, "No value found for node."); // UINFO(9, " fetch val " << *valuep << " on " << nodep << endl); return valuep; @@ -332,12 +332,12 @@ public: } private: - void setValue(AstNode* nodep, const AstNode* valuep) { + void setValue(AstNode* nodep, const AstNodeExpr* valuep) { UASSERT_OBJ(valuep, nodep, "Simulate setting null value"); UINFO(9, " set val " << valuep->name() << " on " << nodep << endl); nodep->user3p((void*)valuep); } - void setOutValue(AstNode* nodep, const AstNode* valuep) { + void setOutValue(AstNode* nodep, const AstNodeExpr* valuep) { UASSERT_OBJ(valuep, nodep, "Simulate setting null value"); UINFO(9, " set oval " << valuep->name() << " on " << nodep << endl); nodep->user2p((void*)valuep); @@ -386,7 +386,7 @@ private: // True to jump over this node - all visitors must call this up front return (m_jumpp && m_jumpp->labelp() != nodep); } - void assignOutValue(AstNodeAssign* nodep, AstNode* vscp, const AstNode* valuep) { + void assignOutValue(AstNodeAssign* nodep, AstNode* vscp, const AstNodeExpr* valuep) { if (VN_IS(nodep, AssignDly)) { // Don't do setValue, as value isn't yet visible to following statements newOutValue(vscp, valuep); @@ -443,10 +443,10 @@ private: } vscp->user1(vscp->user1() | VU_RV); const bool isConst = nodep->varp()->isParam() && nodep->varp()->valuep(); - AstNode* const valuep + AstNodeExpr* const valuep = isConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr; - if (isConst - && valuep) { // Propagate PARAM constants for constant function analysis + // Propagate PARAM constants for constant function analysis + if (isConst && valuep) { if (!m_checkOnly && optimizable()) newValue(vscp, valuep); } else { if (m_checkOnly) varRefCb(nodep); @@ -458,7 +458,7 @@ private: "LHS varref should be handled in AstAssign visitor."); { // Return simulation value - copy by reference instead of value for speed - AstNode* valuep = fetchValueNull(vscp); + AstNodeExpr* valuep = fetchValueNull(vscp); if (!valuep) { if (m_params) { clearOptimizable( @@ -697,7 +697,7 @@ private: m_reclaimValuesp.push_back(initp); } const uint32_t index = fetchConst(selp->bitp())->toUInt(); - AstNode* const valuep = newTrackedClone(fetchValue(nodep->rhsp())); + AstNodeExpr* const valuep = newTrackedClone(fetchValue(nodep->rhsp())); UINFO(9, " set val[" << index << "] = " << valuep << endl); // Values are in the "real" tree under the InitArray so can eventually extract it, // Not in the usual setValue (pointed to by user2/3p) @@ -803,7 +803,7 @@ private: if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { AstConst* const indexp = fetchConst(nodep->bitp()); const uint32_t offset = indexp->num().toUInt(); - AstNode* const itemp = initp->getIndexDefaultedValuep(offset); + AstNodeExpr* const itemp = initp->getIndexDefaultedValuep(offset); if (!itemp) { clearOptimizable(nodep, "Array initialization has too few elements, need element " + cvtToStr(offset)); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 6cab91c4f..0c027e5fe 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -60,7 +60,7 @@ class SliceVisitor final : public VNVisitor { bool m_assignError = false; // True if the current assign already has an error // METHODS - AstNode* cloneAndSel(AstNode* nodep, int elements, int offset) { + AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int offset) { // Insert an ArraySel, except for a few special cases const AstUnpackArrayDType* const arrayp = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType); @@ -73,7 +73,8 @@ class SliceVisitor final : public VNVisitor { V3Error::incErrors(); // Otherwise might infinite loop } m_assignError = true; - return nodep->cloneTree(false); // Likely will cause downstream errors + // Likely will cause downstream errors + return VN_AS(nodep, NodeExpr)->cloneTree(false); } if (arrayp->rangep()->elementsConst() != elements) { if (!m_assignError) { @@ -85,19 +86,18 @@ class SliceVisitor final : public VNVisitor { elements = 1; offset = 0; } - AstNode* newp; + AstNodeExpr* newp; if (const AstInitArray* const initp = VN_CAST(nodep, InitArray)) { UINFO(9, " cloneInitArray(" << elements << "," << offset << ") " << nodep << endl); const int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst() - 1 - offset : offset; - AstNode* itemp = initp->getIndexDefaultedValuep(leOffset); + AstNodeExpr* const itemp = initp->getIndexDefaultedValuep(leOffset); if (!itemp) { nodep->v3error("Array initialization has too few elements, need element " << offset); - itemp = initp->initsp(); } - newp = itemp->cloneTree(false); + newp = itemp ? itemp->cloneTree(false) : new AstConst{nodep->fileline(), 0}; } else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) { UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl); return snodep->cloneType(snodep->condp()->cloneTree(false), @@ -116,14 +116,16 @@ class SliceVisitor final : public VNVisitor { const int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst() - 1 - offset : offset; - newp = new AstArraySel{nodep->fileline(), nodep->cloneTree(false), leOffset}; + newp = new AstArraySel{nodep->fileline(), VN_AS(nodep, NodeExpr)->cloneTree(false), + leOffset}; } else { if (!m_assignError) { nodep->v3error(nodep->prettyTypeName() << " unexpected in assignment to unpacked array"); } m_assignError = true; - newp = nodep->cloneTree(false); // Likely will cause downstream errors + // Likely will cause downstream errors + newp = VN_AS(nodep, NodeExpr)->cloneTree(false); } return newp; } @@ -143,9 +145,8 @@ class SliceVisitor final : public VNVisitor { const int elements = arrayp->rangep()->elementsConst(); for (int offset = 0; offset < elements; ++offset) { AstNodeAssign* const newp - = VN_AS(nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, offset), - cloneAndSel(nodep->rhsp(), elements, offset)), - NodeAssign); + = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, offset), + cloneAndSel(nodep->rhsp(), elements, offset)); if (debug() >= 9) newp->dumpTree(cout, "-new "); newlistp = AstNode::addNext(newlistp, newp); } diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 1b90d3384..f2eca4fac 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -132,7 +132,7 @@ struct SplitVarImpl { // AstNodeModule::user1() -> Block number counter for generating unique names const VNUser1InUse m_user1InUse; // Only used in SplitUnpackedVarVisitor - static AstNodeAssign* newAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp, + static AstNodeAssign* newAssign(FileLine* fileline, AstNodeExpr* lhsp, AstNodeExpr* rhsp, const AstVar* varp) { if (varp->isFuncLocal() || varp->isFuncReturn()) { return new AstAssign{fileline, lhsp, rhsp}; @@ -621,9 +621,9 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { = (context && VN_IS(context, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign)); for (int i = 0; i < dtypep->elementsConst(); ++i) { - AstNode* lhsp + AstNodeExpr* lhsp = newVarRef(fl, vars.at(start_idx + i), lvalue ? VAccess::WRITE : VAccess::READ); - AstNode* rhsp = new AstArraySel{ + AstNodeExpr* rhsp = new AstArraySel{ fl, newVarRef(fl, varp, !lvalue ? VAccess::WRITE : VAccess::READ), i}; AstNode* const refp = lhsp; UINFO(9, "Creating assign idx:" << i << " + " << start_idx << "\n"); @@ -655,12 +655,12 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { const bool lvalue = varp->direction().isWritable(); FileLine* const fl = varp->fileline(); for (size_t i = 0; i < vars.size(); ++i) { - AstNode* const nodes[] = { + AstNodeExpr* const nodes[] = { new AstArraySel{fl, newVarRef(fl, varp, lvalue ? VAccess::WRITE : VAccess::READ), static_cast(i)}, newVarRef(fl, vars.at(i), !lvalue ? VAccess::WRITE : VAccess::READ)}; - AstNode* const lhsp = nodes[lvalue ? 0 : 1]; - AstNode* const rhsp = nodes[lvalue ? 1 : 0]; + AstNodeExpr* const lhsp = nodes[lvalue ? 0 : 1]; + AstNodeExpr* const rhsp = nodes[lvalue ? 1 : 0]; AstNodeAssign* const assignp = newAssign(fl, lhsp, rhsp, varp); if (insertp) { if (lvalue) { // Just after writing to the temporary variable @@ -1025,8 +1025,8 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl { void visit(AstNode* nodep) override { iterateChildren(nodep); } // Extract necessary bit range from a newly created variable to meet ref - static AstNode* extractBits(const PackedVarRefEntry& ref, const SplitNewVar& var, - const VAccess access) { + static AstNodeExpr* extractBits(const PackedVarRefEntry& ref, const SplitNewVar& var, + const VAccess access) { FileLine* const fl = ref.nodep()->fileline(); AstVarRef* const refp = new AstVarRef{fl, var.varp(), access}; if (ref.lsb() <= var.lsb() && var.msb() <= ref.msb()) { // Use the entire bits @@ -1049,10 +1049,10 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl { const bool in = portp->isReadOnly(); FileLine* const fl = portp->fileline(); for (const SplitNewVar& var : vars) { - AstNode* rhsp + AstNodeExpr* rhsp = new AstSel{fl, new AstVarRef{fl, portp, !in ? VAccess::WRITE : VAccess::READ}, var.lsb(), var.bitwidth()}; - AstNode* lhsp = new AstVarRef{fl, var.varp(), in ? VAccess::WRITE : VAccess::READ}; + AstNodeExpr* lhsp = new AstVarRef{fl, var.varp(), in ? VAccess::WRITE : VAccess::READ}; if (!in) std::swap(lhsp, rhsp); AstNodeAssign* const assignp = newAssign(fl, lhsp, rhsp, portp); if (insertp) { @@ -1134,9 +1134,10 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl { new AstVarRef{senitemp->fileline(), varit->varp(), VAccess::READ}}; senitemp->addNextHere(prevp); } else { - AstNode* const bitsp + AstNodeExpr* const bitsp = extractBits(ref, *varit, lvalue ? VAccess::WRITE : VAccess::READ); - prevp = new AstConcat{ref.nodep()->fileline(), bitsp, prevp}; + prevp = new AstConcat{ref.nodep()->fileline(), bitsp, + VN_AS(prevp, NodeExpr)}; } } // If varp is an argument of task/func, need to update temporary var @@ -1174,8 +1175,8 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl { connectPortAndVar(vars, varp, nullptr); } else if (varp->isTrace()) { // Let's reuse the original variable for tracing - AstNode* rhsp = new AstVarRef{vars.front().varp()->fileline(), vars.front().varp(), - VAccess::READ}; + AstNodeExpr* rhsp = new AstVarRef{vars.front().varp()->fileline(), + vars.front().varp(), VAccess::READ}; FileLine* const fl = varp->fileline(); for (size_t i = 1; i < vars.size(); ++i) { rhsp = new AstConcat{fl, new AstVarRef{fl, vars[i].varp(), VAccess::READ}, diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 34fa8951e..04535e9a2 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -119,7 +119,7 @@ public: m_wordUse = true; } // ACCESSORS - AstNode* substWhole(AstNode* errp) { + AstNodeExpr* substWhole(AstNode* errp) { if (!m_varp->isWide() && !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) { const AstNodeAssign* const assp = m_whole.m_assignp; UASSERT_OBJ(assp, errp, "Reading whole that was never assigned"); @@ -129,7 +129,7 @@ public: } } // Return what to substitute given word number for - AstNode* substWord(AstNode* errp, int word) { + AstNodeExpr* substWord(AstNode* errp, int word) { if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) { const AstNodeAssign* const assp = getWordAssignp(word); UASSERT_OBJ(assp, errp, "Reading a word that was never assigned, or bad word #"); @@ -287,9 +287,9 @@ private: } if (!hit) iterate(nodep->lhsp()); } - void replaceSubstEtc(AstNode* nodep, AstNode* substp) { + void replaceSubstEtc(AstNode* nodep, AstNodeExpr* substp) { if (debug() > 5) nodep->dumpTree(cout, " substw_old: "); - AstNode* newp = substp->cloneTree(true); + AstNodeExpr* newp = substp->cloneTree(true); if (!nodep->isQuad() && newp->isQuad()) { newp = new AstCCast{newp->fileline(), newp, nodep}; } @@ -308,7 +308,7 @@ private: const int word = constp->toUInt(); UINFO(8, " USEword" << word << " " << varrefp << endl); SubstVarEntry* const entryp = getEntryp(varrefp); - if (AstNode* const substp = entryp->substWord(nodep, word)) { + if (AstNodeExpr* const substp = entryp->substWord(nodep, word)) { // Check that the RHS hasn't changed value since we recorded it. const SubstUseVisitor visitor{substp, entryp->getWordStep(word)}; if (visitor.ok()) { @@ -335,7 +335,7 @@ private: if (nodep->access().isWriteOrRW()) { UINFO(8, " ASSIGNcpx " << nodep << endl); entryp->assignComplex(); - } else if (AstNode* const substp = entryp->substWhole(nodep)) { + } else if (AstNodeExpr* const substp = entryp->substWhole(nodep)) { // Check that the RHS hasn't changed value since we recorded it. const SubstUseVisitor visitor{substp, entryp->getWholeStep()}; if (visitor.ok()) { diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 8ace9f4f3..0db7f1aba 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -336,7 +336,7 @@ private: AstNode* createLookupInput(FileLine* fl, AstVarScope* indexVscp) { // Concat inputs into a single temp variable (inside always) // First var in inVars becomes the LSB of the concat - AstNode* concatp = nullptr; + AstNodeExpr* concatp = nullptr; for (AstVarScope* invscp : m_inVarps) { AstVarRef* const refp = new AstVarRef{fl, invscp, VAccess::READ}; if (concatp) { @@ -359,8 +359,8 @@ private: AstVarScope* outputAssignedTableVscp) { FileLine* const fl = nodep->fileline(); for (TableOutputVar& tov : m_outVarps) { - AstNode* const alhsp = new AstVarRef{fl, tov.varScopep(), VAccess::WRITE}; - AstNode* const arhsp = select(fl, tov.tabeVarScopep(), indexVscp); + AstNodeExpr* const alhsp = new AstVarRef{fl, tov.varScopep(), VAccess::WRITE}; + AstNodeExpr* const arhsp = select(fl, tov.tabeVarScopep(), indexVscp); AstNode* outsetp = m_assignDly ? static_cast(new AstAssignDly{fl, alhsp, arhsp}) : static_cast(new AstAssign{fl, alhsp, arhsp}); @@ -369,7 +369,7 @@ private: if (tov.mayBeUnassigned()) { V3Number outputChgMask{nodep, static_cast(m_outVarps.size()), 0}; outputChgMask.setBit(tov.ord(), 1); - AstNode* const condp + AstNodeExpr* const condp = new AstAnd{fl, select(fl, outputAssignedTableVscp, indexVscp), new AstConst{fl, outputChgMask}}; outsetp = new AstIf{fl, condp, outsetp}; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 59aaca246..3c30da6d7 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -435,7 +435,7 @@ private: for (const auto& itr : tconnects) { AstVar* const portp = itr.first; AstArg* const argp = itr.second; - AstNode* const pinp = argp->exprp(); + AstNodeExpr* const pinp = argp->exprp(); portp->unlinkFrBack(); pushDeletep(portp); // Remove it from the clone (not original) if (!pinp) { @@ -564,7 +564,7 @@ private: const V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp()); for (const auto& itr : tconnects) { AstVar* const portp = itr.first; - AstNode* const pinp = itr.second->exprp(); + AstNodeExpr* const pinp = itr.second->exprp(); if (!pinp) { // Too few arguments in function call } else { @@ -615,7 +615,7 @@ private: if (refp->taskp()->dpiContext()) { // __Vscopep - AstNode* const snp = refp->scopeNamep()->unlinkFrBack(); + AstScopeName* const snp = refp->scopeNamep()->unlinkFrBack(); UASSERT_OBJ(snp, refp, "Missing scoping context"); ccallp->addArgsp(snp); // __Vfilenamep @@ -630,7 +630,7 @@ private: for (AstNode* pinp = refp->pinsp(); pinp; pinp = nextpinp) { nextpinp = pinp->nextp(); // Move pin to the CCall, removing all Arg's - AstNode* const exprp = VN_AS(pinp, Arg)->exprp(); + AstNodeExpr* const exprp = VN_AS(pinp, Arg)->exprp(); exprp->unlinkFrBack(); ccallp->addArgsp(exprp); } @@ -721,7 +721,7 @@ private: AstNode* newp = nullptr; const int widthWords = portp->basicp()->widthWords(); for (int i = 0; i < total; ++i) { - AstNode* srcp = new AstVarRef(portvscp->fileline(), portvscp, VAccess::WRITE); + AstNodeExpr* srcp = new AstVarRef(portvscp->fileline(), portvscp, VAccess::WRITE); // extract a scalar from multi-dimensional array (internal format) for (auto&& dimStride : dimStrides) { const size_t dimIdx = (i / dimStride.second) % dimStride.first->elementsConst(); @@ -744,7 +744,7 @@ private: from += "[" + cvtToStr(i * coef) + "]"; } from += ket; - AstNode* const rhsp = new AstSel( + AstNodeExpr* const rhsp = new AstSel( portp->fileline(), new AstCExpr(portp->fileline(), from, cwidth, false), 0, portp->width()); stmtp = new AstAssign(portp->fileline(), srcp, rhsp); @@ -1629,7 +1629,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) for (int i = 0; i < tpinnum; ++i) { AstVar* const portp = tconnects[i].first; if (!tconnects[i].second || !tconnects[i].second->exprp()) { - AstNode* newvaluep = nullptr; + AstNodeExpr* newvaluep = nullptr; if (!portp->valuep()) { nodep->v3error("Missing argument on non-defaulted argument " << portp->prettyNameQ() << " in function call to " @@ -1639,7 +1639,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) // The default value for this port might be a constant // expression that hasn't been folded yet. Try folding it // now; we don't have much to lose if it fails. - newvaluep = V3Const::constifyParamsEdit(portp->valuep()); + newvaluep = V3Const::constifyParamsEdit(VN_AS(portp->valuep(), NodeExpr)); if (!VN_IS(newvaluep, Const)) { // Problem otherwise is we might have a varref, task // call, or something else that only makes sense in the @@ -1653,7 +1653,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) newvaluep = newvaluep->cloneTree(true); } } else { - newvaluep = portp->valuep()->cloneTree(true); + newvaluep = VN_AS(portp->valuep(), NodeExpr)->cloneTree(true); } // To avoid problems with callee needing to know to deleteTree // or not, we make this into a pin diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index 30eb3d410..3a3ac25f0 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -91,7 +91,7 @@ private: // to this sentree // Ast{NodeProcedure,CFunc,Begin}::user2() -> bool. Set true if process/task is // suspendable - // AstSenTree::user2() -> AstText*. Debug info passed to the + // AstSenTree::user2() -> AstCExpr*. Debug info passed to the // timing schedulers // Ast{NodeProcedure,CFunc,Begin}::user3() -> DependencyVertex*. Vertex in m_depGraph const VNUser1InUse m_user1InUse; @@ -286,24 +286,29 @@ private: return VN_AS(sensesp->user1p(), VarScope); } // Creates a string describing the sentree - AstText* createEventDescription(AstSenTree* const sensesp) const { + AstCExpr* createEventDescription(AstSenTree* const sensesp) const { if (!sensesp->user2p()) { std::stringstream ss; ss << '"'; V3EmitV::verilogForTree(sensesp, ss); ss << '"'; - auto* const commentp = new AstText{sensesp->fileline(), ss.str()}; + auto* const commentp = new AstCExpr{sensesp->fileline(), ss.str(), 0}; + commentp->dtypeSetString(); sensesp->user2p(commentp); return commentp; } - return VN_AS(sensesp->user2p(), Text)->cloneTree(false); + return VN_AS(sensesp->user2p(), CExpr)->cloneTree(false); } // Adds debug info to a hardcoded method call void addDebugInfo(AstCMethodHard* const methodp) const { if (v3Global.opt.protectIds()) return; FileLine* const flp = methodp->fileline(); - methodp->addPinsp(new AstText{flp, '"' + flp->filename() + '"'}); - methodp->addPinsp(new AstText{flp, cvtToStr(flp->lineno())}); + AstCExpr* const ap = new AstCExpr{flp, '"' + flp->filename() + '"', 0}; + ap->dtypeSetString(); + methodp->addPinsp(ap); + AstCExpr* const bp = new AstCExpr{flp, cvtToStr(flp->lineno()), 0}; + bp->dtypeSetString(); + methodp->addPinsp(bp); } // Adds debug info to a trigSched.trigger() call void addEventDebugInfo(AstCMethodHard* const methodp, AstSenTree* const sensesp) const { @@ -491,7 +496,7 @@ private: } void visit(AstDelay* nodep) override { FileLine* const flp = nodep->fileline(); - AstNode* valuep = V3Const::constifyEdit(nodep->lhsp()->unlinkFrBack()); + AstNodeExpr* valuep = V3Const::constifyEdit(nodep->lhsp()->unlinkFrBack()); auto* const constp = VN_CAST(valuep, Const); if (constp && constp->isZero()) { nodep->v3warn(ZERODLY, "Unsupported: #0 delays do not schedule process resumption in " @@ -632,7 +637,8 @@ private: // do that. These intra-assignment vars will later be passed to forked processes by value. AstNode* const insertBeforep = VN_IS(m_procp, CFunc) ? controlp : nullptr; // Function for replacing values with intermediate variables - const auto replaceWithIntermediate = [&](AstNode* const valuep, const std::string& name) { + const auto replaceWithIntermediate = [&](AstNodeExpr* const valuep, + const std::string& name) { AstVarScope* const newvscp = createTemp(flp, name, valuep->dtypep(), insertBeforep); valuep->replaceWith(new AstVarRef{flp, newvscp, VAccess::READ}); controlp->addHereThisAsNext( @@ -665,7 +671,7 @@ private: // TODO: Find a way to do this without introducing this var. Perhaps make // V3SchedAcyclic recognize awaits and prevent it from treating this kind of logic as // cyclic - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); std::string varname; if (auto* const refp = VN_CAST(lhsp, VarRef)) { varname = m_contAssignVarNames.get(refp->name()); @@ -696,7 +702,7 @@ private: FileLine* const flp = nodep->fileline(); AstNode* const stmtsp = nodep->stmtsp(); if (stmtsp) stmtsp->unlinkFrBackWithNext(); - AstNode* const condp = V3Const::constifyEdit(nodep->condp()->unlinkFrBack()); + AstNodeExpr* const condp = V3Const::constifyEdit(nodep->condp()->unlinkFrBack()); auto* const constp = VN_CAST(condp, Const); if (constp) { condp->v3warn(WAITCONST, "Wait statement condition is constant"); diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index aaf13244a..d1f5353d9 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -421,7 +421,7 @@ private: graphSimplify(false); } - AstNode* selectActivity(FileLine* flp, uint32_t acode, const VAccess& access) { + AstNodeExpr* selectActivity(FileLine* flp, uint32_t acode, const VAccess& access) { return new AstArraySel(flp, new AstVarRef(flp, m_activityVscp, access), acode); } @@ -667,12 +667,12 @@ private: if (!prevActSet || actSet != *prevActSet) { FileLine* const flp = m_topScopep->fileline(); const bool always = actSet.count(TraceActivityVertex::ACTIVITY_ALWAYS) != 0; - AstNode* condp = nullptr; + AstNodeExpr* condp = nullptr; if (always) { condp = new AstConst(flp, 1); // Always true, will be folded later } else { for (const uint32_t actCode : actSet) { - AstNode* const selp = selectActivity(flp, actCode, VAccess::READ); + AstNodeExpr* const selp = selectActivity(flp, actCode, VAccess::READ); condp = condp ? new AstOr(flp, condp, selp) : selp; } } diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index b8a5615e6..449abf60f 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -128,7 +128,7 @@ private: }; std::vector m_signals; // Signals under current scope AstVarScope* m_traVscp = nullptr; // Current AstVarScope we are constructing AstTraceDecls for - AstNode* m_traValuep = nullptr; // Value expression for current signal + AstNodeExpr* m_traValuep = nullptr; // Value expression for current signal string m_traName; // Name component for current signal VDouble0 m_statSigs; // Statistic tracking diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index d5dda0f54..3c1b9e255 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -465,7 +465,7 @@ class TristateVisitor final : public TristateBaseVisitor { AstConst* const newp = new AstConst{nodep->fileline(), num}; return newp; } - AstNode* getEnp(AstNode* nodep) { + AstNodeExpr* getEnp(AstNode* nodep) { if (nodep->user1p()) { if (AstVarRef* const refp = VN_CAST(nodep, VarRef)) { if (refp->varp()->isIO()) { @@ -480,7 +480,7 @@ class TristateVisitor final : public TristateBaseVisitor { nodep->user1p(newAllZerosOrOnes(nodep, true)); } // Otherwise return the previous output enable - return nodep->user1p(); + return VN_AS(nodep->user1p(), NodeExpr); } AstVar* getCreateEnVarp(AstVar* invarp) { // Return the master __en for the specified input variable @@ -501,7 +501,7 @@ class TristateVisitor final : public TristateBaseVisitor { numz0.opNot(numz); // Z->0, else 1 return new AstConst{fl, numz0}; } - AstNode* getEnExprBasedOnOriginalp(AstNode* const nodep) { + AstNodeExpr* getEnExprBasedOnOriginalp(AstNodeExpr* const nodep) { if (AstVarRef* const varrefp = VN_CAST(nodep, VarRef)) { return new AstVarRef{varrefp->fileline(), getCreateEnVarp(varrefp->varp()), VAccess::READ}; @@ -514,17 +514,17 @@ class TristateVisitor final : public TristateBaseVisitor { // whole extend. // Unlink lhsp before copying to save unnecessary copy of lhsp - AstNode* const lhsp = extendp->lhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = extendp->lhsp()->unlinkFrBack(); AstExtend* const enExtendp = extendp->cloneTree(false); extendp->lhsp(lhsp); - AstNode* const enLhsp = getEnExprBasedOnOriginalp(lhsp); + AstNodeExpr* const enLhsp = getEnExprBasedOnOriginalp(lhsp); enExtendp->lhsp(new AstNot{enLhsp->fileline(), enLhsp}); return new AstNot{enExtendp->fileline(), enExtendp}; } else if (AstSel* const selp = VN_CAST(nodep, Sel)) { - AstNode* const fromp = selp->fromp()->unlinkFrBack(); + AstNodeExpr* const fromp = selp->fromp()->unlinkFrBack(); AstSel* const enSelp = selp->cloneTree(false); selp->fromp(fromp); - AstNode* const enFromp = getEnExprBasedOnOriginalp(fromp); + AstNodeExpr* const enFromp = getEnExprBasedOnOriginalp(fromp); enSelp->fromp(enFromp); return enSelp; } else { @@ -566,10 +566,10 @@ class TristateVisitor final : public TristateBaseVisitor { } } - AstNode* newEnableDeposit(AstSel* selp, AstNode* enp) { + AstNodeExpr* newEnableDeposit(AstSel* selp, AstNodeExpr* enp) { // Form a "deposit" instruction for given enable, using existing select as a template. // Would be nicer if we made this a new AST type - AstNode* const newp = new AstShiftL( + AstNodeExpr* const newp = new AstShiftL( selp->fileline(), new AstExtend(selp->fileline(), enp, selp->fromp()->width()), selp->lsbp()->cloneTree(false), selp->fromp()->width()); return newp; @@ -659,8 +659,8 @@ class TristateVisitor final : public TristateBaseVisitor { // For each driver seperate variables (normal and __en) are created and initialized with // values. In case of normal variable, the original expression is reused. Their values are // aggregated using | to form one expression, which are assigned to varp end envarp. - AstNode* orp = nullptr; - AstNode* enp = nullptr; + AstNodeExpr* orp = nullptr; + AstNodeExpr* enp = nullptr; for (auto it = beginStrength; it != endStrength; it++) { AstVarRef* refp = it->m_varrefp; @@ -689,14 +689,14 @@ class TristateVisitor final : public TristateBaseVisitor { nodep->addStmtsp(enLhspAssignp); // now append this driver to the driver logic. - AstNode* const ref1p = new AstVarRef{refp->fileline(), newLhsp, VAccess::READ}; - AstNode* const ref2p = new AstVarRef{refp->fileline(), newEnLhsp, VAccess::READ}; - AstNode* const andp = new AstAnd{refp->fileline(), ref1p, ref2p}; + AstNodeExpr* const ref1p = new AstVarRef{refp->fileline(), newLhsp, VAccess::READ}; + AstNodeExpr* const ref2p = new AstVarRef{refp->fileline(), newEnLhsp, VAccess::READ}; + AstNodeExpr* const andp = new AstAnd{refp->fileline(), ref1p, ref2p}; // or this to the others orp = (!orp) ? andp : new AstOr{refp->fileline(), orp, andp}; - AstNode* const ref3p = new AstVarRef{refp->fileline(), newEnLhsp, VAccess::READ}; + AstNodeExpr* const ref3p = new AstVarRef{refp->fileline(), newEnLhsp, VAccess::READ}; enp = (!enp) ? ref3p : new AstOr{ref3p->fileline(), enp, ref3p}; } AstNode* const assp = new AstAssignW{ @@ -742,8 +742,8 @@ class TristateVisitor final : public TristateBaseVisitor { envarp = VN_AS(invarp->user1p(), Var); // From CASEEQ, foo === 1'bz } - AstNode* orp = nullptr; - AstNode* enp = nullptr; + AstNodeExpr* orp = nullptr; + AstNodeExpr* enp = nullptr; const int w = lhsp->width(); std::sort(refsp->begin(), refsp->end(), @@ -774,7 +774,7 @@ class TristateVisitor final : public TristateBaseVisitor { aggregateTriSameStrength(nodep, varStrengthp, enVarStrengthp, beginStrength, endStrength); - AstNode* exprCurrentStrengthp; + AstNodeExpr* exprCurrentStrengthp; if (enp) { // If weaker driver should be overwritten by a stronger, replace its value with z exprCurrentStrengthp @@ -785,7 +785,7 @@ class TristateVisitor final : public TristateBaseVisitor { } orp = (!orp) ? exprCurrentStrengthp : new AstOr{fl, orp, exprCurrentStrengthp}; - AstNode* enVarStrengthRefp = new AstVarRef{fl, enVarStrengthp, VAccess::READ}; + AstNodeExpr* enVarStrengthRefp = new AstVarRef{fl, enVarStrengthp, VAccess::READ}; enp = (!enp) ? enVarStrengthRefp : new AstOr{fl, enp, enVarStrengthRefp}; @@ -798,7 +798,7 @@ class TristateVisitor final : public TristateBaseVisitor { const AstPull* const pullp = static_cast(lhsp->user3p()); bool pull1 = pullp && pullp->direction() == 1; // Else default is down - AstNode* undrivenp; + AstNodeExpr* undrivenp; if (envarp) { undrivenp = new AstNot{envarp->fileline(), new AstVarRef{envarp->fileline(), envarp, VAccess::READ}}; @@ -1033,20 +1033,20 @@ class TristateVisitor final : public TristateBaseVisitor { // expression 1 or 2 have an output enable '__en' signal. If the // condition has an enable, not sure what to do, so generate an // error. - AstNode* const condp = nodep->condp(); + AstNodeExpr* const condp = nodep->condp(); if (condp->user1p()) { condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with " "tristate logic in the conditional expression"); } - AstNode* const thenp = nodep->thenp(); - AstNode* const elsep = nodep->elsep(); + AstNodeExpr* const thenp = nodep->thenp(); + AstNodeExpr* const elsep = nodep->elsep(); if (thenp->user1p() || elsep->user1p()) { // else no tristates m_tgraph.didProcess(nodep); - AstNode* const en1p = getEnp(thenp); - AstNode* const en2p = getEnp(elsep); + AstNodeExpr* const en1p = getEnp(thenp); + AstNodeExpr* 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 + AstNodeExpr* 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) @@ -1069,7 +1069,8 @@ class TristateVisitor final : public TristateBaseVisitor { UINFO(9, dbgState() << nodep << endl); if (nodep->user1p()) { // Form a "deposit" instruction. Would be nicer if we made this a new AST type - AstNode* const newp = newEnableDeposit(nodep, nodep->user1p()); + AstNodeExpr* const newp + = newEnableDeposit(nodep, VN_AS(nodep->user1p(), NodeExpr)); nodep->fromp()->user1p(newp); // Push to varref (etc) if (debug() >= 9) newp->dumpTree(cout, "-assign-sel; "); m_tgraph.didProcess(nodep); @@ -1083,8 +1084,8 @@ class TristateVisitor final : public TristateBaseVisitor { << nodep->prettyTypeName()); } if (nodep->fromp()->user1p()) { // SEL(VARREF, lsb) - AstNode* const en1p = getEnp(nodep->fromp()); - AstNode* const enp + AstNodeExpr* const en1p = getEnp(nodep->fromp()); + AstNodeExpr* const enp = new AstSel(nodep->fileline(), en1p, nodep->lsbp()->cloneTree(true), nodep->widthp()->cloneTree(true)); UINFO(9, " newsel " << enp << endl); @@ -1110,7 +1111,7 @@ class TristateVisitor final : public TristateBaseVisitor { UINFO(9, dbgState() << nodep << endl); if (nodep->user1p()) { // Each half of the concat gets a select of the enable expression - AstNode* const enp = nodep->user1p(); + AstNodeExpr* const enp = VN_AS(nodep->user1p(), NodeExpr); nodep->user1p(nullptr); nodep->lhsp()->user1p(new AstSel(nodep->fileline(), enp->cloneTree(true), nodep->rhsp()->width(), @@ -1125,13 +1126,13 @@ class TristateVisitor final : public TristateBaseVisitor { UINFO(9, dbgState() << nodep << endl); // Generate the new output enable signal, just as a concat // identical to the data concat - AstNode* const expr1p = nodep->lhsp(); - AstNode* const expr2p = nodep->rhsp(); + AstNodeExpr* const expr1p = nodep->lhsp(); + AstNodeExpr* const expr2p = nodep->rhsp(); if (expr1p->user1p() || expr2p->user1p()) { // else no tristates m_tgraph.didProcess(nodep); - AstNode* const en1p = getEnp(expr1p); - AstNode* const en2p = getEnp(expr2p); - AstNode* const enp = new AstConcat(nodep->fileline(), en1p, en2p); + AstNodeExpr* const en1p = getEnp(expr1p); + AstNodeExpr* const en2p = getEnp(expr2p); + AstNodeExpr* const enp = new AstConcat(nodep->fileline(), en1p, en2p); UINFO(9, " newconc " << enp << endl); nodep->user1p(enp); // propagate up CONCAT(lhsp->enable, rhsp->enable) expr1p->user1p(nullptr); @@ -1156,10 +1157,10 @@ class TristateVisitor final : public TristateBaseVisitor { return; } m_tgraph.didProcess(nodep); - AstNode* const expr1p = nodep->lhsp()->unlinkFrBack(); - AstNode* const expr2p = nodep->rhsp()->unlinkFrBack(); - AstNode* enp; - if (AstNode* const en2p = expr2p->user1p()) { + AstNodeExpr* const expr1p = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const expr2p = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* enp; + if (AstNodeExpr* const en2p = VN_AS(expr2p->user1p(), NodeExpr)) { enp = new AstAnd(nodep->fileline(), expr1p, en2p); } else { enp = expr1p; @@ -1199,22 +1200,22 @@ class TristateVisitor final : public TristateBaseVisitor { // have to define what is means to OR 1'bz with other // expressions. Here I take the approach that when one expression // is 0, that is passes the other. - AstNode* const expr1p = nodep->lhsp(); - AstNode* const expr2p = nodep->rhsp(); + AstNodeExpr* const expr1p = nodep->lhsp(); + AstNodeExpr* const expr2p = nodep->rhsp(); if (!expr1p->user1p() && !expr2p->user1p()) { return; // no tristates in either expression, so nothing to do } m_tgraph.didProcess(nodep); - AstNode* const en1p = getEnp(expr1p); - AstNode* const en2p = getEnp(expr2p); - AstNode* subexpr1p = expr1p->cloneTree(false); - AstNode* subexpr2p = expr2p->cloneTree(false); + AstNodeExpr* const en1p = getEnp(expr1p); + AstNodeExpr* const en2p = getEnp(expr2p); + AstNodeExpr* subexpr1p = expr1p->cloneTree(false); + AstNodeExpr* subexpr2p = expr2p->cloneTree(false); if (isAnd) { subexpr1p = new AstNot(nodep->fileline(), subexpr1p); subexpr2p = new AstNot(nodep->fileline(), subexpr2p); } // calc new output enable - AstNode* const enp = new AstOr( + AstNodeExpr* const enp = new AstOr( nodep->fileline(), new AstAnd(nodep->fileline(), en1p, en2p), new AstOr(nodep->fileline(), new AstAnd(nodep->fileline(), en1p->cloneTree(false), subexpr1p), @@ -1301,12 +1302,12 @@ class TristateVisitor final : public TristateBaseVisitor { AstConst* const constp = VN_CAST(nodep->lhsp(), Const); if (constp && constp->user1p()) { // 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in)) - AstNode* const rhsp = nodep->rhsp(); + AstNodeExpr* const rhsp = nodep->rhsp(); rhsp->unlinkFrBack(); FileLine* const fl = nodep->fileline(); - AstNode* enRhsp; + AstNodeExpr* enRhsp; if (rhsp->user1p()) { - enRhsp = rhsp->user1p(); + enRhsp = VN_AS(rhsp->user1p(), NodeExpr); rhsp->user1p(nullptr); } else { enRhsp = getEnExprBasedOnOriginalp(rhsp); @@ -1315,7 +1316,7 @@ class TristateVisitor final : public TristateBaseVisitor { = VN_AS(constp->user1p(), Const) ->num(); // visit(AstConst) already split into en/ones const V3Number& oneIfEnOne = constp->num(); - AstNode* newp + AstNodeExpr* newp = new AstLogAnd{fl, new AstEq{fl, new AstConst{fl, oneIfEn}, enRhsp}, // Keep the caseeq if there are X's present new AstEqCase{fl, new AstConst{fl, oneIfEnOne}, rhsp}}; @@ -1328,11 +1329,12 @@ class TristateVisitor final : public TristateBaseVisitor { } else if (constp && nodep->rhsp()->user1p()) { FileLine* const fl = nodep->fileline(); constp->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* newp = new AstLogAnd{ - fl, new AstEq{fl, newAllZerosOrOnes(constp, false), rhsp->user1p()}, - // Keep the caseeq if there are X's present - new AstEqCase{fl, constp, rhsp}}; + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* newp = new AstLogAnd{fl, + new AstEq{fl, newAllZerosOrOnes(constp, false), + VN_AS(rhsp->user1p(), NodeExpr)}, + // Keep the caseeq if there are X's present + new AstEqCase{fl, constp, rhsp}}; if (neq) newp = new AstLogNot{fl, newp}; rhsp->user1p(nullptr); UINFO(9, " newceq " << newp << endl); @@ -1376,7 +1378,7 @@ class TristateVisitor final : public TristateBaseVisitor { if (!dropop[1]) iterateAndNextNull(nodep->thsp()); if (!dropop[2]) iterateAndNextNull(nodep->fhsp()); } else { - AstNode* nonXp = nullptr; + AstNodeExpr* nonXp = nullptr; if (!dropop[0]) { nonXp = nodep->rhsp(); } else if (!dropop[1]) { @@ -1400,7 +1402,7 @@ class TristateVisitor final : public TristateBaseVisitor { UINFO(4, " COUNTBITS('z)-> " << nodep << endl); VNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); - AstNode* newp = new AstCountOnes( + AstNodeExpr* newp = new AstCountOnes( nodep->fileline(), new AstVarRef(nodep->fileline(), envarp, VAccess::READ)); if (nonXp) { // Need to still count '0 or '1 or 'x's if (dropop[0]) { @@ -1545,7 +1547,7 @@ class TristateVisitor final : public TristateBaseVisitor { // Therefore, create the enable, output and separate input pin, // then pinReconnectSimple all // Create the output enable pin, connect to new signal - AstNode* enrefp; + AstNodeExpr* enrefp; { AstVar* const enVarp = new AstVar(nodep->fileline(), VVarType::MODULETEMP, nodep->name() + "__en" + cvtToStr(m_unique++), @@ -1580,8 +1582,8 @@ class TristateVisitor final : public TristateBaseVisitor { << nodep->prettyNameQ()); } } else { - AstNode* const outexprp - = nodep->exprp()->cloneTree(false); // Note has lvalue() set + AstNodeExpr* const outexprp + = VN_AS(nodep->exprp(), NodeExpr)->cloneTree(false); // Note has lvalue() set outpinp = new AstPin(nodep->fileline(), nodep->pinNum(), outModVarp->name(), // should be {var}"__out" outexprp); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index abd550ea5..8d768dedb 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -68,7 +68,7 @@ private: // METHODS - void replaceBoundLvalue(AstNode* nodep, AstNode* condp) { + void replaceBoundLvalue(AstNodeExpr* nodep, AstNodeExpr* condp) { // Spec says a out-of-range LHS SEL results in a NOP. // This is a PITA. We could: // 1. IF(...) around an ASSIGN, @@ -101,11 +101,11 @@ private: m_assigndlyp->replaceWith(newp); VL_DO_CLEAR(pushDeletep(m_assigndlyp), m_assigndlyp = nullptr); } - AstNode* prep = nodep; + AstNodeExpr* prep = nodep; // Scan back to put the condlvalue above all selects (IE top of the lvalue) while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel)) { - prep = prep->backp(); + prep = VN_AS(prep->backp(), NodeExpr); } FileLine* const fl = nodep->fileline(); VL_DANGLING(nodep); // Zap it so we don't use it by mistake - use prep @@ -115,8 +115,8 @@ private: if (const AstIf* const ifp = VN_AS(prep->user2p(), If)) { UASSERT_OBJ(!needDly, prep, "Should have already converted to non-delay"); VNRelinker replaceHandle; - AstNode* const earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle); - AstNode* const newp = new AstLogAnd(condp->fileline(), condp, earliercondp); + AstNodeExpr* const earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle); + AstNodeExpr* const newp = new AstLogAnd(condp->fileline(), condp, earliercondp); UINFO(4, "Edit BOUNDLVALUE " << newp << endl); replaceHandle.relink(newp); } else { @@ -207,9 +207,9 @@ private: VL_DO_DANGLING(V3Const::constifyEdit(nodep), nodep); return; } else { - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* newp; + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* newp; // If we got ==1'bx it can never be true (but 1'bx==1'bx can be!) if (((VN_IS(lhsp, Const) && VN_AS(lhsp, Const)->num().isFourState()) || (VN_IS(rhsp, Const) && VN_AS(rhsp, Const)->num().isFourState()))) { @@ -239,9 +239,9 @@ private: VL_DO_DANGLING(V3Const::constifyEdit(nodep), nodep); return; } else { - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* newp; + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* newp; if (!VN_IS(rhsp, Const)) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: RHS of ==? or !=? must be " "constant to be synthesizable"); // Says spec. @@ -253,9 +253,9 @@ private: nummask.opBitsNonX(VN_AS(rhsp, Const)->num()); V3Number numval(rhsp, rhsp->width()); numval.opBitsOne(VN_AS(rhsp, Const)->num()); - AstNode* const and1p = new AstAnd(nodep->fileline(), lhsp, - new AstConst(nodep->fileline(), nummask)); - AstNode* const and2p = new AstConst(nodep->fileline(), numval); + AstNodeExpr* const and1p = new AstAnd(nodep->fileline(), lhsp, + new AstConst(nodep->fileline(), nummask)); + AstNodeExpr* const and2p = new AstConst(nodep->fileline(), numval); if (VN_IS(nodep, EqWild)) { newp = new AstEq(nodep->fileline(), and1p, and2p); } else { @@ -290,7 +290,7 @@ private: dropop[2] = VN_IS(nodep->fhsp(), Const) && VN_AS(nodep->fhsp(), Const)->num().isAnyX(); UINFO(4, " COUNTBITS(" << dropop[0] << dropop[1] << dropop[2] << " " << nodep << endl); - AstNode* nonXp = nullptr; + AstNodeExpr* nonXp = nullptr; if (!dropop[0]) { nonXp = nodep->rhsp(); } else if (!dropop[1]) { @@ -394,10 +394,11 @@ private: if (debug() >= 9) nodep->dumpTree(cout, "sel_old: "); // If (maxmsb >= selected), we're in bound - AstNode* condp = new AstGte(nodep->fileline(), - new AstConst(nodep->fileline(), AstConst::WidthedValue(), - nodep->lsbp()->width(), maxmsb), - nodep->lsbp()->cloneTree(false)); + AstNodeExpr* condp + = new AstGte(nodep->fileline(), + new AstConst(nodep->fileline(), AstConst::WidthedValue(), + nodep->lsbp()->width(), maxmsb), + nodep->lsbp()->cloneTree(false)); // See if the condition is constant true (e.g. always in bound due to constant select) // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); @@ -452,10 +453,11 @@ private: if (debug() >= 9) nodep->dumpTree(cout, "arraysel_old: "); // See if the condition is constant true - AstNode* condp = new AstGte(nodep->fileline(), - new AstConst(nodep->fileline(), AstConst::WidthedValue(), - nodep->bitp()->width(), declElements - 1), - nodep->bitp()->cloneTree(false)); + AstNodeExpr* condp + = new AstGte(nodep->fileline(), + new AstConst(nodep->fileline(), AstConst::WidthedValue(), + nodep->bitp()->width(), declElements - 1), + nodep->bitp()->cloneTree(false)); // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); if (condp->isOne()) { @@ -483,8 +485,8 @@ private: } else if (!lvalue) { // Mid-multidimension read, just use zero // ARRAYSEL(...) -> ARRAYSEL(COND(LT(bitbitp()->unlinkFrBack(&replaceHandle); - AstNode* const newp = new AstCondBound( + AstNodeExpr* const bitp = nodep->bitp()->unlinkFrBack(&replaceHandle); + AstNodeExpr* const newp = new AstCondBound( bitp->fileline(), condp, bitp, new AstConst(bitp->fileline(), AstConst::WidthedValue(), bitp->width(), 0)); // Added X's, tristate them too diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 176f8c00e..f59ea4cea 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -770,22 +770,10 @@ private: iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH); iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change - const AstConst* const constp = VN_CAST(nodep->rhsp(), Const); - AstBasicDType* const basicp = VN_CAST(nodep->rhsp(), BasicDType); - if (!constp && !basicp) { - nodep->v3error("Slice size isn't a constant or basic data type."); - return; - } - if (basicp) { // Convert data type to a constant size - AstConst* const newp = new AstConst(basicp->fileline(), basicp->width()); - nodep->rhsp()->replaceWith(newp); - pushDeletep(basicp); + if (const AstConst* const constp = VN_CAST(nodep->rhsp(), Const)) { + if (constp->toUInt() == 0) nodep->v3error("Slice size cannot be zero."); } else { - const uint32_t sliceSize = constp->toUInt(); - if (!sliceSize) { - nodep->v3error("Slice size cannot be zero."); - return; - } + nodep->v3error("Slice size isn't a constant or basic data type."); } nodep->dtypeSetLogicUnsized(nodep->lhsp()->width(), nodep->lhsp()->widthMin(), VSigning::UNSIGNED); @@ -1444,8 +1432,8 @@ private: if (VN_IS(dtypep, QueueDType)) { switch (nodep->attrType()) { case VAttrType::DIM_SIZE: { - AstNode* const newp = new AstCMethodHard( - nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"); + AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr); + AstNode* const newp = new AstCMethodHard{nodep->fileline(), fromp, "size"}; newp->dtypeSetSigned32(); newp->didWidth(true); newp->protect(false); @@ -1462,8 +1450,9 @@ private: } case VAttrType::DIM_RIGHT: case VAttrType::DIM_HIGH: { - AstNode* const sizep = new AstCMethodHard( - nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"); + AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr); + AstNodeExpr* const sizep + = new AstCMethodHard{nodep->fileline(), fromp, "size"}; sizep->dtypeSetSigned32(); sizep->didWidth(true); sizep->protect(false); @@ -1475,7 +1464,7 @@ private: break; } case VAttrType::DIM_INCREMENT: { - AstNode* const newp + AstNodeExpr* const newp = new AstConst(nodep->fileline(), AstConst::Signed32(), -1); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -1493,9 +1482,9 @@ private: if (!nodep->dimp() || msbdim < 1) { if (VN_IS(dtypep, BasicDType) && dtypep->basicp()->isString()) { // IEEE undocumented but $bits(string) must give length(string) * 8 + AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr); AstNode* const newp = new AstShiftL{ - nodep->fileline(), - new AstLenN{nodep->fileline(), nodep->fromp()->unlinkFrBack()}, + nodep->fileline(), new AstLenN{nodep->fileline(), fromp}, new AstConst{nodep->fileline(), 3}, // * 8 32}; nodep->replaceWith(newp); @@ -1516,8 +1505,8 @@ private: } else { // Need a runtime lookup table. Yuk. UASSERT_OBJ(nodep->fromp() && dtypep, nodep, "Unsized expression"); AstVar* const varp = dimensionVarp(dtypep, nodep->attrType(), msbdim); - AstNode* const dimp = nodep->dimp()->unlinkFrBack(); - AstNode* const newp + AstNodeExpr* const dimp = nodep->dimp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstArraySel{nodep->fileline(), newVarRefDollarUnit(varp), dimp}; nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -1610,7 +1599,7 @@ private: newp = new AstUnpackArrayDType( nodep->fileline(), VFlagChildDType(), childp, new AstRange(nodep->fileline(), new AstConst(elementsp->fileline(), 0), - new AstSub(elementsp->fileline(), elementsp, + new AstSub(elementsp->fileline(), VN_AS(elementsp, NodeExpr), new AstConst(elementsp->fileline(), 1)))); } nodep->replaceWith(newp); @@ -1769,7 +1758,7 @@ private: UASSERT_OBJ(enumDtp, nodep, "$cast determined as enum, but not enum type"); const uint64_t maxval = enumMaxValue(nodep, enumDtp); const bool assoc = maxval > ENUM_LOOKUP_BITS; - AstNode* testp = nullptr; + AstNodeExpr* testp = nullptr; FileLine* const fl_novalue = new FileLine{fl}; fl_novalue->warnOff(V3ErrorCode::ENUMVALUE, true); if (assoc) { @@ -1881,7 +1870,7 @@ private: // For now, replace it ASAP, so widthing can propagate easily // The cast may change signing, but we don't know the sign yet. Make it so. // Note we don't sign fromp() that would make the algorithm O(n^2) if lots of casting. - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; if (bad) { } else if (const AstBasicDType* const basicp = toDtp->basicp()) { if (!basicp->isDouble() && !fromDtp->isDouble()) { @@ -1942,10 +1931,9 @@ private: void visit(AstCastSize* nodep) override { // IEEE: Signedness of result is same as self-determined signedness // However, the result is same as BITSEL, so we do not sign extend the LHS - UASSERT_OBJ(VN_IS(nodep->rhsp(), Const), nodep, "Unsupported: Non-const cast of size"); // if (debug()) nodep->dumpTree(cout, " CastSizePre: "); if (m_vup->prelim()) { - int width = VN_AS(nodep->rhsp(), Const)->toSInt(); + int width = nodep->rhsp()->toSInt(); if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width = 1; @@ -1996,7 +1984,8 @@ private: : nodep->findBitDType(width, width, underDtp->numeric())); nodep->dtypep(outDtp); // We ignore warnings as that is sort of the point of a cast - widthCheckSized(nodep, "Cast expr", underp, outDtp, EXTEND_EXP, false); + widthCheckSized(nodep, "Cast expr", VN_AS(underp, NodeExpr), outDtp, EXTEND_EXP, + false); VL_DANGLING(underp); } } @@ -2403,10 +2392,10 @@ private: nodep->dtypeSetBit(); if (debug() >= 9) nodep->dumpTree(cout, "-inside-in: "); // Now rip out the inside and replace with simple math - AstNode* newp = nullptr; - for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) { - nextip = itemp->nextp(); // Will be unlinking - AstNode* inewp; + AstNodeExpr* newp = nullptr; + for (AstNodeExpr *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) { + nextip = VN_AS(itemp->nextp(), NodeExpr); // Will be unlinking + AstNodeExpr* inewp; const AstNodeDType* const itemDtp = itemp->dtypep()->skipRefp(); if (AstInsideRange* const irangep = VN_CAST(itemp, InsideRange)) { // Similar logic in V3Case @@ -2878,7 +2867,7 @@ private: } else if (nodep->name() == "exists") { // function int exists(input index) // IEEE really should have made this a "bit" return methodOkArguments(nodep, 1, 1); - AstNode* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); + AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", index_exprp->unlinkFrBack()}; newp->dtypeSetSigned32(); @@ -2891,7 +2880,7 @@ private: "clear"}; newp->dtypeSetVoid(); } else { - AstNode* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); + AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "erase", index_exprp->unlinkFrBack()}; newp->dtypeSetVoid(); @@ -2954,7 +2943,7 @@ private: || nodep->name() == "next" // || nodep->name() == "prev") { methodOkArguments(nodep, 1, 1); - AstNode* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); + AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), // first/last/next/prev index_exprp->unlinkFrBack()); @@ -2963,7 +2952,7 @@ private: } else if (nodep->name() == "exists") { // function int exists(input index) // IEEE really should have made this a "bit" return methodOkArguments(nodep, 1, 1); - AstNode* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); + AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", index_exprp->unlinkFrBack()); newp->dtypeSetSigned32(); @@ -2976,7 +2965,7 @@ private: "clear"); newp->dtypeSetVoid(); } else { - AstNode* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); + AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "erase", index_exprp->unlinkFrBack()); newp->dtypeSetVoid(); @@ -3039,14 +3028,15 @@ private: VL_DO_DANGLING(nodep->deleteTree(), nodep); } } - AstNode* methodCallAssocIndexExpr(AstMethodCall* nodep, AstAssocArrayDType* adtypep) { + AstNodeExpr* methodCallAssocIndexExpr(AstMethodCall* nodep, AstAssocArrayDType* adtypep) { AstNode* const index_exprp = VN_CAST(nodep->pinsp(), Arg)->exprp(); iterateCheck(nodep, "index", index_exprp, CONTEXT_DET, FINAL, adtypep->keyDTypep(), EXTEND_EXP); VL_DANGLING(index_exprp); // May have been edited return VN_AS(nodep->pinsp(), Arg)->exprp(); } - AstNode* methodCallWildcardIndexExpr(AstMethodCall* nodep, AstWildcardArrayDType* adtypep) { + AstNodeExpr* methodCallWildcardIndexExpr(AstMethodCall* nodep, + AstWildcardArrayDType* adtypep) { AstNode* const index_exprp = VN_CAST(nodep->pinsp(), Arg)->exprp(); iterateCheck(nodep, "index", index_exprp, CONTEXT_DET, FINAL, adtypep->findStringDType(), EXTEND_EXP); @@ -3172,7 +3162,7 @@ private: "clear"); newp->dtypeSetVoid(); } else { - AstNode* const index_exprp = methodCallQueueIndexExpr(nodep); + AstNodeExpr* const index_exprp = methodCallQueueIndexExpr(nodep); if (index_exprp->isZero()) { // delete(0) is a pop_front newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "pop_front"); @@ -3187,7 +3177,7 @@ private: } else if (nodep->name() == "insert") { methodOkArguments(nodep, 2, 2); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); - AstNode* const index_exprp = methodCallQueueIndexExpr(nodep); + AstNodeExpr* const index_exprp = methodCallQueueIndexExpr(nodep); AstArg* const argp = VN_AS(nodep->pinsp()->nextp(), Arg); iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH); if (index_exprp->isZero()) { // insert(0, ...) is a push_front @@ -3285,7 +3275,7 @@ private: VL_DO_DANGLING(nodep->deleteTree(), nodep); } } - AstNode* methodCallQueueIndexExpr(AstMethodCall* nodep) { + AstNodeExpr* methodCallQueueIndexExpr(AstMethodCall* nodep) { AstNode* const index_exprp = VN_AS(nodep->pinsp(), Arg)->exprp(); iterateCheckSigned32(nodep, "index", index_exprp, BOTH); VL_DANGLING(index_exprp); // May have been edited @@ -3304,7 +3294,7 @@ private: = VN_CAST(classp->findMember(nodep->name()), NodeFTask)) { userIterate(ftaskp, nullptr); if (ftaskp->lifetime().isStatic()) { - AstNode* argsp = nullptr; + AstNodeExpr* argsp = nullptr; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNodeFTaskRef* newp = nullptr; if (VN_IS(ftaskp, Task)) { @@ -3369,10 +3359,10 @@ private: if (methodId) { methodOkArguments(nodep, 0, 0); FileLine* const fl = nodep->fileline(); - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int i = 0; i < adtypep->elementsConst(); ++i) { - AstNode* const arrayRef = nodep->fromp()->cloneTree(false); - AstNode* const selector = new AstArraySel(fl, arrayRef, i); + AstNodeExpr* const arrayRef = nodep->fromp()->cloneTree(false); + AstNodeExpr* const selector = new AstArraySel(fl, arrayRef, i); if (!newp) { newp = selector; } else { @@ -3446,8 +3436,8 @@ private: const bool ignoreCase = nodep->name()[0] == 'i'; methodOkArguments(nodep, 1, 1); AstArg* const argp = VN_AS(nodep->pinsp(), Arg); - AstNode* const lhs = nodep->fromp()->unlinkFrBack(); - AstNode* const rhs = argp->exprp()->unlinkFrBack(); + AstNodeExpr* const lhs = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const rhs = argp->exprp()->unlinkFrBack(); AstNode* const newp = new AstCompareNN(nodep->fileline(), lhs, rhs, ignoreCase); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -3456,8 +3446,8 @@ private: AstArg* const arg0p = VN_AS(nodep->pinsp(), Arg); AstArg* const arg1p = VN_AS(arg0p->nextp(), Arg); AstNodeVarRef* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), VarRef); - AstNode* const rhsp = arg0p->exprp()->unlinkFrBack(); - AstNode* const thsp = arg1p->exprp()->unlinkFrBack(); + AstNodeExpr* const rhsp = arg0p->exprp()->unlinkFrBack(); + AstNodeExpr* const thsp = arg1p->exprp()->unlinkFrBack(); AstVarRef* const varrefp = new AstVarRef(nodep->fileline(), fromp->varp(), VAccess::READ); AstNode* const newp = new AstAssign( @@ -3468,19 +3458,19 @@ private: } else if (nodep->name() == "getc") { methodOkArguments(nodep, 1, 1); AstArg* const arg0p = VN_AS(nodep->pinsp(), Arg); - AstNode* const lhsp = nodep->fromp()->unlinkFrBack(); - AstNode* const rhsp = arg0p->exprp()->unlinkFrBack(); - AstNode* const newp = new AstGetcN(nodep->fileline(), lhsp, rhsp); + AstNodeExpr* const lhsp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const rhsp = arg0p->exprp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstGetcN(nodep->fileline(), lhsp, rhsp); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "substr") { methodOkArguments(nodep, 2, 2); AstArg* const arg0p = VN_AS(nodep->pinsp(), Arg); AstArg* const arg1p = VN_AS(arg0p->nextp(), Arg); - AstNode* const lhsp = nodep->fromp()->unlinkFrBack(); - AstNode* const rhsp = arg0p->exprp()->unlinkFrBack(); - AstNode* const thsp = arg1p->exprp()->unlinkFrBack(); - AstNode* const newp = new AstSubstrN(nodep->fileline(), lhsp, rhsp, thsp); + AstNodeExpr* const lhsp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const rhsp = arg0p->exprp()->unlinkFrBack(); + AstNodeExpr* const thsp = arg1p->exprp()->unlinkFrBack(); + AstNodeExpr* const newp = new AstSubstrN(nodep->fileline(), lhsp, rhsp, thsp); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "atobin" || nodep->name() == "atohex" @@ -3628,7 +3618,7 @@ private: // So detach, add next and reattach VNRelinker relinkHandle; patp->unlinkFrBack(&relinkHandle); - while (AstNode* const movep = patp->lhssp()->nextp()) { + while (AstNodeExpr* const movep = VN_AS(patp->lhssp()->nextp(), NodeExpr)) { movep->unlinkFrBack(); // Not unlinkFrBackWithNext, just one AstNode* newkeyp = nullptr; if (patp->keyp()) newkeyp = patp->keyp()->cloneTree(true); @@ -3743,7 +3733,7 @@ private: if (patp) patp = VN_AS(patp->nextp(), PatMember); } } - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (AstMemberDType* memp = vdtypep->membersp(); memp; memp = VN_AS(memp->nextp(), MemberDType)) { const auto it = patmap.find(memp); @@ -3773,9 +3763,9 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); // Deletes defaultp also, if present } - AstNode* nestedvalueConcat_patternUOrStruct(AstNodeUOrStructDType* memp_vdtypep, - AstPatMember* defaultp, AstNode* newp, - AstPattern* nodep, DTypeMap dtypemap) { + AstNodeExpr* nestedvalueConcat_patternUOrStruct(AstNodeUOrStructDType* memp_vdtypep, + AstPatMember* defaultp, AstNodeExpr* newp, + AstPattern* nodep, DTypeMap dtypemap) { AstPatMember* patp = nullptr; for (AstMemberDType* memp_nested = memp_vdtypep->membersp(); memp_nested; memp_nested = VN_AS(memp_nested->nextp(), MemberDType)) { @@ -3816,11 +3806,11 @@ private: return patp; } - AstNode* valueConcat_patternUOrStruct(AstPatMember* patp, AstNode* newp, AstMemberDType* memp, - AstPattern* nodep) { + AstNodeExpr* valueConcat_patternUOrStruct(AstPatMember* patp, AstNodeExpr* newp, + AstMemberDType* memp, AstPattern* nodep) { if (patp) { patp->dtypep(memp); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); if (!newp) { newp = valuep; } else { @@ -3858,11 +3848,11 @@ private: if (patp) { // Don't want the RHS an array patp->dtypep(arrayDtp->subDTypep()); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); if (VN_IS(arrayDtp, UnpackArrayDType)) { if (!newp) { AstInitArray* const newap - = new AstInitArray(nodep->fileline(), arrayDtp, nullptr); + = new AstInitArray{nodep->fileline(), arrayDtp, nullptr}; newp = newap; } VN_AS(newp, InitArray)->addIndexValuep(ent - range.lo(), valuep); @@ -3870,7 +3860,8 @@ private: if (!newp) { newp = valuep; } else { - AstConcat* const concatp = new AstConcat(patp->fileline(), newp, valuep); + AstConcat* const concatp + = new AstConcat{patp->fileline(), VN_AS(newp, NodeExpr), valuep}; newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width() + concatp->rhsp()->width(), @@ -3892,12 +3883,12 @@ private: void patternAssoc(AstPattern* nodep, AstAssocArrayDType* arrayDtp, AstPatMember* defaultp) { AstNode* defaultValuep = nullptr; if (defaultp) defaultValuep = defaultp->lhssp()->unlinkFrBack(); - AstNode* newp = new AstConsAssoc(nodep->fileline(), defaultValuep); + AstNodeExpr* newp = new AstConsAssoc(nodep->fileline(), defaultValuep); newp->dtypeFrom(arrayDtp); for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp; patp = VN_AS(patp->nextp(), PatMember)) { patp->dtypep(arrayDtp->subDTypep()); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); AstNode* const keyp = patp->keyp(); auto* const newap = new AstSetAssoc(nodep->fileline(), newp, keyp->unlinkFrBack(), valuep); @@ -3917,7 +3908,7 @@ private: for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp; patp = VN_AS(patp->nextp(), PatMember)) { patp->dtypep(arrayDtp->subDTypep()); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); AstNode* const keyp = patp->keyp(); auto* const newap = new AstSetWildcard{nodep->fileline(), newp, keyp->unlinkFrBack(), valuep}; @@ -3934,7 +3925,7 @@ private: for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp; patp = VN_AS(patp->nextp(), PatMember)) { patp->dtypep(arrayp->subDTypep()); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); auto* const newap = new AstConsDynArray(nodep->fileline(), valuep, newp); newap->dtypeFrom(arrayp); newp = newap; @@ -3949,7 +3940,7 @@ private: for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp; patp = VN_AS(patp->nextp(), PatMember)) { patp->dtypep(arrayp->subDTypep()); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); auto* const newap = new AstConsQueue(nodep->fileline(), valuep, newp); newap->dtypeFrom(arrayp); newp = newap; @@ -3963,7 +3954,7 @@ private: const VNumRange range = bdtypep->declRange(); PatVecMap patmap = patVectorMap(nodep, range); UINFO(9, "ent " << range.hi() << " to " << range.lo() << endl); - AstNode* newp = nullptr; + AstNodeExpr* newp = nullptr; for (int ent = range.hi(); ent >= range.lo(); --ent) { AstPatMember* newpatp = nullptr; AstPatMember* patp = nullptr; @@ -3983,7 +3974,7 @@ private: // Determine initial values vdtypep = nodep->findBitDType(); patp->dtypep(vdtypep); - AstNode* const valuep = patternMemberValueIterate(patp); + AstNodeExpr* const valuep = patternMemberValueIterate(patp); { // Packed. Convert to concat for now. if (!newp) { newp = valuep; @@ -4007,15 +3998,15 @@ private: // if (debug() >= 9) newp->dumpTree("-apat-out: "); VL_DO_DANGLING(pushDeletep(nodep), nodep); // Deletes defaultp also, if present } - AstNode* patternMemberValueIterate(AstPatMember* patp) { + AstNodeExpr* patternMemberValueIterate(AstPatMember* patp) { // Determine values - might be another InitArray userIterate(patp, WidthVP(patp->dtypep(), BOTH).p()); // Convert to InitArray or constify immediately - AstNode* valuep = patp->lhssp()->unlinkFrBack(); + AstNodeExpr* valuep = patp->lhssp()->unlinkFrBack(); if (VN_IS(valuep, Const)) { // Forming a AstConcat will cause problems with // unsized (uncommitted sized) constants - if (AstNode* const newp + if (AstConst* const newp = WidthCommitVisitor::newIfConstCommitSize(VN_AS(valuep, Const))) { VL_DO_DANGLING(pushDeletep(valuep), valuep); valuep = newp; @@ -4179,7 +4170,7 @@ private: UASSERT_OBJ(loopsp, nodep, "No loop variables under foreach"); // if (debug()) nodep->dumpTree(cout, "-foreach-old: "); userIterateAndNext(loopsp->fromp(), WidthVP(SELF, BOTH).p()); - AstNode* const fromp = loopsp->fromp(); + AstNodeExpr* const fromp = loopsp->fromp(); UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type"); AstNodeDType* fromDtp = fromp->dtypep()->skipRefp(); // Split into for loop @@ -4248,10 +4239,11 @@ private: sizep->dtypeSetSigned32(); sizep->didWidth(true); sizep->protect(false); - AstNode* const condp + AstNodeExpr* const condp = new AstLt{fl, new AstVarRef{fl, varp, VAccess::READ}, sizep}; - AstNode* const incp = new AstAdd{fl, new AstConst{fl, AstConst::Signed32{}, 1}, - new AstVarRef{fl, varp, VAccess::READ}}; + AstNodeExpr* const incp + = new AstAdd{fl, new AstConst{fl, AstConst::Signed32{}, 1}, + new AstVarRef{fl, varp, VAccess::READ}}; loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, condp, incp); } // Prep for next @@ -4267,10 +4259,10 @@ private: AstVar* const first_varp = new AstVar{ fl, VVarType::BLOCKTEMP, varp->name() + "__Vfirst", VFlagBitPacked{}, 1}; first_varp->usedLoopIdx(true); - AstNode* const firstp = new AstMethodCall{ + AstNodeExpr* const firstp = new AstMethodCall{ fl, fromp->cloneTree(false), "first", new AstArg{fl, "", new AstVarRef{fl, varp, VAccess::READWRITE}}}; - AstNode* const nextp = new AstMethodCall{ + AstNodeExpr* const nextp = new AstMethodCall{ fl, fromp->cloneTree(false), "next", new AstArg{fl, "", new AstVarRef{fl, varp, VAccess::READWRITE}}}; AstNode* const first_clearp @@ -4322,10 +4314,10 @@ private: AstNode* createForeachLoopRanged(AstForeach* nodep, AstNode* bodysp, AstVar* varp, const VNumRange& declRange) { FileLine* const fl = varp->fileline(); - auto* const leftp = new AstConst{fl, AstConst::Signed32{}, declRange.left()}; - auto* const rightp = new AstConst{fl, AstConst::Signed32{}, declRange.right()}; - AstNode* condp; - AstNode* incp; + AstNodeExpr* const leftp = new AstConst{fl, AstConst::Signed32{}, declRange.left()}; + AstNodeExpr* const rightp = new AstConst{fl, AstConst::Signed32{}, declRange.right()}; + AstNodeExpr* condp; + AstNodeExpr* incp; if (declRange.left() < declRange.right()) { condp = new AstLte{fl, new AstVarRef{fl, varp, VAccess::READ}, rightp}; incp = new AstAdd{fl, new AstConst{fl, AstConst::Signed32{}, 1}, @@ -4337,8 +4329,8 @@ private: } return createForeachLoop(nodep, bodysp, varp, leftp, condp, incp); } - AstNode* createForeachLoop(AstForeach* nodep, AstNode* bodysp, AstVar* varp, AstNode* leftp, - AstNode* condp, AstNode* incp) { + AstNode* createForeachLoop(AstForeach* nodep, AstNode* bodysp, AstVar* varp, + AstNodeExpr* leftp, AstNodeExpr* condp, AstNodeExpr* incp) { FileLine* const fl = varp->fileline(); auto* const whilep = new AstWhile{ fl, condp, bodysp, new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, incp}}; @@ -4454,7 +4446,7 @@ private: UINFO(9, " Display in " << nodep->text() << endl); string newFormat; bool inPct = false; - AstNode* argp = nodep->exprsp(); + AstNodeExpr* argp = nodep->exprsp(); const string txt = nodep->text(); string fmt; for (char ch : txt) { @@ -4472,7 +4464,7 @@ private: case 'l': break; // %m - auto insert "library" case 'd': { // Convert decimal to either 'd' or '#' if (argp) { - AstNode* const nextp = argp->nextp(); + AstNodeExpr* const nextp = VN_AS(argp->nextp(), NodeExpr); if (argp->isDouble()) { spliceCvtS(argp, true, 64); ch = '~'; @@ -4501,14 +4493,18 @@ private: newFormat += "%@"; VNRelinker handle; argp->unlinkFrBack(&handle); - AstCExpr* const newp - = new AstCExpr(nodep->fileline(), "VL_TO_STRING(", 0, true); + FileLine* const flp = nodep->fileline(); + AstCExpr* const newp = new AstCExpr{flp, nullptr}; + newp->addExprsp(new AstText{flp, "VL_TO_STRING(", true}); newp->addExprsp(argp); - newp->addExprsp(new AstText(nodep->fileline(), ")", true)); + newp->addExprsp(new AstText{flp, ")", true}); newp->dtypeSetString(); newp->pure(true); newp->protect(false); handle.relink(newp); + // Set argp to what we replaced it with, as we will keep processing the + // next argument. + argp = newp; } else { added = true; if (fmt == "%0") { @@ -4517,19 +4513,19 @@ private: newFormat += "%d"; } } - if (argp) argp = argp->nextp(); + if (argp) argp = VN_AS(argp->nextp(), NodeExpr); break; } case 's': { // Convert string to pack string if (argp && argp->dtypep()->basicp()->isString()) { // Convert it ch = '@'; } - if (argp) argp = argp->nextp(); + if (argp) argp = VN_AS(argp->nextp(), NodeExpr); break; } case 't': { // Convert decimal time to realtime if (argp) { - AstNode* const nextp = argp->nextp(); + AstNodeExpr* const nextp = VN_AS(argp->nextp(), NodeExpr); if (argp->isDouble()) ch = '^'; // Convert it if (nodep->timeunit().isNone()) { nodep->v3fatalSrc("display %t has no time units"); @@ -4541,7 +4537,7 @@ private: case 'f': // FALLTHRU case 'g': { if (argp) { - AstNode* const nextp = argp->nextp(); + AstNodeExpr* const nextp = VN_AS(argp->nextp(), NodeExpr); if (!argp->isDouble()) { iterateCheckReal(nodep, "Display argument", argp, BOTH); } @@ -4559,11 +4555,11 @@ private: } else { ch = nodep->missingArgChar(); } - if (argp) argp = argp->nextp(); + if (argp) argp = VN_AS(argp->nextp(), NodeExpr); break; } default: { // Most operators, just move to next argument - if (argp) argp = argp->nextp(); + if (argp) argp = VN_AS(argp->nextp(), NodeExpr); break; } } // switch @@ -5124,7 +5120,7 @@ private: for (const auto& tconnect : tconnects) { const AstVar* const portp = tconnect.first; AstArg* const argp = tconnect.second; - AstNode* pinp = argp->exprp(); + AstNodeExpr* pinp = argp->exprp(); if (!pinp) continue; // Argument error we'll find later // Prelim may cause the node to get replaced; we've lost our // pointer, so need to iterate separately later @@ -5133,11 +5129,10 @@ private: UINFO(4, " sformat via metacomment: " << nodep << endl); VNRelinker handle; argp->unlinkFrBackWithNext(&handle); // Format + additional args, if any - AstNode* argsp = nullptr; + AstNodeExpr* argsp = nullptr; while (AstArg* const nextargp = VN_AS(argp->nextp(), Arg)) { - argsp = AstNode::addNext( - argsp, nextargp->exprp() - ->unlinkFrBackWithNext()); // Expression goes to SFormatF + // Expression goes to SFormatF + argsp = argsp->addNext(nextargp->exprp()->unlinkFrBackWithNext()); nextargp->unlinkFrBack()->deleteTree(); // Remove the call's Arg wrapper } string format; @@ -5167,7 +5162,7 @@ private: UINFO(4, " Add CvtPackString: " << pinp << endl); VNRelinker handle; pinp->unlinkFrBack(&handle); // No next, that's the next pin - AstNode* const newp = new AstCvtPackString(pinp->fileline(), pinp); + AstNodeExpr* const newp = new AstCvtPackString(pinp->fileline(), pinp); handle.relink(newp); pinp = newp; } @@ -5181,7 +5176,7 @@ private: for (const auto& tconnect : tconnects) { AstVar* const portp = tconnect.first; const AstArg* const argp = tconnect.second; - AstNode* const pinp = argp->exprp(); + AstNodeExpr* const pinp = argp->exprp(); if (!pinp) continue; // Argument error we'll find later // Change data types based on above accept completion if (nodep->taskp()->dpiImport()) checkUnpackedArrayArgs(portp, pinp); @@ -5194,7 +5189,7 @@ private: for (const auto& tconnect : tconnects) { const AstVar* const portp = tconnect.first; const AstArg* const argp = tconnect.second; - AstNode* const pinp = argp->exprp(); + AstNodeExpr* const pinp = argp->exprp(); if (!pinp) continue; // Argument error we'll find later // Do PRELIM again, because above accept may have exited early // due to node replacement @@ -5827,7 +5822,7 @@ private: return false; } - void fixWidthExtend(AstNode* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) { + void fixWidthExtend(AstNodeExpr* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) { // Fix the width mismatch by extending or truncating bits // *ONLY* call this from checkWidth() // Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312; @@ -5848,7 +5843,7 @@ private: V3Number num(nodep, expWidth); num.opAssign(constp->num()); num.isSigned(false); - AstNode* const newp = new AstConst(nodep->fileline(), num); + AstNodeExpr* const newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); VL_DO_DANGLING(pushDeletep(constp), constp); VL_DANGLING(nodep); @@ -5857,7 +5852,7 @@ private: // Trunc - Extract VNRelinker linker; nodep->unlinkFrBack(&linker); - AstNode* const newp = new AstSel(nodep->fileline(), nodep, 0, expWidth); + AstNodeExpr* const newp = new AstSel(nodep->fileline(), nodep, 0, expWidth); newp->didWidth(true); // Don't replace dtype with unsigned linker.relink(newp); nodep = newp; @@ -5872,9 +5867,9 @@ private: case EXTEND_LHS: doSigned = nodep->isSigned(); break; default: nodep->v3fatalSrc("bad case"); } - AstNode* const newp - = (doSigned ? static_cast(new AstExtendS{nodep->fileline(), nodep}) - : static_cast(new AstExtend{nodep->fileline(), nodep})); + AstNodeExpr* const newp + = (doSigned ? static_cast(new AstExtendS{nodep->fileline(), nodep}) + : static_cast(new AstExtend{nodep->fileline(), nodep})); linker.relink(newp); nodep = newp; } @@ -5882,14 +5877,14 @@ private: // For AstVar init() among others // TODO do all to-real and to-integer conversions in this function // rather than in callers - AstNode* const newp = spliceCvtD(nodep); + AstNodeExpr* const newp = spliceCvtD(nodep); nodep = newp; } nodep->dtypeFrom(expDTypep); UINFO(4, " _new: " << nodep << endl); } - void fixWidthReduce(AstNode* nodep) { + void fixWidthReduce(AstNodeExpr* nodep) { // Fix the width mismatch by adding a reduction OR operator // IF (A(CONSTwide)) becomes IF (A(CONSTreduced)) // IF (A(somewide)) becomes IF (A(REDOR(somewide))) @@ -5902,7 +5897,7 @@ private: V3Number num(nodep, expWidth); num.opRedOr(constp->num()); num.isSigned(expSigned); - AstNode* const newp = new AstConst(nodep->fileline(), num); + AstNodeExpr* const newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); VL_DO_DANGLING(constp->deleteTree(), constp); VL_DANGLING(nodep); @@ -5910,7 +5905,7 @@ private: } else { VNRelinker linker; nodep->unlinkFrBack(&linker); - AstNode* const newp = new AstRedOr(nodep->fileline(), nodep); + AstNodeExpr* const newp = new AstRedOr(nodep->fileline(), nodep); linker.relink(newp); nodep = newp; } @@ -5918,14 +5913,14 @@ private: UINFO(4, " _new: " << nodep << endl); } - bool fixAutoExtend(AstNode*& nodepr, int expWidth) { + bool fixAutoExtend(AstNodeExpr*& nodepr, int expWidth) { // For SystemVerilog '0,'1,'x,'z, autoextend and don't warn if (AstConst* const constp = VN_CAST(nodepr, Const)) { if (constp->num().autoExtend() && !constp->num().sized() && constp->width() == 1) { // Make it the proper size. Careful of proper extension of 0's/1's V3Number num(constp, expWidth); num.opRepl(constp->num(), expWidth); // {width{'1}} - AstNode* const newp = new AstConst(constp->fileline(), num); + AstNodeExpr* const newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width if (debug() > 4) constp->dumpTree(cout, " fixAutoExtend_old: "); if (debug() > 4) newp->dumpTree(cout, " _new: "); @@ -5943,7 +5938,7 @@ private: << expWidth << " bits: " << constp->prettyName()); V3Number num(constp, expWidth); num.opExtendXZ(constp->num(), constp->width()); - AstNode* const newp = new AstConst(constp->fileline(), num); + AstNodeExpr* const newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width if (debug() > 4) constp->dumpTree(cout, " fixUnszExtend_old: "); if (debug() > 4) newp->dumpTree(cout, " _new: "); @@ -6037,7 +6032,7 @@ private: if (stage & PRELIM) { underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p()); } - underp = checkCvtUS(underp); + underp = VN_IS(underp, NodeExpr) ? checkCvtUS(VN_AS(underp, NodeExpr)) : underp; AstNodeDType* const expDTypep = underp->dtypep(); underp = iterateCheck(nodep, side, underp, SELF, FINAL, expDTypep, EXTEND_EXP); if (underp) {} // cppcheck @@ -6076,14 +6071,14 @@ private: VNRelinker linker; underp->unlinkFrBack(&linker); AstNode* const newp - = new AstNeqD(nodep->fileline(), underp, + = new AstNeqD(nodep->fileline(), VN_AS(underp, NodeExpr), new AstConst(nodep->fileline(), AstConst::RealDouble(), 0.0)); linker.relink(newp); } else if (VN_IS(underVDTypep, ClassRefDType) || (VN_IS(underVDTypep, BasicDType) && VN_AS(underVDTypep, BasicDType)->keyword() == VBasicDTypeKwd::CHANDLE)) { // Allow warning-free "if (handle)" - VL_DO_DANGLING(fixWidthReduce(underp), underp); // Changed + VL_DO_DANGLING(fixWidthReduce(VN_AS(underp, NodeExpr)), underp); // Changed } else if (!underVDTypep->basicp()) { nodep->v3error("Logical operator " << nodep->prettyTypeName() << " expects a non-complex data type on the " @@ -6105,7 +6100,7 @@ private: : "") << " bits."); } - VL_DO_DANGLING(fixWidthReduce(underp), underp); // Changed + VL_DO_DANGLING(fixWidthReduce(VN_AS(underp, NodeExpr)), underp); // Changed } } } @@ -6131,17 +6126,17 @@ private: } else if (expDTypep->isDouble() && !underp->isDouble()) { AstNode* const oldp = underp; // Need FINAL on children; otherwise splice would block it - underp = spliceCvtD(underp); + underp = spliceCvtD(VN_AS(underp, NodeExpr)); underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else if (!expDTypep->isDouble() && underp->isDouble()) { AstNode* const oldp = underp; // Need FINAL on children; otherwise splice would block it - underp = spliceCvtS(underp, true, expDTypep->width()); // Round RHS + underp = spliceCvtS(VN_AS(underp, NodeExpr), true, expDTypep->width()); // Round RHS underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else if (expDTypep->isString() && !underp->dtypep()->isString()) { AstNode* const oldp = underp; // Need FINAL on children; otherwise splice would block it - underp = spliceCvtString(underp); + underp = spliceCvtString(VN_AS(underp, NodeExpr)); underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else { const AstBasicDType* const expBasicp = expDTypep->basicp(); @@ -6185,7 +6180,8 @@ private: } // Note the check uses the expected size, not the child's subDTypep as we want the // child node's width to end up correct for the assignment (etc) - widthCheckSized(nodep, side, underp, expDTypep, extendRule, warnOn); + widthCheckSized(nodep, side, VN_AS(underp, NodeExpr), expDTypep, extendRule, + warnOn); } else if (!VN_IS(expDTypep->skipRefp(), IfaceRefDType) && VN_IS(underp->dtypep()->skipRefp(), IfaceRefDType)) { underp->v3error(ucfirst(nodep->prettyOperatorName()) @@ -6226,9 +6222,10 @@ private: return underp; } - void widthCheckSized(AstNode* nodep, const char* side, - AstNode* underp, // Node to be checked or have typecast added in front of - AstNodeDType* expDTypep, ExtendRule extendRule, bool warnOn = true) { + void + widthCheckSized(AstNode* nodep, const char* side, + AstNodeExpr* underp, // Node to be checked or have typecast added in front of + AstNodeDType* expDTypep, ExtendRule extendRule, bool warnOn = true) { // Issue warnings on sized number width mismatches, then do appropriate size extension // Generally iterateCheck is what is wanted instead of this // UINFO(9,"wchk "<isDouble()) { nodep->v3error("Expected integral (non-" << nodep->dtypep()->prettyDTypeName() << ") input to " @@ -6315,14 +6312,14 @@ private: return nodep; } - AstNode* spliceCvtD(AstNode* nodep) { + AstNodeExpr* spliceCvtD(AstNodeExpr* nodep) { // For integer used in REAL context, convert to real // We don't warn here, "2.0 * 2" is common and reasonable if (nodep && !nodep->dtypep()->skipRefp()->isDouble()) { UINFO(6, " spliceCvtD: " << nodep << endl); VNRelinker linker; nodep->unlinkFrBack(&linker); - AstNode* newp; + AstNodeExpr* newp; if (nodep->dtypep()->skipRefp()->isSigned()) { newp = new AstISToRD(nodep->fileline(), nodep); } else { @@ -6334,7 +6331,7 @@ private: return nodep; } } - AstNode* spliceCvtS(AstNode* nodep, bool warnOn, int width) { + AstNodeExpr* spliceCvtS(AstNodeExpr* nodep, bool warnOn, int width) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && nodep->dtypep()->skipRefp()->isDouble()) { @@ -6352,7 +6349,7 @@ private: } } if (warnOn) nodep->v3warn(REALCVT, "Implicit conversion of real to integer"); - AstNode* const newp = new AstRToIRoundS(nodep->fileline(), nodep); + AstNodeExpr* const newp = new AstRToIRoundS(nodep->fileline(), nodep); linker.relink(newp); newp->dtypeSetBitSized(width, VSigning::SIGNED); return newp; @@ -6360,14 +6357,14 @@ private: return nodep; } } - AstNode* spliceCvtString(AstNode* nodep) { + AstNodeExpr* spliceCvtString(AstNodeExpr* nodep) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && !(nodep->dtypep()->basicp() && nodep->dtypep()->basicp()->isString())) { UINFO(6, " spliceCvtString: " << nodep << endl); VNRelinker linker; nodep->unlinkFrBack(&linker); - AstNode* const newp = new AstCvtPackString(nodep->fileline(), nodep); + AstNodeExpr* const newp = new AstCvtPackString(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { @@ -6393,8 +6390,8 @@ private: default: break; } FileLine* const fl = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = nullptr; switch (nodep->type()) { case VNType::atGt: newp = new AstGtS(fl, lhsp, rhsp); break; @@ -6428,8 +6425,8 @@ private: // Return new node or nullptr if nothing if (nodep->doubleFlavor()) return nullptr; FileLine* const fl = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = nullptr; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { @@ -6467,8 +6464,8 @@ private: // Return new node or nullptr if nothing if (nodep->stringFlavor()) return nullptr; FileLine* const fl = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = nullptr; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { @@ -6499,7 +6496,7 @@ private: // Return new node or nullptr if nothing if (nodep->doubleFlavor()) return nullptr; FileLine* const fl = nodep->fileline(); - AstNode* const lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); AstNodeUniop* newp = nullptr; switch (nodep->type()) { case VNType::atNegate: newp = new AstNegateD(fl, lhsp); break; @@ -6744,7 +6741,7 @@ private: // Find valid values and populate UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items"); - std::map values; + std::map values; { AstEnumItem* const firstp = nodep->itemsp(); const AstEnumItem* prevp = firstp; // Prev must start with last item @@ -6942,7 +6939,7 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } } - AstNode* newVarRefDollarUnit(AstVar* nodep) { + AstVarRef* newVarRefDollarUnit(AstVar* nodep) { AstVarRef* const varrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::READ}; varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); return varrefp; diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 4b02ad87d..42bed398f 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -116,7 +116,7 @@ private: return FromData(errp, ddtypep, fromRange); } - AstNode* newSubNeg(AstNode* lhsp, int32_t rhs) { + AstNodeExpr* newSubNeg(AstNodeExpr* lhsp, int32_t rhs) { // Return lhs-rhs, but if rhs is negative use an add, so we won't // have to deal with signed math and related 32bit sign extension problems if (rhs == 0) { @@ -126,17 +126,16 @@ private: V3Number num(lhsp, lhsp->width()); num.opSub(VN_AS(lhsp, Const)->num(), V3Number(lhsp, 32, rhs)); num.isSigned(lhsp->isSigned()); - AstNode* const newp = new AstConst(lhsp->fileline(), num); - return newp; + return new AstConst(lhsp->fileline(), num); } else if (rhs > 0) { - AstNode* const newp + AstNodeExpr* const newp = new AstSub(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), rhs)); // We must make sure sub gets sign of original value, not from the constant newp->dtypeFrom(lhsp); return newp; } else { // rhs < 0; - AstNode* const newp + AstNodeExpr* const newp = new AstAdd(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs)); // We must make sure sub gets sign of original value, not from the constant @@ -144,16 +143,16 @@ private: return newp; } } - AstNode* newSubNeg(int32_t lhs, AstNode* rhsp) { + AstNodeExpr* newSubNeg(int32_t lhs, AstNodeExpr* rhsp) { // Return lhs-rhs // We must make sure sub gets sign of original value - AstNode* const newp = new AstSub( + AstNodeExpr* const newp = new AstSub( rhsp->fileline(), new AstConst(rhsp->fileline(), AstConst::Unsized32(), lhs), rhsp); newp->dtypeFrom(rhsp); // Important as AstSub default is lhs's sign return newp; } - AstNode* newSubLsbOf(AstNode* underp, const VNumRange& fromRange) { + AstNodeExpr* newSubLsbOf(AstNodeExpr* underp, const VNumRange& fromRange) { // Account for a variable's LSB in bit selections // Will likely become SUB(underp, lsb_of_signal). // Don't report WIDTH warnings etc here, as may be inside a @@ -165,12 +164,10 @@ private: } else { if (fromRange.littleEndian()) { // reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under) - AstNode* const newp = newSubNeg(fromRange.hi(), underp); - return newp; + return newSubNeg(fromRange.hi(), underp); } else { // reg [3:1] needs a SUB(under,1) - AstNode* const newp = newSubNeg(underp, fromRange.lo()); - return newp; + return newSubNeg(underp, fromRange.lo()); } } } @@ -209,8 +206,8 @@ private: UINFO(6, "SELBIT " << nodep << endl); if (debug() >= 9) nodep->backp()->dumpTree(cout, "--SELBT0: "); // lhsp/rhsp do not need to be constant - AstNode* const fromp = nodep->fromp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting + AstNodeExpr* const fromp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting if (debug() >= 9) nodep->dumpTree(cout, "--SELBT2: "); const FromData fromdata = fromDataForArray(nodep, fromp); AstNodeDType* const ddtypep = fromdata.m_dtypep; @@ -218,7 +215,7 @@ private: UINFO(6, " ddtypep " << ddtypep << endl); if (const AstUnpackArrayDType* const adtypep = VN_CAST(ddtypep, UnpackArrayDType)) { // SELBIT(array, index) -> ARRAYSEL(array, index) - AstNode* subp = rhsp; + AstNodeExpr* subp = rhsp; if (fromRange.lo() != 0 || fromRange.hi() < 0) { subp = newSubNeg(subp, fromRange.lo()); } @@ -229,7 +226,7 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (const AstPackArrayDType* const adtypep = VN_CAST(ddtypep, PackArrayDType)) { // SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex) - AstNode* subp = rhsp; + AstNodeExpr* subp = rhsp; if (fromRange.littleEndian()) { subp = newSubNeg(fromRange.hi(), subp); } else { @@ -253,7 +250,7 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (const AstAssocArrayDType* const adtypep = VN_CAST(ddtypep, AssocArrayDType)) { // SELBIT(array, index) -> ASSOCSEL(array, index) - AstNode* const subp = rhsp; + AstNodeExpr* const subp = rhsp; AstAssocSel* const newp = new AstAssocSel(nodep->fileline(), fromp, subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: "); @@ -262,7 +259,7 @@ private: } else if (const AstWildcardArrayDType* const adtypep = VN_CAST(ddtypep, WildcardArrayDType)) { // SELBIT(array, index) -> WILDCARDSEL(array, index) - AstNode* const subp = rhsp; + AstNodeExpr* const subp = rhsp; AstWildcardSel* const newp = new AstWildcardSel{nodep->fileline(), fromp, subp}; newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: "); @@ -270,7 +267,7 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (const AstDynArrayDType* const adtypep = VN_CAST(ddtypep, DynArrayDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) - AstNode* const subp = rhsp; + AstNodeExpr* const subp = rhsp; AstCMethodHard* const newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: "); @@ -278,7 +275,7 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (const AstQueueDType* const adtypep = VN_CAST(ddtypep, QueueDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) - AstNode* const subp = rhsp; + AstNodeExpr* const subp = rhsp; AstCMethodHard* const newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: "); @@ -291,7 +288,7 @@ private: nodep->v3warn(E_UNSUPPORTED, "Unsupported: String array operation on non-variable"); } - AstNode* newp; + AstNodeExpr* newp; if (varrefp && varrefp->access().isReadOnly()) { newp = new AstGetcN(nodep->fileline(), fromp, rhsp); } else { @@ -345,9 +342,9 @@ private: "First value of [a:b] isn't a constant, maybe you want +: or -:"); checkConstantOrReplace(nodep->rightp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:"); - AstNode* const fromp = nodep->fromp()->unlinkFrBack(); - AstNode* const msbp = nodep->rhsp()->unlinkFrBack(); - AstNode* const lsbp = nodep->thsp()->unlinkFrBack(); + AstNodeExpr* const fromp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const msbp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const lsbp = nodep->thsp()->unlinkFrBack(); int32_t msb = VN_AS(msbp, Const)->toSInt(); int32_t lsb = VN_AS(lsbp, Const)->toSInt(); const int32_t elem = (msb > lsb) ? (msb - lsb + 1) : (lsb - msb + 1); @@ -424,7 +421,7 @@ private: msb = lsb; lsb = x; } - AstNode* const widthp + AstNodeExpr* const widthp = new AstConst(msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user msb + 1 - lsb); @@ -447,7 +444,7 @@ private: msb = lsb; lsb = x; } - AstNode* const widthp + AstNodeExpr* const widthp = new AstConst(msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user msb + 1 - lsb); @@ -493,9 +490,9 @@ private: checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant"); if (debug() >= 9) nodep->dumpTree(cout, "--SELPM3: "); // Now replace it with an AstSel - AstNode* const fromp = nodep->fromp()->unlinkFrBack(); - AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); - AstNode* const widthp = nodep->thsp()->unlinkFrBack(); + AstNodeExpr* const fromp = nodep->fromp()->unlinkFrBack(); + AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); + AstNodeExpr* const widthp = nodep->thsp()->unlinkFrBack(); warnTri(rhsp); const int width = VN_AS(widthp, Const)->toSInt(); if (width > (1 << 28)) { @@ -536,13 +533,13 @@ private: || (VN_IS(ddtypep, NodeUOrStructDType) && VN_AS(ddtypep, NodeUOrStructDType)->packedUnsup())) { int elwidth = 1; - AstNode* newwidthp = widthp; + AstNodeExpr* newwidthp = widthp; if (const AstPackArrayDType* const adtypep = VN_CAST(ddtypep, PackArrayDType)) { elwidth = adtypep->width() / fromRange.elements(); newwidthp = new AstConst(nodep->fileline(), AstConst::Unsized32(), width * elwidth); } - AstNode* newlsbp = nullptr; + AstNodeExpr* newlsbp = nullptr; if (VN_IS(nodep, SelPlus)) { if (fromRange.littleEndian()) { // SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width) diff --git a/src/astgen b/src/astgen index acbb4575e..6d656117f 100755 --- a/src/astgen +++ b/src/astgen @@ -425,9 +425,10 @@ class Cpt: key=lambda val: self._exec_syms[val]): argnp = self._exec_syms[sym] arg = self.add_nodep(sym) - out += "AstNode* " + argnp + " = " + arg + "->unlinkFrBack();\n" + out += "AstNodeExpr* " + argnp + " = " + arg + "->unlinkFrBack();\n" - out += "AstNode* newp = " + self._exec_new_recurse(aref) + ";\n" + out += "AstNodeExpr* newp = " + self._exec_new_recurse( + aref) + ";\n" out += "nodep->replaceWith(newp);" out += "VL_DO_DANGLING(nodep->deleteTree(), nodep);" elif func == "NEVER": @@ -918,12 +919,18 @@ def write_ast_macros(filename): for node in AstNodeList: fh.write("#define ASTGEN_MEMBERS_Ast{t} \\\n".format(t=node.name)) emitBlock('''\ - static Ast{t}* cloneTreeNull(Ast{t}* nodep, bool cloneNextLink) {{ - return nodep ? nodep->cloneTree(cloneNextLink) : nullptr; + Ast{t}* unlinkFrBack(VNRelinker* linkerp = nullptr) {{ + return static_cast(AstNode::unlinkFrBack(linkerp)); + }} + Ast{t}* unlinkFrBackWithNext(VNRelinker* linkerp = nullptr) {{ + return static_cast(AstNode::unlinkFrBackWithNext(linkerp)); }} Ast{t}* cloneTree(bool cloneNext) {{ return static_cast(AstNode::cloneTree(cloneNext)); }} + static Ast{t}* cloneTreeNull(Ast{t}* nodep, bool cloneNextLink) {{ + return nodep ? nodep->cloneTree(cloneNextLink) : nullptr; + }} Ast{t}* clonep() const VL_MT_SAFE {{ return static_cast(AstNode::clonep()); }} Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast(AstNode::addNext(this, nodep)); }} ''', diff --git a/src/verilog.y b/src/verilog.y index 930683c25..3958341cc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -112,7 +112,7 @@ public: } // METHODS - AstArg* argWrapList(AstNode* nodep); + AstArg* argWrapList(AstNodeExpr* nodep); bool allTracingOn(FileLine* fl) { return v3Global.opt.trace() && m_tracingParse && fl->tracingOn(); } @@ -155,7 +155,7 @@ public: AstNode::addNext(nodep, new AstStop(fileline, true)); return nodep; } - AstNode* createGatePin(AstNode* exprp) { + AstNodeExpr* createGatePin(AstNodeExpr* exprp) { AstRange* const rangep = m_gateRangep; if (!rangep) { return exprp; @@ -2238,7 +2238,7 @@ enumNameRangeE: // IEEE: second part of enum_name_declaration { $$ = new AstRange{$1, $2, $4}; } ; -enumNameStartE: // IEEE: third part of enum_name_declaration +enumNameStartE: // IEEE: third part of enum_name_declaration /* empty */ { $$ = nullptr; } | '=' constExpr { $$ = $2; } ; @@ -2790,7 +2790,7 @@ delay_control: //== IEEE: delay_control { $$ = new AstDelay{$1, $3}; RISEFALLDLYUNSUP($3); DEL($5); DEL($7); } ; -delay_value: // ==IEEE:delay_value +delay_value: // ==IEEE:delay_value // // IEEE: ps_identifier packageClassScopeE varRefBase { $$ = AstDot::newIfPkg($2, $1, $2); } | yaINTNUM { $$ = new AstConst($1, *$1); } @@ -2798,11 +2798,11 @@ delay_value: // ==IEEE:delay_value | timeNumAdjusted { $$ = $1; } ; -delayExpr: +delayExpr: expr { $$ = $1; } ; -minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression +minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression delayExpr { $$ = $1; } | delayExpr ':' delayExpr ':' delayExpr { $$ = $3; MINTYPMAXDLYUNSUP($3); DEL($1); DEL($5); } ; @@ -3312,20 +3312,24 @@ statement_item: // IEEE: statement_item FileLine* const newfl = new FileLine{$$->fileline()}; newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true); $$->fileline(newfl); - if (AstNodeExpr* const exprp = VN_CAST($$, NodeExpr)) $$ = exprp->makeStmt(); } + $$ = VN_AS($$, NodeExpr)->makeStmt(); } | yVOID yP_TICK '(' expr '.' task_subroutine_callNoMethod ')' ';' { $$ = new AstDot{$5, false, $4, $6}; FileLine* const newfl = new FileLine{$6->fileline()}; newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true); $6->fileline(newfl); - if (AstNodeExpr* const exprp = VN_CAST($$, NodeExpr)) $$ = exprp->makeStmt(); } + $$ = VN_AS($$, NodeExpr)->makeStmt(); } + | yVOID yP_TICK '(' system_t_call ')' ';' + { $$ = $4; + FileLine* const newfl = new FileLine{$$->fileline()}; + newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true); + $$->fileline(newfl); } // // Expr included here to resolve our not knowing what is a method call // // Expr here must result in a subroutine_call - | task_subroutine_callNoMethod ';' - { $$ = $1; - if (AstNodeExpr* const exprp = VN_CAST($$, NodeExpr)) $$ = exprp->makeStmt(); } + | task_subroutine_callNoMethod ';' { $$ = $1->makeStmt(); } //UNSUP fexpr '.' array_methodNoRoot ';' { UNSUP } | fexpr '.' task_subroutine_callNoMethod ';' { $$ = (new AstDot{$2, false, $1, $3})->makeStmt(); } + | system_t_call ';' { $$ = $1; } //UNSUP fexprScope ';' { UNSUP } // // Not here in IEEE; from class_constructor_declaration // // Because we've joined class_constructor_declaration into generic functions @@ -3496,14 +3500,14 @@ finc_or_dec_expression: // ==IEEE: inc_or_dec_expression //UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g}) // {copied} //UNSUP ; -class_new: // ==IEEE: class_new +class_new: // ==IEEE: class_new // // Special precence so (...) doesn't match expr yNEW__ETC { $$ = new AstNew($1, nullptr); } | yNEW__ETC expr { $$ = new AstNewCopy($1, $2); } | yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew($1, $3); } ; -dynamic_array_new: // ==IEEE: dynamic_array_new +dynamic_array_new: // ==IEEE: dynamic_array_new yNEW__ETC '[' expr ']' { $$ = new AstNewDynamic($1, $3, nullptr); } | yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNewDynamic($1, $3, $6); } ; @@ -3569,16 +3573,16 @@ rand_case_itemList: // IEEE: { rand_case_item + ... } | rand_case_itemList expr colon stmtBlock { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); } ; -open_range_list: // ==IEEE: open_range_list + open_value_range +open_range_list: // ==IEEE: open_range_list + open_value_range open_value_range { $$ = $1; } | open_range_list ',' open_value_range { $$ = $1->addNext($3); } ; -open_value_range: // ==IEEE: open_value_range +open_value_range: // ==IEEE: open_value_range value_range { $$ = $1; } ; -value_range: // ==IEEE: value_range +value_range: // ==IEEE: value_range expr { $$ = $1; } | '[' expr ':' expr ']' { $$ = new AstInsideRange($1, $2, $4); } ; @@ -3588,7 +3592,7 @@ value_range: // ==IEEE: value_range //UNSUP | '[' cgexpr ':' cgexpr ']' { } //UNSUP ; -caseCondList: // IEEE: part of case_item +caseCondList: // IEEE: part of case_item expr { $$ = $1; } | caseCondList ',' expr { $$ = $1->addNext($3); } ; @@ -3752,14 +3756,13 @@ funcRef: // IEEE: part of tf_call //UNSUP: idDotted is really just id to allow dotted method calls ; -task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as task) +task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as task) // // IEEE: tf_call taskRef { $$ = $1; } // // funcref below not task ref to avoid conflict, must later handle either | funcRef yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, $1, $4}; } // // can call as method and yWITH without parenthesis | id yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, new AstFuncRef{$1, *$1, nullptr}, $4}; } - | system_t_call { $$ = $1; } // // IEEE: method_call requires a "." so is in expr // // IEEE: ['std::'] not needed, as normal std package resolution will find it // // IEEE: randomize_call @@ -3785,9 +3788,11 @@ function_subroutine_callNoMethod: // IEEE: function_subroutine | funcRef yWITH__CUR '{' '}' { $$ = new AstWithParse{$2, $1, nullptr}; } ; -system_t_call: // IEEE: system_tf_call (as task) +system_t_call: // IEEE: system_tf_call (as task) // - yaD_PLI systemDpiArgsE { $$ = new AstTaskRef($1, *$1, $2); VN_CAST($$, TaskRef)->pli(true); } + yaD_PLI systemDpiArgsE { AstTaskRef* const refp = new AstTaskRef{$1, *$1, $2}; + refp->pli(true); + $$ = refp->makeStmt(); } // | yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl($1, VDumpCtlType::FILE, $5); DEL($3); $$->addNext(new AstDumpCtl($1, VDumpCtlType::VARS, @@ -3928,7 +3933,7 @@ system_f_call: // IEEE: system_tf_call (as func) | system_f_call_or_t { $$ = $1; } ; -systemDpiArgsE: // IEEE: part of system_if_call for aruments of $dpi call +systemDpiArgsE: // IEEE: part of system_if_call for aruments of $dpi call parenE { $$ = nullptr; } | '(' exprList ')' { $$ = GRAMMARP->argWrapList($2); } ; @@ -4088,7 +4093,7 @@ exprOrDataType: // expr | data_type: combined to prevent conflic //UNSUP | exprOrDataTypeList ',' exprOrDataType { $$ = addNextNull($1, $3); } //UNSUP ; -list_of_argumentsE: // IEEE: [list_of_arguments] +list_of_argumentsE: // IEEE: [list_of_arguments] argsDottedList { $$ = $1; } | argsExprListE { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { @@ -4325,7 +4330,7 @@ array_methodNoRoot: | yUNIQUE { $$ = new AstFuncRef($1, "unique", nullptr); } ; -array_methodWith: +array_methodWith: array_methodNoRoot parenE { $$ = $1; } | array_methodNoRoot parenE yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$3, $1, $5}; } @@ -4390,7 +4395,7 @@ dpi_tf_TraceInitE: // Verilator extension // ~p~ means this is a (p)arenthetized expression // it will get replaced by "", or "s"equence -exprEqE: // IEEE: optional '=' expression (part of param_assignment) +exprEqE: // IEEE: optional '=' expression (part of param_assignment) // // constant_param_expression: '$' is in expr /*empty*/ { $$ = nullptr; } | '=' expr { $$ = $2; } @@ -4766,12 +4771,12 @@ commaVRDListE: | ',' vrdList { $$ = $2; } ; -argsExprList: // IEEE: part of list_of_arguments (used where ,, isn't legal) +argsExprList: // IEEE: part of list_of_arguments (used where ,, isn't legal) expr { $$ = $1; } | argsExprList ',' expr { $$ = $1->addNext($3); } ; -argsExprListE: // IEEE: part of list_of_arguments +argsExprListE: // IEEE: part of list_of_arguments argsExprOneE { $$ = $1; } | argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); } ; @@ -4781,7 +4786,7 @@ argsExprListE: // IEEE: part of list_of_arguments //UNSUP | pev_argsExprListE ',' pev_argsExprOneE { $$ = addNextNull($1, $3); } //UNSUP ; -argsExprOneE: // IEEE: part of list_of_arguments +argsExprOneE: // IEEE: part of list_of_arguments /*empty*/ { $$ = new AstArg(CRELINE(), "", nullptr); } | expr { $$ = new AstArg($1->fileline(), "", $1); } ; @@ -4791,7 +4796,7 @@ argsExprOneE: // IEEE: part of list_of_arguments //UNSUP | pev_expr { $$ = $1; } //UNSUP ; -argsDottedList: // IEEE: part of list_of_arguments +argsDottedList: // IEEE: part of list_of_arguments argsDotted { $$ = $1; } | argsDottedList ',' argsDotted { $$ = addNextNull($1, $3); } ; @@ -4801,7 +4806,7 @@ argsDottedList: // IEEE: part of list_of_arguments //UNSUP | pev_argsDottedList ',' pev_argsDotted { $$ = addNextNull($1, $3); } //UNSUP ; -argsDotted: // IEEE: part of list_of_arguments +argsDotted: // IEEE: part of list_of_arguments '.' idAny '(' ')' { $$ = new AstArg($2, *$2, nullptr); } | '.' idAny '(' expr ')' { $$ = new AstArg($2, *$2, $4); } ; @@ -4811,7 +4816,7 @@ argsDotted: // IEEE: part of list_of_arguments //UNSUP | '.' idAny '(' pev_expr ')' { $$ = new AstArg($2, *$2, $4); } //UNSUP ; -streaming_concatenation: // ==IEEE: streaming_concatenation +streaming_concatenation: // ==IEEE: streaming_concatenation // // Need to disambiguate {<< expr-{ ... expr-} stream_concat } // // From {<< stream-{ ... stream-} } // // Likewise simple_type's idScoped from constExpr's idScope @@ -4824,12 +4829,16 @@ streaming_concatenation: // ==IEEE: streaming_concatenation | '{' yP_SRIGHT stream_concatenation '}' { $$ = new AstStreamR($2, $3, new AstConst($2, 1)); } | '{' yP_SLEFT stream_expressionOrDataType stream_concatenation '}' - { $$ = new AstStreamL($2, $4, $3); } + { AstNodeExpr* const bitsp = VN_IS($3, NodeExpr) ? VN_AS($3, NodeExpr) + : new AstAttrOf{$1, VAttrType::DIM_BITS, $3}; + $$ = new AstStreamL($2, $4, bitsp); } | '{' yP_SRIGHT stream_expressionOrDataType stream_concatenation '}' - { $$ = new AstStreamR($2, $4, $3); } + { AstNodeExpr* const bitsp = VN_IS($3, NodeExpr) ? VN_AS($3, NodeExpr) + : new AstAttrOf{$1, VAttrType::DIM_BITS, $3}; + $$ = new AstStreamR($2, $4, bitsp); } ; -stream_concatenation: // ==IEEE: stream_concatenation +stream_concatenation: // ==IEEE: stream_concatenation // // '{' { stream_expression } '}' '{' cateList '}' { $$ = $2; } ; @@ -5017,24 +5026,24 @@ gateFront: | gateRangeE '(' { $$ = $1; $$ = $2; } ; -gateAndPinList: +gateAndPinList: gatePinExpr { $$ = $1; } | gateAndPinList ',' gatePinExpr { $$ = new AstAnd($2,$1,$3); } ; -gateOrPinList: +gateOrPinList: gatePinExpr { $$ = $1; } | gateOrPinList ',' gatePinExpr { $$ = new AstOr($2,$1,$3); } ; -gateXorPinList: +gateXorPinList: gatePinExpr { $$ = $1; } | gateXorPinList ',' gatePinExpr { $$ = new AstXor($2,$1,$3); } ; -gateUnsupPinList: +gateUnsupPinList: gatePinExpr { $$ = $1; } | gateUnsupPinList ',' gatePinExpr { $$ = $1->addNext($3); } ; -gatePinExpr: +gatePinExpr: expr { $$ = GRAMMARP->createGatePin($1); } ; @@ -5188,7 +5197,7 @@ idClassSel: // Misc Ref to dotted, and/or arraye | packageClassScope idDotted { $$ = new AstDot($2, true, $1, $2); } ; -idClassSelForeach: +idClassSelForeach: idDottedForeach { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select | yTHIS '.' idDottedForeach @@ -5206,7 +5215,7 @@ idDotted: | idDottedMore { $$ = $1; } ; -idDottedForeach: +idDottedForeach: yD_ROOT '.' idDottedMoreForeach { $$ = new AstDot($2, false, new AstParseRef($1, VParseRefExp::PX_ROOT, "$root"), $3); } | idDottedMoreForeach { $$ = $1; } @@ -5217,7 +5226,7 @@ idDottedMore: | idDottedMore '.' idArrayed { $$ = new AstDot($2, false, $1, $3); } ; -idDottedMoreForeach: +idDottedMoreForeach: idArrayedForeach { $$ = $1; } | idDottedMoreForeach '.' idArrayedForeach { $$ = new AstDot($2, false, $1, $3); } ; @@ -5238,7 +5247,7 @@ idArrayed: // IEEE: id + select | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2, $1, $3, $5); } ; -idArrayedForeach: // IEEE: id + select (under foreach expression) +idArrayedForeach: // IEEE: id + select (under foreach expression) id { $$ = new AstParseRef($1, VParseRefExp::PX_TEXT, *$1, nullptr, nullptr); } // // IEEE: id + part_select_range/constant_part_select_range @@ -5607,7 +5616,7 @@ sequence_formal_typeNoDt: // ==IEEE: sequence_formal_type (w/o data //UNSUP | sexpr ';' { $$ = $1; } //UNSUP ; -property_spec: // IEEE: property_spec +property_spec: // IEEE: property_spec //UNSUP: This rule has been super-specialized to what is supported now //UNSUP remove below '@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' pexpr @@ -5686,7 +5695,7 @@ property_spec: // IEEE: property_spec //UNSUP | BISONPRE_COPY_ONCE(expr,{s/~l~/pev_/g; s/~p~/pev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied} //UNSUP ; -pexpr: // IEEE: property_expr (The name pexpr is important as regexps just add an "p" to expr.) +pexpr: // IEEE: property_expr (The name pexpr is important as regexps just add an "p" to expr.) //UNSUP: This rule has been super-specialized to what is supported now //UNSUP remove below // @@ -5701,7 +5710,7 @@ pexpr: // IEEE: property_expr (The name pexpr is important as regexps j | expr { $$ = $1; } ; -complex_pexpr: // IEEE: part of property_expr, see comments there +complex_pexpr: // IEEE: part of property_expr, see comments there expr yP_ORMINUSGT pexpr { $$ = new AstLogOr($2, new AstLogNot($2, $1), $3); } | expr yP_OREQGT pexpr { $$ = new AstImplication($2, $1, $3); } | yNOT pexpr %prec prNEGATION { $$ = new AstLogNot{$1, $2}; } @@ -6406,7 +6415,7 @@ packageClassScopeNoId: // IEEE: [package_scope] not followed by yaID packageClassScope { $$ = $1; $$ = $1; SYMP->nextId(nullptr); } ; -packageClassScopeE: // IEEE: [package_scope] +packageClassScopeE: // IEEE: [package_scope] // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // TODO: To support classes should return generic type, not packagep @@ -6415,7 +6424,7 @@ packageClassScopeE: // IEEE: [package_scope] | packageClassScope { $$ = $1; $$ = $1; } ; -packageClassScope: // IEEE: class_scope +packageClassScope: // IEEE: class_scope // // IEEE: "class_type yP_COLONCOLON" // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId @@ -6428,7 +6437,7 @@ packageClassScope: // IEEE: class_scope { $$ = new AstDot($2, true, $1, $3); $$ = $3; } ; -packageClassScopeList: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE +packageClassScopeList: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE // // Or IEEE: [package_scope] // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId @@ -6439,7 +6448,7 @@ packageClassScopeList: // IEEE: class_type: "id [ parameter_value_assig { $$ = new AstDot($2, true, $1, $2); $$ = $2; } ; -packageClassScopeItem: // IEEE: package_scope or [package_scope]::[class_scope] +packageClassScopeItem: // IEEE: package_scope or [package_scope]::[class_scope] // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE @@ -6455,7 +6464,7 @@ packageClassScopeItem: // IEEE: package_scope or [package_scope]::[clas { $$ = new AstClassOrPackageRef($1, *$1, $1, $2); $$ = $1; } ; -dollarUnitNextId: // $unit +dollarUnitNextId: // $unit // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // Must call nextId without any additional tokens following @@ -6464,7 +6473,7 @@ dollarUnitNextId: // $unit SYMP->nextId(PARSEP->rootp()); } ; -localNextId: // local +localNextId: // local // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // Must call nextId without any additional tokens following diff --git a/test_regress/t/t_stream_bad.out b/test_regress/t/t_stream_bad.out new file mode 100644 index 000000000..d374c004f --- /dev/null +++ b/test_regress/t/t_stream_bad.out @@ -0,0 +1,15 @@ +%Error: t/t_stream_bad.v:12:32: Expecting expression to be constant, but can't convert a RAND to constant. + : ... In instance t + 12 | initial packed_data_32 = {<<$random{byte_in}}; + | ^~~~~~~ +%Error: t/t_stream_bad.v:12:30: Slice size isn't a constant or basic data type. + : ... In instance t + 12 | initial packed_data_32 = {<<$random{byte_in}}; + | ^~ +%Warning-WIDTH: t/t_stream_bad.v:12:27: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS's STREAML generates 8 bits. + : ... In instance t + 12 | initial packed_data_32 = {<<$random{byte_in}}; + | ^ + ... For warning description see https://verilator.org/warn/WIDTH?v=latest + ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_stream_bad.pl b/test_regress/t/t_stream_bad.pl new file mode 100755 index 000000000..a29ead0ed --- /dev/null +++ b/test_regress/t/t_stream_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_stream_bad.v b/test_regress/t/t_stream_bad.v new file mode 100644 index 000000000..c93398145 --- /dev/null +++ b/test_regress/t/t_stream_bad.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Geza Lore. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + logic [31:0] packed_data_32; + byte byte_in[4]; + + initial packed_data_32 = {<<$random{byte_in}}; + +endmodule diff --git a/test_regress/t/t_stream_integer_type.out b/test_regress/t/t_stream_integer_type.out index 59b6a116d..96728e3ee 100644 --- a/test_regress/t/t_stream_integer_type.out +++ b/test_regress/t/t_stream_integer_type.out @@ -72,63 +72,115 @@ : ... In instance t 136 | {<<32{reg_out}} = v_packed_data_128; | ^ -%Error: t/t_stream_integer_type.v:150:33: Operator STREAML expected non-datatype RHS but 'byte' is a datatype. - : ... In instance t - 150 | packed_data_32 = {<