Generate AstNode accessors via astgen

Introduce the @astgen directives parsed by astgen, currently used for
the generation child node (operand) accessors. Please see the updated
internal documentation for details.
This commit is contained in:
Geza Lore 2022-09-15 19:43:56 +01:00
parent 0a8cfb8d2c
commit ce03293128
70 changed files with 1386 additions and 1530 deletions

View File

@ -96,10 +96,11 @@ this.
Each ``AstNode`` has pointers to up to four children, accessed by the Each ``AstNode`` has pointers to up to four children, accessed by the
``op1p`` through ``op4p`` methods. These methods are then abstracted in a ``op1p`` through ``op4p`` methods. These methods are then abstracted in a
specific Ast\* node class to a more specific name. For example with the specific Ast\* node class to a more specific name. For example with the
``AstIf`` node (for ``if`` statements), ``ifsp`` calls ``op2p`` to give the ``AstIf`` node (for ``if`` statements), ``thensp`` calls ``op2p`` to give the
pointer to the AST for the "then" block, while ``elsesp`` calls ``op3p`` to pointer to the AST for the "then" block, while ``elsesp`` calls ``op3p`` to
give the pointer to the AST for the "else" block, or NULL if there is not give the pointer to the AST for the "else" block, or NULL if there is not
one. one. These accessors are automatically generated by ``astgen`` after
parsing the ``@astgen`` directives in the specific ``AstNode`` subclasses.
``AstNode`` has the concept of a next and previous AST - for example the ``AstNode`` has the concept of a next and previous AST - for example the
next and previous statements in a block. Pointers to the AST for these next and previous statements in a block. Pointers to the AST for these
@ -501,22 +502,99 @@ code:
The ``astgen`` Script The ``astgen`` Script
--------------------- ---------------------
Some of the code implementing passes is extremely repetitive, and must be The ``astgen`` script is used to generate some of the repetitive C++ code
implemented for each sub-class of ``AstNode``. However, while repetitive, related to the ``AstNode`` type hierarchy. An example is the abstract ``visit``
there is more variability than can be handled in C++ macros. methods in ``VNVisitor``. There are other uses, please see the ``*__gen*``
files in the bulid directories and the ``astgen`` script itself for details. A
description of the more advanced features of ``astgen`` are provided here.
In Verilator this is implemented by using a script, ``astgen`` to
pre-process the C++ code. For example in ``V3Const.cpp`` this is used to
implement the ``visit()`` functions for each binary operation using the
``TREEOP`` macro.
The original C source code is transformed into C code in the ``obj_opt`` Generating ``AstNode`` members
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some of the member s of ``AstNode`` sub-classes are generated by ``astgen``.
These are emitted as pre-processor macro definitions, which then need to be
added to the ``AstNode`` sub-classes they correspond to. Specifically ``class
AstFoo`` should contain an instance of ``ASTGEN_MEMBERS_Foo;`` at class scope.
The ``astgen`` script checks and errors if this is not present. The method
generated depends on whether the class is a concrete final class, or an
abstract ``AstNode*`` base-class, and on ``@astgen`` directives present in
comment sections in the body of the ``AstNode`` sub-class definitions.
List of ``@astgen`` directives
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``@astgen`` directives in comments contained in the body of ``AstNode``
sub-class definitions are parsed and contribute to the code generated by
``astgen``. The general syntax is ``@astgen <keywords> := <description>``,
where ``<keywords>`` determines what is being defined, and ``<description>`` is
a ``<keywords>`` dependent description of the definition. The list of
``@astgen`` directives is as follows:
``op<N>`` operand directives
"""""""""""""""""""""""""""""
The ``op1``, ``op2``, ``op3`` and ``op4`` directives are used to describe the
name and type of the up to 4 child operands of a node. The syntax of the
``<description>`` field is ``<identifier> : <type>``, where ``<identifier>``
will be used as the base name of the generated operand accessors, and
``<type>`` is one of:
1. An ``AstNode`` sub-class, defining the operand to be of that type, always
no-null, and with an always null ``nextp()``. That is, the child node is
always present, and is a single ``AstNode`` (as opposed to a list).
2. ``Optional[<AstNode sub-class>]``. This is just like in point 1 above, but
defines the child node to be optional, meaning it may be null.
3. ``List[AstNode sub-class]`` describes a list operand, which means the child
node may have a non-null ``nextp()`` and in addition the child itself may be
null, representing an empty list.
An example of the full syntax of the directive is
``@astgen op1 := lhsp : AstNodeMath``.
``astnode`` generates accessors for the child nodes based on these directives.
For non-list children, the names of the getter and setter both are that of the
given ``<identifier>``. For list type children, the getter is ``<identifier>``,
and instead of the setter, there an ``add<Identifier>`` method is generated
that appends new nodes (or lists of nodes) to the child list.
``alias op<N>`` operand alias directives
""""""""""""""""""""""""""""""""""""""""
If a super-class already defined a name and type for a child node using the
``op<N>`` directive, but a more appropriate name exists in the context of a
sub-class, then the alias directive can be used to introduce an additional name
for the child node. The is ``alias op<N> := <identifier>`` where
``<identifier>`` is the new name. ``op<N>`` must have been defined in some
super-class of the current node.
Example: ``@astgen alias op1 := condp``
Additional features of ``astgen``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In addition to generating ``AstNode`` members as described above,
``astgen`` is also use to handle some of the repetitive implementation code
that is still variable enough not to be handled in C++ macros.
In particular, ``astgen`` is used to pre-process some of the C++ source
files. For example in ``V3Const.cpp``, it is used to implement the
``visit()`` functions for each binary operation using the ``TREEOP`` macro.
The original C++ source code is transformed into C++ code in the ``obj_opt``
and ``obj_dbg`` sub-directories (the former for the optimized version of and ``obj_dbg`` sub-directories (the former for the optimized version of
Verilator, the latter for the debug version). So for example Verilator, the latter for the debug version). So for example
``V3Const.cpp`` into ``V3Const__gen.cpp``. ``V3Const.cpp`` into ``V3Const__gen.cpp``.
Visitor Functions ----------------- Visitor Functions
-----------------
Verilator uses the "Visitor" design pattern to implement its refinement and Verilator uses the "Visitor" design pattern to implement its refinement and
optimization passes. This allows separation of the pass algorithm from the optimization passes. This allows separation of the pass algorithm from the

View File

@ -216,7 +216,7 @@ private:
// METHODS // METHODS
void addActive(AstActive* nodep) { void addActive(AstActive* nodep) {
UASSERT_OBJ(m_scopep, nodep, "nullptr scope"); UASSERT_OBJ(m_scopep, nodep, "nullptr scope");
m_scopep->addActivep(nodep); m_scopep->addBlocksp(nodep);
} }
// VISITORS // VISITORS
void visit(AstScope* nodep) override { void visit(AstScope* nodep) override {
@ -302,7 +302,7 @@ private:
LatchDetectGraphVertex* const parentp = m_graph.currentp(); LatchDetectGraphVertex* const parentp = m_graph.currentp();
LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true); LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
m_graph.addPathVertex(branchp, "IF"); m_graph.addPathVertex(branchp, "IF");
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
m_graph.addPathVertex(branchp, "ELSE"); m_graph.addPathVertex(branchp, "ELSE");
iterateAndNextNull(nodep->elsesp()); iterateAndNextNull(nodep->elsesp());
m_graph.currentp(parentp); m_graph.currentp(parentp);
@ -458,7 +458,7 @@ private:
void visit(AstFinal* nodep) override { void visit(AstFinal* nodep) override {
// Relink to CFUNC for the final // Relink to CFUNC for the final
UINFO(4, " FINAL " << nodep << endl); UINFO(4, " FINAL " << nodep << endl);
if (!nodep->bodysp()) { // Empty, Kill it. if (!nodep->stmtsp()) { // Empty, Kill it.
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }
@ -471,10 +471,10 @@ private:
m_scopeFinalp->isStatic(false); m_scopeFinalp->isStatic(false);
m_scopeFinalp->isLoose(true); m_scopeFinalp->isLoose(true);
m_scopeFinalp->slow(true); m_scopeFinalp->slow(true);
m_namer.scopep()->addActivep(m_scopeFinalp); m_namer.scopep()->addBlocksp(m_scopeFinalp);
} }
nodep->unlinkFrBack(); nodep->unlinkFrBack();
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext()); m_scopeFinalp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} }
@ -542,7 +542,7 @@ private:
UINFO(4, " ALW " << nodep << endl); UINFO(4, " ALW " << nodep << endl);
// if (debug() >= 9) nodep->dumpTree(cout, " Alw: "); // if (debug() >= 9) nodep->dumpTree(cout, " Alw: ");
if (!nodep->bodysp()) { if (!nodep->stmtsp()) {
// Empty always. Kill it. // Empty always. Kill it.
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
@ -551,7 +551,7 @@ private:
} }
void visit(AstAlwaysPostponed* nodep) override { void visit(AstAlwaysPostponed* nodep) override {
UINFO(4, " ALW " << nodep << endl); UINFO(4, " ALW " << nodep << endl);
if (!nodep->bodysp()) { if (!nodep->stmtsp()) {
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }

View File

@ -70,7 +70,7 @@ private:
if (!m_monitorNumVarp) { if (!m_monitorNumVarp) {
m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum", m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum",
nodep->findUInt64DType()}; nodep->findUInt64DType()};
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorNumVarp); v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorNumVarp);
} }
const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorNumVarp, access); const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorNumVarp, access);
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
@ -80,7 +80,7 @@ private:
if (!m_monitorOffVarp) { if (!m_monitorOffVarp) {
m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff", m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff",
nodep->findBitDType()}; nodep->findBitDType()};
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorOffVarp); v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorOffVarp);
} }
const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorOffVarp, access); const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorOffVarp, access);
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
@ -147,7 +147,7 @@ private:
selfDestruct = true; selfDestruct = true;
} else { } else {
// V3Coverage assigned us a bucket to increment. // V3Coverage assigned us a bucket to increment.
AstCoverInc* const covincp = VN_AS(snodep->coverincp(), CoverInc); AstCoverInc* const covincp = VN_AS(snodep->coverincsp(), CoverInc);
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion"); UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace
if (message != "") covincp->declp()->comment(message); if (message != "") covincp->declp()->comment(message);
@ -209,7 +209,7 @@ private:
iterateAndNextNull(ifp->condp()); iterateAndNextNull(ifp->condp());
// Recurse into the true case. // Recurse into the true case.
iterateAndNextNull(ifp->ifsp()); iterateAndNextNull(ifp->thensp());
// If the last else is not an else if, recurse into that too. // If the last else is not an else if, recurse into that too.
if (ifp->elsesp() && !nextifp) { // if (ifp->elsesp() && !nextifp) { //
@ -338,15 +338,15 @@ private:
sentreep->unlinkFrBack(); sentreep->unlinkFrBack();
AstAlways* const alwaysp AstAlways* const alwaysp
= new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, nullptr); = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, nullptr);
m_modp->addStmtp(alwaysp); m_modp->addStmtsp(alwaysp);
for (uint32_t i = 0; i < ticks; ++i) { for (uint32_t i = 0; i < ticks; ++i) {
AstVar* const outvarp = new AstVar( AstVar* const outvarp = new AstVar(
nodep->fileline(), VVarType::MODULETEMP, nodep->fileline(), VVarType::MODULETEMP,
"_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep()); "_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep());
m_modp->addStmtp(outvarp); m_modp->addStmtsp(outvarp);
AstNode* const assp = new AstAssignDly( AstNode* const assp = new AstAssignDly(
nodep->fileline(), new AstVarRef(nodep->fileline(), outvarp, VAccess::WRITE), inp); nodep->fileline(), new AstVarRef(nodep->fileline(), outvarp, VAccess::WRITE), inp);
alwaysp->addStmtp(assp); alwaysp->addStmtsp(assp);
// if (debug() >= 9) assp->dumpTree(cout, "-ass: "); // if (debug() >= 9) assp->dumpTree(cout, "-ass: ");
invarp = outvarp; invarp = outvarp;
inp = new AstVarRef(nodep->fileline(), invarp, VAccess::READ); inp = new AstVarRef(nodep->fileline(), invarp, VAccess::READ);
@ -387,7 +387,7 @@ private:
stmtsp}; stmtsp};
ifp->branchPred(VBranchPred::BP_UNLIKELY); ifp->branchPred(VBranchPred::BP_UNLIKELY);
AstNode* const newp = new AstAlwaysPostponed{fl, ifp}; AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
m_modp->addStmtp(newp); m_modp->addStmtsp(newp);
} else if (nodep->displayType() == VDisplayType::DT_STROBE) { } else if (nodep->displayType() == VDisplayType::DT_STROBE) {
nodep->displayType(VDisplayType::DT_DISPLAY); nodep->displayType(VDisplayType::DT_DISPLAY);
// Need one-shot // Need one-shot
@ -395,7 +395,7 @@ private:
const auto varp const auto varp
= new AstVar{fl, VVarType::MODULETEMP, "__Vstrobe" + cvtToStr(m_modStrobeNum++), = new AstVar{fl, VVarType::MODULETEMP, "__Vstrobe" + cvtToStr(m_modStrobeNum++),
nodep->findBitDType()}; nodep->findBitDType()};
m_modp->addStmtp(varp); m_modp->addStmtsp(varp);
// Where $strobe was we do "__Vstrobe = '1;" // Where $strobe was we do "__Vstrobe = '1;"
const auto newsetp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, const auto newsetp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
new AstConst{fl, AstConst::BitTrue{}}}; new AstConst{fl, AstConst::BitTrue{}}};
@ -407,7 +407,7 @@ private:
AstNode* const newp = new AstAlwaysPostponed{fl, ifp}; AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
new AstConst{fl, AstConst::BitFalse{}}}); new AstConst{fl, AstConst::BitFalse{}}});
m_modp->addStmtp(newp); m_modp->addStmtsp(newp);
} }
} }
void visit(AstMonitorOff* nodep) override { void visit(AstMonitorOff* nodep) override {

View File

@ -84,7 +84,7 @@ private:
void visit(AstAlways* nodep) override { void visit(AstAlways* nodep) override {
iterateAndNextNull(nodep->sensesp()); iterateAndNextNull(nodep->sensesp());
if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp(); if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp();
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
m_seniAlwaysp = nullptr; m_seniAlwaysp = nullptr;
} }

View File

@ -61,7 +61,6 @@ bool AstNode::sameGateTree(const AstNode* node2p) const {
return sameTreeIter(this, node2p, true, true); return sameTreeIter(this, node2p, true, true);
} }
void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
int AstNodeArrayDType::left() const { return rangep()->leftConst(); } int AstNodeArrayDType::left() const { return rangep()->leftConst(); }
int AstNodeArrayDType::right() const { return rangep()->rightConst(); } int AstNodeArrayDType::right() const { return rangep()->rightConst(); }
int AstNodeArrayDType::hi() const { return rangep()->hiConst(); } int AstNodeArrayDType::hi() const { return rangep()->hiConst(); }
@ -71,13 +70,13 @@ VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right(
AstRange::AstRange(FileLine* fl, int left, int right) AstRange::AstRange(FileLine* fl, int left, int right)
: ASTGEN_SUPER_Range(fl) { : ASTGEN_SUPER_Range(fl) {
setOp2p(new AstConst{fl, static_cast<uint32_t>(left)}); leftp(new AstConst{fl, static_cast<uint32_t>(left)});
setOp3p(new AstConst{fl, static_cast<uint32_t>(right)}); rightp(new AstConst{fl, static_cast<uint32_t>(right)});
} }
AstRange::AstRange(FileLine* fl, const VNumRange& range) AstRange::AstRange(FileLine* fl, const VNumRange& range)
: ASTGEN_SUPER_Range(fl) { : ASTGEN_SUPER_Range(fl) {
setOp2p(new AstConst{fl, static_cast<uint32_t>(range.left())}); leftp(new AstConst{fl, static_cast<uint32_t>(range.left())});
setOp3p(new AstConst{fl, static_cast<uint32_t>(range.right())}); rightp(new AstConst{fl, static_cast<uint32_t>(range.right())});
} }
int AstRange::leftConst() const { int AstRange::leftConst() const {
AstConst* const constp = VN_CAST(leftp(), Const); AstConst* const constp = VN_CAST(leftp(), Const);
@ -97,7 +96,7 @@ AstPin::AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp)
: ASTGEN_SUPER_Pin(fl) : ASTGEN_SUPER_Pin(fl)
, m_pinNum{pinNum} , m_pinNum{pinNum}
, m_name{varname->name()} { , m_name{varname->name()} {
setNOp1p(exprp); this->exprp(exprp);
} }
AstDpiExportUpdated::AstDpiExportUpdated(FileLine* fl, AstVarScope* varScopep) AstDpiExportUpdated::AstDpiExportUpdated(FileLine* fl, AstVarScope* varScopep)
@ -112,7 +111,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType
: ASTGEN_SUPER_PackArrayDType(fl) { : ASTGEN_SUPER_PackArrayDType(fl) {
childDTypep(dtp); // Only for parser childDTypep(dtp); // Only for parser
refDTypep(nullptr); refDTypep(nullptr);
setOp2p(rangep); this->rangep(rangep);
dtypep(nullptr); // V3Width will resolve dtypep(nullptr); // V3Width will resolve
const int width = subDTypep()->width() * rangep->elementsConst(); const int width = subDTypep()->width() * rangep->elementsConst();
widthForce(width, width); widthForce(width, width);
@ -120,7 +119,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType
AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
: ASTGEN_SUPER_PackArrayDType(fl) { : ASTGEN_SUPER_PackArrayDType(fl) {
refDTypep(dtp); refDTypep(dtp);
setOp2p(rangep); this->rangep(rangep);
dtypep(this); dtypep(this);
const int width = subDTypep()->width() * rangep->elementsConst(); const int width = subDTypep()->width() * rangep->elementsConst();
widthForce(width, width); widthForce(width, width);
@ -141,20 +140,20 @@ bool AstActive::hasClocked() const { return m_sensesp->hasClocked(); }
AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp) AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp)
: ASTGEN_SUPER_ElabDisplay(fl) { : ASTGEN_SUPER_ElabDisplay(fl) {
setOp1p(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp}); addFmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp});
m_displayType = dispType; m_displayType = dispType;
} }
AstCStmt::AstCStmt(FileLine* fl, const string& textStmt) AstCStmt::AstCStmt(FileLine* fl, const string& textStmt)
: ASTGEN_SUPER_CStmt(fl) { : ASTGEN_SUPER_CStmt(fl) {
addNOp1p(new AstText{fl, textStmt, true}); addExprsp(new AstText{fl, textStmt, true});
} }
AstCMath::AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut) AstCMath::AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut)
: ASTGEN_SUPER_CMath(fl) : ASTGEN_SUPER_CMath(fl)
, m_cleanOut{cleanOut} , m_cleanOut{cleanOut}
, m_pure{true} { , m_pure{true} {
addNOp1p(new AstText{fl, textStmt, true}); addExprsp(new AstText{fl, textStmt, true});
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED); if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED);
} }

View File

@ -132,11 +132,13 @@ private:
}; };
class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType { class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
// Array data type, ie "some_dtype var_name [2:0]" // Array data type, ie "some_dtype var_name [2:0]"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// Children: RANGE (array bounds) // @astgen op2 := rangep : Optional[AstRange] // array bounds
private: private:
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable
AstNode* rangenp() const { return reinterpret_cast<AstNode*>(rangep()); }
protected: protected:
AstNodeArrayDType(VNType t, FileLine* fl) AstNodeArrayDType(VNType t, FileLine* fl)
: AstNodeDType{t, fl} {} : AstNodeDType{t, fl} {}
@ -165,14 +167,10 @@ public:
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
} }
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
AstRange* rangep() const { return VN_AS(op2p(), Range); } // op2 = Array(s) of variable
inline void rangep(AstRange* nodep);
// METHODS // METHODS
AstBasicDType* basicp() const override { AstBasicDType* basicp() const override {
return subDTypep()->basicp(); return subDTypep()->basicp();
@ -193,6 +191,7 @@ public:
}; };
class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType { class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType {
// A struct or union; common handling // A struct or union; common handling
// @astgen op1 := membersp : List[AstMemberDType]
private: private:
// TYPES // TYPES
using MemberNameMap = std::map<const std::string, AstMemberDType*>; using MemberNameMap = std::map<const std::string, AstMemberDType*>;
@ -233,16 +232,11 @@ public:
int widthAlignBytes() const override; int widthAlignBytes() const override;
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
int widthTotalBytes() const override; int widthTotalBytes() const override;
// op1 = members
bool similarDType(AstNodeDType* samep) const override { bool similarDType(AstNodeDType* samep) const override {
return this == samep; // We don't compare members, require exact equivalence return this == samep; // We don't compare members, require exact equivalence
} }
string name() const override { return m_name; } string name() const override { return m_name; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
AstMemberDType* membersp() const {
return VN_AS(op1p(), MemberDType);
} // op1 = AstMember list
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
bool packed() const { return m_packed; } bool packed() const { return m_packed; }
// packed() but as don't support unpacked, presently all structs // packed() but as don't support unpacked, presently all structs
static bool packedUnsup() { return true; } static bool packedUnsup() { return true; }
@ -263,33 +257,31 @@ public:
// === AstNode === // === AstNode ===
class AstEnumItem final : public AstNode { class AstEnumItem final : public AstNode {
// @astgen op1 := rangep : Optional[AstRange] // Range for name appending
// @astgen op2 := valuep : Optional[AstNode]
private: private:
string m_name; string m_name;
public: public:
// Parents: ENUM // Parents: ENUM
AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp) AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNode* valuep)
: ASTGEN_SUPER_EnumItem(fl) : ASTGEN_SUPER_EnumItem(fl)
, m_name{name} { , m_name{name} {
addNOp1p(rangep); this->rangep(rangep);
addNOp2p(initp); this->valuep(valuep);
} }
ASTGEN_MEMBERS_EnumItem; ASTGEN_MEMBERS_EnumItem;
string name() const override { return m_name; } string name() const override { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range for name appending
void rangep(AstRange* nodep) { addOp1p((AstNode*)nodep); }
AstNode* valuep() const { return op2p(); } // op2 = Value
void valuep(AstNode* nodep) { addOp2p(nodep); }
}; };
// === AstNodeDType === // === AstNodeDType ===
class AstAssocArrayDType final : public AstNodeDType { class AstAssocArrayDType final : public AstNodeDType {
// Associative array data type, ie "[some_dtype]" // Associative array data type, ie "[some_dtype]"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// Children: DTYPE (the key, which remains here as a pointer) // @astgen op2 := keyChildDTypep : AstNodeDType // the key, which remains here as a pointer
private: private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
AstNodeDType* m_keyDTypep; // Keys of this type (after widthing) AstNodeDType* m_keyDTypep; // Keys of this type (after widthing)
@ -335,9 +327,6 @@ public:
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); } AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -347,9 +336,6 @@ public:
// //
AstNodeDType* keyDTypep() const { return m_keyDTypep ? m_keyDTypep : keyChildDTypep(); } AstNodeDType* keyDTypep() const { return m_keyDTypep ? m_keyDTypep : keyChildDTypep(); }
void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; } void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; }
// op1 = Range of variable
AstNodeDType* keyChildDTypep() const { return VN_AS(op2p(), NodeDType); }
void keyChildDTypep(AstNodeDType* nodep) { setOp2p(nodep); }
// METHODS // METHODS
AstBasicDType* basicp() const override { return nullptr; } AstBasicDType* basicp() const override { return nullptr; }
AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; } AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
@ -361,7 +347,7 @@ public:
}; };
class AstBasicDType final : public AstNodeDType { class AstBasicDType final : public AstNodeDType {
// Builtin atomic/vectored data type // Builtin atomic/vectored data type
// Children: RANGE (converted to constant in V3Width) // @astgen op1 := rangep : Optional[AstRange] // Range of variable
private: private:
struct Members { struct Members {
VBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type VBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type
@ -415,8 +401,6 @@ public:
BROKEN_RTN(dtypep() != this); BROKEN_RTN(dtypep() != this);
return nullptr; return nullptr;
} }
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range of variable
void rangep(AstRange* nodep) { setNOp1p((AstNode*)nodep); }
void setSignedState(const VSigning& signst) { void setSignedState(const VSigning& signst) {
// Note NOSIGN does NOT change the state; this is required by the parser // Note NOSIGN does NOT change the state; this is required by the parser
if (signst == VSigning::UNSIGNED) { if (signst == VSigning::UNSIGNED) {
@ -470,21 +454,18 @@ public:
class AstBracketArrayDType final : public AstNodeDType { class AstBracketArrayDType final : public AstNodeDType {
// Associative/Queue/Normal array data type, ie "[dtype_or_expr]" // Associative/Queue/Normal array data type, ie "[dtype_or_expr]"
// only for early parsing then becomes another data type // only for early parsing then becomes another data type
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// Children: DTYPE (the key) // @astgen op2 := elementsp : AstNode // ??? key dtype ???
public: public:
AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* elementsp) AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* childDTypep,
AstNode* elementsp)
: ASTGEN_SUPER_BracketArrayDType(fl) { : ASTGEN_SUPER_BracketArrayDType(fl) {
setOp1p(dtp); // Only for parser this->childDTypep(childDTypep);
setOp2p(elementsp); // Only for parser this->elementsp(elementsp);
} }
ASTGEN_MEMBERS_BracketArrayDType; ASTGEN_MEMBERS_BracketArrayDType;
bool similarDType(AstNodeDType* samep) const override { V3ERROR_NA_RETURN(false); } bool similarDType(AstNodeDType* samep) const override { V3ERROR_NA_RETURN(false); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
AstNodeDType* subDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override { return childDTypep(); }
// op2 = Range of variable
AstNode* elementsp() const { return op2p(); }
// METHODS // METHODS
// Will be removed in V3Width, which relies on this // Will be removed in V3Width, which relies on this
// being a child not a dtype pointed node // being a child not a dtype pointed node
@ -499,16 +480,16 @@ public:
}; };
class AstClassRefDType final : public AstNodeDType { class AstClassRefDType final : public AstNodeDType {
// Reference to a class // Reference to a class
// Children: PINs (for parameter settings) // @astgen op1 := paramsp: List[AstPin]
private: private:
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
public: public:
AstClassRefDType(FileLine* fl, AstClass* classp, AstNode* paramsp) AstClassRefDType(FileLine* fl, AstClass* classp, AstPin* paramsp)
: ASTGEN_SUPER_ClassRefDType(fl) : ASTGEN_SUPER_ClassRefDType(fl)
, m_classp{classp} { , m_classp{classp} {
dtypep(this); this->dtypep(this);
addNOp4p(paramsp); this->addParamsp(paramsp);
} }
ASTGEN_MEMBERS_ClassRefDType; ASTGEN_MEMBERS_ClassRefDType;
// METHODS // METHODS
@ -537,13 +518,13 @@ public:
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
AstClass* classp() const { return m_classp; } AstClass* classp() const { return m_classp; }
void classp(AstClass* nodep) { m_classp = nodep; } void classp(AstClass* nodep) { m_classp = nodep; }
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
bool isCompound() const override { return true; } bool isCompound() const override { return true; }
}; };
class AstConstDType final : public AstNodeDType { class AstConstDType final : public AstNodeDType {
// const data type, ie "const some_dtype var_name [2:0]" // const data type, ie "const some_dtype var_name [2:0]"
// ConstDType are removed in V3LinkLValue and become AstVar::isConst. // ConstDType are removed in V3LinkLValue and become AstVar::isConst.
// When more generic types are supported AstConstDType will be propagated further. // When more generic types are supported AstConstDType will be propagated further.
// @astgen op1 := childDTypep : Optional[AstNodeDType]
private: private:
AstNodeDType* m_refDTypep = nullptr; // Inherit from this base data type AstNodeDType* m_refDTypep = nullptr; // Inherit from this base data type
public: public:
@ -571,9 +552,6 @@ public:
return skipRefp()->similarDType(samep->skipRefp()); return skipRefp()->similarDType(samep->skipRefp());
} }
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -594,6 +572,7 @@ class AstDefImplicitDType final : public AstNodeDType {
// For parsing enum/struct/unions that are declared with a variable rather than typedef // For parsing enum/struct/unions that are declared with a variable rather than typedef
// This allows "var enum {...} a,b" to share the enum definition for both variables // This allows "var enum {...} a,b" to share the enum definition for both variables
// After link, these become typedefs // After link, these become typedefs
// @astgen op1 := childDTypep : Optional[AstNodeDType]
private: private:
string m_name; string m_name;
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate void* m_containerp; // In what scope is the name unique, so we can know what are duplicate
@ -620,9 +599,6 @@ public:
return type() == samep->type() && same(samep); return type() == samep->type() && same(samep);
} }
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); } AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); }
void* containerp() const { return m_containerp; } void* containerp() const { return m_containerp; }
// METHODS // METHODS
@ -640,7 +616,7 @@ public:
}; };
class AstDynArrayDType final : public AstNodeDType { class AstDynArrayDType final : public AstNodeDType {
// Dynamic array data type, ie "[]" // Dynamic array data type, ie "[]"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
private: private:
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
public: public:
@ -677,9 +653,6 @@ public:
string prettyDTypeName() const override; string prettyDTypeName() const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -722,19 +695,20 @@ public:
}; };
class AstEnumDType final : public AstNodeDType { class AstEnumDType final : public AstNodeDType {
// Parents: TYPEDEF/MODULE // Parents: TYPEDEF/MODULE
// Children: ENUMVALUEs // @astgen op1 := childDTypep : Optional[AstNodeDType]
// @astgen op2 := itemsp : List[AstEnumItem]
private: private:
string m_name; // Name from upper typedef, if any string m_name; // Name from upper typedef, if any
AstNodeDType* m_refDTypep = nullptr; // Elements are of this type after V3Width AstNodeDType* m_refDTypep = nullptr; // Elements are of this type after V3Width
const int m_uniqueNum = 0; const int m_uniqueNum = 0;
public: public:
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp) AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstEnumItem* itemsp)
: ASTGEN_SUPER_EnumDType(fl) : ASTGEN_SUPER_EnumDType(fl)
, m_uniqueNum{uniqueNumInc()} { , m_uniqueNum{uniqueNumInc()} {
childDTypep(dtp); // Only for parser childDTypep(dtp); // Only for parser
refDTypep(nullptr); refDTypep(nullptr);
addNOp2p(itemsp); addItemsp(itemsp);
dtypep(nullptr); // V3Width will resolve dtypep(nullptr); // V3Width will resolve
widthFromSub(subDTypep()); widthFromSub(subDTypep());
} }
@ -754,16 +728,12 @@ public:
} }
bool similarDType(AstNodeDType* samep) const override { return this == samep; } bool similarDType(AstNodeDType* samep) const override { return this == samep; }
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } // op1 = Data type
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
// op1 = Range of variable
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
string name() const override { return m_name; } string name() const override { return m_name; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
AstEnumItem* itemsp() const { return VN_AS(op2p(), EnumItem); } // op2 = AstEnumItem's
// METHODS // METHODS
AstBasicDType* basicp() const override { return subDTypep()->basicp(); } AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); } AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
@ -835,6 +805,7 @@ public:
class AstMemberDType final : public AstNodeDType { class AstMemberDType final : public AstNodeDType {
// A member of a struct/union // A member of a struct/union
// PARENT: AstNodeUOrStructDType // PARENT: AstNodeUOrStructDType
// @astgen op1 := childDTypep : Optional[AstNodeDType]
private: private:
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
string m_name; // Name of variable string m_name; // Name of variable
@ -869,9 +840,6 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -904,6 +872,7 @@ public:
class AstParamTypeDType final : public AstNodeDType { class AstParamTypeDType final : public AstNodeDType {
// Parents: MODULE // Parents: MODULE
// A parameter type statement; much like a var or typedef // A parameter type statement; much like a var or typedef
// @astgen op1 := childDTypep : Optional[AstNodeDType]
private: private:
const VVarType m_varType; // Type of variable (for localparam vs. param) const VVarType m_varType; // Type of variable (for localparam vs. param)
string m_name; // Name of variable string m_name; // Name of variable
@ -918,9 +887,6 @@ public:
} }
ASTGEN_MEMBERS_ParamTypeDType; ASTGEN_MEMBERS_ParamTypeDType;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Type assigning to
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); } AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); }
AstBasicDType* basicp() const override { return subDTypep()->basicp(); } AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); } AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
@ -972,20 +938,21 @@ public:
}; };
class AstQueueDType final : public AstNodeDType { class AstQueueDType final : public AstNodeDType {
// Queue array data type, ie "[ $ ]" // Queue array data type, ie "[ $ ]"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// @astgen op2 := boundp : Optional[AstNode]
private: private:
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing) AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
public: public:
AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp) AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp)
: ASTGEN_SUPER_QueueDType(fl) { : ASTGEN_SUPER_QueueDType(fl) {
setNOp2p(boundp); this->childDTypep(dtp);
childDTypep(dtp); // Only for parser this->boundp(boundp);
refDTypep(nullptr); refDTypep(nullptr);
dtypep(nullptr); // V3Width will resolve dtypep(nullptr); // V3Width will resolve
} }
AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp) AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp)
: ASTGEN_SUPER_QueueDType(fl) { : ASTGEN_SUPER_QueueDType(fl) {
setNOp2p(boundp); this->boundp(boundp);
refDTypep(dtp); refDTypep(dtp);
dtypep(dtp); dtypep(dtp);
} }
@ -1011,13 +978,8 @@ public:
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
string prettyDTypeName() const override; string prettyDTypeName() const override;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none
void boundp(AstNode* nodep) { setNOp2p(nodep); }
inline int boundConst() const; inline int boundConst() const;
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
@ -1034,6 +996,9 @@ public:
bool isCompound() const override { return true; } bool isCompound() const override { return true; }
}; };
class AstRefDType final : public AstNodeDType { class AstRefDType final : public AstNodeDType {
// @astgen op1 := typeofp : AstNode
// @astgen op2 := classOrPackageOpp : Optional[AstNode]
// @astgen op3 := paramsp : List[AstPin]
private: private:
// Pre-Width must reference the Typeref, not what it points to, as some child // Pre-Width must reference the Typeref, not what it points to, as some child
// types like AstBracketArrayType will disappear and can't lose the handle // types like AstBracketArrayType will disappear and can't lose the handle
@ -1046,16 +1011,16 @@ public:
AstRefDType(FileLine* fl, const string& name) AstRefDType(FileLine* fl, const string& name)
: ASTGEN_SUPER_RefDType(fl) : ASTGEN_SUPER_RefDType(fl)
, m_name{name} {} , m_name{name} {}
AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstNode* paramsp) AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstPin* paramsp)
: ASTGEN_SUPER_RefDType(fl) : ASTGEN_SUPER_RefDType(fl)
, m_name{name} { , m_name{name} {
setNOp3p(classOrPackagep); this->classOrPackageOpp(classOrPackagep);
addNOp4p(paramsp); addParamsp(paramsp);
} }
class FlagTypeOfExpr {}; // type(expr) for parser only class FlagTypeOfExpr {}; // type(expr) for parser only
AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp) AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp)
: ASTGEN_SUPER_RefDType(fl) { : ASTGEN_SUPER_RefDType(fl) {
setOp2p(typeofp); this->typeofp(typeofp);
} }
ASTGEN_MEMBERS_RefDType; ASTGEN_MEMBERS_RefDType;
// METHODS // METHODS
@ -1106,7 +1071,6 @@ public:
int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); } int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); }
int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); } int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
// op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
AstTypedef* typedefp() const { return m_typedefp; } AstTypedef* typedefp() const { return m_typedefp; }
void typedefp(AstTypedef* nodep) { m_typedefp = nodep; } void typedefp(AstTypedef* nodep) { m_typedefp = nodep; }
@ -1116,9 +1080,6 @@ public:
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; } AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
AstNode* typeofp() const { return op2p(); }
AstNode* classOrPackageOpp() const { return op3p(); }
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
bool isCompound() const override { bool isCompound() const override {
v3fatalSrc("call isCompound on subdata type, not reference"); v3fatalSrc("call isCompound on subdata type, not reference");
return false; return false;
@ -1126,7 +1087,7 @@ public:
}; };
class AstUnsizedArrayDType final : public AstNodeDType { class AstUnsizedArrayDType final : public AstNodeDType {
// Unsized/open-range Array data type, ie "some_dtype var_name []" // Unsized/open-range Array data type, ie "some_dtype var_name []"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
private: private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
public: public:
@ -1149,9 +1110,6 @@ public:
bool similarDType(AstNodeDType* samep) const override; bool similarDType(AstNodeDType* samep) const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -1194,7 +1152,7 @@ public:
}; };
class AstWildcardArrayDType final : public AstNodeDType { class AstWildcardArrayDType final : public AstNodeDType {
// Wildcard index type associative array data type, ie "some_dtype var_name [*]" // Wildcard index type associative array data type, ie "some_dtype var_name [*]"
// Children: DTYPE (moved to refDTypep() in V3Width) // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
private: private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
public: public:
@ -1217,9 +1175,6 @@ public:
bool similarDType(AstNodeDType* samep) const override; bool similarDType(AstNodeDType* samep) const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* getChildDTypep() const override { return childDTypep(); }
// op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); } AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -1237,8 +1192,6 @@ public:
// === AstNodeArrayDType === // === AstNodeArrayDType ===
class AstPackArrayDType final : public AstNodeArrayDType { class AstPackArrayDType final : public AstNodeArrayDType {
// Packed array data type, ie "some_dtype [2:0] var_name" // Packed array data type, ie "some_dtype [2:0] var_name"
// Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds)
public: public:
inline AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep); inline AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep);
inline AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep); inline AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep);
@ -1248,15 +1201,13 @@ public:
}; };
class AstUnpackArrayDType final : public AstNodeArrayDType { class AstUnpackArrayDType final : public AstNodeArrayDType {
// Array data type, ie "some_dtype var_name [2:0]" // Array data type, ie "some_dtype var_name [2:0]"
// Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds)
bool m_isCompound = false; // Non-POD subDType, or parent requires compound bool m_isCompound = false; // Non-POD subDType, or parent requires compound
public: public:
AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
: ASTGEN_SUPER_UnpackArrayDType(fl) { : ASTGEN_SUPER_UnpackArrayDType(fl) {
childDTypep(dtp); // Only for parser this->childDTypep(dtp); // Only for parser
this->rangep(rangep);
refDTypep(nullptr); refDTypep(nullptr);
setOp2p((AstNode*)rangep);
dtypep(nullptr); // V3Width will resolve dtypep(nullptr); // V3Width will resolve
// For backward compatibility AstNodeArrayDType and others inherit // For backward compatibility AstNodeArrayDType and others inherit
// width and signing from the subDType/base type // width and signing from the subDType/base type
@ -1264,8 +1215,8 @@ public:
} }
AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
: ASTGEN_SUPER_UnpackArrayDType(fl) { : ASTGEN_SUPER_UnpackArrayDType(fl) {
this->rangep(rangep);
refDTypep(dtp); refDTypep(dtp);
setOp2p((AstNode*)rangep);
dtypep(this); dtypep(this);
// For backward compatibility AstNodeArrayDType and others inherit // For backward compatibility AstNodeArrayDType and others inherit
// width and signing from the subDType/base type // width and signing from the subDType/base type

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -188,8 +188,8 @@ void AstBasicDType::init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int
widthForce(rangep->elementsConst(), widthForce(rangep->elementsConst(),
rangep->elementsConst()); // Maybe unknown if parameters underneath it rangep->elementsConst()); // Maybe unknown if parameters underneath it
} }
setNOp1p(rangep); this->rangep(rangep);
dtypep(this); this->dtypep(this);
} }
void AstBasicDType::cvtRangeConst() { void AstBasicDType::cvtRangeConst() {
@ -660,25 +660,15 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
} else { } else {
return nullptr; return nullptr;
} }
} else if (VN_IS(nodep, VarRef)) { } else if (AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) {
if (VN_AS(nodep, VarRef)->varp()->isSc()) { if (vrefp->varp()->isSc()) {
return VN_AS(nodep, VarRef)->varp(); return vrefp->varp();
} else { } else {
return nullptr; return nullptr;
} }
} else if (VN_IS(nodep, ArraySel)) { } else if (AstArraySel* const arraySelp = VN_CAST(nodep, ArraySel)) {
if (nodep->op1p()) { if (AstVar* const p = scVarRecurse(arraySelp->fromp())) return p;
if (AstVar* p = scVarRecurse(nodep->op1p())) return p; if (AstVar* const p = scVarRecurse(arraySelp->bitp())) return p;
}
if (nodep->op2p()) {
if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
}
if (nodep->op3p()) {
if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
}
if (nodep->op4p()) {
if (AstVar* p = scVarRecurse(nodep->op4p())) return p;
}
} }
return nullptr; return nullptr;
} }
@ -1070,8 +1060,8 @@ AstConstPool::AstConstPool(FileLine* fl)
: ASTGEN_SUPER_ConstPool(fl) : ASTGEN_SUPER_ConstPool(fl)
, m_modp{new AstModule(fl, "@CONST-POOL@")} , m_modp{new AstModule(fl, "@CONST-POOL@")}
, m_scopep{new AstScope(fl, m_modp, "@CONST-POOL@", nullptr, nullptr)} { , m_scopep{new AstScope(fl, m_modp, "@CONST-POOL@", nullptr, nullptr)} {
addOp1p(m_modp); this->modulep(m_modp);
m_modp->addStmtp(m_scopep); m_modp->addStmtsp(m_scopep);
} }
const char* AstConstPool::broken() const { const char* AstConstPool::broken() const {
BROKEN_RTN(m_modp && !m_modp->brokeExists()); BROKEN_RTN(m_modp && !m_modp->brokeExists());
@ -1085,9 +1075,9 @@ AstVarScope* AstConstPool::createNewEntry(const string& name, AstNode* initp) {
varp->isConst(true); varp->isConst(true);
varp->isStatic(true); varp->isStatic(true);
varp->valuep(initp->cloneTree(false)); varp->valuep(initp->cloneTree(false));
m_modp->addStmtp(varp); m_modp->addStmtsp(varp);
AstVarScope* const varScopep = new AstVarScope(fl, m_scopep, varp); AstVarScope* const varScopep = new AstVarScope(fl, m_scopep, varp);
m_scopep->addVarp(varScopep); m_scopep->addVarsp(varScopep);
return varScopep; return varScopep;
} }
@ -1233,7 +1223,7 @@ void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) {
} else if (belowp == condp()) { } else if (belowp == condp()) {
// Goes before condition, IE in preconditions // Goes before condition, IE in preconditions
addPrecondsp(newp); addPrecondsp(newp);
} else if (belowp == bodysp()) { } else if (belowp == stmtsp()) {
// Was first statement in body, so new front // Was first statement in body, so new front
belowp->addHereThisAsNext(newp); belowp->addHereThisAsNext(newp);
} else { } else {
@ -1250,12 +1240,12 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
belowp->addNextHere(newp); belowp->addNextHere(newp);
} else if (belowp == condp()) { } else if (belowp == condp()) {
// Becomes first statement in body, body may have been empty // Becomes first statement in body, body may have been empty
if (bodysp()) { if (stmtsp()) {
bodysp()->addHereThisAsNext(newp); stmtsp()->addHereThisAsNext(newp);
} else { } else {
addBodysp(newp); addStmtsp(newp);
} }
} else if (belowp == bodysp()) { } else if (belowp == stmtsp()) {
// Next statement in body // Next statement in body
belowp->addNextHere(newp); belowp->addNextHere(newp);
} else { } else {
@ -1521,19 +1511,15 @@ void AstInitArray::cloneRelink() {
if (it->second->clonep()) it->second = it->second->clonep(); if (it->second->clonep()) it->second = it->second->clonep();
} }
} }
AstNode* AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) { void AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) {
// Returns old value, caller must garbage collect
AstNode* oldp = nullptr;
const auto it = m_map.find(index); const auto it = m_map.find(index);
if (it != m_map.end()) { if (it != m_map.end()) {
oldp = it->second->valuep();
it->second->valuep(newp); it->second->valuep(newp);
} else { } else {
AstInitItem* const itemp = new AstInitItem(fileline(), newp); AstInitItem* const itemp = new AstInitItem(fileline(), newp);
m_map.emplace(index, itemp); m_map.emplace(index, itemp);
addOp2p(itemp); addInitsp(itemp);
} }
return oldp;
} }
AstNode* AstInitArray::getIndexValuep(uint64_t index) const { AstNode* AstInitArray::getIndexValuep(uint64_t index) const {
const auto it = m_map.find(index); const auto it = m_map.find(index);
@ -1808,7 +1794,7 @@ AstPackage* AstNetlist::dollarUnitPkgAddp() {
m_dollarUnitPkgp->inLibrary(true); m_dollarUnitPkgp->inLibrary(true);
m_dollarUnitPkgp->modTrace(false); // may reconsider later m_dollarUnitPkgp->modTrace(false); // may reconsider later
m_dollarUnitPkgp->internal(true); m_dollarUnitPkgp->internal(true);
addModulep(m_dollarUnitPkgp); addModulesp(m_dollarUnitPkgp);
} }
return m_dollarUnitPkgp; return m_dollarUnitPkgp;
} }
@ -1816,7 +1802,7 @@ void AstNetlist::createTopScope(AstScope* scopep) {
UASSERT(scopep, "Must not be nullptr"); UASSERT(scopep, "Must not be nullptr");
UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits"); UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits");
m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep}; m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep};
scopep->modp()->addStmtp(v3Global.rootp()->topScopep()); scopep->modp()->addStmtsp(v3Global.rootp()->topScopep());
} }
void AstNodeModule::dump(std::ostream& str) const { void AstNodeModule::dump(std::ostream& str) const {
this->AstNode::dump(str); this->AstNode::dump(str);

View File

@ -115,7 +115,7 @@ private:
} }
} else { } else {
// Move to module // Move to module
m_modp->addStmtp(nodep); m_modp->addStmtsp(nodep);
} }
} }
@ -214,7 +214,7 @@ private:
UINFO(8, " rename to " << nodep->name() << endl); UINFO(8, " rename to " << nodep->name() << endl);
// Move to module // Move to module
nodep->unlinkFrBack(); nodep->unlinkFrBack();
m_modp->addStmtp(nodep); m_modp->addStmtsp(nodep);
} }
iterateChildren(nodep); iterateChildren(nodep);
} }
@ -233,10 +233,10 @@ private:
const string scname = nodep->forFormat() ? m_displayScope : m_namedScope; const string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
if (!scname.empty()) { if (!scname.empty()) {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* const afterp = nodep->scopeAttrp(); AstText* const afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname}); nodep->addScopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname});
if (afterp) nodep->scopeAttrp(afterp); if (afterp) nodep->addScopeAttrp(afterp);
} }
iterateChildren(nodep); iterateChildren(nodep);
} }

View File

@ -70,7 +70,7 @@ private:
{ {
// Do if // Do if
reset(); reset();
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
const int ifLikely = m_likely; const int ifLikely = m_likely;
const int ifUnlikely = m_unlikely; const int ifUnlikely = m_unlikely;
// Do else // Do else

View File

@ -275,9 +275,9 @@ private:
pushLocalScope(); pushLocalScope();
processEnter(nodep); processEnter(nodep);
processAndIterate(nodep->condp()); processAndIterate(nodep->condp());
if (AstNode* const ifsp = nodep->ifsp()) { if (AstNode* const thensp = nodep->thensp()) {
pushLocalScope(); pushLocalScope();
processAndIterateList(ifsp); processAndIterateList(thensp);
popLocalScope(); popLocalScope();
} }
if (AstNode* const elsesp = nodep->elsesp()) { if (AstNode* const elsesp = nodep->elsesp()) {

View File

@ -77,7 +77,7 @@ private:
if (!preventUnusedStmt.empty()) { if (!preventUnusedStmt.empty()) {
funcp->addStmtsp(new AstCStmt{m_modp->fileline(), preventUnusedStmt}); funcp->addStmtsp(new AstCStmt{m_modp->fileline(), preventUnusedStmt});
} }
m_modp->addStmtp(funcp); m_modp->addStmtsp(funcp);
m_numStmts = 0; m_numStmts = 0;
return funcp; return funcp;
} }
@ -136,7 +136,7 @@ void V3CCtors::evalAsserts() {
funcp->isLoose(true); funcp->isLoose(true);
funcp->slow(false); funcp->slow(false);
funcp->ifdef("VL_DEBUG"); funcp->ifdef("VL_DEBUG");
modp->addStmtp(funcp); modp->addStmtsp(funcp);
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* const varp = VN_CAST(np, Var)) { if (AstVar* const varp = VN_CAST(np, Var)) {
if (varp->isPrimaryInish() && !varp->isSc()) { if (varp->isPrimaryInish() && !varp->isSc()) {
@ -209,7 +209,7 @@ void V3CCtors::cctorsAll() {
// If can be referred to by base pointer, need virtual delete // If can be referred to by base pointer, need virtual delete
funcp->isVirtual(classp->isExtended()); funcp->isVirtual(classp->isExtended());
funcp->slow(false); funcp->slow(false);
modp->addStmtp(funcp); modp->addStmtsp(funcp);
} }
} }
} }

View File

@ -51,7 +51,7 @@ class CUseVisitor final : public VNVisitor {
void addNewUse(AstNode* nodep, VUseType useType, const string& name) { void addNewUse(AstNode* nodep, VUseType useType, const string& name) {
if (m_didUse.emplace(useType, name).second) { if (m_didUse.emplace(useType, name).second) {
AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name}; AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name};
m_modp->addStmtp(newp); m_modp->addStmtsp(newp);
UINFO(8, "Insert " << newp << endl); UINFO(8, "Insert " << newp << endl);
} }
} }

View File

@ -245,7 +245,7 @@ private:
// Convert valueItem from AstCaseItem* to the expression // Convert valueItem from AstCaseItem* to the expression
// Not done earlier, as we may now have a nullptr because it's just a ";" NOP branch // Not done earlier, as we may now have a nullptr because it's just a ";" NOP branch
for (uint32_t i = 0; i < numCases; ++i) { for (uint32_t i = 0; i < numCases; ++i) {
m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->bodysp(); m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->stmtsp();
} }
return true; // All is fine return true; // All is fine
} }
@ -346,7 +346,7 @@ private:
itemp = VN_AS(itemp->nextp(), CaseItem)) { itemp = VN_AS(itemp->nextp(), CaseItem)) {
if (!itemp->condsp()) { if (!itemp->condsp()) {
// Default clause. Just make true, we'll optimize it away later // Default clause. Just make true, we'll optimize it away later
itemp->condsp(new AstConst(itemp->fileline(), AstConst::BitTrue())); itemp->addCondsp(new AstConst(itemp->fileline(), AstConst::BitTrue()));
hadDefault = true; hadDefault = true;
} else { } else {
// Expressioned clause // Expressioned clause
@ -397,7 +397,7 @@ private:
} }
} }
// Replace expression in tree // Replace expression in tree
itemp->condsp(ifexprp); itemp->addCondsp(ifexprp);
} }
} }
VL_DO_DANGLING(cexprp->deleteTree(), cexprp); VL_DO_DANGLING(cexprp->deleteTree(), cexprp);
@ -420,7 +420,7 @@ private:
AstIf* itemnextp = nullptr; AstIf* itemnextp = nullptr;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; for (AstCaseItem* itemp = nodep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), CaseItem)) { itemp = VN_AS(itemp->nextp(), CaseItem)) {
AstNode* const istmtsp = itemp->bodysp(); // Maybe null -- no action. AstNode* const istmtsp = itemp->stmtsp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext(); if (istmtsp) istmtsp->unlinkFrBackWithNext();
// Expressioned clause // Expressioned clause
AstNode* const ifexprp = itemp->condsp()->unlinkFrBack(); AstNode* const ifexprp = itemp->condsp()->unlinkFrBack();
@ -452,7 +452,7 @@ private:
if (itemnextp) { if (itemnextp) {
itemnextp->addElsesp(newp); itemnextp->addElsesp(newp);
} else { } else {
groupnextp->addIfsp(newp); // First in a new group groupnextp->addThensp(newp); // First in a new group
} }
itemnextp = newp; itemnextp = newp;
} }

View File

@ -67,7 +67,7 @@ public:
m_tlChgFuncp->isStatic(false); m_tlChgFuncp->isStatic(false);
m_tlChgFuncp->isLoose(true); m_tlChgFuncp->isLoose(true);
m_tlChgFuncp->declPrivate(true); m_tlChgFuncp->declPrivate(true);
m_scopetopp->addActivep(m_tlChgFuncp); m_scopetopp->addBlocksp(m_tlChgFuncp);
// Each change detection function needs at least one AstChangeDet // Each change detection function needs at least one AstChangeDet
// to ensure that V3EmitC outputs the necessary code. // to ensure that V3EmitC outputs the necessary code.
maybeCreateMidChg(); maybeCreateMidChg();
@ -86,7 +86,7 @@ public:
m_chgFuncp->isStatic(false); m_chgFuncp->isStatic(false);
m_chgFuncp->isLoose(true); m_chgFuncp->isLoose(true);
m_chgFuncp->declPrivate(true); m_chgFuncp->declPrivate(true);
m_scopetopp->addActivep(m_chgFuncp); m_scopetopp->addBlocksp(m_chgFuncp);
// Add a top call to it // Add a top call to it
AstCCall* const callp = new AstCCall{m_scopetopp->fileline(), m_chgFuncp}; AstCCall* const callp = new AstCCall{m_scopetopp->fileline(), m_chgFuncp};
@ -218,9 +218,9 @@ public:
// CHANGEDET(VARREF(_last), VARREF(var)) // CHANGEDET(VARREF(_last), VARREF(var))
AstVar* const newvarp AstVar* const newvarp
= new AstVar{varp->fileline(), VVarType::MODULETEMP, newvarname, varp}; = new AstVar{varp->fileline(), VVarType::MODULETEMP, newvarname, varp};
m_state.m_topModp->addStmtp(newvarp); m_state.m_topModp->addStmtsp(newvarp);
m_newvscp = new AstVarScope{m_vscp->fileline(), m_state.m_scopetopp, newvarp}; m_newvscp = new AstVarScope{m_vscp->fileline(), m_state.m_scopetopp, newvarp};
m_state.m_scopetopp->addVarp(m_newvscp); m_state.m_scopetopp->addVarsp(m_newvscp);
m_varEqnp = new AstVarRef{m_vscp->fileline(), m_vscp, VAccess::READ}; m_varEqnp = new AstVarRef{m_vscp->fileline(), m_vscp, VAccess::READ};
m_newLvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::WRITE}; m_newLvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::WRITE};

View File

@ -54,7 +54,7 @@ private:
// Move this class // Move this class
nodep->name(m_prefix + nodep->name()); nodep->name(m_prefix + nodep->name());
nodep->unlinkFrBack(); nodep->unlinkFrBack();
v3Global.rootp()->addModulep(nodep); v3Global.rootp()->addModulesp(nodep);
// Make containing package // Make containing package
// Note origName is the same as the class origName so errors look correct // Note origName is the same as the class origName so errors look correct
AstClassPackage* const packagep AstClassPackage* const packagep
@ -62,7 +62,7 @@ private:
packagep->name(nodep->name() + "__Vclpkg"); packagep->name(nodep->name() + "__Vclpkg");
nodep->classOrPackagep(packagep); nodep->classOrPackagep(packagep);
packagep->classp(nodep); packagep->classp(nodep);
v3Global.rootp()->addModulep(packagep); v3Global.rootp()->addModulesp(packagep);
// Add package to hierarchy // Add package to hierarchy
AstCell* const cellp = new AstCell{packagep->fileline(), AstCell* const cellp = new AstCell{packagep->fileline(),
packagep->fileline(), packagep->fileline(),
@ -72,7 +72,7 @@ private:
nullptr, nullptr,
nullptr}; nullptr};
cellp->modp(packagep); cellp->modp(packagep);
v3Global.rootp()->topModulep()->addStmtp(cellp); v3Global.rootp()->topModulep()->addStmtsp(cellp);
// Find class's scope // Find class's scope
// Alternative would be to move this and related to V3Scope // Alternative would be to move this and related to V3Scope
const AstScope* classScopep = nullptr; const AstScope* classScopep = nullptr;
@ -85,7 +85,7 @@ private:
AstScope* const scopep AstScope* const scopep
= new AstScope{nodep->fileline(), packagep, classScopep->name(), = new AstScope{nodep->fileline(), packagep, classScopep->name(),
classScopep->aboveScopep(), classScopep->aboveCellp()}; classScopep->aboveScopep(), classScopep->aboveCellp()};
packagep->addStmtp(scopep); packagep->addStmtsp(scopep);
// Iterate // Iterate
VL_RESTORER(m_prefix); VL_RESTORER(m_prefix);
VL_RESTORER(m_classPackagep); VL_RESTORER(m_classPackagep);
@ -178,15 +178,15 @@ public:
AstScope* const scopep = moved.second; AstScope* const scopep = moved.second;
UINFO(9, "moving " << nodep << " to " << scopep << endl); UINFO(9, "moving " << nodep << " to " << scopep << endl);
if (VN_IS(nodep, NodeFTask)) { if (VN_IS(nodep, NodeFTask)) {
scopep->addActivep(nodep->unlinkFrBack()); scopep->addBlocksp(nodep->unlinkFrBack());
} else if (VN_IS(nodep, Var)) { } else if (VN_IS(nodep, Var)) {
AstVarScope* const vscp = VN_AS(nodep->user1p(), VarScope); AstVarScope* const vscp = VN_AS(nodep->user1p(), VarScope);
vscp->scopep(scopep); vscp->scopep(scopep);
vscp->unlinkFrBack(); vscp->unlinkFrBack();
scopep->addVarp(vscp); scopep->addVarsp(vscp);
} else if (VN_IS(nodep, Initial) || VN_IS(nodep, InitialStatic)) { } else if (VN_IS(nodep, Initial) || VN_IS(nodep, InitialStatic)) {
nodep->unlinkFrBack(); nodep->unlinkFrBack();
scopep->addActivep(nodep); scopep->addBlocksp(nodep);
} else { } else {
nodep->v3fatalSrc("Bad case"); nodep->v3fatalSrc("Bad case");
} }
@ -196,7 +196,7 @@ public:
AstNodeModule* const modp = moved.second; AstNodeModule* const modp = moved.second;
UINFO(9, "moving " << nodep << " to " << modp << endl); UINFO(9, "moving " << nodep << " to " << modp << endl);
nodep->unlinkFrBack(); nodep->unlinkFrBack();
modp->addStmtp(nodep); modp->addStmtsp(nodep);
} }
} }
}; };

View File

@ -236,7 +236,7 @@ private:
setClean(nodep, false); setClean(nodep, false);
// We always clean, as we don't trust those pesky users. // We always clean, as we don't trust those pesky users.
if (!VN_IS(nodep->backp(), And)) insertClean(nodep); if (!VN_IS(nodep->backp(), And)) insertClean(nodep);
ensureCleanAndNext(nodep->bodysp()); ensureCleanAndNext(nodep->exprsp());
} }
void visit(AstTraceDecl* nodep) override { void visit(AstTraceDecl* nodep) override {
// No cleaning, or would loose pointer to enum // No cleaning, or would loose pointer to enum
@ -259,7 +259,7 @@ private:
void visit(AstNodeCond* nodep) override { void visit(AstNodeCond* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
ensureClean(nodep->condp()); ensureClean(nodep->condp());
setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p())); setClean(nodep, isClean(nodep->thenp()) && isClean(nodep->elsep()));
} }
void visit(AstWhile* nodep) override { void visit(AstWhile* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
@ -276,7 +276,7 @@ private:
} }
void visit(AstUCStmt* nodep) override { void visit(AstUCStmt* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
ensureCleanAndNext(nodep->bodysp()); ensureCleanAndNext(nodep->exprsp());
} }
void visit(AstNodeCCall* nodep) override { void visit(AstNodeCCall* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);

View File

@ -102,10 +102,10 @@ private:
AstVar* const newvarp = new AstVar(vscp->fileline(), VVarType::MODULETEMP, newvarname, AstVar* const newvarp = new AstVar(vscp->fileline(), VVarType::MODULETEMP, newvarname,
VFlagLogicPacked{}, 1); VFlagLogicPacked{}, 1);
newvarp->noReset(true); // Reset by below assign newvarp->noReset(true); // Reset by below assign
m_modp->addStmtp(newvarp); m_modp->addStmtsp(newvarp);
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp); AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
vscp->user1p(newvscp); vscp->user1p(newvscp);
m_scopep->addVarp(newvscp); m_scopep->addVarsp(newvscp);
// Add init // Add init
AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, VAccess::READ); AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, VAccess::READ);
if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp); if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp);
@ -202,7 +202,7 @@ private:
funcp->slow(slow); funcp->slow(slow);
funcp->isConst(false); funcp->isConst(false);
funcp->declPrivate(true); funcp->declPrivate(true);
m_topScopep->scopep()->addActivep(funcp); m_topScopep->scopep()->addBlocksp(funcp);
return funcp; return funcp;
} }
void splitCheck(AstCFunc* ofuncp) { void splitCheck(AstCFunc* ofuncp) {
@ -229,7 +229,7 @@ private:
funcp->isStatic(false); funcp->isStatic(false);
funcp->isLoose(true); funcp->isLoose(true);
funcp->slow(ofuncp->slow()); funcp->slow(ofuncp->slow());
m_topScopep->scopep()->addActivep(funcp); m_topScopep->scopep()->addBlocksp(funcp);
// //
AstCCall* const callp = new AstCCall{funcp->fileline(), funcp}; AstCCall* const callp = new AstCCall{funcp->fileline(), funcp};
ofuncp->addStmtsp(callp); ofuncp->addStmtsp(callp);
@ -297,7 +297,7 @@ private:
m_scopep = nullptr; m_scopep = nullptr;
} }
void visit(AstNodeProcedure* nodep) override { void visit(AstNodeProcedure* nodep) override {
if (AstNode* const stmtsp = nodep->bodysp()) { if (AstNode* const stmtsp = nodep->stmtsp()) {
stmtsp->unlinkFrBackWithNext(); stmtsp->unlinkFrBackWithNext();
nodep->addNextHere(stmtsp); nodep->addNextHere(stmtsp);
} }
@ -316,7 +316,7 @@ private:
// We could add another IF to detect posedges, and only increment if so. // We could add another IF to detect posedges, and only increment if so.
// It's another whole branch though versus a potential memory miss. // It's another whole branch though versus a potential memory miss.
// We'll go with the miss. // We'll go with the miss.
newp->addIfsp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false))); newp->addThensp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false)));
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} }
@ -367,7 +367,7 @@ private:
m_mtaskBodyp->addStmtsp(m_lastIfp); m_mtaskBodyp->addStmtsp(m_lastIfp);
} }
// Move statements to if // Move statements to if
m_lastIfp->addIfsp(stmtsp); m_lastIfp->addThensp(stmtsp);
} else if (nodep->hasInitial() || nodep->hasSettle()) { } else if (nodep->hasInitial() || nodep->hasSettle()) {
nodep->v3fatalSrc("MTask should not include initial/settle logic."); nodep->v3fatalSrc("MTask should not include initial/settle logic.");
} else { } else {
@ -393,7 +393,7 @@ private:
addToEvalLoop(m_lastIfp); addToEvalLoop(m_lastIfp);
} }
// Move statements to if // Move statements to if
m_lastIfp->addIfsp(stmtsp); m_lastIfp->addThensp(stmtsp);
} else if (nodep->hasInitial()) { } else if (nodep->hasInitial()) {
// Don't need to: clearLastSen();, as we're adding it to different cfunc // Don't need to: clearLastSen();, as we're adding it to different cfunc
// Move statements to function // Move statements to function

View File

@ -43,7 +43,7 @@ static void makeVlToString(AstClass* nodep) {
AstNode* const exprp = new AstCMath{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0}; AstNode* const exprp = new AstCMath{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0};
exprp->dtypeSetString(); exprp->dtypeSetString();
funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp});
nodep->addStmtp(funcp); nodep->addStmtsp(funcp);
} }
static void makeToString(AstClass* nodep) { static void makeToString(AstClass* nodep) {
AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "to_string", nullptr, "std::string"}; AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "to_string", nullptr, "std::string"};
@ -54,7 +54,7 @@ static void makeToString(AstClass* nodep) {
= new AstCMath{nodep->fileline(), R"(std::string{"'{"} + to_string_middle() + "}")", 0}; = new AstCMath{nodep->fileline(), R"(std::string{"'{"} + to_string_middle() + "}")", 0};
exprp->dtypeSetString(); exprp->dtypeSetString();
funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp}); funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp});
nodep->addStmtp(funcp); nodep->addStmtsp(funcp);
} }
static void makeToStringMiddle(AstClass* nodep) { static void makeToStringMiddle(AstClass* nodep) {
AstCFunc* const funcp AstCFunc* const funcp
@ -96,7 +96,7 @@ static void makeToStringMiddle(AstClass* nodep) {
funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt}); funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt});
} }
funcp->addStmtsp(new AstCStmt{nodep->fileline(), "return out;\n"}); funcp->addStmtsp(new AstCStmt{nodep->fileline(), "return out;\n"});
nodep->addStmtp(funcp); nodep->addStmtsp(funcp);
} }
//###################################################################### //######################################################################

View File

@ -193,11 +193,11 @@ public:
const VPragmaType type const VPragmaType type
= m_inlineValue ? VPragmaType::INLINE_MODULE : VPragmaType::NO_INLINE_MODULE; = m_inlineValue ? VPragmaType::INLINE_MODULE : VPragmaType::NO_INLINE_MODULE;
AstNode* const nodep = new AstPragma(modp->fileline(), type); AstNode* const nodep = new AstPragma(modp->fileline(), type);
modp->addStmtp(nodep); modp->addStmtsp(nodep);
} }
for (const auto& itr : m_modPragmas) { for (const auto& itr : m_modPragmas) {
AstNode* const nodep = new AstPragma{modp->fileline(), itr}; AstNode* const nodep = new AstPragma{modp->fileline(), itr};
modp->addStmtp(nodep); modp->addStmtsp(nodep);
} }
} }

View File

@ -1042,20 +1042,19 @@ private:
// as high as possible, which is usally the right choice, except for this. // as high as possible, which is usally the right choice, except for this.
AstNodeCond* const condp = VN_CAST(nodep->rhsp(), NodeCond); AstNodeCond* const condp = VN_CAST(nodep->rhsp(), NodeCond);
if (!condp) return false; if (!condp) return false;
if (!VN_IS(condp->expr1p(), Const) && !VN_IS(condp->expr2p(), Const)) return false; if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false;
AstConst* const maskp = VN_CAST(nodep->lhsp(), Const); AstConst* const maskp = VN_CAST(nodep->lhsp(), Const);
if (!maskp) return false; if (!maskp) return false;
UINFO(4, "AND(CONSTm, CONDcond(c, i, e))->CONDcond(c, AND(m,i), AND(m, e)) " << nodep UINFO(4, "AND(CONSTm, CONDcond(c, i, e))->CONDcond(c, AND(m,i), AND(m, e)) " << nodep
<< endl); << endl);
AstNodeCond* const newp = static_cast<AstNodeCond*>( AstNodeCond* const newp = static_cast<AstNodeCond*>(condp->cloneType(
condp->cloneType(condp->condp()->unlinkFrBack(), condp->condp()->unlinkFrBack(),
new AstAnd(nodep->fileline(), maskp->cloneTree(false), condp->thenp()->unlinkFrBack()),
new AstAnd(nodep->fileline(), maskp->cloneTree(false), new AstAnd(nodep->fileline(), maskp->cloneTree(false),
condp->expr1p()->unlinkFrBack()), condp->elsep()->unlinkFrBack())));
new AstAnd(nodep->fileline(), maskp->cloneTree(false),
condp->expr2p()->unlinkFrBack())));
newp->dtypeFrom(nodep); newp->dtypeFrom(nodep);
newp->expr1p()->dtypeFrom(nodep); // As And might have been to change widths newp->thenp()->dtypeFrom(nodep); // As And might have been to change widths
newp->expr2p()->dtypeFrom(nodep); newp->elsep()->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
return true; return true;
@ -1443,19 +1442,19 @@ private:
} }
} }
bool ifSameAssign(const AstNodeIf* nodep) { bool ifSameAssign(const AstNodeIf* nodep) {
const AstNodeAssign* const ifp = VN_CAST(nodep->ifsp(), NodeAssign); const AstNodeAssign* const thensp = VN_CAST(nodep->thensp(), NodeAssign);
const AstNodeAssign* const elsep = VN_CAST(nodep->elsesp(), NodeAssign); const AstNodeAssign* const elsesp = VN_CAST(nodep->elsesp(), NodeAssign);
if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement if (!thensp || thensp->nextp()) return false; // Must be SINGLE statement
if (!elsep || elsep->nextp()) return false; if (!elsesp || elsesp->nextp()) return false;
if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign if (thensp->type() != elsesp->type()) return false; // Can't mix an assigndly with assign
if (!ifp->lhsp()->sameGateTree(elsep->lhsp())) return false; if (!thensp->lhsp()->sameGateTree(elsesp->lhsp())) return false;
if (!ifp->rhsp()->gateTree()) return false; if (!thensp->rhsp()->gateTree()) return false;
if (!elsep->rhsp()->gateTree()) return false; if (!elsesp->rhsp()->gateTree()) return false;
return true; return true;
} }
bool operandIfIf(const AstNodeIf* nodep) { bool operandIfIf(const AstNodeIf* nodep) {
if (nodep->elsesp()) return false; if (nodep->elsesp()) return false;
const AstNodeIf* const lowerIfp = VN_CAST(nodep->ifsp(), NodeIf); const AstNodeIf* const lowerIfp = VN_CAST(nodep->thensp(), NodeIf);
if (!lowerIfp || lowerIfp->nextp()) return false; if (!lowerIfp || lowerIfp->nextp()) return false;
if (nodep->type() != lowerIfp->type()) return false; if (nodep->type() != lowerIfp->type()) return false;
if (afterComment(lowerIfp->elsesp())) return false; if (afterComment(lowerIfp->elsesp())) return false;
@ -2097,8 +2096,8 @@ private:
AstVar* const temp2p AstVar* const temp2p
= new AstVar(sel2p->fileline(), VVarType::BLOCKTEMP, = new AstVar(sel2p->fileline(), VVarType::BLOCKTEMP,
m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1); m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1);
m_modp->addStmtp(temp1p); m_modp->addStmtsp(temp1p);
m_modp->addStmtp(temp2p); m_modp->addStmtsp(temp2p);
AstNodeAssign* const asn1ap AstNodeAssign* const asn1ap
= VN_AS(nodep->cloneType( = VN_AS(nodep->cloneType(
new AstVarRef(sel1p->fileline(), temp1p, VAccess::WRITE), sel1p), new AstVarRef(sel1p->fileline(), temp1p, VAccess::WRITE), sel1p),
@ -2862,7 +2861,7 @@ private:
varrefp->unlinkFrBack(); varrefp->unlinkFrBack();
AstInitial* const newinitp = new AstInitial( AstInitial* const newinitp = new AstInitial(
nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp)); nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp));
m_modp->addStmtp(newinitp); m_modp->addStmtsp(newinitp);
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
// Set the initial value right in the variable so we can constant propagate // Set the initial value right in the variable so we can constant propagate
AstNode* const initvaluep = exprp->cloneTree(false); AstNode* const initvaluep = exprp->cloneTree(false);
@ -2892,7 +2891,7 @@ private:
keepp = nodep->elsesp(); keepp = nodep->elsesp();
} else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog } else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog
UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl); UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl);
keepp = nodep->ifsp(); keepp = nodep->thensp();
} else { } else {
UINFO(4, "IF condition is X, retaining: " << nodep << endl); UINFO(4, "IF condition is X, retaining: " << nodep << endl);
return; return;
@ -2904,7 +2903,7 @@ private:
nodep->unlinkFrBack(); nodep->unlinkFrBack();
} }
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) { } else if (!afterComment(nodep->thensp()) && !afterComment(nodep->elsesp())) {
if (!isTreePureRecurse(nodep->condp())) { if (!isTreePureRecurse(nodep->condp())) {
// Condition has side effect - leave - perhaps in // Condition has side effect - leave - perhaps in
// future simplify to remove all but side effect terms // future simplify to remove all but side effect terms
@ -2912,27 +2911,27 @@ private:
// Empty block, remove it // Empty block, remove it
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} }
} else if (!afterComment(nodep->ifsp())) { } else if (!afterComment(nodep->thensp())) {
UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl); UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl);
AstNode* const condp = nodep->condp(); AstNode* const condp = nodep->condp();
AstNode* const elsesp = nodep->elsesp(); AstNode* const elsesp = nodep->elsesp();
condp->unlinkFrBackWithNext(); condp->unlinkFrBackWithNext();
elsesp->unlinkFrBackWithNext(); elsesp->unlinkFrBackWithNext();
if (nodep->ifsp()) { // Must have been comment if (nodep->thensp()) { // Must have been comment
nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); nodep->thensp()->unlinkFrBackWithNext()->deleteTree();
} }
nodep->condp(new AstLogNot(condp->fileline(), nodep->condp(new AstLogNot(condp->fileline(),
condp)); // LogNot, as C++ optimization also possible condp)); // LogNot, as C++ optimization also possible
nodep->addIfsp(elsesp); nodep->addThensp(elsesp);
} else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1) } else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|| VN_IS(nodep->condp(), LogNot)) || VN_IS(nodep->condp(), LogNot))
&& nodep->ifsp() && nodep->elsesp()) { && nodep->thensp() && nodep->elsesp()) {
UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl); UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl);
AstNode* const condp AstNode* const condp
= VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext(); = VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext();
AstNode* const ifsp = nodep->ifsp()->unlinkFrBackWithNext(); AstNode* const thensp = nodep->thensp()->unlinkFrBackWithNext();
AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext(); AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext();
AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp); AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, thensp);
ifp->branchPred(nodep->branchPred().invert()); ifp->branchPred(nodep->branchPred().invert());
nodep->replaceWith(ifp); nodep->replaceWith(ifp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
@ -2940,25 +2939,25 @@ private:
UINFO( UINFO(
4, 4,
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})\n"); "IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})\n");
AstNodeAssign* const ifp = VN_AS(nodep->ifsp(), NodeAssign); AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
AstNodeAssign* const elsep = VN_AS(nodep->elsesp(), NodeAssign); AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign);
ifp->unlinkFrBack(); thensp->unlinkFrBack();
AstNode* const condp = nodep->condp()->unlinkFrBack(); AstNode* const condp = nodep->condp()->unlinkFrBack();
AstNode* const truep = ifp->rhsp()->unlinkFrBack(); AstNode* const truep = thensp->rhsp()->unlinkFrBack();
AstNode* const falsep = elsep->rhsp()->unlinkFrBack(); AstNode* const falsep = elsesp->rhsp()->unlinkFrBack();
ifp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); thensp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep));
nodep->replaceWith(ifp); nodep->replaceWith(thensp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} else if (false // Disabled, as vpm assertions are faster } else if (false // Disabled, as vpm assertions are faster
// without due to short-circuiting // without due to short-circuiting
&& operandIfIf(nodep)) { && operandIfIf(nodep)) {
UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl); UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl);
AstNodeIf* const lowerIfp = VN_AS(nodep->ifsp(), NodeIf); AstNodeIf* const lowerIfp = VN_AS(nodep->thensp(), NodeIf);
AstNode* const condp = nodep->condp()->unlinkFrBack(); AstNode* const condp = nodep->condp()->unlinkFrBack();
AstNode* const lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext(); AstNode* const lowerThensp = lowerIfp->thensp()->unlinkFrBackWithNext();
AstNode* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext(); AstNode* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp)); nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp));
lowerIfp->replaceWith(lowerIfsp); lowerIfp->replaceWith(lowerThensp);
VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp); VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp);
} else if (operandBoolShift(nodep->condp())) { } else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp()); replaceBoolShift(nodep->condp());
@ -3015,8 +3014,10 @@ private:
pformatp->text(pformatp->text() + nformatp->text()); pformatp->text(pformatp->text() + nformatp->text());
if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n"); if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n");
if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext()); if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext());
if (nformatp->scopeNamep()) if (AstScopeName* const scopeNamep = nformatp->scopeNamep()) {
pformatp->scopeNamep(nformatp->scopeNamep()->unlinkFrBackWithNext()); scopeNamep->unlinkFrBackWithNext();
pformatp->scopeNamep(scopeNamep);
}
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return true; return true;
} }
@ -3300,19 +3301,19 @@ private:
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b) TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
// Trinary ops // Trinary ops
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump! // Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)"); TREEOP ("AstNodeCond{$condp.isZero, $thenp, $elsep}", "replaceWChild(nodep,$elsep)");
TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)"); TREEOP ("AstNodeCond{$condp.isNeqZero, $thenp, $elsep}", "replaceWChild(nodep,$thenp)");
TREEOPA("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)"); TREEOPA("AstNodeCond{$condp.isZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$elsep)");
TREEOPA("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)"); TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)");
TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)"); TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)");
// This visit function here must allow for short-circuiting. // This visit function here must allow for short-circuiting.
TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)"); TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)");
TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)"); TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)");
TREEOP ("AstCond{$condp.castNot, $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}"); TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->op1p(), $elsep, $thenp}");
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}"); // a?1:b == a||b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes}", "AstLogOr {AstNot{$condp}, $thenp}"); // a?b:1 == ~a||b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isZero, $elsep}", "AstLogAnd{AstNot{$condp}, $elsep}"); // a?0:b == ~a&&b
TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())"); TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
// Prefer constants on left, since that often needs a shift, it lets // Prefer constants on left, since that often needs a shift, it lets
// constant red remove the shift // constant red remove the shift

View File

@ -119,7 +119,7 @@ private:
AstCoverDecl* const declp = new AstCoverDecl(fl, page, comment, linescov, offset); AstCoverDecl* const declp = new AstCoverDecl(fl, page, comment, linescov, offset);
declp->hier(hier); declp->hier(hier);
m_modp->addStmtp(declp); m_modp->addStmtsp(declp);
UINFO(9, "new " << declp << endl); UINFO(9, "new " << declp << endl);
AstCoverInc* const incp = new AstCoverInc(fl, declp); AstCoverInc* const incp = new AstCoverInc(fl, declp);
@ -128,7 +128,7 @@ private:
incp->findUInt32DType()); incp->findUInt32DType());
varp->trace(true); varp->trace(true);
varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
m_modp->addStmtp(varp); m_modp->addStmtsp(varp);
UINFO(5, "New coverage trace: " << varp << endl); UINFO(5, "New coverage trace: " << varp << endl);
AstAssign* const assp = new AstAssign( AstAssign* const assp = new AstAssign(
incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::WRITE), incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::WRITE),
@ -245,11 +245,11 @@ private:
= newCoverInc(nodep->fileline(), "", "v_line", "block", = newCoverInc(nodep->fileline(), "", "v_line", "block",
linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block")); linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block"));
if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) { if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) {
itemp->addStmtp(newp); itemp->addStmtsp(newp);
} else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) { } else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) {
itemp->addStmtsp(newp); itemp->addStmtsp(newp);
} else if (AstWhile* const itemp = VN_CAST(nodep, While)) { } else if (AstWhile* const itemp = VN_CAST(nodep, While)) {
itemp->addBodysp(newp); itemp->addStmtsp(newp);
} else { } else {
nodep->v3fatalSrc("Bad node type"); nodep->v3fatalSrc("Bad node type");
} }
@ -283,7 +283,7 @@ private:
AstVar* const chgVarp AstVar* const chgVarp
= new AstVar(nodep->fileline(), VVarType::MODULETEMP, newvarname, nodep); = new AstVar(nodep->fileline(), VVarType::MODULETEMP, newvarname, nodep);
chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
m_modp->addStmtp(chgVarp); m_modp->addStmtsp(chgVarp);
// Create bucket for each dimension * bit. // Create bucket for each dimension * bit.
// This is necessarily an O(n^2) expansion, which is why // This is necessarily an O(n^2) expansion, which is why
@ -304,7 +304,7 @@ private:
newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0, newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0,
""), ""),
above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true));
m_modp->addStmtp(newp); m_modp->addStmtsp(newp);
} }
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
@ -388,7 +388,7 @@ private:
if (m_state.m_on) { if (m_state.m_on) {
// An else-if. When we iterate the if, use "elsif" marking // An else-if. When we iterate the if, use "elsif" marking
const bool elsif const bool elsif
= nodep->ifsp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp(); = nodep->thensp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp();
if (elsif) VN_AS(nodep->elsesp(), If)->user1(true); if (elsif) VN_AS(nodep->elsesp(), If)->user1(true);
const bool first_elsif = !nodep->user1() && elsif; const bool first_elsif = !nodep->user1() && elsif;
const bool cont_elsif = nodep->user1() && elsif; const bool cont_elsif = nodep->user1() && elsif;
@ -403,7 +403,7 @@ private:
CheckState elseState; CheckState elseState;
{ {
createHandle(nodep); createHandle(nodep);
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
lineTrack(nodep); lineTrack(nodep);
ifState = m_state; ifState = m_state;
} }
@ -422,7 +422,7 @@ private:
// Normal if. Linecov shows what's inside the if (not condition that is // Normal if. Linecov shows what's inside the if (not condition that is
// always executed) // always executed)
UINFO(4, " COVER-branch: " << nodep << endl); UINFO(4, " COVER-branch: " << nodep << endl);
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_branch", "if", nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_branch", "if",
linesCov(ifState, nodep), 0, linesCov(ifState, nodep), 0,
traceNameForLine(nodep, "if"))); traceNameForLine(nodep, "if")));
// The else has a column offset of 1 to uniquify it relative to the if // The else has a column offset of 1 to uniquify it relative to the if
@ -436,7 +436,7 @@ private:
else if (first_elsif || cont_elsif) { else if (first_elsif || cont_elsif) {
UINFO(4, " COVER-elsif: " << nodep << endl); UINFO(4, " COVER-elsif: " << nodep << endl);
if (ifState.lineCoverageOn(nodep)) { if (ifState.lineCoverageOn(nodep)) {
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif", nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "elsif",
linesCov(ifState, nodep), 0, linesCov(ifState, nodep), 0,
traceNameForLine(nodep, "elsif"))); traceNameForLine(nodep, "elsif")));
} }
@ -445,7 +445,7 @@ private:
// Cover as separate blocks (not a branch as is not two-legged) // Cover as separate blocks (not a branch as is not two-legged)
if (ifState.lineCoverageOn(nodep)) { if (ifState.lineCoverageOn(nodep)) {
UINFO(4, " COVER-half-if: " << nodep << endl); UINFO(4, " COVER-half-if: " << nodep << endl);
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if", nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "if",
linesCov(ifState, nodep), 0, linesCov(ifState, nodep), 0,
traceNameForLine(nodep, "if"))); traceNameForLine(nodep, "if")));
} }
@ -468,11 +468,11 @@ private:
VL_RESTORER(m_state); VL_RESTORER(m_state);
{ {
createHandle(nodep); createHandle(nodep);
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it
lineTrack(nodep); lineTrack(nodep);
UINFO(4, " COVER: " << nodep << endl); UINFO(4, " COVER: " << nodep << endl);
nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", nodep->addStmtsp(newCoverInc(nodep->fileline(), "", "v_line", "case",
linesCov(m_state, nodep), 0, linesCov(m_state, nodep), 0,
traceNameForLine(nodep, "case"))); traceNameForLine(nodep, "case")));
} }
@ -486,10 +486,10 @@ private:
m_state.m_on = true; // Always do cover blocks, even if there's a $stop m_state.m_on = true; // Always do cover blocks, even if there's a $stop
createHandle(nodep); createHandle(nodep);
iterateChildren(nodep); iterateChildren(nodep);
if (!nodep->coverincp() && v3Global.opt.coverageUser()) { if (!nodep->coverincsp() && v3Global.opt.coverageUser()) {
// Note the name may be overridden by V3Assert processing // Note the name may be overridden by V3Assert processing
lineTrack(nodep); lineTrack(nodep);
nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", nodep->addCoverincsp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover",
linesCov(m_state, nodep), 0, linesCov(m_state, nodep), 0,
m_beginHier + "_vlCoverageUserTrace")); m_beginHier + "_vlCoverageUserTrace"));
} }

View File

@ -153,13 +153,13 @@ private:
varp = new AstVar(oldvarscp->fileline(), VVarType::BLOCKTEMP, name, varp = new AstVar(oldvarscp->fileline(), VVarType::BLOCKTEMP, name,
VFlagBitPacked(), width); VFlagBitPacked(), width);
} }
addmodp->addStmtp(varp); addmodp->addStmtsp(varp);
m_modVarMap.emplace(std::make_pair(addmodp, name), varp); m_modVarMap.emplace(std::make_pair(addmodp, name), varp);
} }
AstVarScope* const varscp AstVarScope* const varscp
= new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp); = new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp);
oldvarscp->scopep()->addVarp(varscp); oldvarscp->scopep()->addVarsp(varscp);
return varscp; return varscp;
} }
@ -356,11 +356,11 @@ private:
postLogicp = new AstIf(nodep->fileline(), postLogicp = new AstIf(nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, VAccess::READ)); new AstVarRef(nodep->fileline(), setvscp, VAccess::READ));
UINFO(9, " Created " << postLogicp << endl); UINFO(9, " Created " << postLogicp << endl);
finalp->addStmtp(postLogicp); finalp->addStmtsp(postLogicp);
finalp->user3p(setvscp); // Remember IF's vset variable finalp->user3p(setvscp); // Remember IF's vset variable
finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it
} }
postLogicp->addIfsp(new AstAssign(nodep->fileline(), selectsp, valreadp)); postLogicp->addThensp(new AstAssign(nodep->fileline(), selectsp, valreadp));
return newlhsp; return newlhsp;
} }

View File

@ -57,7 +57,7 @@ private:
funcp->isStatic(m_cfuncp->isStatic()); funcp->isStatic(m_cfuncp->isStatic());
funcp->isLoose(m_cfuncp->isLoose()); funcp->isLoose(m_cfuncp->isLoose());
funcp->addStmtsp(nodep); funcp->addStmtsp(nodep);
scopep->addActivep(funcp); scopep->addBlocksp(funcp);
// Call sub function at the point where the body was removed from // Call sub function at the point where the body was removed from
AstCCall* const callp = new AstCCall(nodep->fileline(), funcp); AstCCall* const callp = new AstCCall(nodep->fileline(), funcp);
if (VN_IS(m_modp, Class)) { if (VN_IS(m_modp, Class)) {

View File

@ -257,7 +257,7 @@ private:
// If it's under a scope, move it up to the top // If it's under a scope, move it up to the top
if (m_scopep) { if (m_scopep) {
nodep->unlinkFrBack(); nodep->unlinkFrBack();
m_modp->addStmtp(nodep); m_modp->addStmtsp(nodep);
if (nodep->funcPublic()) { if (nodep->funcPublic()) {
// There may be multiple public functions by the same name; // There may be multiple public functions by the same name;

View File

@ -828,7 +828,7 @@ public:
puts("while ("); puts("while (");
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
puts(") {\n"); puts(") {\n");
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop
puts("}\n"); puts("}\n");
@ -842,7 +842,7 @@ public:
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
if (!nodep->branchPred().unknown()) puts(")"); if (!nodep->branchPred().unknown()) puts(")");
puts(") {\n"); puts(") {\n");
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
puts("}"); puts("}");
if (!nodep->elsesp()) { if (!nodep->elsesp()) {
puts("\n"); puts("\n");
@ -935,17 +935,17 @@ public:
} }
void visit(AstCStmt* nodep) override { void visit(AstCStmt* nodep) override {
putbs(""); putbs("");
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->exprsp());
} }
void visit(AstCMath* nodep) override { void visit(AstCMath* nodep) override {
putbs(""); putbs("");
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->exprsp());
} }
void visit(AstUCStmt* nodep) override { void visit(AstUCStmt* nodep) override {
VL_RESTORER(m_inUC); VL_RESTORER(m_inUC);
m_inUC = true; m_inUC = true;
putsDecoration(ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n")); putsDecoration(ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n"));
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->exprsp());
puts("\n"); puts("\n");
} }
void visit(AstUCFunc* nodep) override { void visit(AstUCFunc* nodep) override {
@ -953,7 +953,7 @@ public:
m_inUC = true; m_inUC = true;
puts("\n"); puts("\n");
putsDecoration(ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n")); putsDecoration(ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n"));
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->exprsp());
puts("\n"); puts("\n");
} }
@ -1033,15 +1033,15 @@ public:
} }
void visit(AstNodeCond* nodep) override { void visit(AstNodeCond* nodep) override {
// Widths match up already, so we'll just use C++'s operator w/o any temps. // Widths match up already, so we'll just use C++'s operator w/o any temps.
if (nodep->expr1p()->isWide()) { if (nodep->thenp()->isWide()) {
emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p()); emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->thenp(), nodep->elsep());
} else { } else {
putbs("("); putbs("(");
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
putbs(" ? "); putbs(" ? ");
iterateAndNextNull(nodep->expr1p()); iterateAndNextNull(nodep->thenp());
putbs(" : "); putbs(" : ");
iterateAndNextNull(nodep->expr2p()); iterateAndNextNull(nodep->elsep());
puts(")"); puts(")");
} }
} }

View File

@ -110,7 +110,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
iterateAndNextConstNull(nodep->sensesp()); iterateAndNextConstNull(nodep->sensesp());
} }
putbs(" begin\n"); putbs(" begin\n");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
putqs(nodep, "end\n"); putqs(nodep, "end\n");
} }
void visit(AstAlwaysPublic* nodep) override { void visit(AstAlwaysPublic* nodep) override {
@ -122,7 +122,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
iterateAndNextConstNull(nodep->sensesp()); iterateAndNextConstNull(nodep->sensesp());
} }
putqs(nodep, " "); putqs(nodep, " ");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
putqs(nodep, "*/\n"); putqs(nodep, "*/\n");
} }
void visit(AstNodeAssign* nodep) override { void visit(AstNodeAssign* nodep) override {
@ -204,7 +204,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
putbs("default"); putbs("default");
} }
putfs(nodep, ": begin "); putfs(nodep, ": begin ");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
putqs(nodep, "end\n"); putqs(nodep, "end\n");
} }
void visit(AstComment* nodep) override { void visit(AstComment* nodep) override {
@ -326,14 +326,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
iterateAndNextConstNull(nodep->incsp()); iterateAndNextConstNull(nodep->incsp());
} }
puts(") begin\n"); puts(") begin\n");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
putqs(nodep, "end\n"); putqs(nodep, "end\n");
} }
void visit(AstRepeat* nodep) override { void visit(AstRepeat* nodep) override {
putfs(nodep, "repeat ("); putfs(nodep, "repeat (");
iterateAndNextConstNull(nodep->countp()); iterateAndNextConstNull(nodep->countp());
puts(") begin\n"); puts(") begin\n");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
putfs(nodep, "end\n"); putfs(nodep, "end\n");
} }
void visit(AstWhile* nodep) override { void visit(AstWhile* nodep) override {
@ -341,7 +341,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
putfs(nodep, "while ("); putfs(nodep, "while (");
iterateAndNextConstNull(nodep->condp()); iterateAndNextConstNull(nodep->condp());
puts(") begin\n"); puts(") begin\n");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->stmtsp());
iterateAndNextConstNull(nodep->incsp()); iterateAndNextConstNull(nodep->incsp());
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
putfs(nodep, "end\n"); putfs(nodep, "end\n");
@ -356,7 +356,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
puts("if ("); puts("if (");
iterateAndNextConstNull(nodep->condp()); iterateAndNextConstNull(nodep->condp());
puts(") begin\n"); puts(") begin\n");
iterateAndNextConstNull(nodep->ifsp()); iterateAndNextConstNull(nodep->thensp());
if (nodep->elsesp()) { if (nodep->elsesp()) {
putqs(nodep, "end\n"); putqs(nodep, "end\n");
putqs(nodep, "else begin\n"); putqs(nodep, "else begin\n");
@ -401,22 +401,22 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
void visit(AstScopeName* nodep) override {} void visit(AstScopeName* nodep) override {}
void visit(AstCStmt* nodep) override { void visit(AstCStmt* nodep) override {
putfs(nodep, "$_CSTMT("); putfs(nodep, "$_CSTMT(");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->exprsp());
puts(");\n"); puts(");\n");
} }
void visit(AstCMath* nodep) override { void visit(AstCMath* nodep) override {
putfs(nodep, "$_CMATH("); putfs(nodep, "$_CMATH(");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->exprsp());
puts(");\n"); puts(");\n");
} }
void visit(AstUCStmt* nodep) override { void visit(AstUCStmt* nodep) override {
putfs(nodep, "$c("); putfs(nodep, "$c(");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->exprsp());
puts(");\n"); puts(");\n");
} }
void visit(AstUCFunc* nodep) override { void visit(AstUCFunc* nodep) override {
putfs(nodep, "$c("); putfs(nodep, "$c(");
iterateAndNextConstNull(nodep->bodysp()); iterateAndNextConstNull(nodep->exprsp());
puts(")"); puts(")");
} }
@ -521,9 +521,9 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
putbs("("); putbs("(");
iterateAndNextConstNull(nodep->condp()); iterateAndNextConstNull(nodep->condp());
putfs(nodep, " ? "); putfs(nodep, " ? ");
iterateAndNextConstNull(nodep->expr1p()); iterateAndNextConstNull(nodep->thenp());
putbs(" : "); putbs(" : ");
iterateAndNextConstNull(nodep->expr2p()); iterateAndNextConstNull(nodep->elsep());
puts(")"); puts(")");
} }
void visit(AstRange* nodep) override { void visit(AstRange* nodep) override {

View File

@ -306,8 +306,8 @@ private:
for (int w = 0; w < nodep->widthWords(); ++w) { for (int w = 0; w < nodep->widthWords(); ++w) {
addWordAssign(nodep, w, addWordAssign(nodep, w,
new AstCond{fl, rhsp->condp()->cloneTree(true), new AstCond{fl, rhsp->condp()->cloneTree(true),
newAstWordSelClone(rhsp->expr1p(), w), newAstWordSelClone(rhsp->thenp(), w),
newAstWordSelClone(rhsp->expr2p(), w)}); newAstWordSelClone(rhsp->elsep(), w)});
} }
return true; return true;
} }

View File

@ -109,7 +109,7 @@ class ForceConvertVisitor final : public VNVisitor {
new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Initial{}}}}; new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Initial{}}}};
activep->sensesStorep(activep->sensesp()); activep->sensesStorep(activep->sensesp());
activep->addStmtsp(new AstInitial{flp, assignp}); activep->addStmtsp(new AstInitial{flp, assignp});
vscp->scopep()->addActivep(activep); vscp->scopep()->addBlocksp(activep);
} }
{ // Add the combinational override { // Add the combinational override
@ -127,7 +127,7 @@ class ForceConvertVisitor final : public VNVisitor {
new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Combo{}}}}; new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Combo{}}}};
activep->sensesStorep(activep->sensesp()); activep->sensesStorep(activep->sensesp());
activep->addStmtsp(new AstAssignW{flp, lhsp, rhsp}); activep->addStmtsp(new AstAssignW{flp, lhsp, rhsp});
vscp->scopep()->addActivep(activep); vscp->scopep()->addBlocksp(activep);
} }
} }
}; };

View File

@ -921,7 +921,7 @@ private:
if (m_dedupable) { if (m_dedupable) {
if (!m_always) { if (!m_always) {
m_always = true; m_always = true;
iterateAndNextNull(alwaysp->bodysp()); iterateAndNextNull(alwaysp->stmtsp());
} else { } else {
m_dedupable = false; m_dedupable = false;
} }
@ -936,7 +936,7 @@ private:
if (m_always && !m_ifCondp && !ifp->elsesp()) { if (m_always && !m_ifCondp && !ifp->elsesp()) {
// we're under an always, this is the first IF, and there's no else // we're under an always, this is the first IF, and there's no else
m_ifCondp = ifp->condp(); m_ifCondp = ifp->condp();
iterateAndNextNull(ifp->ifsp()); iterateAndNextNull(ifp->thensp());
} else { } else {
m_dedupable = false; m_dedupable = false;
} }

View File

@ -76,13 +76,13 @@ private:
// ASSIGN(VARREF(inpclk), VARREF(var)) // ASSIGN(VARREF(inpclk), VARREF(var))
AstVar* const newvarp AstVar* const newvarp
= new AstVar(varp->fileline(), VVarType::MODULETEMP, newvarname, varp); = new AstVar(varp->fileline(), VVarType::MODULETEMP, newvarname, varp);
m_topModp->addStmtp(newvarp); m_topModp->addStmtsp(newvarp);
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp); AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
m_scopetopp->addVarp(newvscp); m_scopetopp->addVarsp(newvscp);
AstAssign* const asninitp = new AstAssign( AstAssign* const asninitp = new AstAssign(
vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE), vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
new AstVarRef(vscp->fileline(), vscp, VAccess::READ)); new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
m_scopetopp->addFinalClkp(asninitp); m_scopetopp->addFinalClksp(asninitp);
// //
vscp->user2p(newvscp); vscp->user2p(newvscp);
} }

View File

@ -294,7 +294,7 @@ private:
UASSERT_OBJ(exprconstp || exprvarrefp, nodep, UASSERT_OBJ(exprconstp || exprvarrefp, nodep,
"Unknown interconnect type; pinReconnectSimple should have cleared up"); "Unknown interconnect type; pinReconnectSimple should have cleared up");
if (exprconstp) { if (exprconstp) {
m_modp->addStmtp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE), m_modp->addStmtsp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
exprconstp->cloneTree(false))); exprconstp->cloneTree(false)));
} else if (nodep->user3()) { } else if (nodep->user3()) {
// Public variable at the lower module end - we need to make sure we propagate // Public variable at the lower module end - we need to make sure we propagate
@ -302,7 +302,7 @@ private:
// remove the change detection on the output variable. // remove the change detection on the output variable.
UINFO(9, "public pin assign: " << exprvarrefp << endl); UINFO(9, "public pin assign: " << exprvarrefp << endl);
UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias"); UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias");
m_modp->addStmtp( m_modp->addStmtsp(
new AstAssignW(flp, new AstVarRef(flp, exprvarrefp->varp(), VAccess::WRITE), new AstAssignW(flp, new AstVarRef(flp, exprvarrefp->varp(), VAccess::WRITE),
new AstVarRef(flp, nodep, VAccess::READ))); new AstVarRef(flp, nodep, VAccess::READ)));
} else if (nodep->isSigPublic() && VN_IS(nodep->dtypep(), UnpackArrayDType)) { } else if (nodep->isSigPublic() && VN_IS(nodep->dtypep(), UnpackArrayDType)) {
@ -310,11 +310,11 @@ private:
// instead of aliased, because otherwise it will pass V3Slice and invalid // instead of aliased, because otherwise it will pass V3Slice and invalid
// code will be emitted. // code will be emitted.
UINFO(9, "assign to public and unpacked: " << nodep << endl); UINFO(9, "assign to public and unpacked: " << nodep << endl);
m_modp->addStmtp( m_modp->addStmtsp(
new AstAssignW{flp, new AstVarRef{flp, nodep, VAccess::WRITE}, new AstAssignW{flp, new AstVarRef{flp, nodep, VAccess::WRITE},
new AstVarRef{flp, exprvarrefp->varp(), VAccess::READ}}); new AstVarRef{flp, exprvarrefp->varp(), VAccess::READ}});
} else if (nodep->isIfaceRef()) { } else if (nodep->isIfaceRef()) {
m_modp->addStmtp( m_modp->addStmtsp(
new AstAssignVarScope(flp, new AstVarRef(flp, nodep, VAccess::WRITE), new AstAssignVarScope(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ))); new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ)));
FileLine* const flbp = exprvarrefp->varp()->fileline(); FileLine* const flbp = exprvarrefp->varp()->fileline();
@ -323,7 +323,7 @@ private:
} else { } else {
// Do to inlining child's variable now within the same // Do to inlining child's variable now within the same
// module, so a AstVarRef not AstVarXRef below // module, so a AstVarRef not AstVarXRef below
m_modp->addStmtp( m_modp->addStmtsp(
new AstAssignAlias(flp, new AstVarRef(flp, nodep, VAccess::WRITE), new AstAssignAlias(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ))); new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ)));
FileLine* const flbp = exprvarrefp->varp()->fileline(); FileLine* const flbp = exprvarrefp->varp()->fileline();
@ -423,16 +423,16 @@ private:
// If there's a %m in the display text, we add a special node that will contain the name() // If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Begin // Similar code in V3Begin
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstText* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp( nodep->addScopeAttrp(
new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()}); new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()});
if (afterp) nodep->scopeAttrp(afterp); if (afterp) nodep->addScopeAttrp(afterp);
afterp = nodep->scopeEntrp(); afterp = nodep->scopeEntrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeEntrp( nodep->addScopeEntrp(
new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()}); new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()});
if (afterp) nodep->scopeEntrp(afterp); if (afterp) nodep->addScopeEntrp(afterp);
iterateChildren(nodep); iterateChildren(nodep);
} }
void visit(AstCoverDecl* nodep) override { void visit(AstCoverDecl* nodep) override {
@ -566,7 +566,7 @@ private:
// Move statements under the module we are inlining into // Move statements under the module we are inlining into
if (AstNode* const stmtsp = newmodp->stmtsp()) { if (AstNode* const stmtsp = newmodp->stmtsp()) {
stmtsp->unlinkFrBackWithNext(); stmtsp->unlinkFrBackWithNext();
m_modp->addStmtp(stmtsp); m_modp->addStmtsp(stmtsp);
} }
// Clear any leftover ports, etc // Clear any leftover ports, etc
VL_DO_DANGLING(newmodp->deleteTree(), newmodp); VL_DO_DANGLING(newmodp->deleteTree(), newmodp);
@ -649,7 +649,7 @@ private:
} }
if (VN_IS(nodep->modp(), Iface)) { if (VN_IS(nodep->modp(), Iface)) {
nodep->addIntfRefp(new AstIntfRef{nodep->fileline(), m_scope}); nodep->addIntfRefsp(new AstIntfRef{nodep->fileline(), m_scope});
} }
{ {
AstNodeModule* const modp = nodep->modp(); AstNodeModule* const modp = nodep->modp();
@ -666,7 +666,7 @@ private:
if ((cellp = VN_CAST(fromVarp->user1p(), Cell)) || (cellp = irdtp->cellp())) { if ((cellp = VN_CAST(fromVarp->user1p(), Cell)) || (cellp = irdtp->cellp())) {
varp->user1p(cellp); varp->user1p(cellp);
const string alias = m_scope + "__DOT__" + pinp->name(); const string alias = m_scope + "__DOT__" + pinp->name();
cellp->addIntfRefp(new AstIntfRef(pinp->fileline(), alias)); cellp->addIntfRefsp(new AstIntfRef(pinp->fileline(), alias));
} }
} }
@ -695,7 +695,7 @@ private:
string alias; string alias;
if (!m_scope.empty()) alias = m_scope + "__DOT__"; if (!m_scope.empty()) alias = m_scope + "__DOT__";
alias += varlp->name(); alias += varlp->name();
cellp->addIntfRefp(new AstIntfRef(varlp->fileline(), alias)); cellp->addIntfRefsp(new AstIntfRef(varlp->fileline(), alias));
} }
//-------------------- //--------------------
void visit(AstNodeMath*) override {} // Accelerate void visit(AstNodeMath*) override {} // Accelerate

View File

@ -170,7 +170,7 @@ private:
UINFO(8, "ifsp:\n"); UINFO(8, "ifsp:\n");
m_instrCount = 0; m_instrCount = 0;
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
uint32_t ifCount = m_instrCount; uint32_t ifCount = m_instrCount;
if (nodep->branchPred().unlikely()) ifCount = 0; if (nodep->branchPred().unlikely()) ifCount = 0;
@ -185,7 +185,7 @@ private:
if (nodep->elsesp()) nodep->elsesp()->user4(0); // Don't dump it if (nodep->elsesp()) nodep->elsesp()->user4(0); // Don't dump it
} else { } else {
m_instrCount = savedCount + elseCount; m_instrCount = savedCount + elseCount;
if (nodep->ifsp()) nodep->ifsp()->user4(0); // Don't dump it if (nodep->thensp()) nodep->thensp()->user4(0); // Don't dump it
} }
} }
void visit(AstNodeCond* nodep) override { void visit(AstNodeCond* nodep) override {
@ -197,20 +197,20 @@ private:
UINFO(8, "?\n"); UINFO(8, "?\n");
m_instrCount = 0; m_instrCount = 0;
iterateAndNextNull(nodep->expr1p()); iterateAndNextNull(nodep->thenp());
const uint32_t ifCount = m_instrCount; const uint32_t ifCount = m_instrCount;
UINFO(8, ":\n"); UINFO(8, ":\n");
m_instrCount = 0; m_instrCount = 0;
iterateAndNextNull(nodep->expr2p()); iterateAndNextNull(nodep->elsep());
const uint32_t elseCount = m_instrCount; const uint32_t elseCount = m_instrCount;
if (ifCount < elseCount) { if (ifCount < elseCount) {
m_instrCount = savedCount + elseCount; m_instrCount = savedCount + elseCount;
if (nodep->expr1p()) nodep->expr1p()->user4(0); // Don't dump it if (nodep->thenp()) nodep->thenp()->user4(0); // Don't dump it
} else { } else {
m_instrCount = savedCount + ifCount; m_instrCount = savedCount + ifCount;
if (nodep->expr2p()) nodep->expr2p()->user4(0); // Don't dump it if (nodep->elsep()) nodep->elsep()->user4(0); // Don't dump it
} }
} }
void visit(AstActive* nodep) override { void visit(AstActive* nodep) override {

View File

@ -340,7 +340,7 @@ private:
LifeBlock* const elseLifep = new LifeBlock(prevLifep, m_statep); LifeBlock* const elseLifep = new LifeBlock(prevLifep, m_statep);
{ {
m_lifep = ifLifep; m_lifep = ifLifep;
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
} }
{ {
m_lifep = elseLifep; m_lifep = elseLifep;
@ -375,7 +375,7 @@ private:
} }
{ {
m_lifep = bodyLifep; m_lifep = bodyLifep;
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
} }
m_lifep = prevLifep; m_lifep = prevLifep;

View File

@ -268,7 +268,7 @@ private:
{ {
m_modp = modp; m_modp = modp;
// Important that this adds to end, as next iterate assumes does all cells // Important that this adds to end, as next iterate assumes does all cells
modp->addStmtp(cellsp); modp->addStmtsp(cellsp);
iterateAndNextNull(cellsp); iterateAndNextNull(cellsp);
} }
} }
@ -321,7 +321,7 @@ private:
otherModp->recursiveClone(true); otherModp->recursiveClone(true);
// user1 etc will retain its pre-clone value // user1 etc will retain its pre-clone value
cellmodp->user2p(otherModp); cellmodp->user2p(otherModp);
v3Global.rootp()->addModulep(otherModp); v3Global.rootp()->addModulesp(otherModp);
new V3GraphEdge(&m_graph, vertex(cellmodp), vertex(otherModp), 1, new V3GraphEdge(&m_graph, vertex(cellmodp), vertex(otherModp), 1,
false); false);
} }

View File

@ -994,7 +994,7 @@ class LinkDotFindVisitor final : public VNVisitor {
if (!nodep->isExternDef()) { if (!nodep->isExternDef()) {
// Move it to proper spot under the target class // Move it to proper spot under the target class
nodep->unlinkFrBack(); nodep->unlinkFrBack();
classp->addStmtp(nodep); classp->addStmtsp(nodep);
nodep->isExternDef(true); // So we check there's a matching extern nodep->isExternDef(true); // So we check there's a matching extern
nodep->classOrPackagep()->unlinkFrBack()->deleteTree(); nodep->classOrPackagep()->unlinkFrBack()->deleteTree();
} }
@ -1030,7 +1030,7 @@ class LinkDotFindVisitor final : public VNVisitor {
newvarp->funcReturn(true); newvarp->funcReturn(true);
newvarp->trace(false); // Not user visible newvarp->trace(false); // Not user visible
newvarp->attrIsolateAssign(nodep->attrIsolateAssign()); newvarp->attrIsolateAssign(nodep->attrIsolateAssign());
nodep->addFvarp(newvarp); nodep->fvarp(newvarp);
// Explicit insert required, as the var name shadows the upper level's task name // Explicit insert required, as the var name shadows the upper level's task name
m_statep->insertSym(m_curSymp, newvarp->name(), newvarp, m_statep->insertSym(m_curSymp, newvarp->name(), newvarp,
nullptr /*classOrPackagep*/); nullptr /*classOrPackagep*/);
@ -1938,7 +1938,7 @@ private:
VFlagLogicPacked{}, 1); VFlagLogicPacked{}, 1);
newp->trace(modp->modTrace()); newp->trace(modp->modTrace());
nodep->varp(newp); nodep->varp(newp);
modp->addStmtp(newp); modp->addStmtsp(newp);
// Link it to signal list, must add the variable under the module; // Link it to signal list, must add the variable under the module;
// current scope might be lower now // current scope might be lower now
m_statep->insertSym(moduleSymp, newp->name(), newp, nullptr /*classOrPackagep*/); m_statep->insertSym(moduleSymp, newp->name(), newp, nullptr /*classOrPackagep*/);
@ -3097,7 +3097,7 @@ private:
nodep->classOrPackagep(foundp->classOrPackagep()); nodep->classOrPackagep(foundp->classOrPackagep());
} }
} else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) { } else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) {
AstNode* const paramsp = nodep->paramsp(); AstPin* const paramsp = nodep->paramsp();
if (paramsp) paramsp->unlinkFrBackWithNext(); if (paramsp) paramsp->unlinkFrBackWithNext();
AstClassRefDType* const newp AstClassRefDType* const newp
= new AstClassRefDType{nodep->fileline(), defp, paramsp}; = new AstClassRefDType{nodep->fileline(), defp, paramsp};

View File

@ -106,7 +106,7 @@ private:
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
// Body insert just before themselves // Body insert just before themselves
m_insStmtp = nullptr; // First thing should be new statement m_insStmtp = nullptr; // First thing should be new statement
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
// Done the loop // Done the loop
m_insStmtp = nullptr; // Next thing should be new statement m_insStmtp = nullptr; // Next thing should be new statement
@ -131,7 +131,7 @@ private:
m_insStmtp = nodep; m_insStmtp = nodep;
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
m_insStmtp = nullptr; m_insStmtp = nullptr;
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
iterateAndNextNull(nodep->elsesp()); iterateAndNextNull(nodep->elsesp());
m_insStmtp = nullptr; m_insStmtp = nullptr;
} }
@ -143,7 +143,7 @@ private:
iterateAndNextNull(nodep->condsp()); iterateAndNextNull(nodep->condsp());
} }
m_insStmtp = nullptr; // Next thing should be new statement m_insStmtp = nullptr; // Next thing should be new statement
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
} }
void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
nodep->v3fatalSrc( nodep->v3fatalSrc(

View File

@ -69,7 +69,7 @@ private:
underp = VN_AS(nodep, NodeFTask)->stmtsp(); underp = VN_AS(nodep, NodeFTask)->stmtsp();
} else if (VN_IS(nodep, Foreach)) { } else if (VN_IS(nodep, Foreach)) {
if (endOfIter) { if (endOfIter) {
underp = VN_AS(nodep, Foreach)->bodysp(); underp = VN_AS(nodep, Foreach)->stmtsp();
} else { } else {
underp = nodep; underp = nodep;
under_and_next = false; // IE we skip the entire foreach under_and_next = false; // IE we skip the entire foreach
@ -78,7 +78,7 @@ private:
if (endOfIter) { if (endOfIter) {
// Note we jump to end of bodysp; a FOR loop has its // Note we jump to end of bodysp; a FOR loop has its
// increment under incsp() which we don't skip // increment under incsp() which we don't skip
underp = VN_AS(nodep, While)->bodysp(); underp = VN_AS(nodep, While)->stmtsp();
} else { } else {
underp = nodep; underp = nodep;
under_and_next = false; // IE we skip the entire while under_and_next = false; // IE we skip the entire while
@ -157,7 +157,7 @@ private:
AstVar* const varp AstVar* const varp
= new AstVar(nodep->fileline(), VVarType::BLOCKTEMP, name, nodep->findSigned32DType()); = new AstVar(nodep->fileline(), VVarType::BLOCKTEMP, name, nodep->findSigned32DType());
varp->usedLoopIdx(true); varp->usedLoopIdx(true);
m_modp->addStmtp(varp); m_modp->addStmtsp(varp);
AstNode* initsp = new AstAssign( AstNode* initsp = new AstAssign(
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), countp); nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), countp);
AstNode* const decp = new AstAssign( AstNode* const decp = new AstAssign(
@ -167,7 +167,7 @@ private:
AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
AstNode* const condp = new AstGtS( AstNode* const condp = new AstGtS(
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp); nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp);
AstNode* const bodysp = nodep->bodysp(); AstNode* const bodysp = nodep->stmtsp();
if (bodysp) bodysp->unlinkFrBackWithNext(); if (bodysp) bodysp->unlinkFrBackWithNext();
AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp); AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp);
initsp = initsp->addNext(newp); initsp = initsp->addNext(newp);
@ -178,7 +178,7 @@ private:
void visit(AstWait* nodep) override { void visit(AstWait* nodep) override {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: wait statements"); nodep->v3warn(E_UNSUPPORTED, "Unsupported: wait statements");
// Statements we'll just execute immediately; equivalent to if they followed this // Statements we'll just execute immediately; equivalent to if they followed this
if (AstNode* const bodysp = nodep->bodysp()) { if (AstNode* const bodysp = nodep->stmtsp()) {
bodysp->unlinkFrBackWithNext(); bodysp->unlinkFrBackWithNext();
nodep->replaceWith(bodysp); nodep->replaceWith(bodysp);
} else { } else {
@ -195,7 +195,7 @@ private:
m_loopInc = false; m_loopInc = false;
iterateAndNextNull(nodep->precondsp()); iterateAndNextNull(nodep->precondsp());
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
m_loopInc = true; m_loopInc = true;
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
} }
@ -204,7 +204,7 @@ private:
VL_RESTORER(m_loopp); VL_RESTORER(m_loopp);
{ {
m_loopp = nodep; m_loopp = nodep;
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
} }
} }
void visit(AstReturn* nodep) override { void visit(AstReturn* nodep) override {

View File

@ -76,7 +76,7 @@ void V3LinkLevel::modSortByLevel() {
UINFO(9, "modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666 UINFO(9, "modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666
for (AstNodeModule* nodep : mods) nodep->unlinkFrBack(); for (AstNodeModule* nodep : mods) nodep->unlinkFrBack();
UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work"); UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work");
for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulep(nodep); for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulesp(nodep);
UINFO(9, "modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 UINFO(9, "modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666
V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
} }
@ -154,7 +154,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
newmodp->modPublic(true); newmodp->modPublic(true);
newmodp->protect(false); newmodp->protect(false);
newmodp->timeunit(oldmodp->timeunit()); newmodp->timeunit(oldmodp->timeunit());
rootp->addModulep(newmodp); rootp->addModulesp(newmodp);
// TODO the module creation above could be done after linkcells, but // TODO the module creation above could be done after linkcells, but
// the rest must be done after data type resolution // the rest must be done after data type resolution
@ -170,7 +170,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
// with module names/"v" // with module names/"v"
modp->name(), modp->name(), nullptr, nullptr, nullptr); modp->name(), modp->name(), nullptr, nullptr, nullptr);
cellp->modp(modp); cellp->modp(modp);
newmodp->addStmtp(cellp); newmodp->addStmtsp(cellp);
} }
} }
@ -213,7 +213,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
(!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()), (!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()),
oldmodp->name(), nullptr, nullptr, nullptr); oldmodp->name(), nullptr, nullptr, nullptr);
cellp->modp(oldmodp); cellp->modp(oldmodp);
newmodp->addStmtp(cellp); newmodp->addStmtsp(cellp);
// Add pins // Add pins
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
@ -229,7 +229,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
AstVar* const varp = oldvarp->cloneTree(false); AstVar* const varp = oldvarp->cloneTree(false);
varp->name(name); varp->name(name);
varp->protect(false); varp->protect(false);
newmodp->addStmtp(varp); newmodp->addStmtsp(varp);
varp->sigPublic(true); // User needs to be able to get to it... varp->sigPublic(true); // User needs to be able to get to it...
if (oldvarp->isIO()) { if (oldvarp->isIO()) {
oldvarp->primaryIO(false); oldvarp->primaryIO(false);

View File

@ -372,7 +372,7 @@ private:
// lvalue is true, because we know we have a verilator public_flat_rw // lvalue is true, because we know we have a verilator public_flat_rw
// but someday we may be more general // but someday we may be more general
const bool lvalue = m_varp->isSigUserRWPublic(); const bool lvalue = m_varp->isSigUserRWPublic();
nodep->addStmtp( nodep->addStmtsp(
new AstVarRef(nodep->fileline(), m_varp, lvalue ? VAccess::WRITE : VAccess::READ)); new AstVarRef(nodep->fileline(), m_varp, lvalue ? VAccess::WRITE : VAccess::READ));
} }
} }
@ -596,7 +596,7 @@ private:
sensesp->unlinkFrBackWithNext(); sensesp->unlinkFrBackWithNext();
alwaysp->sensesp(sensesp); alwaysp->sensesp(sensesp);
} }
if (nodep->stmtsp()) alwaysp->addStmtp(nodep->stmtsp()->unlinkFrBackWithNext()); if (nodep->stmtsp()) alwaysp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} }
} }

View File

@ -86,7 +86,7 @@ private:
// Initial assignments under function/tasks can just be simple // Initial assignments under function/tasks can just be simple
// assignments without the initial // assignments without the initial
if (m_ftaskp) { if (m_ftaskp) {
VL_DO_DANGLING(nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()), nodep); VL_DO_DANGLING(nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext()), nodep);
} }
} }
void visit(AstNodeCoverOrAssert* nodep) override { void visit(AstNodeCoverOrAssert* nodep) override {
@ -483,7 +483,7 @@ private:
} }
varoutp = varp; varoutp = varp;
// Tie off // Tie off
m_modp->addStmtp( m_modp->addStmtsp(
new AstAssignW(varp->fileline(), new AstAssignW(varp->fileline(),
new AstVarRef(varp->fileline(), varp, VAccess::WRITE), new AstVarRef(varp->fileline(), varp, VAccess::WRITE),
new AstConst(varp->fileline(), AstConst::BitFalse()))); new AstConst(varp->fileline(), AstConst::BitFalse())));

View File

@ -565,7 +565,7 @@ private:
return false; return false;
} }
if (const AstNodeCond* const condp = VN_CAST(nodep, NodeCond)) { if (const AstNodeCond* const condp = VN_CAST(nodep, NodeCond)) {
return yieldsOneOrZero(condp->expr1p()) && yieldsOneOrZero(condp->expr2p()); return yieldsOneOrZero(condp->thenp()) && yieldsOneOrZero(condp->elsep());
} }
if (const AstCCast* const castp = VN_CAST(nodep, CCast)) { if (const AstCCast* const castp = VN_CAST(nodep, CCast)) {
// Cast never sign extends // Cast never sign extends
@ -593,7 +593,7 @@ private:
return new AstConst{rhsp->fileline(), AstConst::BitTrue{}, condTrue}; return new AstConst{rhsp->fileline(), AstConst::BitTrue{}, condTrue};
} else if (const AstNodeCond* const condp = extractCondFromRhs(rhsp)) { } else if (const AstNodeCond* const condp = extractCondFromRhs(rhsp)) {
AstNode* const resp AstNode* const resp
= condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack(); = condTrue ? condp->thenp()->unlinkFrBack() : condp->elsep()->unlinkFrBack();
if (condp == rhsp) return resp; if (condp == rhsp) return resp;
if (const AstAnd* const andp = VN_CAST(rhsp, And)) { if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this"); UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this");
@ -676,7 +676,7 @@ private:
// Construct the new RHSs and add to branches // Construct the new RHSs and add to branches
thenp->rhsp(foldAndUnlink(rhsp, true)); thenp->rhsp(foldAndUnlink(rhsp, true));
elsep->rhsp(foldAndUnlink(rhsp, false)); elsep->rhsp(foldAndUnlink(rhsp, false));
resultp->addIfsp(thenp); resultp->addThensp(thenp);
resultp->addElsesp(elsep); resultp->addElsesp(elsep);
// Cleanup // Cleanup
VL_DO_DANGLING(rhsp->deleteTree(), rhsp); VL_DO_DANGLING(rhsp->deleteTree(), rhsp);
@ -684,8 +684,8 @@ private:
AstNodeIf* const ifp = VN_AS(currp, NodeIf); AstNodeIf* const ifp = VN_AS(currp, NodeIf);
UASSERT_OBJ(ifp, currp, "Must be AstNodeIf"); UASSERT_OBJ(ifp, currp, "Must be AstNodeIf");
// Move branch contents under new if // Move branch contents under new if
if (AstNode* const listp = ifp->ifsp()) { if (AstNode* const listp = ifp->thensp()) {
resultp->addIfsp(listp->unlinkFrBackWithNext()); resultp->addThensp(listp->unlinkFrBackWithNext());
} }
if (AstNode* const listp = ifp->elsesp()) { if (AstNode* const listp = ifp->elsesp()) {
resultp->addElsesp(listp->unlinkFrBackWithNext()); resultp->addElsesp(listp->unlinkFrBackWithNext());
@ -695,7 +695,7 @@ private:
} }
} while (nextp); } while (nextp);
// Merge the branches of the resulting AstIf after re-analysis // Merge the branches of the resulting AstIf after re-analysis
if (resultp->ifsp()) m_workQueuep->push(resultp->ifsp()); if (resultp->thensp()) m_workQueuep->push(resultp->thensp());
if (resultp->elsesp()) m_workQueuep->push(resultp->elsesp()); if (resultp->elsesp()) m_workQueuep->push(resultp->elsesp());
} else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) { } else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) {
// There was nothing to merge this AstNodeIf with, so try to merge its branches. // There was nothing to merge this AstNodeIf with, so try to merge its branches.
@ -711,7 +711,7 @@ private:
AstNode::user2ClearTree(); AstNode::user2ClearTree();
// Merge recursively within the branches of an un-merged AstNodeIF // Merge recursively within the branches of an un-merged AstNodeIF
if (recursivep) { if (recursivep) {
iterateAndNextNull(recursivep->ifsp()); iterateAndNextNull(recursivep->thensp());
iterateAndNextNull(recursivep->elsesp()); iterateAndNextNull(recursivep->elsesp());
// Close a pending merge to ensure merge state is // Close a pending merge to ensure merge state is
// reset as expected at the end of this function // reset as expected at the end of this function
@ -840,7 +840,7 @@ private:
// Check if mergeable // Check if mergeable
if (!checkOrMakeMergeable(nodep)) { if (!checkOrMakeMergeable(nodep)) {
// If not mergeable, try to merge the branches // If not mergeable, try to merge the branches
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
iterateAndNextNull(nodep->elsesp()); iterateAndNextNull(nodep->elsesp());
return; return;
} }

View File

@ -1789,7 +1789,7 @@ void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
<< " s=" << cvtToHex(scopep) << " " << lvertexp << endl); << " s=" << cvtToHex(scopep) << " " << lvertexp << endl);
AstActive* const newActivep AstActive* const newActivep
= processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/); = processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/);
if (newActivep) m_scopetop.addActivep(newActivep); if (newActivep) m_scopetop.addBlocksp(newActivep);
processMoveDoneOne(vertexp); processMoveDoneOne(vertexp);
} }
@ -1811,7 +1811,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
// procedures. Everything else is handled in one go // procedures. Everything else is handled in one go
AstNodeProcedure* const procp = VN_CAST(nodep, NodeProcedure); AstNodeProcedure* const procp = VN_CAST(nodep, NodeProcedure);
if (procp && !v3Global.opt.profCFuncs()) { if (procp && !v3Global.opt.profCFuncs()) {
nodep = procp->bodysp(); nodep = procp->stmtsp();
pushDeletep(procp); pushDeletep(procp);
} }
@ -1831,7 +1831,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
newFuncpr->isLoose(true); newFuncpr->isLoose(true);
newStmtsr = 0; newStmtsr = 0;
if (domainp->hasInitial() || domainp->hasSettle()) newFuncpr->slow(true); if (domainp->hasInitial() || domainp->hasSettle()) newFuncpr->slow(true);
scopep->addActivep(newFuncpr); scopep->addBlocksp(newFuncpr);
// Create top call to it // Create top call to it
AstCCall* const callp = new AstCCall(nodep->fileline(), newFuncpr); AstCCall* const callp = new AstCCall(nodep->fileline(), newFuncpr);
// Where will we be adding the call? // Where will we be adding the call?
@ -1886,7 +1886,7 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
} }
AstActive* const newActivep AstActive* const newActivep
= processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/); = processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/);
if (newActivep) m_scopetop.addActivep(newActivep); if (newActivep) m_scopetop.addBlocksp(newActivep);
} }
} }
@ -1966,7 +1966,7 @@ void OrderProcess::processMTasks() {
// of the MTask graph. // of the MTask graph.
FileLine* const rootFlp = v3Global.rootp()->fileline(); FileLine* const rootFlp = v3Global.rootp()->fileline();
AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, "eval"}; AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, "eval"};
m_scopetop.addActivep(execGraphp); m_scopetop.addBlocksp(execGraphp);
// Create CFuncs and bodies for each MTask. // Create CFuncs and bodies for each MTask.
GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks); GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks);
@ -2018,7 +2018,7 @@ void OrderProcess::processMTasks() {
const MTaskState& fromState = mtaskStates[fromp->id()]; const MTaskState& fromState = mtaskStates[fromp->id()];
new V3GraphEdge(depGraphp, fromState.m_execMTaskp, state.m_execMTaskp, 1); new V3GraphEdge(depGraphp, fromState.m_execMTaskp, state.m_execMTaskp, 1);
} }
execGraphp->addMTaskBodyp(bodyp); execGraphp->addMTaskBodiesp(bodyp);
} }
} }

View File

@ -1132,7 +1132,7 @@ class ParamVisitor final : public VNVisitor {
// NOT recurse the body. // NOT recurse the body.
V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change
if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) { if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) {
if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->ifsp())) { if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->thensp())) {
keepp->unlinkFrBackWithNext(); keepp->unlinkFrBackWithNext();
nodep->replaceWith(keepp); nodep->replaceWith(keepp);
} else { } else {
@ -1150,9 +1150,7 @@ class ParamVisitor final : public VNVisitor {
//! expression, since this is currently restricted to simple comparisons. If we ever do //! expression, since this is currently restricted to simple comparisons. If we ever do
//! move to more generic constant expressions, such code will be needed here. //! move to more generic constant expressions, such code will be needed here.
void visit(AstBegin* nodep) override { void visit(AstBegin* nodep) override {
if (nodep->genforp()) { if (AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor)) {
AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor);
UASSERT_OBJ(forp, nodep, "Non-GENFOR under generate-for BEGIN");
// We should have a GENFOR under here. We will be replacing the begin, // We should have a GENFOR under here. We will be replacing the begin,
// so process here rather than at the generate to avoid iteration problems // so process here rather than at the generate to avoid iteration problems
UINFO(9, " BEGIN " << nodep << endl); UINFO(9, " BEGIN " << nodep << endl);
@ -1211,7 +1209,7 @@ class ParamVisitor final : public VNVisitor {
if (const AstConst* const ccondp = VN_CAST(ep, Const)) { if (const AstConst* const ccondp = VN_CAST(ep, Const)) {
V3Number match(nodep, 1); V3Number match(nodep, 1);
match.opEq(ccondp->num(), exprp->num()); match.opEq(ccondp->num(), exprp->num());
if (!keepp && match.isNeqZero()) keepp = itemp->bodysp(); if (!keepp && match.isNeqZero()) keepp = itemp->stmtsp();
} else { } else {
itemp->v3error("Generate Case item does not evaluate to constant"); itemp->v3error("Generate Case item does not evaluate to constant");
} }
@ -1222,7 +1220,7 @@ class ParamVisitor final : public VNVisitor {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; for (AstCaseItem* itemp = nodep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), CaseItem)) { itemp = VN_AS(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) { if (itemp->isDefault()) {
if (!keepp) keepp = itemp->bodysp(); if (!keepp) keepp = itemp->stmtsp();
} }
} }
// Replace // Replace
@ -1269,7 +1267,7 @@ public:
}); });
// Re-insert modules // Re-insert modules
for (AstNodeModule* const modp : modps) netlistp->addModulep(modp); for (AstNodeModule* const modp : modps) netlistp->addModulesp(modp);
} }
} }
~ParamVisitor() override = default; ~ParamVisitor() override = default;

View File

@ -283,7 +283,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
if (errmsg != "") return; // Threw error already if (errmsg != "") return; // Threw error already
// Create fake node for later error reporting // Create fake node for later error reporting
AstNodeModule* const nodep = new AstNotFoundModule(fileline, modname); AstNodeModule* const nodep = new AstNotFoundModule(fileline, modname);
v3Global.rootp()->addModulep(nodep); v3Global.rootp()->addModulesp(nodep);
return; return;
} }

View File

@ -3051,7 +3051,7 @@ static void addMTaskToFunction(const ThreadSchedule& schedule, const uint32_t th
AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, name, mtaskStateDtypep); AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, name, mtaskStateDtypep);
varp->valuep(new AstConst(fl, nDependencies)); varp->valuep(new AstConst(fl, nDependencies));
varp->protect(false); // Do not protect as we still have references in AstText varp->protect(false); // Do not protect as we still have references in AstText
modp->addStmtp(varp); modp->addStmtsp(varp);
// For now, reference is still via text bashing // For now, reference is still via text bashing
addStrStmt("vlSelf->" + name + +".waitUntilUpstreamDone(even_cycle);\n"); addStrStmt("vlSelf->" + name + +".waitUntilUpstreamDone(even_cycle);\n");
} }
@ -3112,7 +3112,7 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
const uint32_t threadId = schedule.threadId(thread.front()); const uint32_t threadId = schedule.threadId(thread.front());
const string name{"__Vthread__" + tag + "__" + cvtToStr(threadId)}; const string name{"__Vthread__" + tag + "__" + cvtToStr(threadId)};
AstCFunc* const funcp = new AstCFunc(fl, name, nullptr, "void"); AstCFunc* const funcp = new AstCFunc(fl, name, nullptr, "void");
modp->addStmtp(funcp); modp->addStmtsp(funcp);
funcps.push_back(funcp); funcps.push_back(funcp);
funcp->isStatic(true); // Uses void self pointer, so static and hand rolled funcp->isStatic(true); // Uses void self pointer, so static and hand rolled
funcp->isLoose(true); funcp->isLoose(true);
@ -3140,7 +3140,7 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
= new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final", mtaskStateDtypep); = new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final", mtaskStateDtypep);
varp->valuep(new AstConst(fl, funcps.size())); varp->valuep(new AstConst(fl, funcps.size()));
varp->protect(false); // Do not protect as we still have references in AstText varp->protect(false); // Do not protect as we still have references in AstText
modp->addStmtp(varp); modp->addStmtsp(varp);
return funcps; return funcps;
} }

View File

@ -176,7 +176,7 @@ private:
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
m_inWhilep = nullptr; m_inWhilep = nullptr;
startStatement(nodep); startStatement(nodep);
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
m_stmtp = nullptr; m_stmtp = nullptr;
} }
@ -329,7 +329,7 @@ private:
} }
void visit(AstNodeCond* nodep) override { void visit(AstNodeCond* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
if (nodep->expr1p()->isWide() && !VN_IS(nodep->condp(), Const) if (nodep->thenp()->isWide() && !VN_IS(nodep->condp(), Const)
&& !VN_IS(nodep->condp(), VarRef)) { && !VN_IS(nodep->condp(), VarRef)) {
// We're going to need the expression several times in the expanded code, // We're going to need the expression several times in the expanded code,
// so might as well make it a common expression // so might as well make it a common expression

View File

@ -95,7 +95,7 @@ private:
} }
void addComment(AstTextBlock* txtp, FileLine* fl, const string& comment) { void addComment(AstTextBlock* txtp, FileLine* fl, const string& comment) {
txtp->addNodep(new AstComment{fl, comment}); txtp->addNodesp(new AstComment{fl, comment});
} }
void hashComment(AstTextBlock* txtp, FileLine* fl) { void hashComment(AstTextBlock* txtp, FileLine* fl) {
@ -143,7 +143,7 @@ private:
// Module declaration // Module declaration
m_modPortsp = new AstTextBlock{fl, "module " + m_libName + " (\n", false, true}; m_modPortsp = new AstTextBlock{fl, "module " + m_libName + " (\n", false, true};
txtp->addNodep(m_modPortsp); txtp->addNodesp(m_modPortsp);
txtp->addText(fl, ");\n\n"); txtp->addText(fl, ");\n\n");
// Timescale // Timescale
@ -177,7 +177,7 @@ private:
"(\n", "(\n",
false, true}; false, true};
m_comboPortsp->addText(fl, "chandle handle__V\n"); m_comboPortsp->addText(fl, "chandle handle__V\n");
txtp->addNodep(m_comboPortsp); txtp->addNodesp(m_comboPortsp);
txtp->addText(fl, ");\n\n"); txtp->addText(fl, ");\n\n");
seqComment(txtp, fl); seqComment(txtp, fl);
if (m_hasClk) { if (m_hasClk) {
@ -187,7 +187,7 @@ private:
"(\n", "(\n",
false, true}; false, true};
m_seqPortsp->addText(fl, "chandle handle__V\n"); m_seqPortsp->addText(fl, "chandle handle__V\n");
txtp->addNodep(m_seqPortsp); txtp->addNodesp(m_seqPortsp);
txtp->addText(fl, ");\n\n"); txtp->addText(fl, ");\n\n");
} }
comboIgnoreComment(txtp, fl); comboIgnoreComment(txtp, fl);
@ -197,7 +197,7 @@ private:
"(\n", "(\n",
false, true}; false, true};
m_comboIgnorePortsp->addText(fl, "chandle handle__V\n"); m_comboIgnorePortsp->addText(fl, "chandle handle__V\n");
txtp->addNodep(m_comboIgnorePortsp); txtp->addNodesp(m_comboIgnorePortsp);
txtp->addText(fl, ");\n\n"); txtp->addText(fl, ");\n\n");
finalComment(txtp, fl); finalComment(txtp, fl);
@ -227,17 +227,17 @@ private:
txtp->addText(fl, "\n"); txtp->addText(fl, "\n");
m_comboDeclsp = new AstTextBlock{fl}; m_comboDeclsp = new AstTextBlock{fl};
txtp->addNodep(m_comboDeclsp); txtp->addNodesp(m_comboDeclsp);
m_seqDeclsp = new AstTextBlock{fl}; m_seqDeclsp = new AstTextBlock{fl};
txtp->addNodep(m_seqDeclsp); txtp->addNodesp(m_seqDeclsp);
m_tmpDeclsp = new AstTextBlock{fl}; m_tmpDeclsp = new AstTextBlock{fl};
txtp->addNodep(m_tmpDeclsp); txtp->addNodesp(m_tmpDeclsp);
// CPP hash value // CPP hash value
addComment(txtp, fl, "Hash value to make sure this file and the corresponding"); addComment(txtp, fl, "Hash value to make sure this file and the corresponding");
addComment(txtp, fl, "library agree"); addComment(txtp, fl, "library agree");
m_hashValuep = new AstTextBlock{fl, "localparam int protectlib_hash__V = 32'd"}; m_hashValuep = new AstTextBlock{fl, "localparam int protectlib_hash__V = 32'd"};
txtp->addNodep(m_hashValuep); txtp->addNodesp(m_hashValuep);
txtp->addText(fl, "\n"); txtp->addText(fl, "\n");
// Initial // Initial
@ -256,7 +256,7 @@ private:
+ m_libName + "_protectlib_combo_update(\n", + m_libName + "_protectlib_combo_update(\n",
false, true}; false, true};
m_comboParamsp->addText(fl, "handle__V\n"); m_comboParamsp->addText(fl, "handle__V\n");
txtp->addNodep(m_comboParamsp); txtp->addNodesp(m_comboParamsp);
txtp->addText(fl, ");\n"); txtp->addText(fl, ");\n");
txtp->addText(fl, "end\n\n"); txtp->addText(fl, "end\n\n");
@ -264,21 +264,21 @@ private:
if (m_hasClk) { if (m_hasClk) {
addComment(txtp, fl, "Evaluate clock edges"); addComment(txtp, fl, "Evaluate clock edges");
m_clkSensp = new AstTextBlock{fl, "always @(", false, true}; m_clkSensp = new AstTextBlock{fl, "always @(", false, true};
txtp->addNodep(m_clkSensp); txtp->addNodesp(m_clkSensp);
txtp->addText(fl, ") begin\n"); txtp->addText(fl, ") begin\n");
m_comboIgnoreParamsp m_comboIgnoreParamsp
= new AstTextBlock{fl, m_libName + "_protectlib_combo_ignore(\n", false, true}; = new AstTextBlock{fl, m_libName + "_protectlib_combo_ignore(\n", false, true};
m_comboIgnoreParamsp->addText(fl, "handle__V\n"); m_comboIgnoreParamsp->addText(fl, "handle__V\n");
txtp->addNodep(m_comboIgnoreParamsp); txtp->addNodesp(m_comboIgnoreParamsp);
txtp->addText(fl, ");\n"); txtp->addText(fl, ");\n");
m_seqParamsp = new AstTextBlock{ m_seqParamsp = new AstTextBlock{
fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false, fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false,
true}; true};
m_seqParamsp->addText(fl, "handle__V\n"); m_seqParamsp->addText(fl, "handle__V\n");
txtp->addNodep(m_seqParamsp); txtp->addNodesp(m_seqParamsp);
txtp->addText(fl, ");\n"); txtp->addText(fl, ");\n");
m_nbAssignsp = new AstTextBlock{fl}; m_nbAssignsp = new AstTextBlock{fl};
txtp->addNodep(m_nbAssignsp); txtp->addNodesp(m_nbAssignsp);
txtp->addText(fl, "end\n\n"); txtp->addText(fl, "end\n\n");
} }
@ -288,13 +288,13 @@ private:
if (m_hasClk) { if (m_hasClk) {
m_seqAssignsp = new AstTextBlock{fl, "if (last_seq_seqnum__V > " m_seqAssignsp = new AstTextBlock{fl, "if (last_seq_seqnum__V > "
"last_combo_seqnum__V) begin\n"}; "last_combo_seqnum__V) begin\n"};
txtp->addNodep(m_seqAssignsp); txtp->addNodesp(m_seqAssignsp);
m_comboAssignsp = new AstTextBlock{fl, "end\nelse begin\n"}; m_comboAssignsp = new AstTextBlock{fl, "end\nelse begin\n"};
txtp->addNodep(m_comboAssignsp); txtp->addNodesp(m_comboAssignsp);
txtp->addText(fl, "end\n"); txtp->addText(fl, "end\n");
} else { } else {
m_comboAssignsp = new AstTextBlock{fl, ""}; m_comboAssignsp = new AstTextBlock{fl, ""};
txtp->addNodep(m_comboAssignsp); txtp->addNodesp(m_comboAssignsp);
} }
txtp->addText(fl, "end\n\n"); txtp->addText(fl, "end\n\n");
@ -341,7 +341,7 @@ private:
+ "_protectlib_check_hash" + "_protectlib_check_hash"
"(int protectlib_hash__V) {\n"); "(int protectlib_hash__V) {\n");
m_cHashValuep = new AstTextBlock{fl, "const int expected_hash__V = "}; m_cHashValuep = new AstTextBlock{fl, "const int expected_hash__V = "};
txtp->addNodep(m_cHashValuep); txtp->addNodesp(m_cHashValuep);
txtp->addText(fl, /**/ "if (protectlib_hash__V != expected_hash__V) {\n"); txtp->addText(fl, /**/ "if (protectlib_hash__V != expected_hash__V) {\n");
txtp->addText(fl, /****/ "fprintf(stderr, \"%%Error: cannot use " + m_libName txtp->addText(fl, /****/ "fprintf(stderr, \"%%Error: cannot use " + m_libName
+ " library, " + " library, "
@ -364,13 +364,13 @@ private:
m_cComboParamsp = new AstTextBlock{ m_cComboParamsp = new AstTextBlock{
fl, "long long " + m_libName + "_protectlib_combo_update(\n", false, true}; fl, "long long " + m_libName + "_protectlib_combo_update(\n", false, true};
m_cComboParamsp->addText(fl, "void* vhandlep__V\n"); m_cComboParamsp->addText(fl, "void* vhandlep__V\n");
txtp->addNodep(m_cComboParamsp); txtp->addNodesp(m_cComboParamsp);
txtp->addText(fl, ")\n"); txtp->addText(fl, ")\n");
m_cComboInsp = new AstTextBlock{fl, "{\n"}; m_cComboInsp = new AstTextBlock{fl, "{\n"};
castPtr(fl, m_cComboInsp); castPtr(fl, m_cComboInsp);
txtp->addNodep(m_cComboInsp); txtp->addNodesp(m_cComboInsp);
m_cComboOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"}; m_cComboOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"};
txtp->addNodep(m_cComboOutsp); txtp->addNodesp(m_cComboOutsp);
txtp->addText(fl, "return handlep__V->m_seqnum++;\n"); txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
txtp->addText(fl, "}\n\n"); txtp->addText(fl, "}\n\n");
@ -379,13 +379,13 @@ private:
m_cSeqParamsp = new AstTextBlock{ m_cSeqParamsp = new AstTextBlock{
fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true}; fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true};
m_cSeqParamsp->addText(fl, "void* vhandlep__V\n"); m_cSeqParamsp->addText(fl, "void* vhandlep__V\n");
txtp->addNodep(m_cSeqParamsp); txtp->addNodesp(m_cSeqParamsp);
txtp->addText(fl, ")\n"); txtp->addText(fl, ")\n");
m_cSeqClksp = new AstTextBlock{fl, "{\n"}; m_cSeqClksp = new AstTextBlock{fl, "{\n"};
castPtr(fl, m_cSeqClksp); castPtr(fl, m_cSeqClksp);
txtp->addNodep(m_cSeqClksp); txtp->addNodesp(m_cSeqClksp);
m_cSeqOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"}; m_cSeqOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"};
txtp->addNodep(m_cSeqOutsp); txtp->addNodesp(m_cSeqOutsp);
txtp->addText(fl, "return handlep__V->m_seqnum++;\n"); txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
txtp->addText(fl, "}\n\n"); txtp->addText(fl, "}\n\n");
} }
@ -394,7 +394,7 @@ private:
m_cIgnoreParamsp = new AstTextBlock{ m_cIgnoreParamsp = new AstTextBlock{
fl, "void " + m_libName + "_protectlib_combo_ignore(\n", false, true}; fl, "void " + m_libName + "_protectlib_combo_ignore(\n", false, true};
m_cIgnoreParamsp->addText(fl, "void* vhandlep__V\n"); m_cIgnoreParamsp->addText(fl, "void* vhandlep__V\n");
txtp->addNodep(m_cIgnoreParamsp); txtp->addNodesp(m_cIgnoreParamsp);
txtp->addText(fl, ")\n"); txtp->addText(fl, ")\n");
txtp->addText(fl, "{ }\n\n"); txtp->addText(fl, "{ }\n\n");
@ -448,7 +448,7 @@ private:
void handleClock(AstVar* varp) { void handleClock(AstVar* varp) {
FileLine* const fl = varp->fileline(); FileLine* const fl = varp->fileline();
handleInput(varp); handleInput(varp);
m_seqPortsp->addNodep(varp->cloneTree(false)); m_seqPortsp->addNodesp(varp->cloneTree(false));
if (m_hasClk) { if (m_hasClk) {
m_seqParamsp->addText(fl, varp->name() + "\n"); m_seqParamsp->addText(fl, varp->name() + "\n");
m_clkSensp->addText(fl, "posedge " + varp->name() + " or negedge " + varp->name()); m_clkSensp->addText(fl, "posedge " + varp->name() + " or negedge " + varp->name());
@ -460,30 +460,30 @@ private:
void handleDataInput(AstVar* varp) { void handleDataInput(AstVar* varp) {
FileLine* const fl = varp->fileline(); FileLine* const fl = varp->fileline();
handleInput(varp); handleInput(varp);
m_comboPortsp->addNodep(varp->cloneTree(false)); m_comboPortsp->addNodesp(varp->cloneTree(false));
m_comboParamsp->addText(fl, varp->name() + "\n"); m_comboParamsp->addText(fl, varp->name() + "\n");
m_comboIgnorePortsp->addNodep(varp->cloneTree(false)); m_comboIgnorePortsp->addNodesp(varp->cloneTree(false));
if (m_hasClk) m_comboIgnoreParamsp->addText(fl, varp->name() + "\n"); if (m_hasClk) m_comboIgnoreParamsp->addText(fl, varp->name() + "\n");
m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n"); m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
m_cComboInsp->addText(fl, cInputConnection(varp)); m_cComboInsp->addText(fl, cInputConnection(varp));
m_cIgnoreParamsp->addText(fl, varp->dpiArgType(true, false) + "\n"); m_cIgnoreParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
} }
void handleInput(AstVar* varp) { m_modPortsp->addNodep(varp->cloneTree(false)); } void handleInput(AstVar* varp) { m_modPortsp->addNodesp(varp->cloneTree(false)); }
static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) { static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) {
AstVar* const newVarp AstVar* const newVarp
= new AstVar{varp->fileline(), VVarType::VAR, varp->name() + suffix, varp->dtypep()}; = new AstVar{varp->fileline(), VVarType::VAR, varp->name() + suffix, varp->dtypep()};
textp->addNodep(newVarp); textp->addNodesp(newVarp);
} }
void handleOutput(AstVar* varp) { void handleOutput(AstVar* varp) {
FileLine* const fl = varp->fileline(); FileLine* const fl = varp->fileline();
m_modPortsp->addNodep(varp->cloneTree(false)); m_modPortsp->addNodesp(varp->cloneTree(false));
m_comboPortsp->addNodep(varp->cloneTree(false)); m_comboPortsp->addNodesp(varp->cloneTree(false));
m_comboParamsp->addText(fl, varp->name() + "_combo__V\n"); m_comboParamsp->addText(fl, varp->name() + "_combo__V\n");
if (m_hasClk) { if (m_hasClk) {
m_seqPortsp->addNodep(varp->cloneTree(false)); m_seqPortsp->addNodesp(varp->cloneTree(false));
m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n"); m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n");
} }

View File

@ -144,7 +144,7 @@ private:
varp->isStatic(true); varp->isStatic(true);
varp->valuep(initp); varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing // Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items"); UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items");
for (AstEnumItem* itemp = nodep->itemsp(); itemp; for (AstEnumItem* itemp = nodep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), EnumItem)) { itemp = VN_AS(itemp->nextp(), EnumItem)) {

View File

@ -114,7 +114,7 @@ private:
AstWhile* const whilep = new AstWhile(fl, condp, nullptr, incp); AstWhile* const whilep = new AstWhile(fl, condp, nullptr, incp);
initp->addNext(whilep); initp->addNext(whilep);
bodyp->replaceWith(initp); bodyp->replaceWith(initp);
whilep->addBodysp(bodyp); whilep->addStmtsp(bodyp);
// Replace constant index with new loop index // Replace constant index with new loop index
AstNode* const offsetp AstNode* const offsetp

View File

@ -135,7 +135,7 @@ private:
if (m_modp->isTop()) { if (m_modp->isTop()) {
v3Global.rootp()->createTopScope(m_scopep); v3Global.rootp()->createTopScope(m_scopep);
} else { } else {
m_modp->addStmtp(m_scopep); m_modp->addStmtsp(m_scopep);
} }
// Copy blocks into this scope // Copy blocks into this scope
@ -188,7 +188,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstAssignAlias* nodep) override { void visit(AstAssignAlias* nodep) override {
@ -196,7 +196,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstAssignVarScope* nodep) override { void visit(AstAssignVarScope* nodep) override {
@ -204,7 +204,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstAssignW* nodep) override { void visit(AstAssignW* nodep) override {
@ -212,7 +212,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstAlwaysPublic* nodep) override { void visit(AstAlwaysPublic* nodep) override {
@ -220,7 +220,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstCoverToggle* nodep) override { void visit(AstCoverToggle* nodep) override {
@ -228,7 +228,7 @@ private:
UINFO(4, " Move " << nodep << endl); UINFO(4, " Move " << nodep << endl);
AstNode* const clonep = nodep->cloneTree(false); AstNode* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
iterateChildren(clonep); // We iterate under the *clone* iterateChildren(clonep); // We iterate under the *clone*
} }
void visit(AstCFunc* nodep) override { void visit(AstCFunc* nodep) override {
@ -236,7 +236,7 @@ private:
UINFO(4, " CFUNC " << nodep << endl); UINFO(4, " CFUNC " << nodep << endl);
AstCFunc* const clonep = nodep->cloneTree(false); AstCFunc* const clonep = nodep->cloneTree(false);
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
clonep->scopep(m_scopep); clonep->scopep(m_scopep);
// We iterate under the *clone* // We iterate under the *clone*
iterateChildren(clonep); iterateChildren(clonep);
@ -253,7 +253,7 @@ private:
clonep = nodep->cloneTree(false); clonep = nodep->cloneTree(false);
} }
nodep->user2p(clonep); nodep->user2p(clonep);
m_scopep->addActivep(clonep); m_scopep->addBlocksp(clonep);
// We iterate under the *clone* // We iterate under the *clone*
iterateChildren(clonep); iterateChildren(clonep);
} }
@ -272,7 +272,7 @@ private:
} }
UASSERT_OBJ(m_scopep, nodep, "No scope for var"); UASSERT_OBJ(m_scopep, nodep, "No scope for var");
m_varScopes.emplace(std::make_pair(nodep, m_scopep), varscp); m_varScopes.emplace(std::make_pair(nodep, m_scopep), varscp);
m_scopep->addVarp(varscp); m_scopep->addVarsp(varscp);
} }
} }
void visit(AstVarRef* nodep) override { void visit(AstVarRef* nodep) override {
@ -295,14 +295,14 @@ private:
// TOP and above will be the user's name(). // TOP and above will be the user's name().
// Note 'TOP.' is stripped by scopePrettyName // Note 'TOP.' is stripped by scopePrettyName
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstText* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); nodep->addScopeAttrp(new AstText(nodep->fileline(), prefix));
if (afterp) nodep->scopeAttrp(afterp); if (afterp) nodep->addScopeAttrp(afterp);
afterp = nodep->scopeEntrp(); afterp = nodep->scopeEntrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeEntrp(new AstText(nodep->fileline(), prefix)); nodep->addScopeEntrp(new AstText(nodep->fileline(), prefix));
if (afterp) nodep->scopeEntrp(afterp); if (afterp) nodep->addScopeEntrp(afterp);
iterateChildren(nodep); iterateChildren(nodep);
} }
void visit(AstScope* nodep) override { void visit(AstScope* nodep) override {

View File

@ -64,7 +64,7 @@ public:
// Not found, create a new one // Not found, create a new one
AstSenTree* const newSenTreep = senTreep->cloneTree(false); AstSenTree* const newSenTreep = senTreep->cloneTree(false);
m_topScopep->addSenTreep(newSenTreep); m_topScopep->addSenTreesp(newSenTreep);
m_trees.emplace(*newSenTreep); m_trees.emplace(*newSenTreep);
return newSenTreep; return newSenTreep;
} }

View File

@ -513,7 +513,7 @@ private:
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
if (optimizable()) { if (optimizable()) {
if (fetchConst(nodep->condp())->num().isNeqZero()) { if (fetchConst(nodep->condp())->num().isNeqZero()) {
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
} else { } else {
iterateAndNextNull(nodep->elsesp()); iterateAndNextNull(nodep->elsesp());
} }
@ -647,11 +647,11 @@ private:
iterate(nodep->condp()); iterate(nodep->condp());
if (optimizable()) { if (optimizable()) {
if (fetchConst(nodep->condp())->num().isNeqZero()) { if (fetchConst(nodep->condp())->num().isNeqZero()) {
iterate(nodep->expr1p()); iterate(nodep->thenp());
newValue(nodep, fetchValue(nodep->expr1p())); newValue(nodep, fetchValue(nodep->thenp()));
} else { } else {
iterate(nodep->expr2p()); iterate(nodep->elsep());
newValue(nodep, fetchValue(nodep->expr2p())); newValue(nodep, fetchValue(nodep->elsep()));
} }
} }
} }
@ -835,7 +835,7 @@ private:
V3Number match{nodep, 1}; V3Number match{nodep, 1};
match.opEq(fetchConst(nodep->exprp())->num(), fetchConst(ep)->num()); match.opEq(fetchConst(nodep->exprp())->num(), fetchConst(ep)->num());
if (match.isNeqZero()) { if (match.isNeqZero()) {
iterateAndNextNull(itemp->bodysp()); iterateAndNextNull(itemp->stmtsp());
hit = true; hit = true;
} }
} }
@ -847,7 +847,7 @@ private:
itemp = VN_AS(itemp->nextp(), CaseItem)) { itemp = VN_AS(itemp->nextp(), CaseItem)) {
if (hit) break; if (hit) break;
if (!hit && itemp->isDefault()) { if (!hit && itemp->isDefault()) {
iterateAndNextNull(itemp->bodysp()); iterateAndNextNull(itemp->stmtsp());
hit = true; hit = true;
} }
} }
@ -917,7 +917,7 @@ private:
if (!fetchConst(nodep->condp())->num().isNeqZero()) { // if (!fetchConst(nodep->condp())->num().isNeqZero()) { //
break; break;
} }
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
if (loops++ > unrollCount() * 16) { if (loops++ > unrollCount() * 16) {
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an" clearOptimizable(nodep, "Loop unrolling took too long; probably this is an"
@ -952,7 +952,7 @@ private:
if (!fetchConst(nodep->condp())->num().isNeqZero()) { // if (!fetchConst(nodep->condp())->num().isNeqZero()) { //
break; break;
} }
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
if (jumpingOver(nodep)) break; if (jumpingOver(nodep)) break;
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
if (jumpingOver(nodep)) break; if (jumpingOver(nodep)) break;

View File

@ -101,8 +101,8 @@ class SliceVisitor final : public VNVisitor {
} else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) { } else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) {
UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl); UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl);
return snodep->cloneType(snodep->condp()->cloneTree(false), return snodep->cloneType(snodep->condp()->cloneTree(false),
cloneAndSel(snodep->expr1p(), elements, offset), cloneAndSel(snodep->thenp(), elements, offset),
cloneAndSel(snodep->expr2p(), elements, offset)); cloneAndSel(snodep->elsep(), elements, offset));
} else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) { } else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) {
UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl); UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl);
const int leOffset = (snodep->declRange().lo() const int leOffset = (snodep->declRange().lo()

View File

@ -601,14 +601,14 @@ protected:
UINFO(4, " ALW " << nodep << endl); UINFO(4, " ALW " << nodep << endl);
if (debug() >= 9) nodep->dumpTree(cout, " alwIn:: "); if (debug() >= 9) nodep->dumpTree(cout, " alwIn:: ");
scoreboardClear(); scoreboardClear();
processBlock(nodep->bodysp()); processBlock(nodep->stmtsp());
if (debug() >= 9) nodep->dumpTree(cout, " alwOut: "); if (debug() >= 9) nodep->dumpTree(cout, " alwOut: ");
} }
void visit(AstNodeIf* nodep) override { void visit(AstNodeIf* nodep) override {
UINFO(4, " IF " << nodep << endl); UINFO(4, " IF " << nodep << endl);
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
processBlock(nodep->ifsp()); processBlock(nodep->thensp());
processBlock(nodep->elsesp()); processBlock(nodep->elsesp());
} }
@ -713,14 +713,14 @@ public:
// Put a placeholder node into stmtp to track our position. // Put a placeholder node into stmtp to track our position.
// We'll strip these out after the blocks are fully cloned. // We'll strip these out after the blocks are fully cloned.
AstSplitPlaceholder* const placeholderp = makePlaceholderp(); AstSplitPlaceholder* const placeholderp = makePlaceholderp();
alwaysp->addStmtp(placeholderp); alwaysp->addStmtsp(placeholderp);
m_addAfter[color] = placeholderp; m_addAfter[color] = placeholderp;
m_newBlocksp->push_back(alwaysp); m_newBlocksp->push_back(alwaysp);
} }
// Scan the body of the always. We'll handle if/else // Scan the body of the always. We'll handle if/else
// specially, everything else is a leaf node that we can // specially, everything else is a leaf node that we can
// just clone into one of the split always blocks. // just clone into one of the split always blocks.
iterateAndNextNull(m_origAlwaysp->bodysp()); iterateAndNextNull(m_origAlwaysp->stmtsp());
} }
protected: protected:
@ -776,7 +776,7 @@ protected:
m_addAfter[color] = if_placeholderp; m_addAfter[color] = if_placeholderp;
} }
iterateAndNextNull(nodep->ifsp()); iterateAndNextNull(nodep->thensp());
for (const auto& color : colors) m_addAfter[color] = clones[color]->elsesp(); for (const auto& color : colors) m_addAfter[color] = clones[color]->elsesp();
@ -804,7 +804,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor {
VL_RESTORER(m_isPure); VL_RESTORER(m_isPure);
m_isPure = true; m_isPure = true;
iterateChildren(nodep); iterateChildren(nodep);
if (!nodep->ifsp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack()); if (!nodep->thensp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack());
} }
void visit(AstAlways* nodep) override { void visit(AstAlways* nodep) override {
VL_RESTORER(m_isPure); VL_RESTORER(m_isPure);
@ -812,7 +812,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor {
iterateChildren(nodep); iterateChildren(nodep);
if (m_isPure) { if (m_isPure) {
bool emptyOrCommentOnly = true; bool emptyOrCommentOnly = true;
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
// If this always block contains only AstComment, remove here. // If this always block contains only AstComment, remove here.
// V3Gate will remove anyway. // V3Gate will remove anyway.
if (!VN_IS(bodysp, Comment)) { if (!VN_IS(bodysp, Comment)) {
@ -955,7 +955,7 @@ protected:
void visit(AstAlways* nodep) override { void visit(AstAlways* nodep) override {
// build the scoreboard // build the scoreboard
scoreboardClear(); scoreboardClear();
scanBlock(nodep->bodysp()); scanBlock(nodep->stmtsp());
if (m_noReorderWhy != "") { if (m_noReorderWhy != "") {
// We saw a jump or something else rare that we don't handle. // We saw a jump or something else rare that we don't handle.
@ -989,7 +989,7 @@ protected:
m_curIfConditional = nodep; m_curIfConditional = nodep;
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
m_curIfConditional = nullptr; m_curIfConditional = nullptr;
scanBlock(nodep->ifsp()); scanBlock(nodep->thensp());
scanBlock(nodep->elsesp()); scanBlock(nodep->elsesp());
} }

View File

@ -191,16 +191,16 @@ struct SplitVarImpl {
template <class T_ALWAYSLIKE> template <class T_ALWAYSLIKE>
void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) { void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) {
if (ap->isJustOneBodyStmt() && ap->bodysp() == stmtp) { if (ap->isJustOneBodyStmt() && ap->stmtsp() == stmtp) {
stmtp->unlinkFrBack(); stmtp->unlinkFrBack();
// Insert begin-end because temp value may be inserted to this block later. // Insert begin-end because temp value may be inserted to this block later.
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1)); const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1));
ap->addStmtp(new AstBegin{ap->fileline(), name, stmtp}); ap->addStmtsp(new AstBegin{ap->fileline(), name, stmtp});
} }
} }
void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) { void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) {
if (initp->isJustOneBodyStmt() && initp->bodysp() == stmtp) { if (initp->isJustOneBodyStmt() && initp->stmtsp() == stmtp) {
stmtp->unlinkFrBack(); stmtp->unlinkFrBack();
// Insert begin-end because temp value may be inserted to this block later. // Insert begin-end because temp value may be inserted to this block later.
FileLine* const fl = initp->fileline(); FileLine* const fl = initp->fileline();
@ -477,7 +477,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl {
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
setContextAndIterate(nodep, nodep->sensesp()); setContextAndIterate(nodep, nodep->sensesp());
} }
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
iterate(bodysp); iterate(bodysp);
} }
}; };
@ -485,7 +485,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl {
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
setContextAndIterate(nodep, nodep->sensesp()); setContextAndIterate(nodep, nodep->sensesp());
} }
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) { for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
iterate(bodysp); iterate(bodysp);
} }
} }

View File

@ -141,7 +141,7 @@ private:
{ {
m_counting = false; m_counting = false;
m_instrs = 0.0; m_instrs = 0.0;
iterateAndNextConstNull(nodep->ifsp()); iterateAndNextConstNull(nodep->thensp());
ifInstrs = m_instrs; ifInstrs = m_instrs;
} }
} }
@ -158,7 +158,7 @@ private:
// Now collect the stats // Now collect the stats
if (m_counting) { if (m_counting) {
if (ifInstrs >= elseInstrs) { if (ifInstrs >= elseInstrs) {
iterateAndNextConstNull(nodep->ifsp()); iterateAndNextConstNull(nodep->thensp());
} else { } else {
iterateAndNextConstNull(nodep->elsesp()); iterateAndNextConstNull(nodep->elsesp());
} }

View File

@ -253,9 +253,9 @@ private:
AstVar* const indexVarp AstVar* const indexVarp
= new AstVar{fl, VVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables), = new AstVar{fl, VVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables),
VFlagBitPacked{}, static_cast<int>(m_inWidthBits)}; VFlagBitPacked{}, static_cast<int>(m_inWidthBits)};
m_modp->addStmtp(indexVarp); m_modp->addStmtsp(indexVarp);
AstVarScope* const indexVscp = new AstVarScope{indexVarp->fileline(), m_scopep, indexVarp}; AstVarScope* const indexVscp = new AstVarScope{indexVarp->fileline(), m_scopep, indexVarp};
m_scopep->addVarp(indexVscp); m_scopep->addVarsp(indexVscp);
// The 'output assigned' table builder // The 'output assigned' table builder
TableBuilder outputAssignedTableBuilder{fl}; TableBuilder outputAssignedTableBuilder{fl};
@ -274,8 +274,8 @@ private:
// Link it in. // Link it in.
// Keep sensitivity list, but delete all else // Keep sensitivity list, but delete all else
nodep->bodysp()->unlinkFrBackWithNext()->deleteTree(); nodep->stmtsp()->unlinkFrBackWithNext()->deleteTree();
nodep->addStmtp(stmtsp); nodep->addStmtsp(stmtsp);
if (debug() >= 6) nodep->dumpTree(cout, " table_new: "); if (debug() >= 6) nodep->dumpTree(cout, " table_new: ");
} }

View File

@ -250,7 +250,7 @@ private:
} }
UASSERT_OBJ(m_ctorp, nodep, "class constructor missing"); // LinkDot always makes it UASSERT_OBJ(m_ctorp, nodep, "class constructor missing"); // LinkDot always makes it
for (AstInitialAutomatic* initialp : m_initialps) { for (AstInitialAutomatic* initialp : m_initialps) {
if (AstNode* const newp = initialp->bodysp()) { if (AstNode* const newp = initialp->stmtsp()) {
newp->unlinkFrBackWithNext(); newp->unlinkFrBackWithNext();
if (!m_ctorp->stmtsp()) { if (!m_ctorp->stmtsp()) {
m_ctorp->addStmtsp(newp); m_ctorp->addStmtsp(newp);
@ -371,7 +371,7 @@ private:
newvarp->funcLocal(true); newvarp->funcLocal(true);
funcp->addInitsp(newvarp); funcp->addInitsp(newvarp);
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
m_scopep->addVarp(newvscp); m_scopep->addVarsp(newvscp);
return newvscp; return newvscp;
} }
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, VBasicDTypeKwd kwd) { AstVarScope* createInputVar(AstCFunc* funcp, const string& name, VBasicDTypeKwd kwd) {
@ -381,7 +381,7 @@ private:
newvarp->direction(VDirection::INPUT); newvarp->direction(VDirection::INPUT);
funcp->addArgsp(newvarp); funcp->addArgsp(newvarp);
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
m_scopep->addVarp(newvscp); m_scopep->addVarsp(newvscp);
return newvscp; return newvscp;
} }
AstVarScope* createVarScope(AstVar* invarp, const string& name) { AstVarScope* createVarScope(AstVar* invarp, const string& name) {
@ -397,9 +397,9 @@ private:
= new AstVar{invarp->fileline(), VVarType::BLOCKTEMP, name, invarp}; = new AstVar{invarp->fileline(), VVarType::BLOCKTEMP, name, invarp};
newvarp->funcLocal(false); newvarp->funcLocal(false);
newvarp->propagateAttrFrom(invarp); newvarp->propagateAttrFrom(invarp);
m_modp->addStmtp(newvarp); m_modp->addStmtsp(newvarp);
AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp}; AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp};
m_scopep->addVarp(newvscp); m_scopep->addVarsp(newvscp);
return newvscp; return newvscp;
} }
} }
@ -766,7 +766,7 @@ private:
funcp->protect(false); funcp->protect(false);
funcp->cname(nodep->cname()); funcp->cname(nodep->cname());
// Add DPI Export to top, since it's a global function // Add DPI Export to top, since it's a global function
m_topScopep->scopep()->addActivep(funcp); m_topScopep->scopep()->addBlocksp(funcp);
{ // Create dispatch wrapper { // Create dispatch wrapper
// Note this function may dispatch to myfunc on a different class. // Note this function may dispatch to myfunc on a different class.
@ -855,9 +855,9 @@ private:
// doesn't rip up the variables on us // doesn't rip up the variables on us
args += ");\n"; args += ");\n";
AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)("); AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)(");
newp->addBodysp(argnodesp); newp->addExprsp(argnodesp);
VL_DANGLING(argnodesp); VL_DANGLING(argnodesp);
newp->addBodysp(new AstText(nodep->fileline(), args, true)); newp->addExprsp(new AstText(nodep->fileline(), args, true));
funcp->addStmtsp(newp); funcp->addStmtsp(newp);
} }
@ -899,7 +899,7 @@ private:
funcp->protect(false); funcp->protect(false);
funcp->pure(nodep->pure()); funcp->pure(nodep->pure());
// Add DPI Import to top, since it's a global function // Add DPI Import to top, since it's a global function
m_topScopep->scopep()->addActivep(funcp); m_topScopep->scopep()->addBlocksp(funcp);
makePortList(nodep, funcp); makePortList(nodep, funcp);
return funcp; return funcp;
} }
@ -1064,9 +1064,9 @@ private:
FileLine* const fl = m_topScopep->fileline(); FileLine* const fl = m_topScopep->fileline();
AstVar* const varp AstVar* const varp
= new AstVar{fl, VVarType::VAR, "__Vdpi_export_trigger", VFlagBitPacked{}, 1}; = new AstVar{fl, VVarType::VAR, "__Vdpi_export_trigger", VFlagBitPacked{}, 1};
m_topScopep->scopep()->modp()->addStmtp(varp); m_topScopep->scopep()->modp()->addStmtsp(varp);
dpiExportTriggerp = new AstVarScope{fl, m_topScopep->scopep(), varp}; dpiExportTriggerp = new AstVarScope{fl, m_topScopep->scopep(), varp};
m_topScopep->scopep()->addVarp(dpiExportTriggerp); m_topScopep->scopep()->addVarsp(dpiExportTriggerp);
v3Global.rootp()->dpiExportTriggerp(dpiExportTriggerp); v3Global.rootp()->dpiExportTriggerp(dpiExportTriggerp);
} }
return dpiExportTriggerp; return dpiExportTriggerp;
@ -1134,7 +1134,7 @@ private:
AstVarScope* rtnvscp = nullptr; AstVarScope* rtnvscp = nullptr;
if (rtnvarp) { if (rtnvarp) {
rtnvscp = new AstVarScope(rtnvarp->fileline(), m_scopep, rtnvarp); rtnvscp = new AstVarScope(rtnvarp->fileline(), m_scopep, rtnvarp);
m_scopep->addVarp(rtnvscp); m_scopep->addVarsp(rtnvscp);
rtnvarp->user2p(rtnvscp); rtnvarp->user2p(rtnvscp);
} }
@ -1228,7 +1228,7 @@ private:
} }
AstVarScope* const newvscp AstVarScope* const newvscp
= new AstVarScope{portp->fileline(), m_scopep, portp}; = new AstVarScope{portp->fileline(), m_scopep, portp};
m_scopep->addVarp(newvscp); m_scopep->addVarsp(newvscp);
portp->user2p(newvscp); portp->user2p(newvscp);
} }
} }
@ -1314,9 +1314,9 @@ private:
new AstVarRef{fl, dpiExportTriggerp, VAccess::READ}}}, new AstVarRef{fl, dpiExportTriggerp, VAccess::READ}}},
nullptr}; nullptr};
for (AstVarScope* const varScopep : writtenps) { for (AstVarScope* const varScopep : writtenps) {
alwaysp->addStmtp(new AstDpiExportUpdated{fl, varScopep}); alwaysp->addStmtsp(new AstDpiExportUpdated{fl, varScopep});
} }
m_scopep->addActivep(alwaysp); m_scopep->addBlocksp(alwaysp);
} }
} }
@ -1516,7 +1516,7 @@ private:
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
// Body insert just before themselves // Body insert just before themselves
m_insStmtp = nullptr; // First thing should be new statement m_insStmtp = nullptr; // First thing should be new statement
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
iterateAndNextNull(nodep->incsp()); iterateAndNextNull(nodep->incsp());
// Done the loop // Done the loop
m_insStmtp = nullptr; // Next thing should be new statement m_insStmtp = nullptr; // Next thing should be new statement

View File

@ -454,9 +454,9 @@ private:
v3Global.rootp()->typeTablep()->addTypesp(newArrDtp); v3Global.rootp()->typeTablep()->addTypesp(newArrDtp);
AstVar* const newvarp AstVar* const newvarp
= new AstVar(flp, VVarType::MODULETEMP, "__Vm_traceActivity", newArrDtp); = new AstVar(flp, VVarType::MODULETEMP, "__Vm_traceActivity", newArrDtp);
m_topModp->addStmtp(newvarp); m_topModp->addStmtsp(newvarp);
AstVarScope* const newvscp = new AstVarScope(flp, m_topScopep, newvarp); AstVarScope* const newvscp = new AstVarScope(flp, m_topScopep, newvarp);
m_topScopep->addVarp(newvscp); m_topScopep->addVarsp(newvscp);
m_activityVscp = newvscp; m_activityVscp = newvscp;
// Insert activity setters // Insert activity setters
@ -493,7 +493,7 @@ private:
funcp->slow(full); funcp->slow(full);
funcp->isStatic(isTopFunc); funcp->isStatic(isTopFunc);
// Add it to top scope // Add it to top scope
m_topScopep->addActivep(funcp); m_topScopep->addBlocksp(funcp);
const auto addInitStr = [funcp, flp](const string& str) -> void { const auto addInitStr = [funcp, flp](const string& str) -> void {
funcp->addInitsp(new AstCStmt(flp, str)); funcp->addInitsp(new AstCStmt(flp, str));
}; };
@ -676,7 +676,7 @@ private:
// Add TraceInc node // Add TraceInc node
AstTraceInc* const incp AstTraceInc* const incp
= new AstTraceInc(declp->fileline(), declp, /* full: */ false, baseCode); = new AstTraceInc(declp->fileline(), declp, /* full: */ false, baseCode);
ifp->addIfsp(incp); ifp->addThensp(incp);
subStmts += incp->nodeCount(); subStmts += incp->nodeCount();
// Track partitioning // Track partitioning
@ -698,7 +698,7 @@ private:
cleanupFuncp->slow(false); cleanupFuncp->slow(false);
cleanupFuncp->isStatic(true); cleanupFuncp->isStatic(true);
cleanupFuncp->isLoose(true); cleanupFuncp->isLoose(true);
m_topScopep->addActivep(cleanupFuncp); m_topScopep->addBlocksp(cleanupFuncp);
cleanupFuncp->addInitsp(new AstCStmt(fl, voidSelfAssign(m_topModp))); cleanupFuncp->addInitsp(new AstCStmt(fl, voidSelfAssign(m_topModp)));
cleanupFuncp->addInitsp(new AstCStmt(fl, symClassAssign())); cleanupFuncp->addInitsp(new AstCStmt(fl, symClassAssign()));
@ -755,7 +755,7 @@ private:
m_regFuncp->slow(true); m_regFuncp->slow(true);
m_regFuncp->isStatic(false); m_regFuncp->isStatic(false);
m_regFuncp->isLoose(true); m_regFuncp->isLoose(true);
m_topScopep->addActivep(m_regFuncp); m_topScopep->addBlocksp(m_regFuncp);
// Create the full dump functions, also allocates signal numbers // Create the full dump functions, also allocates signal numbers
createFullTraceFunction(traces, nFullCodes, m_parallelism); createFullTraceFunction(traces, nFullCodes, m_parallelism);

View File

@ -162,7 +162,7 @@ private:
funcp->isStatic(false); funcp->isStatic(false);
funcp->isLoose(true); funcp->isLoose(true);
funcp->slow(true); funcp->slow(true);
topScopep->addActivep(funcp); topScopep->addBlocksp(funcp);
return funcp; return funcp;
} }
@ -303,8 +303,8 @@ private:
scopeName = scopeName.substr(0, lastDot + 1); scopeName = scopeName.substr(0, lastDot + 1);
const size_t scopeLen = scopeName.length(); const size_t scopeLen = scopeName.length();
UASSERT_OBJ(cellp->intfRefp(), cellp, "Interface without tracing reference"); UASSERT_OBJ(cellp->intfRefsp(), cellp, "Interface without tracing reference");
for (AstIntfRef *irp = cellp->intfRefp(), *nextIrp; irp; irp = nextIrp) { for (AstIntfRef *irp = cellp->intfRefsp(), *nextIrp; irp; irp = nextIrp) {
nextIrp = VN_AS(irp->nextp(), IntfRef); nextIrp = VN_AS(irp->nextp(), IntfRef);
const string irpName = irp->prettyName(); const string irpName = irp->prettyName();

View File

@ -422,7 +422,7 @@ class TristateVisitor final : public TristateBaseVisitor {
"Unsupported: Creating tristate signal not underneath a module: " "Unsupported: Creating tristate signal not underneath a module: "
<< nodep->prettyNameQ()); << nodep->prettyNameQ());
} else { } else {
m_modp->addStmtp(newp); m_modp->addStmtsp(newp);
} }
} }
void associateLogic(AstNode* fromp, AstNode* top) { void associateLogic(AstNode* fromp, AstNode* top) {
@ -554,7 +554,7 @@ class TristateVisitor final : public TristateBaseVisitor {
AstNode* const newp = new AstAssignW(varp->fileline(), varrefp, constp); AstNode* const newp = new AstAssignW(varp->fileline(), varrefp, constp);
UINFO(9, " newoev " << newp << endl); UINFO(9, " newoev " << newp << endl);
varrefp->user1p(newAllZerosOrOnes(varp, false)); varrefp->user1p(newAllZerosOrOnes(varp, false));
nodep->addStmtp(newp); nodep->addStmtsp(newp);
mapInsertLhsVarRef(varrefp); // insertTristates will convert mapInsertLhsVarRef(varrefp); // insertTristates will convert
// // to a varref to the __out# variable // // to a varref to the __out# variable
} }
@ -627,7 +627,7 @@ class TristateVisitor final : public TristateBaseVisitor {
lhsp->name() + "__out" + cvtToStr(m_unique), lhsp->name() + "__out" + cvtToStr(m_unique),
VFlagBitPacked(), w); // 2-state ok; sep enable VFlagBitPacked(), w); // 2-state ok; sep enable
UINFO(9, " newout " << newlhsp << endl); UINFO(9, " newout " << newlhsp << endl);
nodep->addStmtp(newlhsp); nodep->addStmtsp(newlhsp);
refp->varp(newlhsp); // assign the new var to the varref refp->varp(newlhsp); // assign the new var to the varref
refp->name(newlhsp->name()); refp->name(newlhsp->name());
@ -636,13 +636,13 @@ class TristateVisitor final : public TristateBaseVisitor {
lhsp->name() + "__en" + cvtToStr(m_unique++), lhsp->name() + "__en" + cvtToStr(m_unique++),
VFlagBitPacked(), w); // 2-state ok VFlagBitPacked(), w); // 2-state ok
UINFO(9, " newenp " << newenp << endl); UINFO(9, " newenp " << newenp << endl);
nodep->addStmtp(newenp); nodep->addStmtsp(newenp);
AstNode* const enassp = new AstAssignW( AstNode* const enassp = new AstAssignW(
refp->fileline(), new AstVarRef(refp->fileline(), newenp, VAccess::WRITE), refp->fileline(), new AstVarRef(refp->fileline(), newenp, VAccess::WRITE),
getEnp(refp)); getEnp(refp));
UINFO(9, " newass " << enassp << endl); UINFO(9, " newass " << enassp << endl);
nodep->addStmtp(enassp); nodep->addStmtsp(enassp);
// now append this driver to the driver logic. // now append this driver to the driver logic.
AstNode* const ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ); AstNode* const ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ);
@ -675,7 +675,7 @@ class TristateVisitor final : public TristateBaseVisitor {
VL_DO_DANGLING(undrivenp->deleteTree(), undrivenp); VL_DO_DANGLING(undrivenp->deleteTree(), undrivenp);
} }
if (envarp) { if (envarp) {
nodep->addStmtp(new AstAssignW( nodep->addStmtsp(new AstAssignW(
enp->fileline(), new AstVarRef(envarp->fileline(), envarp, VAccess::WRITE), enp)); enp->fileline(), new AstVarRef(envarp->fileline(), envarp, VAccess::WRITE), enp));
} }
// __out (child) or <in> (parent) = drive-value expression // __out (child) or <in> (parent) = drive-value expression
@ -683,7 +683,7 @@ class TristateVisitor final : public TristateBaseVisitor {
lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, VAccess::WRITE), orp); lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, VAccess::WRITE), orp);
assp->user2(U2_BOTH); // Don't process further; already resolved assp->user2(U2_BOTH); // Don't process further; already resolved
if (debug() >= 9) assp->dumpTree(cout, "-lhsp-eqn: "); if (debug() >= 9) assp->dumpTree(cout, "-lhsp-eqn: ");
nodep->addStmtp(assp); nodep->addStmtsp(assp);
} }
void addToAssignmentList(AstAssignW* nodep) { void addToAssignmentList(AstAssignW* nodep) {
@ -864,11 +864,11 @@ class TristateVisitor final : public TristateBaseVisitor {
if (m_graphing) { if (m_graphing) {
iterateChildren(nodep); iterateChildren(nodep);
if (m_alhs) { if (m_alhs) {
associateLogic(nodep, nodep->expr1p()); associateLogic(nodep, nodep->thenp());
associateLogic(nodep, nodep->expr2p()); associateLogic(nodep, nodep->elsep());
} else { } else {
associateLogic(nodep->expr1p(), nodep); associateLogic(nodep->thenp(), nodep);
associateLogic(nodep->expr2p(), nodep); associateLogic(nodep->elsep(), nodep);
} }
} else { } else {
if (m_alhs && nodep->user1p()) { if (m_alhs && nodep->user1p()) {
@ -887,20 +887,20 @@ class TristateVisitor final : public TristateBaseVisitor {
condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with " condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with "
"tristate logic in the conditional expression"); "tristate logic in the conditional expression");
} }
AstNode* const expr1p = nodep->expr1p(); AstNode* const thenp = nodep->thenp();
AstNode* const expr2p = nodep->expr2p(); AstNode* const elsep = nodep->elsep();
if (expr1p->user1p() || expr2p->user1p()) { // else no tristates if (thenp->user1p() || elsep->user1p()) { // else no tristates
m_tgraph.didProcess(nodep); m_tgraph.didProcess(nodep);
AstNode* const en1p = getEnp(expr1p); AstNode* const en1p = getEnp(thenp);
AstNode* const en2p = getEnp(expr2p); AstNode* const en2p = getEnp(elsep);
// The output enable of a cond is a cond of the output enable of the // The output enable of a cond is a cond of the output enable of the
// two expressions with the same conditional. // two expressions with the same conditional.
AstNode* const enp AstNode* const enp
= new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p); = new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p);
UINFO(9, " newcond " << enp << endl); UINFO(9, " newcond " << enp << endl);
nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable) nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable)
expr1p->user1p(nullptr); thenp->user1p(nullptr);
expr2p->user1p(nullptr); elsep->user1p(nullptr);
} }
} }
} }
@ -1391,7 +1391,7 @@ class TristateVisitor final : public TristateBaseVisitor {
UINFO(9, " newpin " << enpinp << endl); UINFO(9, " newpin " << enpinp << endl);
enpinp->user2(U2_BOTH); // don't iterate the pin later enpinp->user2(U2_BOTH); // don't iterate the pin later
nodep->addNextHere(enpinp); nodep->addNextHere(enpinp);
m_modp->addStmtp(enVarp); m_modp->addStmtsp(enVarp);
enrefp = new AstVarRef(nodep->fileline(), enVarp, VAccess::READ); enrefp = new AstVarRef(nodep->fileline(), enVarp, VAccess::READ);
UINFO(9, " newvrf " << enrefp << endl); UINFO(9, " newvrf " << enrefp << endl);
if (debug() >= 9) enpinp->dumpTree(cout, "-pin-ena: "); if (debug() >= 9) enpinp->dumpTree(cout, "-pin-ena: ");
@ -1608,7 +1608,7 @@ class TristateVisitor final : public TristateBaseVisitor {
void visit(AstCaseItem* nodep) override { void visit(AstCaseItem* nodep) override {
// don't deal with casez compare '???? values // don't deal with casez compare '???? values
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
} }
void visit(AstCell* nodep) override { void visit(AstCell* nodep) override {

View File

@ -120,7 +120,7 @@ private:
} else { } else {
AstVar* const varp AstVar* const varp
= new AstVar(fl, VVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep()); = new AstVar(fl, VVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep());
m_modp->addStmtp(varp); m_modp->addStmtsp(varp);
AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep' AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep'
prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE)); prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE));
AstIf* const newp = new AstIf( AstIf* const newp = new AstIf(
@ -173,7 +173,7 @@ private:
m_constXCvt = false; // Avoid losing the X's in casex m_constXCvt = false; // Avoid losing the X's in casex
iterateAndNextNull(nodep->condsp()); iterateAndNextNull(nodep->condsp());
m_constXCvt = true; m_constXCvt = true;
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->stmtsp());
} }
} }
void visit(AstNodeDType* nodep) override { void visit(AstNodeDType* nodep) override {
@ -353,9 +353,9 @@ private:
// Add inits in front of other statement. // Add inits in front of other statement.
// In the future, we should stuff the initp into the module's constructor. // In the future, we should stuff the initp into the module's constructor.
AstNode* const afterp = m_modp->stmtsp()->unlinkFrBackWithNext(); AstNode* const afterp = m_modp->stmtsp()->unlinkFrBackWithNext();
m_modp->addStmtp(newvarp); m_modp->addStmtsp(newvarp);
m_modp->addStmtp(newinitp); m_modp->addStmtsp(newinitp);
m_modp->addStmtp(afterp); m_modp->addStmtsp(afterp);
if (debug() >= 9) newref1p->dumpTree(cout, " _new: "); if (debug() >= 9) newref1p->dumpTree(cout, " _new: ");
if (debug() >= 9) newvarp->dumpTree(cout, " _new: "); if (debug() >= 9) newvarp->dumpTree(cout, " _new: ");
if (debug() >= 9) newinitp->dumpTree(cout, " _new: "); if (debug() >= 9) newinitp->dumpTree(cout, " _new: ");

View File

@ -387,21 +387,21 @@ private:
if (nodep->backp()->nextp() == nodep) initp = nodep->backp(); if (nodep->backp()->nextp() == nodep) initp = nodep->backp();
// Grab assignment // Grab assignment
AstNode* incp = nullptr; // Should be last statement AstNode* incp = nullptr; // Should be last statement
AstNode* bodysp = nodep->bodysp(); AstNode* stmtsp = nodep->stmtsp();
if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp()); if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp());
// cppcheck-suppress duplicateCondition // cppcheck-suppress duplicateCondition
if (nodep->incsp()) { if (nodep->incsp()) {
incp = nodep->incsp(); incp = nodep->incsp();
} else { } else {
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {}
if (incp) VL_DO_DANGLING(V3Const::constifyEdit(incp), incp); if (incp) VL_DO_DANGLING(V3Const::constifyEdit(incp), incp);
// Again, as may have changed // Again, as may have changed
bodysp = nodep->bodysp(); stmtsp = nodep->stmtsp();
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {}
if (incp == bodysp) bodysp = nullptr; if (incp == stmtsp) stmtsp = nullptr;
} }
// And check it // And check it
if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, bodysp)) { if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, stmtsp)) {
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
} }
} }
@ -426,7 +426,7 @@ private:
// deleted by V3Const. // deleted by V3Const.
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
} else if (forUnrollCheck(nodep, nodep->initsp(), nullptr, nodep->condp(), } else if (forUnrollCheck(nodep, nodep->initsp(), nullptr, nodep->condp(),
nodep->incsp(), nodep->bodysp())) { nodep->incsp(), nodep->stmtsp())) {
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
} else { } else {
nodep->v3error("For loop doesn't have genvar index, or is malformed"); nodep->v3error("For loop doesn't have genvar index, or is malformed");

View File

@ -188,7 +188,7 @@ class VariableOrder final {
stmtsp->unlinkFrBackWithNext(); stmtsp->unlinkFrBackWithNext();
AstNode::addNext<AstNode, AstNode>(firstp, stmtsp); AstNode::addNext<AstNode, AstNode>(firstp, stmtsp);
} }
modp->addStmtp(firstp); modp->addStmtsp(firstp);
} }
} }

View File

@ -462,22 +462,22 @@ private:
iterateCheckBool(nodep, "Conditional Test", nodep->condp(), BOTH); iterateCheckBool(nodep, "Conditional Test", nodep->condp(), BOTH);
// Determine sub expression widths only relying on what's in the subops // Determine sub expression widths only relying on what's in the subops
// CONTEXT determined, but need data type for pattern assignments // CONTEXT determined, but need data type for pattern assignments
userIterateAndNext(nodep->expr1p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); userIterateAndNext(nodep->thenp(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
userIterateAndNext(nodep->expr2p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p()); userIterateAndNext(nodep->elsep(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
// Calculate width of this expression. // Calculate width of this expression.
// First call (prelim()) m_vup->width() is probably zero, so we'll return // First call (prelim()) m_vup->width() is probably zero, so we'll return
// the size of this subexpression only. // the size of this subexpression only.
// Second call (final()) m_vup->width() is probably the expression size, so // Second call (final()) m_vup->width() is probably the expression size, so
// the expression includes the size of the output too. // the expression includes the size of the output too.
if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) { if (nodep->thenp()->isDouble() || nodep->elsep()->isDouble()) {
nodep->dtypeSetDouble(); nodep->dtypeSetDouble();
} else if (nodep->expr1p()->isString() || nodep->expr2p()->isString()) { } else if (nodep->thenp()->isString() || nodep->elsep()->isString()) {
nodep->dtypeSetString(); nodep->dtypeSetString();
} else { } else {
const int width = std::max(nodep->expr1p()->width(), nodep->expr2p()->width()); const int width = std::max(nodep->thenp()->width(), nodep->elsep()->width());
const int mwidth const int mwidth
= std::max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin()); = std::max(nodep->thenp()->widthMin(), nodep->elsep()->widthMin());
const bool issigned = nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned(); const bool issigned = nodep->thenp()->isSigned() && nodep->elsep()->isSigned();
nodep->dtypeSetLogicUnsized(width, mwidth, VSigning::fromBool(issigned)); nodep->dtypeSetLogicUnsized(width, mwidth, VSigning::fromBool(issigned));
} }
} }
@ -486,9 +486,9 @@ private:
AstNodeDType* const subDTypep = expDTypep; AstNodeDType* const subDTypep = expDTypep;
nodep->dtypeFrom(expDTypep); nodep->dtypeFrom(expDTypep);
// Error report and change sizes for suboperands of this node. // Error report and change sizes for suboperands of this node.
iterateCheck(nodep, "Conditional True", nodep->expr1p(), CONTEXT, FINAL, subDTypep, iterateCheck(nodep, "Conditional True", nodep->thenp(), CONTEXT, FINAL, subDTypep,
EXTEND_EXP); EXTEND_EXP);
iterateCheck(nodep, "Conditional False", nodep->expr2p(), CONTEXT, FINAL, subDTypep, iterateCheck(nodep, "Conditional False", nodep->elsep(), CONTEXT, FINAL, subDTypep,
EXTEND_EXP); EXTEND_EXP);
} }
} }
@ -1834,7 +1834,7 @@ private:
castSized(nodep, nodep->fromp(), width); castSized(nodep, nodep->fromp(), width);
// Note castSized might modify nodep->fromp() // Note castSized might modify nodep->fromp()
} else { } else {
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, fromDtp, EXTEND_EXP, iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, fromDtp, EXTEND_EXP,
false); false);
} }
if (basicp->isDouble() && !nodep->fromp()->isDouble()) { if (basicp->isDouble() && !nodep->fromp()->isDouble()) {
@ -1866,14 +1866,14 @@ private:
<< toDtp->prettyDTypeNameQ()); << toDtp->prettyDTypeNameQ());
} }
if (!newp) newp = nodep->fromp()->unlinkFrBack(); if (!newp) newp = nodep->fromp()->unlinkFrBack();
nodep->lhsp(newp); nodep->fromp(newp);
// if (debug()) nodep->dumpTree(cout, " CastOut: "); // if (debug()) nodep->dumpTree(cout, " CastOut: ");
// if (debug()) nodep->backp()->dumpTree(cout, " CastOutUpUp: "); // if (debug()) nodep->backp()->dumpTree(cout, " CastOutUpUp: ");
} }
if (m_vup->final()) { if (m_vup->final()) {
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(), iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(),
EXTEND_EXP, false); EXTEND_EXP, false);
AstNode* const underp = nodep->lhsp()->unlinkFrBack(); AstNode* const underp = nodep->fromp()->unlinkFrBack();
// if (debug()) underp->dumpTree(cout, " CastRep: "); // if (debug()) underp->dumpTree(cout, " CastRep: ");
nodep->replaceWith(underp); nodep->replaceWith(underp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
@ -3972,7 +3972,7 @@ private:
userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT, PRELIM).p()); userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT, PRELIM).p());
for (AstCaseItem *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) { for (AstCaseItem *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip = VN_AS(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced nextip = VN_AS(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced
if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), nullptr); if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->stmtsp(), nullptr);
for (AstNode *nextcp, *condp = itemp->condsp(); condp; condp = nextcp) { for (AstNode *nextcp, *condp = itemp->condsp(); condp; condp = nextcp) {
nextcp = condp->nextp(); // Prelim may cause the node to get replaced nextcp = condp->nextp(); // Prelim may cause the node to get replaced
VL_DO_DANGLING(userIterate(condp, WidthVP(CONTEXT, PRELIM).p()), condp); VL_DO_DANGLING(userIterate(condp, WidthVP(CONTEXT, PRELIM).p()), condp);
@ -4015,27 +4015,27 @@ private:
userIterateAndNext(nodep->initsp(), nullptr); userIterateAndNext(nodep->initsp(), nullptr);
iterateCheckBool(nodep, "For Test Condition", nodep->condp(), iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
BOTH); // it's like an if() condition. BOTH); // it's like an if() condition.
if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->bodysp(), nullptr); if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->stmtsp(), nullptr);
userIterateAndNext(nodep->incsp(), nullptr); userIterateAndNext(nodep->incsp(), nullptr);
} }
void visit(AstRepeat* nodep) override { void visit(AstRepeat* nodep) override {
assertAtStatement(nodep); assertAtStatement(nodep);
userIterateAndNext(nodep->countp(), WidthVP(SELF, BOTH).p()); userIterateAndNext(nodep->countp(), WidthVP(SELF, BOTH).p());
userIterateAndNext(nodep->bodysp(), nullptr); userIterateAndNext(nodep->stmtsp(), nullptr);
} }
void visit(AstWhile* nodep) override { void visit(AstWhile* nodep) override {
assertAtStatement(nodep); assertAtStatement(nodep);
userIterateAndNext(nodep->precondsp(), nullptr); userIterateAndNext(nodep->precondsp(), nullptr);
iterateCheckBool(nodep, "For Test Condition", nodep->condp(), iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
BOTH); // it's like an if() condition. BOTH); // it's like an if() condition.
userIterateAndNext(nodep->bodysp(), nullptr); userIterateAndNext(nodep->stmtsp(), nullptr);
userIterateAndNext(nodep->incsp(), nullptr); userIterateAndNext(nodep->incsp(), nullptr);
} }
void visit(AstNodeIf* nodep) override { void visit(AstNodeIf* nodep) override {
assertAtStatement(nodep); assertAtStatement(nodep);
// if (debug()) nodep->dumpTree(cout, " IfPre: "); // if (debug()) nodep->dumpTree(cout, " IfPre: ");
if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly
userIterateAndNext(nodep->ifsp(), nullptr); userIterateAndNext(nodep->thensp(), nullptr);
userIterateAndNext(nodep->elsesp(), nullptr); userIterateAndNext(nodep->elsesp(), nullptr);
} }
iterateCheckBool(nodep, "If", nodep->condp(), BOTH); // it's like an if() condition. iterateCheckBool(nodep, "If", nodep->condp(), BOTH); // it's like an if() condition.
@ -4056,7 +4056,7 @@ private:
UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type"); UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type");
AstNodeDType* fromDtp = fromp->dtypep()->skipRefp(); AstNodeDType* fromDtp = fromp->dtypep()->skipRefp();
// Split into for loop // Split into for loop
AstNode* bodyp = nodep->bodysp(); // Might be null AstNode* bodyp = nodep->stmtsp(); // Might be null
if (bodyp) bodyp->unlinkFrBackWithNext(); if (bodyp) bodyp->unlinkFrBackWithNext();
// We record where the body needs to eventually go with bodyPointp // We record where the body needs to eventually go with bodyPointp
// (Can't use bodyp as might be null) // (Can't use bodyp as might be null)
@ -4348,8 +4348,8 @@ private:
argp->unlinkFrBack(&handle); argp->unlinkFrBack(&handle);
AstCMath* const newp AstCMath* const newp
= new AstCMath(nodep->fileline(), "VL_TO_STRING(", 0, true); = new AstCMath(nodep->fileline(), "VL_TO_STRING(", 0, true);
newp->addBodysp(argp); newp->addExprsp(argp);
newp->addBodysp(new AstText(nodep->fileline(), ")", true)); newp->addExprsp(new AstText(nodep->fileline(), ")", true));
newp->dtypeSetString(); newp->dtypeSetString();
newp->pure(true); newp->pure(true);
newp->protect(false); newp->protect(false);
@ -6356,7 +6356,7 @@ private:
varp->isStatic(true); varp->isStatic(true);
varp->valuep(initp); varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing // Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
// Element 0 is a non-index and has speced values // Element 0 is a non-index and has speced values
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0)); initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0));
for (unsigned i = 1; i < msbdim + 1; ++i) { for (unsigned i = 1; i < msbdim + 1; ++i) {
@ -6421,7 +6421,7 @@ private:
varp->isStatic(true); varp->isStatic(true);
varp->valuep(initp); varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing // Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
// Default for all unspecified values // Default for all unspecified values
if (attrType == VAttrType::ENUM_NAME) { if (attrType == VAttrType::ENUM_NAME) {

View File

@ -24,6 +24,8 @@ class Node:
self._file = file # File this class is defined in self._file = file # File this class is defined in
self._lineno = lineno # Line this class is defined on self._lineno = lineno # Line this class is defined on
self._ordIdx = None # Ordering index of this class self._ordIdx = None # Ordering index of this class
self._arity = -1 # Arity of node
self._ops = {} # Operands of node
@property @property
def name(self): def name(self):
@ -33,6 +35,10 @@ class Node:
def superClass(self): def superClass(self):
return self._superClass return self._superClass
@property
def isRoot(self):
return self.superClass is None
@property @property
def isCompleted(self): def isCompleted(self):
return isinstance(self._subClasses, tuple) return isinstance(self._subClasses, tuple)
@ -50,6 +56,20 @@ class Node:
assert not self.isCompleted assert not self.isCompleted
self._subClasses.append(subClass) self._subClasses.append(subClass)
def addOp(self, n, name, monad, kind):
assert 1 <= n <= 4
self._ops[n] = (name, monad, kind)
self._arity = max(self._arity, n)
def getOp(self, n):
assert 1 <= n <= 4
op = self._ops.get(n, None)
if op is not None:
return op
if not self.isRoot:
return self.superClass.getOp(n)
return None
# Computes derived properties over entire class hierarchy. # Computes derived properties over entire class hierarchy.
# No more changes to the hierarchy are allowed once this was called # No more changes to the hierarchy are allowed once this was called
def complete(self, typeId=0, ordIdx=0): def complete(self, typeId=0, ordIdx=0):
@ -62,6 +82,11 @@ class Node:
self._ordIdx = ordIdx self._ordIdx = ordIdx
ordIdx = ordIdx + 1 ordIdx = ordIdx + 1
if self.isRoot:
self._arity = 0
else:
self._arity = max(self._arity, self._superClass.arity)
# Leaves # Leaves
if self.isLeaf: if self.isLeaf:
self._typeId = typeId self._typeId = typeId
@ -78,11 +103,6 @@ class Node:
assert self.isCompleted assert self.isCompleted
return self._subClasses return self._subClasses
@property
def isRoot(self):
assert self.isCompleted
return self.superClass is None
@property @property
def isLeaf(self): def isLeaf(self):
assert self.isCompleted assert self.isCompleted
@ -140,6 +160,11 @@ class Node:
assert self.isCompleted assert self.isCompleted
return self._ordIdx return self._ordIdx
@property
def arity(self):
assert self.isCompleted
return self._arity
def isSubClassOf(self, other): def isSubClassOf(self, other):
assert self.isCompleted assert self.isCompleted
if self is other: if self is other:
@ -495,6 +520,25 @@ class Cpt:
###################################################################### ######################################################################
def partitionAndStrip(string, separator):
return map(lambda _: _.strip(), string.partition(separator))
def parseOpType(string):
match = re.match(r'^(\w+)\[(\w+)\]$', string)
if match:
monad, kind = match.groups()
if monad not in ("Optional", "List"):
return None
kind = parseOpType(kind)
if not kind or kind[0]:
return None
return monad, kind[1]
if re.match(r'^Ast(\w+)$', string):
return "", string[3:]
return None
def read_types(filename): def read_types(filename):
hasErrors = False hasErrors = False
@ -539,12 +583,65 @@ def read_types(filename):
node = Node(classn, superClass, filename, lineno) node = Node(classn, superClass, filename, lineno)
superClass.addSubClass(node) superClass.addSubClass(node)
Nodes[classn] = node Nodes[classn] = node
if not node: if not node:
continue continue
if re.match(r'^\s*ASTGEN_MEMBERS_' + node.name + ';', line): if re.match(r'^\s*ASTGEN_MEMBERS_' + node.name + ';', line):
hasAstgenMembers = True hasAstgenMembers = True
match = re.match(r'^\s*//\s*@astgen\s+(.*)$', line)
if match:
decl = re.sub(r'//.*$', '', match.group(1))
what, sep, rest = partitionAndStrip(decl, ":=")
what = re.sub(r'\s+', ' ', what)
if not sep:
error(
lineno,
"Malformed '@astgen' directive (expecting '<keywords> := <description>'): "
+ decl)
elif what in ("op1", "op2", "op3", "op4"):
n = int(what[-1])
ident, sep, kind = partitionAndStrip(rest, ":")
ident = ident.strip()
if not sep or not re.match(r'^\w+$', ident):
error(
lineno, "Malformed '@astgen " + what +
"' directive (expecting '" + what +
" := <identifier> : <type>': " + decl)
else:
kind = parseOpType(kind)
if not kind:
error(
lineno, "Bad type for '@astgen " + what +
"' (expecting Ast*, Optional[Ast*], or List[Ast*]):"
+ decl)
elif node.getOp(n) is not None:
error(
lineno, "Already defined " + what + " for " +
node.name)
else:
node.addOp(n, ident, *kind)
elif what in ("alias op1", "alias op2", "alias op3",
"alias op4"):
n = int(what[-1])
ident = rest.strip()
if not re.match(r'^\w+$', ident):
error(
lineno, "Malformed '@astgen " + what +
"' directive (expecting '" + what +
" := <identifier>': " + decl)
else:
op = node.getOp(n)
if op is None:
error(lineno,
"Alaised op" + str(n) + " is not defined")
else:
node.addOp(n, ident, *op[1:])
else:
line = re.sub(r'//.*$', '', line)
if re.match(r'.*[Oo]p[1-9].*', line):
error(lineno,
"Use generated accessors to access op<N> operands")
checkFinishedNode(node) checkFinishedNode(node)
if hasErrors: if hasErrors:
sys.exit("%Error: Stopping due to errors reported above") sys.exit("%Error: Stopping due to errors reported above")
@ -614,6 +711,7 @@ def write_report(filename):
fh.write("\nClasses:\n") fh.write("\nClasses:\n")
for node in SortedNodes: for node in SortedNodes:
fh.write(" class Ast%-17s\n" % node.name) fh.write(" class Ast%-17s\n" % node.name)
fh.write(" arity: {}\n".format(node.arity))
fh.write(" parent: ") fh.write(" parent: ")
for superClass in node.allSuperClasses: for superClass in node.allSuperClasses:
if not superClass.isRoot: if not superClass.isRoot:
@ -759,6 +857,42 @@ def write_macros(filename):
''', ''',
t=node.name) t=node.name)
for n in (1, 2, 3, 4):
op = node.getOp(n)
if not op:
continue
name, monad, kind = op
retrieve = ("VN_AS(op{n}p(), {kind})" if kind != "Node" else
"op{n}p()").format(n=n, kind=kind)
if monad == "List":
emitBlock('''\
Ast{kind}* {name}() const {{ return {retrieve}; }}
void add{Name}(Ast{kind}* nodep) {{ addNOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
''',
kind=kind,
name=name,
Name=name[0].upper() + name[1:],
n=n,
retrieve=retrieve)
elif monad == "Optional":
emitBlock('''\
Ast{kind}* {name}() const {{ return {retrieve}; }}
void {name}(Ast{kind}* nodep) {{ setNOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
''',
kind=kind,
name=name,
n=n,
retrieve=retrieve)
else:
emitBlock('''\
Ast{kind}* {name}() const {{ return {retrieve}; }}
void {name}(Ast{kind}* nodep) {{ setOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
''',
kind=kind,
name=name,
n=n,
retrieve=retrieve)
fh.write( fh.write(
" static_assert(true, \"\")\n") # Swallowing the semicolon " static_assert(true, \"\")\n") # Swallowing the semicolon

View File

@ -391,9 +391,8 @@ def clean_input(filename, outname):
if not re.match(r'^\s*$', line): if not re.match(r'^\s*$', line):
sys.exit( sys.exit(
"%Error: " + filename + ":" + str(lineno) + ": Need " + "%Error: " + filename + ":" + str(lineno) + ": Need " +
needmore + str(needmore) +
" more blank lines to keep line numbers are constant\n" " more blank lines to keep line numbers constant\n")
)
needmore -= 1 needmore -= 1
else: else:
lines.append(line) lines.append(line)

View File

@ -1068,6 +1068,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
// Blank lines for type insertion // Blank lines for type insertion
// Blank lines for type insertion // Blank lines for type insertion
// Blank lines for type insertion // Blank lines for type insertion
// Blank lines for type insertion
%start source_text %start source_text
@ -1092,8 +1093,8 @@ description: // ==IEEE: description
| interface_declaration { } | interface_declaration { }
| program_declaration { } | program_declaration { }
| package_declaration { } | package_declaration { }
| package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); } | package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
| bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); } | bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
// unsupported // IEEE: config_declaration // unsupported // IEEE: config_declaration
// // Verilator only // // Verilator only
| yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3 | yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
@ -1119,7 +1120,7 @@ timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
package_declaration: // ==IEEE: package_declaration package_declaration: // ==IEEE: package_declaration
packageFront package_itemListE yENDPACKAGE endLabelE packageFront package_itemListE yENDPACKAGE endLabelE
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($2) $1->addStmtsp($2);
GRAMMARP->m_modp = nullptr; GRAMMARP->m_modp = nullptr;
SYMP->popScope($1); SYMP->popScope($1);
GRAMMARP->endLabel($<fl>4,$1,$4); } GRAMMARP->endLabel($<fl>4,$1,$4); }
@ -1132,7 +1133,7 @@ packageFront<nodeModulep>:
$$->lifetime($2); $$->lifetime($2);
$$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
$$->timeunit(PARSEP->timeLastUnit()); $$->timeunit(PARSEP->timeLastUnit());
PARSEP->rootp()->addModulep($$); PARSEP->rootp()->addModulesp($$);
SYMP->pushNew($$); SYMP->pushNew($$);
GRAMMARP->m_modp = $$; } GRAMMARP->m_modp = $$; }
; ;
@ -1228,18 +1229,18 @@ module_declaration: // ==IEEE: module_declaration
modFront importsAndParametersE portsStarE ';' modFront importsAndParametersE portsStarE ';'
/*cont*/ module_itemListE yENDMODULE endLabelE /*cont*/ module_itemListE yENDMODULE endLabelE
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($2) $1->addStmtsp($2);
if ($3) $1->addStmtp($3); if ($3) $1->addStmtsp($3);
if ($5) $1->addStmtp($5); if ($5) $1->addStmtsp($5);
GRAMMARP->m_modp = nullptr; GRAMMARP->m_modp = nullptr;
SYMP->popScope($1); SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); } GRAMMARP->endLabel($<fl>7,$1,$7); }
| udpFront parameter_port_listE portsStarE ';' | udpFront parameter_port_listE portsStarE ';'
/*cont*/ module_itemListE yENDPRIMITIVE endLabelE /*cont*/ module_itemListE yENDPRIMITIVE endLabelE
{ $1->modTrace(false); // Stash for implicit wires, etc { $1->modTrace(false); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($2) $1->addStmtsp($2);
if ($3) $1->addStmtp($3); if ($3) $1->addStmtsp($3);
if ($5) $1->addStmtp($5); if ($5) $1->addStmtsp($5);
GRAMMARP->m_tracingParse = true; GRAMMARP->m_tracingParse = true;
GRAMMARP->m_modp = nullptr; GRAMMARP->m_modp = nullptr;
SYMP->popScope($1); SYMP->popScope($1);
@ -1259,7 +1260,7 @@ modFront<nodeModulep>:
$$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
$$->timeunit(PARSEP->timeLastUnit()); $$->timeunit(PARSEP->timeLastUnit());
$$->unconnectedDrive(PARSEP->unconnectedDrive()); $$->unconnectedDrive(PARSEP->unconnectedDrive());
PARSEP->rootp()->addModulep($$); PARSEP->rootp()->addModulesp($$);
SYMP->pushNew($$); SYMP->pushNew($$);
GRAMMARP->m_modp = $$; } GRAMMARP->m_modp = $$; }
; ;
@ -1275,9 +1276,9 @@ udpFront<nodeModulep>:
{ $$ = new AstPrimitive($<fl>3, *$3); $$->inLibrary(true); { $$ = new AstPrimitive($<fl>3, *$3); $$->inLibrary(true);
$$->lifetime($2); $$->lifetime($2);
$$->modTrace(false); $$->modTrace(false);
$$->addStmtp(new AstPragma($<fl>3, VPragmaType::INLINE_MODULE)); $$->addStmtsp(new AstPragma($<fl>3, VPragmaType::INLINE_MODULE));
GRAMMARP->m_tracingParse = false; GRAMMARP->m_tracingParse = false;
PARSEP->rootp()->addModulep($$); PARSEP->rootp()->addModulesp($$);
SYMP->pushNew($$); } SYMP->pushNew($$); }
; ;
@ -1489,9 +1490,9 @@ interface_declaration: // IEEE: interface_declaration + interface_nonan
// // timeunits_delcarationE is instead in interface_item // // timeunits_delcarationE is instead in interface_item
intFront importsAndParametersE portsStarE ';' intFront importsAndParametersE portsStarE ';'
interface_itemListE yENDINTERFACE endLabelE interface_itemListE yENDINTERFACE endLabelE
{ if ($2) $1->addStmtp($2); { if ($2) $1->addStmtsp($2);
if ($3) $1->addStmtp($3); if ($3) $1->addStmtsp($3);
if ($5) $1->addStmtp($5); if ($5) $1->addStmtsp($5);
SYMP->popScope($1); } SYMP->popScope($1); }
| yEXTERN intFront parameter_port_listE portsStarE ';' | yEXTERN intFront parameter_port_listE portsStarE ';'
{ BBUNSUP($<fl>1, "Unsupported: extern interface"); } { BBUNSUP($<fl>1, "Unsupported: extern interface"); }
@ -1502,7 +1503,7 @@ intFront<nodeModulep>:
{ $$ = new AstIface($<fl>3, *$3); { $$ = new AstIface($<fl>3, *$3);
$$->inLibrary(true); $$->inLibrary(true);
$$->lifetime($2); $$->lifetime($2);
PARSEP->rootp()->addModulep($$); PARSEP->rootp()->addModulesp($$);
SYMP->pushNew($$); } SYMP->pushNew($$); }
; ;
@ -1578,9 +1579,9 @@ program_declaration: // IEEE: program_declaration + program_nonansi_h
pgmFront parameter_port_listE portsStarE ';' pgmFront parameter_port_listE portsStarE ';'
/*cont*/ program_itemListE yENDPROGRAM endLabelE /*cont*/ program_itemListE yENDPROGRAM endLabelE
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($2) $1->addStmtsp($2);
if ($3) $1->addStmtp($3); if ($3) $1->addStmtsp($3);
if ($5) $1->addStmtp($5); if ($5) $1->addStmtsp($5);
GRAMMARP->m_modp = nullptr; GRAMMARP->m_modp = nullptr;
SYMP->popScope($1); SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); } GRAMMARP->endLabel($<fl>7,$1,$7); }
@ -1596,7 +1597,7 @@ pgmFront<nodeModulep>:
$$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn()); $$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn());
$$->modTrace(GRAMMARP->allTracingOn($$->fileline())); $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
$$->timeunit(PARSEP->timeLastUnit()); $$->timeunit(PARSEP->timeLastUnit());
PARSEP->rootp()->addModulep($$); PARSEP->rootp()->addModulesp($$);
SYMP->pushNew($$); SYMP->pushNew($$);
GRAMMARP->m_modp = $$; } GRAMMARP->m_modp = $$; }
; ;
@ -2008,12 +2009,13 @@ struct_unionDecl<nodeUOrStructDTypep>: // IEEE: part of data_type
{ $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); SYMP->popScope($$); } { $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); SYMP->popScope($$); }
; ;
struct_union_memberList<nodep>: // IEEE: { struct_union_member } struct_union_memberList<memberDTypep>: // IEEE: { struct_union_member }
struct_union_member { $$ = $1; } struct_union_member { $$ = $1; }
| struct_union_memberList struct_union_member { $$ = addNextNull($1, $2); } | struct_union_memberList struct_union_member { $$ = addNextNull($1, $2); }
; ;
struct_union_member<nodep>: // ==IEEE: struct_union_member struct_union_member<memberDTypep>: // ==IEEE: struct_union_member
// // UNSUP random_qualifer not propagagted until have randomize support // // UNSUP random_qualifer not propagagted until have randomize support
random_qualifierE data_type_or_void random_qualifierE data_type_or_void
/*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. /*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
@ -2021,7 +2023,7 @@ struct_union_member<nodep>: // ==IEEE: struct_union_member
| vlTag { $$ = nullptr; } | vlTag { $$ = nullptr; }
; ;
list_of_member_decl_assignments<nodep>: // Derived from IEEE: list_of_variable_decl_assignments list_of_member_decl_assignments<memberDTypep>: // Derived from IEEE: list_of_variable_decl_assignments
member_decl_assignment { $$ = $1; } member_decl_assignment { $$ = $1; }
| list_of_member_decl_assignments ',' member_decl_assignment { $$ = addNextNull($1, $3); } | list_of_member_decl_assignments ',' member_decl_assignment { $$ = addNextNull($1, $3); }
; ;
@ -2177,17 +2179,17 @@ enum_base_typeE<nodeDTypep>: // IEEE: enum_base_type
$$ = GRAMMARP->createArray(refp, $3, true); } $$ = GRAMMARP->createArray(refp, $3, true); }
; ;
enum_nameList<nodep>: enum_nameList<enumItemp>:
enum_name_declaration { $$ = $1; } enum_name_declaration { $$ = $1; }
| enum_nameList ',' enum_name_declaration { $$ = addNextNull($1, $3); } | enum_nameList ',' enum_name_declaration { $$ = addNextNull($1, $3); }
; ;
enum_name_declaration<nodep>: // ==IEEE: enum_name_declaration enum_name_declaration<enumItemp>: // ==IEEE: enum_name_declaration
idAny/*enum_identifier*/ enumNameRangeE enumNameStartE idAny/*enum_identifier*/ enumNameRangeE enumNameStartE
{ $$ = new AstEnumItem($<fl>1, *$1, $2, $3); } { $$ = new AstEnumItem($<fl>1, *$1, $2, $3); }
; ;
enumNameRangeE<nodep>: // IEEE: second part of enum_name_declaration enumNameRangeE<rangep>: // IEEE: second part of enum_name_declaration
/* empty */ /* empty */
{ $$ = nullptr; } { $$ = nullptr; }
| '[' intnumAsConst ']' | '[' intnumAsConst ']'
@ -2472,7 +2474,7 @@ continuous_assign<nodep>: // IEEE: continuous_assign
if ($3) if ($3)
for (auto* nodep = $$; nodep; nodep = nodep->nextp()) { for (auto* nodep = $$; nodep; nodep = nodep->nextp()) {
auto* const assignp = VN_AS(nodep, NodeAssign); auto* const assignp = VN_AS(nodep, NodeAssign);
assignp->addTimingControlp(nodep == $$ ? $3 : $3->cloneTree(false)); assignp->timingControlp(nodep == $$ ? $3 : $3->cloneTree(false));
} }
} }
; ;
@ -2634,7 +2636,7 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
} }
// Statements are under 'genforp' as cells under this // Statements are under 'genforp' as cells under this
// for loop won't get an extra layer of hierarchy tacked on // for loop won't get an extra layer of hierarchy tacked on
blkp->addGenforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp)); blkp->genforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp));
$$ = blkp; $$ = blkp;
VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp); VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp);
} }
@ -2679,12 +2681,12 @@ genvar_iteration<nodep>: // ==IEEE: genvar_iteration
new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; } new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; }
; ;
case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }] case_generate_itemListE<caseItemp>: // IEEE: [{ case_generate_itemList }]
/* empty */ { $$ = nullptr; } /* empty */ { $$ = nullptr; }
| case_generate_itemList { $$ = $1; } | case_generate_itemList { $$ = $1; }
; ;
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList } case_generate_itemList<caseItemp>: // IEEE: { case_generate_itemList }
~c~case_generate_item { $$ = $1; } ~c~case_generate_item { $$ = $1; }
| ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); } | ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); }
; ;
@ -2693,7 +2695,7 @@ case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
//UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied} //UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied}
//UNSUP ; //UNSUP ;
case_generate_item<nodep>: // ==IEEE: case_generate_item case_generate_item<caseItemp>: // ==IEEE: case_generate_item
caseCondList colon generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; } caseCondList colon generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; }
| yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; } | yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; }
| yDEFAULT generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; } | yDEFAULT generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; }
@ -2768,7 +2770,7 @@ netSig<varp>: // IEEE: net_decl_assignment - one element from
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2); { $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
auto* const assignp = new AstAssignW{$3, new AstVarRef{$<fl>1, *$1, VAccess::WRITE}, $4}; auto* const assignp = new AstAssignW{$3, new AstVarRef{$<fl>1, *$1, VAccess::WRITE}, $4};
if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false)); if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false));
if ($$->delayp()) assignp->addTimingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3 if ($$->delayp()) assignp->timingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3
AstNode::addNext<AstNode, AstNode>($$, assignp); } | netId variable_dimensionList sigAttrListE AstNode::addNext<AstNode, AstNode>($$, assignp); } | netId variable_dimensionList sigAttrListE
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); } { $$ = VARDONEA($<fl>1,*$1, $2, $3); }
; ;
@ -4110,19 +4112,19 @@ funcId<nodeFTaskp>: // IEEE: function_data_type_or_implicit
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID // // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
/**/ fIdScoped /**/ fIdScoped
{ $$ = $1; { $$ = $1;
$$->addFvarp(new AstBasicDType($<fl>1, LOGIC_IMPLICIT)); $$->fvarp(new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); } SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); }
| signingE rangeList fIdScoped | signingE rangeList fIdScoped
{ $$ = $3; { $$ = $3;
$$->addFvarp(GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true)); $$->fvarp(GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>3); } SYMP->pushNewUnderNodeOrCurrent($$, $<scp>3); }
| signing fIdScoped | signing fIdScoped
{ $$ = $2; { $$ = $2;
$$->addFvarp(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1)); $$->fvarp(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); } SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
| data_type fIdScoped | data_type fIdScoped
{ $$ = $2; { $$ = $2;
$$->addFvarp($1); $$->fvarp($1);
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); } SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
// // To verilator tasks are the same as void functions (we separately detect time passing) // // To verilator tasks are the same as void functions (we separately detect time passing)
| yVOID taskId | yVOID taskId
@ -4992,12 +4994,12 @@ combinational_body<nodep>: // IEEE: combinational_body + sequential_body
yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); } yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); }
; ;
tableEntryList<nodep>: // IEEE: { combinational_entry | sequential_entry } tableEntryList<udpTableLinep>: // IEEE: { combinational_entry | sequential_entry }
tableEntry { $$ = $1; } tableEntry { $$ = $1; }
| tableEntryList tableEntry { $$ = addNextNull($1, $2); } | tableEntryList tableEntry { $$ = addNextNull($1, $2); }
; ;
tableEntry<nodep>: // IEEE: combinational_entry + sequential_entry tableEntry<udpTableLinep>: // IEEE: combinational_entry + sequential_entry
yaTABLELINE { $$ = new AstUdpTableLine($<fl>1,*$1); } yaTABLELINE { $$ = new AstUdpTableLine($<fl>1,*$1); }
| error { $$ = nullptr; } | error { $$ = nullptr; }
; ;
@ -6227,14 +6229,14 @@ classVirtualE<cbool>:
| yVIRTUAL__CLASS { $$ = true; } | yVIRTUAL__CLASS { $$ = true; }
; ;
classExtendsE<nodep>: // IEEE: part of class_declaration classExtendsE<classExtendsp>: // IEEE: part of class_declaration
// // The classExtendsE rule relys on classFront having the // // The classExtendsE rule relys on classFront having the
// // new class scope correct via classFront // // new class scope correct via classFront
/* empty */ { $$ = nullptr; $<scp>$ = nullptr; } /* empty */ { $$ = nullptr; $<scp>$ = nullptr; }
| yEXTENDS classExtendsList { $$ = $2; $<scp>$ = $<scp>2; } | yEXTENDS classExtendsList { $$ = $2; $<scp>$ = $<scp>2; }
; ;
classExtendsList<nodep>: // IEEE: part of class_declaration classExtendsList<classExtendsp>: // IEEE: part of class_declaration
classExtendsOne { $$ = $1; $<scp>$ = $<scp>1; } classExtendsOne { $$ = $1; $<scp>$ = $<scp>1; }
| classExtendsList ',' classExtendsOne | classExtendsList ',' classExtendsOne
{ $$ = $3; $<scp>$ = $<scp>3; { $$ = $3; $<scp>$ = $<scp>3;
@ -6242,7 +6244,7 @@ classExtendsList<nodep>: // IEEE: part of class_declaration
"and unsupported for interface classes."); } "and unsupported for interface classes."); }
; ;
classExtendsOne<nodep>: // IEEE: part of class_declaration classExtendsOne<classExtendsp>: // IEEE: part of class_declaration
class_typeExtImpList class_typeExtImpList
{ $$ = new AstClassExtends($1->fileline(), $1); { $$ = new AstClassExtends($1->fileline(), $1);
$<scp>$ = $<scp>1; } $<scp>$ = $<scp>1; }