Fix internals to make null-pointer-check clean. Also add more const's. No functional change intended, but likely something will break.

This commit is contained in:
Wilson Snyder 2018-02-01 21:32:58 -05:00
parent 94e8cf1de9
commit 597d28b505
73 changed files with 1421 additions and 1373 deletions

View File

@ -4,6 +4,10 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.000 devel
** This is a major release. Any patches may require major rework to apply.
** Fix internals to make null-pointer-check clean.
**** Fix internals to avoid 'using namespace std'.

View File

@ -199,7 +199,6 @@ AC_SUBST(CFG_CXXFLAGS_WEXTRA)
# Flags for compiling Verilator internals including parser always
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)

View File

@ -312,8 +312,8 @@ private:
// Move always to appropriate ACTIVE based on its sense list
if (oldsensesp
&& oldsensesp->sensesp()
&& oldsensesp->sensesp()->castSenItem()
&& oldsensesp->sensesp()->castSenItem()->isNever()) {
&& VN_IS(oldsensesp->sensesp(), SenItem)
&& VN_CAST(oldsensesp->sensesp(), SenItem)->isNever()) {
// Never executing. Kill it.
if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);

View File

@ -83,8 +83,8 @@ private:
AstSenTree* sensesp = nodep->sensesp();
if (!sensesp) nodep->v3fatalSrc("NULL");
if (sensesp->sensesp()
&& sensesp->sensesp()->castSenItem()
&& sensesp->sensesp()->castSenItem()->isNever()) {
&& VN_IS(sensesp->sensesp(), SenItem)
&& VN_CAST(sensesp->sensesp(), SenItem)->isNever()) {
// Never executing. Kill it.
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);

View File

@ -105,12 +105,12 @@ private:
//
AstNode* bodysp = NULL;
bool selfDestruct = false;
if (AstPslCover* snodep = nodep->castPslCover()) {
if (AstPslCover* snodep = VN_CAST(nodep, PslCover)) {
if (!v3Global.opt.coverageUser()) {
selfDestruct = true;
} else {
// V3Coverage assigned us a bucket to increment.
AstCoverInc* covincp = snodep->coverincp()->castCoverInc();
AstCoverInc* covincp = VN_CAST(snodep->coverincp(), CoverInc);
if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion");
covincp->unlinkFrBack();
if (message!="") covincp->declp()->comment(message);
@ -122,7 +122,7 @@ private:
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
AstNode* newp = new AstAlways (nodep->fileline(),
VAlwaysKwd::ALWAYS,
@ -146,7 +146,7 @@ private:
AstNode* passsp = nodep->passsp(); if (passsp) passsp->unlinkFrBackWithNext();
AstNode* failsp = nodep->failsp(); if (failsp) failsp->unlinkFrBackWithNext();
//
if (nodep->castVAssert()) {
if (VN_IS(nodep, VAssert)) {
if (passsp) passsp = newIfAssertOn(passsp);
if (failsp) failsp = newIfAssertOn(failsp);
} else {
@ -155,7 +155,7 @@ private:
AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp);
AstNode* newp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
// Install it
nodep->replaceWith(newp);
@ -227,7 +227,7 @@ private:
nodep->iterateChildren(*this);
if (!nodep->user1SetOnce()) {
bool has_default=false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) has_default=true;
}
if (nodep->fullPragma() || nodep->priorityPragma()) {
@ -246,7 +246,7 @@ private:
// Not parallel, but harmlessly so.
} else {
AstNode* propp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
AstNode* onep;
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {

View File

@ -828,7 +828,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
// To solve this, this function returns the pointer to the replacement node,
// which in many cases is just the same node that was passed in.
AstNode* nodep = this; // Note "this" may point to bogus point later in this function
if (nodep->castNetlist()) {
if (VN_IS(nodep, Netlist)) {
// Calling on top level; we know the netlist won't get replaced
nodep->accept(v);
} else if (!nodep->backp()) {
@ -875,7 +875,7 @@ void AstNode::cloneRelinkTree() {
//======================================================================
// Comparison
bool AstNode::gateTreeIter() {
bool AstNode::gateTreeIter() const {
// private: Return true if the two trees are identical
if (!isGateOptimizable()) return false;
if (m_op1p && !m_op1p->gateTreeIter()) return false;
@ -885,7 +885,7 @@ bool AstNode::gateTreeIter() {
return true;
}
bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly) {
bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ignNext, bool gateOnly) const {
// private: Return true if the two trees are identical
if (!node1p && !node2p) return true;
if (!node1p || !node2p) return false;
@ -927,7 +927,7 @@ void AstNode::checkTreeIter(AstNode* backp) {
if (backp != this->backp()) {
this->v3fatalSrc("Back node inconsistent");
}
if (castNodeTermop() || castNodeVarRef()) {
if (VN_IS(this, NodeTermop) || VN_IS(this, NodeVarRef)) {
// Termops have a short-circuited iterateChildren, so check usage
if (op1p()||op2p()||op3p()||op4p())
this->v3fatalSrc("Terminal operation with non-terminals");
@ -1055,7 +1055,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
checkTree();
// Broken isn't part of check tree because it can munge iterp's
// set by other steps if it is called in the middle of other operations
if (AstNetlist* netp=this->castNetlist()) V3Broken::brokenAll(netp);
if (AstNetlist* netp=VN_CAST(this, Netlist)) V3Broken::brokenAll(netp);
}
// Next dump can indicate start from here
editCountSetLast();

View File

@ -44,6 +44,15 @@ class VFlagChildDType {}; // Used by parser.y to select constructor that sets c
//######################################################################
// (V)erilator (N)ode (is)): True if AstNode is of a a given AstType
#define VN_IS(nodep,nodetypename) (AstNode::privateIs ## nodetypename(nodep))
// (V)erilator (N)ode (cast): Cast to given type if can; effectively dynamic_cast(nodep)(nodetypename)
#define VN_CAST(nodep,nodetypename) (AstNode::privateCast ## nodetypename(nodep))
#define VN_CAST_CONST(nodep,nodetypename) (AstNode::privateConstCast ## nodetypename(nodep) )
//######################################################################
class AstType {
public:
#include "V3Ast__gen_types.h" // From ./astgen
@ -1048,8 +1057,8 @@ private:
AstNode* cloneTreeIterList();
void checkTreeIter(AstNode* backp);
void checkTreeIterList(AstNode* backp);
bool gateTreeIter();
bool sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly);
bool gateTreeIter() const;
bool sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ignNext, bool gateOnly) const;
void deleteTreeIter();
void deleteNode();
public:
@ -1240,11 +1249,11 @@ public:
// ACCESSORS for specific types
// Alas these can't be virtual or they break when passed a NULL
bool isZero();
bool isOne();
bool isNeqZero();
bool isAllOnes();
bool isAllOnesV(); // Verilog width rules apply
bool isZero() const;
bool isOne() const;
bool isNeqZero() const;
bool isAllOnes() const;
bool isAllOnesV() const; // Verilog width rules apply
// METHODS - data type changes especially for initial creation
void dtypep(AstNodeDType* nodep) { if (m_dtypep != nodep) { m_dtypep = nodep; editCountInc(); } }
@ -1303,8 +1312,8 @@ public:
// METHODS - Iterate on a tree
AstNode* cloneTree(bool cloneNextLink);
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable
bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
bool sameGateTree(const AstNode* node2p) const; // Does tree of this == node2p?, not allowing non-isGateOptimizable
void deleteTree(); // Always deletes the next link
void checkTree(); // User Interface version
void checkIter() const;
@ -1376,7 +1385,7 @@ public:
virtual bool cleanOut() = 0; // True if output has extra upper bits zero
// Someday we will generically support data types on every math node
// Until then isOpaque indicates we shouldn't constant optimize this node type
bool isOpaque() { return castCvtPackString()!=NULL; }
bool isOpaque() { return VN_IS(this, CvtPackString); }
};
class AstNodeTermop : public AstNodeMath {
@ -1516,7 +1525,7 @@ public:
AstNode* fromp() const { return lhsp(); }
AstNode* rhsp() const { return op2p(); }
AstNode* thsp() const { return op3p(); }
AstAttrOf* attrp() const { return op4p()->castAttrOf(); }
AstAttrOf* attrp() const { return VN_CAST(op4p(), AttrOf); }
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
void thsp(AstNode* nodep) { return setOp3p(nodep); }
@ -1611,7 +1620,7 @@ public:
ASTNODE_BASE_FUNCS(NodeCase)
virtual int instrCount() const { return instrCountBranch(); }
AstNode* exprp() const { return op1p(); } // op1 = case condition <expression>
AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions
AstCaseItem* itemsp() const { return VN_CAST(op2p(), CaseItem); } // op2 = list of case expressions
AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
@ -1774,8 +1783,9 @@ public:
virtual void dump(std::ostream& str);
// For basicp() we reuse the size to indicate a "fake" basic type of same size
virtual AstBasicDType* basicp() const {
return (isFourstate() ? findLogicDType(width(),width(),numeric())->castBasicDType()
: findBitDType(width(),width(),numeric())->castBasicDType()); }
return (isFourstate()
? VN_CAST(findLogicDType(width(),width(),numeric()), BasicDType)
: VN_CAST(findBitDType(width(),width(),numeric()), BasicDType)); }
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
@ -1785,7 +1795,7 @@ public:
virtual bool similarDType(AstNodeDType* samep) const {
return this==samep; // We don't compare members, require exact equivalence
}
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
AstMemberDType* membersp() const { return VN_CAST(op1p(), MemberDType); } // op1 = AstMember list
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
bool packed() const { return m_packed; }
bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs
@ -1836,13 +1846,13 @@ public:
}
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable
AstRange* rangep() const { return VN_CAST(op2p(), Range); } // op2 = Array(s) of variable
void rangep(AstRange* nodep);
// METHODS
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
@ -1927,7 +1937,7 @@ public:
AstNode* stmtsp() const { return op3p(); } // op3 = List of statements
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
// op4 = scope name
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
AstScopeName* scopeNamep() const { return VN_CAST(op4p(), ScopeName); }
// MORE ACCESSORS
void dpiOpenParentInc() { ++m_dpiOpenParent; }
void dpiOpenParentClear() { m_dpiOpenParent=0; }
@ -1996,7 +2006,7 @@ public:
AstNode* pinsp() const { return op2p(); }
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
// op3 = scope tracking
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
AstScopeName* scopeNamep() const { return VN_CAST(op3p(), ScopeName); }
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
};
@ -2029,7 +2039,7 @@ public:
virtual bool maybePointedTo() const { return true; }
virtual string name() const { return m_name; }
AstNode* stmtsp() const { return op2p(); } // op2 = List of statements
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
AstActive* activesp() const { return VN_CAST(op3p(), Active); } // op3 = List of i/sblocks
// METHODS
void addInlinesp(AstNode* nodep) { addOp1p(nodep); }
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
@ -2071,7 +2081,8 @@ public:
#include "V3Ast__gen_impl.h" // From ./astgen
// Things like:
// inline AstAlways* AstNode::castAlways() { return dynamic_cast<AstAlways*>(this);}
// inline AstAlways* AstNode::castAlways() { return dynamic_cast<AstAlways*>(this);}
// inline bool AstNode::privateIsaAlways(const AstNode* nodep) { return nodep && nodep->type() == AstType::atAlways; }
//######################################################################
// Inline ACCESSORS
@ -2080,17 +2091,17 @@ inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0;
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize
inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); }
inline bool AstNode::isDouble() const { return dtypep() && VN_IS(dtypep(), BasicDType) && VN_CAST(dtypep(), BasicDType)->isDouble(); }
inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); }
inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); }
inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); }
inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); }
inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); }
inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, false); }
inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, true); }
inline bool AstNode::isZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isEqZero()); }
inline bool AstNode::isNeqZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isNeqZero()); }
inline bool AstNode::isOne() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isEqOne()); }
inline bool AstNode::isAllOnes() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->isEqAllOnes()); }
inline bool AstNode::isAllOnesV() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->isEqAllOnesV()); }
inline bool AstNode::sameTree(const AstNode* node2p) const { return sameTreeIter(this, node2p, true, false); }
inline bool AstNode::sameGateTree(const AstNode* node2p) const { return sameTreeIter(this, node2p, true, true); }
inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); }

View File

@ -44,7 +44,7 @@ const char* AstIfaceRefDType::broken() const {
}
AstIface* AstIfaceRefDType::ifaceViaCellp() const {
return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
return ((m_cellp && m_cellp->modp()) ? VN_CAST(m_cellp->modp(), Iface) : m_ifacep);
}
const char* AstNodeVarRef::broken() const {
@ -58,12 +58,13 @@ void AstNodeVarRef::cloneRelink() {
}
int AstNodeSel::bitConst() const {
AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
AstConst* constp=VN_CAST(bitp(), Const);
return (constp ? constp->toSInt() : 0);
}
void AstNodeClassDType::repairMemberCache() {
clearCache();
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
for (AstMemberDType* itemp = membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
else m_members.insert(make_pair(itemp->name(), itemp));
}
@ -71,7 +72,7 @@ void AstNodeClassDType::repairMemberCache() {
const char* AstNodeClassDType::broken() const {
vl_unordered_set<AstMemberDType*> exists;
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
for (AstMemberDType* itemp = membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
exists.insert(itemp);
}
for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
@ -243,7 +244,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
arg += " (& "+name()+")";
for (AstNodeDType* dtp=dtypep(); dtp; ) {
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstUnpackArrayDType* adtypep = dtp->castUnpackArrayDType()) {
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) {
arg += "["+cvtToStr(adtypep->declRange().elements())+"]";
dtp = adtypep->subDTypep();
} else break;
@ -315,7 +316,7 @@ string AstVar::vlPropInit() const {
bool first = true;
for (AstNodeDType* dtp=dtypep(); dtp; ) {
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtp->castNodeArrayDType()) {
if (AstNodeArrayDType* adtypep = VN_CAST(dtp, NodeArrayDType)) {
if (first) {
out += ", VerilatedVarProps::Unpacked()";
first = false;
@ -422,15 +423,15 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
// See if this is a SC assignment; if so return that type
// Historically sc variables are identified by a variable
// attribute. TODO it would better be a data type attribute.
if (AstVar* anodep = nodep->castVar()) {
if (AstVar* anodep = VN_CAST(nodep, Var)) {
if (anodep->isSc()) return anodep;
else return NULL;
}
else if (nodep->castVarRef()) {
if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
else if (VN_IS(nodep, VarRef)) {
if (VN_CAST(nodep, VarRef)->varp()->isSc()) return VN_CAST(nodep, VarRef)->varp();
else return NULL;
}
else if (nodep->castArraySel()) {
else if (VN_IS(nodep, ArraySel)) {
if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
@ -457,14 +458,14 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
if ((dim++)==dimension) {
return dtypep;
}
dtypep = adtypep->subDTypep();
continue;
}
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
// AstBasicDType - nothing below, return null
if (adtypep->isRanged()) {
if ((dim++) == dimension) {
@ -473,7 +474,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
}
return NULL;
}
else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
if (adtypep->packed()) {
if ((dim++) == dimension) {
return adtypep;
@ -492,7 +493,7 @@ uint32_t AstNodeDType::arrayUnpackedElements() {
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
entries *= adtypep->elementsConst();
dtypep = adtypep->subDTypep();
}
@ -511,13 +512,13 @@ std::pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (adtypep->castPackArrayDType()) packed++;
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
if (VN_IS(adtypep, PackArrayDType)) packed++;
else unpacked++;
dtypep = adtypep->subDTypep();
continue;
}
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
else if (const AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
if (includeBasic && adtypep->isRanged()) packed++;
}
break;
@ -537,15 +538,15 @@ int AstNodeDType::widthPow2() const {
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
// Else AstArraySel etc; search for the base
while (nodep) {
if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; }
else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; }
if (VN_IS(nodep, ArraySel)) { nodep=VN_CAST(nodep, ArraySel)->fromp(); continue; }
else if (VN_IS(nodep, Sel)) { nodep=VN_CAST(nodep, Sel)->fromp(); continue; }
// AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; }
else if (nodep->castNodePreSel()) {
if (nodep->castNodePreSel()->attrp()) {
nodep=nodep->castNodePreSel()->attrp();
else if (VN_IS(nodep, AttrOf)) { nodep=VN_CAST(nodep, AttrOf)->fromp(); continue; }
else if (VN_IS(nodep, NodePreSel)) {
if (VN_CAST(nodep, NodePreSel)->attrp()) {
nodep=VN_CAST(nodep, NodePreSel)->attrp();
} else {
nodep=nodep->castNodePreSel()->lhsp();
nodep=VN_CAST(nodep, NodePreSel)->lhsp();
}
continue;
}
@ -579,7 +580,7 @@ string AstScope::nameDotless() const {
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=VN_CAST(textp->nextp(), Text)) {
out += textp->text();
}
// TOP will be replaced by top->name()
@ -591,7 +592,7 @@ string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=VN_CAST(textp->nextp(), Text)) {
out += textp->text();
}
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
@ -609,28 +610,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
bool AstSenTree::hasClocked() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
if (senp->isClocked()) return true;
}
return false;
}
bool AstSenTree::hasSettle() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
if (senp->isSettle()) return true;
}
return false;
}
bool AstSenTree::hasInitial() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
if (senp->isInitial()) return true;
}
return false;
}
bool AstSenTree::hasCombo() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
if (senp->isCombo()) return true;
}
return false;
@ -651,7 +652,7 @@ void AstTypeTable::clearCache() {
m_detailedMap.clear();
// Clear generic()'s so dead detection will work
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
bdtypep->generic(false);
}
}
@ -661,7 +662,7 @@ void AstTypeTable::repairCache() {
// After we mass-change widthMin in V3WidthCommit, we need to correct the table.
clearCache();
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
(void)findInsertSameDType(bdtypep);
}
}
@ -812,7 +813,7 @@ void AstNode::dump(std::ostream& str) {
if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
}
if (name()!="") {
if (castConst()) str<<" "<<name(); // Already quoted
if (VN_IS(this, Const)) str<<" "<<name(); // Already quoted
else str<<" "<<V3Number::quoteNameControls(name());
}
}
@ -934,7 +935,7 @@ void AstNodeDType::dumpSmall(std::ostream& str) {
}
void AstNodeArrayDType::dumpSmall(std::ostream& str) {
this->AstNodeDType::dumpSmall(str);
if (castPackArrayDType()) str<<"p"; else str<<"u";
if (VN_IS(this, PackArrayDType)) str<<"p"; else str<<"u";
str<<declRange();
}
void AstNodeArrayDType::dump(std::ostream& str) {

View File

@ -132,11 +132,11 @@ public:
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
AstNode* rightp() const { return littleEndian()?msbp():lsbp(); }
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
int msbConst() const { AstConst* constp=VN_CAST(msbp(), Const); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=VN_CAST(lsbp(), Const); return (constp?constp->toSInt():0); }
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
int leftConst() const { AstConst* constp=leftp()->castConst(); return (constp?constp->toSInt():0); }
int rightConst() const { AstConst* constp=rightp()->castConst(); return (constp?constp->toSInt():0); }
int leftConst() const { AstConst* constp=VN_CAST(leftp(), Const); return (constp?constp->toSInt():0); }
int rightConst() const { AstConst* constp=VN_CAST(rightp(), Const); return (constp?constp->toSInt():0); }
int leftToRightInc() const { return littleEndian()?1:-1; }
bool littleEndian() const { return m_littleEndian; }
void littleEndian(bool flag) { m_littleEndian=flag; }
@ -168,7 +168,7 @@ public:
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; }
AstNode* exprp() const { return op1p(); } // op1 = Pin expression
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Range of pin
AstRange* rangep() const { return VN_CAST(op2p(), Range); } // op2 = Range of pin
};
//######################################################################
@ -188,7 +188,7 @@ public:
}
ASTNODE_NODE_FUNCS(ParamTypeDType)
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
@ -196,7 +196,7 @@ public:
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); }
virtual bool similarDType(AstNodeDType* samep) const {
AstParamTypeDType* sp = samep->castParamTypeDType();
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep);
return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
}
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
@ -227,7 +227,7 @@ public:
ASTNODE_NODE_FUNCS(Typedef)
virtual void dump(std::ostream& str);
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
@ -279,7 +279,7 @@ public:
return type()==samep->type() && same(samep); }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void* containerp() const { return m_containerp; }
@ -373,7 +373,7 @@ public:
virtual void dumpSmall(std::ostream& str);
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
@ -466,7 +466,7 @@ public:
return type()==samep->type() && same(samep); }
virtual string name() const { return m.m_keyword.ascii(); }
virtual const char* broken() const { BROKEN_RTN(dtypep()!=this); return NULL; }
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
AstRange* rangep() const { return VN_CAST(op1p(), Range); } // op1 = Range of variable
void rangep(AstRange* nodep) { setNOp1p(nodep); }
void setSignedState(VSignedState signst) {
// Note NOSIGN does NOT change the state; this is required by the parser
@ -498,7 +498,7 @@ public:
bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; }
VNumRange declRange() const { return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange(); }
void cvtRangeConst() { // Convert to smaller represenation
if (rangep() && rangep()->msbp()->castConst() && rangep()->lsbp()->castConst()) {
if (rangep() && VN_IS(rangep()->msbp(), Const) && VN_IS(rangep()->lsbp(), Const)) {
m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(),
rangep()->littleEndian());
rangep()->unlinkFrBackWithNext()->deleteTree();
@ -534,7 +534,7 @@ public:
return skipRefp()->similarDType(samep->skipRefp()); }
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } // node's type() included elsewhere
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
@ -698,7 +698,7 @@ public:
virtual bool hasDType() const { return true; }
virtual bool maybePointedTo() const { return true; }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
@ -734,7 +734,7 @@ public:
virtual bool maybePointedTo() const { return true; }
virtual bool hasDType() const { return true; }
void name(const string& flag) { m_name = flag; }
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range for name appending
AstRange* rangep() const { return VN_CAST(op1p(), Range); } // op1 = Range for name appending
void rangep(AstNode* nodep) { addOp1p(nodep); }
AstNode* valuep() const { return op2p(); } // op2 = Value
void valuep(AstNode* nodep) { addOp2p(nodep); }
@ -754,7 +754,7 @@ public:
virtual string name() const { return itemp()->name(); }
virtual const char* broken() const { BROKEN_RTN(!itemp()); return NULL; }
virtual int instrCount() const { return 0; }
virtual void cloneRelink() { if (m_itemp->clonep()) m_itemp = m_itemp->clonep()->castEnumItem(); }
virtual void cloneRelink() { if (m_itemp->clonep()) m_itemp = VN_CAST(m_itemp->clonep(), EnumItem); }
virtual bool same(const AstNode* samep) const {
const AstEnumItemRef* sp = static_cast<const AstEnumItemRef*>(samep);
return itemp() == sp->itemp(); }
@ -794,13 +794,13 @@ public:
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Data type
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
AstEnumItem* itemsp() const { return op2p()->castEnumItem(); } // op2 = AstEnumItem's
AstEnumItem* itemsp() const { return VN_CAST(op2p(), EnumItem); } // op2 = AstEnumItem's
void addValuesp(AstNode* nodep) { addOp2p(nodep); }
// METHODS
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
@ -837,9 +837,9 @@ class AstArraySel : public AstNodeSel {
// Children: varref|arraysel, math
private:
void init(AstNode* fromp) {
if (fromp && fromp->dtypep()->skipRefp()->castNodeArrayDType()) {
if (fromp && VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) {
// Strip off array to find what array references
dtypeFrom(fromp->dtypep()->skipRefp()->castNodeArrayDType()->subDTypep());
dtypeFrom(VN_CAST(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep());
}
}
public:
@ -945,9 +945,9 @@ public:
AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp)
:AstNodeTriop(fl, fromp, lsbp, widthp) {
m_declElWidth = 1;
if (widthp->castConst()) {
dtypeSetLogicSized(widthp->castConst()->toUInt(),
widthp->castConst()->toUInt(),
if (VN_IS(widthp, Const)) {
dtypeSetLogicSized(VN_CAST(widthp, Const)->toUInt(),
VN_CAST(widthp, Const)->toUInt(),
AstNumeric::UNSIGNED);
}
}
@ -973,13 +973,13 @@ public:
virtual bool sizeMattersThs() {return false;}
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode*) const { return true; }
virtual int instrCount() const { return widthInstrs()*(lsbp()->castConst()?3:10); }
virtual int instrCount() const { return widthInstrs()*(VN_CAST(lsbp(), Const)?3:10); }
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
AstNode* lsbp() const { return op2p(); } // op2 = Msb selection expression
AstNode* widthp() const { return op3p(); } // op3 = Width
int widthConst() const { return widthp()->castConst()->toSInt(); }
int lsbConst() const { return lsbp()->castConst()->toSInt(); }
int msbConst() const { return lsbConst()+widthConst()-1; }
int widthConst() const { return VN_CAST(widthp(), Const)->toSInt(); }
int lsbConst() const { return VN_CAST(lsbp(), Const)->toSInt(); }
int msbConst() const { return lsbConst()+widthConst()-1; }
VNumRange& declRange() { return m_declRange; }
void declRange(const VNumRange& flag) { m_declRange = flag; }
int declElWidth() const { return m_declElWidth; }
@ -1189,7 +1189,7 @@ public:
string vlPropInit() const; // Return VerilatorVarProps initializer
void combineType(AstVarType type);
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNode* valuep() const { return op3p(); } // op3 = Initial value that never changes (static const)
@ -1396,7 +1396,7 @@ public:
ASTNODE_NODE_FUNCS(TopScope)
AstNode* stmtsp() const { return op1p(); }
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
AstScope* scopep() const { return op2p()->castScope(); } // op1 = AstVarScope's
AstScope* scopep() const { return VN_CAST(op2p(), Scope); } // op1 = AstVarScope's
};
class AstVarScope : public AstNode {
@ -1753,9 +1753,9 @@ public:
void origName(const string& name) { m_origName = name; }
string modName() const { return m_modName; } // * = Instance name
void modName(const string& name) { m_modName = name; }
AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values
AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged)
AstPin* pinsp() const { return VN_CAST(op1p(), Pin); } // op1 = List of cell ports
AstPin* paramsp() const { return VN_CAST(op2p(), Pin); } // op2 = List of parameter #(##) values
AstRange* rangep() const { return VN_CAST(op3p(), Range); } // op3 = Range of arrayed instants (NULL=not ranged)
AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated
void addPinsp(AstPin* nodep) { addOp1p(nodep); }
void addParamsp(AstPin* nodep) { addOp2p(nodep); }
@ -1846,7 +1846,7 @@ public:
AstBind(FileLine* fl, const string& name, AstNode* cellsp)
: AstNode(fl)
, m_name(name) {
if (!cellsp->castCell()) cellsp->v3fatalSrc("Only cells allowed to be bound");
if (!VN_IS(cellsp, Cell)) cellsp->v3fatalSrc("Only cells allowed to be bound");
addNOp1p(cellsp);
}
ASTNODE_NODE_FUNCS(Bind)
@ -2061,7 +2061,7 @@ public:
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized
AstNodeVarRef* varrefp() const { return VN_CAST(op1p(), NodeVarRef); } // op1 = Signal sensitized
//
virtual bool isClocked() const { return edgeType().clockedStmt(); }
virtual bool isCombo() const { return edgeType()==AstEdgeType::ET_COMBO; }
@ -2083,7 +2083,7 @@ public:
}
ASTNODE_NODE_FUNCS(SenGate)
virtual string emitVerilog() { return "(%l) %f&& (%r)"; }
AstSenItem* sensesp() const { return op1p()->castSenItem(); }
AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); }
AstNode* rhsp() const { return op2p(); }
void sensesp(AstSenItem* nodep) { addOp1p(nodep); }
void rhsp(AstNode* nodep) { setOp2p(nodep); }
@ -2110,7 +2110,7 @@ public:
virtual void dump(std::ostream& str);
virtual bool maybePointedTo() const { return true; }
bool isMulti() const { return m_multi; }
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
void addSensesp(AstNodeSenItem* nodep) { addOp1p(nodep); }
void multi(bool flag) { m_multi = true; }
// METHODS
@ -2130,7 +2130,7 @@ public:
ASTNODE_NODE_FUNCS(Always)
//
virtual void dump(std::ostream& str);
AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
VAlwaysKwd keyword() const { return m_keyword; }
@ -2150,7 +2150,7 @@ public:
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
//
AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
// Special accessors
@ -2404,7 +2404,7 @@ public:
virtual bool isPredictOptimizable() const { return true; }
virtual bool isOutputter() const { return false; } // Though the AstCoverInc under this is an outputter
// but isPure() true
AstCoverInc* incp() const { return op1p()->castCoverInc(); }
AstCoverInc* incp() const { return VN_CAST(op1p(), CoverInc); }
void incp(AstCoverInc* nodep) { setOp1p(nodep); }
AstNode* origp() const { return op2p(); }
AstNode* changep() const { return op3p(); }
@ -2514,7 +2514,7 @@ public:
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
AstScopeName* scopeNamep() const { return op2p()->castScopeName(); }
AstScopeName* scopeNamep() const { return VN_CAST(op2p(), ScopeName); }
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
@ -2560,7 +2560,7 @@ public:
void displayType(AstDisplayType type) { m_displayType = type; }
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); }
AstNode* filep() const { return op3p(); }
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
};
@ -2589,7 +2589,7 @@ public:
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); }
AstNode* lhsp() const { return op3p(); }
void lhsp(AstNode* nodep) { setOp3p(nodep); }
};
@ -3047,7 +3047,7 @@ public:
addNOp2p(stablesp); addNOp3p(bodysp);
}
ASTNODE_NODE_FUNCS(UntilStable)
AstVarRef* stablesp() const { return op2p()->castVarRef(); } // op2= list of variables that must become stable
AstVarRef* stablesp() const { return VN_CAST(op2p(), VarRef); } // op2= list of variables that must become stable
AstNode* bodysp() const { return op3p(); } // op3= body of loop
void addStablesp(AstVarRef* newp) { addOp2p(newp); }
void addBodysp(AstNode* newp) { addOp3p(newp); }
@ -3371,7 +3371,7 @@ public:
AstSenTree* sensesp() const { return m_sensesp; }
// op1 = Sensitivity tree, if a clocked block in early stages
void sensesStorep(AstSenTree* nodep) { addOp1p(nodep); }
AstSenTree* sensesStorep() const { return op1p()->castSenTree(); }
AstSenTree* sensesStorep() const { return VN_CAST(op1p(), SenTree); }
// op2 = Combo logic
AstNode* stmtsp() const { return op2p(); }
void addStmtsp(AstNode* nodep) { addOp2p(nodep); }
@ -3416,10 +3416,10 @@ public:
virtual string emitVerilog() { return ""; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; }
AstText* scopeAttrp() const { return op1p()->castText(); }
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
AstText* scopeEntrp() const { return op2p()->castText(); }
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
AstText* scopeAttrp() const { return VN_CAST(op1p(), Text); }
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
AstText* scopeEntrp() const { return VN_CAST(op2p(), Text); }
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope
string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
@ -3435,7 +3435,7 @@ public:
addNOp1p(bodysp);
}
ASTNODE_NODE_FUNCS(UdpTable)
AstUdpTableLine* bodysp() const { return op1p()->castUdpTableLine(); } // op1 = List of UdpTableLines
AstUdpTableLine* bodysp() const { return VN_CAST(op1p(), UdpTableLine); } // op1 = List of UdpTableLines
};
class AstUdpTableLine : public AstNode {
@ -3839,7 +3839,7 @@ public:
virtual bool sizeMattersLhs() {return false;}
AstNode* lhsp() const { return op1p(); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); }
AstNodeDType* childDTypep() const { return VN_CAST(op2p(), NodeDType); }
};
class AstCastParse : public AstNode {
@ -4904,7 +4904,7 @@ class AstReplicate : public AstNodeBiop {
private:
void init() {
if (lhsp()) {
if (AstConst* constp=rhsp()->castConst()) {
if (const AstConst* constp = VN_CAST(rhsp(), Const)) {
dtypeSetLogicSized(lhsp()->width()*constp->toUInt(), lhsp()->width()*constp->toUInt(), AstNumeric::UNSIGNED);
}
}
@ -5020,7 +5020,7 @@ public:
virtual bool cleanOut() {V3ERROR_NA; return "";}
virtual int instrCount() const { return widthInstrs(); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
@ -5084,7 +5084,7 @@ public:
addNOp2p(bodysp);
}
ASTNODE_NODE_FUNCS(Clocking)
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p(); } // op2 = Body
};
@ -5104,7 +5104,7 @@ public:
}
ASTNODE_NODE_FUNCS(PslClocked)
virtual bool hasDType() const { return true; } // Used under PslCover, which expects a bool child
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
AstNode* disablep() const { return op2p(); } // op2 = disable
AstNode* propp() const { return op3p(); } // op3 = property
};
@ -5128,7 +5128,7 @@ public:
virtual bool same(const AstNode* samep) const { return samep->name() == name(); }
virtual void name(const string& name) { m_name = name; }
AstNode* propp() const { return op1p(); } // op1 = property
AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain
AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
AstNode* coverincp() const { return op3p(); } // op3 = coverage node
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
@ -5477,7 +5477,7 @@ public:
virtual bool isPredictOptimizable() const { return false; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
AstVarRef* varrefp() const { return op1p()->castVarRef(); } // op1= varref to reset
AstVarRef* varrefp() const { return VN_CAST(op1p(), VarRef); } // op1= varref to reset
};
class AstCStmt : public AstNodeStmt {
@ -5519,7 +5519,7 @@ public:
for (int i=0; i<AstBasicDTypeKwd::_ENUM_MAX; ++i) m_basicps[i] = NULL;
}
ASTNODE_NODE_FUNCS(TypeTable)
AstNodeDType* typesp() const { return op1p()->castNodeDType();} // op1 = List of dtypes
AstNodeDType* typesp() const { return VN_CAST(op1p(), NodeDType);} // op1 = List of dtypes
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
@ -5555,10 +5555,10 @@ public:
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
return NULL;
}
AstNodeModule* modulesp() const { return op1p()->castNodeModule();} // op1 = List of modules
AstNodeModule* topModulep() const { return op1p()->castNodeModule(); } // * = Top module in hierarchy (first one added, for now)
AstNodeModule* modulesp() const { return VN_CAST(op1p(), NodeModule); } // op1 = List of modules
AstNodeModule* topModulep() const { return VN_CAST(op1p(), NodeModule); } // * = Top module in hierarchy (first one added, for now)
void addModulep(AstNodeModule* modulep) { addOp1p(modulep); }
AstCFile* filesp() const { return op2p()->castCFile();} // op2 = List of files
AstCFile* filesp() const { return VN_CAST(op2p(), CFile);} // op2 = List of files
void addFilesp(AstCFile* filep) { addOp2p(filep); }
AstNode* miscsp() const { return op3p();} // op3 = List of dtypes etc
void addMiscsp(AstNode* nodep) { addOp3p(nodep); }

View File

@ -212,7 +212,7 @@ public:
class BrokenCheckVisitor : public AstNVisitor {
private:
void checkWidthMin(AstNode* nodep) {
void checkWidthMin(const AstNode* nodep) {
if (nodep->width() != nodep->widthMin()
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
nodep->v3fatalSrc("Width != WidthMin");
@ -225,7 +225,7 @@ private:
}
if (nodep->dtypep()) {
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!VN_IS(nodep->dtypep(), NodeDType)) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
}
if (v3Global.assertDTypesResolved()) {
if (nodep->hasDType()) {
@ -234,7 +234,7 @@ private:
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
}
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep);
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
}
checkWidthMin(nodep);
nodep->iterateChildrenConst(*this);
@ -244,8 +244,8 @@ private:
processAndIterate(nodep);
if (v3Global.assertDTypesResolved()
&& nodep->brokeLhsMustBeLvalue()
&& nodep->lhsp()->castNodeVarRef()
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
&& VN_IS(nodep->lhsp(), NodeVarRef)
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue()) {
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
}
}

View File

@ -112,9 +112,9 @@ void V3CCtors::evalAsserts() {
funcp->ifdef("VL_DEBUG");
modp->addStmtp(funcp);
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* varp = np->castVar()) {
if (AstVar* varp = VN_CAST(np, Var)) {
if (varp->isPrimaryIn() && !varp->isSc()) {
if (AstBasicDType* basicp = varp->dtypeSkipRefp()->castBasicDType()) {
if (AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
int storedWidth = basicp->widthAlignBytes() * 8;
int lastWordWidth = varp->width() % storedWidth;
if (lastWordWidth != 0) {
@ -143,12 +143,12 @@ void V3CCtors::evalAsserts() {
void V3CCtors::cctorsAll() {
UINFO(2,__FUNCTION__<<": "<<endl);
evalAsserts();
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
// Process each module in turn
{
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* varp = np->castVar()) {
if (AstVar* varp = VN_CAST(np, Var)) {
if (!varp->isIfaceParent() && !varp->isIfaceRef()) {
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
}
@ -160,7 +160,7 @@ void V3CCtors::cctorsAll() {
(modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
"if (0 && vlSymsp && first) {} // Prevent unused\n");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstCoverDecl* coverp = np->castCoverDecl()) {
if (AstCoverDecl* coverp = VN_CAST(np, CoverDecl)) {
AstNode* backp = coverp->backp();
coverp->unlinkFrBack();
configure_coverage.add(coverp);

View File

@ -66,12 +66,12 @@ private:
}
virtual void visit(AstNodeCase* nodep) {
if (nodep->castCase() && nodep->castCase()->casex()) {
if (VN_IS(nodep, Case) && VN_CAST(nodep, Case)->casex()) {
nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)");
}
// Detect multiple defaults
bool hitDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) {
if (hitDefault) {
nodep->v3error("Multiple default statements in case statement.");
@ -84,7 +84,7 @@ private:
{
m_caseExprp = nodep;
nodep->exprp()->accept(*this);
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
itemp->condsp()->iterateAndNext(*this);
}
m_caseExprp = NULL;
@ -93,12 +93,12 @@ private:
virtual void visit(AstConst* nodep) {
// See also neverItem
if (m_caseExprp && nodep->num().isFourState()) {
if (m_caseExprp->castGenCase()) {
if (VN_IS(m_caseExprp, GenCase)) {
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
} else if (VN_IS(m_caseExprp, Case) && VN_CAST(m_caseExprp, Case)->casex()) {
// Don't sweat it, we already complained about casex in general
} else if (m_caseExprp->castCase() && (m_caseExprp->castCase()->casez()
|| m_caseExprp->castCase()->caseInside())) {
} else if (VN_IS(m_caseExprp, Case) && (VN_CAST(m_caseExprp, Case)->casez()
|| VN_CAST(m_caseExprp, Case)->caseInside())) {
if (nodep->num().isUnknown()) {
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
}
@ -151,11 +151,11 @@ private:
bool opaque = false;
m_caseItems = 0;
m_caseNoOverlapsAllCovered = true;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
if (icondp->width() > width) width = icondp->width();
if (icondp->isDouble()) opaque = true;
if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant
if (!VN_IS(icondp, Const)) width = CASE_BARF; // Can't parse; not a constant
m_caseItems++;
}
}
@ -170,10 +170,10 @@ private:
// Now pick up the values for each assignment
// We can cheat and use uint32_t's because we only support narrow case's
bool bitched = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
AstConst* iconstp = icondp->castConst();
AstConst* iconstp = VN_CAST(icondp, Const);
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
if (neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
@ -215,7 +215,7 @@ private:
// Convert valueItem from AstCaseItem* to the expression
// Not done earlier, as we may now have a NULL because it's just a ";" NOP branch
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
m_valueItem[i] = m_valueItem[i]->castCaseItem()->bodysp();
m_valueItem[i] = VN_CAST(m_valueItem[i], CaseItem)->bodysp();
}
return true; // All is fine
}
@ -310,7 +310,7 @@ private:
// the appropriate IF AND terms.
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
bool hadDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (!itemp->condsp()) {
// Default clause. Just make true, we'll optimize it away later
itemp->condsp(new AstConst(itemp->fileline(), AstConst::LogicTrue()));
@ -324,14 +324,14 @@ private:
icondp->unlinkFrBack();
AstNode* condp = NULL; // Default is to use and1p/and2p
AstConst* iconstp = icondp->castConst();
AstConst* iconstp = VN_CAST(icondp, Const);
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
} else if (AstInsideRange* irangep = VN_CAST(icondp, InsideRange)) {
// Similar logic in V3Width::visit(AstInside)
AstNode* ap = AstGte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
@ -387,7 +387,7 @@ private:
AstNode* grouprootp = NULL;
AstIf* groupnextp = NULL;
AstIf* itemnextp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext();
// Expressioned clause

View File

@ -101,7 +101,7 @@ private:
// Otherwise a (uint64)(a>b) would return wrong value, as
// less than has undeterministic signedness.
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
&& !nodep->lhsp()->castCCast()) {
&& !VN_IS(nodep->lhsp(), CCast)) {
insertCast(nodep->lhsp(), VL_WORDSIZE);
}
}
@ -147,9 +147,9 @@ private:
}
virtual void visit(AstVarRef* nodep) {
if (!nodep->lvalue()
&& !nodep->backp()->castCCast()
&& nodep->backp()->castNodeMath()
&& !nodep->backp()->castArraySel()
&& !VN_IS(nodep->backp(), CCast)
&& VN_IS(nodep->backp(), NodeMath)
&& !VN_IS(nodep->backp(), ArraySel)
&& nodep->backp()->width()
&& castSize(nodep) != castSize(nodep->varp())) {
// Cast vars to IData first, else below has upper bits wrongly set

View File

@ -448,7 +448,7 @@ private:
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
AstNode* nodep = vertexp->nodep();
string front = pad(filelineWidth(),nodep->fileline()->ascii()+":")+" "+prefix+" +- ";
if (nodep->castVarScope()) {
if (VN_IS(nodep, VarScope)) {
*m_ofp<<front<<"Variable: "<<nodep->prettyName()<<endl;
}
else {
@ -584,7 +584,7 @@ private:
}
// If multiple domains need to do complicated optimizations
if (senedited) {
senoutp = V3Const::constifyExpensiveEdit(senoutp)->castSenTree();
senoutp = VN_CAST(V3Const::constifyExpensiveEdit(senoutp), SenTree);
}
if (traceDests) {
vertexp->dstDomainSet(true); // Note it's set - domainp may be null, so can't use that
@ -700,11 +700,11 @@ private:
nodep->iterateChildren(*this);
}
virtual void visit(AstSel* nodep) {
if (!nodep->lsbp()->castConst()) setNodeHazard(nodep);
if (!VN_IS(nodep->lsbp(), Const)) setNodeHazard(nodep);
nodep->iterateChildren(*this);
}
virtual void visit(AstNodeSel* nodep) {
if (!nodep->bitp()->castConst()) setNodeHazard(nodep);
if (!VN_IS(nodep->bitp(), Const)) setNodeHazard(nodep);
nodep->iterateChildren(*this);
}

View File

@ -85,7 +85,7 @@ public:
if (!m_tlChgFuncp->stmtsp()) {
m_tlChgFuncp->addStmtsp(new AstCReturn(m_scopetopp->fileline(), callp));
} else {
AstCReturn* returnp = m_tlChgFuncp->stmtsp()->castCReturn();
AstCReturn* returnp = VN_CAST(m_tlChgFuncp->stmtsp(), CReturn);
if (!returnp) m_scopetopp->v3fatalSrc("Lost CReturn in top change function");
// This is currently using AstLogOr which will shortcut the evaluation if
// any function returns true. This is likely what we want and is similar to the logic already in use

View File

@ -78,7 +78,7 @@ private:
if (old_dtypep->width() != width) {
// Since any given dtype's cppWidth() is the same, we can just
// remember one convertion for each, and reuse it
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNodeDType()) {
if (AstNodeDType* new_dtypep = VN_CAST(old_dtypep->user3p(), NodeDType)) {
nodep->dtypep(new_dtypep);
} else {
nodep->dtypeChgWidth(width, nodep->widthMin());
@ -90,8 +90,8 @@ private:
}
void computeCppWidth (AstNode* nodep) {
if (!nodep->user2() && nodep->hasDType()) {
if (nodep->castVar() || nodep->castNodeDType() // Don't want to change variable widths!
|| nodep->dtypep()->skipRefp()->castUnpackArrayDType()) { // Or arrays
if (VN_IS(nodep, Var) || VN_IS(nodep, NodeDType) // Don't want to change variable widths!
|| VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { // Or arrays
} else {
setCppWidth(nodep);
}
@ -230,7 +230,7 @@ private:
computeCppWidth(nodep);
setClean (nodep, false);
// We always clean, as we don't trust those pesky users.
if (!nodep->backp()->castAnd()) {
if (!VN_IS(nodep->backp(), And)) {
insertClean(nodep);
}
insureCleanAndNext (nodep->bodysp());

View File

@ -672,7 +672,7 @@ class GaterVisitor : public GaterBaseVisitor {
AstSenTree* sensesp = nodep->sensesp()->cloneTree(true);
#else
// Make a SenGate
AstSenItem* oldsenitemsp = nodep->sensesp()->sensesp()->castSenItem();
AstSenItem* oldsenitemsp = VN_CAST(nodep->sensesp()->sensesp(), SenItem);
if (!oldsenitemsp) nodep->v3fatalSrc("SenTree doesn't have any SenItem under it");
AstSenTree* sensesp = new AstSenTree(nodep->fileline(),
@ -857,7 +857,7 @@ class GaterVisitor : public GaterBaseVisitor {
AstVarScope* lastvscp = m_stmtVscp;
bool lastpli = m_stmtInPli;
m_directlyUnderAlw = under;
if (nodep->castNodeStmt()) { // Restored below
if (VN_IS(nodep, NodeStmt)) { // Restored below
UINFO(9," Stmt: "<<nodep<<endl);
m_stmtVscp = NULL;
m_stmtInPli = false;
@ -871,7 +871,7 @@ class GaterVisitor : public GaterBaseVisitor {
nodep->iterateChildren(*this);
}
m_directlyUnderAlw = lastdua;
if (nodep->castNodeStmt()) { // Reset what set above; else propagate up to above statement
if (VN_IS(nodep, NodeStmt)) { // Reset what set above; else propagate up to above statement
m_stmtVscp = lastvscp;
m_stmtInPli = lastpli;
}

View File

@ -154,11 +154,11 @@ private:
AstNode* createSenseEquation(AstNodeSenItem* nodesp) {
// Nodep may be a list of elements; we need to walk it
AstNode* senEqnp = NULL;
for (AstNodeSenItem* senp = nodesp; senp; senp=senp->nextp()->castNodeSenItem()) {
for (AstNodeSenItem* senp = nodesp; senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
AstNode* senOnep = NULL;
if (AstSenItem* itemp = senp->castSenItem()) {
if (AstSenItem* itemp = VN_CAST(senp, SenItem)) {
senOnep = createSenItemEquation(itemp);
} else if (AstSenGate* itemp = senp->castSenGate()) {
} else if (AstSenGate* itemp = VN_CAST(senp, SenGate)) {
senOnep = createSenGateEquation(itemp);
} else {
senp->v3fatalSrc("Strange node under sentree");

View File

@ -221,7 +221,7 @@ private:
void walkEmptyFuncs() {
for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) {
AstNode* node1p = it->second;
AstCFunc* oldfuncp = node1p->castCFunc();
AstCFunc* oldfuncp = VN_CAST(node1p, CFunc);
if (oldfuncp
&& oldfuncp->emptyBody()
&& !oldfuncp->dontCombine()) {
@ -238,7 +238,7 @@ private:
for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) {
V3Hash hashval = it->first;
AstNode* node1p = it->second;
if (!node1p->castCFunc()) continue;
if (!VN_IS(node1p, CFunc)) continue;
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes");
for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) {
AstNode* node2p = eqit->second;
@ -247,9 +247,9 @@ private:
if (node1p->user3p() || node2p->user3p()) continue; // Already merged
if (node1p->sameTree(node2p)) { // walk of tree has same comparison
// Replace AstCCall's that point here
replaceFuncWFunc(node2p->castCFunc(), node1p->castCFunc());
replaceFuncWFunc(VN_CAST(node2p, CFunc), VN_CAST(node1p, CFunc));
// Replacement may promote a slow routine to fast path
if (!node2p->castCFunc()->slow()) node1p->castCFunc()->slow(false);
if (!VN_CAST(node2p, CFunc)->slow()) VN_CAST(node1p, CFunc)->slow(false);
}
}
}
@ -265,7 +265,7 @@ private:
pushDeletep(oldfuncp); VL_DANGLING(oldfuncp);
}
void replaceOnlyCallFunc(AstCCall* nodep) {
if (AstCFunc* oldfuncp = nodep->backp()->castCFunc()) {
if (AstCFunc* oldfuncp = VN_CAST(nodep->backp(), CFunc)) {
//oldfuncp->dumpTree(cout,"MAYDEL: ");
if (nodep->nextp()==NULL
&& oldfuncp->initsp()==NULL

File diff suppressed because it is too large Load Diff

View File

@ -200,7 +200,7 @@ private:
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
const ToggleEnt& above,
AstVar* varp, AstVar* chgVarp) { // Constant
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
if (bdtypep->isRanged()) {
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
int index_code = index_docs - bdtypep->lsb();
@ -218,7 +218,7 @@ private:
varp, chgVarp);
}
}
else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
int index_code = index_docs - adtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
@ -230,7 +230,7 @@ private:
newent.cleanup();
}
}
else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) {
else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
int index_code = index_docs - adtypep->lsb();
@ -245,9 +245,9 @@ private:
newent.cleanup();
}
}
else if (AstStructDType* adtypep = dtypep->castStructDType()) {
else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) {
// For now it's packed, so similar to array
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
int index_code = itemp->lsb();
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
@ -261,7 +261,7 @@ private:
newent.cleanup();
}
}
else if (AstUnionDType* adtypep = dtypep->castUnionDType()) {
else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
// Arbitrarially handle only the first member of the union
if (AstMemberDType* itemp = adtypep->membersp()) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
@ -284,9 +284,9 @@ private:
UINFO(4," IF: "<<nodep<<endl);
if (m_checkBlock) {
// An else-if. When we iterate the if, use "elsif" marking
bool elsif = (nodep->elsesp()->castIf()
&& !nodep->elsesp()->castIf()->nextp());
if (elsif) nodep->elsesp()->castIf()->user1(true);
bool elsif = (VN_IS(nodep->elsesp(), If)
&& !VN_CAST(nodep->elsesp(), If)->nextp());
if (elsif) VN_CAST(nodep->elsesp(), If)->user1(true);
//
nodep->ifsp()->iterateAndNext(*this);
if (m_checkBlock && !m_inModOff

View File

@ -82,7 +82,7 @@ private:
AstNode* duporigp = hashed.iteratorNodep(dupit);
// Note hashed will point to the original variable (what's duplicated), not the covertoggle,
// but we need to get back to the covertoggle which is immediately above, so:
AstCoverToggle* removep = duporigp->backp()->castCoverToggle();
AstCoverToggle* removep = VN_CAST(duporigp->backp(), CoverToggle);
if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
UINFO(8," Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
UINFO(8," dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);

View File

@ -125,7 +125,7 @@ private:
void checkDType(AstNodeDType* nodep) {
if (!nodep->generic() // Don't remove generic types
&& m_elimDTypes // dtypes stick around until post-widthing
&& !nodep->castMemberDType() // Keep member names iff upper type exists
&& !VN_IS(nodep, MemberDType) // Keep member names iff upper type exists
) {
m_dtypesp.push_back(nodep);
}
@ -229,7 +229,7 @@ private:
checkAll(nodep);
// Don't let packages with only public variables disappear
// Normal modules may disappear, e.g. if they are parameterized then removed
if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
if (nodep->attrPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
}
virtual void visit(AstVarScope* nodep) {
nodep->iterateChildren(*this);
@ -242,7 +242,7 @@ private:
virtual void visit(AstVar* nodep) {
nodep->iterateChildren(*this);
checkAll(nodep);
if (nodep->isSigPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
if (nodep->isSigPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
if (mightElimVar(nodep)) {
m_varsp.push_back(nodep);
}
@ -254,7 +254,7 @@ private:
nodep->rhsp()->iterateAndNext(*this);
checkAll(nodep);
// Has to be direct assignment without any EXTRACTing.
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
if (varrefp && !m_sideEffect
&& varrefp->varScopep()) { // For simplicity, we only remove post-scoping
m_assignMap.insert(make_pair(varrefp->varScopep(), nodep));
@ -281,7 +281,7 @@ private:
retry=false;
AstNodeModule* nextmodp;
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
nextmodp = modp->nextp()->castNodeModule();
nextmodp = VN_CAST(modp->nextp(), NodeModule);
if (modp->dead() || (modp->level()>2 && modp->user1()==0 && !modp->internal())) {
// > 2 because L1 is the wrapper, L2 is the top user module
UINFO(4," Dead module "<<modp<<endl);
@ -376,9 +376,9 @@ private:
// It's possible that there if a reference to each individual member, but
// not to the dtype itself. Check and don't remove the parent dtype if
// members are still alive.
if ((classp = (*it)->castNodeClassDType())) {
if ((classp = VN_CAST((*it), NodeClassDType))) {
bool cont = true;
for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = memberp->nextp()->castMemberDType()) {
for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = VN_CAST(memberp->nextp(), MemberDType)) {
if (memberp->user1() != 0) {
cont = false;
break;

View File

@ -188,25 +188,25 @@ private:
AstNode* newlhsp = NULL; // NULL = unlink old assign
AstSel* bitselp = NULL;
AstArraySel* arrayselp = NULL;
if (lhsp->castSel()) {
bitselp = lhsp->castSel();
arrayselp = bitselp->fromp()->castArraySel();
if (VN_IS(lhsp, Sel)) {
bitselp = VN_CAST(lhsp, Sel);
arrayselp = VN_CAST(bitselp->fromp(), ArraySel);
} else {
arrayselp = lhsp->castArraySel();
arrayselp = VN_CAST(lhsp, ArraySel);
}
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
if (arrayselp->dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
//
//=== Dimensions: __Vdlyvdim__
std::deque<AstNode*> dimvalp; // Assignment value for each dimension of assignment
AstNode* dimselp=arrayselp;
for (; dimselp->castArraySel(); dimselp=dimselp->castArraySel()->fromp()) {
AstNode* valp = dimselp->castArraySel()->bitp()->unlinkFrBack();
for (; VN_IS(dimselp, ArraySel); dimselp=VN_CAST(dimselp, ArraySel)->fromp()) {
AstNode* valp = VN_CAST(dimselp, ArraySel)->bitp()->unlinkFrBack();
dimvalp.push_front(valp);
}
AstVarRef* varrefp = dimselp->castVarRef();
AstVarRef* varrefp = VN_CAST(dimselp, VarRef);
if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels");
if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
varrefp->unlinkFrBack();
@ -216,7 +216,7 @@ private:
std::deque<AstNode*> dimreadps; // Read value for each dimension of assignment
for (unsigned dimension=0; dimension<dimvalp.size(); dimension++) {
AstNode* dimp = dimvalp[dimension];
if (dimp->castConst()) { // bit = const, can just use it
if (VN_IS(dimp, Const)) { // bit = const, can just use it
dimreadps.push_front(dimp);
} else {
string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension)
@ -235,7 +235,7 @@ private:
AstNode* bitreadp=NULL; // Code to read Vdlyvlsb
if (bitselp) {
AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack();
if (bitselp->fromp()->castConst()) {// vlsb = constant, can just push constant into where we use it
if (VN_IS(bitselp->fromp(), Const)) { // vlsb = constant, can just push constant into where we use it
bitreadp = lsbvaluep;
} else {
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
@ -250,7 +250,7 @@ private:
//
//=== Value: __Vdlyvval__
AstNode* valreadp; // Code to read Vdlyvval
if (nodep->rhsp()->castConst()) { // vval = constant, can just push constant into where we use it
if (VN_IS(nodep->rhsp(), Const)) { // vval = constant, can just push constant into where we use it
valreadp = nodep->rhsp()->unlinkFrBack();
} else {
string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
@ -268,7 +268,7 @@ private:
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
// This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something;
setvscp = nodep->user3p()->castVarScope();
setvscp = VN_CAST(nodep->user3p(), VarScope);
++m_statSharedSet;
} else { // Create new one
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
@ -303,9 +303,9 @@ private:
// Build "IF (changeit) ...
UINFO(9," For "<<setvscp<<endl);
UINFO(9," & "<<varrefp<<endl);
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castAlwaysPost();
AstAlwaysPost* finalp = VN_CAST(varrefp->varScopep()->user4p(), AlwaysPost);
if (finalp) {
AstActive* oldactivep = finalp->user2p()->castActive();
AstActive* oldactivep = VN_CAST(finalp->user2p(), Active);
checkActivePost(varrefp, oldactivep);
if (setinitp) oldactivep->addStmtsp(setinitp);
} else { // first time we've dealt with this memory
@ -321,7 +321,7 @@ private:
if (finalp->user3p() == setvscp) {
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
// we can share the IF statement too
postLogicp = finalp->user4p()->castIf();
postLogicp = VN_CAST(finalp->user4p(), If);
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
} else {
postLogicp = new AstIf (nodep->fileline(),
@ -363,11 +363,11 @@ private:
}
virtual void visit(AstAssignDly* nodep) {
m_inDly = true;
m_nextDlyp = nodep->nextp()->castAssignDly(); // Next assignment in same block, maybe NULL.
m_nextDlyp = VN_CAST(nodep->nextp(), AssignDly); // Next assignment in same block, maybe NULL.
if (m_cfuncp) nodep->v3error("Unsupported: Delayed assignment inside public function/task");
if (nodep->lhsp()->castArraySel()
|| (nodep->lhsp()->castSel()
&& nodep->lhsp()->castSel()->fromp()->castArraySel())) {
if (VN_IS(nodep->lhsp(), ArraySel)
|| (VN_IS(nodep->lhsp(), Sel)
&& VN_IS(VN_CAST(nodep->lhsp(), Sel)->fromp(), ArraySel))) {
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* newlhsp = createDlyArray(nodep, lhsp);
if (m_inLoop) nodep->v3warn(BLKLOOPINIT,"Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)");
@ -394,9 +394,9 @@ private:
if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
AstVarScope* oldvscp = nodep->varScopep();
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
AstVarScope* dlyvscp = oldvscp->user1p()->castVarScope();
AstVarScope* dlyvscp = VN_CAST(oldvscp->user1p(), VarScope);
if (dlyvscp) { // Multiple use of delayed variable
AstActive* oldactivep = dlyvscp->user2p()->castActive();
AstActive* oldactivep = VN_CAST(dlyvscp->user2p(), Active);
checkActivePost(nodep, oldactivep);
}
if (!dlyvscp) { // First use of this delayed variable

View File

@ -122,7 +122,7 @@ private:
if (m_stmtp
&& (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it
&& (m_maxdepth-m_depth) > v3Global.opt.compLimitParens()
&& !nodep->backp()->castNodeStmt() // Not much point if we're about to use it
&& !VN_IS(nodep->backp(), NodeStmt) // Not much point if we're about to use it
) {
m_maxdepth = m_depth;
createDeepTemp(nodep);

View File

@ -98,7 +98,7 @@ private:
void visitStmt(AstNodeStmt* nodep) {
m_depth++;
if (m_depth > v3Global.opt.compLimitBlocks()
&& !nodep->castCCall()) { // Already done
&& !VN_IS(nodep, CCall)) { // Already done
UINFO(4, "DeepBlocks "<<m_depth<<" "<<nodep<<endl);
AstNode* backp = nodep->backp(); // Only for debug
if (debug()>=9) backp->dumpTree(cout,"- pre : ");

View File

@ -68,7 +68,7 @@ private:
// True iff there's exactly one instance of this module in the design.
int instances = 0;
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (stmtp->castScope()) {
if (VN_IS(stmtp, Scope)) {
if (++instances > 1) { return false; }
}
}
@ -187,7 +187,7 @@ private:
funcp->declPrivate(true);
AstNode* argsp = NULL;
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn()) {
AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput());
if (argsp) argsp = argsp->addNextNull(newp);

View File

@ -44,9 +44,11 @@
class EmitCStmts : public EmitCBaseVisitor {
private:
typedef std::vector<const AstVar*> VarVec;
bool m_suppressSemi;
AstVarRef* m_wideTempRefp; // Variable that _WW macros should be setting
std::vector<AstVar*> m_ctorVarsVec; // All variables in constructor order
VarVec m_ctorVarsVec; // All variables in constructor order
int m_splitSize; // # of cfunc nodes placed into output file
int m_splitFilenum; // File number being created, 0 = primary
@ -74,7 +76,7 @@ public:
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
const string& vfmt, char fmtLetter);
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
void emitVarDecl(const AstVar* nodep, const string& prefixIfImp);
typedef enum {EVL_CLASS_IO, EVL_CLASS_SIG, EVL_CLASS_TEMP, EVL_CLASS_PAR, EVL_CLASS_ALL,
EVL_FUNC_ALL} EisWhich;
void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp);
@ -93,10 +95,10 @@ public:
}
void emitOpName(AstNode* nodep, const string& format,
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
void emitDeclArrayBrackets(AstVar* nodep) {
void emitDeclArrayBrackets(const AstVar* nodep) {
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
for (const AstUnpackArrayDType* arrayp=VN_CAST_CONST(nodep->dtypeSkipRefp(), UnpackArrayDType); arrayp;
arrayp = VN_CAST_CONST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
}
@ -104,7 +106,7 @@ public:
void emitTypedefs(AstNode* firstp) {
bool first = true;
for (AstNode* loopp=firstp; loopp; loopp = loopp->nextp()) {
if (AstTypedef* nodep = loopp->castTypedef()) {
if (const AstTypedef* nodep = VN_CAST(loopp, Typedef)) {
if (nodep->attrPublic()) {
if (first) {
first = false;
@ -113,16 +115,16 @@ public:
} else {
puts("\n");
}
if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) {
if (const AstEnumDType* adtypep = VN_CAST(nodep->dtypep()->skipRefToEnump(), EnumDType)) {
if (adtypep->width()>64) {
putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
} else {
puts("enum "+nodep->name()+" {\n");
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), EnumItem)) {
puts(itemp->name());
puts(" = ");
itemp->valuep()->iterateAndNext(*this);
if (itemp->nextp()->castEnumItem()) puts(",");
if (VN_IS(itemp->nextp(), EnumItem)) puts(",");
puts("\n");
}
puts("};\n");
@ -136,7 +138,7 @@ public:
// VISITORS
virtual void visit(AstNodeAssign* nodep) {
bool paren = true; bool decind = false;
if (AstSel* selp=nodep->lhsp()->castSel()) {
if (AstSel* selp=VN_CAST(nodep->lhsp(), Sel)) {
if (selp->widthMin()==1) {
putbs("VL_ASSIGNBIT_");
emitIQW(selp->fromp());
@ -173,12 +175,12 @@ public:
puts(cvtToStr(nodep->widthMin())+",");
nodep->lhsp()->iterateAndNext(*this); puts(", ");
} else if (nodep->isWide()
&& nodep->lhsp()->castVarRef()
&& !nodep->rhsp()->castCMath()
&& !nodep->rhsp()->castVarRef()
&& !nodep->rhsp()->castArraySel()) {
&& VN_IS(nodep->lhsp(), VarRef)
&& !VN_IS(nodep->rhsp(), CMath)
&& !VN_IS(nodep->rhsp(), VarRef)
&& !VN_IS(nodep->rhsp(), ArraySel)) {
// Wide functions assign into the array directly, don't need separate assign statement
m_wideTempRefp = nodep->lhsp()->castVarRef();
m_wideTempRefp = VN_CAST(nodep->lhsp(), VarRef);
paren = false;
} else if (nodep->isWide()) {
putbs("VL_ASSIGN_W(");
@ -189,7 +191,7 @@ public:
nodep->lhsp()->iterateAndNext(*this);
puts(" ");
ofp()->blockInc(); decind = true;
if (!nodep->rhsp()->castConst()) ofp()->putBreak();
if (!VN_IS(nodep->rhsp(), Const)) ofp()->putBreak();
puts("= ");
}
nodep->rhsp()->iterateAndNext(*this);
@ -210,7 +212,7 @@ public:
subnodep->accept(*this);
comma = true;
}
if (nodep->backp()->castNodeMath() || nodep->backp()->castCReturn()) {
if (VN_IS(nodep->backp(), NodeMath) || VN_IS(nodep->backp(), CReturn)) {
// We should have a separate CCall for math and statement usage, but...
puts(")");
} else {
@ -332,9 +334,9 @@ public:
putbs(",");
uint32_t array_lsb = 0;
{
AstVarRef* varrefp = nodep->memp()->castVarRef();
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
if (!varrefp) { nodep->v3error("Readmem loading non-variable"); }
else if (AstUnpackArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castUnpackArrayDType()) {
else if (const AstUnpackArrayDType* adtypep = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
array_lsb = adtypep->lsb();
}
@ -496,7 +498,7 @@ public:
}
virtual void visit(AstRedXor* nodep) {
if (nodep->lhsp()->isWide()) {
visit(nodep->castNodeUniop());
visit(VN_CAST(nodep, NodeUniop));
} else {
putbs("VL_REDXOR_");
puts(cvtToStr(nodep->lhsp()->dtypep()->widthPow2()));
@ -509,31 +511,31 @@ public:
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(nodep->castNodeBiop());
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPow* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(nodep->castNodeBiop());
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowSS* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(nodep->castNodeBiop());
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowSU* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(nodep->castNodeBiop());
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowUS* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(nodep->castNodeBiop());
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstCCast* nodep) {
// Extending a value of the same word width is just a NOP.
@ -562,7 +564,7 @@ public:
}
virtual void visit(AstReplicate* nodep) {
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
if (((int)nodep->rhsp()->castConst()->toUInt()
if (((int)VN_CAST(nodep->rhsp(), Const)->toUInt()
* nodep->lhsp()->widthMin()) != nodep->widthMin())
nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
puts("VL_REPLICATE_");
@ -581,8 +583,8 @@ public:
virtual void visit(AstStreamL* nodep) {
// Attempt to use a "fast" stream function for slice size = power of 2
if (!nodep->isWide()) {
uint32_t isPow2 = nodep->rhsp()->castConst()->num().countOnes() == 1;
uint32_t sliceSize = nodep->rhsp()->castConst()->toUInt();
uint32_t isPow2 = VN_CAST(nodep->rhsp(), Const)->num().countOnes() == 1;
uint32_t sliceSize = VN_CAST(nodep->rhsp(), Const)->toUInt();
if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) {
puts("VL_STREAML_FAST_");
emitIQW(nodep);
@ -593,7 +595,7 @@ public:
puts(","+cvtToStr(nodep->rhsp()->widthMin()));
puts(",");
nodep->lhsp()->iterateAndNext(*this); puts(", ");
uint32_t rd_log2 = V3Number::log2b(nodep->rhsp()->castConst()->toUInt());
uint32_t rd_log2 = V3Number::log2b(VN_CAST(nodep->rhsp(), Const)->toUInt());
puts(cvtToStr(rd_log2)+")");
return;
}
@ -606,7 +608,7 @@ public:
puts(nodep->varp()->name());
}
void emitCvtPackStr(AstNode* nodep) {
if (AstConst* constp = nodep->castConst()) {
if (const AstConst* constp = VN_CAST(nodep, Const)) {
putbs("std::string(");
putsQuoted(constp->num().toString());
puts(")");
@ -656,7 +658,7 @@ public:
puts(",");
if (!assigntop) {
puts(assignString);
} else if (assigntop->castVarRef()) {
} else if (VN_IS(assigntop, VarRef)) {
puts(assigntop->hiername());
puts(assigntop->varp()->name());
} else {
@ -677,7 +679,7 @@ public:
puts(",");
if (!assigntop) {
puts(assignString);
} else if (assigntop->castVarRef()) {
} else if (VN_IS(assigntop, VarRef)) {
puts(assigntop->hiername());
puts(assigntop->varp()->name());
} else {
@ -790,8 +792,8 @@ class EmitCImp : EmitCStmts {
AstNode* lhsp = changep->lhsp();
AstNode* rhsp = changep->rhsp();
static int addDoubleOr = 10; // Determined experimentally as best
if (!lhsp->castVarRef() && !lhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
if (!rhsp->castVarRef() && !rhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
if (!VN_IS(lhsp, VarRef) && !VN_IS(lhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
if (!VN_IS(rhsp, VarRef) && !VN_IS(rhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
for (int word=0; word<changep->lhsp()->widthWords(); word++) {
if (!gotOne) {
gotOne = true;
@ -887,7 +889,7 @@ class EmitCImp : EmitCStmts {
if (nodep->initsp()) putsDecoration("// Variables\n");
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* varp=subnodep->castVar()) {
if (AstVar* varp=VN_CAST(subnodep, Var)) {
if (varp->isFuncReturn()) emitVarDecl(varp, "");
}
}
@ -937,8 +939,8 @@ class EmitCImp : EmitCStmts {
bool gotOneIgnore = false;
doubleOrDetect(nodep, gotOneIgnore);
string varname;
if (nodep->lhsp()->castVarRef()) {
varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName();
if (VN_IS(nodep->lhsp(), VarRef)) {
varname = ": "+VN_CAST(nodep->lhsp(), VarRef)->varp()->prettyName();
}
puts(")) VL_DBG_MSGF(\" CHANGE: "+nodep->fileline()->ascii()
+varname+"\\n\"); );\n");
@ -996,7 +998,7 @@ public:
//######################################################################
// Internal EmitCStmts
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
if (nodep->isIO()) {
if (nodep->isSc()) {
@ -1077,9 +1079,9 @@ void EmitCStmts::emitVarCtors() {
puts("\n");
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
bool first = true;
for (std::vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
AstVar* varp = *it;
bool isArray = !varp->dtypeSkipRefp()->castBasicDType();
for (VarVec::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
const AstVar* varp = *it;
bool isArray = !VN_CAST(varp->dtypeSkipRefp(), BasicDType);
if (isArray) {
puts("// Skipping array: ");
puts(varp->name());
@ -1230,17 +1232,17 @@ struct EmitDispState {
void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
if (emitDispState.m_format == ""
&& nodep->castDisplay()) { // not fscanf etc, as they need to return value
&& VN_IS(nodep, Display)) { // not fscanf etc, as they need to return value
// NOP
} else {
// Format
bool isStmt = false;
if (AstFScanF* dispp = nodep->castFScanF()) {
if (const AstFScanF* dispp = VN_CAST(nodep, FScanF)) {
isStmt = false;
puts("VL_FSCANF_IX(");
dispp->filep()->iterate(*this);
puts(",");
} else if (AstSScanF* dispp = nodep->castSScanF()) {
} else if (const AstSScanF* dispp = VN_CAST(nodep, SScanF)) {
isStmt = false;
checkMaxWords(dispp->fromp());
puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X(");
@ -1248,7 +1250,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
puts(",");
dispp->fromp()->iterate(*this);
puts(",");
} else if (AstDisplay* dispp = nodep->castDisplay()) {
} else if (const AstDisplay* dispp = VN_CAST(nodep, Display)) {
isStmt = true;
if (dispp->filep()) {
puts("VL_FWRITEF(");
@ -1257,14 +1259,14 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
} else {
puts("VL_WRITEF(");
}
} else if (AstSFormat* dispp = nodep->castSFormat()) {
} else if (const AstSFormat* dispp = VN_CAST(nodep, SFormat)) {
isStmt = true;
puts("VL_SFORMAT_X(");
puts(cvtToStr(dispp->lhsp()->widthMin()));
putbs(",");
dispp->lhsp()->iterate(*this);
putbs(",");
} else if (AstSFormatF* dispp = nodep->castSFormatF()) {
} else if (const AstSFormatF* dispp = VN_CAST(nodep, SFormatF)) {
isStmt = false;
if (dispp) {}
puts("VL_SFORMATF_NX(");
@ -1424,21 +1426,21 @@ void EmitCImp::emitVarReset(AstVar* varp) {
// If an ARRAYINIT we initialize it using an initial block similar to a signal
//puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n");
}
else if (AstInitArray* initarp = varp->valuep()->castInitArray()) {
if (AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType()) {
else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) {
if (AstUnpackArrayDType* arrayp = VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType)) {
if (initarp->defaultp()) {
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
puts("{ int __Vi=0;");
puts(" for (; __Vi<"+cvtToStr(arrayp->elementsConst()));
puts("; ++__Vi) {\n");
emitSetVarConstant(varp->name()+"[__Vi]", initarp->defaultp()->castConst());
emitSetVarConstant(varp->name()+"[__Vi]", VN_CAST(initarp->defaultp(), Const));
puts("}}\n");
}
int pos = 0;
for (AstNode* itemp = initarp->initsp(); itemp; ++pos, itemp=itemp->nextp()) {
int index = initarp->posIndex(pos);
if (!initarp->defaultp() && index!=pos) initarp->v3fatalSrc("Not enough values in array initalizement");
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", itemp->castConst());
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", VN_CAST(itemp, Const));
}
} else {
varp->v3fatalSrc("InitArray under non-arrayed var");
@ -1450,8 +1452,9 @@ void EmitCImp::emitVarReset(AstVar* varp) {
else {
int vects = 0;
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
@ -1588,7 +1591,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
// OK if this hash includes some things we won't dump, since just looking for loading the wrong model
VHashSha1 hash;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) {
hash.insert(varp->name());
hash.insert(varp->dtypep()->width());
}
@ -1604,7 +1607,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
// Save all members
if (v3Global.opt.inhibitSim()) puts("os"+op+"__Vm_inhibitSim;\n");
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) {
if (varp->isIO() && modp->isTop() && optSystemC()) {
// System C top I/O doesn't need loading, as the lower level subinst code does it.
}
@ -1613,8 +1616,9 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
else {
int vects = 0;
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
@ -1658,7 +1662,7 @@ void EmitCImp::emitStaticDecl(AstNodeModule* modp) {
void EmitCImp::emitTextSection(AstType type) {
int last_line = -999;
for (AstNode* nodep = m_modp->stmtsp(); nodep != NULL; nodep = nodep->nextp()) {
if (AstNodeText* textp = nodep->castNodeText()) {
if (const AstNodeText* textp = VN_CAST(nodep, NodeText)) {
if (nodep->type() == type) {
if (last_line != nodep->fileline()->lineno()) {
if (last_line < 0) {
@ -1687,7 +1691,7 @@ void EmitCImp::emitCellCtors(AstNodeModule* modp) {
puts(EmitCBaseVisitor::symTopAssign()+"\n");
}
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
puts("VL_CELL ("+cellp->name()+", "+modClassName(cellp->modp())+");\n");
}
}
@ -1700,12 +1704,13 @@ void EmitCImp::emitSensitives() {
putsDecoration("// Sensitivities on all clocks and combo inputs\n");
puts("SC_METHOD(eval);\n");
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) {
if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) {
int vects = 0;
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
@ -1799,7 +1804,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
// Largest->smallest reduces the number of pad variables.
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
// TODO: Move this sort to an earlier visitor stage.
typedef std::multimap<int, AstVar*> VarSortMap;
typedef std::multimap<int, const AstVar*> VarSortMap;
VarSortMap varAnonMap;
VarSortMap varNonanonMap;
int anonMembers = 0;
@ -1807,13 +1812,13 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
for (int isstatic=1; isstatic>=0; isstatic--) {
if (prefixIfImp!="" && !isstatic) continue;
for (AstNode* nodep=firstp; nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) {
bool doit = true;
switch (which) {
case EVL_CLASS_IO: doit = varp->isIO(); break;
case EVL_CLASS_SIG: doit = (varp->isSignal() && !varp->isIO()); break;
case EVL_CLASS_TEMP: doit = (varp->isTemp() && !varp->isIO()); break;
case EVL_CLASS_PAR: doit = (varp->isParam() && !varp->valuep()->castConst()); break;
case EVL_CLASS_PAR: doit = (varp->isParam() && !VN_IS(varp->valuep(), Const)); break;
case EVL_CLASS_ALL: doit = true; break;
case EVL_FUNC_ALL: doit = true; break;
default: v3fatalSrc("Bad Case");
@ -1823,7 +1828,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes();
int sortbytes = 9;
if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0;
else if (varp->dtypeSkipRefp()->castUnpackArrayDType()) sortbytes=8;
else if (VN_IS(varp->dtypeSkipRefp(), UnpackArrayDType)) sortbytes=8;
else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7;
else if (varp->isScBv() || varp->isScBigUint()) sortbytes=6;
else if (sigbytes==8) sortbytes=5;
@ -1873,7 +1878,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
for (int l1=0; l1<anonL1s && it != varAnonMap.end(); ++l1) {
if (anonL1s != 1) puts("struct {\n");
for (int l0=0; l0<lim && it != varAnonMap.end(); ++l0) {
AstVar* varp = it->second;
const AstVar* varp = it->second;
emitVarDecl(varp, prefixIfImp);
++it;
}
@ -1885,13 +1890,13 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
}
// Leftovers, just in case off by one error somewhere above
for (; it != varAnonMap.end(); ++it) {
AstVar* varp = it->second;
const AstVar* varp = it->second;
emitVarDecl(varp, prefixIfImp);
}
}
// Output nonanons
for (VarSortMap::iterator it = varNonanonMap.begin(); it != varNonanonMap.end(); ++it) {
AstVar* varp = it->second;
const AstVar* varp = it->second;
emitVarDecl(varp, prefixIfImp);
}
}
@ -1903,10 +1908,11 @@ struct CmpName {
};
void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
std::vector<AstCFunc*> funcsp;
typedef std::vector<const AstCFunc*> FuncVec;
FuncVec funcsp;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCFunc* funcp = nodep->castCFunc()) {
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
if (!funcp->skipDecl()) {
funcsp.push_back(funcp);
}
@ -1915,8 +1921,8 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
stable_sort(funcsp.begin(), funcsp.end(), CmpName());
for (std::vector<AstCFunc*>::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
AstCFunc* funcp = *it;
for (FuncVec::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
const AstCFunc* funcp = *it;
if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
ofp()->putsPrivate(funcp->declPrivate());
if (funcp->ifdef()!="") puts("#ifdef "+funcp->ifdef()+"\n");
@ -1961,7 +1967,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
puts("class "+symClassName()+";\n");
vl_unordered_set<string> didClassName;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
string className = modClassName(cellp->modp());
if (didClassName.find(className)==didClassName.end()) {
puts("class "+className+";\n");
@ -1987,7 +1993,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
{ // Instantiated cells
bool did = false;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
if (!did) {
did = true;
putsDecoration("// CELLS\n");
@ -2031,17 +2037,17 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->putsPrivate(false); // public:
emitVarList(modp->stmtsp(), EVL_CLASS_PAR, ""); // Only those that are non-CONST
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) {
if (varp->isParam() && (varp->isUsedParam() || varp->isSigPublic())) {
if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?");
// These should be static const values, however microsloth VC++ doesn't
// support them. They also cause problems with GDB under GCC2.95.
if (varp->isWide()) { // Unsupported for output
putsDecoration("// enum WData "+varp->name()+" //wide");
} else if (!varp->valuep()->castConst()) { // Unsupported for output
} else if (!VN_IS(varp->valuep(), Const)) { // Unsupported for output
//putsDecoration("// enum ..... "+varp->name()+" //not simple value, see variable above instead");
} else if (varp->dtypep()->castBasicDType()
&& varp->dtypep()->castBasicDType()->isOpaque()) { // Can't put out e.g. doubles
} else if (VN_IS(varp->dtypep(), BasicDType)
&& VN_CAST(varp->dtypep(), BasicDType)->isOpaque()) { // Can't put out e.g. doubles
} else {
puts("enum ");
puts(varp->isQuad()?"_QData":"_IData");
@ -2226,7 +2232,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
emitImp (modp);
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCFunc* funcp = nodep->castCFunc()) {
if (AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
if (splitNeeded()) {
// Close old file
delete m_ofp; m_ofp=NULL;
@ -2329,21 +2335,21 @@ class EmitCTrace : EmitCStmts {
}
bool emitTraceIsScBv(AstTraceInc* nodep) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
if (!varrefp) return false;
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScBv();
}
bool emitTraceIsScBigUint(AstTraceInc* nodep) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
if (!varrefp) return false;
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScBigUint();
}
bool emitTraceIsScUint(AstTraceInc* nodep) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
if (!varrefp) return false;
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScUint();
@ -2404,8 +2410,8 @@ class EmitCTrace : EmitCStmts {
puts(");\n");
}
void emitTraceValue(AstTraceInc* nodep, int arrayindex) {
if (nodep->valuep()->castVarRef()) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
if (VN_IS(nodep->valuep(), VarRef)) {
AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
AstVar* varp = varrefp->varp();
puts("(");
if (emitTraceIsScBigUint(nodep)) puts("(vluint32_t*)");
@ -2534,7 +2540,7 @@ public:
void V3EmitC::emitc() {
UINFO(2,__FUNCTION__<<": "<<endl);
// Process each module in turn
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
if (v3Global.opt.outputSplit()) {
{ EmitCImp imp; imp.main(nodep, false, true); }
{ EmitCImp imp; imp.main(nodep, true, false); }

View File

@ -66,12 +66,12 @@ public:
v3Global.rootp()->addFilesp(cfilep);
return cfilep;
}
string cFuncArgs(AstCFunc* nodep) {
string cFuncArgs(const AstCFunc* nodep) {
// Return argument list for given C function
string args = nodep->argTypes();
// Might be a user function with argument list.
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
for (const AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (const AstVar* portp = VN_CAST_CONST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args+= ", ";
if (nodep->dpiImport() || nodep->dpiExportWrapper())

View File

@ -278,7 +278,7 @@ void EmitCSyms::emitSymHdr() {
// for
puts("\n// INCLUDE MODULE CLASSES\n");
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
puts("#include \""+modClassName(nodep)+".h\"\n");
}
@ -369,7 +369,7 @@ void EmitCSyms::emitSymImp() {
// Includes
puts("#include \""+symClassName()+".h\"\n");
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
puts("#include \""+modClassName(nodep)+".h\"\n");
}
@ -481,10 +481,10 @@ void EmitCSyms::emitSymImp() {
}
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
bounds += " ,"; bounds += cvtToStr(adtypep->msb());
bounds += ","; bounds += cvtToStr(adtypep->lsb());
if (dtypep->castPackArrayDType()) pdim++; else udim++;
if (VN_IS(dtypep, PackArrayDType)) pdim++; else udim++;
dtypep = adtypep->subDTypep();
}
else break; // AstBasicDType - nothing below, 1
@ -628,7 +628,7 @@ void EmitCSyms::emitDpiImp() {
puts("return "+topClassName()+"::"+nodep->name()+"(");
string args;
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args+= ", ";
args += portp->name();

View File

@ -102,7 +102,7 @@ public:
else if (support==2 && slow) {
}
else {
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) {
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=VN_CAST(nodep->nextp(), CFile)) {
if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) {
putMakeClassEntry(of, nodep->name());
}

View File

@ -170,7 +170,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
virtual void visit(AstNodeCase* nodep) {
putfs(nodep,"");
if (AstCase* casep = nodep->castCase()) {
if (const AstCase* casep = VN_CAST(nodep, Case)) {
if (casep->priorityPragma()) puts("priority ");
if (casep->uniquePragma()) puts("unique ");
if (casep->unique0Pragma()) puts("unique0 ");
@ -179,7 +179,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
puts(" (");
nodep->exprp()->iterateAndNext(*this);
puts(")\n");
if (AstCase* casep = nodep->castCase()) {
if (const AstCase* casep = VN_CAST(nodep, Case)) {
if (casep->fullPragma() || casep->parallelPragma()) {
puts(" // synopsys");
if (casep->fullPragma()) puts(" full_case");
@ -316,7 +316,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
virtual void visit(AstNodeIf* nodep) {
putfs(nodep,"");
if (AstIf* ifp = nodep->castIf()) {
if (const AstIf* ifp = VN_CAST(nodep, If)) {
if (ifp->priorityPragma()) puts("priority ");
if (ifp->uniquePragma()) puts("unique ");
if (ifp->unique0Pragma()) puts("unique0 ");
@ -462,10 +462,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
virtual void visit(AstRange* nodep) {
puts("[");
if (nodep->msbp()->castConst() && nodep->lsbp()->castConst()) {
if (VN_IS(nodep->msbp(), Const) && VN_IS(nodep->lsbp(), Const)) {
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
puts(cvtToStr(nodep->leftp()->castConst()->toSInt())); puts(":");
puts(cvtToStr(nodep->rightp()->castConst()->toSInt())); puts("]");
puts(cvtToStr(VN_CAST(nodep->leftp(), Const)->toSInt())); puts(":");
puts(cvtToStr(VN_CAST(nodep->rightp(), Const)->toSInt())); puts("]");
} else {
nodep->leftp()->iterateAndNext(*this); puts(":");
nodep->rightp()->iterateAndNext(*this); puts("]");
@ -473,19 +473,19 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
virtual void visit(AstSel* nodep) {
nodep->fromp()->iterateAndNext(*this); puts("[");
if (nodep->lsbp()->castConst()) {
if (VN_IS(nodep->lsbp(), Const)) {
if (nodep->widthp()->isOne()) {
if (nodep->lsbp()->castConst()) {
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()));
if (VN_IS(nodep->lsbp(), Const)) {
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()));
} else {
nodep->lsbp()->iterateAndNext(*this);
}
} else {
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()
+nodep->widthp()->castConst()->toSInt()
-1));
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()
+ VN_CAST(nodep->widthp(), Const)->toSInt()
- 1));
puts(":");
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()));
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()));
}
} else {
nodep->lsbp()->iterateAndNext(*this); putfs(nodep,"+:");
@ -725,7 +725,7 @@ void V3EmitV::emitv() {
EmitVFileVisitor visitor (v3Global.rootp(), &of);
} else {
// Process each module in turn
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
V3OutVFile of (v3Global.opt.makeDir()
+"/"+EmitCBaseVisitor::modClassName(modp)+"__Vout.v");
of.putsHeader();

View File

@ -76,10 +76,10 @@ class EmitXmlFileVisitor : public AstNVisitor {
void outputTag(AstNode* nodep, string tag) {
if (tag=="") tag = VString::downcase(nodep->typeName());
puts("<"+tag+" "+nodep->fileline()->xml());
if (nodep->castNodeDType()) { puts(" id="); outputId(nodep); }
if (VN_IS(nodep, NodeDType)) { puts(" id="); outputId(nodep); }
if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); }
if (nodep->tag()!="") { puts(" tag="); putsQuoted(nodep->tag()); }
if (AstNodeDType* dtp = nodep->castNodeDType()) {
if (AstNodeDType* dtp = VN_CAST(nodep, NodeDType)) {
if (dtp->subDTypep()) { puts(" sub_dtype_id="); outputId(dtp->subDTypep()->skipRefp()); }
} else {
if (nodep->dtypep()) { puts(" dtype_id="); outputId(nodep->dtypep()->skipRefp()); }

View File

@ -107,7 +107,7 @@ private:
void fixCloneLvalue (AstNode* nodep) {
// In AstSel transforms, we call clone() on VarRefs that were lvalues,
// but are now being used on the RHS of the assignment
if (nodep->castVarRef()) nodep->castVarRef()->lvalue(false);
if (VN_IS(nodep, VarRef)) VN_CAST(nodep, VarRef)->lvalue(false);
// Iterate
if (nodep->op1p()) fixCloneLvalue(nodep->op1p());
if (nodep->op2p()) fixCloneLvalue(nodep->op2p());
@ -178,9 +178,9 @@ private:
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
// Return equation to get the VL_BITWORD of a constant or non-constant
if (lsbp->castConst()) {
if (VN_IS(lsbp, Const)) {
return new AstConst (lsbp->fileline(),
wordAdder + VL_BITWORD_I(lsbp->castConst()->toUInt()));
wordAdder + VL_BITWORD_I(VN_CAST(lsbp, Const)->toUInt()));
} else {
AstNode* shiftp = new AstShiftR (lsbp->fileline(),
lsbp->cloneTree(true),
@ -201,17 +201,17 @@ private:
// If there's a CONDBOUND safety to keep arrays in bounds,
// we're going to AND it to a value that always fits inside a
// word, so we don't need it.
//if (nodep->castCondBound() && nodep->castCondBound()->lhsp()->castLte()) {
// nodep = nodep->castCondBound()->rhsp();
//if (VN_IS(nodep, CondBound) && VN_IS(VN_CAST(nodep, CondBound)->lhsp(), Lte)) {
// nodep = VN_CAST(nodep, CondBound)->rhsp();
//}
return nodep;
}
AstNode* newSelBitBit(AstNode* lsbp) {
// Return equation to get the VL_BITBIT of a constant or non-constant
if (lsbp->castConst()) {
if (VN_IS(lsbp, Const)) {
return new AstConst (lsbp->fileline(),
VL_BITBIT_I(lsbp->castConst()->toUInt()));
VL_BITBIT_I(VN_CAST(lsbp, Const)->toUInt()));
} else {
return new AstAnd (lsbp->fileline(),
new AstConst(lsbp->fileline(), VL_WORDSIZE-1),
@ -243,7 +243,7 @@ private:
}
bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) {
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
if (nodep->dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
for (int w=0; w<nodep->widthWords(); w++) {
addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
}
@ -352,7 +352,7 @@ private:
nodep->iterateChildren(*this);
// Remember, Sel's may have non-integer rhs, so need to optimize for that!
if (nodep->widthMin()!=(int)nodep->widthConst()) nodep->v3fatalSrc("Width mismatch");
if (nodep->backp()->castNodeAssign() && nodep==nodep->backp()->castNodeAssign()->lhsp()) {
if (VN_IS(nodep->backp(), NodeAssign) && nodep==VN_CAST(nodep->backp(), NodeAssign)->lhsp()) {
// Sel is an LHS assignment select
} else if (nodep->isWide()) {
// See under ASSIGN(WIDE)
@ -460,7 +460,7 @@ private:
bool expandWide (AstNodeAssign* nodep, AstSel* rhsp) {
if (nodep->widthMin()!=(int)rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
if (rhsp->lsbp()->castConst() && VL_BITBIT_I(rhsp->lsbConst())==0) {
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
int lsb = rhsp->lsbConst();
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
for (int w=0; w<nodep->widthWords(); w++) {
@ -513,7 +513,7 @@ private:
// Yuk.
bool destwide = lhsp->fromp()->isWide();
bool ones = nodep->rhsp()->isAllOnesV();
if (lhsp->lsbp()->castConst()) {
if (VN_IS(lhsp->lsbp(), Const)) {
// The code should work without this constant test, but it won't
// constify as nicely as we'd like.
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
@ -702,7 +702,7 @@ private:
newp = new AstNegate (nodep->fileline(), lhsp);
} else {
UINFO(8," REPLICATE "<<nodep<<endl);
AstConst* constp = nodep->rhsp()->castConst();
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->toUInt();
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
@ -727,7 +727,7 @@ private:
UINFO(8," Wordize ASSIGN(REPLICATE) "<<nodep<<endl);
AstNode* lhsp = rhsp->lhsp();
int lhswidth = lhsp->widthMin();
AstConst* constp = rhsp->rhsp()->castConst();
const AstConst* constp = VN_CAST(rhsp->rhsp(), Const);
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->toUInt();
for (int w=0; w<rhsp->widthWords(); w++) {
@ -777,7 +777,7 @@ private:
newAstWordSelClone (nodep->rhsp(), w));
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
}
if (nodep->castNeq()) {
if (VN_IS(nodep, Neq)) {
newp = new AstNeq (nodep->fileline(),
new AstConst (nodep->fileline(), 0), newp);
} else {
@ -873,36 +873,36 @@ private:
m_stmtp = nodep;
nodep->iterateChildren(*this);
bool did = false;
if (nodep->isWide() && ((nodep->lhsp()->castVarRef()
|| nodep->lhsp()->castArraySel()))
if (nodep->isWide() && ((VN_IS(nodep->lhsp(), VarRef)
|| VN_IS(nodep->lhsp(), ArraySel)))
&& !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC
&& !AstVar::scVarRecurse(nodep->rhsp())) {
if (AstConst* rhsp = nodep->rhsp()->castConst()) {
if (AstConst* rhsp = VN_CAST(nodep->rhsp(), Const)) {
did = expandWide(nodep,rhsp);
} else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) {
} else if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
did = expandWide(nodep,rhsp);
} else if (AstSel* rhsp = nodep->rhsp()->castSel()) {
} else if (AstSel* rhsp = VN_CAST(nodep->rhsp(), Sel)) {
did = expandWide(nodep,rhsp);
} else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) {
} else if (AstArraySel* rhsp = VN_CAST(nodep->rhsp(), ArraySel)) {
did = expandWide(nodep,rhsp);
} else if (AstConcat* rhsp = nodep->rhsp()->castConcat()) {
} else if (AstConcat* rhsp = VN_CAST(nodep->rhsp(), Concat)) {
did = expandWide(nodep,rhsp);
} else if (AstReplicate* rhsp = nodep->rhsp()->castReplicate()) {
} else if (AstReplicate* rhsp = VN_CAST(nodep->rhsp(), Replicate)) {
did = expandWide(nodep,rhsp);
} else if (AstAnd* rhsp = nodep->rhsp()->castAnd()) {
} else if (AstAnd* rhsp = VN_CAST(nodep->rhsp(), And)) {
did = expandWide(nodep,rhsp);
} else if (AstOr* rhsp = nodep->rhsp()->castOr()) {
} else if (AstOr* rhsp = VN_CAST(nodep->rhsp(), Or)) {
did = expandWide(nodep,rhsp);
} else if (AstNot* rhsp = nodep->rhsp()->castNot()) {
} else if (AstNot* rhsp = VN_CAST(nodep->rhsp(), Not)) {
did = expandWide(nodep,rhsp);
} else if (AstXor* rhsp = nodep->rhsp()->castXor()) {
} else if (AstXor* rhsp = VN_CAST(nodep->rhsp(), Xor)) {
did = expandWide(nodep,rhsp);
} else if (AstXnor* rhsp = nodep->rhsp()->castXnor()) {
} else if (AstXnor* rhsp = VN_CAST(nodep->rhsp(), Xnor)) {
did = expandWide(nodep,rhsp);
} else if (AstNodeCond* rhsp = nodep->rhsp()->castNodeCond()) {
} else if (AstNodeCond* rhsp = VN_CAST(nodep->rhsp(), NodeCond)) {
did = expandWide(nodep,rhsp);
}
} else if (AstSel* lhsp = nodep->lhsp()->castSel()) {
} else if (AstSel* lhsp = VN_CAST(nodep->lhsp(), Sel)) {
did = expandLhs(nodep,lhsp);
}
// Cleanup common code

View File

@ -234,19 +234,19 @@ private:
}
virtual void visit(AstNodeAssign* nodep) {
m_substTreep = nodep->rhsp();
if (!nodep->lhsp()->castNodeVarRef())
if (!VN_IS(nodep->lhsp(), NodeVarRef))
clearSimple("ASSIGN(non-VARREF)");
else nodep->iterateChildren(*this);
// We don't push logic other then assignments/NOTs into SenItems
// This avoids a mess in computing what exactly a POSEDGE is
// V3Const cleans up any NOTs by flipping the edges for us
if (m_buffersOnly
&& !(nodep->rhsp()->castVarRef()
&& !(VN_IS(nodep->rhsp(), VarRef)
// Avoid making non-clocked logic into clocked,
// as it slows down the verilator_sim_benchmark
|| (nodep->rhsp()->castNot()
&& nodep->rhsp()->castNot()->lhsp()->castVarRef()
&& nodep->rhsp()->castNot()->lhsp()->castVarRef()->varp()->isUsedClock())
|| (VN_IS(nodep->rhsp(), Not)
&& VN_IS(VN_CAST(nodep->rhsp(), Not)->lhsp(), VarRef)
&& VN_CAST(VN_CAST(nodep->rhsp(), Not)->lhsp(), VarRef)->varp()->isUsedClock())
)) {
clearSimple("Not a buffer (goes to a clock)");
}
@ -342,7 +342,7 @@ private:
m_logicVertexp->clearReducible("Block Unreducible"); // Sequential logic is dedupable
}
if (consumeReason) m_logicVertexp->setConsumed(consumeReason);
if (nodep->castSenItem()) m_logicVertexp->setConsumed("senItem");
if (VN_IS(nodep, SenItem)) m_logicVertexp->setConsumed("senItem");
nodep->iterateChildren(*this);
m_logicVertexp = NULL;
}
@ -508,7 +508,7 @@ private:
m_inSlow = lastslow;
}
virtual void visit(AstConcat* nodep) {
if (nodep->backp()->castNodeAssign() && nodep->backp()->castNodeAssign()->lhsp()==nodep) {
if (VN_IS(nodep->backp(), NodeAssign) && VN_CAST(nodep->backp(), NodeAssign)->lhsp()==nodep) {
nodep->v3fatalSrc("Concat on LHS of assignment; V3Const should have deleted it");
}
nodep->iterateChildren(*this);
@ -702,31 +702,31 @@ void GateVisitor::replaceAssigns() {
// Take the Comments/assigns that were moved to the VarScope and change them to a
// simple value assignment
AstVarScope* vscp = vvertexp->varScp();
if (vscp->valuep() && !vscp->valuep()->castNodeMath()) {
if (vscp->valuep() && !VN_IS(vscp->valuep(), NodeMath)) {
//if (debug()>9) vscp->dumpTree(cout, "-vscPre: ");
while (AstNode* delp=vscp->valuep()->castComment()) {
while (AstNode* delp=VN_CAST(vscp->valuep(), Comment)) {
delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp);
}
if (AstInitial* delp=vscp->valuep()->castInitial()) {
if (AstInitial* delp=VN_CAST(vscp->valuep(), Initial)) {
AstNode* bodyp=delp->bodysp();
bodyp->unlinkFrBackWithNext();
delp->replaceWith(bodyp);
delp->deleteTree(); VL_DANGLING(delp);
}
if (AstAlways* delp=vscp->valuep()->castAlways()) {
if (AstAlways* delp=VN_CAST(vscp->valuep(), Always)) {
AstNode* bodyp=delp->bodysp();
bodyp->unlinkFrBackWithNext();
delp->replaceWith(bodyp);
delp->deleteTree(); VL_DANGLING(delp);
}
if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) {
if (AstNodeAssign* delp=VN_CAST(vscp->valuep(), NodeAssign)) {
AstNode* rhsp=delp->rhsp();
rhsp->unlinkFrBack();
delp->replaceWith(rhsp);
delp->deleteTree(); VL_DANGLING(delp);
}
//if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<<endl;}
if (!vscp->valuep()->castNodeMath()
if (!VN_IS(vscp->valuep(), NodeMath)
|| vscp->valuep()->nextp()) {
vscp->dumpTree(std::cerr, "vscStrange: ");
vscp->v3fatalSrc("Value of varscope not mathematical");
@ -829,8 +829,8 @@ private:
m_didReplace = true;
if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var");
AstNode* substp = m_replaceTreep->cloneTree(false);
if (nodep->castNodeVarRef()
&& substp->castNodeVarRef()
if (VN_IS(nodep, NodeVarRef)
&& VN_IS(substp, NodeVarRef)
&& nodep->same(substp)) {
// Prevent a infinite loop...
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
@ -840,9 +840,9 @@ private:
// IE what we're replacing with.
// However a VARREF should point to the original as it's otherwise confusing
// to throw warnings that point to a PIN rather than where the pin us used.
if (substp->castVarRef()) substp->fileline(nodep->fileline());
if (VN_IS(substp, VarRef)) substp->fileline(nodep->fileline());
// Make the substp an rvalue like nodep. This facilitate the hashing in dedupe.
if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false);
if (AstNodeVarRef* varrefp = VN_CAST(substp, NodeVarRef)) varrefp->lvalue(false);
nodep->replaceWith(substp);
nodep->deleteTree(); VL_DANGLING(nodep);
}
@ -929,7 +929,7 @@ public:
// So dupit is either a different, duplicate rhsp, or the end of the hash.
if (dupit != m_hashed.end()) {
m_hashed.erase(inserted);
return m_hashed.iteratorNodep(dupit)->user2p()->castNodeAssign();
return VN_CAST(m_hashed.iteratorNodep(dupit)->user2p(), NodeAssign);
}
return NULL;
}
@ -1017,7 +1017,7 @@ public:
if (m_dedupable && m_assignp) {
AstNode* lhsp = m_assignp->lhsp();
// Possible todo, handle more complex lhs expressions
if (AstNodeVarRef* lhsVarRefp = lhsp->castNodeVarRef()) {
if (AstNodeVarRef* lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
if (lhsVarRefp->varScopep() != consumerVarScopep) consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign");
if (AstNodeAssign* dup = m_hash.hashAndFindDupe(m_assignp,activep,m_ifCondp)) {
return (AstNodeVarRef*) dup->lhsp();
@ -1157,13 +1157,13 @@ private:
// assemble two Sel into one if possible
AstSel* merge(AstSel* pre, AstSel* cur) {
AstVarRef* preVarRefp = pre->fromp()->castVarRef();
AstVarRef* curVarRefp = cur->fromp()->castVarRef();
AstVarRef* preVarRefp = VN_CAST(pre->fromp(), VarRef);
AstVarRef* curVarRefp = VN_CAST(cur->fromp(), VarRef);
if (!preVarRefp || !curVarRefp || !curVarRefp->same(preVarRefp)) return NULL; // not the same var
AstConst* pstart = pre->lsbp()->castConst();
AstConst* pwidth = pre->widthp()->castConst();
AstConst* cstart = cur->lsbp()->castConst();
AstConst* cwidth = cur->widthp()->castConst();
const AstConst* pstart = VN_CAST(pre->lsbp(), Const);
const AstConst* pwidth = VN_CAST(pre->widthp(), Const);
const AstConst* cstart = VN_CAST(cur->lsbp(), Const);
const AstConst* cwidth = VN_CAST(cur->widthp(), Const);
if (!pstart || !pwidth || !cstart || !cwidth) return NULL; // too complicated
if (cur->lsbConst()+cur->widthConst() == pre->lsbConst())
return new AstSel(curVarRefp->fileline(), curVarRefp->cloneTree(false), cur->lsbConst(), pre->widthConst()+cur->widthConst());
@ -1175,10 +1175,10 @@ private:
V3GraphEdge* oldedgep = edgep;
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
if (GateLogicVertex* lvertexp = dynamic_cast<GateLogicVertex*>(oldedgep->fromp())) {
if (AstNodeAssign* assignp = lvertexp->nodep()->castNodeAssign()) {
//if (lvertexp->outSize1() && assignp->lhsp()->castSel()) {
if (assignp->lhsp()->castSel() && lvertexp->outSize1()) {
UINFO(9, "assing to the nodep["<<assignp->lhsp()->castSel()->lsbConst()<<"]"<<endl);
if (AstNodeAssign* assignp = VN_CAST(lvertexp->nodep(), NodeAssign)) {
//if (lvertexp->outSize1() && VN_IS(assignp->lhsp(), Sel)) {
if (VN_IS(assignp->lhsp(), Sel) && lvertexp->outSize1()) {
UINFO(9, "assing to the nodep["<<VN_CAST(assignp->lhsp(), Sel)->lsbConst()<<"]"<<endl);
// first assign with Sel-lhs
if (!m_activep) m_activep = lvertexp->activep();
if (!m_logicvp) m_logicvp = lvertexp;
@ -1192,8 +1192,8 @@ private:
continue;
}
AstSel* preselp = m_assignp->lhsp()->castSel();
AstSel* curselp = assignp->lhsp()->castSel();
AstSel* preselp = VN_CAST(m_assignp->lhsp(), Sel);
AstSel* curselp = VN_CAST(assignp->lhsp(), Sel);
if (!preselp || !curselp) continue;
if (AstSel* newselp = merge(preselp, curselp)) {
@ -1370,10 +1370,10 @@ private:
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) {
GateClkDecompState* currState = (GateClkDecompState*) vu.c();
int clk_offset = currState->m_offset;
if (AstAssignW* assignp = lvertexp->nodep()->castAssignW()) {
if (const AstAssignW* assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
UINFO(9,"CLK DECOMP Logic (off = "<<clk_offset<<") - "<<lvertexp<<" : "<<m_clk_vsp<<endl);
if (AstSel* rselp = assignp->rhsp()->castSel()) {
if (rselp->lsbp()->castConst() && rselp->widthp()->castConst()) {
if (AstSel* rselp = VN_CAST(assignp->rhsp(), Sel)) {
if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) {
if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) {
UINFO(9,"CLK DECOMP Sel [ "<<rselp->msbConst()<<" : "<<rselp->lsbConst()<<" ] dropped clock ("<<clk_offset<<")"<<endl);
return VNUser(0);
@ -1382,7 +1382,7 @@ private:
} else {
return VNUser(0);
}
} else if (AstConcat* catp = assignp->rhsp()->castConcat()) {
} else if (AstConcat* catp = VN_CAST(assignp->rhsp(), Concat)) {
UINFO(9,"CLK DECOMP Concat searching - "<<assignp->lhsp()<<endl);
int concat_offset;
if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp, concat_offset)) {
@ -1390,13 +1390,13 @@ private:
}
clk_offset += concat_offset;
}
if (AstSel* lselp = assignp->lhsp()->castSel()) {
if (lselp->lsbp()->castConst() && lselp->widthp()->castConst()) {
if (const AstSel* lselp = VN_CAST(assignp->lhsp(), Sel)) {
if (VN_IS(lselp->lsbp(), Const) && VN_IS(lselp->widthp(), Const)) {
clk_offset += lselp->lsbConst();
} else {
return VNUser(0);
}
} else if (AstVarRef* vrp = assignp->lhsp()->castVarRef()) {
} else if (const AstVarRef* vrp = VN_CAST(assignp->lhsp(), VarRef)) {
if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) {
if (clk_offset != 0) {
UINFO(9,"Should only make it here with clk_offset = 0"<<endl);
@ -1468,7 +1468,7 @@ class GateDeassignVisitor : public GateBaseVisitor {
private:
// VISITORS
virtual void visit(AstVarScope* nodep) {
if (AstNodeAssign* assp = nodep->valuep()->castNodeAssign()) {
if (AstNodeAssign* assp = VN_CAST(nodep->valuep(), NodeAssign)) {
UINFO(5," Removeassign "<<assp<<endl);
AstNode* valuep = assp->rhsp();
valuep->unlinkFrBack();

View File

@ -65,7 +65,7 @@ private:
// METHODS
AstVarScope* genInpClk(AstVarScope* vscp) {
if (vscp->user2p()) {
return vscp->user2p()->castVarScope();
return VN_CAST(vscp->user2p(), VarScope);
} else {
AstVar* varp = vscp->varp();
string newvarname = "__VinpClk__"+vscp->scopep()->nameDotless()+"__"+varp->name();

View File

@ -62,8 +62,8 @@ private:
// METHODS
void nodeHashIterate(AstNode* nodep) {
if (!nodep->user4()) {
if (nodep->backp()->castCFunc()
&& !(nodep->castNodeStmt() || nodep->castCFunc())) {
if (VN_IS(nodep->backp(), CFunc)
&& !(VN_IS(nodep, NodeStmt) || VN_IS(nodep, CFunc))) {
nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" in statement position but not marked stmt (node under function)");
}
V3Hash oldHash = m_lowerHash;

View File

@ -109,7 +109,7 @@ private:
m_allMods.push_back(nodep);
m_modp->user2(CIL_MAYBE);
m_modp->user4(0); // statement count
if (m_modp->castIface()) {
if (VN_IS(m_modp, Iface)) {
// Inlining an interface means we no longer have a cell handle to resolve to.
// If inlining moves post-scope this can perhaps be relaxed.
cantInline("modIface",true);
@ -200,7 +200,7 @@ private:
|| v3Global.opt.inlineMult() < 1
|| refs*statements < v3Global.opt.inlineMult())));
// Packages aren't really "under" anything so they confuse this algorithm
if (modp->castPackage()) doit = false;
if (VN_IS(modp, Package)) doit = false;
UINFO(4, " Inline="<<doit<<" Possible="<<allowed
<<" Refs="<<refs<<" Stmts="<<statements<<" "<<modp<<endl);
modp->user1(doit);
@ -313,8 +313,8 @@ private:
if (nodep->user2p()) {
// Make an assignment, so we'll trace it properly
// user2p is either a const or a var.
AstConst* exprconstp = nodep->user2p()->castConst();
AstVarRef* exprvarrefp = nodep->user2p()->castVarRef();
AstConst* exprconstp = VN_CAST(nodep->user2p(), Const);
AstVarRef* exprvarrefp = VN_CAST(nodep->user2p(), VarRef);
UINFO(8,"connectto: "<<nodep->user2p()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
@ -350,16 +350,16 @@ private:
}
}
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
if (AstIfaceRefDType* ifacerefp = nodep->dtypep()->castIfaceRefDType()) {
if (AstIfaceRefDType* ifacerefp = VN_CAST(nodep->dtypep(), IfaceRefDType)) {
m_renamedInterfaces.insert(nodep->name());
// Each inlined cell that contain an interface variable need to copy the IfaceRefDType and point it to
// the newly cloned interface cell.
AstIfaceRefDType* newdp = ifacerefp->cloneTree(false)->castIfaceRefDType();
AstIfaceRefDType* newdp = VN_CAST(ifacerefp->cloneTree(false), IfaceRefDType);
nodep->dtypep(newdp);
ifacerefp->addNextHere(newdp);
// Relink to point to newly cloned cell
if (newdp->cellp()) {
if (AstCell* newcellp = newdp->cellp()->user4p()->castCell()) {
if (AstCell* newcellp = VN_CAST(newdp->cellp()->user4p(), Cell)) {
newdp->cellp(newcellp);
newdp->cellName(newcellp->name());
// Tag the old ifacerefp to ensure it leaves no stale reference to the inlined cell.
@ -390,9 +390,9 @@ private:
virtual void visit(AstVarRef* nodep) {
if (nodep->varp()->user2p() // It's being converted to an alias.
&& !nodep->varp()->user3()
&& !nodep->backp()->castAssignAlias()) { // Don't constant propagate aliases (we just made)
AstConst* exprconstp = nodep->varp()->user2p()->castConst();
AstVarRef* exprvarrefp = nodep->varp()->user2p()->castVarRef();
&& !VN_IS(nodep->backp(), AssignAlias)) { // Don't constant propagate aliases (we just made)
AstConst* exprconstp = VN_CAST(nodep->varp()->user2p(), Const);
AstVarRef* exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef);
if (exprconstp) {
nodep->replaceWith(exprconstp->cloneTree(true));
nodep->deleteTree(); VL_DANGLING(nodep);
@ -535,7 +535,7 @@ private:
// Better off before, as if module has multiple instantiations
// we'll save work, and we can't call pinReconnectSimple in
// this loop as it clone()s itself.
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (!pinp->exprp()) continue;
V3Inst::pinReconnectSimple(pinp, nodep, m_modp, false);
}
@ -554,7 +554,7 @@ private:
nodep->name(), nodep->modp()->origName());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
// Create assignments to the pins
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (!pinp->exprp()) continue;
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// Make new signal; even though we'll optimize the interconnect, we
@ -565,17 +565,17 @@ private:
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
AstNode* connectRefp = pinp->exprp();
if (!connectRefp->castConst() && !connectRefp->castVarRef()) {
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
}
if (pinNewVarp->isOutOnly() && connectRefp->castConst()) {
if (pinNewVarp->isOutOnly() && VN_IS(connectRefp, Const)) {
pinp->v3error("Output port is connected to a constant pin, electrical short");
}
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
if (connectRefp->castVarRef()) {
connectRefp->castVarRef()->varp()->propagateAttrFrom(pinOldVarp);
if (VN_IS(connectRefp, VarRef)) {
VN_CAST(connectRefp, VarRef)->varp()->propagateAttrFrom(pinOldVarp);
}
// One to one interconnect won't make a temporary variable.
@ -641,7 +641,7 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
// idea to avoid dumping the hugely exploded tree.
AstNodeModule* nextmodp;
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
nextmodp = modp->nextp()->castNodeModule();
nextmodp = VN_CAST(modp->nextp(), NodeModule);
if (modp->user1()) { // Was inlined
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
}

View File

@ -81,7 +81,7 @@ private:
UINFO(4," PIN "<<nodep<<endl);
if (!nodep->exprp()) return; // No-connect
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst())
if (nodep->modVarp()->isOutOnly() && VN_IS(nodep->exprp(), Const))
nodep->v3error("Output port is connected to a constant pin, electrical short");
// Use user1p on the PIN to indicate we created an assign for this pin
if (!nodep->user1SetOnce()) {
@ -107,12 +107,12 @@ private:
m_modp->addStmtp(assp);
if (debug()>=9) assp->dumpTree(cout," _new: ");
} else if (nodep->modVarp()->isIfaceRef()
|| (nodep->modVarp()->subDTypep()->castUnpackArrayDType()
&& nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) {
|| (VN_IS(nodep->modVarp()->subDTypep(), UnpackArrayDType)
&& VN_IS(VN_CAST(nodep->modVarp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))) {
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
AstVarRef* refp = exprp->castVarRef();
AstVarXRef* xrefp = exprp->castVarXRef();
const AstVarRef* refp = VN_CAST(exprp, VarRef);
const AstVarXRef* xrefp = VN_CAST(exprp, VarXRef);
if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef");
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
m_modp->addStmtp(assp);
@ -169,7 +169,7 @@ private:
// VISITORS
virtual void visit(AstVar* nodep) {
if (nodep->dtypep()->castIfaceRefDType()) {
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
UINFO(8," dm-1-VAR "<<nodep<<endl);
insert(nodep);
}
@ -231,16 +231,16 @@ private:
// VISITORS
virtual void visit(AstVar* nodep) {
if (nodep->dtypep()->castUnpackArrayDType()
&& nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType()) {
if (VN_IS(nodep->dtypep(), UnpackArrayDType)
&& VN_IS(VN_CAST(nodep->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType)) {
UINFO(8," dv-vec-VAR "<<nodep<<endl);
AstUnpackArrayDType* arrdtype = nodep->dtypep()->castUnpackArrayDType();
AstUnpackArrayDType* arrdtype = VN_CAST(nodep->dtypep(), UnpackArrayDType);
AstNode* prevp = NULL;
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__";
UINFO(8,"VAR name insert "<<varNewName<<" "<<nodep<<endl);
if (!m_deModVars.find(varNewName)) {
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
AstIfaceRefDType* ifaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType)->cloneTree(false);
arrdtype->addNextHere(ifaceRefp);
ifaceRefp->cellp(NULL);
@ -271,10 +271,10 @@ private:
if (nodep->rangep()) {
m_cellRangep = nodep->rangep();
AstVar* ifaceVarp = nodep->nextp()->castVar();
AstVar* ifaceVarp = VN_CAST(nodep->nextp(), Var);
bool isIface = ifaceVarp
&& ifaceVarp->dtypep()->castUnpackArrayDType()
&& ifaceVarp->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
&& VN_IS(ifaceVarp->dtypep(), UnpackArrayDType)
&& VN_IS(VN_CAST(ifaceVarp->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
// Make all of the required clones
for (int i = 0; i < m_cellRangep->elementsConst(); i++) {
@ -295,11 +295,11 @@ private:
// If this AstCell is actually an interface instantiation, also clone the IfaceRef
// within the same parent module as the cell
if (isIface) {
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType();
AstUnpackArrayDType* arrdtype = VN_CAST(ifaceVarp->dtypep(), UnpackArrayDType);
AstIfaceRefDType* origIfaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType);
origIfaceRefp->cellp(NULL);
AstVar* varNewp = ifaceVarp->cloneTree(false);
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
AstIfaceRefDType* ifaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType)->cloneTree(false);
arrdtype->addNextHere(ifaceRefp);
ifaceRefp->cellp(newp);
ifaceRefp->cellName(newp->name());
@ -356,9 +356,9 @@ private:
}
AstNode* exprp = nodep->exprp()->unlinkFrBack();
bool inputPin = nodep->modVarp()->isInput();
if (!inputPin && !exprp->castVarRef()
&& !exprp->castConcat() // V3Const will collapse the SEL with the one we're about to make
&& !exprp->castSel()) { // V3Const will collapse the SEL with the one we're about to make
if (!inputPin && !VN_IS(exprp, VarRef)
&& !VN_IS(exprp, Concat) // V3Const will collapse the SEL with the one we're about to make
&& !VN_IS(exprp, Sel)) { // V3Const will collapse the SEL with the one we're about to make
nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires.");
// Note spec allows more complicated matches such as slices and such
}
@ -369,19 +369,19 @@ private:
} else {
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
}
} else if (AstArraySel* arrselp = nodep->exprp()->castArraySel()) {
if (AstUnpackArrayDType* arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) {
if (!arrp->subDTypep()->castIfaceRefDType())
} else if (AstArraySel* arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
if (AstUnpackArrayDType* arrp = VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
if (!VN_IS(arrp->subDTypep(), IfaceRefDType))
return;
V3Const::constifyParamsEdit(arrselp->rhsp());
AstConst* constp = arrselp->rhsp()->castConst();
const AstConst* constp = VN_CAST(arrselp->rhsp(), Const);
if (!constp) {
nodep->v3error("Unsupported: Non-constant index when passing interface to module");
return;
}
string index = AstNode::encodeNumber(constp->toSInt());
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
AstVarRef* varrefp = VN_CAST(arrselp->lhsp(), VarRef);
AstVarXRef* newp = new AstVarXRef(nodep->fileline(), varrefp->name()+"__BRA__"+index+"__KET__", "", true);
newp->dtypep(nodep->modVarp()->dtypep());
newp->packagep(varrefp->packagep());
@ -390,8 +390,8 @@ private:
}
} else {
AstVar* pinVarp = nodep->modVarp();
AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType();
if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType())
AstUnpackArrayDType* pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
if (!pinArrp || !VN_IS(pinArrp->subDTypep(), IfaceRefDType))
return;
AstNode* prevp = NULL;
AstNode* prevPinp = NULL;
@ -405,7 +405,7 @@ private:
if (!pinVarp->backp()) {
varNewp = m_deModVars.find(varNewName);
} else {
AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType();
AstIfaceRefDType* ifaceRefp = VN_CAST(pinArrp->subDTypep(), IfaceRefDType);
ifaceRefp->cellp(NULL);
varNewp = pinVarp->cloneTree(false);
varNewp->name(varNewName);
@ -429,7 +429,7 @@ private:
newp->modVarp(varNewp);
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
// And replace exprp with a new varxref
AstVarRef* varrefp = newp->exprp()->castVarRef();
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef);
string newname = varrefp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
newVarXRefp->varp(newp->modVarp());
@ -504,12 +504,12 @@ public:
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstVarXRef* connectXRefp = pinp->exprp()->castVarXRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->castBasicDType(); // Maybe NULL
AstVarRef* connectRefp = VN_CAST(pinp->exprp(), VarRef);
AstVarXRef* connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
AstBasicDType* pinBasicp = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe NULL
AstBasicDType* connBasicp = NULL;
AstAssignW* assignp = NULL;
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->castBasicDType();
if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType);
//
if (!alwaysCvt
&& connectRefp
@ -532,7 +532,7 @@ public:
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& connBasicp->width() == pinVarp->width()) {
// Done. One to one interconnect won't need a temporary variable.
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
} else if (!alwaysCvt && !forTristate && VN_IS(pinp->exprp(), Const)) {
// Done. Constant.
} else {
// Make a new temp wire

View File

@ -104,7 +104,7 @@ public:
m_assignp = assp;
m_constp = NULL;
m_everSet = true;
if (assp->rhsp()->castConst()) m_constp = assp->rhsp()->castConst();
if (VN_IS(assp->rhsp(), Const)) m_constp = VN_CAST(assp->rhsp(), Const);
}
inline void complexAssign() { // A[x]=... or some complicated assignment
m_assignp = NULL;
@ -329,8 +329,8 @@ private:
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
}
// Has to be direct assignment without any EXTRACTing.
if (nodep->lhsp()->castVarRef() && !m_sideEffect && !m_noopt) {
AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep();
if (VN_IS(nodep->lhsp(), VarRef) && !m_sideEffect && !m_noopt) {
AstVarScope* vscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope lost on variable");
m_lifep->simpleAssign(vscp, nodep);
} else {

View File

@ -148,8 +148,8 @@ private:
}
}
virtual void visit(AstAssignPost* nodep) {
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) {
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
// Scrunch these:
// __Vdly__q = __PVT__clk_clocks;
// ... {no reads or writes of __PVT__q after the first write to __Vdly__q}

View File

@ -131,7 +131,7 @@ private:
AstNodeModule* findModuleSym(const string& modName) {
VSymEnt* foundp = m_mods.rootp()->findIdFallback(modName);
if (!foundp) return NULL;
else return foundp->nodep()->castNodeModule();
else return VN_CAST(foundp->nodep(), NodeModule);
}
AstNodeModule* resolveModule(AstNode* nodep, const string& modName) {
@ -203,7 +203,7 @@ private:
<<"' does not match "<<nodep->typeName()<<" name: "<<nodep->prettyName());
}
}
if (nodep->castIface() || nodep->castPackage()) nodep->inLibrary(true); // Interfaces can't be at top, unless asked
if (VN_IS(nodep, Iface) || VN_IS(nodep, Package)) nodep->inLibrary(true); // Interfaces can't be at top, unless asked
bool topMatch = (v3Global.opt.topModule()==nodep->prettyName());
if (topMatch) {
m_topVertexp = vertex(nodep);
@ -231,11 +231,11 @@ private:
// but we might support modules-under-modules someday.
AstNodeModule* modp = resolveModule(nodep, nodep->ifaceName());
if (modp) {
if (modp->castIface()) {
if (VN_IS(modp, Iface)) {
// Track module depths, so can sort list from parent down to children
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false);
if (!nodep->cellp()) nodep->ifacep(modp->castIface());
} else if (modp->castNotFoundModule()) { // Will error out later
if (!nodep->cellp()) nodep->ifacep(VN_CAST(modp, Iface));
} else if (VN_IS(modp, NotFoundModule)) { // Will error out later
} else {
nodep->v3error("Non-interface used as an interface: "<<nodep->prettyName());
}
@ -298,7 +298,7 @@ private:
// This lets us link the XREFs between the (uncloned) children so
// they don't point to the same module which would
// break parameter resolution.
AstNodeModule* otherModp = cellmodp->user2p()->castNodeModule();
AstNodeModule* otherModp = VN_CAST(cellmodp->user2p(), NodeModule);
if (!otherModp) {
otherModp = cellmodp->cloneTree(false);
otherModp->name(otherModp->name()+"__Vrcm");
@ -342,7 +342,7 @@ private:
// Convert .* to list of pins
bool pinStar = false;
for (AstPin* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
nextp = pinp->nextp()->castPin();
nextp = VN_CAST(pinp->nextp(), Pin);
if (pinp->dotStar()) {
if (pinStar) pinp->v3error("Duplicate .* in a cell");
pinStar = true;
@ -351,10 +351,10 @@ private:
}
}
// Convert unnamed pins to pin number based assignments
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (pinp->name()=="") pinp->name("__pinNumber"+cvtToStr(pinp->pinNum()));
}
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
pinp->param(true);
if (pinp->name()=="") pinp->name("__paramNumber"+cvtToStr(pinp->pinNum()));
}
@ -362,7 +362,7 @@ private:
nodep->modName(nodep->modp()->name());
// Note what pins exist
vl_unordered_set<string> ports; // Symbol table of all connected port names
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
if (!pinp->exprp()) {
if (pinp->name().substr(0, 11) == "__pinNumber") {
@ -378,7 +378,7 @@ private:
// We search ports, rather than in/out declarations as they aren't resolved yet,
// and it's easier to do it now than in V3LinkDot when we'd need to repeat steps.
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
if (AstPort* portp = portnodep->castPort()) {
if (const AstPort* portp = VN_CAST(portnodep, Port)) {
if (ports.find(portp->name()) == ports.end()
&& ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) {
if (pinStar) {
@ -398,7 +398,7 @@ private:
}
}
}
if (nodep->modp()->castIface()) {
if (VN_IS(nodep->modp(), Iface)) {
// Cell really is the parent's instantiation of an interface, not a normal module
// Make sure we have a variable to refer to this cell, so can <ifacename>.<innermember>
// in the same way that a child does. Rename though to avoid conflict with cell.
@ -443,7 +443,7 @@ private:
void readModNames() {
// Look at all modules, and store pointers to all module names
for (AstNodeModule* nextp,* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nextp) {
nextp = nodep->nextp()->castNodeModule();
nextp = VN_CAST(nodep->nextp(), NodeModule);
AstNodeModule* foundp = findModuleSym(nodep->name());
if (foundp && foundp != nodep) {
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) {

View File

@ -190,13 +190,13 @@ public:
// METHODS
static string nodeTextType(AstNode* nodep) {
if (nodep->castVar()) return "variable";
else if (nodep->castCell()) return "cell";
else if (nodep->castTask()) return "task";
else if (nodep->castFunc()) return "function";
else if (nodep->castBegin()) return "block";
else if (nodep->castIface()) return "interface";
else if (nodep->castParamTypeDType()) return "parameter type";
if (VN_IS(nodep, Var)) return "variable";
else if (VN_IS(nodep, Cell)) return "cell";
else if (VN_IS(nodep, Task)) return "task";
else if (VN_IS(nodep, Func)) return "function";
else if (VN_IS(nodep, Begin)) return "block";
else if (VN_IS(nodep, Iface)) return "interface";
else if (VN_IS(nodep, ParamTypeDType)) return "parameter type";
else return nodep->prettyTypeName();
}
@ -217,8 +217,8 @@ public:
// Good.
} else if (foundp->imported()) { // From package
// We don't throw VARHIDDEN as if the import is later the symbol table's import wouldn't warn
} else if (nodep->castBegin() && fnodep->castBegin()
&& nodep->castBegin()->generate()) {
} else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin)
&& VN_CAST(nodep, Begin)->generate()) {
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
// See t_gen_forif.v for an example.
} else {
@ -370,10 +370,10 @@ public:
}
// Iface for a raw or arrayed iface
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType();
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
if (!ifacerefp) {
if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) {
ifacerefp = arrp->subDTypep()->castIfaceRefDType();
if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
}
}
return ifacerefp;
@ -381,7 +381,7 @@ public:
void computeIfaceVarSyms() {
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
VSymEnt* varSymp = *it;
AstVar* varp = varSymp ? varSymp->nodep()->castVar() : NULL;
AstVar* varp = varSymp ? VN_CAST(varSymp->nodep(), Var) : NULL;
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
@ -403,7 +403,7 @@ public:
VSymEnt* foundp = ifaceSymp->findIdFallback(ifacerefp->modportName());
bool ok = false;
if (foundp) {
if (AstModport* modportp = foundp->nodep()->castModport()) {
if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
UINFO(4,"Link Modport: "<<modportp<<endl);
ifacerefp->modportp(modportp);
ifOrPortSymp = foundp;
@ -424,8 +424,8 @@ public:
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
if (rhsp->nodep()->castCell()
&& !rhsp->nodep()->castCell()->modp()->castIface()) {
if (VN_IS(rhsp->nodep(), Cell)
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)) {
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
}
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
@ -447,7 +447,7 @@ public:
// srcp should be an interface reference pointing to the interface we want to import
lhsp->importFromIface(symsp(), srcp);
// Allow access to objects not permissible to be listed in a modport
if (srcp->nodep()->castModport()) {
if (VN_IS(srcp->nodep(), Modport)) {
lhsp->importFromIface(symsp(), srcp->parentp(), true);
}
}
@ -499,8 +499,8 @@ public:
// then look up (inst name or modname)
if (firstId) {
// Check this module - subcellnames
AstCell* cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated below
AstCellInline* inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated below
AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell) : NULL; // Replicated below
AstCellInline* inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline) : NULL; // Replicated below
if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
lookupSymp = findSymp;
}
@ -512,8 +512,8 @@ public:
bool crossedCell = false; // Crossed a cell boundary
while (lookupSymp) {
lookupSymp = lookupSymp->parentp();
cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated above
inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated above
cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell) : NULL; // Replicated above
inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline) : NULL; // Replicated above
if (lookupSymp) {
UINFO(9,"\t\tUp to "<<lookupSymp<<endl);
if (cellp || inlinep) {
@ -525,7 +525,7 @@ public:
}
else if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
lookupSymp = findSymp;
if (crossedCell && lookupSymp->nodep()->castVar()) {
if (crossedCell && VN_IS(lookupSymp->nodep(), Var)) {
UINFO(9,"\t\tNot found but matches var name in parent "<<lookupSymp<<endl);
return NULL; // Not found (but happens to be var name in parent)
}
@ -644,8 +644,8 @@ class LinkDotFindVisitor : public AstNVisitor {
virtual void visit(AstNetlist* nodep) {
// Process $unit or other packages
// Not needed - dotted references not allowed from inside packages
//for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
// if (nodep->castPackage()) {}}
//for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
// if (VN_IS(nodep, Package)) {}}
m_statep->insertDUnit(nodep);
@ -676,7 +676,7 @@ class LinkDotFindVisitor : public AstNVisitor {
UINFO(8," "<<nodep<<endl);
// m_curSymp/m_modSymp maybe NULL for packages and non-top modules
// Packages will be under top after the initial phases, but until then need separate handling
bool standalonePkg = !m_modSymp && (m_statep->forPrearray() && nodep->castPackage());
bool standalonePkg = !m_modSymp && (m_statep->forPrearray() && VN_IS(nodep, Package));
bool doit = (m_modSymp || standalonePkg);
string oldscope = m_scope;
VSymEnt* oldModSymp = m_modSymp;
@ -691,7 +691,7 @@ class LinkDotFindVisitor : public AstNVisitor {
UINFO(4," Link Module: "<<nodep<<endl);
if (nodep->dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?");
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
m_packagep = nodep->castPackage();
m_packagep = VN_CAST(nodep, Package);
if (standalonePkg) {
if (m_packagep->isDollarUnit()) {
m_curSymp = m_modSymp = m_statep->dunitEntp();
@ -713,7 +713,7 @@ class LinkDotFindVisitor : public AstNVisitor {
nodep->user2(false);
nodep->user4(true);
// Interfaces need another pass when signals are resolved
if (AstIface* ifacep = nodep->castIface()) {
if (AstIface* ifacep = VN_CAST(nodep, Iface)) {
m_statep->insertIfaceModSym(ifacep, m_curSymp);
}
} else { //!doit
@ -829,7 +829,7 @@ class LinkDotFindVisitor : public AstNVisitor {
// places such as tasks, where "task ...; begin ... end"
// are common.
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (stmtp->castVar()) {
if (VN_IS(stmtp, Var)) {
++m_modBeginNum;
nodep->name("unnamedblk"+cvtToStr(m_modBeginNum));
break;
@ -865,8 +865,8 @@ class LinkDotFindVisitor : public AstNVisitor {
// This should probably be done in the Parser instead, as then we could
// just attact normal signal attributes to it.
if (nodep->fvarp()
&& !nodep->fvarp()->castVar()) {
AstNodeDType* dtypep = nodep->fvarp()->castNodeDType();
&& !VN_IS(nodep->fvarp(), Var)) {
AstNodeDType* dtypep = VN_CAST(nodep->fvarp(), NodeDType);
// If unspecified, function returns one bit; however when we support NEW() it could
// also return the class reference.
if (dtypep) dtypep->unlinkFrBack();
@ -894,7 +894,7 @@ class LinkDotFindVisitor : public AstNVisitor {
// Find under either a task or the module's vars
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname?
AstVar* findvarp = foundp ? foundp->nodep()->castVar() : NULL;
AstVar* findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : NULL;
bool ins=false;
if (!foundp) {
ins=true;
@ -910,7 +910,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|| (findvarp->isSignal() && nodep->isIO())) {
findvarp->combineType(nodep);
nodep->fileline()->modifyStateInherit(nodep->fileline());
AstBasicDType* bdtypep = findvarp->childDTypep()->castBasicDType();
AstBasicDType* bdtypep = VN_CAST(findvarp->childDTypep(), BasicDType);
if (bdtypep && bdtypep->implicit()) {
// Then have "input foo" and "real foo" so the dtype comes from the other side.
AstNodeDType* newdtypep = nodep->subDTypep();
@ -991,7 +991,7 @@ class LinkDotFindVisitor : public AstNVisitor {
// Find under either a task or the module's vars
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname?
AstEnumItem* findvarp = foundp ? foundp->nodep()->castEnumItem() : NULL;
AstEnumItem* findvarp = foundp ? VN_CAST(foundp->nodep(), EnumItem) : NULL;
bool ins=false;
if (!foundp) {
ins=true;
@ -1091,10 +1091,10 @@ private:
void pinImplicitExprRecurse(AstNode* nodep) {
// Under a pin, Check interconnect expression for a pin reference or a concat.
// Create implicit variable as needed
if (nodep->castDot()) { // Not creating a simple implied type,
if (VN_IS(nodep, Dot)) { // Not creating a simple implied type,
// and implying something else would just confuse later errors
}
else if (nodep->castVarRef() || nodep->castParseRef()) {
else if (VN_IS(nodep, VarRef) || VN_IS(nodep, ParseRef)) {
// To prevent user errors, we should only do single bit
// implicit vars, however some netlists (MIPS) expect single
// bit implicit wires to get created with range 0:0 etc.
@ -1140,7 +1140,7 @@ private:
nodep->iterateChildren(*this);
nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<<nodep->prettyName()<<"(...etc...))");
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
AstCell* cellp = foundp ? foundp->nodep()->castCell() : NULL;
AstCell* cellp = foundp ? VN_CAST(foundp->nodep(), Cell) : NULL;
if (!cellp) {
nodep->v3error("In defparam, cell "<<nodep->path()<<" never declared");
} else {
@ -1162,7 +1162,7 @@ private:
// Need to set pin numbers after varnames are created
// But before we do the final resolution based on names
VSymEnt* foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name());
AstVar* refp = foundp ? foundp->nodep()->castVar() : NULL;
AstVar* refp = foundp ? VN_CAST(foundp->nodep(), Var) : NULL;
if (!refp) {
nodep->v3error("Input/output/inout declaration not found for port: "<<nodep->prettyName());
} else if (!refp->isIO() && !refp->isIfaceRef()) {
@ -1187,10 +1187,10 @@ private:
// tran gates need implicit creation
// As VarRefs don't exist in forPrimary, sanity check
if (m_statep->forPrimary()) nodep->v3fatalSrc("Assign aliases unexpected pre-dot");
if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) {
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
pinImplicitExprRecurse(forrefp);
}
if (AstVarRef* forrefp = nodep->rhsp()->castVarRef()) {
if (AstVarRef* forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
pinImplicitExprRecurse(forrefp);
}
nodep->iterateChildren(*this);
@ -1282,8 +1282,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
// we'll need to replace it with a VARXREF(aliased_to)
if (debug()>=9) nodep->dumpTree(cout,"-\t\t\t\talias: ");
AstVarScope* fromVscp = nodep->lhsp()->castVarRef()->varScopep();
AstVarScope* toVscp = nodep->rhsp()->castVarRef()->varScopep();
AstVarScope* fromVscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
AstVarScope* toVscp = VN_CAST(nodep->rhsp(), VarRef)->varScopep();
if (!fromVscp || !toVscp) nodep->v3fatalSrc("Bad alias scopes");
fromVscp->user2p(toVscp);
nodep->iterateChildren(*this);
@ -1293,8 +1293,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
if (debug()>=9) nodep->dumpTree(cout,"-\t\t\t\tavs: ");
VSymEnt* rhsSymp;
{
AstVarRef* refp = nodep->rhsp()->castVarRef();
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
AstVarRef* refp = VN_CAST(nodep->rhsp(), VarRef);
AstVarXRef* xrefp = VN_CAST(nodep->rhsp(), VarXRef);
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : "";
VSymEnt* symp = NULL;
@ -1314,8 +1314,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
}
VSymEnt* lhsSymp;
{
AstVarXRef* xrefp = nodep->lhsp()->castVarXRef();
AstVarRef* refp = nodep->lhsp()->castVarRef();
const AstVarXRef* xrefp = VN_CAST(nodep->lhsp(), VarXRef);
const AstVarRef* refp = VN_CAST(nodep->lhsp(), VarRef);
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
string scopename = refp ? refp->varp()->name() : xrefp->dotted()+"."+xrefp->name();
@ -1385,7 +1385,7 @@ class LinkDotIfaceVisitor : public AstNVisitor {
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
if (!symp) {
nodep->v3error("Modport item not found: "<<nodep->prettyName());
} else if (AstNodeFTask* ftaskp = symp->nodep()->castNodeFTask()) {
} else if (AstNodeFTask* ftaskp = VN_CAST(symp->nodep(), NodeFTask)) {
// Make symbol under modport that points at the _interface_'s var, not the modport.
nodep->ftaskp(ftaskp);
VSymEnt* subSymp = m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, NULL/*package*/);
@ -1405,12 +1405,12 @@ class LinkDotIfaceVisitor : public AstNVisitor {
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
if (!symp) {
nodep->v3error("Modport item not found: "<<nodep->prettyName());
} else if (AstVar* varp = symp->nodep()->castVar()) {
} else if (AstVar* varp = VN_CAST(symp->nodep(), Var)) {
// Make symbol under modport that points at the _interface_'s var via the modport.
// (Need modport still to test input/output markings)
nodep->varp(varp);
m_statep->insertSym(m_curSymp, nodep->name(), nodep, NULL/*package*/);
} else if (AstVarScope* vscp = symp->nodep()->castVarScope()) {
} else if (AstVarScope* vscp = VN_CAST(symp->nodep(), VarScope)) {
// Make symbol under modport that points at the _interface_'s var, not the modport.
nodep->varp(vscp->varp());
m_statep->insertSym(m_curSymp, nodep->name(), vscp, NULL/*package*/);
@ -1531,10 +1531,10 @@ private:
// Return a variable if possible, auto converting a modport to variable
if (!symp) {
return NULL;
} else if (symp->nodep()->castVar()) {
return symp->nodep()->castVar();
} else if (symp->nodep()->castModportVarRef()) {
AstModportVarRef* snodep = symp->nodep()->castModportVarRef();
} else if (VN_IS(symp->nodep(), Var)) {
return VN_CAST(symp->nodep(), Var);
} else if (VN_IS(symp->nodep(), ModportVarRef)) {
AstModportVarRef* snodep = VN_CAST(symp->nodep(), ModportVarRef);
AstVar* varp = snodep->varp();
if (lvalue && snodep->isInput()) {
nodep->v3error("Attempt to drive input-only modport: "<<nodep->prettyName());
@ -1545,8 +1545,8 @@ private:
}
}
void taskFuncSwapCheck(AstNodeFTaskRef* nodep) {
if (nodep->taskp() && nodep->taskp()->castTask()
&& nodep->castFuncRef()) nodep->v3error("Illegal call of a task as a function: "<<nodep->prettyName());
if (nodep->taskp() && VN_IS(nodep->taskp(), Task)
&& VN_IS(nodep, FuncRef)) nodep->v3error("Illegal call of a task as a function: "<<nodep->prettyName());
}
inline void checkNoDot(AstNode* nodep) {
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
@ -1620,7 +1620,7 @@ private:
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
}
else {
if (nodep->modp()->castNotFoundModule()) {
if (VN_IS(nodep->modp(), NotFoundModule)) {
// Prevent warnings about missing pin connects
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree();
@ -1649,14 +1649,14 @@ private:
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
const char* whatp = nodep->param() ? "parameter pin" : "pin";
if (!foundp) {
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
if (nodep->name() == "__paramNumber1" && VN_IS(m_cellp->modp(), Primitive)) {
// Primitive parameter is really a delay we can just ignore
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
}
else if (AstVar* refp = foundp->nodep()->castVar()) {
else if (AstVar* refp = VN_CAST(foundp->nodep(), Var)) {
if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<<nodep->prettyName());
} else {
@ -1664,7 +1664,7 @@ private:
markAndCheckPinDup(nodep, refp, whatp);
}
}
else if (AstParamTypeDType* refp = foundp->nodep()->castParamTypeDType()) {
else if (AstParamTypeDType* refp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
nodep->modPTypep(refp);
markAndCheckPinDup(nodep, refp, whatp);
}
@ -1692,7 +1692,7 @@ private:
m_ds.m_dotPos = DP_SCOPE;
// m_ds.m_dotText communicates the cell prefix between stages
if (nodep->lhsp()->castPackageRef()) {
if (VN_IS(nodep->lhsp(), PackageRef)) {
//if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in dotted reference"); m_ds.m_dotErr=true; }
m_ds.m_dotPos = DP_PACKAGE;
} else {
@ -1700,7 +1700,7 @@ private:
nodep->lhsp()->iterateAndNext(*this);
//if (debug()>=9) nodep->dumpTree("-dot-lho: ");
}
if (m_ds.m_unresolved && (nodep->lhsp()->castCellRef() || nodep->lhsp()->castCellArrayRef())) {
if (m_ds.m_unresolved && (VN_IS(nodep->lhsp(), CellRef) || VN_IS(nodep->lhsp(), CellArrayRef))) {
m_ds.m_unlinkedScope = nodep->lhsp();
}
if (!m_ds.m_dotErr) { // Once something wrong, give up
@ -1766,8 +1766,8 @@ private:
expectWhat = "scope/variable";
allowScope = true;
allowVar = true;
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
packagep = m_ds.m_dotp->lhsp()->castPackageRef()->packagep();
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
packagep = VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep();
if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
m_ds.m_dotPos = DP_SCOPE;
@ -1799,9 +1799,9 @@ private:
// What fell out?
bool ok = false;
if (!foundp) {
} else if (foundp->nodep()->castCell()
|| foundp->nodep()->castBegin()
|| foundp->nodep()->castModule()) { // if top
} else if (VN_IS(foundp->nodep(), Cell)
|| VN_IS(foundp->nodep(), Begin)
|| VN_IS(foundp->nodep(), Module)) { // if top
if (allowScope) {
ok = true;
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
@ -1810,16 +1810,16 @@ private:
m_ds.m_dotPos = DP_SCOPE;
// Upper AstDot visitor will handle it from here
}
else if (foundp->nodep()->castCell()
else if (VN_IS(foundp->nodep(), Cell)
&& allowVar && m_cellp) {
AstCell* cellp = foundp->nodep()->castCell();
if (cellp->modp()->castIface()) {
AstCell* cellp = VN_CAST(foundp->nodep(), Cell);
if (VN_IS(cellp->modp(), Iface)) {
// Interfaces can be referenced like a variable for interconnect
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin
string findName = nodep->name()+"__Viftop";
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
AstVar* ifaceRefVarp = ifaceSymp ? ifaceSymp->nodep()->castVar() : NULL;
AstVar* ifaceRefVarp = ifaceSymp ? VN_CAST(ifaceSymp->nodep(), Var) : NULL;
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<<findName);
//
ok = true;
@ -1830,7 +1830,7 @@ private:
UINFO(9," cell -> iface varref "<<foundp->nodep()<<endl);
AstNode* newp = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, false);
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
} else if (cellp->modp()->castNotFoundModule()) {
} else if (VN_IS(cellp->modp(), NotFoundModule)) {
cellp->v3error("Cannot find file containing interface: " << AstNode::prettyName(cellp->modp()->name()));
}
}
@ -1857,7 +1857,7 @@ private:
refp->varp(varp);
m_ds.m_dotText = "";
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
newp = new AstUnlinkedRef(nodep->fileline(), refp->castVarXRef(),
newp = new AstUnlinkedRef(nodep->fileline(), VN_CAST(refp, VarXRef),
refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
m_ds.m_unlinkedScope = NULL;
m_ds.m_unresolved = false;
@ -1875,23 +1875,23 @@ private:
ok = true;
}
}
else if (AstModport* modportp = foundp->nodep()->castModport()) {
else if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
// A scope reference into an interface's modport (not necessarily at a pin connection)
UINFO(9,"cell-ref-to-modport "<<m_ds.m_dotText<<" "<<nodep<<endl);
UINFO(9,"dotSymp "<<m_ds.m_dotSymp<<" "<<m_ds.m_dotSymp->nodep()<<endl);
// Iface was the previously dotted component
if (!m_ds.m_dotSymp
|| !m_ds.m_dotSymp->nodep()->castCell()
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) {
|| !VN_IS(m_ds.m_dotSymp->nodep(), Cell)
|| !VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp()
|| !VN_IS(VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp(), Iface)) {
nodep->v3error("Modport not referenced as <interface>."<<modportp->prettyName());
} else if (!m_ds.m_dotSymp->nodep()->castCell()->modp()
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) {
} else if (!VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp()
|| !VN_IS(VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp(), Iface)) {
nodep->v3error("Modport not referenced from underneath an interface: "<<modportp->prettyName());
} else {
AstCell* cellp = m_ds.m_dotSymp->nodep()->castCell();
AstCell* cellp = VN_CAST(m_ds.m_dotSymp->nodep(), Cell);
if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell");
AstIface* ifacep = cellp->modp()->castIface();
AstIface* ifacep = VN_CAST(cellp->modp(), Iface);
//string cellName = m_ds.m_dotText; // Use cellp->name
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
m_ds.m_dotText += nodep->name();
@ -1903,7 +1903,7 @@ private:
nodep->replaceWith(refp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else if (AstEnumItem* valuep = foundp->nodep()->castEnumItem()) {
else if (AstEnumItem* valuep = VN_CAST(foundp->nodep(), EnumItem)) {
if (allowVar) {
AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep());
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
@ -1914,7 +1914,7 @@ private:
//
if (!ok) {
// Cells/interfaces can't be implicit
bool isCell = foundp ? foundp->nodep()->castCell() != NULL : false;
bool isCell = foundp ? VN_IS(foundp->nodep(), Cell) : false;
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="" && !isCell);
bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
if (err) {
@ -2000,7 +2000,7 @@ private:
// V3Inst may have expanded arrays of interfaces to AstVarXRef's even though they are in the same module
// detect this and convert to normal VarRefs
if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) {
if (nodep->dtypep()->castIfaceRefDType()) {
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), nodep->varp(), nodep->lvalue());
nodep->replaceWith(newrefp);
nodep->deleteTree(); VL_DANGLING(nodep);
@ -2009,14 +2009,14 @@ private:
} else {
string baddot;
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstVarScope* vscp = foundp ? foundp->nodep()->castVarScope() : NULL;
AstVarScope* vscp = foundp ? VN_CAST(foundp->nodep(), VarScope) : NULL;
if (!vscp) {
nodep->v3error("Can't find varpin scope of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep);
} else {
while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal
UINFO(7," Resolved pre-alias "<<vscp<<endl); // Also prints taskp
vscp = vscp->user2p()->castVarScope();
vscp = VN_CAST(vscp->user2p(), VarScope);
}
// Convert the VarXRef to a VarRef, so we don't need later optimizations to deal with VarXRef.
nodep->varp(vscp->varp());
@ -2054,9 +2054,9 @@ private:
if (nodep->user3SetOnce()) return;
UINFO(8," "<<nodep<<endl);
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep());
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
if (!VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
m_ds.m_dotPos = DP_SCOPE;
m_ds.m_dotp = NULL;
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
@ -2113,7 +2113,7 @@ private:
VSymEnt* foundp = NULL;
AstNodeFTask* taskp = NULL;
foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL; // Maybe NULL
taskp = foundp ? VN_CAST(foundp->nodep(), NodeFTask) : NULL; // Maybe NULL
if (taskp) {
nodep->taskp(taskp);
nodep->packagep(foundp->packagep());
@ -2215,9 +2215,9 @@ private:
// Resolve its reference
if (nodep->user3SetOnce()) return;
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep());
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
if (!VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
m_ds.m_dotPos = DP_SCOPE;
m_ds.m_dotp = NULL;
} else {
@ -2230,11 +2230,11 @@ private:
} else {
foundp = m_curSymp->findIdFallback(nodep->name());
}
if (AstTypedef* defp = foundp ? foundp->nodep()->castTypedef() : NULL) {
if (AstTypedef* defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : NULL) {
nodep->refDTypep(defp->subDTypep());
nodep->packagep(foundp->packagep());
}
else if (AstParamTypeDType* defp = foundp ? foundp->nodep()->castParamTypeDType() : NULL) {
else if (AstParamTypeDType* defp = foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : NULL) {
nodep->refDTypep(defp);
nodep->packagep(foundp->packagep());
}
@ -2249,7 +2249,7 @@ private:
nodep->iterateChildren(*this);
checkNoDot(nodep);
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
AstNodeFTask* taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL;
AstNodeFTask* taskp = foundp ? VN_CAST(foundp->nodep(), NodeFTask) : NULL;
if (!taskp) { nodep->v3error("Can't find definition of exported task/function: "<<nodep->prettyName()); }
else if (taskp->dpiExport()) {
nodep->v3error("Function was already DPI Exported, duplicate not allowed: "<<nodep->prettyName());

View File

@ -63,16 +63,16 @@ private:
AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) {
// Put label under given node, and if WHILE optionally at end of iteration
UINFO(4,"Create label for "<<nodep<<endl);
if (nodep->castJumpLabel()) return nodep->castJumpLabel(); // Done
if (VN_IS(nodep, JumpLabel)) return VN_CAST(nodep, JumpLabel); // Done
AstNode* underp = NULL;
bool under_and_next = true;
if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp();
else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp();
else if (nodep->castWhile()) {
if (VN_IS(nodep, Begin)) underp = VN_CAST(nodep, Begin)->stmtsp();
else if (VN_IS(nodep, NodeFTask)) underp = VN_CAST(nodep, NodeFTask)->stmtsp();
else if (VN_IS(nodep, While)) {
if (endOfIter) {
// Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip
underp = nodep->castWhile()->bodysp();
underp = VN_CAST(nodep, While)->bodysp();
} else {
underp = nodep; under_and_next=false; // IE we skip the entire while
}
@ -84,14 +84,14 @@ private:
// Skip over variables as we'll just move them in a momement
// Also this would otherwise prevent us from using a label twice
// see t_func_return test.
while (underp && underp->castVar()) underp = underp->nextp();
while (underp && VN_IS(underp, Var)) underp = underp->nextp();
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
if (!underp) {
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
return NULL;
} else if (underp->castJumpLabel()) {
return underp->castJumpLabel();
} else if (VN_IS(underp, JumpLabel)) {
return VN_CAST(underp, JumpLabel);
} else { // Move underp stuff to be under a new label
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL);
@ -104,7 +104,7 @@ private:
// Keep any AstVars under the function not under the new JumpLabel
for (AstNode* nextp, *varp=underp; varp; varp = nextp) {
nextp = varp->nextp();
if (varp->castVar()) {
if (VN_IS(varp, Var)) {
labelp->addPrev(varp->unlinkFrBack());
}
}
@ -177,7 +177,7 @@ private:
}
virtual void visit(AstReturn* nodep) {
nodep->iterateChildren(*this);
AstFunc* funcp = m_ftaskp->castFunc();
AstFunc* funcp = VN_CAST(m_ftaskp, Func);
if (!m_ftaskp) { nodep->v3error("Return isn't underneath a task or function"); }
else if (funcp && !nodep->lhsp()) { nodep->v3error("Return underneath a function should have return value"); }
else if (!funcp && nodep->lhsp()) { nodep->v3error("Return underneath a task shouldn't have return value"); }
@ -185,7 +185,7 @@ private:
if (funcp && nodep->lhsp()) {
// Set output variable to return value
nodep->addPrev(new AstAssign(nodep->fileline(),
new AstVarRef(nodep->fileline(), funcp->fvarp()->castVar(), true),
new AstVarRef(nodep->fileline(), VN_CAST(funcp->fvarp(), Var), true),
nodep->lhsp()->unlinkFrBackWithNext()));
}
// Jump to the end of the function call

View File

@ -242,7 +242,7 @@ private:
// We'll deal with mismatching pins later
if (!taskp) return;
for (AstNode* stmtp = taskp->stmtsp(); stmtp && pinp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) {
if (portp->isInput()) {
pinp->iterate(*this);

View File

@ -56,7 +56,7 @@ void V3LinkLevel::modSortByLevel() {
ModVec vec;
AstNodeModule* topp = NULL;
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
if (nodep->level()<=2) {
if (topp) {
nodep->v3warn(E_MULTITOP, "Unsupported: Multiple top level modules: "
@ -108,7 +108,7 @@ void V3LinkLevel::wrapTop(AstNetlist* netlistp) {
void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) {
AstNodeModule* newmodp = netlistp->modulesp();
if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process");
AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule();
AstNodeModule* oldmodp = VN_CAST(newmodp->nextp(), NodeModule);
if (!oldmodp) netlistp->v3fatalSrc("No module found to process");
// Add instance
@ -121,7 +121,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) {
// Add pins
for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* oldvarp=subnodep->castVar()) {
if (AstVar* oldvarp=VN_CAST(subnodep, Var)) {
UINFO(8,"VARWRAP "<<oldvarp<<endl);
if (oldvarp->isIO()) {
AstVar* varp = oldvarp->cloneTree(false);
@ -154,8 +154,8 @@ void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) {
// This way all later SCOPE based optimizations can ignore packages
AstNodeModule* newmodp = netlistp->modulesp();
if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process");
for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
if (modp->castPackage()) {
for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
if (VN_IS(modp, Package)) {
AstCell* cellp = new AstCell(modp->fileline(),
// Could add __03a__03a="::" to prevent conflict
// with module names/"v"

View File

@ -119,8 +119,8 @@ private:
cleanFileline(nodep);
nodep->iterateChildren(*this);
if (nodep->rangep()) {
if (!nodep->rangep()->msbp()->castConst()
|| !nodep->rangep()->lsbp()->castConst()) nodep->v3error("Enum ranges must be integral, per spec");
if (!VN_IS(nodep->rangep()->msbp(), Const)
|| !VN_IS(nodep->rangep()->lsbp(), Const)) nodep->v3error("Enum ranges must be integral, per spec");
int msb = nodep->rangep()->msbConst();
int lsb = nodep->rangep()->lsbConst();
int increment = (msb > lsb) ? -1 : 1;
@ -142,9 +142,9 @@ private:
virtual void visit(AstVar* nodep) {
cleanFileline(nodep);
if (nodep->subDTypep()->castParseTypeDType()) {
if (VN_IS(nodep->subDTypep(), ParseTypeDType)) {
// It's a parameter type. Use a different node type for this.
AstNodeDType* dtypep = nodep->valuep()->castNodeDType();
AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType);
if (!dtypep) {
nodep->v3error("Parameter type's initial value isn't a type: "<<nodep->prettyName());
nodep->unlinkFrBack();
@ -204,7 +204,7 @@ private:
cleanFileline(nodep);
nodep->iterateChildren(*this);
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
AstTypedef* typep = nodep->backp()->castTypedef();
AstTypedef* typep = VN_CAST(nodep->backp(), Typedef);
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
typep->attrPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
@ -296,13 +296,13 @@ private:
// AstVar, AstTypedef, AstNodeFTask are common containers
AstNode* backp = nodep->backp();
for (; backp; backp=backp->backp()) {
if (backp->castVar()) break;
else if (backp->castTypedef()) break;
else if (backp->castNodeFTask()) break;
if (VN_IS(backp, Var)) break;
else if (VN_IS(backp, Typedef)) break;
else if (VN_IS(backp, NodeFTask)) break;
}
if (!backp) nodep->v3fatalSrc("Implicit enum/struct type created under unexpected node type");
AstNodeDType* dtypep = nodep->childDTypep(); dtypep->unlinkFrBack();
if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing
if (VN_IS(backp, Typedef)) { // A typedef doesn't need us to make yet another level of typedefing
// For typedefs just remove the AstRefDType level of abstraction
nodep->replaceWith(dtypep);
nodep->deleteTree(); VL_DANGLING(nodep);

View File

@ -136,8 +136,8 @@ private:
// and any width errors will look a bit odd, but it works.
AstNode* sensp = nodep->sensp();
if (sensp
&& !sensp->castNodeVarRef()
&& !sensp->castConst()) {
&& !VN_IS(sensp, NodeVarRef)
&& !VN_IS(sensp, Const)) {
// Make a new temp wire
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname,
@ -145,11 +145,11 @@ private:
// We can't just add under the module, because we may be inside a generate, begin, etc.
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
AstNode* addwherep = nodep; // Add to this element's next
while (addwherep->castSenItem()
|| addwherep->castSenTree()) {
while (VN_IS(addwherep, SenItem)
|| VN_IS(addwherep, SenTree)) {
addwherep = addwherep->backp();
}
if (!addwherep->castAlways()) { // Assertion perhaps?
if (!VN_IS(addwherep, Always)) { // Assertion perhaps?
sensp->v3error("Unsupported: Non-single-bit pos/negedge clock statement under some complicated block");
addwherep = m_modp;
}
@ -166,26 +166,26 @@ private:
bool did=1;
while (did) {
did=0;
if (AstNodeSel* selp = nodep->sensp()->castNodeSel()) {
if (AstNodeSel* selp = VN_CAST(nodep->sensp(), NodeSel)) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
// NodeSel doesn't include AstSel....
if (AstSel* selp = nodep->sensp()->castSel()) {
if (AstSel* selp = VN_CAST(nodep->sensp(), Sel)) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) {
if (AstNodePreSel* selp = VN_CAST(nodep->sensp(), NodePreSel)) {
AstNode* fromp = selp->lhsp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
}
}
if (!nodep->sensp()->castNodeVarRef()
&& !nodep->sensp()->castEnumItemRef() // V3Const will cleanup
if (!VN_IS(nodep->sensp(), NodeVarRef)
&& !VN_IS(nodep->sensp(), EnumItemRef) // V3Const will cleanup
&& !nodep->isIllegal()) {
if (debug()) nodep->dumpTree(cout,"-tree: ");
nodep->v3error("Unsupported: Complex statement in sensitivity list");
@ -203,16 +203,16 @@ private:
// So we replicate it in another node
// Note that V3Param knows not to replace AstVarRef's under AstAttrOf's
AstNode* basefromp = AstArraySel::baseFromp(nodep);
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
if (AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
varrefp->cloneTree(false)));
} else if (AstUnlinkedRef* uvxrp = basefromp->castUnlinkedRef()) { // Maybe unlinked - so need to clone
} else if (AstUnlinkedRef* uvxrp = VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
uvxrp->cloneTree(false)));
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
} else if (AstMemberSel* fromp = VN_CAST(basefromp, MemberSel)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
fromp->cloneTree(false)));
} else if (AstEnumItemRef* fromp = basefromp->castEnumItemRef()) {
} else if (AstEnumItemRef* fromp = VN_CAST(basefromp, EnumItemRef)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
fromp->cloneTree(false)));
} else {
@ -307,7 +307,7 @@ private:
skipCount--;
continue;
}
AstConst *constp = argp->castConst();
AstConst *constp = VN_CAST(argp, Const);
bool isFromString = (constp) ? constp->num().isFromString() : false;
if (isFromString) {
int numchars = argp->dtypep()->width()/8;
@ -357,15 +357,15 @@ private:
virtual void visit(AstFOpen* nodep) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
}
virtual void visit(AstFClose* nodep) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
}
virtual void visit(AstFEof* nodep) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
}
virtual void visit(AstFScanF* nodep) {
nodep->iterateChildren(*this);
@ -380,9 +380,9 @@ private:
// Cleanup old-school displays without format arguments
if (!nodep->hasFormat()) {
if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format");
if (nodep->exprsp()->castConst()
&& nodep->exprsp()->castConst()->num().isFromString()) {
AstConst* fmtp = nodep->exprsp()->unlinkFrBack()->castConst();
if (VN_IS(nodep->exprsp(), Const)
&& VN_CAST(nodep->exprsp(), Const)->num().isFromString()) {
AstConst* fmtp = VN_CAST(nodep->exprsp()->unlinkFrBack(), Const);
nodep->text(fmtp->num().toString());
pushDeletep(fmtp); VL_DANGLING(fmtp);
}
@ -390,7 +390,8 @@ private:
}
string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
nodep->text(newFormat);
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
if ((VN_IS(nodep->backp(), Display)
&& VN_CAST(nodep->backp(), Display)->displayType().needScopeTracking())
|| nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
@ -408,7 +409,7 @@ private:
// Massive hack, just tie off all outputs so our analysis can proceed
AstVar* varoutp = NULL;
for (AstNode* stmtp = m_modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (AstVar* varp = VN_CAST(stmtp, Var)) {
if (varp->isInput()) {
} else if (varp->isOutput()) {
if (varoutp) { varp->v3error("Multiple outputs not allowed in udp modules"); }

View File

@ -141,7 +141,7 @@ private:
// We don't need to test for tracing; it would be in the tracefunc if it was needed
UINFO(4," ModVar->BlkVar "<<nodep<<endl);
++m_statLocVars;
AstCFunc* newfuncp = nodep->user1p()->castCFunc();
AstCFunc* newfuncp = VN_CAST(nodep->user1p(), CFunc);
nodep->unlinkFrBack();
newfuncp->addInitsp(nodep);
// Done
@ -175,8 +175,8 @@ private:
// This could be more complicated; allow always-set under both branches of a IF.
// If so, check for ArrayRef's and such, as they aren't acceptable.
for (; nodep; nodep=nodep->nextp()) {
if (nodep->castNodeAssign()) {
if (AstVarRef* varrefp = nodep->castNodeAssign()->lhsp()->castVarRef()) {
if (VN_IS(nodep, NodeAssign)) {
if (AstVarRef* varrefp = VN_CAST(VN_CAST(nodep, NodeAssign)->lhsp(), VarRef)) {
if (!varrefp->lvalue()) varrefp->v3fatalSrc("LHS assignment not lvalue");
if (!varrefp->varp()->user4p()) {
UINFO(4," FuncAsn "<<varrefp<<endl);

View File

@ -270,7 +270,7 @@ private:
virtual void visit(AstNodeAssign* nodep) {
m_hasClk = false;
if (AstVarRef* varrefp = nodep->rhsp()->castVarRef()) {
if (AstVarRef* varrefp = VN_CAST(nodep->rhsp(), VarRef)) {
this->visit(varrefp);
m_rightClkWidth = varrefp->width();
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
@ -298,7 +298,7 @@ private:
return; // skip the marking
}
AstVarRef* lhsp = nodep->lhsp()->castVarRef();
const AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef);
if (lhsp && (lhsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_UNKNOWN)) {
lhsp->varp()->attrClocker(AstVarAttrClocker::CLOCKER_YES); // mark as clocker
m_newClkMarked = true; // enable a further run since new clocker is marked
@ -343,8 +343,8 @@ private:
virtual void visit(AstReplicate* nodep) {
if (m_inAss) {
nodep->iterateChildren(*this);
if (nodep->rhsp()->castConst()) {
m_childClkWidth = m_childClkWidth * nodep->rhsp()->castConst()->toUInt();
if (VN_IS(nodep->rhsp(), Const)) {
m_childClkWidth = m_childClkWidth * VN_CAST(nodep->rhsp(), Const)->toUInt();
} else {
m_childClkWidth = nodep->width(); // can not check in this case.
}
@ -389,7 +389,7 @@ private:
return level;
}
virtual void visit(AstNodeAssign* nodep) {
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef() )
if (const AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef) )
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
m_clkAss = true;
UINFO(6, "node was marked as clocker "<<varrefp<<endl);
@ -563,8 +563,8 @@ private:
toLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->top());
}
//
if ((fromLVtxp && fromLVtxp->nodep()->castInitial())
|| (toLVtxp && toLVtxp->nodep()->castInitial())) {
if ((fromLVtxp && VN_IS(fromLVtxp->nodep(), Initial))
|| (toLVtxp && VN_IS(toLVtxp->nodep(), Initial))) {
// IEEE does not specify ordering between initial blocks, so we can do whatever we want
// We especially do not want to evaluate multiple times, so do not mark the edge circular
}
@ -1079,7 +1079,7 @@ void OrderVisitor::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
processInputsInIterate(vvertexp, todoVec);
}
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
if (vvertexp->nodep()->castNodeAssign()) {
if (VN_IS(vvertexp->nodep(), NodeAssign)) {
processInputsInIterate(vvertexp, todoVec);
}
}
@ -1340,8 +1340,8 @@ bool OrderVisitor::domainsExclusive(const AstSenTree* fromp,
// always @(negedge A)
//
// ... unless you know more about A and B, which sounds hard.
const AstSenItem* fromSenListp = fromp->sensesp()->castSenItem();
const AstSenItem* toSenListp = top->sensesp()->castSenItem();
const AstSenItem* fromSenListp = VN_CAST(fromp->sensesp(), SenItem);
const AstSenItem* toSenListp = VN_CAST(top->sensesp(), SenItem);
// If clk gating is ever reenabled, we may need to update this to handle
// AstSenGate also.
if (!fromSenListp) fromp->v3fatalSrc("sensitivity list item is not an AstSenItem");
@ -1516,11 +1516,11 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
<<" s="<<(void*)(scopep)<<" "<<lvertexp<<endl);
AstSenTree* domainp = lvertexp->domainp();
AstNode* nodep = lvertexp->nodep();
AstNodeModule* modp = scopep->user1p()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
if (nodep->castUntilStable()) {
AstNodeModule* modp = VN_CAST(scopep->user1p(), NodeModule); UASSERT(modp,"NULL"); // Stashed by visitor func
if (VN_IS(nodep, UntilStable)) {
nodep->v3fatalSrc("Not implemented");
}
else if (nodep->castSenTree()) {
else if (VN_IS(nodep, SenTree)) {
// Just ignore sensitivities, we'll deal with them when we move statements that need them
}
else { // Normal logic

View File

@ -123,14 +123,14 @@ private:
std::vector<int> usedLetter; usedLetter.resize(256);
// Pass 1, assign first letter to each gparam's name
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (AstVar* varp = VN_CAST(stmtp, Var)) {
if (varp->isGParam()||varp->isIfaceRef()) {
char ch = varp->name()[0];
ch = toupper(ch); if (ch<'A' || ch>'Z') ch='Z';
varp->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
usedLetter[static_cast<int>(ch)]++;
}
} else if (AstParamTypeDType* typep = stmtp->castParamTypeDType()) {
} else if (AstParamTypeDType* typep = VN_CAST(stmtp, ParamTypeDType)) {
char ch = 'T';
typep->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
usedLetter[static_cast<int>(ch)]++;
@ -175,7 +175,7 @@ private:
void collectPins(CloneMap* clonemapp, AstNodeModule* modp) {
// Grab all I/O so we can remap our pins later
for (AstNode* stmtp=modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (AstVar* varp = VN_CAST(stmtp, Var)) {
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
// Cloning saved a pointer to the new node for us, so just follow that link.
AstVar* oldvarp = varp->clonep();
@ -183,7 +183,7 @@ private:
clonemapp->insert(make_pair(oldvarp, varp));
}
}
else if (AstParamTypeDType* ptp = stmtp->castParamTypeDType()) {
else if (AstParamTypeDType* ptp = VN_CAST(stmtp, ParamTypeDType)) {
if (ptp->isGParam()) {
AstParamTypeDType* oldptp = ptp->clonep();
clonemapp->insert(make_pair(oldptp, ptp));
@ -192,18 +192,18 @@ private:
}
}
void relinkPins(CloneMap* clonemapp, AstPin* startpinp) {
for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = startpinp; pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (pinp->modVarp()) {
// Find it in the clone structure
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
pinp->modVarp(cloneiter->second->castVar());
pinp->modVarp(VN_CAST(cloneiter->second, Var));
}
else if (pinp->modPTypep()) {
CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep());
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
pinp->modPTypep(cloneiter->second->castParamTypeDType());
pinp->modPTypep(VN_CAST(cloneiter->second, ParamTypeDType));
}
else {
pinp->v3fatalSrc("Not linked?");
@ -229,8 +229,8 @@ private:
for (int nonIf=0; nonIf<2; ++nonIf) {
for (CellList::iterator it=m_cellps.begin(); it!=m_cellps.end(); ++it) {
AstCell* nodep = *it;
if ((nonIf==0 && nodep->modp()->castIface())
|| (nonIf==1 && !nodep->modp()->castIface())) {
if ((nonIf==0 && VN_IS(nodep->modp(), Iface))
|| (nonIf==1 && !VN_IS(nodep->modp(), Iface))) {
visitCell(nodep);
}
}
@ -253,7 +253,7 @@ private:
UINFO(4," MOD-recursive-dead. "<<nodep<<endl); // Fake, made for recursive elimination
nodep->dead(true); // So Dead checks won't count references to it
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|| nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
// Add request to END of modules left to process
m_todoModps.insert(make_pair(nodep->level(), nodep));
visitModules();
@ -275,7 +275,7 @@ private:
if (nodep->isParam()) {
if (!nodep->valuep()) { nodep->v3fatalSrc("Parameter without initial value"); }
V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init()
if (!nodep->valuep()->castConst()) { // Complex init, like an array
if (!VN_IS(nodep->valuep(), Const)) { // Complex init, like an array
// Make a new INITIAL to set the value.
// This allows the normal array/struct handling code to properly initialize the parameter
nodep->addNext(new AstInitial(nodep->fileline(),
@ -293,11 +293,11 @@ private:
bool ifaceParamReplace(AstVarXRef* nodep, AstNode* candp) {
for (; candp; candp = candp->nextp()) {
if (nodep->name() == candp->name()) {
if (AstVar* varp = candp->castVar()) {
if (AstVar* varp = VN_CAST(candp, Var)) {
UINFO(9,"Found interface parameter: "<<varp<<endl);
nodep->varp(varp);
return true;
} else if (AstPin* pinp = candp->castPin()) {
} else if (AstPin* pinp = VN_CAST(candp, Pin)) {
UINFO(9,"Found interface parameter: "<<pinp<<endl);
if (!pinp->exprp()) pinp->v3fatalSrc("Interface parameter pin missing expression");
nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep);
@ -313,15 +313,15 @@ private:
if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) {
AstNode* backp = nodep;
while ((backp = backp->backp())) {
if (backp->castNodeModule()) {
if (VN_IS(backp, NodeModule)) {
UINFO(9,"Hit module boundary, done looking for interface"<<endl);
break;
}
if (backp->castVar()
&& backp->castVar()->isIfaceRef()
&& backp->castVar()->childDTypep()
&& backp->castVar()->childDTypep()->castIfaceRefDType()) {
AstIfaceRefDType* ifacerefp = backp->castVar()->childDTypep()->castIfaceRefDType();
if (VN_IS(backp, Var)
&& VN_CAST(backp, Var)->isIfaceRef()
&& VN_CAST(backp, Var)->childDTypep()
&& VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType)) {
AstIfaceRefDType* ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType);
// Interfaces passed in on the port map have ifaces
if (AstIface* ifacep = ifacerefp->ifacep()) {
if (dotted == backp->name()) {
@ -347,8 +347,8 @@ private:
}
virtual void visit(AstUnlinkedRef* nodep) {
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
AstNodeFTaskRef* taskrefp = nodep->op1p()->castNodeFTaskRef();
AstVarXRef* varxrefp = VN_CAST(nodep->op1p(), VarXRef);
AstNodeFTaskRef* taskrefp = VN_CAST(nodep->op1p(), NodeFTaskRef);
if (varxrefp) {
m_unlinkedTxt = varxrefp->dotted();
} else if (taskrefp) {
@ -369,7 +369,7 @@ private:
}
virtual void visit(AstCellArrayRef* nodep) {
V3Const::constifyParamsEdit(nodep->selp());
if (AstConst* constp = nodep->selp()->castConst()) {
if (const AstConst* constp = VN_CAST(nodep->selp(), Const)) {
string index = AstNode::encodeNumber(constp->toSInt());
string replacestr = nodep->name() + "__BRA__??__KET__";
size_t pos = m_unlinkedTxt.find(replacestr);
@ -408,7 +408,7 @@ private:
V3Width::widthGenerateParamsEdit(nodep); // Param typed widthing will
// NOT recurse the body.
V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change
if (AstConst* constp = nodep->condp()->castConst()) {
if (const AstConst* constp = VN_CAST(nodep->condp(), Const)) {
AstNode* keepp = (constp->isZero()
? nodep->elsesp()
: nodep->ifsp());
@ -431,7 +431,7 @@ private:
//! move to more generic constant expressions, such code will be needed here.
virtual void visit(AstBegin* nodep) {
if (nodep->genforp()) {
AstGenFor* forp = nodep->genforp()->castGenFor();
AstGenFor* forp = VN_CAST(nodep->genforp(), GenFor);
if (!forp) nodep->v3fatalSrc("Non-GENFOR under generate-for 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
@ -468,9 +468,9 @@ private:
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body,
// don't trigger errors yet.
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
AstConst* exprp = nodep->exprp()->castConst();
AstConst* exprp = VN_CAST(nodep->exprp(), Const);
// Constify
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* ep = itemp->condsp(); ep; ) {
AstNode* nextp = ep->nextp(); //May edit list
ep->iterateAndNext(*this);
@ -479,10 +479,10 @@ private:
}
}
// Item match
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (!itemp->isDefault()) {
for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) {
if (AstConst* ccondp = ep->castConst()) {
if (const AstConst* ccondp = VN_CAST(ep, Const)) {
V3Number match (nodep->fileline(), 1);
match.opEq(ccondp->num(), exprp->num());
if (!keepp && match.isNeqZero()) {
@ -495,7 +495,7 @@ private:
}
}
// Else default match
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) {
if (!keepp) keepp=itemp->bodysp();
}
@ -550,20 +550,20 @@ void ParamVisitor::visitCell(AstCell* nodep) {
if (nodep->recursive()) any_overrides = true; // Must always clone __Vrcm (recursive modules)
longname += "_";
if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t");
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (!pinp->exprp()) continue; // No-connect
if (AstVar* modvarp = pinp->modVarp()) {
if (!modvarp->isGParam()) {
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
} else if (pinp->exprp()->castInitArray()
&& modvarp->subDTypep()->castUnpackArrayDType()) {
} else if (VN_IS(pinp->exprp(), InitArray)
&& VN_IS(modvarp->subDTypep(), UnpackArrayDType)) {
// Array assigned to array
AstNode* exprp = pinp->exprp();
longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
any_overrides = true;
} else {
AstConst* exprp = pinp->exprp()->castConst();
AstConst* origp = modvarp->valuep()->castConst();
AstConst* exprp = VN_CAST(pinp->exprp(), Const);
AstConst* origp = VN_CAST(modvarp->valuep(), Const);
if (!exprp) {
//if (debug()) pinp->dumpTree(cout,"error:");
pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName());
@ -583,7 +583,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
}
}
} else if (AstParamTypeDType* modvarp = pinp->modPTypep()) {
AstNodeDType* exprp = pinp->exprp()->castNodeDType();
AstNodeDType* exprp = VN_CAST(pinp->exprp(), NodeDType);
AstNodeDType* origp = modvarp->subDTypep();
if (!exprp) {
pinp->v3error("Parameter type pin value isn't a type: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
@ -605,39 +605,39 @@ void ParamVisitor::visitCell(AstCell* nodep) {
}
}
IfaceRefRefs ifaceRefRefs;
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
AstVar* modvarp = pinp->modVarp();
if (modvarp->isIfaceRef()) {
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
if (!portIrefp && modvarp->subDTypep()->castUnpackArrayDType()) {
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
AstIfaceRefDType* portIrefp = VN_CAST(modvarp->subDTypep(), IfaceRefDType);
if (!portIrefp && VN_IS(modvarp->subDTypep(), UnpackArrayDType)) {
portIrefp = VN_CAST(VN_CAST(modvarp->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
}
AstIfaceRefDType* pinIrefp = NULL;
AstNode* exprp = pinp->exprp();
if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
&& exprp->castVarRef()->varp()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType();
&& VN_IS(exprp, VarRef)
&& VN_CAST(exprp, VarRef)->varp()
&& VN_CAST(exprp, VarRef)->varp()->subDTypep()
&& VN_IS(VN_CAST(exprp, VarRef)->varp()->subDTypep(), IfaceRefDType))
pinIrefp = VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), IfaceRefDType);
else if (exprp
&& exprp->op1p()
&& exprp->op1p()->castVarRef()
&& exprp->op1p()->castVarRef()->varp()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
&& VN_IS(exprp->op1p(), VarRef)
&& VN_CAST(exprp->op1p(), VarRef)->varp()
&& VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep()
&& VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)
&& VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep()
&& VN_CAST(VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))
pinIrefp = VN_CAST(VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
else if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
&& exprp->castVarRef()->varp()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
&& VN_IS(exprp, VarRef)
&& VN_CAST(exprp, VarRef)->varp()
&& VN_CAST(exprp, VarRef)->varp()->subDTypep()
&& VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)
&& VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep()
&& VN_CAST(VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))
pinIrefp = VN_CAST(VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
UINFO(9," portIfaceRef "<<portIrefp<<endl);
@ -698,9 +698,9 @@ void ParamVisitor::visitCell(AstCell* nodep) {
}
// Keep tree sorted by level
AstNodeModule* insertp = srcModp;
while (insertp->nextp()->castNodeModule()
&& insertp->nextp()->castNodeModule()->level() < cellmodp->level()) {
insertp = insertp->nextp()->castNodeModule();
while (VN_IS(insertp->nextp(), NodeModule)
&& VN_CAST(insertp->nextp(), NodeModule)->level() < cellmodp->level()) {
insertp = VN_CAST(insertp->nextp(), NodeModule);
}
insertp->addNextHere(cellmodp);
@ -730,7 +730,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
// Assign parameters to the constants specified
// DOES clone() so must be finished with module clonep() before here
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (pinp->exprp()) {
if (AstVar* modvarp = pinp->modVarp()) {
AstNode* newp = pinp->exprp(); // Const or InitArray
@ -740,7 +740,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
modvarp->valuep(newp->cloneTree(false));
}
else if (AstParamTypeDType* modptp = pinp->modPTypep()) {
AstNodeDType* dtypep = pinp->exprp()->castNodeDType();
AstNodeDType* dtypep = VN_CAST(pinp->exprp(), NodeDType);
if (!dtypep) pinp->v3fatalSrc("unlinked param dtype");
if (modptp->childDTypep()) pushDeletep(modptp->childDTypep()->unlinkFrBack());
// Set this parameter to value requested by cell

View File

@ -123,9 +123,9 @@ private:
}
bool assignNoTemp(AstNodeAssign* nodep) {
return (nodep->lhsp()->castVarRef()
return (VN_IS(nodep->lhsp(), VarRef)
&& !AstVar::scVarRecurse(nodep->lhsp())
&& nodep->rhsp()->castConst());
&& VN_IS(nodep->rhsp(), Const));
}
void checkNode(AstNode* nodep) {
// Consider adding a temp for this expression.
@ -141,14 +141,14 @@ private:
if (nodep->isWide()) {
if (m_assignLhs) {
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castNodeAssign()
&& assignNoTemp(nodep->firstAbovep()->castNodeAssign())) {
&& VN_IS(nodep->firstAbovep(), NodeAssign)
&& assignNoTemp(VN_CAST(nodep->firstAbovep(), NodeAssign))) {
// Not much point if it's just a direct assignment to a constant
} else if (nodep->backp()->castSel()
&& nodep->backp()->castSel()->widthp() == nodep) {
} else if (VN_IS(nodep->backp(), Sel)
&& VN_CAST(nodep->backp(), Sel)->widthp() == nodep) {
// AstSel::width must remain a constant
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castArraySel()) {
&& VN_IS(nodep->firstAbovep(), ArraySel)) {
// ArraySel's are pointer refs, ignore
} else {
UINFO(4,"Cre Temp: "<<nodep<<endl);
@ -267,7 +267,7 @@ private:
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
if (!nodep->user2SetOnce()) {
UINFO(4," ShiftFix "<<nodep<<endl);
AstConst* shiftp = nodep->rhsp()->castConst();
const AstConst* shiftp = VN_CAST(nodep->rhsp(), Const);
if (shiftp && shiftp->num().mostSetBitP1() > 32) {
shiftp->v3error("Unsupported: Shifting of by over 32-bit number isn't supported."
<<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n");
@ -359,8 +359,8 @@ private:
virtual void visit(AstNodeCond* nodep) {
nodep->iterateChildren(*this);
if (nodep->expr1p()->isWide()
&& !nodep->condp()->castConst()
&& !nodep->condp()->castVarRef()) {
&& !VN_IS(nodep->condp(), Const)
&& !VN_IS(nodep->condp(), VarRef)) {
// We're going to need the expression several times in the expanded code,
// so might as well make it a common expression
createDeepTemp(nodep->condp(), false);
@ -375,10 +375,10 @@ private:
m_stmtp = NULL;
if (v3Global.opt.autoflush()) {
AstNode* searchp = nodep->nextp();
while (searchp && searchp->castComment()) searchp = searchp->nextp();
while (searchp && VN_IS(searchp, Comment)) searchp = searchp->nextp();
if (searchp
&& searchp->castDisplay()
&& nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) {
&& VN_IS(searchp, Display)
&& nodep->filep()->sameGateTree(VN_CAST(searchp, Display)->filep())) {
// There's another display next; we can just wait to flush
} else {
UINFO(4,"Autoflush "<<nodep<<endl);
@ -393,7 +393,7 @@ private:
// to avoid passing a pointer to a temporary.
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
if (expp->dtypep()->basicp()->isString()
&& !expp->castVarRef()) {
&& !VN_IS(expp, VarRef)) {
createDeepTemp(expp, true);
}
}

View File

@ -110,11 +110,11 @@ private:
m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(),
nodep, scopename, m_aboveScopep, m_aboveCellp);
if (nodep->castPackage()) m_packageScopes.insert(make_pair(nodep->castPackage(), m_scopep));
if (VN_IS(nodep, Package)) m_packageScopes.insert(make_pair(VN_CAST(nodep, Package), m_scopep));
// Now for each child cell, iterate the module this cell points to
for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) {
if (AstCell* cellp = cellnextp->castCell()) {
if (AstCell* cellp = VN_CAST(cellnextp, Cell)) {
AstScope* oldScopep = m_scopep;
AstCell* oldAbCellp = m_aboveCellp;
AstScope* oldAbScopep = m_aboveScopep;
@ -381,7 +381,7 @@ private:
if (nodep->packagep()) {
// Point to the clone
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
AstNodeFTask* newp = nodep->taskp()->user2p()->castNodeFTask();
AstNodeFTask* newp = VN_CAST(nodep->taskp()->user2p(), NodeFTask);
if (!newp) nodep->v3fatalSrc("No clone for package function");
nodep->taskp(newp);
UINFO(9," New pkg-taskref "<<nodep<<endl);

View File

@ -119,14 +119,14 @@ private:
// Potentially very slow, intended for debugging
string prettyNumber(V3Number* nump, AstNodeDType* dtypep) {
if (AstRefDType* refdtypep = dtypep->castRefDType()) {
if (AstRefDType* refdtypep = VN_CAST(dtypep, RefDType)) {
dtypep = refdtypep->skipRefp();
}
if (AstStructDType* stp = dtypep->castStructDType()) {
if (AstStructDType* stp = VN_CAST(dtypep, StructDType)) {
if (stp->packed()) {
std::ostringstream out;
out<<"'{";
for (AstMemberDType* itemp = stp->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
for (AstMemberDType* itemp = stp->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
int width = itemp->width();
int lsb = itemp->lsb();
int msb = lsb + width - 1;
@ -143,7 +143,7 @@ private:
out<<"}";
return out.str();
}
} else if (AstPackArrayDType * arrayp = dtypep->castPackArrayDType()) {
} else if (AstPackArrayDType * arrayp = VN_CAST(dtypep, PackArrayDType)) {
if (AstNodeDType * childTypep = arrayp->subDTypep()) {
std::ostringstream out;
out<<"[";
@ -314,7 +314,7 @@ private:
}
void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) {
// Don't do setNumber, as value isn't yet visible to following statements
if (nodep->castAssignDly()) {
if (VN_IS(nodep, AssignDly)) {
// Don't do setNumber, as value isn't yet visible to following statements
newOutNumber(vscp)->opAssign(*nump);
} else {
@ -341,9 +341,9 @@ private:
// We can't have non-delayed assignments with same value on LHS and RHS
// as we don't figure out variable ordering.
// Delayed is OK though, as we'll decode the next state separately.
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()
&& !nodep->varp()->dtypeSkipRefp()->castPackArrayDType()
&& !nodep->varp()->dtypeSkipRefp()->castStructDType())
if (!VN_IS(nodep->varp()->dtypeSkipRefp(), BasicDType)
&& !VN_IS(nodep->varp()->dtypeSkipRefp(), PackArrayDType)
&& !VN_IS(nodep->varp()->dtypeSkipRefp(), StructDType))
clearOptimizable(nodep,"Array references/not basic");
if (nodep->lvalue()) {
if (m_inDlyAssign) {
@ -576,11 +576,11 @@ private:
// Recurse down to find final variable being set (outVarrefp), with value to write on nodep->rhsp()
checkNodeInfo(selp);
selp->lsbp()->iterateAndNext(*this); // Bit index
if (AstVarRef* varrefp = selp->fromp()->castVarRef()) {
if (AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef)) {
outVarrefpRef = varrefp;
lsbRef = *fetchNumber(selp->lsbp());
return; // And presumably still optimizable()
} else if (AstSel* subselp = selp->lhsp()->castSel()) {
} else if (AstSel* subselp = VN_CAST(selp->lhsp(), Sel)) {
V3Number sublsb = V3Number(nodep->fileline());
handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb/*ref*/, depth+1);
if (optimizable()) {
@ -595,7 +595,7 @@ private:
virtual void visit(AstNodeAssign* nodep) {
if (jumpingOver(nodep)) return;
if (!optimizable()) return; // Accelerate
if (nodep->castAssignDly()) {
if (VN_IS(nodep, AssignDly)) {
if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
m_anyAssignDly = true;
m_inDlyAssign = true;
@ -604,11 +604,11 @@ private:
m_anyAssignComb = true;
}
if (AstSel* selp = nodep->lhsp()->castSel()) {
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) {
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
handleAssignSel(nodep, selp);
}
else if (!nodep->lhsp()->castVarRef()) {
else if (!VN_IS(nodep->lhsp(), VarRef)) {
clearOptimizable(nodep, "LHS isn't simple variable");
}
else if (m_checkOnly) {
@ -617,7 +617,7 @@ private:
else if (optimizable()) {
nodep->rhsp()->iterateAndNext(*this);
if (optimizable()) {
AstNode* vscp = varOrScope(nodep->lhsp()->castVarRef());
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
assignOutNumber(nodep, vscp, fetchNumber(nodep->rhsp()));
}
}
@ -636,7 +636,7 @@ private:
} else if (optimizable()) {
nodep->exprp()->iterateAndNext(*this);
bool hit = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (!itemp->isDefault()) {
for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) {
if (hit) break;
@ -653,7 +653,7 @@ private:
}
}
// Else default match
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
if (hit) break;
if (!hit && itemp->isDefault()) {
itemp->bodysp()->iterateAndNext(*this);
@ -764,9 +764,9 @@ private:
if (!optimizable()) return; // Accelerate
UINFO(5," FUNCREF "<<nodep<<endl);
if (!m_params) { badNodeType(nodep); return; }
AstNodeFTask* funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
AstNodeFTask* funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
// Apply function call values to function
V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
// Must do this in two steps, eval all params, then apply them

View File

@ -72,7 +72,7 @@ class SliceVisitor : public AstNVisitor {
AstNode* cloneAndSel(AstNode* nodep, int elements, int offset) {
// Insert an ArraySel, except for a few special cases
AstUnpackArrayDType* arrayp = nodep->dtypep()->skipRefp()->castUnpackArrayDType();
AstUnpackArrayDType* arrayp = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
if (!arrayp) { // V3Width should have complained, but...
if (!m_assignError) nodep->v3error(nodep->prettyTypeName()<<" is not an unpacked array, but is in an unpacked array context");
m_assignError = true;
@ -85,7 +85,7 @@ class SliceVisitor : public AstNVisitor {
elements = 1; offset = 0;
}
AstNode* newp;
if (AstInitArray* initp = nodep->castInitArray()) {
if (AstInitArray* initp = VN_CAST(nodep, InitArray)) {
UINFO(9," cloneInitArray("<<elements<<","<<offset<<") "<<nodep<<endl);
AstNode* itemp = initp->initsp();
int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset;
@ -98,21 +98,21 @@ class SliceVisitor : public AstNVisitor {
}
newp = itemp->cloneTree(false);
}
else if (AstNodeCond* snodep = nodep->castNodeCond()) {
else if (AstNodeCond* snodep = VN_CAST(nodep, NodeCond)) {
UINFO(9," cloneCond("<<elements<<","<<offset<<") "<<nodep<<endl);
return snodep->cloneType(snodep->condp()->cloneTree(false),
cloneAndSel(snodep->expr1p(), elements, offset),
cloneAndSel(snodep->expr2p(), elements, offset));
}
else if (AstSliceSel* snodep = nodep->castSliceSel()) {
else if (AstSliceSel* snodep = VN_CAST(nodep, SliceSel)) {
UINFO(9," cloneSliceSel("<<elements<<","<<offset<<") "<<nodep<<endl);
int leOffset = (snodep->declRange().lo()
+ (!snodep->declRange().littleEndian() ? snodep->declRange().elements()-1-offset : offset));
newp = new AstArraySel(nodep->fileline(), snodep->fromp()->cloneTree(false), leOffset);
}
else if (nodep->castArraySel()
|| nodep->castNodeVarRef()
|| nodep->castNodeSel()) {
else if (VN_IS(nodep, ArraySel)
|| VN_IS(nodep, NodeVarRef)
|| VN_IS(nodep, NodeSel)) {
UINFO(9," cloneSel("<<elements<<","<<offset<<") "<<nodep<<endl);
int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset;
newp = new AstArraySel(nodep->fileline(), nodep->cloneTree(false), leOffset);
@ -128,12 +128,12 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstNodeAssign* nodep) {
// Called recursively on newly created assignments
if (!nodep->user1()
&& !nodep->castAssignAlias()) {
&& !VN_IS(nodep, AssignAlias)) {
nodep->user1(true);
m_assignError = false;
if (debug()>=9) { cout<<endl; nodep->dumpTree(cout," Deslice-In: "); }
AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp();
if (AstUnpackArrayDType* arrayp = dtp->castUnpackArrayDType()) {
if (AstUnpackArrayDType* arrayp = VN_CAST(dtp, UnpackArrayDType)) {
// Left and right could have different msb/lsbs/endianness, but #elements is common
// and all variables are realigned to start at zero
// Assign of a little endian'ed slice to a big endian one must reverse the elements
@ -170,17 +170,19 @@ class SliceVisitor : public AstNVisitor {
// If it's an unpacked array, blow it up into comparing each element
AstNodeDType* fromDtp = nodep->lhsp()->dtypep()->skipRefp();
UINFO(9, " Bi-Eq/Neq expansion "<<nodep<<endl);
if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) {
if (AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
AstNodeBiop* logp = NULL;
for (int index = 0; index < adtypep->rangep()->elementsConst(); ++index) {
// EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1])
AstNodeBiop* clonep = nodep->cloneType
(new AstArraySel(nodep->fileline(),
nodep->lhsp()->cloneTree(false),
index),
new AstArraySel(nodep->fileline(),
nodep->rhsp()->cloneTree(false),
index))->castNodeBiop();
AstNodeBiop* clonep
= VN_CAST(nodep->cloneType
(new AstArraySel(nodep->fileline(),
nodep->lhsp()->cloneTree(false),
index),
new AstArraySel(nodep->fileline(),
nodep->rhsp()->cloneTree(false),
index)),
NodeBiop);
if (!logp) logp = clonep;
else {
switch (nodep->type()) {

View File

@ -365,7 +365,7 @@ private:
void reorderBlock(AstNode* nodep) {
// Reorder statements in the completed graph
AstAlways* splitAlwaysp = nodep->backp()->castAlways();
AstAlways* splitAlwaysp = VN_CAST(nodep->backp(), Always);
// Map the rank numbers into nodes they associate with
typedef std::multimap<uint32_t,AstNode*> RankNodeMap;

View File

@ -101,7 +101,7 @@ private:
nodep->iterateChildrenConst(*this);
if (m_counting && nodep->dtypep()) {
if (nodep->isUsedClock()) ++m_statVarClock;
if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray;
if (VN_IS(nodep->dtypeSkipRefp(), UnpackArrayDType)) ++m_statVarArray;
else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
if (int(m_statVarWidths.size()) <= nodep->width()) {
m_statVarWidths.resize(nodep->width()+5);
@ -123,7 +123,7 @@ private:
allNodes(nodep);
nodep->iterateChildrenConst(*this);
if (m_counting) {
if (nodep->varp()->dtypeSkipRefp()->castBasicDType()) {
if (VN_IS(nodep->varp()->dtypeSkipRefp(), BasicDType)) {
m_statVarScpBytes += nodep->varp()->dtypeSkipRefp()->widthTotalBytes();
}
}

View File

@ -268,7 +268,7 @@ private:
m_assignStep++;
nodep->rhsp()->iterateAndNext(*this);
bool hit=false;
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) {
if (AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef)) {
if (isSubstVar(varrefp->varp())) {
SubstVarEntry* entryp = getEntryp(varrefp);
hit = true;
@ -281,11 +281,11 @@ private:
}
}
}
else if (AstWordSel* wordp = nodep->lhsp()->castWordSel()) {
if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) {
if (wordp->rhsp()->castConst()
else if (AstWordSel* wordp = VN_CAST(nodep->lhsp(), WordSel)) {
if (AstVarRef* varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
if (VN_IS(wordp->rhsp(), Const)
&& isSubstVar(varrefp->varp())) {
int word = wordp->rhsp()->castConst()->toUInt();
int word = VN_CAST(wordp->rhsp(), Const)->toUInt();
SubstVarEntry* entryp = getEntryp(varrefp);
hit = true;
if (m_ops > SUBST_MAX_OPS_SUBST) {
@ -315,8 +315,8 @@ private:
}
virtual void visit(AstWordSel* nodep) {
nodep->rhsp()->accept(*this);
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
AstConst* constp = nodep->rhsp()->castConst();
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
AstConst* constp = VN_CAST(nodep->rhsp(), Const);
if (varrefp && isSubstVar(varrefp->varp())
&& !varrefp->lvalue()
&& constp) {

View File

@ -210,7 +210,7 @@ public:
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
const string& name = it->first;
VSymEnt* subSrcp = it->second;
AstVar* varp = subSrcp->nodep()->castVar();
const AstVar* varp = VN_CAST(subSrcp->nodep(), Var);
if (!onlyUnmodportable || (varp && varp->varType() == AstVarType::GPARAM)) {
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp);
reinsert(name, subSymp);
@ -224,8 +224,8 @@ public:
string scopes;
for (IdNameMap::iterator it = m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) {
AstNode* nodep = it->second->nodep();
if (nodep->castCell()
|| (nodep->castModule() && nodep->castModule()->isTop())) {
if (VN_IS(nodep, Cell)
|| (VN_IS(nodep, Module) && VN_CAST(nodep, Module)->isTop())) {
if (scopes != "") scopes += ", ";
scopes += AstNode::prettyName(it->first);
}

View File

@ -217,7 +217,7 @@ private:
createOutputAssigns(nodep, stmtsp, indexVscp, chgVscp);
// Link it in.
if (AstAlways* nodeap = nodep->castAlways()) {
if (AstAlways* nodeap = VN_CAST(nodep, Always)) {
// Keep sensitivity list, but delete all else
nodeap->bodysp()->unlinkFrBackWithNext()->deleteTree();
nodeap->addStmtp(stmtsp);
@ -328,7 +328,7 @@ private:
setp = new AstConst (outnump->fileline(), *outnump);
}
// Note InitArray requires us to have the values in inValue order
m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addValuep(setp);
VN_CAST(m_tableVarps[outnum]->varp()->valuep(), InitArray)->addValuep(setp);
outnum++;
}
@ -336,7 +336,7 @@ private:
if (inValue != inValueNextInitArray++)
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
AstNode* setp = new AstConst (nodep->fileline(), outputChgMask);
chgVscp->varp()->valuep()->castInitArray()->addValuep(setp);
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
}
} // each value
}
@ -351,8 +351,8 @@ private:
if (var1p->width() == var2p->width()
&& (var1p->dtypep()->arrayUnpackedElements()
== var2p->dtypep()->arrayUnpackedElements())) {
AstNode* init1p = var1p->valuep()->castInitArray();
AstNode* init2p = var2p->valuep()->castInitArray();
const AstNode* init1p = VN_CAST(var1p->valuep(), InitArray);
const AstNode* init2p = VN_CAST(var2p->valuep(), InitArray);
if (init1p->sameGateTree(init2p)) {
UINFO(8," Duplicate table var "<<vsc2p<<" == "<<vsc1p<<endl);
vsc1p->unlinkFrBack()->deleteTree();

View File

@ -119,7 +119,7 @@ private:
public:
// METHODS
AstScope* getScope(AstNodeFTask* nodep) {
AstScope* scopep = nodep->user3p()->castScope();
AstScope* scopep = VN_CAST(nodep->user3p(), Scope);
if (!scopep) nodep->v3fatalSrc("No scope for function");
return scopep;
}
@ -166,7 +166,7 @@ private:
// However, to create variables, we need to track the scopes involved.
// Find all var->varscope mappings, for later cleanup
for (AstNode* stmtp = nodep->varsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVarScope* vscp = stmtp->castVarScope()) {
if (AstVarScope* vscp = VN_CAST(stmtp, VarScope)) {
if (vscp->varp()->isFuncLocal()) {
UINFO(9," funcvsc "<<vscp<<endl);
m_varToScopeMap.insert(std::make_pair(std::make_pair(nodep, vscp->varp()), vscp));
@ -175,7 +175,7 @@ private:
}
// Likewise, all FTask->scope mappings
for (AstNode* stmtp = nodep->blocksp(); stmtp; stmtp=stmtp->nextp()) {
if (AstNodeFTask* taskp = stmtp->castNodeFTask()) {
if (AstNodeFTask* taskp = VN_CAST(stmtp, NodeFTask)) {
taskp->user3p(nodep);
}
}
@ -263,7 +263,7 @@ private:
// Similar code in V3Inline
if (nodep->varp()->user2p()) { // It's being converted to a alias.
UINFO(9, " relinkVar "<<(void*)nodep->varp()->user2p()<<" "<<nodep<<endl);
AstVarScope* newvscp = nodep->varp()->user2p()->castVarScope();
AstVarScope* newvscp = VN_CAST(nodep->varp()->user2p(), VarScope);
if (!newvscp) nodep->v3fatalSrc("not linked");
nodep->varScopep(newvscp);
nodep->varp(nodep->varScopep()->varp());
@ -382,14 +382,14 @@ private:
pinp->unlinkFrBack(); // Relinked to assignment below
argp->unlinkFrBack()->deleteTree(); // Args no longer needed
//
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
}
else if (portp->isInout()) {
// Correct lvalue; see comments below
V3LinkLValue::linkLValueSet(pinp);
if (AstVarRef* varrefp = pinp->castVarRef()) {
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) {
// Connect to this exact variable
AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope");
portp->user2p(localVscp);
@ -439,7 +439,7 @@ private:
AstNode* nextstmtp;
for (AstNode* stmtp = beginp; stmtp; stmtp=nextstmtp) {
nextstmtp = stmtp->nextp();
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
// Any I/O variables that fell out of above loop were already linked
if (!portp->user2p()) {
// Move it to a new localized variable
@ -487,14 +487,14 @@ private:
} else {
UINFO(9, " Port "<<portp<<endl);
UINFO(9, " pin "<<pinp<<endl);
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
}
else if (portp->isInout()) {
// Correct lvalue; see comments below
V3LinkLValue::linkLValueSet(pinp);
if (pinp->castVarRef()) {
if (VN_IS(pinp, VarRef)) {
// Connect to this exact variable
} else {
pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
@ -541,7 +541,7 @@ private:
for (AstNode* pinp = refp->pinsp(); pinp; pinp=nextpinp) {
nextpinp = pinp->nextp();
// Move pin to the CCall, removing all Arg's
AstNode* exprp = pinp->castArg()->exprp();
AstNode* exprp = VN_CAST(pinp, Arg)->exprp();
exprp->unlinkFrBack();
ccallp->addArgsp(exprp);
}
@ -564,7 +564,7 @@ private:
dpiproto += " "+nodep->cname()+" (";
string args;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn() && portp!=rtnvarp) {
if (args != "") { args+= ", "; dpiproto+= ", "; }
args += portp->name(); // Leftover so ,'s look nice
@ -716,7 +716,7 @@ private:
args += "("+v3Global.opt.prefix()+"__Syms*)(__Vscopep->symsp())"; // Upcast w/o overhead
AstNode* argnodesp = NULL;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) {
// No createDpiTemp; we make a real internal variable instead
// SAME CODE BELOW
@ -757,7 +757,7 @@ private:
// Convert output/inout arguments back to internal type
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) {
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
}
@ -817,7 +817,7 @@ private:
void makePortList(AstNodeFTask* nodep, AstVar* rtnvarp, AstCFunc* dpip) {
// Copy nodep's list of function I/O to the new dpip c function
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) {
// Move it to new function
AstVar* newPortp = portp->cloneTree(false);
@ -838,8 +838,8 @@ private:
// Convert input/inout arguments to DPI types
string args;
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
if (AstVar* portp = VN_CAST(stmtp, Var)) {
AstVarScope* portvscp = VN_CAST(portp->user2p(), VarScope); // Remembered when we created it earlier
if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp
&& portp->name() != "__Vscopep" // Passed to dpiContext, not callee
&& portp->name() != "__Vfilenamep"
@ -901,10 +901,10 @@ private:
// Convert output/inout arguments back to internal type
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())
&& !portp->isDpiOpenArray()) {
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
AstVarScope* portvscp = VN_CAST(portp->user2p(), VarScope); // Remembered when we created it earlier
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true));
}
}
@ -918,7 +918,7 @@ private:
AstNode::user2ClearTree();
AstVar* rtnvarp = NULL;
if (nodep->isFunction()) {
AstVar* portp = nodep->fvarp()->castVar();
AstVar* portp = VN_CAST(nodep->fvarp(), Var);
if (!portp) nodep->v3fatalSrc("function without function output variable");
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)");
@ -1021,7 +1021,7 @@ private:
// Create list of arguments and move to function
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
nextp = stmtp->nextp();
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) {
// Move it to new function
portp->unlinkFrBack();
@ -1096,7 +1096,7 @@ private:
}
else if (m_insMode == IM_WHILE_PRECOND) {
UINFO(5," IM_While_Precond "<<m_insStmtp);
AstWhile* whilep = m_insStmtp->castWhile();
AstWhile* whilep = VN_CAST(m_insStmtp, While);
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
whilep->addPrecondsp(newp);
}
@ -1131,13 +1131,13 @@ private:
UINFO(4," FTask REF "<<nodep<<endl);
if (debug()>=9) { nodep->dumpTree(cout,"-inlfunc:"); }
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
string namePrefix = ((nodep->castFuncRef()?"__Vfunc_":"__Vtask_")
string namePrefix = ((VN_IS(nodep, FuncRef) ? "__Vfunc_":"__Vtask_")
+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++));
// Create output variable
AstVarScope* outvscp = NULL;
if (nodep->taskp()->isFunction()) {
// Not that it's a FUNCREF, but that we're calling a function (perhaps as a task)
outvscp = createVarScope (nodep->taskp()->fvarp()->castVar(),
outvscp = createVarScope (VN_CAST(nodep->taskp()->fvarp(), Var),
namePrefix+"__Vfuncout");
}
// Create cloned statements
@ -1149,7 +1149,7 @@ private:
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
}
// Replace the ref
if (nodep->castFuncRef()) {
if (VN_IS(nodep, FuncRef)) {
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
nodep->replaceWith(outrefp);
@ -1197,7 +1197,7 @@ private:
// Any variables inside the function still have varscopes pointing to them.
// We're going to delete the vars, so delete the varscopes.
if (nodep->isFunction()) {
if (AstVar* portp = nodep->fvarp()->castVar()) {
if (AstVar* portp = VN_CAST(nodep->fvarp(), Var)) {
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
UINFO(9," funcremovevsc "<<vscp<<endl);
pushDeletep(vscp->unlinkFrBack()); VL_DANGLING(vscp);
@ -1205,7 +1205,7 @@ private:
}
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
nextp = stmtp->nextp();
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
UINFO(9," funcremovevsc "<<vscp<<endl);
pushDeletep(vscp->unlinkFrBack()); VL_DANGLING(vscp);
@ -1282,7 +1282,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
int tpinnum = 0;
AstVar* sformatp = NULL;
for (AstNode* stmtp = taskStmtsp; stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) {
tconnects.push_back(make_pair(portp, (AstArg*)NULL));
nameToIndex.insert(make_pair(portp->name(), tpinnum)); // For name based connections
@ -1301,7 +1301,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
bool reorganize = false;
for (AstNode* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
nextp = pinp->nextp();
AstArg* argp = pinp->castArg(); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
AstArg* argp = VN_CAST(pinp, Arg); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
if (argp->name() != "") {
// By name
NameToIndex::iterator it = nameToIndex.find(argp->name());
@ -1346,12 +1346,12 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
nodep->v3error("Missing argument on non-defaulted argument '"<<portp->prettyName()
<<"' in function call to "<<nodep->taskp()->prettyTypeName());
newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0);
} else if (!portp->valuep()->castConst()) {
} else if (!VN_IS(portp->valuep(), Const)) {
// The default value for this port might be a constant
// expression that hasn't been folded yet. Try folding it
// now; we don't have much to lose if it fails.
newvaluep = V3Const::constifyParamsEdit(portp->valuep());
if (!newvaluep->castConst()) {
if (!VN_IS(newvaluep, Const)) {
// Problem otherwise is we might have a varref, task call, or something else that only
// makes sense in the domain of the function, not the callee.
nodep->v3error("Unsupported: Non-constant default value in missing argument '"<<portp->prettyName()

View File

@ -223,7 +223,7 @@ private:
if (nodep->valuep() && !vvertexp->duplicatep()) {
V3Hashed::iterator dupit = hashed.findDuplicate(nodep->valuep());
if (dupit != hashed.end()) {
AstTraceInc* dupincp = hashed.iteratorNodep(dupit)->backp()->castTraceInc();
AstTraceInc* dupincp = VN_CAST(hashed.iteratorNodep(dupit)->backp(), TraceInc);
if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type");
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1u().toGraphVertex());
UINFO(8," Orig "<<nodep<<endl);
@ -359,10 +359,10 @@ private:
}
AstCCall* callp = new AstCCall(funcp->fileline(), funcp);
callp->argTypes("vlSymsp, vcdp, code");
if (callfromp->castCFunc()) {
callfromp->castCFunc()->addStmtsp(callp);
} else if (callfromp->castIf()) {
callfromp->castIf()->addIfsp(callp);
if (VN_IS(callfromp, CFunc)) {
VN_CAST(callfromp, CFunc)->addStmtsp(callp);
} else if (VN_IS(callfromp, If)) {
VN_CAST(callfromp, If)->addIfsp(callp);
} else {
callfromp->v3fatalSrc("Unknown caller node type"); // Where to add it??
}
@ -602,7 +602,7 @@ private:
// If so, all funcs might share the same activity code
TraceActivityVertex* activityVtxp = getActivityVertexp(nodep, nodep->funcp()->slow());
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
if (AstCCall* ccallp = nextp->castCCall()) {
if (AstCCall* ccallp = VN_CAST(nextp, CCall)) {
ccallp->user2(true); // Processed
UINFO(8," SubCCALL "<<ccallp<<endl);
V3GraphVertex* ccallFuncVtxp = getCFuncVertexp(ccallp->funcp());

View File

@ -198,7 +198,7 @@ private:
if (m_traVscp) {
if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) {
addIgnore("Wide memory > --trace-max-array ents");
} else if (nodep->subDTypep()->skipRefp()->castBasicDType() // Nothing lower than this array
} else if (VN_IS(nodep->subDTypep()->skipRefp(), BasicDType) // Nothing lower than this array
&& m_traVscp->dtypep()->skipRefp() == nodep) { // Nothing above this array
// Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling
// This will put "(index)" at end of signal name for us
@ -258,13 +258,13 @@ private:
if (!nodep->packed()) {
addIgnore("Unsupported: Unpacked struct/union");
} else {
for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
string oldShowname = m_traShowname;
AstNode* oldValuep = m_traValuep;
{
m_traShowname += string(" ")+itemp->prettyName();
if (nodep->castStructDType()) {
if (VN_IS(nodep, StructDType)) {
m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
itemp->lsb(), subtypep->width());
subtypep->accept(*this);

View File

@ -101,7 +101,7 @@ public:
virtual ~TristateVertex() {}
// ACCESSORS
AstNode* nodep() const { return m_nodep; }
AstVar* varp() const { return nodep()->castVar(); }
AstVar* varp() const { return VN_CAST(nodep(), Var); }
virtual string name() const {
return ((isTristate() ? "tri\\n"
:feedsTri() ? "feed\\n" : "-\\n")
@ -180,7 +180,7 @@ private:
// A variable is tristated. Find all of the LHS VARREFs that drive this signal now need tristate drivers
for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep=edgep->inNextp()) {
TristateVertex* vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
if (AstVarRef* refp = vvertexp->nodep()->castVarRef()) {
if (const AstVarRef* refp = VN_CAST(vvertexp->nodep(), VarRef)) {
if (refp->lvalue()
// Doesn't hurt to not check if already set, but by doing so when we
// print out the debug messages, we'll see this node at level 0 instead.
@ -269,7 +269,7 @@ public:
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
TristateVertex* vvertexp = static_cast<TristateVertex*>(itp);
if (vvertexp->isTristate()) {
if (AstVar* nodep = vvertexp->nodep()->castVar()) {
if (AstVar* nodep = VN_CAST(vvertexp->nodep(), Var)) {
v.push_back(nodep);
}
}
@ -393,7 +393,7 @@ class TristateVisitor : public TristateBaseVisitor {
else m_modp->addStmtp(newp);
invarp->user1p(newp); // find envar given invarp
}
return invarp->user1p()->castVar();
return VN_CAST(invarp->user1p(), Var);
}
AstVar* getCreateOutVarp(AstVar* invarp) {
@ -408,7 +408,7 @@ class TristateVisitor : public TristateBaseVisitor {
else m_modp->addStmtp(newp);
invarp->user4p(newp); // find outvar given invarp
}
return invarp->user4p()->castVar();
return VN_CAST(invarp->user4p(), Var);
}
AstVar* getCreateUnconnVarp(AstNode* fromp, AstNodeDType* dtypep) {
@ -467,10 +467,10 @@ class TristateVisitor : public TristateBaseVisitor {
nodep->v3error("Unsupported LHS tristate construct: "<<nodep->prettyTypeName());
}
// Ignore Var's because they end up adjacent to statements
if ((nodep->op1p() && nodep->op1p()->user1p() && !nodep->op1p()->castVar())
|| (nodep->op2p() && nodep->op2p()->user1p() && !nodep->op1p()->castVar())
|| (nodep->op3p() && nodep->op3p()->user1p() && !nodep->op1p()->castVar())
|| (nodep->op4p() && nodep->op4p()->user1p() && !nodep->op1p()->castVar())) {
if ((nodep->op1p() && nodep->op1p()->user1p() && !VN_IS(nodep->op1p(), Var))
|| (nodep->op2p() && nodep->op2p()->user1p() && !VN_IS(nodep->op1p(), Var))
|| (nodep->op3p() && nodep->op3p()->user1p() && !VN_IS(nodep->op1p(), Var))
|| (nodep->op4p() && nodep->op4p()->user1p() && !VN_IS(nodep->op1p(), Var))) {
nodep->v3error("Unsupported tristate construct: "<<nodep->prettyTypeName());
}
}
@ -546,7 +546,7 @@ class TristateVisitor : public TristateBaseVisitor {
outvarp->user3p(invarp->user3p()); // AstPull* propagation
if (invarp->user3p()) UINFO(9, "propagate pull to "<<outvarp<<endl);
} else if (invarp->user1p()) {
envarp = invarp->user1p()->castVar(); // From CASEEQ, foo === 1'bz
envarp = VN_CAST(invarp->user1p(), Var); // From CASEEQ, foo === 1'bz
}
AstNode* orp = NULL;
@ -936,13 +936,13 @@ class TristateVisitor : public TristateBaseVisitor {
// away later when we determine the signal has no tristate
nodep->iterateChildren(*this);
UINFO(9,dbgState()<<nodep<<endl);
AstConst* constp = nodep->lhsp()->castConst(); // Constification always moves const to LHS
AstVarRef* varrefp = nodep->rhsp()->castVarRef(); // Input variable
const AstConst* constp = VN_CAST(nodep->lhsp(), Const); // Constification always moves const to LHS
AstVarRef* varrefp = VN_CAST(nodep->rhsp(), VarRef); // Input variable
if (constp && constp->user1p() && varrefp) {
// 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in))
varrefp->unlinkFrBack();
FileLine* fl = nodep->fileline();
V3Number oneIfEn = constp->user1p()->castConst()->num(); // visit(AstConst) already split into en/ones
V3Number oneIfEn = VN_CAST(constp->user1p(), Const)->num(); // visit(AstConst) already split into en/ones
V3Number oneIfEnOne = constp->num();
AstVar* envarp = getCreateEnVarp(varrefp->varp());
AstNode* newp = new AstLogAnd (fl, new AstEq (fl, new AstConst(fl, oneIfEn),
@ -962,7 +962,7 @@ class TristateVisitor : public TristateBaseVisitor {
}
}
void visitEqNeqWild(AstNodeBiop* nodep) {
if (!nodep->rhsp()->castConst()) {
if (!VN_IS(nodep->rhsp(), Const)) {
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
// rhs we want to keep X/Z intact, so otherwise ignore
}
@ -985,7 +985,7 @@ class TristateVisitor : public TristateBaseVisitor {
virtual void visit(AstPull* nodep) {
UINFO(9,dbgState()<<nodep<<endl);
if (m_graphing) {
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
lhsp->lvalue(true);
m_logicp = nodep;
m_tgraph.setTristate(nodep);
@ -1001,7 +1001,7 @@ class TristateVisitor : public TristateBaseVisitor {
// current limitation of this implementation is that a pullup/down
// gets applied to all bits of a bus and a bus cannot have drivers
// in opposite directions on indvidual pins.
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
lhsp->lvalue(true);
m_tgraph.didProcess(nodep);
m_tgraph.didProcess(lhsp->varp());
@ -1159,12 +1159,12 @@ class TristateVisitor : public TristateBaseVisitor {
exprrefp = NULL; // Primary input only
} else {
// pinReconnect should have converted this
exprrefp = outpinp->exprp()->castVarRef();
exprrefp = VN_CAST(outpinp->exprp(), VarRef);
if (!exprrefp) nodep->v3error("Unsupported tristate port expression: "<<nodep->exprp()->prettyTypeName());
}
} else {
// pinReconnect should have converted this
exprrefp = outAssignp->rhsp()->castVarRef(); // This should be the same var as the output pin
exprrefp = VN_CAST(outAssignp->rhsp(), VarRef); // This should be the same var as the output pin
if (!exprrefp) nodep->v3error("Unsupported tristate port expression: "<<nodep->exprp()->prettyTypeName());
}
if (exprrefp) {

View File

@ -266,7 +266,7 @@ private:
AstVar* varp = nodep->varp();
if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx()
&& !m_inBBox // We may have falsely considered a SysIgnore as a driver
&& !nodep->castVarXRef() // Xrefs might point at two different instances
&& !VN_IS(nodep, VarXRef) // Xrefs might point at two different instances
&& !varp->fileline()->warnIsOff(V3ErrorCode::ALWCOMBORDER)) { // Warn only once per variable
nodep->v3warn(ALWCOMBORDER, "Always_comb variable driven after use: "<<nodep->prettyName());
varp->fileline()->modifyWarnOff(V3ErrorCode::ALWCOMBORDER, true); // Complain just once for any usage
@ -303,8 +303,8 @@ private:
nodep->iterateChildren(*this);
}
virtual void visit(AstSel* nodep) {
AstNodeVarRef* varrefp = nodep->fromp()->castNodeVarRef();
AstConst* constp = nodep->lsbp()->castConst();
AstNodeVarRef* varrefp = VN_CAST(nodep->fromp(), NodeVarRef);
AstConst* constp = VN_CAST(nodep->lsbp(), Const);
if (varrefp && constp && !constp->num().isFourState()) {
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);

View File

@ -104,8 +104,8 @@ private:
AstNode* prep = nodep;
// Scan back to put the condlvalue above all selects (IE top of the lvalue)
while (prep->backp()->castNodeSel()
|| prep->backp()->castSel()) {
while (VN_IS(prep->backp(), NodeSel)
|| VN_IS(prep->backp(), Sel)) {
prep=prep->backp();
}
FileLine* fl = nodep->fileline();
@ -113,7 +113,7 @@ private:
// Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b,
// Saves us teaching V3Const how to optimize, and it won't be needed again.
if (AstIf* ifp = prep->user2p()->castIf()) {
if (AstIf* ifp = VN_CAST(prep->user2p(), If)) {
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
AstNRelinker replaceHandle;
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
@ -179,7 +179,7 @@ private:
UINFO(4," N/EQCASE->EQ "<<nodep<<endl);
V3Const::constifyEdit(nodep->lhsp()); // lhsp may change
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) {
// Both sides are constant, node can be constant
V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
return;
@ -188,14 +188,14 @@ private:
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* newp;
// If we got ==1'bx it can never be true (but 1'bx==1'bx can be!)
if (((lhsp->castConst() && lhsp->castConst()->num().isFourState())
|| (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) {
V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1));
if (((VN_IS(lhsp, Const) && VN_CAST(lhsp, Const)->num().isFourState())
|| (VN_IS(rhsp, Const) && VN_CAST(rhsp, Const)->num().isFourState()))) {
V3Number num (nodep->fileline(), 1, (VN_IS(nodep, EqCase) ? 0:1));
newp = new AstConst (nodep->fileline(), num);
lhsp->deleteTree(); VL_DANGLING(lhsp);
rhsp->deleteTree(); VL_DANGLING(rhsp);
} else {
if (nodep->castEqCase())
if (VN_IS(nodep, EqCase))
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
else newp = new AstNeq (nodep->fileline(), lhsp, rhsp);
}
@ -209,7 +209,7 @@ private:
UINFO(4," N/EQWILD->EQ "<<nodep<<endl);
V3Const::constifyEdit(nodep->lhsp()); // lhsp may change
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) {
// Both sides are constant, node can be constant
V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
return;
@ -217,20 +217,20 @@ private:
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* newp;
if (!rhsp->castConst()) {
if (!VN_IS(rhsp, Const)) {
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
// Replace with anything that won't cause more errors
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
} else {
// X or Z's become mask, ala case statements.
V3Number nummask (rhsp->fileline(), rhsp->width());
nummask.opBitsNonX(rhsp->castConst()->num());
nummask.opBitsNonX(VN_CAST(rhsp, Const)->num());
V3Number numval (rhsp->fileline(), rhsp->width());
numval.opBitsOne (rhsp->castConst()->num());
numval.opBitsOne (VN_CAST(rhsp, Const)->num());
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
new AstConst(nodep->fileline(), nummask));
AstNode* and2p = new AstConst(nodep->fileline(), numval);
if (nodep->castEqWild())
if (VN_IS(nodep, EqWild))
newp = new AstEq (nodep->fileline(), and1p, and2p);
else newp = new AstNeq (nodep->fileline(), and1p, and2p);
rhsp->deleteTree(); VL_DANGLING(rhsp);
@ -333,7 +333,7 @@ private:
// Guard against reading/writing past end of bit vector array
AstNode* basefromp = AstArraySel::baseFromp(nodep);
bool lvalue = false;
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
lvalue = varrefp->lvalue();
}
// Find range of dtype we are selecting from
@ -385,9 +385,9 @@ private:
// Guard against reading/writing past end of arrays
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
bool lvalue = false;
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
lvalue = varrefp->lvalue();
} else if (basefromp->castConst()) {
} else if (VN_IS(basefromp, Const)) {
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
} else {
nodep->v3fatalSrc("No VarRef or Const under ArraySel");
@ -396,7 +396,7 @@ private:
int declElements = -1;
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
declElements = adtypep->elementsConst();
} else {
nodep->v3error("Select from non-array "<<dtypep->prettyTypeName());
@ -415,7 +415,7 @@ private:
condp->deleteTree();
}
else if (!lvalue
&& !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension
&& !VN_IS(nodep->backp(), ArraySel)) { // Too complicated and slow if mid-multidimension
// ARRAYSEL(...) -> COND(LT(bit<maxbit), ARRAYSEL(...), {width{1'bx}})
AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle);

View File

@ -110,22 +110,22 @@ private:
if (incp) UINFO(6, " Inc "<<incp<<endl);
// Initial value check
AstAssign* initAssp = initp->castAssign();
AstAssign* initAssp = VN_CAST(initp, Assign);
if (!initAssp) return cantUnroll(nodep, "no initial assignment");
if (initp->nextp() && initp->nextp()!=nodep) nodep->v3fatalSrc("initial assignment shouldn't be a list");
if (!initAssp->lhsp()->castVarRef()) return cantUnroll(nodep, "no initial assignment to simple variable");
if (!VN_IS(initAssp->lhsp(), VarRef)) return cantUnroll(nodep, "no initial assignment to simple variable");
//
// Condition check
if (condp->nextp()) nodep->v3fatalSrc("conditional shouldn't be a list");
//
// Assignment of next value check
AstAssign* incAssp = incp->castAssign();
AstAssign* incAssp = VN_CAST(incp, Assign);
if (!incAssp) return cantUnroll(nodep, "no increment assignment");
if (incAssp->nextp()) nodep->v3fatalSrc("increment shouldn't be a list");
m_forVarp = initAssp->lhsp()->castVarRef()->varp();
m_forVscp = initAssp->lhsp()->castVarRef()->varScopep();
if (nodep->castGenFor() && !m_forVarp->isGenVar()) {
m_forVarp = VN_CAST(initAssp->lhsp(), VarRef)->varp();
m_forVscp = VN_CAST(initAssp->lhsp(), VarRef)->varScopep();
if (VN_IS(nodep, GenFor) && !m_forVarp->isGenVar()) {
nodep->v3error("Non-genvar used in generate for: "<<m_forVarp->prettyName()<<endl);
}
if (m_generate) V3Const::constifyParamsEdit(initAssp->rhsp()); // rhsp may change
@ -134,7 +134,7 @@ private:
// however, for repeat loops, the loop variable is auto-generated
// and the initp statements will reference a variable outside of the initp scope
// alas, failing to simulate.
AstConst* constInitp = initAssp->rhsp()->castConst();
AstConst* constInitp = VN_CAST(initAssp->rhsp(), Const);
if (!constInitp) return cantUnroll(nodep, "non-constant initializer");
//
@ -156,7 +156,7 @@ private:
if (!m_generate) {
AstAssign *incpAssign = incp->castAssign();
AstAssign *incpAssign = VN_CAST(incp, Assign);
if (!canSimulate(incpAssign->rhsp())) return cantUnroll(incp, "Unable to simulate increment");
if (!canSimulate(condp)) return cantUnroll(condp, "Unable to simulate condition");
@ -251,7 +251,7 @@ private:
outLoopsr++;
// Run inc
AstAssign* incpass = incp->castAssign();
AstAssign* incpass = VN_CAST(incp, Assign);
V3Number newLoopValue = V3Number(initp->fileline());
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
return false;
@ -287,7 +287,7 @@ private:
bodysp->unlinkFrBackWithNext();
stmtsp = AstNode::addNextNull(stmtsp, bodysp); // Maybe null if no body
}
if (incp && !nodep->castGenFor()) { // Generates don't need to increment loop index
if (incp && !VN_IS(nodep, GenFor)) { // Generates don't need to increment loop index
incp->unlinkFrBackWithNext();
stmtsp = AstNode::addNextNull(stmtsp, incp); // Maybe null if no body
}
@ -338,7 +338,7 @@ private:
}
// loopValue += valInc
AstAssign *incpass = incp->castAssign();
AstAssign *incpass = VN_CAST(incp, Assign);
V3Number newLoopValue = V3Number(nodep->fileline());
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
nodep->v3error("Loop unrolling failed");

View File

@ -24,7 +24,7 @@
// widthUnsized() = # bits for unsized constant, or 0 if it's sized
// widthMin() = Alternative acceptable width for linting, or width() if sized
// Determine this subop's width, can be either:
// Fixed width X
// Fixed width X
// Unsized, min width X ('d5 is unsized, min 3 bits.)
// Pass up:
// width() = # bits this expression generates
@ -38,8 +38,8 @@
// If subop larger, add a EXTRACT
// If subop smaller, add a EXTEND
// Pass size to sub-expressions if required (+/-* etc)
// FINAL = true.
// Subexpressions lint and extend as needed
// FINAL = true.
// Subexpressions lint and extend as needed
//
//*************************************************************************
// Signedness depends on:
@ -53,7 +53,7 @@
// Else, if any operand unsigned, output unsigned
//
// Real number rules:
// Real numbers are real (duh)
// Real numbers are real (duh)
// Reals convert to integers by rounding
// Reals init to 0.0
// Logicals convert compared to zero
@ -393,14 +393,14 @@ private:
AstNumeric::UNSIGNED);
// Cleanup zero width Verilog2001 {x,{0{foo}}} now,
// otherwise having width(0) will cause later assertions to fire
if (AstReplicate* repp=nodep->lhsp()->castReplicate()) {
if (AstReplicate* repp=VN_CAST(nodep->lhsp(), Replicate)) {
if (repp->width()==0) { // Keep rhs
nodep->replaceWith(nodep->rhsp()->unlinkFrBack());
pushDeletep(nodep); VL_DANGLING(nodep);
return;
}
}
if (AstReplicate* repp=nodep->rhsp()->castReplicate()) {
if (AstReplicate* repp=VN_CAST(nodep->rhsp(), Replicate)) {
if (repp->width()==0) { // Keep lhs
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
pushDeletep(nodep); VL_DANGLING(nodep);
@ -446,10 +446,10 @@ private:
iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH);
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
AstConst* constp = nodep->rhsp()->castConst();
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
uint32_t times = constp->toUInt();
if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
if (times==0 && !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)"); times=1;
}
if (nodep->lhsp()->isString()) {
@ -477,10 +477,10 @@ private:
iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH);
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
AstConst* constp = nodep->rhsp()->castConst();
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
uint32_t times = constp->toUInt();
if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
if (times==0 && !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)");
}
nodep->dtypeSetString();
@ -497,8 +497,8 @@ private:
iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH);
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
AstConst* constp = nodep->rhsp()->castConst();
AstBasicDType* basicp = nodep->rhsp()->castBasicDType();
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
AstBasicDType* basicp = VN_CAST(nodep->rhsp(), BasicDType);
if (!constp && !basicp) { nodep->v3error("Slice size isn't a constant or basic data type."); return; }
if (basicp) { // Convert data type to a constant size
AstConst* newp = new AstConst(basicp->fileline(), basicp->width());
@ -544,8 +544,8 @@ private:
int width = nodep->elementsConst();
if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<<std::hex<<width);
// Note width() not set on range; use elementsConst()
if (nodep->littleEndian() && !nodep->backp()->castUnpackArrayDType()
&& !nodep->backp()->castCell()) { // For cells we warn in V3Inst
if (nodep->littleEndian() && !VN_IS(nodep->backp(), UnpackArrayDType)
&& !VN_IS(nodep->backp(), Cell)) { // For cells we warn in V3Inst
nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<<nodep->lsbConst()<<":"<<nodep->msbConst());
}
}
@ -564,14 +564,14 @@ private:
iterateCheckSizedSelf(nodep,"Select Width",nodep->widthp(),SELF,BOTH);
iterateCheckSizedSelf(nodep,"Select LHS",nodep->lhsp(),SELF,BOTH);
V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change
AstConst* widthConstp = nodep->widthp()->castConst();
AstConst* widthConstp = VN_CAST(nodep->widthp(), Const);
if (!widthConstp) {
nodep->v3error("Width of bit extract isn't a constant");
nodep->dtypeSetLogicBool(); return;
}
int width = nodep->widthConst();
if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel
if (nodep->lsbp()->castConst()
if (VN_IS(nodep->lsbp(), Const)
&& nodep->msbConst() < nodep->lsbConst()) {
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
<<nodep->msbConst()<<"<"<<nodep->lsbConst());
@ -617,7 +617,7 @@ private:
UINFO(1," Related node: "<<nodep<<endl);
}
}
if (nodep->lsbp()->castConst() && nodep->msbConst() > frommsb) {
if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() > frommsb) {
// See also warning in V3Const
// We need to check here, because the widthCheckSized may silently
// add another SEL which will lose the out-of-range check
@ -660,7 +660,7 @@ private:
int frommsb;
int fromlsb;
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) {
if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
frommsb = adtypep->msb();
fromlsb = adtypep->lsb();
if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; }
@ -692,10 +692,11 @@ private:
if (!m_doGenerate) {
// Must check bounds before adding a select that truncates the bound
// Note we've already subtracted off LSB
if (nodep->bitp()->castConst() && (nodep->bitp()->castConst()->toSInt() > (frommsb-fromlsb)
|| nodep->bitp()->castConst()->toSInt() < 0)) {
if (VN_IS(nodep->bitp(), Const)
&& (VN_CAST(nodep->bitp(), Const)->toSInt() > (frommsb-fromlsb)
|| VN_CAST(nodep->bitp(), Const)->toSInt() < 0)) {
nodep->v3warn(SELRANGE,"Selection index out of range: "
<<(nodep->bitp()->castConst()->toSInt()+fromlsb)
<<(VN_CAST(nodep->bitp(), Const)->toSInt()+fromlsb)
<<" outside "<<frommsb<<":"<<fromlsb);
UINFO(1," Related node: "<<nodep<<endl);
}
@ -711,7 +712,7 @@ private:
//
// Array indices are always constant
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType();
AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType);
if (!adtypep) {
UINFO(1," Related dtype: "<<fromDtp<<endl);
nodep->v3fatalSrc("Packed array reference exceeds dimension of array");
@ -923,8 +924,8 @@ private:
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
std::pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
uint32_t msbdim = dim.first+dim.second;
if (!nodep->dimp() || nodep->dimp()->castConst() || msbdim<1) {
int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt();
if (!nodep->dimp() || VN_IS(nodep->dimp(), Const) || msbdim<1) {
int dim = !nodep->dimp() ? 1 : VN_CAST(nodep->dimp(), Const)->toSInt();
AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
@ -962,7 +963,7 @@ private:
// Cleanup array size
userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p());
nodep->dtypep(nodep); // The array itself, not subDtype
if (nodep->castUnpackArrayDType()) {
if (VN_IS(nodep, UnpackArrayDType)) {
// Historically array elements have width of the ref type not the full array
nodep->widthFromSub(nodep->subDTypep());
} else {
@ -1042,7 +1043,7 @@ private:
// nodep->dtp could be data type, or a primary_constant
// Don't iterate lhsp, will deal with that once convert the type
V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change
if (AstConst* constp = nodep->dtp()->castConst()) {
if (AstConst* constp = VN_CAST(nodep->dtp(), Const)) {
constp->unlinkFrBack();
AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp);
nodep->replaceWith(newp);
@ -1095,19 +1096,19 @@ private:
virtual void visit(AstCastSize* nodep) {
// IEEE: Signedness of result is same as self-determined signedness
// However, the result is same as BITSEL, so we do not sign extend the LHS
if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
if (!VN_IS(nodep->rhsp(), Const)) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
//if (debug()) nodep->dumpTree(cout," CastSizePre: ");
if (m_vup->prelim()) {
int width = nodep->rhsp()->castConst()->toSInt();
int width = VN_CAST(nodep->rhsp(), Const)->toSInt();
if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; }
userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p());
AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType();
AstBasicDType* underDtp = VN_CAST(nodep->lhsp()->dtypep(), BasicDType);
if (!underDtp) {
underDtp = nodep->lhsp()->dtypep()->basicp();
}
if (!underDtp) {
nodep->v3error("Unsupported: Size-changing cast on non-basic data type");
underDtp = nodep->findLogicBoolDType()->castBasicDType();
underDtp = VN_CAST(nodep->findLogicBoolDType(), BasicDType);
}
// A cast propagates its size to the lower expression and is included in the maximum
// width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math.
@ -1161,21 +1162,21 @@ private:
if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep));
nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep()));
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var");
if (nodep->dtypeSkipRefp()->castUnsizedArrayDType()) {
if (VN_IS(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
if (!(m_ftaskp && m_ftaskp->dpiImport())) {
nodep->v3error("Unsized/open arrays ('[]') are only supported in DPI imports");
}
}
else if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType()
|| nodep->dtypeSkipRefp()->castNodeArrayDType()
|| nodep->dtypeSkipRefp()->castNodeClassDType())) {
else if (nodep->isIO() && !(VN_IS(nodep->dtypeSkipRefp(), BasicDType)
|| VN_IS(nodep->dtypeSkipRefp(), NodeArrayDType)
|| VN_IS(nodep->dtypeSkipRefp(), NodeClassDType))) {
nodep->v3error("Unsupported: Inputs and outputs must be simple data types");
}
if (nodep->dtypep()->skipRefToConstp()->castConstDType()) {
if (VN_IS(nodep->dtypep()->skipRefToConstp(), ConstDType)) {
nodep->isConst(true);
}
// Parameters if implicit untyped inherit from what they are assigned to
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
AstBasicDType* bdtypep = VN_CAST(nodep->dtypep(), BasicDType);
bool didchk = false;
bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit();
if (implicitParam) {
@ -1241,7 +1242,7 @@ private:
virtual void visit(AstNodeVarRef* nodep) {
if (nodep->didWidth()) return;
if (!nodep->varp()) {
if (m_paramsOnly && nodep->castVarXRef()) {
if (m_paramsOnly && VN_IS(nodep, VarXRef)) {
checkConstantOrReplace(nodep, "Parameter-resolved constants must not use dotted references: "+nodep->prettyName()); VL_DANGLING(nodep);
return;
} else {
@ -1255,7 +1256,7 @@ private:
//if (debug()>=9) { nodep->dumpTree(cout," VRin "); nodep->varp()->dumpTree(cout," forvar "); }
// Note genvar's are also entered as integers
nodep->dtypeFrom(nodep->varp());
if (nodep->backp()->castNodeAssign() && nodep->lvalue()) { // On LHS
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
}
//if (debug()>=9) nodep->dumpTree(cout," VRout ");
@ -1280,12 +1281,12 @@ private:
// Assign missing values
V3Number num (nodep->fileline(), nodep->width(), 0);
V3Number one (nodep->fileline(), nodep->width(), 1);
std::map<V3Number,AstEnumItem*> inits;
for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
std::map<V3Number,AstEnumItem*> inits;
for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), EnumItem)) {
if (itemp->valuep()) {
if (debug()>=9) { UINFO(0,"EnumInit "<<itemp<<endl); itemp->valuep()->dumpTree(cout,"-EnumInit: "); }
V3Const::constifyParamsEdit(itemp->valuep()); // itemp may change
if (!itemp->valuep()->castConst()) {
if (!VN_IS(itemp->valuep(), Const)) {
itemp->valuep()->v3error("Enum value isn't a constant");
itemp->valuep()->unlinkFrBack()->deleteTree();
continue;
@ -1302,7 +1303,7 @@ private:
}
itemp->valuep(new AstConst(itemp->fileline(), num));
}
num.opAssign(itemp->valuep()->castConst()->num());
num.opAssign(VN_CAST(itemp->valuep(), Const)->num());
// Look for duplicates
if (inits.find(num) != inits.end()) { // IEEE says illegal
itemp->v3error("Overlapping enumeration value: "<<itemp->prettyName()<<endl
@ -1311,7 +1312,7 @@ private:
} else {
inits.insert(make_pair(num,itemp));
}
num.opAdd(one, itemp->valuep()->castConst()->num());
num.opAdd(one, VN_CAST(itemp->valuep(), Const)->num());
}
}
virtual void visit(AstEnumItem* nodep) {
@ -1333,7 +1334,7 @@ private:
AstNode* enump = nodep->itemp();
if (!enump) nodep->v3fatalSrc("EnumItemRef not linked");
for (; enump; enump=enump->backp()) {
if (enump->castEnumDType()) break;
if (VN_IS(enump, EnumDType)) break;
}
if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum");
userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked
@ -1346,7 +1347,7 @@ private:
AstNodeDType* vdtypep = m_vup->dtypep();
if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor");
nodep->dtypep(vdtypep);
if (AstNodeArrayDType* arrayp = vdtypep->skipRefp()->castNodeArrayDType()) {
if (AstNodeArrayDType* arrayp = VN_CAST(vdtypep->skipRefp(), NodeArrayDType)) {
userIterateChildren(nodep, WidthVP(arrayp->subDTypep(),BOTH).p());
} else {
nodep->v3fatalSrc("InitArray on non-array");
@ -1379,7 +1380,7 @@ private:
for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) {
nextip = itemp->nextp(); // Will be unlinking
AstNode* inewp;
if (AstInsideRange* irangep = itemp->castInsideRange()) {
if (AstInsideRange* irangep = VN_CAST(itemp, InsideRange)) {
// Similar logic in V3Case
inewp = new AstAnd(itemp->fileline(),
new AstGte(itemp->fileline(),
@ -1431,13 +1432,13 @@ private:
nodep->isFourstate(false);
// MSB is first, so go backwards
AstMemberDType* itemp;
for (itemp = nodep->membersp(); itemp && itemp->nextp(); itemp=itemp->nextp()->castMemberDType()) ;
for (itemp = nodep->membersp(); itemp && itemp->nextp(); itemp=VN_CAST(itemp->nextp(), MemberDType)) ;
for (AstMemberDType* backip; itemp; itemp=backip) {
if (nodep->isFourstate()) nodep->isFourstate(true);
backip = itemp->backp()->castMemberDType();
backip = VN_CAST(itemp->backp(), MemberDType);
itemp->lsb(lsb);
if (nodep->castUnionDType()) {
width = std::max(width, itemp->width());
if (VN_IS(nodep, UnionDType)) {
width = std::max(width, itemp->width());
} else {
lsb += itemp->width();
width += itemp->width();
@ -1463,14 +1464,14 @@ private:
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
UINFO(9," from dt "<<fromDtp<<endl);
AstMemberDType* memberp = NULL; // NULL=error below
if (AstNodeClassDType* adtypep = fromDtp->castNodeClassDType()) {
if (AstNodeClassDType* adtypep = VN_CAST(fromDtp, NodeClassDType)) {
// No need to width-resolve the class, as it was done when we did the child
memberp = adtypep->findMember(nodep->name());
if (!memberp) {
nodep->v3error("Member '"<<nodep->prettyName()<<"' not found in structure");
}
}
else if (fromDtp->castEnumDType()) {
else if (VN_IS(fromDtp, EnumDType)) {
// Method call on enum without following parenthesis, e.g. "ENUM.next"
// Convert this into a method call, and let that visitor figure out what to do next
AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL);
@ -1511,7 +1512,7 @@ private:
if (debug()>=9) nodep->dumpTree("-mts-in: ");
// Should check types the method requires, but at present we don't do much
userIterate(nodep->fromp(), WidthVP(SELF,BOTH).p());
for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) {
for (AstArg* argp = VN_CAST(nodep->pinsp(), Arg); argp; argp = VN_CAST(argp->nextp(), Arg)) {
if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF,BOTH).p());
}
// Find the fromp dtype - should be a class
@ -1519,7 +1520,7 @@ private:
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL;
UINFO(9," from dt "<<fromDtp<<endl);
if (AstEnumDType* adtypep = fromDtp->castEnumDType()) {
if (AstEnumDType* adtypep = VN_CAST(fromDtp, EnumDType)) {
// Method call on enum without following parenthesis, e.g. "ENUM.next"
// Convert this into a method call, and let that visitor figure out what to do next
if (adtypep) {}
@ -1536,12 +1537,12 @@ private:
} else if (nodep->name() == "first") {
AstEnumItem* itemp = adtypep->itemsp();
if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
} else if (nodep->name() == "last") {
AstEnumItem* itemp = adtypep->itemsp();
while (itemp && itemp->nextp()) itemp = itemp->nextp()->castEnumItem();
while (itemp && itemp->nextp()) itemp = VN_CAST(itemp->nextp(), EnumItem);
if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
}
if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const");
newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables
@ -1559,8 +1560,8 @@ private:
if (nodep->pinsp() && nodep->name() == "name") {
nodep->v3error("Arguments passed to enum.name method, but it does not take arguments");
} else if (nodep->pinsp() && !(nodep->pinsp()->castArg()->exprp()->castConst()
&& nodep->pinsp()->castArg()->exprp()->castConst()->toUInt()==1
} else if (nodep->pinsp() && !(VN_IS(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)
&& VN_CAST(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)->toUInt()==1
&& !nodep->pinsp()->nextp())) {
nodep->v3error("Unsupported: Arguments passed to enum.next method");
}
@ -1571,8 +1572,8 @@ private:
// a map for when the value is many bits and sparse.
uint64_t msbdim = 0;
{
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()->castEnumItem()) {
AstConst* vconstp = itemp->valuep()->castConst();
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = VN_CAST(itemp->nextp(), EnumItem)) {
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
}
@ -1595,7 +1596,7 @@ private:
nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
}
}
else if (AstUnpackArrayDType* arrayType = fromDtp->castUnpackArrayDType()) {
else if (AstUnpackArrayDType* arrayType = VN_CAST(fromDtp, UnpackArrayDType)) {
enum {
UNKNOWN = 0,
ARRAY_OR,
@ -1666,7 +1667,7 @@ private:
UINFO(9," adtypep "<<vdtypep<<endl);
nodep->dtypep(vdtypep);
// Determine replication count, and replicate initial value as widths need to be individually determined
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
int times = visitPatMemberRep(patp);
for (int i=1; i<times; i++) {
AstNode* newp = patp->cloneTree(false);
@ -1675,7 +1676,7 @@ private:
}
}
// Convert any PatMember with multiple items to multiple PatMembers
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
if (patp->lhssp()->nextp()) {
// Can't just addNext, as would add to end of all members. So detach, add next and reattach
AstNRelinker relinkHandle;
@ -1689,17 +1690,17 @@ private:
}
}
AstPatMember* defaultp = NULL;
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
if (patp->isDefault()) {
if (defaultp) nodep->v3error("Multiple '{ default: } clauses");
defaultp = patp;
patp->unlinkFrBack();
}
}
while (AstConstDType* classp = vdtypep->castConstDType()) {
while (const AstConstDType* classp = VN_CAST(vdtypep, ConstDType)) {
vdtypep = classp->subDTypep()->skipRefp();
}
if (AstNodeClassDType* classp = vdtypep->castNodeClassDType()) {
if (AstNodeClassDType* classp = VN_CAST(vdtypep, NodeClassDType)) {
// Due to "default" and tagged patterns, we need to determine
// which member each AstPatMember corresponds to before we can
// determine the dtypep for that PatMember's value, and then
@ -1708,11 +1709,11 @@ private:
PatMap patmap;
{
AstMemberDType* memp = classp->membersp();
AstPatMember* patp = nodep->itemsp()->castPatMember();
AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember);
for (; memp || patp; ) {
if (patp) {
if (patp->keyp()) {
if (AstText* textp = patp->keyp()->castText()) {
if (AstText* textp = VN_CAST(patp->keyp(), Text)) {
memp = classp->findMember(textp->text());
if (!memp) {
patp->keyp()->v3error("Assignment pattern key '"<<textp->text()<<"' not found as member");
@ -1731,16 +1732,16 @@ private:
} else {
std::pair<PatMap::iterator, bool> ret = patmap.insert(make_pair(memp, patp));
if (!ret.second) {
patp->v3error("Assignment pattern contains duplicate entry: " << patp->keyp()->castText()->text());
patp->v3error("Assignment pattern contains duplicate entry: " << VN_CAST(patp->keyp(), Text)->text());
}
}
// Next
if (memp) memp = memp->nextp()->castMemberDType();
if (patp) patp = patp->nextp()->castPatMember();
if (memp) memp = VN_CAST(memp->nextp(), MemberDType);
if (patp) patp = VN_CAST(patp->nextp(), PatMember);
}
}
AstNode* newp = NULL;
for (AstMemberDType* memp = classp->membersp(); memp; memp=memp->nextp()->castMemberDType()) {
for (AstMemberDType* memp = classp->membersp(); memp; memp=VN_CAST(memp->nextp(), MemberDType)) {
PatMap::iterator it = patmap.find(memp);
AstPatMember* newpatp = NULL;
AstPatMember* patp = NULL;
@ -1750,7 +1751,7 @@ private:
patp = newpatp;
}
else {
if (!classp->castUnionDType()) {
if (!VN_IS(classp, UnionDType)) {
patp->v3error("Assignment pattern missed initializing elements: "<<memp->prettyTypeName());
}
}
@ -1765,9 +1766,9 @@ private:
// Convert to concat for now
AstNode* valuep = patp->lhssp()->unlinkFrBack();
if (valuep->castConst()) {
if (VN_IS(valuep, Const)) {
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
pushDeletep(valuep); VL_DANGLING(valuep);
valuep = newp;
}
@ -1787,8 +1788,8 @@ private:
else nodep->v3error("Assignment pattern with no members");
pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present
}
else if (vdtypep->castNodeArrayDType()) {
AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType();
else if (VN_IS(vdtypep, NodeArrayDType)) {
AstNodeArrayDType* arrayp = VN_CAST(vdtypep, NodeArrayDType);
VNumRange range = arrayp->declRange();
PatVecMap patmap = patVectorMap(nodep, range);
UINFO(9,"ent "<<range.hi()<<" to "<<range.lo()<<endl);
@ -1819,14 +1820,14 @@ private:
userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember*
// Convert to InitArray or constify immediately
AstNode* valuep = patp->lhssp()->unlinkFrBack();
if (valuep->castConst()) {
if (VN_IS(valuep, Const)) {
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
pushDeletep(valuep); VL_DANGLING(valuep);
valuep = newp;
}
}
if (arrayp->castUnpackArrayDType()) {
if (VN_IS(arrayp, UnpackArrayDType)) {
if (!newp) {
AstInitArray* newap = new AstInitArray(nodep->fileline(), arrayp, NULL);
newap->addValuep(valuep);
@ -1834,7 +1835,7 @@ private:
} else {
// We iterate hi()..lo() as that is what packed needs,
// but INITARRAY needs lo() first
newp->castInitArray()->addFrontValuep(valuep);
VN_CAST(newp, InitArray)->addFrontValuep(valuep);
}
} else { // Packed. Convert to concat for now.
if (!newp) newp = valuep;
@ -1855,9 +1856,9 @@ private:
//if (debug()>=9) newp->dumpTree("-apat-out: ");
pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present
}
else if (vdtypep->castBasicDType()
&& vdtypep->castBasicDType()->isRanged()) {
AstBasicDType* bdtypep = vdtypep->castBasicDType();
else if (VN_IS(vdtypep, BasicDType)
&& VN_CAST(vdtypep, BasicDType)->isRanged()) {
AstBasicDType* bdtypep = VN_CAST(vdtypep, BasicDType);
VNumRange range = bdtypep->declRange();
PatVecMap patmap = patVectorMap(nodep, range);
UINFO(9,"ent "<<range.hi()<<" to "<<range.lo()<<endl);
@ -1887,9 +1888,9 @@ private:
userIterate(patp, WidthVP(patp->dtypep(),BOTH).p());
// Convert to InitArray or constify immediately
AstNode* valuep = patp->lhssp()->unlinkFrBack();
if (valuep->castConst()) {
if (VN_IS(valuep, Const)) {
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
pushDeletep(valuep); VL_DANGLING(valuep);
valuep = newp;
}
@ -1932,7 +1933,7 @@ private:
if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1
iterateCheckSizedSelf(nodep,"LHS",nodep->repp(),SELF,BOTH);
V3Const::constifyParamsEdit(nodep->repp()); // repp may change
AstConst* constp = nodep->repp()->castConst();
const AstConst* constp = VN_CAST(nodep->repp(), Const);
if (!constp) { nodep->v3error("Replication value isn't a constant."); times=0; }
else times = constp->toUInt();
if (times==0) { nodep->v3error("Pattern replication value of 0 is not legal."); times=1; }
@ -1962,8 +1963,8 @@ private:
assertAtStatement(nodep);
userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p());
for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) {
nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced
if (!nodep->castGenCase()) userIterateAndNext(itemp->bodysp(), NULL);
nextip = VN_CAST(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced
if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), NULL);
for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) {
nextcp = condp->nextp(); // Prelim may cause the node to get replaced
userIterate(condp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(condp);
@ -1972,7 +1973,7 @@ private:
// Take width as maximum across all items, if any is real whole thing is real
AstNodeDType* subDTypep = nodep->exprp()->dtypep();
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) {
if (condp->dtypep() != subDTypep) {
if (condp->dtypep()->isDouble()) {
@ -1988,7 +1989,7 @@ private:
}
// Apply width
iterateCheck(nodep,"Case expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_LHS);
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) {
nextcp = condp->nextp(); // Final may cause the node to get replaced
iterateCheck(nodep,"Case Item",condp,CONTEXT,FINAL,subDTypep,EXTEND_LHS);
@ -1999,7 +2000,7 @@ private:
assertAtStatement(nodep);
userIterateAndNext(nodep->initsp(), NULL);
iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition.
if (!nodep->castGenFor()) userIterateAndNext(nodep->bodysp(), NULL);
if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->bodysp(), NULL);
userIterateAndNext(nodep->incsp(), NULL);
}
@ -2018,7 +2019,7 @@ private:
virtual void visit(AstNodeIf* nodep) {
assertAtStatement(nodep);
//if (debug()) nodep->dumpTree(cout," IfPre: ");
if (!nodep->castGenIf()) { // for m_paramsOnly
if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly
userIterateAndNext(nodep->ifsp(), NULL);
userIterateAndNext(nodep->elsesp(), NULL);
}
@ -2195,7 +2196,7 @@ private:
assertAtStatement(nodep);
userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p());
userIterateAndNext(nodep->memp(), WidthVP(SELF,BOTH).p());
if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) {
if (!VN_IS(nodep->memp()->dtypep()->skipRefp(), UnpackArrayDType)) {
nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array");
}
userIterateAndNext(nodep->lsbp(), WidthVP(SELF,BOTH).p());
@ -2281,17 +2282,17 @@ private:
// Check if an interface is connected to a non-interface and vice versa
AstNodeDType* modDTypep = nodep->modVarp()->dtypep();
AstNodeDType* exprDTypep = nodep->exprp()->dtypep();
if ((modDTypep->castIfaceRefDType() && !exprDTypep->castIfaceRefDType()) ||
(exprDTypep->castIfaceRefDType() && !modDTypep->castIfaceRefDType())) {
if ((VN_IS(modDTypep, IfaceRefDType) && !VN_IS(exprDTypep, IfaceRefDType)) ||
(VN_IS(exprDTypep, IfaceRefDType) && !VN_IS(modDTypep, IfaceRefDType))) {
nodep->v3error("Illegal "<<nodep->prettyOperatorName()<<","
<<" mismatch between port which is"<<(modDTypep->castIfaceRefDType()?"":" not")<<" an interface,"
<<" and expression which is"<<(exprDTypep->castIfaceRefDType()?"":" not")<<" an interface.");
<<" mismatch between port which is"<<(VN_CAST(modDTypep, IfaceRefDType)?"":" not")<<" an interface,"
<<" and expression which is"<<(VN_CAST(exprDTypep, IfaceRefDType)?"":" not")<<" an interface.");
}
// TODO Simple dtype checking, should be a more general check
AstNodeArrayDType* exprArrayp = exprDTypep->skipRefp()->castUnpackArrayDType();
AstNodeArrayDType* modArrayp = modDTypep->skipRefp()->castUnpackArrayDType();
if (exprArrayp && modArrayp && exprArrayp->subDTypep()->skipRefp()->castIfaceRefDType()
AstNodeArrayDType* exprArrayp = VN_CAST(exprDTypep->skipRefp(), UnpackArrayDType);
AstNodeArrayDType* modArrayp = VN_CAST(modDTypep->skipRefp(), UnpackArrayDType);
if (exprArrayp && modArrayp && VN_IS(exprArrayp->subDTypep()->skipRefp(), IfaceRefDType)
&& exprArrayp->declRange().elements() != modArrayp->declRange().elements()) {
int exprSize = exprArrayp->declRange().elements();
int modSize = modArrayp->declRange().elements();
@ -2315,7 +2316,7 @@ private:
}
virtual void visit(AstCell* nodep) {
if (!m_paramsOnly) {
if (nodep->modp()->castNotFoundModule()) {
if (VN_IS(nodep->modp(), NotFoundModule)) {
// We've resolved parameters and hit a module that we couldn't resolve. It's
// finally time to report it.
// Note only here in V3Width as this is first visitor after V3Dead.
@ -2371,7 +2372,7 @@ private:
m_ftaskp = nodep;
userIterateChildren(nodep, NULL);
if (nodep->fvarp()) {
m_funcp = nodep->castFunc();
m_funcp = VN_CAST(nodep, Func);
if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function");
nodep->dtypeFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep()
}
@ -2404,7 +2405,7 @@ private:
}
virtual void visit(AstFuncRef* nodep) {
visit(nodep->castNodeFTaskRef());
visit(VN_CAST(nodep, NodeFTaskRef));
nodep->dtypeFrom(nodep->taskp());
//if (debug()) nodep->dumpTree(cout," FuncOut: ");
}
@ -2428,17 +2429,17 @@ private:
// Prelim may cause the node to get replaced; we've lost our
// pointer, so need to iterate separately later
if (portp->attrSFormat()
&& (!pinp->castSFormatF() || pinp->nextp())) { // Not already done
&& (!VN_IS(pinp, SFormatF) || pinp->nextp())) { // Not already done
UINFO(4," sformat via metacomment: "<<nodep<<endl);
AstNRelinker handle;
argp->unlinkFrBackWithNext(&handle); // Format + additional args, if any
AstNode* argsp = NULL;
while (AstArg* nextargp = argp->nextp()->castArg()) {
while (AstArg* nextargp = VN_CAST(argp->nextp(), Arg)) {
argsp = AstNode::addNext(argsp, nextargp->exprp()->unlinkFrBackWithNext()); // Expression goes to SFormatF
nextargp->unlinkFrBack()->deleteTree(); // Remove the call's Arg wrapper
}
string format;
if (pinp->castConst()) format = pinp->castConst()->num().toString();
if (VN_IS(pinp, Const)) format = VN_CAST(pinp, Const)->num().toString();
else pinp->v3error("Format to $display-like function must have constant format string");
pushDeletep(argp); VL_DANGLING(argp);
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp);
@ -2450,9 +2451,10 @@ private:
goto reloop; // so exit early; next loop will correct it
}
else if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING
&& !pinp->castCvtPackString()
&& !pinp->castSFormatF() // Already generates a string
&& !(pinp->castVarRef() && pinp->castVarRef()->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) {
&& !VN_IS(pinp, CvtPackString)
&& !VN_IS(pinp, SFormatF) // Already generates a string
&& !(VN_IS(pinp, VarRef)
&& VN_CAST(pinp, VarRef)->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) {
UINFO(4," Add CvtPackString: "<<pinp<<endl);
AstNRelinker handle;
pinp->unlinkFrBack(&handle); // No next, that's the next pin
@ -2807,17 +2809,17 @@ private:
AstNodeDType* subDTypep = expDTypep;
nodep->dtypeFrom(expDTypep);
// ShiftRS converts to ShiftR, but not vice-versa
if (nodep->castShiftRS()) {
if (VN_IS(nodep, ShiftRS)) {
if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { VL_DANGLING(nodep);
nodep = newp; // Process new node instead
}
}
bool warnOn = true;
// No warning if "X = 1'b1<<N"; assume user is doing what they want
if (nodep->lhsp()->isOne() && nodep->backp()->castNodeAssign()) warnOn = false;
if (nodep->lhsp()->isOne() && VN_IS(nodep->backp(), NodeAssign)) warnOn = false;
iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,warnOn);
if (nodep->rhsp()->width()>32) {
AstConst* shiftp = nodep->rhsp()->castConst();
AstConst* shiftp = VN_CAST(nodep->rhsp(), Const);
if (shiftp && shiftp->num().mostSetBitP1() <= 32) {
// If (number)<<96'h1, then make it into (number)<<32'h1
V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num());
@ -2911,10 +2913,10 @@ private:
}
// Some warning suppressions
bool lhsWarn=true; bool rhsWarn = true;
if (nodep->castAdd() || nodep->castSub()) {
if (VN_IS(nodep, Add) || VN_IS(nodep, Sub)) {
if (subDTypep->widthMin() == (nodep->lhsp()->widthMin()+1)) lhsWarn=false; // Warn if user wants extra bit from carry
if (subDTypep->widthMin() == (nodep->rhsp()->widthMin()+1)) rhsWarn=false; // Warn if user wants extra bit from carry
} else if (nodep->castMul() || nodep->castMulS()) {
} else if (VN_IS(nodep, Mul) || VN_IS(nodep, MulS)) {
if (subDTypep->widthMin() >= (nodep->lhsp()->widthMin())) lhsWarn=false;
if (subDTypep->widthMin() >= (nodep->rhsp()->widthMin())) rhsWarn=false;
}
@ -2972,7 +2974,7 @@ private:
// for example $unsigned(a)+$signed(b), the SIGNED(B) will be unsigned dtype out
UINFO(4," widthExtend_(r="<<extendRule<<") old: "<<nodep<<endl);
if (extendRule == EXTEND_OFF) return;
AstConst* constp = nodep->castConst();
AstConst* constp = VN_CAST(nodep, Const);
int expWidth = expDTypep->width();
if (constp && !constp->num().isNegative()) {
// Save later constant propagation work, just right-size it.
@ -3026,7 +3028,7 @@ private:
int expWidth = 1;
int expSigned = false;
UINFO(4," widthReduce_old: "<<nodep<<endl);
AstConst* constp = nodep->castConst();
AstConst* constp = VN_CAST(nodep, Const);
if (constp) {
V3Number num (nodep->fileline(), expWidth);
num.opRedOr(constp->num());
@ -3048,7 +3050,7 @@ private:
bool fixAutoExtend (AstNode*& nodepr, int expWidth) {
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
if (AstConst* constp = nodepr->castConst()) {
if (AstConst* constp = VN_CAST(nodepr, Const)) {
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
// Make it the proper size. Careful of proper extension of 0's/1's
V3Number num (constp->fileline(), expWidth);
@ -3123,8 +3125,8 @@ private:
//if (debug()) nodep->dumpTree(cout,"-checkass: ");
if (stage != FINAL) nodep->v3fatalSrc("Bad width call");
// We iterate and size the RHS based on the result of RHS evaluation
bool lhsStream = (nodep->castNodeAssign()
&& nodep->castNodeAssign()->lhsp()->castNodeStream());
bool lhsStream = (VN_IS(nodep, NodeAssign)
&& VN_IS(VN_CAST(nodep, NodeAssign)->lhsp(), NodeStream));
rhsp = iterateCheck(nodep,side,rhsp,ASSIGN,FINAL,lhsDTypep,lhsStream?EXTEND_OFF:EXTEND_LHS);
//if (debug()) nodep->dumpTree(cout,"-checkout: ");
if (rhsp) {} // cppcheck
@ -3257,15 +3259,15 @@ private:
underp=NULL; // Changes underp
return;
}
if (underp->castConst() && underp->castConst()->num().isFromString()
if (VN_IS(underp, Const) && VN_CAST(underp, Const)->num().isFromString()
&& expWidth > underp->width()
&& (((expWidth - underp->width()) % 8) == 0)) { // At least it's character sized
// reg [31:0] == "foo" we'll consider probably fine.
// Maybe this should be a special warning? Not for now.
warnOn = false;
}
if ((nodep->castAdd() && underp->width()==1 && underp->isOne())
|| (nodep->castSub() && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) {
if ((VN_IS(nodep, Add) && underp->width()==1 && underp->isOne())
|| (VN_IS(nodep, Sub) && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) {
// "foo + 1'b1", or "foo - 1'b1" are very common, people assume they extend correctly
warnOn = false;
}
@ -3284,9 +3286,9 @@ private:
// If we're in an NodeAssign, don't truncate the RHS if the LHS is
// a NodeStream. The streaming operator changes the rules regarding
// which bits to truncate.
AstNodeAssign* assignp = nodep->castNodeAssign();
AstPin* pinp = nodep->castPin();
if (assignp && assignp->lhsp()->castNodeStream()) {
AstNodeAssign* assignp = VN_CAST(nodep, NodeAssign);
AstPin* pinp = VN_CAST(nodep, Pin);
if (assignp && VN_IS(assignp->lhsp(), NodeStream)) {
} else if (pinp && !pinp->modVarp()->isInput()) { // V3Inst::pinReconnectSimple must deal
UINFO(5,"pinInSizeMismatch: "<<pinp);
} else {
@ -3517,15 +3519,15 @@ private:
for (int i = 1; i <= dim; ++i) {
//UINFO(9, " dim at "<<dim<<" "<<dtypep<<endl);
declRange = VNumRange(); // ranged() set false
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
declRange = adtypep->declRange();
if (i<dim) dtypep = adtypep->subDTypep()->skipRefp();
continue;
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
} else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
declRange = adtypep->declRange();
if (adtypep) {} // UNUSED
break; // Sub elements don't look like arrays and can't iterate into
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
} else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
if (adtypep->isRanged()) declRange = adtypep->declRange();
break;
}
@ -3538,14 +3540,14 @@ private:
int bits = 1;
while (dtypep) {
//UINFO(9, " bits at "<<bits<<" "<<dtypep<<endl);
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
bits *= adtypep->declRange().elements();
dtypep = adtypep->subDTypep()->skipRefp();
continue;
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
} else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
bits *= adtypep->width();
break;
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
} else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
bits *= adtypep->width();
break;
}
@ -3660,10 +3662,10 @@ private:
{
AstEnumItem* firstp = nodep->itemsp();
AstEnumItem* prevp = firstp; // Prev must start with last item
while (prevp->nextp()) prevp = prevp->nextp()->castEnumItem();
while (prevp->nextp()) prevp = VN_CAST(prevp->nextp(), EnumItem);
for (AstEnumItem* itemp = firstp; itemp;) {
AstEnumItem* nextp = itemp->nextp()->castEnumItem();
AstConst* vconstp = itemp->valuep()->castConst();
AstEnumItem* nextp = VN_CAST(itemp->nextp(), EnumItem);
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
uint32_t i = vconstp->toUInt();
if (attrType == AstAttrType::ENUM_NAME) {
@ -3692,10 +3694,10 @@ private:
PatVecMap patVectorMap(AstPattern* nodep, const VNumRange& range) {
PatVecMap patmap;
int element = range.left();
for (AstPatMember* patp = nodep->itemsp()->castPatMember();
patp; patp = patp->nextp()->castPatMember()) {
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember);
patp; patp = VN_CAST(patp->nextp(), PatMember)) {
if (patp->keyp()) {
if (AstConst* constp = patp->keyp()->castConst()) {
if (const AstConst* constp = VN_CAST(patp->keyp(), Const)) {
element = constp->toSInt();
} else {
patp->keyp()->v3error("Assignment pattern key not supported/understood: "<<patp->keyp()->prettyTypeName());
@ -3740,7 +3742,7 @@ private:
bool markHasOpenArray(AstNodeFTask* nodep) {
bool hasOpen = false;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) {
if (portp->isDpiOpenArray() || hasOpenArrayIterateDType(portp->dtypep())) {
portp->isDpiOpenArray(true);
hasOpen = true;
@ -3751,7 +3753,7 @@ private:
}
bool hasOpenArrayIterateDType(AstNodeDType* nodep) {
// Return true iff this datatype or child has an openarray
if (nodep->castUnsizedArrayDType()) return true;
if (VN_IS(nodep, UnsizedArrayDType)) return true;
if (nodep->subDTypep()) return hasOpenArrayIterateDType(nodep->subDTypep()->skipRefp());
return false;
}
@ -3767,7 +3769,7 @@ private:
void checkConstantOrReplace(AstNode* nodep, const string& message) {
// See also V3WidthSel::checkConstantOrReplace
// Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us!
if (!nodep->castConst()) {
if (!VN_IS(nodep, Const)) {
nodep->v3error(message);
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
pushDeletep(nodep); VL_DANGLING(nodep);

View File

@ -101,7 +101,7 @@ private:
// Recurse to handle the data type, as may change the size etc of this type
if (!nodep->user1()) nodep->accept(*this);
// Look for duplicate
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
AstBasicDType* newp = nodep->findInsertSameDType(bdtypep);
if (newp != bdtypep && debug()>=9) {
UINFO(9,"dtype replacement "); nodep->dumpSmall(cout);

View File

@ -62,7 +62,7 @@ private:
void checkConstantOrReplace(AstNode* nodep, const string& message) {
// See also V3Width::checkConstantOrReplace
// Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us!
if (!nodep->castConst()) {
if (!VN_IS(nodep, Const)) {
nodep->v3error(message);
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
pushDeletep(nodep); VL_DANGLING(nodep);
@ -83,8 +83,8 @@ private:
UINFO(9," fromData start ddtypep = "<<basefromp<<endl);
VNumRange fromRange; // constructs to isRanged(false)
while (basefromp) {
if (basefromp->castAttrOf()) {
basefromp = basefromp->castAttrOf()->fromp();
if (VN_IS(basefromp, AttrOf)) {
basefromp = VN_CAST(basefromp, AttrOf)->fromp();
continue;
}
break;
@ -93,17 +93,17 @@ private:
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
AstNode* errp = ddtypep;
UINFO(9," fromData.ddtypep = "<<ddtypep<<endl);
if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
if (const AstNodeArrayDType* adtypep = VN_CAST(ddtypep, NodeArrayDType)) {
fromRange = adtypep->declRange();
}
else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) {
else if (const AstNodeClassDType* adtypep = VN_CAST(ddtypep, NodeClassDType)) {
fromRange = adtypep->declRange();
}
else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
if (adtypep->isRanged()) {
if (adtypep->rangep()
&& (!adtypep->rangep()->msbp()->castConst()
|| !adtypep->rangep()->lsbp()->castConst()))
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|| !VN_IS(adtypep->rangep()->lsbp(), Const)))
nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
fromRange = adtypep->declRange();
} else {
@ -123,10 +123,10 @@ private:
// have to deal with signed math and related 32bit sign extension problems
if (rhs == 0) {
return lhsp;
} else if (lhsp->castConst()) {
} else if (VN_IS(lhsp, Const)) {
// Optional vs just making add/sub below, but saves constification some work
V3Number num (lhsp->fileline(), lhsp->width());
num.opSub(lhsp->castConst()->num(), V3Number(lhsp->fileline(), 32, rhs));
num.opSub(VN_CAST(lhsp, Const)->num(), V3Number(lhsp->fileline(), 32, rhs));
num.isSigned(lhsp->isSigned());
AstNode* newp = new AstConst(lhsp->fileline(), num);
return newp;
@ -207,7 +207,7 @@ private:
AstNodeDType* ddtypep = fromdata.m_dtypep;
VNumRange fromRange = fromdata.m_fromRange;
UINFO(6," ddtypep "<<ddtypep<<endl);
if (AstUnpackArrayDType* adtypep = ddtypep->castUnpackArrayDType()) {
if (AstUnpackArrayDType* adtypep = VN_CAST(ddtypep, UnpackArrayDType)) {
// SELBIT(array, index) -> ARRAYSEL(array, index)
AstNode* subp = rhsp;
if (fromRange.lo()!=0 || fromRange.hi()<0) {
@ -219,7 +219,7 @@ private:
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
// SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex)
AstNode* subp = rhsp;
if (fromRange.lo()!=0 || fromRange.hi()<0) {
@ -245,7 +245,7 @@ private:
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castBasicDType()) {
else if (VN_IS(ddtypep, BasicDType)) {
// SELBIT(range, index) -> SEL(array, index, 1)
AstSel* newp = new AstSel (nodep->fileline(),
fromp,
@ -257,7 +257,7 @@ private:
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castNodeClassDType()) { // It's packed, so a bit from the packed struct
else if (VN_IS(ddtypep, NodeClassDType)) { // It's packed, so a bit from the packed struct
// SELBIT(range, index) -> SEL(array, index, 1)
AstSel* newp = new AstSel (nodep->fileline(),
fromp,
@ -292,13 +292,13 @@ private:
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
AstNode* lsbp = nodep->thsp()->unlinkFrBack();
vlsint32_t msb = msbp->castConst()->toSInt();
vlsint32_t lsb = lsbp->castConst()->toSInt();
vlsint32_t msb = VN_CAST(msbp, Const)->toSInt();
vlsint32_t lsb = VN_CAST(lsbp, Const)->toSInt();
vlsint32_t elem = (msb>lsb) ? (msb-lsb+1) : (lsb-msb+1);
FromData fromdata = fromDataForArray(nodep, fromp, false);
AstNodeDType* ddtypep = fromdata.m_dtypep;
VNumRange fromRange = fromdata.m_fromRange;
if (ddtypep->castUnpackArrayDType()) {
if (VN_IS(ddtypep, UnpackArrayDType)) {
// Slice extraction
if (fromRange.elements() == elem
&& fromRange.lo() == lsb) { // Extracting whole of original array
@ -313,7 +313,7 @@ private:
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
// SELEXTRACT(array, msb, lsb) -> SEL(array, lsb*width-of-subindex, width-of-subindex*(msb-lsb))
if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0)
adtypep->v3fatalSrc("Array extraction with width miscomputed "
@ -339,7 +339,7 @@ private:
if (newp->widthMin()!=(int)newp->widthConst()) nodep->v3fatalSrc("Width mismatch");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castBasicDType()) {
else if (VN_IS(ddtypep, BasicDType)) {
if (fromRange.littleEndian()) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
@ -359,7 +359,7 @@ private:
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castNodeClassDType()) {
else if (VN_IS(ddtypep, NodeClassDType)) {
// Classes aren't little endian
if (lsb > msb) {
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
@ -402,24 +402,24 @@ private:
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* widthp = nodep->thsp()->unlinkFrBack();
int width = widthp->castConst()->toSInt();
int width = VN_CAST(widthp, Const)->toSInt();
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<<widthp->prettyName());
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
FromData fromdata = fromDataForArray(nodep, fromp, width!=1);
AstNodeDType* ddtypep = fromdata.m_dtypep;
VNumRange fromRange = fromdata.m_fromRange;
if (ddtypep->castBasicDType()
|| ddtypep->castPackArrayDType()
|| (ddtypep->castNodeClassDType()
&& ddtypep->castNodeClassDType()->packedUnsup())) {
if (VN_IS(ddtypep, BasicDType)
|| VN_IS(ddtypep, PackArrayDType)
|| (VN_IS(ddtypep, NodeClassDType)
&& VN_CAST(ddtypep, NodeClassDType)->packedUnsup())) {
int elwidth = 1;
AstNode* newwidthp = widthp;
if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
elwidth = adtypep->width() / fromRange.elements();
newwidthp = new AstConst (nodep->fileline(),AstConst::Unsized32(), width * elwidth);
}
AstNode* newlsbp = NULL;
if (nodep->castSelPlus()) {
if (VN_IS(nodep, SelPlus)) {
if (fromRange.littleEndian()) {
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
newlsbp = newSubNeg((fromRange.hi()-width+1), rhsp);
@ -427,7 +427,7 @@ private:
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
newlsbp = newSubNeg(rhsp, fromRange.lo());
}
} else if (nodep->castSelMinus()) {
} else if (VN_IS(nodep, SelMinus)) {
if (fromRange.littleEndian()) {
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
newlsbp = newSubNeg(fromRange.hi(), rhsp);

40
src/astgen Executable file → Normal file
View File

@ -237,27 +237,45 @@ sub write_visitor {
sub write_intf {
my $fh = open_file(@_);
print $fh "\n";
print $fh " // These for use by VN_IS macro only\n";
foreach my $type (sort (keys %Classes)) {
next if $type eq "Node"; # Special, just a return (this);
printf $fh " Ast%-16s cast${type}();\n"
,$type."*";
print $fh " static bool privateIs",$type,"(const AstNode* nodep);\n";
}
print $fh "\n";
print $fh " // These for use by VN_CAST macro only\n";
foreach my $type (sort (keys %Classes)) {
print $fh " static Ast",$type,"* privateCast",$type,"(AstNode* nodep);\n";
}
foreach my $type (sort (keys %Classes)) {
print $fh " static const Ast",$type,"* privateConstCast",$type,"(const AstNode* nodep);\n";
}
$fh->close();
}
sub write_impl {
my $fh = open_file(@_);
print $fh "\n";
print $fh " // These for use by VN_IS macro only\n";
foreach my $type (sort (keys %Classes)) {
next if $type eq "Node"; # Special, just a return (this);
# For performance, prefer static_cast where we can
if (children_of($type)) {
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast<Ast${type}*>(this)); }\n"
,$type."*";
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return (bool)(dynamic_cast<const Ast",$type,"*>(nodep)); }\n";
} else {
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (this && this->type() == AstType::at${type}) ? static_cast<Ast${type}*>(this) : NULL; }\n"
,$type."*";
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return nodep && nodep->type() == AstType::at",$type,"; }\n";
}
}
foreach my $type (sort (keys %Classes)) {
print $fh "inline Ast",$type,"* AstNode::privateCast",$type,"(AstNode* nodep) { return dynamic_cast<Ast",$type,"*>(nodep); }\n";
}
foreach my $type (sort (keys %Classes)) {
print $fh "inline const Ast",$type,"* AstNode::privateConstCast",$type,"(const AstNode* nodep) { return dynamic_cast<const Ast",$type,"*>(nodep); }\n";
}
$fh->close();
}
@ -405,12 +423,14 @@ sub tree_line {
next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs
$mif .= " && " if $mif;
my $subnodeif = $subnode;
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.cast([A-Z][A-Za-z0-9]+)$/VN_IS(nodep->$1(),$2)/g;
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g;
$subnodeif = add_nodep($subnodeif);
$mif .= $subnodeif;
}
my $exec_func = treeop_exec_func($self, $to);
while ($exec_func =~ s/([-()a-zA-Z0-9_>]+)->cast([A-Z][A-Za-z0-9]+)\(\)/VN_CAST($1,$2)/) {}
$self->{treeop}{$type} ||= [];
my $n = $#{$self->{treeop}{$type}} + 1;
@ -601,7 +621,7 @@ sub tree_base {
" nodep->lhsp()->iterateAndNext(*this);\n",
@out_for_type_sc);
$self->print(" nodep->rhsp()->iterateAndNext(*this);\n",
" AstNodeTriop *tnp = nodep->castNodeTriop();\n",
" AstNodeTriop *tnp = VN_CAST(nodep, NodeTriop);\n",
" if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n",
@out_for_type,
" }\n") if ($out_for_type[0]);

View File

@ -1073,11 +1073,11 @@ void V3ParseImp::lexToken() {
AstNode* scp = foundp->nodep();
yylval.scp = scp;
UINFO(7," lexToken: Found "<<scp<<endl);
if (scp->castTypedef()) token = yaID__aTYPE;
else if (scp->castTypedefFwd()) token = yaID__aTYPE;
else if (scp->castPackage()) token = yaID__aPACKAGE;
//UNSUP else if (scp->castClass()) token = yaID__aCLASS;
//UNSUP else if (scp->castCoverGroup()) token = yaID__aCOVERGROUP;
if (VN_IS(scp, Typedef)) token = yaID__aTYPE;
else if (VN_IS(scp, TypedefFwd)) token = yaID__aTYPE;
else if (VN_IS(scp, Package)) token = yaID__aPACKAGE;
//UNSUP else if (VN_IS(scp, NodeClass)) token = yaID__aCLASS;
//UNSUP else if (VN_IS(scp, CoverGroup)) token = yaID__aCOVERGROUP;
else token = yaID__ETC;
} else { // Not found
yylval.scp = NULL;

View File

@ -128,7 +128,7 @@ public:
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
} else {
pkgp = symp->nodep()->castPackage();
pkgp = VN_CAST(symp->nodep(), Package);
}
return pkgp;
}
@ -145,12 +145,12 @@ public:
rangearraysp = rangesp; // Already a range; everything is an array
} else {
AstNodeRange* finalp = rangesp;
while (finalp->nextp()) finalp=finalp->nextp()->castNodeRange();
while (finalp->nextp()) finalp = VN_CAST(finalp->nextp(), Range);
if (finalp != rangesp) {
finalp->unlinkFrBack();
rangearraysp = rangesp;
}
if (AstRange* finalRangep = finalp->castRange()) { // not an UnsizedRange
if (AstRange* finalRangep = VN_CAST(finalp, Range)) { // not an UnsizedRange
if (dtypep->implicit()) {
// It's no longer implicit but a real logic type
AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC,
@ -749,7 +749,7 @@ package_import_itemList<nodep>:
package_import_item<nodep>: // ==IEEE: package_import_item
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
{ $$ = new AstPackageImport($<fl>1, $<scp>1->castPackage(), *$3);
{ $$ = new AstPackageImport($<fl>1, VN_CAST($<scp>1, Package), *$3);
SYMP->importItem($<scp>1,*$3); }
;
@ -770,7 +770,7 @@ package_export_itemList<nodep>:
package_export_item<nodep>: // ==IEEE: package_export_item
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
{ $$ = new AstPackageExport($<fl>1, $<scp>1->castPackage(), *$3);
{ $$ = new AstPackageExport($<fl>1, VN_CAST($<scp>1, Package), *$3);
SYMP->exportItem($<scp>1,*$3); }
;
@ -1497,7 +1497,7 @@ variable_dimensionListE<rangep>: // IEEE: variable_dimension + empty
variable_dimensionList<rangep>: // IEEE: variable_dimension + empty
variable_dimension { $$ = $1; }
| variable_dimensionList variable_dimension { $$ = $1->addNext($2)->castNodeRange(); }
| variable_dimensionList variable_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
;
variable_dimension<rangep>: // ==IEEE: variable_dimension
@ -1836,7 +1836,7 @@ conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
AstBegin* lowerBegp = $9->castBegin();
AstBegin* lowerBegp = VN_CAST($9, Begin);
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
AstNode* lowerNoBegp = lowerBegp->stmtsp();
@ -1845,7 +1845,7 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
AstBegin* blkp = new AstBegin($1,lowerBegp->name(),NULL,true);
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
AstNode* initp = $3; AstNode* varp = $3;
if (varp->castVar()) { // Genvar
if (VN_IS(varp, Var)) { // Genvar
initp = varp->nextp();
initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init
blkp->addStmtsp(varp);
@ -2009,7 +2009,7 @@ packed_dimensionListE<rangep>: // IEEE: [{ packed_dimension }]
packed_dimensionList<rangep>: // IEEE: { packed_dimension }
packed_dimension { $$ = $1; }
| packed_dimensionList packed_dimension { $$ = $1->addNext($2)->castNodeRange(); }
| packed_dimensionList packed_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
;
packed_dimension<rangep>: // ==IEEE: packed_dimension
@ -2116,12 +2116,12 @@ cellpinList<pinp>:
cellparamItList<pinp>: // IEEE: list_of_parameter_assignmente
cellparamItemE { $$ = $1; }
| cellparamItList ',' cellparamItemE { $$ = $1->addNextNull($3)->castPin(); }
| cellparamItList ',' cellparamItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
;
cellpinItList<pinp>: // IEEE: list_of_port_connections
cellpinItemE { $$ = $1; }
| cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); }
| cellpinItList ',' cellpinItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
;
cellparamItemE<pinp>: // IEEE: named_parameter_assignment + empty
@ -2194,8 +2194,8 @@ event_control<sentreep>: // ==IEEE: event_control
event_expression<senitemp>: // IEEE: event_expression - split over several
senitem { $$ = $1; }
| event_expression yOR senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); }
| event_expression ',' senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); } /* Verilog 2001 */
| event_expression yOR senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
| event_expression ',' senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); } /* Verilog 2001 */
;
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
@ -2646,7 +2646,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($<fl>1,$3); }
//
| yaD_DPI parenE { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList($$->castTaskRef()); }
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
@ -2691,7 +2691,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2,V3Number($2,"'b0")); } // Unsized 0
//
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList($$->castFuncRef()); }
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); }
//
| yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
| yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
@ -2772,7 +2772,7 @@ exprOrDataType<nodep>: // expr | data_type: combined to prevent conflicts
list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
argsDottedList { $$ = $1; }
| argsExprListE { if ($1->castArg() && $1->castArg()->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
| argsExprListE { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
/*cont*/ else $$ = $1; }
| argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); }
;
@ -3728,7 +3728,7 @@ ps_id_etc: // package_scope + general id
ps_type<dtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
// Even though we looked up the type and have a AstNode* to it,
// we can't fully resolve it because it may have been just a forward definition.
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); $$->castRefDType()->packagep($1); }
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); VN_CAST($$, RefDType)->packagep($1); }
// // Simplify typing - from ps_covergroup_identifier
//UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $<fl>$=$<fl>1; $$=$1+$2; }
;
@ -3748,7 +3748,7 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
yD_UNIT { SYMP->nextId(PARSEP->rootp()); }
/*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($<fl>1); }
| yaID__aPACKAGE { SYMP->nextId($<scp>1); }
/*cont*/ yP_COLONCOLON { $$ = $<scp>1->castPackage(); }
/*cont*/ yP_COLONCOLON { $$ = VN_CAST($<scp>1, Package); }
//UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
;
@ -3848,26 +3848,26 @@ AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int v
AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) {
// Remove any UnsizedRange's from list
for (AstNodeRange* nodep = nrangep, *nextp; nodep; nodep=nextp) {
nextp = nrangep->nextp()->castNodeRange();
if (!nodep->castRange()) {
nextp = VN_CAST(nrangep->nextp(), NodeRange);
if (!VN_IS(nodep, Range)) {
nodep->v3error("Unsupported or syntax error: Unsized range in cell or other declaration");
nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep);
}
}
return nrangep->castRange();
return VN_CAST(nrangep, Range);
}
AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstNodeRange* nrangep, bool isPacked) {
// Split RANGE0-RANGE1-RANGE2 into ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3),RANGE),RANGE)
AstNodeDType* arrayp = basep;
if (nrangep) { // Maybe no range - return unmodified base type
while (nrangep->nextp()) nrangep = nrangep->nextp()->castNodeRange();
while (nrangep->nextp()) nrangep = VN_CAST(nrangep->nextp(), NodeRange);
while (nrangep) {
AstNodeRange* prevp = nrangep->backp()->castNodeRange();
AstNodeRange* prevp = VN_CAST(nrangep->backp(), NodeRange);
if (prevp) nrangep->unlinkFrBack();
AstRange* rangep = nrangep->castRange();
AstRange* rangep = VN_CAST(nrangep, Range);
if (!rangep) {
if (!nrangep->castUnsizedRange()) nrangep->v3fatalSrc("Expected range or unsized range");
if (!VN_IS(nrangep, UnsizedRange)) nrangep->v3fatalSrc("Expected range or unsized range");
arrayp = new AstUnsizedArrayDType(nrangep->fileline(), VFlagChildDType(), arrayp);
} else if (isPacked) {
arrayp = new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
@ -3922,7 +3922,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstNodeR
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY1) {
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 1));
}
if (dtypep->castParseTypeDType()) {
if (VN_IS(dtypep, ParseTypeDType)) {
// Parser needs to know what is a type
AstNode* newp = new AstTypedefFwd(fileline, name);
nodep->addNext(newp);