From 47588f343bf4e6a62fde785af89c5c7f2c84d20b Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 12 Nov 2023 18:30:48 +0000 Subject: [PATCH] astgen: Enforce the use of aliased operand accessors (#4688) This patch enforces the use of the most specific accessors for operands which have an '@astgen alias' declaration, by making the superclass accessors of the same operands private. This ensures client code is cleaner as you can't use multiple different methods to reference the same operands (which we used to in some places). Also prep for some refactoring. --- src/V3AstNodeExpr.h | 4 ++-- src/V3Const.cpp | 38 +++++++++++++++++++------------------- src/V3EmitCFunc.h | 20 ++++++++++---------- src/V3Expand.cpp | 8 ++++---- src/V3Inst.cpp | 12 ++++++------ src/V3LinkLValue.cpp | 10 +++++----- src/V3LinkParse.cpp | 2 +- src/V3Simulate.h | 2 +- src/V3Slice.cpp | 2 +- src/V3Subst.cpp | 14 +++++++------- src/V3Width.cpp | 42 +++++++++++++++++++++--------------------- src/V3WidthSel.cpp | 10 +++++----- src/astgen | 28 ++++++++++++++++++++++++---- 13 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 3e42f73e1..86eb1f3a3 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4311,7 +4311,7 @@ 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 + // @astgen alias op3 := widthp public: AstSelMinus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp) : ASTGEN_SUPER_SelMinus(fl, fromp, bitp, widthp) {} @@ -4321,7 +4321,7 @@ 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 + // @astgen alias op3 := widthp public: AstSelPlus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp) : ASTGEN_SUPER_SelPlus(fl, fromp, bitp, widthp) {} diff --git a/src/V3Const.cpp b/src/V3Const.cpp index de342d983..f86e7c62b 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -462,7 +462,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { void visit(AstWordSel* nodep) override { CONST_BITOP_RETURN_IF(!m_leafp, nodep); AstConst* const constp = VN_CAST(nodep->bitp(), Const); - CONST_BITOP_RETURN_IF(!constp, nodep->rhsp()); + CONST_BITOP_RETURN_IF(!constp, nodep->bitp()); UASSERT_OBJ(m_leafp->wordIdx() == -1, nodep, "Unexpected nested WordSel"); m_leafp->wordIdx(constp->toSInt()); iterateConst(nodep->fromp()); @@ -1269,9 +1269,9 @@ private: // V3Expand may make a arraysel that exceeds the bounds of the array // It was an expression, then got constified. In reality, the WordSel // must be wrapped in a Cond, that will be false. - return (VN_IS(nodep->rhsp(), Const) && VN_IS(nodep->fromp(), NodeVarRef) + return (VN_IS(nodep->bitp(), Const) && VN_IS(nodep->fromp(), NodeVarRef) && VN_AS(nodep->fromp(), NodeVarRef)->access().isReadOnly() - && (static_cast(VN_AS(nodep->rhsp(), Const)->toUInt()) + && (static_cast(VN_AS(nodep->bitp(), Const)->toUInt()) >= VN_AS(nodep->fromp(), NodeVarRef)->varp()->widthWords())); } bool operandSelFull(const AstSel* nodep) { @@ -2539,7 +2539,7 @@ 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); - AstNodeExpr* const fromp = repp->lhsp(); + AstNodeExpr* const fromp = repp->srcp(); AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const); if (!lsbp) return false; AstNodeExpr* const widthp = nodep->widthp(); @@ -2562,11 +2562,11 @@ private: } bool operandRepRep(AstReplicate* nodep) { // REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2)) - AstReplicate* const rep2p = VN_AS(nodep->lhsp(), Replicate); - AstNodeExpr* const from2p = rep2p->lhsp(); - AstConst* const cnt1p = VN_CAST(nodep->rhsp(), Const); + AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate); + AstNodeExpr* const from2p = rep2p->srcp(); + AstConst* const cnt1p = VN_CAST(nodep->countp(), Const); if (!cnt1p) return false; - AstConst* const cnt2p = VN_CAST(rep2p->rhsp(), Const); + AstConst* const cnt2p = VN_CAST(rep2p->countp(), Const); if (!cnt2p) return false; // from2p->unlinkFrBack(); @@ -2589,15 +2589,15 @@ private: AstNodeExpr* from2p = nodep->rhsp(); uint32_t cnt2 = 1; if (VN_IS(from1p, Replicate)) { - AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->rhsp(), Const); + AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const); if (!cnt1p) return false; - from1p = VN_AS(from1p, Replicate)->lhsp(); + from1p = VN_AS(from1p, Replicate)->srcp(); cnt1 = cnt1p->toUInt(); } if (VN_IS(from2p, Replicate)) { - AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->rhsp(), Const); + AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const); if (!cnt2p) return false; - from2p = VN_AS(from2p, Replicate)->lhsp(); + from2p = VN_AS(from2p, Replicate)->srcp(); cnt2 = cnt2p->toUInt(); } if (!operandsSame(from1p, from2p)) return false; @@ -3488,8 +3488,8 @@ private: TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)"); TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)"); // This visit function here must allow for short-circuiting. - TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)"); - TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)"); + TREEOPS("AstCond {$condp.isZero}", "replaceWIteratedThs(nodep)"); + TREEOPS("AstCond {$condp.isNeqZero}", "replaceWIteratedRhs(nodep)"); 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, !$elsep.isClassHandleValue}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b @@ -3670,9 +3670,9 @@ private: // bits end up in the wrong places TREEOPV("AstExtend {$lhsp.castExtend}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp())"); TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp())"); - TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs + TREEOPV("AstReplicate{$srcp, $countp.isOne, $srcp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs - TREEOPV("AstReplicate{$lhsp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}} + TREEOPV("AstReplicate{$srcp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}} TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE"); // {a,a}->{2{a}}, {a,2{a}}->{3{a}, etc // Next rule because AUTOINST puts the width of bits in // to pins, even when the widths are exactly the same across the hierarchy. @@ -3694,9 +3694,9 @@ private: // win if bit select is a constant (otherwise we may need to compute bit index several times) TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)"); TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)"); - TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); - TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); - TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); + TREEOPV("AstSel{$fromp.castAnd,$fromp.castConst}", "replaceSelIntoUniop(nodep)"); + TREEOPV("AstSel{$fromp.castOr,$fromp.castConst}", "replaceSelIntoUniop(nodep)"); + TREEOPV("AstSel{$fromp.castXor,$fromp.castConst}", "replaceSelIntoUniop(nodep)"); // This visit function here must allow for short-circuiting. TREEOPS("AstLogIf{$lhsp.isZero}", "replaceNum(nodep, 1)"); TREEOPV("AstLogIf{$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}"); diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 6c7ef5fb0..ebf115092 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -1184,25 +1184,25 @@ public: } void visit(AstSel* nodep) override { // Note ASSIGN checks for this on a LHS - emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp()); + emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->widthp()); } void visit(AstReplicate* nodep) override { - if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) { - UASSERT_OBJ((static_cast(VN_AS(nodep->rhsp(), Const)->toUInt()) - * nodep->lhsp()->widthMin()) + if (nodep->srcp()->widthMin() == 1 && !nodep->isWide()) { + UASSERT_OBJ((static_cast(VN_AS(nodep->countp(), Const)->toUInt()) + * nodep->srcp()->widthMin()) == nodep->widthMin(), nodep, "Replicate non-constant or width miscomputed"); puts("VL_REPLICATE_"); emitIQW(nodep); puts("OI("); - if (nodep->lhsp()) puts(cvtToStr(nodep->lhsp()->widthMin())); + if (nodep->srcp()) puts(cvtToStr(nodep->srcp()->widthMin())); puts(","); - iterateAndNextConstNull(nodep->lhsp()); + iterateAndNextConstNull(nodep->srcp()); puts(", "); - iterateAndNextConstNull(nodep->rhsp()); + iterateAndNextConstNull(nodep->countp()); puts(")"); } else { - emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr); + emitOpName(nodep, nodep->emitC(), nodep->srcp(), nodep->countp(), nullptr); } } void visit(AstStreamL* nodep) override { @@ -1229,9 +1229,9 @@ public: } void visit(AstCastDynamic* nodep) override { putbs("VL_CAST_DYNAMIC("); - iterateAndNextConstNull(nodep->lhsp()); + iterateAndNextConstNull(nodep->fromp()); puts(", "); - iterateAndNextConstNull(nodep->rhsp()); + iterateAndNextConstNull(nodep->top()); puts(")"); } void visit(AstCountBits* nodep) override { diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index af67ad82e..1880404bc 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -731,7 +731,7 @@ private: } else { if (isImpure(nodep)) return; FileLine* const fl = nodep->fileline(); - AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack(); + AstNodeExpr* lhsp = nodep->srcp()->unlinkFrBack(); AstNodeExpr* newp; const int lhswidth = lhsp->widthMin(); if (lhswidth == 1) { @@ -739,7 +739,7 @@ private: newp = new AstNegate{fl, lhsp}; } else { UINFO(8, " REPLICATE " << nodep << endl); - const AstConst* const constp = VN_AS(nodep->rhsp(), Const); + const AstConst* const constp = VN_AS(nodep->countp(), Const); UASSERT_OBJ(constp, nodep, "Replication value isn't a constant. Checked earlier!"); const uint32_t times = constp->toUInt(); @@ -765,9 +765,9 @@ private: UINFO(8, " Wordize ASSIGN(REPLICATE) " << nodep << endl); if (!doExpandWide(rhsp)) return false; FileLine* const fl = nodep->fileline(); - AstNodeExpr* const lhsp = rhsp->lhsp(); + AstNodeExpr* const lhsp = rhsp->srcp(); const int lhswidth = lhsp->widthMin(); - const AstConst* const constp = VN_AS(rhsp->rhsp(), Const); + const AstConst* const constp = VN_AS(rhsp->countp(), 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) { diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index fa5b2da3c..ce6022187 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -362,11 +362,11 @@ private: } // end expanding ranged cell else if (AstArraySel* const arrselp = VN_CAST(nodep->exprp(), ArraySel)) { if (const AstUnpackArrayDType* const arrp - = VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) { + = VN_CAST(arrselp->fromp()->dtypep(), UnpackArrayDType)) { if (!VN_IS(arrp->subDTypep(), IfaceRefDType)) return; // Interface pin attaches to one element of arrayed interface - V3Const::constifyParamsEdit(arrselp->rhsp()); - const AstConst* const constp = VN_CAST(arrselp->rhsp(), Const); + V3Const::constifyParamsEdit(arrselp->bitp()); + const AstConst* const constp = VN_CAST(arrselp->bitp(), Const); if (!constp) { nodep->v3warn( E_UNSUPPORTED, @@ -374,9 +374,9 @@ private: return; } const string index = AstNode::encodeNumber(constp->toSInt()); - if (VN_IS(arrselp->lhsp(), SliceSel)) - arrselp->lhsp()->v3error("Unsupported: interface slices"); - const AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef); + if (VN_IS(arrselp->fromp(), SliceSel)) + arrselp->fromp()->v3error("Unsupported: interface slices"); + const AstVarRef* const varrefp = VN_CAST(arrselp->fromp(), VarRef); UASSERT_OBJ(varrefp, arrselp, "No interface varref under array"); AstVarXRef* const newp = new AstVarXRef{ nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "", diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 11a1e4499..1b5b2776d 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -238,19 +238,19 @@ private: void visit(AstSel* nodep) override { VL_RESTORER(m_setRefLvalue); { - iterateAndNextNull(nodep->lhsp()); + iterateAndNextNull(nodep->fromp()); // Only set lvalues on the from m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->rhsp()); - iterateAndNextNull(nodep->thsp()); + iterateAndNextNull(nodep->lsbp()); + iterateAndNextNull(nodep->widthp()); } } void visit(AstNodeSel* nodep) override { VL_RESTORER(m_setRefLvalue); { // Only set lvalues on the from - iterateAndNextNull(nodep->lhsp()); + iterateAndNextNull(nodep->fromp()); m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->rhsp()); + iterateAndNextNull(nodep->bitp()); } } void visit(AstCellArrayRef* nodep) override { diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 5e25a0dcc..591c68777 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -561,7 +561,7 @@ private: // Convert to AstSelLoopVars so V3LinkDot knows what's being defined AstNode* const newp = new AstSelLoopVars{selp->fileline(), selp->fromp()->unlinkFrBack(), - selp->rhsp()->unlinkFrBackWithNext()}; + selp->bitp()->unlinkFrBackWithNext()}; selp->replaceWith(newp); VL_DO_DANGLING(selp->deleteTree(), selp); } else if (VN_IS(bracketp, SelLoopVars)) { diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 1adeeeed5..afa060c7d 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -768,7 +768,7 @@ private: outVarrefpRef = varrefp; lsbRef = fetchConst(selp->lsbp())->num(); return; // And presumably still optimizable() - } else if (AstSel* const subselp = VN_CAST(selp->lhsp(), Sel)) { + } else if (AstSel* const subselp = VN_CAST(selp->fromp(), Sel)) { V3Number sublsb{nodep}; handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb /*ref*/, depth + 1); if (optimizable()) { diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index cc479b95c..45607e876 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -148,7 +148,7 @@ class SliceVisitor final : public VNVisitor { if (AstSliceSel* const slicep = VN_CAST(itemp, SliceSel)) { offset += slicep->declRange().lo(); newp = new AstArraySel{nodep->fileline(), - slicep->lhsp()->cloneTreePure(false), offset}; + slicep->fromp()->cloneTreePure(false), offset}; } else { newp = new AstArraySel{nodep->fileline(), itemp->cloneTreePure(false), offset}; diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index b569f3390..8935d3732 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -267,9 +267,9 @@ private: } } } else if (const AstWordSel* const wordp = VN_CAST(nodep->lhsp(), WordSel)) { - if (AstVarRef* const varrefp = VN_CAST(wordp->lhsp(), VarRef)) { - if (VN_IS(wordp->rhsp(), Const) && isSubstVar(varrefp->varp())) { - const int word = VN_AS(wordp->rhsp(), Const)->toUInt(); + if (AstVarRef* const varrefp = VN_CAST(wordp->fromp(), VarRef)) { + if (VN_IS(wordp->bitp(), Const) && isSubstVar(varrefp->varp())) { + const int word = VN_AS(wordp->bitp(), Const)->toUInt(); SubstVarEntry* const entryp = getEntryp(varrefp); hit = true; if (m_ops > SUBST_MAX_OPS_SUBST) { @@ -297,9 +297,9 @@ private: } void visit(AstWordSel* nodep) override { if (!m_funcp) return; - iterate(nodep->rhsp()); - AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef); - const AstConst* const constp = VN_CAST(nodep->rhsp(), Const); + iterate(nodep->bitp()); + AstVarRef* const varrefp = VN_CAST(nodep->fromp(), VarRef); + const AstConst* const constp = VN_CAST(nodep->bitp(), Const); if (varrefp && isSubstVar(varrefp->varp()) && varrefp->access().isReadOnly() && constp) { // Nicely formed lvalues handled in NodeAssign // Other lvalues handled as unknown mess in AstVarRef @@ -318,7 +318,7 @@ private: entryp->consumeWord(word); } } else { - iterate(nodep->lhsp()); + iterate(nodep->fromp()); } } void visit(AstVarRef* nodep) override { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 6c41170d9..3f2132100 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -730,12 +730,12 @@ private: // LHS, RHS is self-determined // width: value(LHS) * width(RHS) if (m_vup->prelim()) { - iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH); - V3Const::constifyParamsNoWarnEdit(nodep->rhsp()); // rhsp may change + iterateCheckSizedSelf(nodep, "RHS", nodep->countp(), SELF, BOTH); + V3Const::constifyParamsNoWarnEdit(nodep->countp()); // rhsp may change uint32_t times = 1; - const AstConst* const constp = VN_CAST(nodep->rhsp(), Const); + const AstConst* const constp = VN_CAST(nodep->countp(), Const); if (constp) times = constp->toUInt(); AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp(); @@ -746,18 +746,18 @@ private: << vdtypep->prettyDTypeNameQ() << " data type"); } - if (VN_IS(nodep->lhsp(), Concat)) { + if (VN_IS(nodep->srcp(), Concat)) { // Convert to concat directly, and visit(AstConst) will convert. // Don't iterate lhsp as SELF, the potential Concat below needs // the adtypep passed down to recognize the QueueDType - userIterateAndNext(nodep->lhsp(), WidthVP{vdtypep, BOTH}.p()); - nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); + userIterateAndNext(nodep->srcp(), WidthVP{vdtypep, BOTH}.p()); + nodep->replaceWith(nodep->srcp()->unlinkFrBack()); VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } else { // int a[] = {lhs} -> same as '{lhs} auto* const newp = new AstPattern{ nodep->fileline(), - new AstPatMember{nodep->lhsp()->fileline(), nodep->lhsp()->unlinkFrBack(), + new AstPatMember{nodep->srcp()->fileline(), nodep->srcp()->unlinkFrBack(), nullptr, nullptr}}; nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); @@ -769,11 +769,11 @@ private: nodep->v3warn(E_UNSUPPORTED, "Unsupported: Replication to form " << vdtypep->prettyDTypeNameQ() << " data type"); } - iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH); - if ((vdtypep && vdtypep->isString()) || nodep->lhsp()->isString()) { + iterateCheckSizedSelf(nodep, "LHS", nodep->srcp(), SELF, BOTH); + if ((vdtypep && vdtypep->isString()) || nodep->srcp()->isString()) { AstNode* const newp - = new AstReplicateN{nodep->fileline(), nodep->lhsp()->unlinkFrBack(), - nodep->rhsp()->unlinkFrBack()}; + = new AstReplicateN{nodep->fileline(), nodep->srcp()->unlinkFrBack(), + nodep->countp()->unlinkFrBack()}; nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); return; @@ -785,8 +785,8 @@ private: " (IEEE 1800-2017 11.4.12.1)"); times = 1; // Set to 1, so we can continue looking for errors } - nodep->dtypeSetLogicUnsized((nodep->lhsp()->width() * times), - (nodep->lhsp()->widthMin() * times), + nodep->dtypeSetLogicUnsized((nodep->srcp()->width() * times), + (nodep->srcp()->widthMin() * times), VSigning::UNSIGNED); } } @@ -898,7 +898,7 @@ private: userIterateAndNext(nodep->lsbp(), WidthVP{SELF, PRELIM}.p()); checkCvtUS(nodep->fromp()); iterateCheckSizedSelf(nodep, "Select Width", nodep->widthp(), SELF, BOTH); - iterateCheckSizedSelf(nodep, "Select LHS", nodep->lhsp(), SELF, BOTH); + iterateCheckSizedSelf(nodep, "Select LHS", nodep->fromp(), SELF, BOTH); V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change const AstConst* const widthConstp = VN_CAST(nodep->widthp(), Const); if (!widthConstp) { @@ -1141,7 +1141,7 @@ private: void visit(AstSelBit* nodep) override { // Just a quick check as after V3Param these nodes instead are AstSel's userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p()); AstNode* const selp = V3Width::widthSelNoIterEdit(nodep); @@ -1155,8 +1155,8 @@ private: void visit(AstSelExtract* nodep) override { // Just a quick check as after V3Param these nodes instead are AstSel's userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->leftp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->rightp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p()); AstNode* const selp = V3Width::widthSelNoIterEdit(nodep); if (selp != nodep) { @@ -1168,8 +1168,8 @@ private: } void visit(AstSelPlus* nodep) override { userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->widthp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p()); AstNode* const selp = V3Width::widthSelNoIterEdit(nodep); if (selp != nodep) { @@ -1181,8 +1181,8 @@ private: } void visit(AstSelMinus* nodep) override { userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel - userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel + userIterateAndNext(nodep->widthp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p()); AstNode* const selp = V3Width::widthSelNoIterEdit(nodep); if (selp != nodep) { diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 8c8aa4bb4..4f28676d2 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -216,7 +216,7 @@ private: if (debug() >= 9) nodep->backp()->dumpTree("- SELBT0: "); // lhsp/rhsp do not need to be constant AstNodeExpr* const fromp = nodep->fromp()->unlinkFrBack(); - AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting + AstNodeExpr* const rhsp = nodep->bitp()->unlinkFrBack(); // bit we're extracting if (debug() >= 9) nodep->dumpTree("- SELBT2: "); const FromData fromdata = fromDataForArray(nodep, fromp); AstNodeDType* const ddtypep = fromdata.m_dtypep; @@ -354,8 +354,8 @@ private: AstNodeDType* const ddtypep = fromdata.m_dtypep; const VNumRange fromRange = fromdata.m_fromRange; if (VN_IS(ddtypep, QueueDType)) { - AstNodeExpr* const qleftp = nodep->rhsp()->unlinkFrBack(); - AstNodeExpr* const qrightp = nodep->thsp()->unlinkFrBack(); + AstNodeExpr* const qleftp = nodep->leftp()->unlinkFrBack(); + AstNodeExpr* const qrightp = nodep->rightp()->unlinkFrBack(); AstNodeExpr* const qleftBacknessp = selQueueBackness(qleftp); AstNodeExpr* const qrightBacknessp = selQueueBackness(qrightp); // Use special methods to refer to back rather than math using @@ -381,8 +381,8 @@ 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 -:"); - AstNodeExpr* const msbp = nodep->rhsp()->unlinkFrBack(); - AstNodeExpr* const lsbp = nodep->thsp()->unlinkFrBack(); + AstNodeExpr* const msbp = nodep->leftp()->unlinkFrBack(); + AstNodeExpr* const lsbp = nodep->rightp()->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); diff --git a/src/astgen b/src/astgen index a9662cd6a..70f102c60 100755 --- a/src/astgen +++ b/src/astgen @@ -503,13 +503,16 @@ class Cpt: " // Generated by astgen with short-circuiting\n" + " void visit(Ast" + node.name + "* nodep) override {\n" + - " iterateAndNextNull(nodep->lhsp());\n" + - "".join(out_for_type_sc)) + " iterateAndNextNull(nodep->{op1}());\n".format( + op1=node.getOp(1)[0]) + "".join(out_for_type_sc)) if out_for_type[0]: - self.print(" iterateAndNextNull(nodep->rhsp());\n") + self.print( + " iterateAndNextNull(nodep->{op2}());\n".format( + op2=node.getOp(2)[0])) if node.isSubClassOf(AstNodes["NodeTriop"]): self.print( - " iterateAndNextNull(nodep->thsp());\n") + " iterateAndNextNull(nodep->{op3}());\n". + format(op3=node.getOp(3)[0])) self.print("".join(out_for_type) + " }\n") elif len(out_for_type) > 0: # Other types with something to print skip = node.name in self.tree_skip_visit @@ -976,6 +979,8 @@ def write_ast_macros(filename): ''', t=node.name) + hiddenMethods = [] + for n in range(1, 5): op = node.getOp(n) if not op: @@ -983,6 +988,11 @@ def write_ast_macros(filename): name, monad, kind = op retrieve = ("VN_DBG_AS(op{n}p(), {kind})" if kind != "Node" else "op{n}p()").format(n=n, kind=kind) + superOp = node.superClass.getOp(n) + superName = None + if superOp: + superName = superOp[0] + hiddenMethods.append(superName) if monad == "List": emitBlock('''\ Ast{kind}* {name}() const VL_MT_STABLE {{ return {retrieve}; }} @@ -993,6 +1003,9 @@ def write_ast_macros(filename): Name=name[0].upper() + name[1:], n=n, retrieve=retrieve) + if superOp: + hiddenMethods.append("add" + superName[0].upper() + + superName[1:]) elif monad == "Optional": emitBlock('''\ Ast{kind}* {name}() const VL_MT_STABLE {{ return {retrieve}; }} @@ -1012,6 +1025,13 @@ def write_ast_macros(filename): n=n, retrieve=retrieve) + if hiddenMethods: + fh.write("private: \\\n") + for method in hiddenMethods: + fh.write(" using Ast{sup}::{method}; \\\n".format( + sup=node.superClass.name, method=method)) + fh.write("public: \\\n") + fh.write( " static_assert(true, \"\")\n") # Swallowing the semicolon