Internals: Add UASSERT_OBJ macro to replace hand-done ifs. No functional change intended.

This makes it easier to filter out correctly zero code-coverage lines.
This commit is contained in:
Wilson Snyder 2019-07-06 12:57:50 -04:00
parent 7e54ff1b37
commit 8548ecfdac
66 changed files with 626 additions and 653 deletions

View File

@ -66,7 +66,7 @@ private:
// METHODS
void addActive(AstActive* nodep) {
if (!m_scopep) nodep->v3fatalSrc("NULL scope");
UASSERT_OBJ(m_scopep, nodep, "NULL scope");
m_scopep->addActivep(nodep);
}
// VISITORS
@ -314,7 +314,8 @@ private:
&& 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.");
UASSERT_OBJ(!oldsensesp->sensesp()->nextp(), nodep,
"Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
@ -391,11 +392,10 @@ private:
}
virtual void visit(AstSenGate* nodep) {
AstSenItem* subitemp = nodep->sensesp();
if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE
&& subitemp->edgeType() != AstEdgeType::ET_POSEDGE
&& subitemp->edgeType() != AstEdgeType::ET_NEGEDGE) {
nodep->v3fatalSrc("Strange activity type under SenGate");
}
UASSERT_OBJ(subitemp->edgeType() == AstEdgeType::ET_ANYEDGE
|| subitemp->edgeType() == AstEdgeType::ET_POSEDGE
|| subitemp->edgeType() == AstEdgeType::ET_NEGEDGE,
nodep, "Strange activity type under SenGate");
iterateChildren(nodep);
}
virtual void visit(AstSenItem* nodep) {

View File

@ -72,14 +72,13 @@ private:
UINFO(4," ACTIVE "<<nodep<<endl);
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
AstSenTree* sensesp = nodep->sensesp();
if (!sensesp) nodep->v3fatalSrc("NULL");
UASSERT_OBJ(sensesp, nodep, "NULL");
if (sensesp->sensesp()
&& VN_IS(sensesp->sensesp(), SenItem)
&& VN_CAST(sensesp->sensesp(), SenItem)->isNever()) {
// Never executing. Kill it.
if (VL_UNCOVERABLE(sensesp->sensesp()->nextp())) {
nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
}
UASSERT_OBJ(!sensesp->sensesp()->nextp(), nodep,
"Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
@ -101,9 +100,8 @@ private:
// Move the active's contents to the other active
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
if (nodep->sensesStorep()) {
if (VL_UNCOVERABLE(sensesp != nodep->sensesStorep())) {
nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
}
UASSERT_OBJ(sensesp == nodep->sensesStorep(), nodep,
"sensesStore should have been deleted earlier if different");
sensesp->unlinkFrBack();
// There may be other references to same sense tree,
// we'll be removing all references when we get to them,

View File

@ -120,7 +120,7 @@ private:
} else {
// V3Coverage assigned us a bucket to increment.
AstCoverInc* covincp = VN_CAST(snodep->coverincp(), CoverInc);
if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion");
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
covincp->unlinkFrBack();
if (message!="") covincp->declp()->comment(message);
bodysp = covincp;
@ -317,10 +317,11 @@ private:
iterateChildren(nodep);
uint32_t ticks = 1;
if (nodep->ticksp()) {
if (!VN_IS(nodep->ticksp(), Const)) nodep->v3fatalSrc("Expected constant ticks, checked in V3Width");
UASSERT_OBJ(VN_IS(nodep->ticksp(), Const), nodep,
"Expected constant ticks, checked in V3Width");
ticks = VN_CAST(nodep->ticksp(), Const)->toUInt();
}
if (ticks<1) nodep->v3fatalSrc("0 tick should have been checked in V3Width");
UASSERT_OBJ(ticks>=1, nodep, "0 tick should have been checked in V3Width");
AstNode* inp = nodep->exprp()->unlinkFrBack();
AstVar* invarp = NULL;
AstSenTree* sentreep = nodep->sentreep(); sentreep->unlinkFrBack();

View File

@ -248,7 +248,7 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
// Add to m_nextp, returns this
UDEBUGONLY(if (!newp) nodep->v3fatalSrc("Null item passed to addNext"););
UDEBUGONLY(UASSERT_OBJ(newp, nodep, "Null item passed to addNext"););
nodep->debugTreeChange("-addNextThs: ", __LINE__, false);
newp->debugTreeChange("-addNextNew: ", __LINE__, true);
if (!nodep) { // verilog.y and lots of other places assume this
@ -259,7 +259,8 @@ AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
if (oldtailp->m_nextp) {
if (oldtailp->m_headtailp) {
oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end
UDEBUGONLY(if (oldtailp->m_nextp) nodep->v3fatalSrc("Node had next, but headtail says it shouldn't"););
UDEBUGONLY(UASSERT_OBJ(!oldtailp->m_nextp, nodep,
"Node had next, but headtail says it shouldn't"););
} else {
// Though inefficent, we are occasionally passed a addNext in the middle of a list.
while (oldtailp->m_nextp != NULL) oldtailp = oldtailp->m_nextp;
@ -337,9 +338,9 @@ void AstNode::addNextHere(AstNode* newp) {
void AstNode::setOp1p(AstNode* newp) {
UASSERT(newp, "Null item passed to setOp1p");
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
UDEBUGONLY(UASSERT_OBJ(!m_op1p, this, "Adding to non-empty, non-list op1"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op1"););
this->debugTreeChange("-setOp1pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp1pNew: ", __LINE__, true);
m_op1p = newp;
@ -350,9 +351,9 @@ void AstNode::setOp1p(AstNode* newp) {
void AstNode::setOp2p(AstNode* newp) {
UASSERT(newp, "Null item passed to setOp2p");
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
UDEBUGONLY(UASSERT_OBJ(!m_op2p, this, "Adding to non-empty, non-list op2"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op2"););
this->debugTreeChange("-setOp2pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp2pNew: ", __LINE__, true);
m_op2p = newp;
@ -363,9 +364,9 @@ void AstNode::setOp2p(AstNode* newp) {
void AstNode::setOp3p(AstNode* newp) {
UASSERT(newp, "Null item passed to setOp3p");
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
UDEBUGONLY(UASSERT_OBJ(!m_op3p, this, "Adding to non-empty, non-list op3"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op3"););
this->debugTreeChange("-setOp3pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp3pNew: ", __LINE__, true);
m_op3p = newp;
@ -376,9 +377,9 @@ void AstNode::setOp3p(AstNode* newp) {
void AstNode::setOp4p(AstNode* newp) {
UASSERT(newp, "Null item passed to setOp4p");
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
UDEBUGONLY(UASSERT_OBJ(!m_op4p, this, "Adding to non-empty, non-list op4"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op4"););
this->debugTreeChange("-setOp4pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp4pNew: ", __LINE__, true);
m_op4p = newp;
@ -580,9 +581,11 @@ void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set
// Insert the whole old list following the new node's list.
// Thus a unlink without next, followed by relink, gives the same list.
AstNode* newlistlastp = newp->m_headtailp;
if (newlistlastp->m_nextp && newlistlastp!=newp) newp->v3fatalSrc("Headtailp tail isn't at the tail");
UASSERT_OBJ(!(newlistlastp->m_nextp && newlistlastp!=newp), newp,
"Headtailp tail isn't at the tail");
AstNode* oldlistlastp = pointpr->m_headtailp;
if (oldlistlastp->m_nextp && oldlistlastp!=pointpr) newp->v3fatalSrc("Old headtailp tail isn't at the tail");
UASSERT_OBJ(!(oldlistlastp->m_nextp && oldlistlastp!=pointpr), newp,
"Old headtailp tail isn't at the tail");
// Next links
newlistlastp->m_nextp = pointpr;
pointpr->m_backp = newlistlastp;
@ -772,14 +775,15 @@ void AstNode::iterateAndNext(AstNVisitor& v) {
// there's no lower level reason yet though the back must exist.
AstNode* nodep = this;
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
if (VL_UNCOVERABLE(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
UASSERT_OBJ(!(nodep && !nodep->m_backp), nodep,
"iterateAndNext node has no back");
#endif
if (nodep) ASTNODE_PREFETCH(nodep->m_nextp);
while (nodep) { // effectively: if (!this) return; // Callers rely on this
if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp);
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
// Desirable check, but many places where multiple iterations are OK
//if (VL_UNCOVERABLE(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
// UASSERT_OBJ(!niterp->m_iterpp, niterp, "IterateAndNext under iterateAndNext may miss edits");
// Optimization note: Doing PREFETCH_RW on m_iterpp is a net even
// cppcheck-suppress nullPointer
niterp->m_iterpp = &niterp;
@ -856,7 +860,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
else if (this->m_backp->m_op3p == this) nextnodepp = &(this->m_backp->m_op3p);
else if (this->m_backp->m_op4p == this) nextnodepp = &(this->m_backp->m_op4p);
else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp);
if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself");
UASSERT_OBJ(nextnodepp, this, "Node's back doesn't point to forward to node itself");
{
nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
}
@ -934,13 +938,11 @@ V3Hash::V3Hash(const string& name) {
void AstNode::checkTreeIter(AstNode* backp) {
// private: Check a tree and children
if (backp != this->backp()) {
this->v3fatalSrc("Back node inconsistent");
}
UASSERT_OBJ(backp == this->backp(), this, "Back node inconsistent");
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");
UASSERT_OBJ(!(op1p()||op2p()||op3p()||op4p()), this,
"Terminal operation with non-terminals");
}
if (m_op1p) m_op1p->checkTreeIterList(this);
if (m_op2p) m_op2p->checkTreeIterList(this);
@ -955,12 +957,13 @@ void AstNode::checkTreeIterList(AstNode* backp) {
AstNode* tailp = this;
for (AstNode* nodep=headp; nodep; nodep=nodep->nextp()) {
nodep->checkTreeIter(backp);
if (headp!=this && nextp()) this->v3fatalSrc("Headtailp should be null in middle of lists");
UASSERT_OBJ(headp==this || !nextp(), this,
"Headtailp should be null in middle of lists");
tailp = nodep;
backp = nodep;
}
if (headp->m_headtailp != tailp) headp->v3fatalSrc("Tail in headtailp is inconsistent");
if (tailp->m_headtailp != headp) tailp->v3fatalSrc("Head in headtailp is inconsistent");
UASSERT_OBJ(headp->m_headtailp == tailp, headp, "Tail in headtailp is inconsistent");
UASSERT_OBJ(tailp->m_headtailp == headp, tailp, "Head in headtailp is inconsistent");
}
void AstNode::checkTree() {
@ -1096,12 +1099,13 @@ void AstNode::v3errorEnd(std::ostringstream& str) const {
// Data type conversion
void AstNode::dtypeChgSigned(bool flag) {
if (!dtypep()) this->v3fatalSrc("No dtype when changing to (un)signed");
UASSERT_OBJ(dtypep(), this, "No dtype when changing to (un)signed");
dtypeChgWidthSigned(dtypep()->width(), dtypep()->widthMin(),
flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED);
}
void AstNode::dtypeChgWidth(int width, int widthMin) {
if (!dtypep()) this->v3fatalSrc("No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise
UASSERT_OBJ(dtypep(), this,
"No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise
dtypeChgWidthSigned(width, widthMin, dtypep()->numeric());
}

View File

@ -642,28 +642,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
}
bool AstSenTree::hasClocked() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
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");
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
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");
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
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");
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
if (senp->isCombo()) return true;
}
@ -764,12 +764,12 @@ AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
// Special walking tree inserters
void AstNode::addBeforeStmt(AstNode* newp, AstNode*) {
if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt");
UASSERT_OBJ(backp(), newp, "Can't find current statement to addBeforeStmt");
// Look up; virtual call will find where to put it
this->backp()->addBeforeStmt(newp, this);
}
void AstNode::addNextStmt(AstNode* newp, AstNode*) {
if (!backp()) newp->v3fatalSrc("Can't find current statement to addNextStmt");
UASSERT_OBJ(backp(), newp, "Can't find current statement to addNextStmt");
// Look up; virtual call will find where to put it
this->backp()->addNextStmt(newp, this);
}

View File

@ -1941,7 +1941,7 @@ public:
AstBind(FileLine* fl, const string& name, AstNode* cellsp)
: AstNode(fl)
, m_name(name) {
if (!VN_IS(cellsp, Cell)) cellsp->v3fatalSrc("Only cells allowed to be bound");
UASSERT_OBJ(VN_IS(cellsp, Cell), cellsp, "Only cells allowed to be bound");
addNOp1p(cellsp);
}
ASTNODE_NODE_FUNCS(Bind)

View File

@ -141,7 +141,7 @@ private:
// Remap var names and replace lower Begins
iterateAndNextNull(nodep->stmtsp());
if (nodep->genforp()) nodep->v3fatalSrc("GENFORs should have been expanded earlier");
UASSERT_OBJ(!nodep->genforp(), nodep, "GENFORs should have been expanded earlier");
}
m_namedScope = oldScope;
m_unnamedScope = oldUnnamed;

View File

@ -60,10 +60,9 @@ public:
// Called by operator delete on any node - only if VL_LEAK_CHECKS
if (debug()>=9) cout<<"-nodeDel: "<<cvtToHex(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (VL_UNCOVERABLE(iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED))) {
reinterpret_cast<const AstNode*>(nodep)
->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
}
UASSERT_OBJ(!(iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)),
reinterpret_cast<const AstNode*>(nodep),
"Deleting AstNode object that was never tracked or already deleted");
if (iter!=s_nodes.end()) s_nodes.erase(iter);
}
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
@ -74,9 +73,8 @@ public:
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()>=9) cout<<"-nodeNew: "<<cvtToHex(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (VL_UNCOVERABLE(iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED))) {
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
}
UASSERT_OBJ(!(iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED)),
nodep, "Newing AstNode object that is already allocated");
if (iter == s_nodes.end()) {
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
s_nodes.insert(make_pair(nodep, flags));
@ -101,14 +99,12 @@ public:
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
#endif
} else {
if (VL_UNCOVERABLE(!(iter->second & FLAG_ALLOCATED))) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
UASSERT_OBJ(iter->second & FLAG_ALLOCATED, nodep,
"AstNode is in tree, but not allocated");
#endif
}
if (VL_UNCOVERABLE(iter->second & FLAG_IN_TREE)) {
nodep->v3fatalSrc("AstNode is already in tree at another location");
}
UASSERT_OBJ(!(iter->second & FLAG_IN_TREE), nodep,
"AstNode is already in tree at another location");
}
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
if (iter == s_nodes.end()) {
@ -230,36 +226,31 @@ public:
class BrokenCheckVisitor : public AstNVisitor {
private:
void checkWidthMin(const AstNode* nodep) {
if (VL_UNCOVERABLE(nodep->width() != nodep->widthMin()
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH)) {
nodep->v3fatalSrc("Width != WidthMin");
}
UASSERT_OBJ(nodep->width() == nodep->widthMin()
|| v3Global.widthMinUsage() != VWidthMinUsage::MATCHES_WIDTH,
nodep, "Width != WidthMin");
}
void processAndIterate(AstNode* nodep) {
BrokenTable::setUnder(nodep, true);
const char* whyp = nodep->broken();
if (VL_UNCOVERABLE(whyp)) {
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
}
UASSERT_OBJ(!whyp, nodep,
"Broken link in node (or something without maybePointedTo): "<<whyp);
if (nodep->dtypep()) {
if (VL_UNCOVERABLE(!nodep->dtypep()->brokeExists())) {
nodep->v3fatalSrc("Broken link in node->dtypep() to "
<<cvtToHex(nodep->dtypep()));
} else if (VL_UNCOVERABLE(!VN_IS(nodep->dtypep(), NodeDType))) {
nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "
<<cvtToHex(nodep->dtypep()));
}
UASSERT_OBJ(nodep->dtypep()->brokeExists(), nodep,
"Broken link in node->dtypep() to "<<cvtToHex(nodep->dtypep()));
UASSERT_OBJ(VN_IS(nodep->dtypep(), NodeDType), nodep,
"Non-dtype link in node->dtypep() to "<<cvtToHex(nodep->dtypep()));
}
if (v3Global.assertDTypesResolved()) {
if (nodep->hasDType()) {
if (VL_UNCOVERABLE(!nodep->dtypep())) nodep->v3fatalSrc(
"No dtype on node with hasDType(): "<<nodep->prettyTypeName());
UASSERT_OBJ(nodep->dtypep(), nodep,
"No dtype on node with hasDType(): "<<nodep->prettyTypeName());
} else {
if (VL_UNCOVERABLE(nodep->dtypep())) nodep->v3fatalSrc(
"DType on node without hasDType(): "<<nodep->prettyTypeName());
UASSERT_OBJ(!nodep->dtypep(), nodep,
"DType on node without hasDType(): "<<nodep->prettyTypeName());
}
if (VL_UNCOVERABLE(nodep->getChildDTypep())) nodep->v3fatalSrc(
"childDTypep() non-null on node after should have removed");
UASSERT_OBJ(!nodep->getChildDTypep(), nodep,
"childDTypep() non-null on node after should have removed");
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
}
checkWidthMin(nodep);
@ -268,12 +259,11 @@ private:
}
virtual void visit(AstNodeAssign* nodep) {
processAndIterate(nodep);
if (VL_UNCOVERABLE(v3Global.assertDTypesResolved()
&& nodep->brokeLhsMustBeLvalue()
&& VN_IS(nodep->lhsp(), NodeVarRef)
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue())) {
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
}
UASSERT_OBJ(!(v3Global.assertDTypesResolved()
&& nodep->brokeLhsMustBeLvalue()
&& VN_IS(nodep->lhsp(), NodeVarRef)
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue()),
nodep, "Assignment LHS is not an lvalue");
}
virtual void visit(AstNode* nodep) {
processAndIterate(nodep);

View File

@ -171,7 +171,7 @@ private:
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
//if (debug()>=9) icondp->dumpTree(cout, " caseitem: ");
AstConst* iconstp = VN_CAST(icondp, Const);
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
UASSERT_OBJ(iconstp, nodep, "above 'can't parse' should have caught this");
if (neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
} else {

View File

@ -633,9 +633,9 @@ private:
}
virtual void visit(AstNodeVarRef* nodep) {
if (m_scopep) {
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block");
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
AstVarScope* varscp = nodep->varScopep();
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
CdcVarVertex* varvertexp = makeVarVertex(varscp);
UINFO(5," VARREF to "<<varscp<<endl);
// We use weight of one for normal edges,

View File

@ -87,7 +87,7 @@ public:
m_tlChgFuncp->addStmtsp(new AstCReturn(m_scopetopp->fileline(), callp));
} else {
AstCReturn* returnp = VN_CAST(m_tlChgFuncp->stmtsp(), CReturn);
if (!returnp) m_scopetopp->v3fatalSrc("Lost CReturn in top change function");
UASSERT_OBJ(returnp, m_scopetopp, "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 inside
@ -260,8 +260,8 @@ private:
AstNode::user1ClearTree();
// Create the change detection function
AstScope* scopep = nodep->scopep();
if (!scopep) nodep->v3fatalSrc("No scope found on top level,"
" perhaps you have no statements?");
UASSERT_OBJ(scopep, nodep,
"No scope found on top level, perhaps you have no statements?");
m_statep->m_scopetopp = scopep;
// Create a wrapper change detection function that calls each change detection function

View File

@ -78,7 +78,8 @@ private:
} else {
nodep->dtypeChgWidth(width, nodep->widthMin());
AstNodeDType* new_dtypep2 = nodep->dtypep();
if (new_dtypep2 == old_dtypep) nodep->v3fatalSrc("Dtype didn't change when width changed");
UASSERT_OBJ(new_dtypep2 != old_dtypep, nodep,
"Dtype didn't change when width changed");
old_dtypep->user3p(new_dtypep2); // Remember for next time
}
}

View File

@ -557,11 +557,10 @@ class GaterVisitor : public GaterBaseVisitor {
for (V3GraphVertex* vertexp = m_graph.verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
if (GaterVarVertex* vVxp = dynamic_cast<GaterVarVertex*>(vertexp)) {
if (!vVxp->inBeginp()) {
// At this point, any variable not linked is an error
// (It should have at least landed under the Head node)
vVxp->nodep()->v3fatalSrc("Variable became stranded in clk gate detection");
}
// At this point, any variable not linked is an error
// (It should have at least landed under the Head node)
UASSERT_OBJ(vVxp->inBeginp(), vVxp->nodep(),
"Variable became stranded in clk gate detection");
if (!lastVxp || vVxp->sortCmp(lastVxp)) {
// Different sources for this new node
color++;
@ -612,7 +611,7 @@ class GaterVisitor : public GaterBaseVisitor {
// Edges from IFs represent a real IF branch in the equation tree
//UINFO(9," ifver "<<cvtToHex(edgep)<<" cc"<<edgep->dotColor()<<endl);
eqnp = cVxp->nodep()->condp()->cloneTree(true);
if (!eqnp) cVxp->nodep()->v3fatalSrc("null condition");
UASSERT_OBJ(eqnp, cVxp->nodep(), "null condition");
if (cedgep->ifelseFalse()) {
eqnp = new AstNot(eqnp->fileline(), eqnp);
}
@ -646,7 +645,8 @@ class GaterVisitor : public GaterBaseVisitor {
lastExprp = newExprFromGraph(vVxp);
}
// Mark variable to move
if (vVxp->nodep()->user2p()) vVxp->nodep()->v3fatalSrc("One variable got marked under two gaters");
UASSERT_OBJ(!vVxp->nodep()->user2p(), vVxp->nodep(),
"One variable got marked under two gaters");
vVxp->nodep()->user2p(lastExprp);
m_statBits += vVxp->nodep()->width(); // Moving a wide bus counts more!
// There shouldn't be two possibilities we want to
@ -675,7 +675,7 @@ class GaterVisitor : public GaterBaseVisitor {
#else
// Make a SenGate
AstSenItem* oldsenitemsp = VN_CAST(nodep->sensesp()->sensesp(), SenItem);
if (!oldsenitemsp) nodep->v3fatalSrc("SenTree doesn't have any SenItem under it");
UASSERT_OBJ(oldsenitemsp, nodep, "SenTree doesn't have any SenItem under it");
AstSenTree* sensesp = new AstSenTree(nodep->fileline(),
new AstSenGate(nodep->fileline(),

View File

@ -179,7 +179,7 @@ private:
}
AstIf* makeActiveIf(AstSenTree* sensesp) {
AstNode* senEqnp = createSenseEquation(sensesp->sensesp());
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
AstIf* newifp = new AstIf(sensesp->fileline(), senEqnp, NULL, NULL);
return (newifp);
}
@ -193,7 +193,8 @@ private:
UINFO(4," TOPSCOPE "<<nodep<<endl);
m_topScopep = nodep;
m_scopep = nodep->scopep();
if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?");
UASSERT_OBJ(m_scopep, nodep,
"No scope found on top level, perhaps you have no statements?");
//VV***** We reset all user1p()
AstNode::user1ClearTree();
// Make top functions
@ -263,7 +264,7 @@ private:
m_scopep = nodep;
iterateChildren(nodep);
if (AstNode* movep = nodep->finalClksp()) {
if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope");
UASSERT_OBJ(m_topScopep, nodep, "Final clocks under non-top scope");
movep->unlinkFrBackWithNext();
m_evalFuncp->addFinalsp(movep);
}
@ -346,13 +347,14 @@ private:
if (!m_topScopep || !nodep->stmtsp()) {
// Not at the top or empty block...
// Only empty blocks should be leftover on the non-top. Killem.
if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active");
UASSERT_OBJ(!nodep->stmtsp(), nodep, "Non-empty lower active");
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else if (m_mtaskBodyp) {
UINFO(4," TR ACTIVE "<<nodep<<endl);
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
if (nodep->hasClocked()) {
if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity");
UASSERT_OBJ(!nodep->hasInitial(), nodep,
"Initial block should not have clock sensitivity");
if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) {
UINFO(4," sameSenseTree\n");
} else {
@ -377,7 +379,8 @@ private:
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
if (nodep->hasClocked()) {
// Remember the latest sensitivity so we can compare it next time
if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity");
UASSERT_OBJ(!nodep->hasInitial(), nodep,
"Initial block should not have clock sensitivity");
if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) {
UINFO(4," sameSenseTree\n");
} else {

View File

@ -96,7 +96,8 @@ public:
AstCCall* callp = eqit->second;
if (!callp->user3()) { // !already done
UINFO(4, " Called "<<callp<<endl);
if (callp->funcp() != oldfuncp) callp->v3fatalSrc("Call list broken, points to call w/different func");
UASSERT_OBJ(callp->funcp() == oldfuncp, callp,
"Call list broken, points to call w/different func");
if (newfuncp) {
AstCCall* newp = new AstCCall(callp, newfuncp);
// Special new AstCCall form above transfers children of callp to newfuncp
@ -236,7 +237,7 @@ private:
V3Hash hashval = it->first;
AstNode* node1p = it->second;
if (!VN_IS(node1p, CFunc)) continue;
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes");
UASSERT_OBJ(!hashval.isIllegal(), node1p, "Illegal (unhashed) nodes");
for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) {
AstNode* node2p = eqit->second;
if (!(eqit->first == hashval)) break;

View File

@ -589,9 +589,8 @@ private:
void replaceNum(AstNode* oldp, const V3Number& num) {
// Replace oldp node with a constant set to specified value
UASSERT(oldp, "Null old");
if (VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()) {
oldp->v3fatalSrc("Already constant??");
}
UASSERT_OBJ(!(VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()),
oldp, "Already constant??");
AstNode* newp = new AstConst(oldp->fileline(), num);
newp->dtypeFrom(oldp);
if (debug()>5) oldp->dumpTree(cout, " const_old: ");
@ -810,7 +809,8 @@ private:
int rstart = rselp->lsbConst();
int rwidth = rselp->widthConst();
if ((rstart + rwidth) != lstart) nodep->v3fatalSrc("tried to merge two selects which are not adjacent");
UASSERT_OBJ((rstart + rwidth) == lstart, nodep,
"tried to merge two selects which are not adjacent");
AstSel* newselp = new AstSel(lselp->fromp()->fileline(),
rselp->fromp()->cloneTree(false), rstart, lwidth+rwidth);
UINFO(5, "merged two adjacent sel "<<lselp <<" and "<<rselp<< " to one "<<newselp<<endl);
@ -1066,7 +1066,7 @@ private:
int msb2 = lsb2+lc2p->width()-1;
int lsb1 = msb2+1;
int msb1 = lsb1+lc1p->width()-1;
if (msb1!=(conp->width()-1)) nodep->v3fatalSrc("Width calc mismatch");
UASSERT_OBJ(msb1 == (conp->width()-1), nodep, "Width calc mismatch");
// Form ranges
AstSel* sel1p = new AstSel(conp->fileline(), rhsp, lsb1, msb1-lsb1+1);
AstSel* sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2-lsb2+1);
@ -1081,7 +1081,7 @@ private:
newp = AstNode::addNext(newp, asn1ap);
newp = AstNode::addNext(newp, asn2ap);
} else {
if (!m_modp) nodep->v3fatalSrc("Not under module");
UASSERT_OBJ(m_modp, nodep, "Not under module");
// We could create just one temp variable, but we'll get better optimization
// if we make one per term.
string name1 = (string("__Vconcswap")+cvtToStr(m_modp->varNumGetInc()));
@ -1234,7 +1234,7 @@ private:
} else {
// Fetch the result
V3Number* outnump = simvis.fetchNumberNull(nodep);
if (!outnump) nodep->v3fatalSrc("No number returned from simulation");
UASSERT_OBJ(outnump, nodep, "No number returned from simulation");
// Replace it
replaceNum(nodep,*outnump); VL_DANGLING(nodep);
}
@ -1440,7 +1440,7 @@ private:
AstNode* fromp = repp->lhsp();
AstConst* lsbp = VN_CAST(nodep->lsbp(), Const); if (!lsbp) return false;
AstNode* widthp = nodep->widthp(); if (!VN_IS(widthp, Const)) return false;
if (!fromp->width()) nodep->v3fatalSrc("Not widthed");
UASSERT_OBJ(fromp->width(), nodep, "Not widthed");
if ((lsbp->toUInt() / fromp->width())
!= ((lsbp->toUInt()+nodep->width()-1) / fromp->width())) return false;
//
@ -1500,7 +1500,7 @@ private:
void replaceSelIntoBiop(AstSel* nodep) {
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
AstNodeBiop* fromp = VN_CAST(nodep->fromp()->unlinkFrBack(), NodeBiop);
if (!fromp) nodep->v3fatalSrc("Called on non biop");
UASSERT_OBJ(fromp, nodep, "Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
@ -1517,7 +1517,7 @@ private:
void replaceSelIntoUniop(AstSel* nodep) {
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
AstNodeUniop* fromp = VN_CAST(nodep->fromp()->unlinkFrBack(), NodeUniop);
if (!fromp) nodep->v3fatalSrc("Called on non biop");
UASSERT_OBJ(fromp, nodep, "Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
@ -1564,7 +1564,7 @@ private:
}
virtual void visit(AstNodeVarRef* nodep) {
iterateChildren(nodep);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(nodep->varp(), nodep, "Not linked");
bool did = false;
if (m_doV && nodep->varp()->valuep() && !m_attrp) {
//if (debug()) valuep->dumpTree(cout, " visitvaref: ");
@ -1627,7 +1627,7 @@ private:
}
virtual void visit(AstEnumItemRef* nodep) {
iterateChildren(nodep);
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
bool did = false;
if (nodep->itemp()->valuep()) {
//if (debug()) nodep->varp()->valuep()->dumpTree(cout, " visitvaref: ");
@ -1682,7 +1682,7 @@ private:
UINFO(8,"senItem(NOT...) "<<nodep<<" "<<invert<<endl);
if (invert) nodep->edgeType( nodep->edgeType().invert() );
AstNodeVarRef* senvarp = VN_CAST(lastSensp->unlinkFrBack(), NodeVarRef);
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
UASSERT_OBJ(senvarp, sensp, "Non-varref sensitivity variable");
sensp->replaceWith(senvarp);
sensp->deleteTree(); VL_DANGLING(sensp);
} else if (!m_doNConst // Deal with later when doNConst missing
@ -1690,7 +1690,8 @@ private:
|| VN_IS(nodep->sensp(), Const))) {
} else if (nodep->isIllegal()) { // Deal with later
} else {
if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable");
UASSERT_OBJ(!(nodep->hasVar() && !nodep->varrefp()), nodep,
"Null sensitivity variable");
}
}
virtual void visit(AstSenGate* nodep) {

View File

@ -81,7 +81,7 @@ private:
// duplicated), not the covertoggle, but we need to get back to the
// covertoggle which is immediately above, so:
AstCoverToggle* removep = VN_CAST(duporigp->backp(), CoverToggle);
if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
UASSERT_OBJ(removep, nodep, "CoverageJoin duplicate of wrong type");
UINFO(8," Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
UINFO(8," dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);
// The CoverDecl the duplicate pointed to now needs to point to the

View File

@ -120,7 +120,7 @@ private:
AstVarScope* createVarSc(AstVarScope* oldvarscp, const string& name,
int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
UASSERT_OBJ(oldvarscp->scopep(), oldvarscp, "Var unscoped");
AstVar* varp;
AstNodeModule* addmodp = oldvarscp->scopep()->modp();
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
@ -158,7 +158,7 @@ private:
}
void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) {
// Check for MULTIDRIVEN, and if so make new sentree that joins old & new sentree
if (!oldactivep) varrefp->v3fatalSrc("<= old dly assignment not put under sensitivity block");
UASSERT_OBJ(oldactivep, varrefp, "<= old dly assignment not put under sensitivity block");
if (oldactivep->sensesp() != m_activep->sensesp()) {
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
&& !varrefp->varp()->user2()) {
@ -203,10 +203,9 @@ private:
} else {
arrayselp = VN_CAST(lhsp, ArraySel);
}
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) {
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
}
UASSERT_OBJ(arrayselp, nodep, "No arraysel under bitsel?");
UASSERT_OBJ(!VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType), nodep,
"ArraySel with unpacked arrays should have been removed in V3Slice");
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
//
//=== Dimensions: __Vdlyvdim__
@ -217,8 +216,8 @@ private:
dimvalp.push_front(valp);
}
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");
UASSERT_OBJ(varrefp, nodep, "No var underneath arraysels");
UASSERT_OBJ(varrefp->varScopep(), varrefp, "Var didn't get varscoped in V3Scope.cpp");
varrefp->unlinkFrBack();
AstVar* oldvarp = varrefp->varp();
int modVecNum = m_scopeVecMap[varrefp->varScopep()]++;
@ -333,7 +332,8 @@ private:
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
// we can share the IF statement too
postLogicp = VN_CAST(finalp->user4p(), If);
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
UASSERT_OBJ(postLogicp, nodep,
"Delayed assignment misoptimized; prev var found w/o associated IF");
} else {
postLogicp = new AstIf(nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, false),
@ -400,12 +400,12 @@ private:
if (m_inDly && nodep->lvalue()) {
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
markVarUsage(nodep->varScopep(), VU_DLY);
if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block");
UASSERT_OBJ(m_activep, nodep, "<= not under sensitivity block");
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");
UASSERT_OBJ(oldvscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
AstVarScope* dlyvscp = VN_CAST(oldvscp->user1p(), VarScope);
if (dlyvscp) { // Multiple use of delayed variable
AstActive* oldactivep = VN_CAST(dlyvscp->user2p(), Active);

View File

@ -66,7 +66,7 @@ private:
// bitmask instead of widths....)
// See t_func_crc for an example test that requires this
VFlagLogicPacked(), nodep->width());
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
UASSERT_OBJ(m_funcp, nodep, "Deep expression not under a function");
m_funcp->addInitsp(varp);
// Replace node tree with reference to var
AstVarRef* newp = new AstVarRef(nodep->fileline(), varp, false);
@ -134,7 +134,7 @@ private:
// Marking of non-static functions (because they might need "this")
// (Here instead of new vistor after V3Descope just to avoid another visitor)
void needNonStaticFunc(AstNode* nodep) {
if (!m_funcp) nodep->v3fatalSrc("Non-static accessor not under a function");
UASSERT_OBJ(m_funcp, nodep, "Non-static accessor not under a function");
if (m_funcp->isStatic().trueU()) {
UINFO(5,"Mark non-public due to "<<nodep<<endl);
m_funcp->isStatic(false);

View File

@ -182,7 +182,7 @@ private:
AstCFunc* funcp = eachIt->second;
FuncMmap::iterator nextIt2 = eachIt; ++nextIt2;
bool moreOfSame = (nextIt2!=m_modFuncs.end() && nextIt2->first == name);
if (!funcp->scopep()) funcp->v3fatalSrc("Not scoped");
UASSERT_OBJ(funcp->scopep(), funcp, "Not scoped");
UINFO(6," Wrapping "<<name<<" "<<funcp<<endl);
UINFO(6," at "<<newfuncp->argTypes()<<" und "<<funcp->argTypes()<<endl);
@ -255,7 +255,7 @@ private:
virtual void visit(AstNodeVarRef* nodep) {
iterateChildren(nodep);
// Convert the hierch name
if (!m_scopep) nodep->v3fatalSrc("Node not under scope");
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
bool hierThis;
nodep->hiername(descopedName(nodep->varScopep()->scopep(), hierThis/*ref*/,
nodep->varScopep()->varp()));
@ -266,8 +266,8 @@ private:
//UINFO(9," "<<nodep<<endl);
iterateChildren(nodep);
// Convert the hierch name
if (!m_scopep) nodep->v3fatalSrc("Node not under scope");
if (!nodep->funcp()->scopep()) nodep->v3fatalSrc("CFunc not under scope");
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
UASSERT_OBJ(nodep->funcp()->scopep(), nodep, "CFunc not under scope");
bool hierThis;
nodep->hiername(descopedName(nodep->funcp()->scopep(), hierThis/*ref*/));
// Can't do this, as we may have more calls later

View File

@ -89,7 +89,7 @@ public:
puts(nodep->dtypep()->charIQWN());
}
void emitScIQW(AstVar* nodep) {
if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable");
UASSERT_OBJ(nodep->isSc(), nodep, "emitting SystemC operator on non-SC variable");
puts(nodep->isScBigUint() ? "SB"
: nodep->isScUint() ? "SU"
: nodep->isScBv() ? "SW"
@ -632,9 +632,9 @@ public:
}
virtual void visit(AstReplicate* nodep) {
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
if ((static_cast<int>(VN_CAST(nodep->rhsp(), Const)->toUInt())
* nodep->lhsp()->widthMin()) != nodep->widthMin())
nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
UASSERT_OBJ((static_cast<int>(VN_CAST(nodep->rhsp(), Const)->toUInt())
* nodep->lhsp()->widthMin()) == nodep->widthMin(),
nodep, "Replicate non-constant or width miscomputed");
puts("VL_REPLICATE_");
emitIQW(nodep);
puts("OI(");
@ -798,7 +798,7 @@ public:
}
virtual void visit(AstConst* nodep) {
if (nodep->isWide()) {
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Constant w/ no temp");
UASSERT_OBJ(m_wideTempRefp, nodep, "Wide Constant w/ no temp");
emitConstant(nodep, m_wideTempRefp, "");
m_wideTempRefp = NULL; // We used it, barf if set it a second time
} else {
@ -909,8 +909,8 @@ class EmitCImp : EmitCStmts {
else {
AstNode* lhsp = changep->lhsp();
AstNode* rhsp = changep->rhsp();
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?");
UASSERT_OBJ(VN_IS(lhsp, VarRef) || VN_IS(lhsp, ArraySel), changep, "Not ref?");
UASSERT_OBJ(VN_IS(rhsp, VarRef) || VN_IS(rhsp, ArraySel), changep, "Not ref?");
for (int word=0;
word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1);
++word) {
@ -1164,9 +1164,8 @@ class EmitCImp : EmitCStmts {
}
virtual void visit(AstExecGraph* nodep) {
if (nodep != v3Global.rootp()->execGraphp()) {
nodep->v3fatalSrc("ExecGraph should be a singleton!");
}
UASSERT_OBJ(nodep == v3Global.rootp()->execGraphp(), nodep,
"ExecGraph should be a singleton!");
// The location of the AstExecGraph within the containing _eval()
// function is where we want to invoke the graph and wait for it to
// complete. Do that now.
@ -1185,10 +1184,8 @@ class EmitCImp : EmitCStmts {
const ExecMTask* etp = dynamic_cast<const ExecMTask*>(vxp);
if (etp->threadRoot()) execMTasks.push_back(etp);
}
if (execMTasks.size() >
static_cast<unsigned>(v3Global.opt.threads())) {
nodep->v3fatalSrc("More root mtasks than available threads");
}
UASSERT_OBJ(execMTasks.size() <= static_cast<unsigned>(v3Global.opt.threads()),
nodep, "More root mtasks than available threads");
if (!execMTasks.empty()) {
for (uint32_t i = 0; i < execMTasks.size(); ++i) {
@ -1256,7 +1253,7 @@ public:
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
AstBasicDType* basicp = nodep->basicp();
if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
if (nodep->isIO()) {
if (nodep->isSc()) {
m_ctorVarsVec.push_back(nodep);
@ -1417,7 +1414,8 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
case 't': detail = true; detailp = thsp; break;
case 'P':
if (nodep->isWide()) {
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
UASSERT_OBJ(m_wideTempRefp, nodep,
"Wide Op w/ no temp, perhaps missing op in V3EmitC?");
COMMA;
puts(m_wideTempRefp->hiername());
puts(m_wideTempRefp->varp()->name());
@ -1448,8 +1446,8 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
break;
case 'i':
COMMA;
if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); }
else iterateAndNextNull(detailp);
UASSERT_OBJ(detailp, nodep, "emitOperator() references undef node");
iterateAndNextNull(detailp);
needComma = true;
break;
default:
@ -1654,7 +1652,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
case '^': displayArg(nodep,&elistp,isScan, vfmt,'^'); break; // Realtime
case 'v': displayArg(nodep, &elistp, isScan, vfmt, 'v'); break;
case 'm': {
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
UASSERT_OBJ(scopenamep, nodep, "Display with %m but no AstScopeName");
string suffix = scopenamep->scopePrettySymName();
if (suffix=="") emitDispState.pushFormat("%S");
else emitDispState.pushFormat("%N"); // Add a . when needed
@ -1687,7 +1685,7 @@ void EmitCImp::emitVarReset(AstVar* varp) {
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
} else if (varp->isParam()) {
if (!varp->valuep()) varp->v3fatalSrc("No init for a param?");
UASSERT_OBJ(varp->valuep(), varp, "No init for a param?");
// If a simple CONST value we initialize it using an enum
// If an ARRAYINIT we initialize it using an initial block similar to a signal
//puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n");
@ -1705,7 +1703,8 @@ void EmitCImp::emitVarReset(AstVar* varp) {
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");
UASSERT_OBJ(initarp->defaultp() || index==pos, initarp,
"Not enough values in array initalizement");
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", VN_CAST(itemp, Const));
}
} else {
@ -1722,9 +1721,8 @@ void EmitCImp::emitVarReset(AstVar* varp) {
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
int vecnum = vects++;
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
}
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
"Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";");
@ -1780,7 +1778,7 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
void EmitCImp::emitMTaskVertexCtors(bool* firstp) {
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Should have an execGraphp");
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
const V3Graph* depGraphp = execGraphp->depGraphp();
unsigned finalEdgesInCt = 0;
@ -1962,9 +1960,8 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
arrayp;
arrayp = VN_CAST(elementp, UnpackArrayDType)) {
int vecnum = vects++;
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
}
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
"Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
// MSVC++ pre V7 doesn't support 'for (int ...)',
// so declare in sep block
@ -2062,9 +2059,8 @@ void EmitCImp::emitSensitives() {
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
int vecnum = vects++;
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
}
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
"Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum);
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(arrayp->lsb())+";");
@ -2404,7 +2400,7 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
if (modp->isTop() && v3Global.opt.mtasks()) {
// Emit the mtask func prototypes.
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Root should have an execGraphp");
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
const V3Graph* depGraphp = execGraphp->depGraphp();
for (const V3GraphVertex* vxp = depGraphp->verticesBeginp();
vxp; vxp = vxp->verticesNextp()) {
@ -2424,7 +2420,7 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
void EmitCImp::emitMTaskState() {
ofp()->putsPrivate(true);
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Root should have an execGraphp");
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
const V3Graph* depGraphp = execGraphp->depGraphp();
for (const V3GraphVertex* vxp = depGraphp->verticesBeginp();
@ -2566,7 +2562,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
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?");
UASSERT_OBJ(varp->valuep(), nodep, "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

View File

@ -206,7 +206,7 @@ class EmitCSyms : EmitCBaseVisitor {
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettySymName())));
}
if (nodep->dpiExport()) {
if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function");
UASSERT_OBJ(m_funcp, nodep, "ScopeName not under DPI function");
m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(),
ScopeFuncData(nodep, m_funcp, m_modp)));
} else {

View File

@ -403,23 +403,23 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
case 'f': putfs(nodep, ""); break;
case 'k': putbs(""); break;
case 'l': {
if (!lhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
else iterateAndNextNull(lhsp);
UASSERT_OBJ(lhsp, nodep, "emitVerilog() references undef node");
iterateAndNextNull(lhsp);
break;
}
case 'r': {
if (!rhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
else iterateAndNextNull(rhsp);
UASSERT_OBJ(rhsp, nodep, "emitVerilog() references undef node");
iterateAndNextNull(rhsp);
break;
}
case 't': {
if (!thsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
else iterateAndNextNull(thsp);
UASSERT_OBJ(thsp, nodep, "emitVerilog() references undef node");
iterateAndNextNull(thsp);
break;
}
case 'd': {
if (!nodep->dtypep()) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
else iterateAndNextNull(nodep->dtypep());
UASSERT_OBJ(nodep->dtypep(), nodep, "emitVerilog() references undef node");
iterateAndNextNull(nodep->dtypep());
break;
}
default:

View File

@ -310,11 +310,17 @@ inline void v3errorEndFatal(std::ostringstream& sstr) {
# define UDEBUGONLY(stmts) {if (0) {stmts}}
#endif
#define UASSERT(condition,stmsg) { if (VL_UNCOVERABLE(!(condition))) { v3fatalSrc(stmsg); }}
// Assertion without object, generally UOBJASSERT preferred
#define UASSERT(condition,stmsg) \
do { if (VL_UNCOVERABLE(!(condition))) { v3fatalSrc(stmsg); }} while(0)
// Assertion with object
#define UASSERT_OBJ(condition,obj,stmsg) \
do { if (VL_UNCOVERABLE(!(condition))) { (obj)->v3fatalSrc(stmsg); }} while(0)
// For use in V3Ast static functions only
#define UASSERT_STATIC(condition,stmsg) \
{ if (VL_UNCOVERABLE(!(condition))) { \
std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__<<":"<<(stmsg)<<std::endl; abort(); } }
do { if (VL_UNCOVERABLE(!(condition))) { \
std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__ \
<<":"<<(stmsg)<<std::endl; abort(); } } while(0)
// Check self test values for expected value. Safe from side-effects.
// Type argument can be removed when go to C++11 (use auto).
#define UASSERT_SELFTEST(Type,got,exp) \
@ -322,12 +328,14 @@ inline void v3errorEndFatal(std::ostringstream& sstr) {
UASSERT(g==e, "Self-test failed '" #got "==" #exp "'"" got=" \
<<g<<" expected="<<e); } while(0)
#define V3ERROR_NA { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); }
#define V3ERROR_NA \
do { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); } while(0)
/// Declare a convenience debug() routine that may be added to any class in
/// Verilator so that --debugi-<srcfile> will work to control UINFOs in
/// that class:
#define VL_DEBUG_FUNC static int debug() { \
#define VL_DEBUG_FUNC \
static int debug() { \
static int level = -1; \
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); \
return level; \

View File

@ -239,9 +239,8 @@ private:
}
bool expandWide(AstNodeAssign* nodep, AstArraySel* rhsp) {
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
if (VL_UNCOVERABLE(VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType))) {
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
}
UASSERT_OBJ(!VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType), nodep,
"ArraySel with unpacked arrays should have been removed in V3Slice");
for (int w=0; w<nodep->widthWords(); w++) {
addWordAssign(nodep, w, newAstWordSelClone(rhsp, w));
}
@ -324,11 +323,9 @@ private:
newp = new AstCCast(nodep->fileline(), lhsp, nodep);
}
} else { // Long
if (lhsp->isQuad() || lhsp->isWide()) {
nodep->v3fatalSrc("extending larger thing into smaller?");
} else {
lhsp->dtypeFrom(nodep); // Just mark it, else nop
}
UASSERT_OBJ(!(lhsp->isQuad() || lhsp->isWide()), nodep,
"extending larger thing into smaller?");
lhsp->dtypeFrom(nodep); // Just mark it, else nop
}
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
}
@ -349,7 +346,7 @@ private:
if (nodep->user1SetOnce()) return; // Process once
iterateChildren(nodep);
// Remember, Sel's may have non-integer rhs, so need to optimize for that!
if (nodep->widthMin() != nodep->widthConst()) nodep->v3fatalSrc("Width mismatch");
UASSERT_OBJ(nodep->widthMin() == nodep->widthConst(), nodep, "Width mismatch");
if (VN_IS(nodep->backp(), NodeAssign)
&& nodep==VN_CAST(nodep->backp(), NodeAssign)->lhsp()) {
// Sel is an LHS assignment select
@ -468,7 +465,7 @@ private:
}
bool expandWide(AstNodeAssign* nodep, AstSel* rhsp) {
if (nodep->widthMin() != rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
UASSERT_OBJ(nodep->widthMin() == rhsp->widthConst(), nodep, "Width mismatch");
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
int lsb = rhsp->lsbConst();
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
@ -729,7 +726,8 @@ private:
} else {
UINFO(8," REPLICATE "<<nodep<<endl);
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
UASSERT_OBJ(constp, nodep,
"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);
@ -756,7 +754,7 @@ private:
AstNode* lhsp = rhsp->lhsp();
int lhswidth = lhsp->widthMin();
const AstConst* constp = VN_CAST(rhsp->rhsp(), Const);
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
UASSERT_OBJ(constp, rhsp, "Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->toUInt();
for (int w=0; w<rhsp->widthWords(); w++) {
AstNode* newp;

View File

@ -435,9 +435,9 @@ private:
}
virtual void visit(AstNodeVarRef* nodep) {
if (m_scopep) {
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block");
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
AstVarScope* varscp = nodep->varScopep();
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
GateVarVertex* vvertexp = makeVarVertex(varscp);
UINFO(5," VARREF to "<<varscp<<endl);
if (m_inSenItem) vvertexp->setIsClock();
@ -509,10 +509,9 @@ private:
m_inSlow = lastslow;
}
virtual void visit(AstConcat* 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");
}
UASSERT_OBJ(!(VN_IS(nodep->backp(), NodeAssign)
&& VN_CAST(nodep->backp(), NodeAssign)->lhsp()==nodep),
nodep, "Concat on LHS of assignment; V3Const should have deleted it");
iterateChildren(nodep);
}
@ -850,14 +849,14 @@ private:
// It's possible we substitute into something that will be reduced more later,
// however, as we never delete the top Always/initial statement, all should be well.
m_didReplace = true;
if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var");
UASSERT_OBJ(!nodep->lvalue(), nodep,
"Can't replace lvalue assignments with const var");
AstNode* substp = m_replaceTreep->cloneTree(false);
if (VN_IS(nodep, NodeVarRef)
&& VN_IS(substp, NodeVarRef)
&& nodep->same(substp)) {
// Prevent an infinite loop...
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
}
UASSERT_OBJ(!(VN_IS(nodep, NodeVarRef)
&& VN_IS(substp, NodeVarRef)
&& nodep->same(substp)),
// Prevent an infinite loop...
substp, "Replacing node with itself; perhaps circular logic?");
// Which fileline() to use?
// If replacing with logic, an error/warning is likely to want to point to the logic
// IE what we're replacing with.
@ -1044,9 +1043,8 @@ public:
AstNode* lhsp = m_assignp->lhsp();
// Possible todo, handle more complex lhs expressions
if (AstNodeVarRef* lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
if (lhsVarRefp->varScopep() != consumerVarScopep) {
consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign");
}
UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep,
consumerVarScopep, "Consumer doesn't match lhs of assign");
if (AstNodeAssign* dup = m_ghash.hashAndFindDupe(m_assignp, activep, m_ifCondp)) {
return static_cast<AstNodeVarRef*>(dup->lhsp());
}
@ -1081,7 +1079,8 @@ private:
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
V3GraphEdge* edgep = vvertexp->inBeginp();
GateLogicVertex* lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
if (!vvertexp->dedupable()) vvertexp->varScp()->v3fatalSrc("GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
UASSERT_OBJ(vvertexp->dedupable(), vvertexp->varScp(),
"GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
GateOkVisitor okVisitor(lvertexp->nodep(), false, true);
if (okVisitor.isSimple()) {
AstVarScope* dupVarScopep = dupVarRefp->varScopep();

View File

@ -87,7 +87,7 @@ private:
AstNode::user2ClearTree(); // user2p() used on entire tree
AstScope* scopep = nodep->scopep();
if (!scopep) nodep->v3fatalSrc("No scope found on top level");
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
m_scopetopp = scopep;
iterateChildren(nodep);
@ -96,7 +96,7 @@ private:
virtual void visit(AstVarRef* nodep) {
// Consumption/generation of a variable,
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
if (m_activep && !nodep->user3()) {
nodep->user3(true);
if (vscp->isCircular()) {
@ -111,7 +111,7 @@ private:
}
virtual void visit(AstActive* nodep) {
m_activep = nodep;
if (!nodep->sensesp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->sensesp(), nodep, "Unlinked");
iterateChildren(nodep->sensesp()); // iterateAndNext?
m_activep = NULL;
iterateChildren(nodep);
@ -191,7 +191,7 @@ private:
virtual void visit(AstVarRef* nodep) {
// Consumption/generation of a variable,
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
if (m_activep) {
UINFO(8," VarAct "<<nodep<<endl);
vscp->user1(true);
@ -212,7 +212,7 @@ private:
virtual void visit(AstActive* nodep) {
UINFO(8,"ACTIVE "<<nodep<<endl);
m_activep = nodep;
if (!nodep->sensesp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->sensesp(), nodep, "Unlinked");
iterateChildren(nodep->sensesp()); // iterateAndNext?
m_activep = NULL;
iterateChildren(nodep);

View File

@ -579,7 +579,7 @@ double V3Graph::orderDFSIterate(V3GraphVertex* vertexp) {
// Compute fanouts of each node
// If forward edge, don't double count that fanout
if (vertexp->user() == 2) return vertexp->fanout(); // Already processed it
if (vertexp->user() == 1) vertexp->v3fatalSrc("Loop found, backward edges should be dead");
UASSERT_OBJ(vertexp->user() != 1, vertexp, "Loop found, backward edges should be dead");
vertexp->user(1);
double fanout = 0;
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {

View File

@ -40,7 +40,7 @@ DfaVertex* DfaGraph::findStart() {
vertexp; vertexp=vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
if (vvertexp->start()) {
if (startp) vertexp->v3fatalSrc("Multiple start points in NFA graph");
UASSERT_OBJ(!startp, vertexp, "Multiple start points in NFA graph");
startp = vvertexp;
}
} else {
@ -118,9 +118,8 @@ private:
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
hash ^= hashVertex(nfaStatep);
if (debug()) {
if (nfaStatep->user()==m_step) {
nfaStatep->v3fatalSrc("DFA state points to duplicate NFA state.");
}
UASSERT_OBJ(nfaStatep->user() != m_step, nfaStatep,
"DFA state points to duplicate NFA state.");
nfaStatep->user(m_step);
}
}

View File

@ -94,9 +94,8 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
GraphPCNode* ourUserp = static_cast<GraphPCNode*>(vertexp->userp());
if (checkOnly) {
if (VL_UNCOVERABLE(ourUserp->m_cp[way] != critPathCost)) {
vertexp->v3fatalSrc("Validation of critical paths failed");
}
UASSERT_OBJ(ourUserp->m_cp[way] == critPathCost,
vertexp, "Validation of critical paths failed");
} else {
ourUserp->m_cp[way] = critPathCost;
}

View File

@ -60,9 +60,7 @@ private:
// Decrement blocking edges count, return true if the vertex is
// newly unblocked
bool unblock() {
if (VL_UNCOVERABLE(m_numBlockingEdges <= 0)) {
vertexp()->v3fatalSrc("Underflow of blocking edges");
}
UASSERT_OBJ(m_numBlockingEdges > 0, vertexp(), "Underflow of blocking edges");
m_numBlockingEdges--;
return (m_numBlockingEdges == 0);
}
@ -210,9 +208,8 @@ private:
typename WaitingVertices::iterator it =
m_waitingVertices.find(toVertexp);
if (VL_UNCOVERABLE(it == m_waitingVertices.end())) {
toVertexp->v3fatalSrc("Found edge into vertex not in waiting list.");
}
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
"Found edge into vertex not in waiting list.");
if (it->second.unblock()) {
m_readyVertices.insert(it->second);
m_waitingVertices.erase(it);
@ -225,9 +222,8 @@ private:
typename WaitingVertices::iterator it =
m_waitingVertices.find(fromVertexp);
if (VL_UNCOVERABLE(it == m_waitingVertices.end())) {
fromVertexp->v3fatalSrc("Found edge into vertex not in waiting list.");
}
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,
"Found edge into vertex not in waiting list.");
if (it->second.unblock()) {
m_readyVertices.insert(it->second);
m_waitingVertices.erase(it);

View File

@ -59,16 +59,15 @@ private:
void nodeHashIterate(AstNode* nodep) {
V3Hash thisHash;
if (!m_cacheInUser4 || !nodep->user4()) {
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)");
}
UASSERT_OBJ(!(VN_IS(nodep->backp(), CFunc)
&& !(VN_IS(nodep, NodeStmt) || VN_IS(nodep, CFunc))), nodep,
"Node "<<nodep->prettyTypeName()
<<" in statement position but not marked stmt (node under function)");
V3Hash oldHash = m_lowerHash;
{
m_lowerHash = nodep->sameHash();
if (m_lowerHash.isIllegal()) {
nodep->v3fatalSrc("sameHash function undefined (returns 0) for node under CFunc.");
}
UASSERT_OBJ(!m_lowerHash.isIllegal(), nodep,
"sameHash function undefined (returns 0) for node under CFunc.");
// For identical nodes, the type should be the same thus
// dtypep should be the same too
m_lowerHash = V3Hash(m_lowerHash, V3Hash(nodep->type()<<6,
@ -132,8 +131,8 @@ void V3Hashed::hash(AstNode* nodep) {
}
bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) {
if (!node1p->user4p()) node1p->v3fatalSrc("Called isIdentical on non-hashed nodes");
if (!node2p->user4p()) node2p->v3fatalSrc("Called isIdentical on non-hashed nodes");
UASSERT_OBJ(node1p->user4p(), node1p, "Called isIdentical on non-hashed nodes");
UASSERT_OBJ(node2p->user4p(), node2p, "Called isIdentical on non-hashed nodes");
return (node1p->user4p() == node2p->user4p() // Same hash
&& node1p->sameTree(node2p));
}
@ -141,7 +140,7 @@ bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) {
void V3Hashed::erase(iterator it) {
AstNode* nodep = iteratorNodep(it);
UINFO(8," erase "<<nodep<<endl);
if (!nodep->user4p()) nodep->v3fatalSrc("Called removeNode on non-hashed node");
UASSERT_OBJ(nodep->user4p(), nodep, "Called removeNode on non-hashed node");
m_hashMmap.erase(it);
nodep->user4p(NULL); // So we don't allow removeNode again
}
@ -196,7 +195,7 @@ void V3Hashed::dumpFile(const string& filename, bool tree) {
V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) {
UINFO(8," findD "<<nodep<<endl);
if (!nodep->user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node");
UASSERT_OBJ(nodep->user4p(), nodep, "Called findDuplicate on non-hashed node");
std::pair<HashMmap::iterator,HashMmap::iterator> eqrange = mmap().equal_range(nodeHash(nodep));
for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) {
AstNode* node2p = eqit->second;
@ -209,7 +208,7 @@ V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) {
V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp) {
UINFO(8," findD "<<nodep<<endl);
if (!nodep->user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node");
UASSERT_OBJ(nodep->user4p(), nodep, "Called findDuplicate on non-hashed node");
std::pair<HashMmap::iterator,HashMmap::iterator> eqrange
= mmap().equal_range(nodeHash(nodep));
for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) {

View File

@ -306,9 +306,8 @@ private:
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");
}
UASSERT_OBJ(exprconstp || exprvarrefp, nodep,
"Unknown interconnect type; pinReconnectSimple should have cleared up");
if (exprconstp) {
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
@ -318,7 +317,7 @@ private:
// the logic changes up and down; if we aliased, we might
// remove the change detection on the output variable.
UINFO(9,"public pin assign: "<<exprvarrefp<<endl);
if (nodep->isNonOutput()) nodep->v3fatalSrc("Outputs only - inputs use AssignAlias");
UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias");
m_modp->addStmtp(
new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), true),
@ -555,12 +554,11 @@ private:
// delete it in later optimizations.
AstVar* pinOldVarp = pinp->modVarp();
AstVar* pinNewVarp = pinOldVarp->clonep();
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
UASSERT_OBJ(pinNewVarp, pinOldVarp, "Cloning failed");
AstNode* connectRefp = pinp->exprp();
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
}
UASSERT_OBJ(VN_IS(connectRefp, Const) || VN_IS(connectRefp, VarRef), pinp,
"Unknown interconnect type; pinReconnectSimple should have cleared up");
V3Inst::checkOutputShort(pinp);
// Propagate any attributes across the interconnect

View File

@ -75,9 +75,8 @@ private:
V3Inst::pinReconnectSimple(nodep, m_cellp, false);
// Make an ASSIGNW (expr, pin)
AstNode* exprp = nodep->exprp()->cloneTree(false);
if (exprp->width() != nodep->modVarp()->width()) {
nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple");
}
UASSERT_OBJ(exprp->width() == nodep->modVarp()->width(), nodep,
"Width mismatch, should have been handled in pinReconnectSimple");
if (nodep->modVarp()->isInoutish()) {
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
} else if (nodep->modVarp()->isWritable()) {
@ -104,7 +103,8 @@ private:
nodep->modVarp(), m_cellp->name(), false);
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");
UASSERT_OBJ(refp || xrefp, exprp,
"Interfaces: Pin is not connected to a VarRef or VarXRef");
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
m_cellp->addNextHere(assp);
} else {
@ -249,7 +249,7 @@ private:
virtual void visit(AstCell* nodep) {
UINFO(4," CELL "<<nodep<<endl);
// Find submodule vars
if (!nodep->modp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->modp(), nodep, "Unlinked");
m_deModVars.main(nodep->modp());
//
if (nodep->rangep()) {

View File

@ -100,10 +100,9 @@ private:
// (which at the V3Order stage represent verilog tasks, not to
// the CFuncs that V3Order will generate.) So don't check for
// collisions in CFuncs.
if (nodep->user5p()) {
nodep->v3fatalSrc("Node originally inserted below logic vertex "
<<static_cast<AstNode*>(nodep->user5p()));
}
UASSERT_OBJ(!nodep->user5p(), nodep,
"Node originally inserted below logic vertex "
<<static_cast<AstNode*>(nodep->user5p()));
nodep->user5p(const_cast<void*>(reinterpret_cast<const void*>(m_startNodep)));
}
@ -235,25 +234,20 @@ private:
// are no actives-under-actives. In any case, check that we're at
// root:
markCost(nodep);
if (nodep != m_startNodep) {
nodep->v3fatalSrc("Multiple actives, or not start node");
}
UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node");
}
virtual void visit(AstCCall* nodep) {
VisitBase vb(this, nodep);
iterateChildren(nodep);
m_tracingCall = true;
iterate(nodep->funcp());
if (m_tracingCall) {
nodep->v3fatalSrc("visit(AstCFunc) should have cleared m_tracingCall.");
}
UASSERT_OBJ(!m_tracingCall, nodep, "visit(AstCFunc) should have cleared m_tracingCall.");
}
virtual void visit(AstCFunc* nodep) {
// Don't count a CFunc other than by tracing a call or counting it
// from the root
if (!m_tracingCall && (nodep != m_startNodep)) {
nodep->v3fatalSrc("AstCFunc not under AstCCall, or not start node");
}
UASSERT_OBJ(m_tracingCall || nodep == m_startNodep, nodep,
"AstCFunc not under AstCCall, or not start node");
m_tracingCall = false;
bool saved_inCFunc = m_inCFunc;
m_inCFunc = true;
@ -287,7 +281,7 @@ public:
InstrCountDumpVisitor(AstNode* nodep, std::ostream* osp)
: m_osp(osp), m_depth(0) {
// No check for NULL output, so...
if (!osp) nodep->v3fatalSrc("Don't call if not dumping");
UASSERT_OBJ(osp, nodep, "Don't call if not dumping");
if (nodep) iterate(nodep);
}
virtual ~InstrCountDumpVisitor() {}

View File

@ -299,10 +299,10 @@ private:
virtual void visit(AstVarRef* nodep) {
// Consumption/generation of a variable,
// it's used so can't elim assignment before this use.
if (!nodep->varScopep()) nodep->v3fatalSrc("NULL");
UASSERT_OBJ(nodep->varScopep(), nodep, "NULL");
//
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
if (nodep->lvalue()) {
m_sideEffect = true; // $sscanf etc may have RHS vars that are lvalues
m_lifep->complexAssign(vscp);
@ -324,7 +324,7 @@ private:
// Has to be direct assignment without any EXTRACTing.
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");
UASSERT_OBJ(vscp, nodep, "Scope lost on variable");
m_lifep->simpleAssign(vscp, nodep);
} else {
iterateAndNextNull(nodep->lhsp());

View File

@ -60,7 +60,7 @@ private:
// VISITORS
virtual void visit(AstVarRef* nodep) {
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
if (AstVarScope* newvscp = reinterpret_cast<AstVarScope*>(vscp->user4p())) {
UINFO(9, " Replace "<<nodep<<" to "<<newvscp<<endl);
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
@ -267,14 +267,12 @@ private:
iterateChildren(nodep);
if (v3Global.opt.mtasks()) {
if (!m_mtasksGraphp) {
nodep->v3fatalSrc("Should have initted m_mtasksGraphp by now");
}
UASSERT_OBJ(m_mtasksGraphp, nodep,
"Should have initted m_mtasksGraphp by now");
m_checker.reset(new GraphPathChecker(m_mtasksGraphp));
} else {
if (m_mtasksGraphp) {
nodep->v3fatalSrc("Did not expect any m_mtasksGraphp in serial mode");
}
UASSERT_OBJ(!m_mtasksGraphp, nodep,
"Did not expect any m_mtasksGraphp in serial mode");
}
// Find all assignposts. Determine which ones can be
@ -289,7 +287,7 @@ private:
virtual void visit(AstVarRef* nodep) {
// Consumption/generation of a variable,
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
LifeLocation loc(m_execMTaskp, ++m_sequence);
if (nodep->lvalue()) {
@ -311,9 +309,8 @@ private:
if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
// rhsp is the dly var
AstVarScope* dlyVarp = rhsp->varScopep();
if (m_assignposts.find(dlyVarp) != m_assignposts.end()) {
nodep->v3fatalSrc("LifePostLocation attempted duplicate dlyvar map addition");
}
UASSERT_OBJ(m_assignposts.find(dlyVarp) == m_assignposts.end(), nodep,
"LifePostLocation attempted duplicate dlyvar map addition");
LifeLocation loc(m_execMTaskp, ++m_sequence);
m_assignposts[dlyVarp] = LifePostLocation(loc, nodep);
}

View File

@ -250,7 +250,7 @@ private:
virtual void visit(AstPackageImport* nodep) {
// Package Import: We need to do the package before the use of a package
iterateChildren(nodep);
if (!nodep->packagep()) nodep->v3fatalSrc("Unlinked package"); // Parser should set packagep
UASSERT_OBJ(nodep->packagep(), nodep, "Unlinked package"); // Parser should set packagep
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(nodep->packagep()), 1, false);
}

View File

@ -248,7 +248,7 @@ public:
symp->fallbackp(NULL);
rootEntp()->insert("$unit ", symp); // Space so can never name conflict with user code
//
if (m_dunitEntp) nodep->v3fatalSrc("Call insertDUnit only once");
UASSERT_OBJ(!m_dunitEntp, nodep, "Call insertDUnit only once");
m_dunitEntp = symp;
}
VSymEnt* insertTopCell(AstNodeModule* nodep, const string& scopename) {
@ -265,7 +265,7 @@ public:
}
VSymEnt* insertCell(VSymEnt* abovep, VSymEnt* modSymp,
AstCell* nodep, const string& scopename) {
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTcel se"<<cvtToHex(symp)<<" "<<scopename
<<" above=se"<<cvtToHex(abovep)
@ -289,7 +289,7 @@ public:
AstCellInline* nodep, const string& basename) {
// A fake point in the hierarchy, corresponding to an inlined module
// This refrences to another Sym, and eventually resolves to a module with a prefix
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTinl se"<<cvtToHex(symp)
<<" "<<basename<<" above=se"<<cvtToHex(abovep)
@ -312,7 +312,7 @@ public:
// After we remove begins these will go away
// Note we fallback to the symbol table of the parent, as we want to find variables there
// However, cells walk the graph, so cells will appear under the begin/ftask itself
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTblk se"<<cvtToHex(symp)
<<" above=se"<<cvtToHex(abovep)<<" node="<<nodep<<endl);
@ -329,7 +329,7 @@ public:
}
VSymEnt* insertSym(VSymEnt* abovep, const string& name,
AstNode* nodep, AstPackage* packagep) {
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTsym se"<<cvtToHex(symp)<<" name='"<<name
<<"' above=se"<<cvtToHex(abovep)<<" node="<<nodep<<endl);
@ -350,14 +350,13 @@ public:
// Don't use this in ResolveVisitor, as we need to pick up the proper
// reference under each SCOPE
VSymEnt* symp = nodep->user1u().toSymEnt();
if (!symp) nodep->v3fatalSrc("Module/etc never assigned a symbol entry?");
UASSERT_OBJ(symp, nodep, "Module/etc never assigned a symbol entry?");
return symp;
}
VSymEnt* getScopeSym(AstScope* nodep) {
NameScopeSymMap::iterator it = m_nameScopeSymMap.find(nodep->name());
if (it == m_nameScopeSymMap.end()) {
nodep->v3fatalSrc("Scope never assigned a symbol entry?");
}
UASSERT_OBJ(it != m_nameScopeSymMap.end(), nodep,
"Scope never assigned a symbol entry?");
return it->second;
}
void implicitOkAdd(AstNodeModule* nodep, const string& varname) {
@ -401,7 +400,7 @@ public:
AstVar* varp = varSymp ? VN_CAST(varSymp->nodep(), Var) : NULL;
UINFO(9, " insAllIface se"<<cvtToHex(varSymp)<<" "<<varp<<endl);
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!");
if (!ifacerefp->ifaceViaCellp()) {
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
ifacerefp->v3error("Cannot find file containing interface: "
@ -444,10 +443,9 @@ public:
// a child cell connecting to that interface
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
UINFO(9," insertScopeAlias se"<<cvtToHex(lhsp)<<" se"<<cvtToHex(rhsp)<<endl);
if (VN_IS(rhsp->nodep(), Cell)
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)) {
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
}
UASSERT_OBJ(!(VN_IS(rhsp->nodep(), Cell)
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)),
rhsp->nodep(), "Got a non-IFACE alias RHS");
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
}
void computeScopeAliases() {
@ -714,7 +712,7 @@ class LinkDotFindVisitor : public AstNVisitor {
<<AstNode::prettyName(nodep->origName()));
} else if (doit) {
UINFO(4," Link Module: "<<nodep<<endl);
if (nodep->dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?");
UASSERT_OBJ(!nodep->dead(), nodep, "Module in cell tree mislabeled as dead?");
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
m_packagep = VN_CAST(nodep, Package);
if (standalonePkg) {
@ -757,7 +755,8 @@ class LinkDotFindVisitor : public AstNVisitor {
m_packagep = NULL;
}
virtual void visit(AstScope* nodep) {
if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope");
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
"Scopes should only exist right after V3Scope");
// Ignored. Processed in next step
}
virtual void visit(AstCell* nodep) {
@ -782,10 +781,9 @@ class LinkDotFindVisitor : public AstNVisitor {
string baddot;
VSymEnt* okSymp;
aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp);
if (!aboveSymp) {
nodep->v3fatalSrc("Can't find cell insertion point at '"
<<baddot<<"' in: "<<nodep->prettyName());
}
UASSERT_OBJ(aboveSymp, nodep,
"Can't find cell insertion point at '"
<<baddot<<"' in: "<<nodep->prettyName());
}
{
m_scope = m_scope+"."+nodep->name();
@ -814,10 +812,9 @@ class LinkDotFindVisitor : public AstNVisitor {
string baddot;
VSymEnt* okSymp;
aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp);
if (!aboveSymp) {
nodep->v3fatalSrc("Can't find cellinline insertion point at '"
<<baddot<<"' in: "<<nodep->prettyName());
}
UASSERT_OBJ(aboveSymp, nodep,
"Can't find cellinline insertion point at '"
<<baddot<<"' in: "<<nodep->prettyName());
m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident);
} else { // No __DOT__, just directly underneath
m_statep->insertInline(aboveSymp, m_modSymp, nodep, nodep->name());
@ -882,7 +879,7 @@ class LinkDotFindVisitor : public AstNVisitor {
virtual void visit(AstNodeFTask* nodep) {
// NodeTask: Remember its name for later resolution
UINFO(5," "<<nodep<<endl);
if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Function/Task not under module?");
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Function/Task not under module?");
// Remember the existing symbol table scope
VSymEnt* oldCurSymp = m_curSymp;
{
@ -917,7 +914,7 @@ class LinkDotFindVisitor : public AstNVisitor {
}
virtual void visit(AstVar* nodep) {
// Var: Remember its name for later resolution
if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Var not under module?");
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
iterateChildren(nodep);
if (!m_statep->forScopeCreation()) {
// Find under either a task or the module's vars
@ -965,7 +962,8 @@ class LinkDotFindVisitor : public AstNVisitor {
// Then have "input foo" and "real foo" so the
// dtype comes from the other side.
AstNodeDType* newdtypep = nodep->subDTypep();
if (!newdtypep || !nodep->childDTypep()) findvarp->v3fatalSrc("No child type?");
UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp,
"No child type?");
bdtypep->unlinkFrBack()->deleteTree();
newdtypep->unlinkFrBack();
findvarp->childDTypep(newdtypep);
@ -1027,18 +1025,18 @@ class LinkDotFindVisitor : public AstNVisitor {
}
virtual void visit(AstTypedef* nodep) {
// Remember its name for later resolution
if (!m_curSymp) nodep->v3fatalSrc("Typedef not under module?");
UASSERT_OBJ(m_curSymp, nodep, "Typedef not under module?");
iterateChildren(nodep);
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
}
virtual void visit(AstParamTypeDType* nodep) {
if (!m_curSymp) nodep->v3fatalSrc("Parameter type not under module?");
UASSERT_OBJ(m_curSymp, nodep, "Parameter type not under module?");
iterateChildren(nodep);
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
}
virtual void visit(AstCFunc* nodep) {
// For dotted resolution, ignore all AstVars under functions, otherwise shouldn't exist
if (m_statep->forScopeCreation()) nodep->v3fatalSrc("No CFuncs expected in tree yet");
UASSERT_OBJ(!m_statep->forScopeCreation(), nodep, "No CFuncs expected in tree yet");
}
virtual void visit(AstEnumItem* nodep) {
// EnumItem: Remember its name for later resolution
@ -1186,7 +1184,8 @@ private:
UINFO(5," "<<nodep<<endl);
if (nodep->dead() || !nodep->user4()) {
UINFO(4,"Mark dead module "<<nodep<<endl);
if (!m_statep->forPrearray()) nodep->v3fatalSrc("Dead module persisted past where should have removed");
UASSERT_OBJ(m_statep->forPrearray(), nodep,
"Dead module persisted past where should have removed");
// Don't remove now, because we may have a tree of
// parameterized modules with VARXREFs into the deleted module
// region. V3Dead should cleanup.
@ -1266,7 +1265,7 @@ private:
virtual void visit(AstAssignAlias* nodep) {
// 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");
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
pinImplicitExprRecurse(forrefp);
}
@ -1317,7 +1316,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
}
virtual void visit(AstScope* nodep) {
UINFO(8," SCOPE "<<nodep<<endl);
if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope");
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
"Scopes should only exist right after V3Scope");
// Using the CELL names, we created all hierarchy. We now need to match this Scope
// up with the hierarchy created by the CELL names.
m_modSymp = m_statep->getScopeSym(nodep);
@ -1335,20 +1335,21 @@ class LinkDotScopeVisitor : public AstNVisitor {
// Find the interface cell the var references
AstIfaceRefDType* dtypep
= LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
UASSERT_OBJ(dtypep, nodep, "Non AstIfaceRefDType on isIfaceRef() var");
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
string ifcellname = dtypep->cellName();
string baddot; VSymEnt* okSymp;
VSymEnt* cellSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp);
if (!cellSymp) nodep->v3fatalSrc("No symbol for interface cell: "
<<nodep->prettyName(ifcellname));
UASSERT_OBJ(cellSymp, nodep,
"No symbol for interface cell: "<<nodep->prettyName(ifcellname));
UINFO(5, " Found interface cell: se"<<cvtToHex(cellSymp)
<<" "<<cellSymp->nodep()<<endl);
if (dtypep->modportName()!="") {
VSymEnt* mpSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp);
if (!mpSymp) { nodep->v3fatalSrc("No symbol for interface modport: "
<<nodep->prettyName(dtypep->modportName())); }
else cellSymp = mpSymp;
UASSERT_OBJ(mpSymp, nodep,
"No symbol for interface modport: "
<<nodep->prettyName(dtypep->modportName()));
cellSymp = mpSymp;
UINFO(5, " Found modport cell: se"
<<cvtToHex(cellSymp)<<" "<<mpSymp->nodep()<<endl);
}
@ -1370,7 +1371,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
if (debug()>=9) nodep->dumpTree(cout, "-\t\t\t\talias: ");
AstVarScope* fromVscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
AstVarScope* toVscp = VN_CAST(nodep->rhsp(), VarRef)->varScopep();
if (!fromVscp || !toVscp) nodep->v3fatalSrc("Bad alias scopes");
UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes");
fromVscp->user2p(toVscp);
iterateChildren(nodep);
}
@ -1381,7 +1382,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
{
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");
UASSERT_OBJ(refp || xrefp, nodep,
"Unsupported: Non Var(X)Ref attached to interface pin");
string inl = ((xrefp && xrefp->inlinedDots().size())
? (xrefp->inlinedDots() + "__DOT__") : "");
VSymEnt* symp = NULL;
@ -1397,7 +1399,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
}
if (!symp) UINFO(9,"No symbol for interface alias rhs ("
<<string(refp?"VARREF ":"VARXREF ")<<scopename<<")"<<endl);
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
UASSERT_OBJ(symp, nodep, "No symbol for interface alias rhs");
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"
<<cvtToHex(symp)<<" "<<symp->nodep()<<endl);
rhsSymp = symp;
@ -1407,11 +1409,12 @@ class LinkDotScopeVisitor : public AstNVisitor {
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");
UASSERT_OBJ(refp || xrefp, nodep,
"Unsupported: Non Var(X)Ref attached to interface pin");
string scopename = refp ? refp->varp()->name() : xrefp->dotted()+"."+xrefp->name();
string baddot; VSymEnt* okSymp;
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
if (!symp) nodep->v3fatalSrc("No symbol for interface alias lhs");
UASSERT_OBJ(symp, nodep, "No symbol for interface alias lhs");
UINFO(5, " Found a linked scope LHS: "<<scopename
<<" se"<<cvtToHex(symp)<<" "<<symp->nodep()<<endl);
lhsSymp = symp;
@ -1721,10 +1724,9 @@ private:
checkNoDot(nodep);
m_cellp = nodep;
AstNode::user5ClearTree();
if (!nodep->modp()) {
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
}
else {
UASSERT_OBJ(nodep->modp(), nodep,
"Cell has unlinked module"); // V3LinkCell should have errored out
{
if (VN_IS(nodep->modp(), NotFoundModule)) {
// Prevent warnings about missing pin connects
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
@ -1751,7 +1753,7 @@ private:
checkNoDot(nodep);
iterateChildren(nodep);
if (!nodep->modVarp()) {
if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?");
UASSERT_OBJ(m_pinSymp, nodep, "Pin not under cell?");
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
const char* whatp = nodep->param() ? "parameter pin" : "pin";
if (!foundp) {
@ -1852,8 +1854,8 @@ private:
UINFO(9," linkPARSEREF "<<m_ds.ascii()<<" n="<<nodep<<endl);
// m_curSymp is symbol table of outer expression
// m_ds.m_dotSymp is symbol table relative to "."'s above now
if (!m_ds.m_dotSymp) nodep->v3fatalSrc("NULL lookup symbol table");
if (!m_statep->forPrimary()) nodep->v3fatalSrc("ParseRefs should no longer exist");
UASSERT_OBJ(m_ds.m_dotSymp, nodep, "NULL lookup symbol table");
UASSERT_OBJ(m_statep->forPrimary(), nodep, "ParseRefs should no longer exist");
DotStates lastStates = m_ds;
bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed
if (start) {
@ -1879,11 +1881,10 @@ private:
expectWhat = "scope/variable";
allowScope = true;
allowVar = true;
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) {
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
}
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
m_ds.m_dotp->lhsp(), "Bad package link");
packagep = VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep();
if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
UASSERT_OBJ(packagep, m_ds.m_dotp->lhsp(), "Bad package link");
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
m_ds.m_dotPos = DP_SCOPE;
} else if (m_ds.m_dotPos == DP_SCOPE) {
@ -1931,13 +1932,13 @@ private:
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");
UASSERT_OBJ(cellEntp, nodep, "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 ? VN_CAST(ifaceSymp->nodep(), Var) : NULL;
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "
<<findName);
UASSERT_OBJ(ifaceRefVarp, nodep,
"Can't find interface var ref: "<<findName);
//
ok = true;
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
@ -1956,7 +1957,7 @@ private:
else if (AstVar* varp = foundToVarp(foundp, nodep, false)) {
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
if (ifacerefp) {
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
UASSERT_OBJ(ifacerefp->ifaceViaCellp(), ifacerefp, "Unlinked interface");
// Really this is a scope reference into an interface
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
@ -2011,7 +2012,7 @@ private:
<<modportp->prettyName());
} else {
AstCell* cellp = VN_CAST(m_ds.m_dotSymp->nodep(), Cell);
if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell");
UASSERT_OBJ(cellp, nodep, "Modport not referenced from a cell");
AstIface* ifacep = VN_CAST(cellp->modp(), Iface);
//string cellName = m_ds.m_dotText; // Use cellp->name
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
@ -2081,7 +2082,7 @@ private:
iterateChildren(nodep);
if (!nodep->varp()) {
UINFO(9," linkVarRef se"<<cvtToHex(m_curSymp)<<" n="<<nodep<<endl);
if (!m_curSymp) nodep->v3fatalSrc("NULL lookup symbol table");
UASSERT_OBJ(m_curSymp, nodep, "NULL lookup symbol table");
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
if (AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->lvalue()) : NULL) {
nodep->varp(varp);
@ -2110,10 +2111,9 @@ private:
dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw)
string inl = AstNode::dedotName(nodep->inlinedDots());
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
if (!dotSymp) {
nodep->v3fatalSrc("Couldn't resolve inlined scope '"
<<baddot<<"' in: "<<nodep->inlinedDots());
}
UASSERT_OBJ(dotSymp, nodep,
"Couldn't resolve inlined scope '"
<<baddot<<"' in: "<<nodep->inlinedDots());
}
dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL
if (!m_statep->forScopeCreation()) {
@ -2190,12 +2190,10 @@ private:
if (nodep->user3SetOnce()) return;
UINFO(8," "<<nodep<<endl);
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
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");
}
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
m_ds.m_dotp->lhsp(), "Bad package link");
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(),
m_ds.m_dotp->lhsp(), "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;
@ -2369,12 +2367,10 @@ private:
// Resolve its reference
if (nodep->user3SetOnce()) return;
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
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");
}
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
m_ds.m_dotp->lhsp(), "Bad package link");
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(),
m_ds.m_dotp->lhsp(), "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;

View File

@ -81,12 +81,10 @@ private:
// Also this would otherwise prevent us from using a label twice
// see t_func_return test.
while (underp && VN_IS(underp, Var)) underp = underp->nextp();
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
UASSERT_OBJ(underp, nodep, "Break/disable/continue not under expected statement");
UINFO(5," Underpoint is "<<underp<<endl);
if (!underp) {
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
return NULL;
} else if (VN_IS(underp, JumpLabel)) {
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);

View File

@ -80,7 +80,7 @@ void V3LinkLevel::modSortByLevel() {
// pointers, may have a stale m_iterp() needing cleanup
nodep->unlinkFrBack();
}
if (v3Global.rootp()->modulesp()) v3Global.rootp()->v3fatalSrc("Unlink didn't work");
UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work");
for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) {
AstNodeModule* nodep = *it;
v3Global.rootp()->addModulep(nodep);
@ -132,7 +132,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
AstNodeModule* newmodp = rootp->modulesp();
if (!newmodp || !newmodp->isTop()) rootp->v3fatalSrc("No TOP module found to insert under");
UASSERT_OBJ(newmodp && newmodp->isTop(), rootp, "No TOP module found to insert under");
// Find all duplicate signal names (if multitop)
typedef vl_unordered_set<std::string> NameSet;

View File

@ -241,62 +241,62 @@ private:
iterateChildren(nodep);
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
AstTypedef* typep = VN_CAST(nodep->backp(), Typedef);
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef");
typep->attrPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrScClocked(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrClockEn(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->sigUserRWPublic(true); m_varp->sigModPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->sigUserRWPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->sigUserRdPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->sigUserRWPublic(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrIsolateAssign(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrSFormat(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrScBv(true);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
@ -337,7 +337,8 @@ private:
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");
UASSERT_OBJ(backp, nodep,
"Implicit enum/struct type created under unexpected node type");
AstNodeDType* dtypep = nodep->childDTypep(); dtypep->unlinkFrBack();
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

View File

@ -240,12 +240,12 @@ private:
virtual void visit(AstPragma* nodep) {
if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) {
if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module");
UASSERT_OBJ(m_modp, nodep, "PUBLIC_MODULE not under a module");
m_modp->modPublic(true);
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) {
if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task");
UASSERT_OBJ(m_ftaskp, nodep, "PUBLIC_TASK not under a task");
m_ftaskp->taskPublic(true);
m_modp->modPublic(true); // Need to get to the task...
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
@ -387,7 +387,7 @@ private:
iterateChildren(nodep);
// Cleanup old-school displays without format arguments
if (!nodep->hasFormat()) {
if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format");
UASSERT_OBJ(nodep->text()=="", nodep, "Non-format $sformatf should have \"\" format");
if (VN_IS(nodep->exprsp(), Const)
&& VN_CAST(nodep->exprsp(), Const)->num().isFromString()) {
AstConst* fmtp = VN_CAST(nodep->exprsp()->unlinkFrBack(), Const);

View File

@ -173,7 +173,7 @@ private:
for (; nodep; nodep=nodep->nextp()) {
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");
UASSERT_OBJ(varrefp->lvalue(), varrefp, "LHS assignment not lvalue");
if (!varrefp->varp()->user4p()) {
UINFO(4," FuncAsn "<<varrefp<<endl);
varrefp->varp()->user4p(varrefp);

View File

@ -202,7 +202,7 @@ public:
// METHODS
OrderVarVertex* newVarUserVertex(V3Graph* graphp, AstScope* scopep,
AstVarScope* varscp, WhichVertex type, bool* createdp=NULL) {
if (type>=WV_MAX) varscp->v3fatalSrc("Bad case");
UASSERT_OBJ(type < WV_MAX, varscp, "Bad case");
OrderVarVertex* vertexp = m_vertexp[type];
if (!vertexp) {
UINFO(6,"New vertex "<<varscp<<endl);
@ -735,7 +735,7 @@ private:
UINFO(4," STMT "<<nodep<<endl);
//VV***** We reset user4p()
AstNode::user4ClearTree();
if (!m_activep || !m_activep->sensesp()) nodep->v3fatalSrc("NULL");
UASSERT_OBJ(m_activep && m_activep->sensesp(), nodep, "NULL");
// If inside combo logic, ignore the domain, we'll assign one based on interconnect
AstSenTree* startDomainp = m_activep->sensesp();
if (startDomainp->hasCombo()) startDomainp=NULL;
@ -963,7 +963,7 @@ private:
}
virtual void visit(AstTopScope* nodep) {
// Process the last thing we're finishing
if (m_topScopep) nodep->v3fatalSrc("Only one topscope should ever be created");
UASSERT_OBJ(!m_topScopep, nodep, "Only one topscope should ever be created");
UINFO(2," Loading tree...\n");
//VV***** We reset userp()
AstNode::user1ClearTree();
@ -1022,7 +1022,8 @@ private:
m_activeSenVxp = NULL;
m_inClocked = nodep->hasClocked();
// Grab the sensitivity list
if (nodep->sensesStorep()) nodep->v3fatalSrc("Senses should have been activeTop'ed to be global!");
UASSERT_OBJ(!nodep->sensesStorep(), nodep,
"Senses should have been activeTop'ed to be global!");
iterate(nodep->sensesp());
// Collect statements under it
iterateChildren(nodep);
@ -1040,15 +1041,15 @@ private:
virtual void visit(AstNodeVarRef* nodep) {
if (m_scopep) {
AstVarScope* varscp = nodep->varScopep();
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
if (m_inSenTree) {
// Add CLOCK dependency... This is a root of the tree we'll trace
if (nodep->lvalue()) nodep->v3fatalSrc("How can a sensitivity be setting a var?");
UASSERT_OBJ(!nodep->lvalue(), nodep, "How can a sensitivity be setting a var?");
OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD);
varVxp->isClock(true);
new OrderEdge(&m_graph, varVxp, m_activeSenVxp, WEIGHT_MEDIUM);
} else {
if (!m_logicVxp) nodep->v3fatalSrc("Var ref not under a logic block");
UASSERT_OBJ(m_logicVxp, nodep, "Var ref not under a logic block");
// What new directions is this used
// We don't want to add extra edges if the logic block has many usages of same var
bool gen = false;
@ -1307,8 +1308,8 @@ static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) {
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");
if (!toSenListp) top->v3fatalSrc("sensitivity list item is not an AstSenItem");
UASSERT_OBJ(fromSenListp, fromp, "sensitivity list item is not an AstSenItem");
UASSERT_OBJ(toSenListp, top, "sensitivity list item is not an AstSenItem");
if (fromSenListp->nextp()) return false;
if (toSenListp->nextp()) return false;
@ -1337,9 +1338,8 @@ inline void OrderMoveDomScope::ready(OrderVisitor* ovp) {
// Mark one vertex as finished, remove from ready list if done
inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) {
if (!m_onReadyList) {
vertexp->v3fatalSrc("Moving vertex from ready when nothing was on que as ready.");
}
UASSERT_OBJ(m_onReadyList, vertexp,
"Moving vertex from ready when nothing was on que as ready.");
if (m_readyVertices.empty()) { // Else more work to get to later
m_onReadyList = false;
m_readyDomScopeE.unlink(ovp->m_pomReadyDomScope, this);
@ -1406,9 +1406,8 @@ void OrderVisitor::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
// First make sure input path is fully recursed
processInputsInIterate(vertexp, todoVec);
// Propagate PrimaryIn through simple assignments
if (!vertexp->isFromInput()) {
vertexp->v3fatalSrc("processInputsOutIterate only for input marked vertexes");
}
UASSERT_OBJ(vertexp->isFromInput(), vertexp,
"processInputsOutIterate only for input marked vertexes");
vertexp->user(3); // out-edges processed
{
@ -1460,7 +1459,7 @@ void OrderVisitor::processCircular() {
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
if (edgep->weight()==0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cuttable edge not of proper type");
UINFO(6," CutCircularO: "<<vvertexp->name()<<endl);
nodeMarkCircular(vvertexp, oedgep);
}
@ -1468,7 +1467,7 @@ void OrderVisitor::processCircular() {
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
if (edgep->weight()==0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cuttable edge not of proper type");
UINFO(6," CutCircularI: "<<vvertexp->name()<<endl);
nodeMarkCircular(vvertexp, oedgep);
}
@ -1563,7 +1562,8 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
}
AstSenTree* newtreep = domainp->cloneTree(false);
AstNodeSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
if (!newtree2p) fromVertexp->domainp()->v3fatalSrc("No senitem found under clocked domain");
UASSERT_OBJ(newtree2p, fromVertexp->domainp(),
"No senitem found under clocked domain");
newtreep->addSensesp(newtree2p);
newtree2p = NULL; // Below edit may replace it
V3Const::constifyExpensiveEdit(newtreep); // Remove duplicates
@ -1759,9 +1759,7 @@ void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) {
void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp,
OrderMoveDomScope* domScopep, int level) {
if (vertexp->domScopep() != domScopep) {
vertexp->v3fatalSrc("Domain mismatch; list misbuilt?");
}
UASSERT_OBJ(vertexp->domScopep() == domScopep, vertexp, "Domain mismatch; list misbuilt?");
const OrderLogicVertex* lvertexp = vertexp->logicp();
const AstScope* scopep = lvertexp->scopep();
UINFO(5," POSmove l"<<std::setw(3)<<level<<" d="<<cvtToHex(lvertexp->domainp())

View File

@ -204,16 +204,14 @@ private:
// Find it in the clone structure
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
if (cloneiter == clonemapp->end()) {
pinp->v3fatalSrc("Couldn't find pin in clone list");
}
UASSERT_OBJ(cloneiter != clonemapp->end(), pinp,
"Couldn't find pin in clone list");
pinp->modVarp(VN_CAST(cloneiter->second, Var));
}
else if (pinp->modPTypep()) {
CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep());
if (cloneiter == clonemapp->end()) {
pinp->v3fatalSrc("Couldn't find pin in clone list");
}
UASSERT_OBJ(cloneiter != clonemapp->end(), pinp,
"Couldn't find pin in clone list");
pinp->modPTypep(VN_CAST(cloneiter->second, ParamTypeDType));
}
else {
@ -318,7 +316,7 @@ private:
return true;
} 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");
UASSERT_OBJ(pinp->exprp(), pinp, "Interface parameter pin missing expression");
nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep);
return true;
}
@ -455,7 +453,7 @@ private:
virtual void visit(AstBegin* nodep) {
if (nodep->genforp()) {
AstGenFor* forp = VN_CAST(nodep->genforp(), GenFor);
if (!forp) nodep->v3fatalSrc("Non-GENFOR under generate-for BEGIN");
UASSERT_OBJ(forp, nodep, "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
UINFO(9," BEGIN "<<nodep<<endl);
@ -560,7 +558,7 @@ public:
void ParamVisitor::visitCell(AstCell* nodep) {
// Cell: Check for parameters in the instantiation.
iterateChildren(nodep);
if (!nodep->modp()) nodep->v3fatalSrc("Not linked?");
UASSERT_OBJ(nodep->modp(), nodep, "Not linked?");
// We always run this, even if no parameters, as need to look for interfaces,
// and remove any recursive references
{
@ -777,7 +775,8 @@ void ParamVisitor::visitCell(AstCell* nodep) {
AstIfaceRefDType* cloneIrefp = portIrefp->clonep();
UINFO(8," IfaceOld "<<portIrefp<<endl);
UINFO(8," IfaceTo "<<pinIrefp<<endl);
if (!cloneIrefp) portIrefp->v3fatalSrc("parameter clone didn't hit AstIfaceRefDType");
UASSERT_OBJ(cloneIrefp, portIrefp,
"parameter clone didn't hit AstIfaceRefDType");
UINFO(8," IfaceClo "<<cloneIrefp<<endl);
cloneIrefp->ifacep(pinIrefp->ifaceViaCellp());
UINFO(8," IfaceNew "<<cloneIrefp<<endl);
@ -796,7 +795,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
}
else if (AstParamTypeDType* modptp = pinp->modPTypep()) {
AstNodeDType* dtypep = VN_CAST(pinp->exprp(), NodeDType);
if (!dtypep) pinp->v3fatalSrc("unlinked param dtype");
UASSERT_OBJ(dtypep, pinp, "unlinked param dtype");
if (modptp->childDTypep()) {
pushDeletep(modptp->childDTypep()->unlinkFrBack());
}

View File

@ -109,9 +109,8 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
if (prevp) nrangep->unlinkFrBack();
AstRange* rangep = VN_CAST(nrangep, Range);
if (!rangep) {
if (VL_UNCOVERABLE(!VN_IS(nrangep, UnsizedRange))) {
nrangep->v3fatalSrc("Expected range or unsized range");
}
UASSERT_OBJ(VN_IS(nrangep, UnsizedRange), nrangep,
"Expected range or unsized range");
arrayp = new AstUnsizedArrayDType
(nrangep->fileline(), VFlagChildDType(), arrayp);
} else if (isPacked) {

View File

@ -60,7 +60,7 @@ public:
private:
// METHODS
static VSymEnt* getTable(AstNode* nodep) {
if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found");
UASSERT_OBJ(nodep->user4p(), nodep, "Current symtable not found");
return nodep->user4u().toSymEnt();
}
@ -116,7 +116,7 @@ public:
return;
}
m_sympStack.pop_back();
if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; }
UASSERT_OBJ(!m_sympStack.empty(), nodep, "symbol stack underflow");
m_symCurrentp = m_sympStack.back();
}
void showUpward() {
@ -139,10 +139,9 @@ public:
void importItem(AstNode* packagep, const string& id_or_star) {
// Import from package::id_or_star to this
VSymEnt* symp = getTable(packagep);
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
packagep->v3fatalSrc("Import package not found");
return;
}
UASSERT_OBJ(symp, packagep,
// Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
"Import package not found");
// Walk old sym table and reinsert into current table
// We let V3LinkDot report the error instead of us
symCurrentp()->importFromPackage(&m_syms, symp, id_or_star);
@ -150,10 +149,9 @@ public:
void exportItem(AstNode* packagep, const string& id_or_star) {
// Export from this the remote package::id_or_star
VSymEnt* symp = getTable(packagep);
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
packagep->v3fatalSrc("Export package not found");
return;
}
UASSERT_OBJ(symp, packagep,
// Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
"Export package not found");
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
}
void exportStarStar(AstNode* packagep) {

View File

@ -314,7 +314,7 @@ private:
// important property of PartPropagateCp which allows it to be far
// faster than a recursive algorithm on some graphs.
CpMap::iterator it = m_seen.find(vxp);
if (it != m_seen.end()) vxp->v3fatalSrc("Set CP on node twice");
UASSERT_OBJ(it == m_seen.end(), vxp, "Set CP on node twice");
m_seen[vxp] = cost;
}
uint32_t critPathCost(V3GraphVertex* vxp, GraphWay way) const {
@ -452,7 +452,7 @@ public:
// This is mtaskp's relative with longest !wayward inclusive CP:
EdgeSet::reverse_iterator edgeIt = edges.rbegin();
uint32_t edgeCp = (*edgeIt).value();
if (edgeCp != cp) vxp->v3fatalSrc("CP doesn't match longest wayward edge");
UASSERT_OBJ(edgeCp == cp, vxp, "CP doesn't match longest wayward edge");
}
private:
VL_UNCOPYABLE(CpCostAccessor);
@ -988,12 +988,10 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
edgep; edgep = edgep->nextp(rev)) {
// Run a few asserts on the initial mtask graph,
// while we're iterating through...
if (edgep->weight() == 0) {
mtaskp->v3fatalSrc("Should be no cut edges in mtasks graph");
}
if (relatives.find(edgep->furtherp(rev)) != relatives.end()) {
mtaskp->v3fatalSrc("Should be no redundant edges in mtasks graph");
}
UASSERT_OBJ(edgep->weight() != 0, mtaskp,
"Should be no cut edges in mtasks graph");
UASSERT_OBJ(relatives.find(edgep->furtherp(rev)) == relatives.end(), mtaskp,
"Should be no redundant edges in mtasks graph");
relatives.insert(edgep->furtherp(rev));
LogicMTask* relativep
@ -1187,9 +1185,8 @@ public:
for (V3GraphEdge* edgep = itp->outBeginp(); edgep;
edgep=edgep->outNextp()) {
m_sb.addElem(MTaskEdge::cast(edgep));
if (neighbors.find(edgep->top()) != neighbors.end()) {
itp->v3fatalSrc("Redundant edge found in input to PartContraction()");
}
UASSERT_OBJ(neighbors.find(edgep->top()) == neighbors.end(), itp,
"Redundant edge found in input to PartContraction()");
neighbors.insert(edgep->top());
}
siblingPairFromRelatives(GraphWay::REVERSE, itp, true);
@ -1352,12 +1349,12 @@ private:
LogicMTask* otherp = (pairp->bp() == mtaskp) ?
pairp->ap() : pairp->bp();
size_t erased = m_mtask2sibs[otherp].erase(pairp);
if (erased <= 0) otherp->v3fatalSrc("Expected existing mtask");
UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask");
erased = m_pairs.erase(*pairp);
if (erased <= 0) mtaskp->v3fatalSrc("Expected existing mtask");
UASSERT_OBJ(erased > 0, mtaskp, "Expected existing mtask");
}
size_t erased = m_mtask2sibs.erase(mtaskp);
if (erased <= 0) mtaskp->v3fatalSrc("Expected existing mtask");
UASSERT_OBJ(erased > 0, mtaskp, "Expected existing mtask");
}
void contract(MergeCandidate* mergeCanp) {
@ -1571,24 +1568,21 @@ private:
} else if (m_slowAsserts) {
// It's fine if we already have this SiblingMC, we may have
// created it earlier. Just confirm that we have associated data.
if (m_mtask2sibs.find(ap) == m_mtask2sibs.end()) {
ap->v3fatalSrc("Sibling not found");
}
if (m_mtask2sibs.find(bp) == m_mtask2sibs.end()) {
bp->v3fatalSrc("Sibling not found");
}
UASSERT_OBJ(m_mtask2sibs.find(ap) != m_mtask2sibs.end(), ap,
"Sibling not found");
UASSERT_OBJ(m_mtask2sibs.find(bp) != m_mtask2sibs.end(), bp,
"Sibling not found");
bool found = false;
for (SibpSet::iterator it = m_mtask2sibs[ap].begin();
it != m_mtask2sibs[ap].end(); ++it) {
const SiblingMC* sibsp = *it;
if (!sibsp->removedFromSb() && !m_sb.contains(sibsp)) {
ap->v3fatalSrc("One sibling must be the one we collided with");
}
UASSERT_OBJ(!(!sibsp->removedFromSb() && !m_sb.contains(sibsp)), ap,
"One sibling must be the one we collided with");
if ( (sibsp->ap() == ap && sibsp->bp() == bp)
|| (sibsp->bp() == ap && sibsp->ap() == bp))
found = true;
}
if (!found) ap->v3fatalSrc("Sibling not found");
UASSERT_OBJ(found, ap, "Sibling not found");
}
};
@ -1955,7 +1949,7 @@ private:
while (!rankIt->second.empty()) {
LogicMTaskSet::iterator begin = rankIt->second.begin();
LogicMTask* donorp = *begin;
if (donorp == mergedp) donorp->v3fatalSrc("Donor can't be merged edge");
UASSERT_OBJ(donorp != mergedp, donorp, "Donor can't be merged edge");
rankIt->second.erase(begin);
// Merge donorp into mergedp.
// Fix up the map, so donor's OLVs map to mergedp
@ -1976,9 +1970,8 @@ private:
}
if (lastMergedp) {
if (lastMergedp->rank() >= mergedp->rank()) {
mergedp->v3fatalSrc("Merging must be on lower rank");
}
UASSERT_OBJ(lastMergedp->rank() < mergedp->rank(), mergedp,
"Merging must be on lower rank");
if (!lastMergedp->hasRelative(GraphWay::FORWARD, mergedp)) {
new MTaskEdge(m_mtasksp, lastMergedp, mergedp, 1);
}
@ -2309,7 +2302,7 @@ public:
// Update the ready list
size_t erased = m_ready.erase(bestMtaskp);
if (erased <= 0) bestMtaskp->v3fatalSrc("Should have erased something?");
UASSERT_OBJ(erased > 0, bestMtaskp, "Should have erased something?");
for (V3GraphEdge* edgeOutp = bestMtaskp->outBeginp();
edgeOutp; edgeOutp = edgeOutp->outNextp()) {
ExecMTask* nextp = dynamic_cast<ExecMTask*>(edgeOutp->top());
@ -2318,9 +2311,8 @@ public:
"Tasks after one being assigned should not be assigned yet");
// They also should not be ready yet, since they only now
// may become ready
if (m_ready.find(nextp) != m_ready.end()) {
nextp->v3fatalSrc("Tasks after one being assigned should not be ready");
}
UASSERT_OBJ(m_ready.find(nextp) == m_ready.end(), nextp,
"Tasks after one being assigned should not be ready");
bool isReady = true;
for (V3GraphEdge* edgeInp = nextp->inBeginp();
edgeInp; edgeInp = edgeInp->inNextp()) {
@ -2514,7 +2506,7 @@ void V3Partition::setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp)
UASSERT(it != vx2mtaskp->end(), "MTask map can't find id");
LogicMTask* otherMTaskp = it->second;
UASSERT(otherMTaskp, "NULL other Mtask");
if (otherMTaskp == mtaskp) mtaskp->v3fatalSrc("Would create a cycle edge");
UASSERT_OBJ(otherMTaskp != mtaskp, mtaskp, "Would create a cycle edge");
// Don't create redundant edges.
if (mtaskp->hasRelative(GraphWay::FORWARD, otherMTaskp)) {
@ -2543,7 +2535,7 @@ void V3Partition::go(V3Graph* mtasksp) {
for (V3GraphVertex* vxp = m_fineDepsGraphp->verticesBeginp();
vxp; vxp = vxp->verticesNextp()) {
MTaskMoveVertex* mtmvVxp = dynamic_cast<MTaskMoveVertex*>(vxp);
if (!mtmvVxp) vxp->v3fatalSrc("Every vertex here should be an MTaskMoveVertex");
UASSERT_OBJ(mtmvVxp, vxp, "Every vertex here should be an MTaskMoveVertex");
LogicMTask* mtaskp = new LogicMTask(mtasksp, mtmvVxp);
vx2mtask[mtmvVxp] = mtaskp;

View File

@ -82,7 +82,7 @@ private:
string newvarname = string("__Vilp");
varp = new AstVar(fl, AstVarType::STMTTEMP,
newvarname, VFlagLogicPacked(), 32);
if (!cfuncp) fl->v3fatalSrc("Assignment not under a function");
UASSERT_OBJ(cfuncp, fl, "Assignment not under a function");
cfuncp->addInitsp(varp);
cfuncp->user1p(varp);
}
@ -101,7 +101,7 @@ private:
// Transform first assign into for loop body
AstNodeAssign* bodyp = m_mgAssignps.front();
if (bodyp->lhsp() != m_mgSelLp) bodyp->v3fatalSrc("Corrupt queue/state");
UASSERT_OBJ(bodyp->lhsp() == m_mgSelLp, bodyp, "Corrupt queue/state");
FileLine* fl = bodyp->fileline();
AstVar* itp = findCreateVarTemp(fl, m_mgCfuncp);

View File

@ -77,11 +77,11 @@ private:
AstScope* scopep = it->second;
if (nodep->packagep()) {
PackageScopeMap::iterator it2 = m_packageScopes.find(nodep->packagep());
if (it2==m_packageScopes.end()) nodep->v3fatalSrc("Can't locate package scope");
UASSERT_OBJ(it2 != m_packageScopes.end(), nodep, "Can't locate package scope");
scopep = it2->second;
}
VarScopeMap::iterator it3 = m_varScopes.find(make_pair(nodep->varp(), scopep));
if (it3==m_varScopes.end()) nodep->v3fatalSrc("Can't locate varref scope");
UASSERT_OBJ(it3 != m_varScopes.end(), nodep, "Can't locate varref scope");
AstVarScope* varscp = it3->second;
nodep->varScopep(varscp);
}
@ -124,7 +124,7 @@ private:
m_aboveCellp = cellp;
m_aboveScopep = m_scopep;
AstNodeModule* modp = cellp->modp();
if (!modp) cellp->v3fatalSrc("Unlinked mod");
UASSERT_OBJ(modp, cellp, "Unlinked mod");
iterate(modp); // Recursive call to visit(AstNodeModule)
}
// Done, restore vars
@ -251,7 +251,7 @@ private:
if (v3Global.opt.isNoClocker(varscp->prettyName())) {
nodep->attrClocker(AstVarAttrClocker::CLOCKER_NO);
}
if (!m_scopep) nodep->v3fatalSrc("No scope for var");
UASSERT_OBJ(m_scopep, nodep, "No scope for var");
m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp));
m_scopep->addVarp(varscp);
}
@ -259,7 +259,7 @@ private:
virtual void visit(AstVarRef* nodep) {
// VarRef needs to point to VarScope
// Make sure variable has made user1p.
if (!nodep->varp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
if (nodep->varp()->isIfaceRef()) {
nodep->varScopep(NULL);
} else {
@ -378,9 +378,9 @@ private:
UINFO(9," Old pkg-taskref "<<nodep<<endl);
if (nodep->packagep()) {
// Point to the clone
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked");
AstNodeFTask* newp = VN_CAST(nodep->taskp()->user2p(), NodeFTask);
if (!newp) nodep->v3fatalSrc("No clone for package function");
UASSERT_OBJ(newp, nodep, "No clone for package function");
nodep->taskp(newp);
UINFO(9," New pkg-taskref "<<nodep<<endl);
} else {

View File

@ -267,13 +267,13 @@ public:
}
V3Number* fetchNumber(AstNode* nodep) {
V3Number* nump = fetchNumberNull(nodep);
if (!nump) nodep->v3fatalSrc("No value found for node.");
UASSERT_OBJ(nump, nodep, "No value found for node.");
//UINFO(9," fetch num "<<*nump<<" on "<<nodep<<endl);
return nump;
}
V3Number* fetchOutNumber(AstNode* nodep) {
V3Number* nump = fetchOutNumberNull(nodep);
if (!nump) nodep->v3fatalSrc("No value found for node.");
UASSERT_OBJ(nump, nodep, "No value found for node.");
return nump;
}
private:
@ -314,7 +314,7 @@ private:
AstNode* vscp;
if (m_scoped) vscp = nodep->varScopep();
else vscp = nodep->varp();
if (!vscp) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(vscp, nodep, "Not linked");
return vscp;
}
int unrollCount() {
@ -347,7 +347,7 @@ private:
virtual void visit(AstVarRef* nodep) {
if (jumpingOver(nodep)) return;
if (!optimizable()) return; // Accelerate
if (!nodep->varp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
iterateChildren(nodep->varp());
AstNode* vscp = varOrScope(nodep);
@ -391,9 +391,9 @@ private:
}
}
if (!m_checkOnly && optimizable()) { // simulating
if (nodep->lvalue()) {
nodep->v3fatalSrc("LHS varref should be handled in AstAssign visitor.");
} else {
UASSERT_OBJ(!nodep->lvalue(), nodep,
"LHS varref should be handled in AstAssign visitor.");
{
// Return simulation value - copy by reference instead of value for speed
V3Number* nump = fetchNumberNull(vscp);
if (!nump) {
@ -447,7 +447,7 @@ private:
}
virtual void visit(AstEnumItemRef* nodep) {
checkNodeInfo(nodep);
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
if (!m_checkOnly && optimizable()) {
AstNode* valuep = nodep->itemp()->valuep();
if (valuep) {
@ -572,9 +572,8 @@ private:
iterateAndNextNull(nodep->rhsp()); // Value to assign
handleAssignSelRecurse(nodep, selp, varrefp/*ref*/, lsb/*ref*/, 0);
if (!m_checkOnly && optimizable()) {
if (!varrefp) {
nodep->v3fatalSrc("Indicated optimizable, but no variable found on RHS of select");
}
UASSERT_OBJ(varrefp, nodep,
"Indicated optimizable, but no variable found on RHS of select");
AstNode* vscp = varOrScope(varrefp);
V3Number outnum = V3Number(nodep);
if (V3Number* vscpnump = fetchOutNumberNull(vscp)) {
@ -796,9 +795,9 @@ private:
UINFO(5," FUNCREF "<<nodep<<endl);
if (!m_params) { badNodeType(nodep); return; }
AstNodeFTask* funcp = VN_CAST(nodep->taskp(), NodeFTask);
if (!funcp) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(funcp, nodep, "Not linked");
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
funcp = VN_CAST(nodep->taskp(), NodeFTask); UASSERT_OBJ(funcp, nodep, "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
@ -832,7 +831,7 @@ private:
m_callStack.pop_front();
if (!m_checkOnly && optimizable()) {
// Grab return value from output variable (if it's a function)
if (!funcp->fvarp()) nodep->v3fatalSrc("Function reference points at non-function");
UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function");
newNumber(nodep, *fetchNumber(funcp->fvarp()));
}
}
@ -947,10 +946,7 @@ private:
}
void mainGuts(AstNode* nodep) {
iterate(nodep);
if (m_jumpp) {
m_jumpp->v3fatalSrc("JumpGo branched to label that wasn't found");
m_jumpp = NULL;
}
UASSERT_OBJ(!m_jumpp, m_jumpp, "JumpGo branched to label that wasn't found");
}
public:
// CONSTRUCTORS

View File

@ -161,9 +161,8 @@ class SliceVisitor : public AstNVisitor {
}
virtual void visit(AstInitArray* nodep) {
if (VL_UNCOVERABLE(m_assignp)) {
nodep->v3fatalSrc("Array initialization should have been removed earlier");
}
UASSERT_OBJ(!m_assignp, nodep,
"Array initialization should have been removed earlier");
}
void expandBiOp(AstNodeBiop* nodep) {
@ -202,7 +201,7 @@ class SliceVisitor : public AstNVisitor {
}
}
}
if (!logp) nodep->v3fatalSrc("Unpacked array with empty indices range");
UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range");
nodep->replaceWith(logp);
pushDeletep(nodep); VL_DANGLING(nodep);
nodep = logp;

View File

@ -309,7 +309,7 @@ private:
//UINFO(9," push "<<nodep<<endl);
SplitLogicVertex* vertexp = new SplitLogicVertex(&m_graph, nodep);
m_stmtStackps.push_back(vertexp);
if (nodep->user3p()) nodep->v3fatalSrc("user3p should not be used; cleared in processBlock");
UASSERT_OBJ(!nodep->user3p(), nodep, "user3p should not be used; cleared in processBlock");
nodep->user3p(vertexp);
}
void scoreboardPopStmt() {
@ -365,7 +365,7 @@ protected:
virtual void visit(AstVarRef* nodep) {
if (!m_stmtStackps.empty()) {
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Not linked");
UASSERT_OBJ(vscp, nodep, "Not linked");
if (!nodep->varp()->isConst()) { // Constant lookups can be ignored
// ---
// NOTE: Formerly at this location we would avoid
@ -518,7 +518,7 @@ protected:
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
uint32_t color = vvertexp->color();
if (!color) nextp->v3fatalSrc("No node color assigned");
UASSERT_OBJ(color, nextp, "No node color assigned");
if (lastOfColor[color]) {
new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp);
}
@ -580,9 +580,8 @@ protected:
AstNode* firstp = nodep; // We may reorder, and nodep is no longer first.
void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
nodep->user3p(NULL);
if (!nodep->firstAbovep()) {
nodep->v3fatalSrc("Node passed is in next list; should have processed all list at once");
}
UASSERT_OBJ(nodep->firstAbovep(), nodep,
"Node passed is in next list; should have processed all list at once");
// Process it
if (!nodep->nextp()) {
// Just one, so can't reorder. Just look for more blocks/statements.
@ -656,7 +655,7 @@ public:
const ColorSet& colors() const { return m_colors; }
const ColorSet& colors(AstNodeIf* nodep) const {
IfColorMap::const_iterator it = m_ifColors.find(nodep);
if (it == m_ifColors.end()) nodep->v3fatalSrc("Unknown node in split color() map");
UASSERT_OBJ(it != m_ifColors.end(), nodep, "Unknown node in split color() map");
return it->second;
}
@ -758,7 +757,7 @@ protected:
// for such an embedded if.
// Each leaf must have a user3p
if (!nodep->user3p()) nodep->v3fatalSrc("null user3p in V3Split leaf");
UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf");
// Clone the leaf into its new always block
SplitLogicVertex* vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());

View File

@ -136,7 +136,7 @@ public:
if (!m_varp->isWide()
&& !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) {
AstNodeAssign* assp = m_whole.m_assignp;
if (!assp) errp->v3fatalSrc("Reading whole that was never assigned");
UASSERT_OBJ(assp, errp, "Reading whole that was never assigned");
return (assp->rhsp());
} else {
return NULL;
@ -145,7 +145,7 @@ public:
AstNode* substWord(AstNode* errp, int word) { // Return what to substitute given word number for
if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) {
AstNodeAssign* assp = getWordAssignp(word);
if (!assp) errp->v3fatalSrc("Reading a word that was never assigned, or bad word #");
UASSERT_OBJ(assp, errp, "Reading a word that was never assigned, or bad word #");
return (assp->rhsp());
} else {
return NULL;

View File

@ -310,16 +310,15 @@ private:
shift += invscp->width();
// We're just using32 bit arithmetic, because there's no
// way the input table can be 2^32 bytes!
if (shift>31) nodep->v3fatalSrc("shift overflow");
UASSERT_OBJ(shift <= 32, nodep, "shift overflow");
UINFO(8," Input "<<invscp->name()<<" = "<<*(simvis.fetchNumber(invscp))<<endl);
}
// Simulate
simvis.mainTableEmulate(nodep);
if (VL_UNCOVERABLE(!simvis.optimizable())) {
simvis.whyNotNodep()->v3fatalSrc("Optimizable cleared, even though earlier test run said not: "
<<simvis.whyNotMessage());
}
UASSERT_OBJ(simvis.optimizable(), simvis.whyNotNodep(),
"Optimizable cleared, even though earlier test run said not: "
<<simvis.whyNotMessage());
// If a output changed, add it to table
int outnum = 0;
@ -348,9 +347,9 @@ private:
}
{ // Set changed table
if (VL_UNCOVERABLE(inValue != inValueNextInitArray++)) {
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
}
UASSERT_OBJ(inValue == inValueNextInitArray, nodep,
"InitArray requires us to have the values in inValue order");
inValueNextInitArray++;
AstNode* setp = new AstConst(nodep->fileline(), outputChgMask);
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
}

View File

@ -120,12 +120,12 @@ public:
// METHODS
AstScope* getScope(AstNodeFTask* nodep) {
AstScope* scopep = VN_CAST(nodep->user3p(), Scope);
if (!scopep) nodep->v3fatalSrc("No scope for function");
UASSERT_OBJ(scopep, nodep, "No scope for function");
return scopep;
}
AstVarScope* findVarScope(AstScope* scopep, AstVar* nodep) {
VarToScopeMap::iterator iter = m_varToScopeMap.find(make_pair(scopep, nodep));
if (iter == m_varToScopeMap.end()) nodep->v3fatalSrc("No scope for var");
UASSERT_OBJ(iter != m_varToScopeMap.end(), nodep, "No scope for var");
return iter->second;
}
bool ftaskNoInline(AstNodeFTask* nodep) {
@ -199,7 +199,7 @@ private:
pushDeletep(m_assignwp); m_assignwp = NULL;
}
// We make multiple edges if a task is called multiple times from another task.
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked task");
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked task");
new TaskEdge(&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp()));
}
virtual void visit(AstNodeFTask* nodep) {
@ -269,7 +269,7 @@ private:
if (nodep->varp()->user2p()) { // It's being converted to an alias.
UINFO(9, " relinkVar "<<cvtToHex(nodep->varp()->user2p())<<" "<<nodep<<endl);
AstVarScope* newvscp = VN_CAST(nodep->varp()->user2p(), VarScope);
if (!newvscp) nodep->v3fatalSrc("not linked");
UASSERT_OBJ(newvscp, nodep, "not linked");
nodep->varScopep(newvscp);
nodep->varp(nodep->varScopep()->varp());
nodep->name(nodep->varp()->name());
@ -362,7 +362,7 @@ private:
AstNode* createInlinedFTask(AstNodeFTaskRef* refp,
const string& namePrefix, AstVarScope* outvscp) {
// outvscp is the variable for functions only, if NULL, it's a task
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
AstNode* newbodysp = AstNode::cloneTreeNull(refp->taskp()->stmtsp(), true); // Maybe NULL
AstNode* beginp = new AstComment(refp->fileline(), string("Function: ")+refp->name());
if (newbodysp) beginp->addNext(newbodysp);
@ -397,7 +397,7 @@ private:
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) {
// Connect to this exact variable
AstVarScope* localVscp = varrefp->varScopep();
if (!localVscp) varrefp->v3fatalSrc("Null var scope");
UASSERT_OBJ(localVscp, varrefp, "Null var scope");
portp->user2p(localVscp);
pushDeletep(pinp);
} else {
@ -442,7 +442,7 @@ private:
}
}
}
if (refp->pinsp()) refp->v3fatalSrc("Pin wasn't removed by above loop");
UASSERT_OBJ(!refp->pinsp(), refp, "Pin wasn't removed by above loop");
{
AstNode* nextstmtp;
for (AstNode* stmtp = beginp; stmtp; stmtp=nextstmtp) {
@ -479,9 +479,9 @@ private:
AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix,
AstVarScope* outvscp) {
// outvscp is the variable for functions only, if NULL, it's a task
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp());
if (!cfuncp) refp->v3fatalSrc("No non-inline task associated with this task call?");
UASSERT_OBJ(cfuncp, refp, "No non-inline task associated with this task call?");
//
AstNode* beginp = new AstComment(refp->fileline(), string("Function: ")+refp->name());
AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL);
@ -543,7 +543,7 @@ private:
if (refp->taskp()->dpiContext()) {
// __Vscopep
AstNode* snp = refp->scopeNamep()->unlinkFrBack();
if (!snp) refp->v3fatalSrc("Missing scoping context");
UASSERT_OBJ(snp, refp, "Missing scoping context");
ccallp->addArgsp(snp);
// __Vfilenamep
ccallp->addArgsp(new AstCMath(refp->fileline(),
@ -967,7 +967,7 @@ private:
AstVar* rtnvarp = NULL;
if (nodep->isFunction()) {
AstVar* portp = VN_CAST(nodep->fvarp(), Var);
if (!portp) nodep->v3fatalSrc("function without function output variable");
UASSERT_OBJ(portp, nodep, "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.)");
if (ftaskNoInline || nodep->dpiExport()) portp->funcReturn(false); // Converting return to 'outputs'
@ -986,7 +986,8 @@ private:
if (nodep->dpiImport()) {
if (nodep->dpiOpenChild()) { // The parent will make the dpi proto
if (nodep->dpiOpenParent()) nodep->v3fatalSrc("DPI task should be parent or wrapper, not both");
UASSERT_OBJ(!nodep->dpiOpenParent(), nodep,
"DPI task should be parent or wrapper, not both");
}
else { // Parent or not open child, make wrapper
string dpiproto = dpiprotoName(nodep, rtnvarp);
@ -1066,7 +1067,8 @@ private:
}
if (nodep->dpiExport()) {
AstScopeName* snp = nodep->scopeNamep(); if (!snp) nodep->v3fatalSrc("Missing scoping context");
AstScopeName* snp = nodep->scopeNamep();
UASSERT_OBJ(snp, nodep, "Missing scoping context");
snp->dpiExport(true); // The AstScopeName is really a statement(ish) for tracking, not a function
snp->unlinkFrBack();
cfuncp->addInitsp(snp);
@ -1138,7 +1140,7 @@ private:
// Return node that must be visited, if any
// See also AstNode::addBeforeStmt; this predates that function
if (debug()>=9) { nodep->dumpTree(cout, "-newstmt:"); }
if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement");
UASSERT_OBJ(m_insStmtp, nodep, "Function not underneath a statement");
AstNode* visitp = NULL;
if (m_insMode == IM_BEFORE) {
// Add the whole thing before insertAt
@ -1153,7 +1155,7 @@ private:
else if (m_insMode == IM_WHILE_PRECOND) {
UINFO(5," IM_While_Precond "<<m_insStmtp<<endl);
AstWhile* whilep = VN_CAST(m_insStmtp, While);
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE");
whilep->addPrecondsp(newp);
visitp = newp;
}
@ -1184,11 +1186,11 @@ private:
m_scopep = NULL;
}
virtual void visit(AstNodeFTaskRef* nodep) {
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?");
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked?");
iterateIntoFTask(nodep->taskp()); // First, do hierarchical funcs
UINFO(4," FTask REF "<<nodep<<endl);
if (debug()>=9) { nodep->dumpTree(cout, "-inlfunc:"); }
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
UASSERT_OBJ(m_scopep, nodep, "func ref not under scope");
string namePrefix = ((VN_IS(nodep, FuncRef) ? "__Vfunc_":"__Vtask_")
+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++));
// Create output variable
@ -1209,7 +1211,7 @@ private:
// Replace the ref
AstNode* visitp = NULL;
if (VN_IS(nodep, FuncRef)) {
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function");
AstVarRef* outrefp = new AstVarRef(nodep->fileline(), outvscp, false);
nodep->replaceWith(outrefp);
// Insert new statements
@ -1349,7 +1351,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
typedef std::map<string,int> NameToIndex;
NameToIndex nameToIndex;
V3TaskConnects tconnects;
if (!nodep->taskp()) nodep->v3fatalSrc("unlinked");
UASSERT_OBJ(nodep->taskp(), nodep, "unlinked");
// Find ports
int tpinnum = 0;
@ -1374,7 +1376,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
bool reorganize = false;
for (AstNode* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
nextp = pinp->nextp();
AstArg* argp = VN_CAST(pinp, Arg); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
AstArg* argp = VN_CAST(pinp, Arg);
UASSERT_OBJ(argp, pinp, "Non-arg under ftask reference");
if (argp->name() != "") {
// By name
NameToIndex::iterator it = nameToIndex.find(argp->name());
@ -1460,7 +1463,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
while (nodep->pinsp()) nodep->pinsp()->unlinkFrBack(); // Must unlink each pin, not all pins linked together as one list
for (int i=0; i<tpinnum; ++i) {
AstArg* argp = tconnects[i].second;
if (!argp) nodep->v3fatalSrc("Lost argument in func conversion");
UASSERT_OBJ(argp, nodep, "Lost argument in func conversion");
nodep->addPinsp(argp);
}
}

View File

@ -131,7 +131,8 @@ public:
virtual FileLine* fileline() const { return nodep()->fileline(); }
TraceTraceVertex* duplicatep() const { return m_duplicatep; }
void duplicatep(TraceTraceVertex* dupp) {
if (duplicatep()) nodep()->v3fatalSrc("Assigning duplicatep() to already duplicated node");
UASSERT_OBJ(!duplicatep(), nodep(),
"Assigning duplicatep() to already duplicated node");
m_duplicatep = dupp;
}
};
@ -205,10 +206,9 @@ private:
if (TraceTraceVertex* vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) {
AstTraceInc* nodep = vvertexp->nodep();
if (nodep->valuep()) {
if (nodep->valuep()->backp() != nodep) {
nodep->v3fatalSrc("Trace duplicate back needs consistency,"
" so we can map duplicates back to TRACEINCs");
}
UASSERT_OBJ(nodep->valuep()->backp() == nodep, nodep,
"Trace duplicate back needs consistency,"
" so we can map duplicates back to TRACEINCs");
hashed.hash(nodep->valuep());
UINFO(8, " Hashed "<<std::hex<<hashed.nodeHash(nodep->valuep())
<<" "<<nodep<<endl);
@ -229,7 +229,7 @@ private:
if (dupit != hashed.end()) {
AstTraceInc* dupincp
= VN_CAST(hashed.iteratorNodep(dupit)->backp(), TraceInc);
if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type");
UASSERT_OBJ(dupincp, nodep, "Trace duplicate of wrong type");
TraceTraceVertex* dupvertexp
= dynamic_cast<TraceTraceVertex*>(dupincp->user1u().toGraphVertex());
UINFO(8," Orig "<<nodep<<endl);
@ -275,7 +275,8 @@ private:
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
TraceActivityVertex* actVtxp
= dynamic_cast<TraceActivityVertex*>(edgep->fromp());
if (!actVtxp) vvertexp->nodep()->v3fatalSrc("Tracing a node with FROM non activity");
UASSERT_OBJ(actVtxp, vvertexp->nodep(),
"Tracing a node with FROM non activity");
if (actVtxp->activityAlways()) {
alwaysEdgep = edgep;
break;
@ -438,7 +439,8 @@ private:
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
TraceActivityVertex* cfvertexp
= dynamic_cast<TraceActivityVertex*>(edgep->fromp());
if (!cfvertexp) vvertexp->nodep()->v3fatalSrc("Should have been function pointing to this trace");
UASSERT_OBJ(cfvertexp, vvertexp->nodep(),
"Should have been function pointing to this trace");
UINFO(9," Activity: "<<cfvertexp<<endl);
if (cfvertexp->activityAlways()) {
// If code 0, we always trace; ignore other codes
@ -550,7 +552,8 @@ private:
dupvertexp = dupvertexp->duplicatep();
UINFO(9," dupOf "<<cvtToHex(dupvertexp)<<" "<<cvtToHex(dupvertexp->nodep())
<<" "<<dupvertexp<<endl);
if (dupvertexp->duplicatep()) dupvertexp->nodep()->v3fatalSrc("Original node was marked as a duplicate");
UASSERT_OBJ(!dupvertexp->duplicatep(), dupvertexp->nodep(),
"Original node was marked as a duplicate");
}
if (dupvertexp != vvertexp) {
@ -644,7 +647,7 @@ private:
}
virtual void visit(AstTopScope* nodep) {
AstScope* scopep = nodep->scopep();
if (!scopep) nodep->v3fatalSrc("No scope found on top level");
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
m_highScopep = scopep;
iterateChildren(nodep);
}
@ -692,21 +695,21 @@ private:
}
virtual void visit(AstTraceInc* nodep) {
UINFO(8," TRACE "<<nodep<<endl);
if (m_finding) nodep->v3fatalSrc("Traces should have been removed in prev step.");
UASSERT_OBJ(!m_finding, nodep, "Traces should have been removed in prev step.");
nodep->unlinkFrBack();
V3GraphVertex* vertexp = new TraceTraceVertex(&m_graph, nodep);
nodep->user1p(vertexp);
if (!m_funcp || (!m_chgFuncp || !m_fullFuncp)) nodep->v3fatalSrc("Trace not under func");
UASSERT_OBJ(m_funcp && m_chgFuncp && m_fullFuncp, nodep, "Trace not under func");
m_tracep = nodep;
iterateChildren(nodep);
m_tracep = NULL;
}
virtual void visit(AstVarRef* nodep) {
if (m_tracep) {
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
if (nodep->lvalue()) nodep->v3fatalSrc("Lvalue in trace? Should be const.");
UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?");
UASSERT_OBJ(!nodep->lvalue(), nodep, "Lvalue in trace? Should be const.");
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
if (!varVtxp) {
varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep());
@ -720,7 +723,7 @@ private:
}
}
else if (m_funcp && m_finding && nodep->lvalue()) {
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?");
V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp);
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
if (varVtxp) { // else we're not tracing this signal

View File

@ -157,7 +157,7 @@ private:
// it uses spaces to separate hierarchy components.
m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name());
if (m_traShowname.substr(0, 4) == "TOP ") m_traShowname.replace(0, 4, "");
if (!m_initSubFuncp) nodep->v3fatalSrc("NULL");
UASSERT_OBJ(m_initSubFuncp, nodep, "NULL");
m_traVscp = nodep;
m_traValuep = NULL;

View File

@ -300,12 +300,12 @@ class TristatePinVisitor : public TristateBaseVisitor {
}
virtual void visit(AstArraySel* nodep) {
// Doesn't work because we'd set lvalue on the array index's var
if (m_lvalue) nodep->v3fatalSrc("ArraySel conversion to output, under tristate node");
UASSERT_OBJ(!m_lvalue, nodep, "ArraySel conversion to output, under tristate node");
iterateChildren(nodep);
}
virtual void visit(AstSliceSel* nodep) {
// Doesn't work because we'd set lvalue on the array index's var
if (m_lvalue) nodep->v3fatalSrc("SliceSel conversion to output, under tristate node");
UASSERT_OBJ(!m_lvalue, nodep, "SliceSel conversion to output, under tristate node");
iterateChildren(nodep);
}
virtual void visit(AstNode* nodep) {
@ -1155,7 +1155,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstVar* outModVarp = static_cast<AstVar*>(nodep->modVarp()->user4p());
if (!outModVarp) {
// At top, no need for __out as might be input only. Otherwise resolvable.
if (!m_modp->isTop()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(m_modp->isTop(), nodep, "Unlinked");
} else {
AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set
outpinp = new AstPin(nodep->fileline(),
@ -1305,7 +1305,8 @@ class TristateVisitor : public TristateBaseVisitor {
virtual void visit(AstNodeModule* nodep) {
UINFO(8, nodep<<endl);
if (m_graphing) nodep->v3fatalSrc("Modules under modules not supported"); // Lots of per-module state breaks
UASSERT_OBJ(!m_graphing, nodep,
"Modules under modules not supported"); // Lots of per-module state breaks
// Clear state
m_tgraph.clear();
m_unique = 0;

View File

@ -110,7 +110,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 = VN_CAST(prep->user2p(), If)) {
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
UASSERT_OBJ(!needDly, prep, "Should have already converted to non-delay");
AstNRelinker replaceHandle;
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
AstNode* newp = new AstLogAnd(condp->fileline(),
@ -285,7 +285,7 @@ private:
} else {
// Make a Vxrand variable
// We use the special XTEMP type so it doesn't break pure functions
if (!m_modp) nodep->v3fatalSrc("X number not under module");
UASSERT_OBJ(m_modp, nodep, "X number not under module");
string newvarname = (string("__Vxrand")
+cvtToStr(m_modp->varNumGetInc()));
AstVar* newvarp
@ -391,7 +391,7 @@ private:
// Find range of dtype we are selecting from
int declElements = -1;
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
UASSERT_OBJ(dtypep, nodep, "Select of non-selectable type");
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
declElements = adtypep->elementsConst();
} else {

View File

@ -107,16 +107,17 @@ private:
// Initial value check
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");
UASSERT_OBJ(!(initp->nextp() && initp->nextp()!=nodep), nodep,
"initial assignment shouldn't be a list");
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");
UASSERT_OBJ(!condp->nextp(), nodep, "conditional shouldn't be a list");
//
// Assignment of next value check
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");
UASSERT_OBJ(!incAssp->nextp(), nodep, "increment shouldn't be a list");
m_forVarp = VN_CAST(initAssp->lhsp(), VarRef)->varp();
m_forVscp = VN_CAST(initAssp->lhsp(), VarRef)->varScopep();
@ -190,10 +191,7 @@ private:
bool simulateTree(AstNode *nodep, const V3Number *loopValue,
AstNode *dtypep, V3Number &outNum) {
AstNode* clonep = nodep->cloneTree(true);
if (!clonep) {
nodep->v3fatalSrc("Failed to clone tree");
return false;
}
UASSERT_OBJ(clonep, nodep, "Failed to clone tree");
if (loopValue) {
m_varValuep = new AstConst(nodep->fileline(), *loopValue);
// Iteration requires a back, so put under temporary node

View File

@ -561,7 +561,7 @@ private:
// LSB is self-determined (IEEE 2012 11.5.1)
// We also use SELs to shorten a signed constant etc, in this case they are signed.
if (nodep->didWidth()) return;
if (!m_vup) nodep->v3fatalSrc("Select under an unexpected context");
UASSERT_OBJ(m_vup, nodep, "Select under an unexpected context");
if (m_vup->prelim()) {
if (debug()>=9) nodep->dumpTree(cout, "-selWidth: ");
userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT, PRELIM).p());
@ -576,7 +576,7 @@ private:
nodep->dtypeSetLogicBool(); return;
}
int width = nodep->widthConst();
if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel
UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel
if (VN_IS(nodep->lsbp(), Const)
&& nodep->msbConst() < nodep->lsbConst()) {
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
@ -952,7 +952,8 @@ private:
break;
case AstAttrType::DIM_DIMENSIONS:
case AstAttrType::DIM_UNPK_DIMENSIONS: {
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
"Unsized expression");
std::pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->dimensions(true);
int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS
? dim.second : (dim.first+dim.second));
@ -967,7 +968,8 @@ private:
case AstAttrType::DIM_LOW:
case AstAttrType::DIM_RIGHT:
case AstAttrType::DIM_SIZE: {
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
"Unsized expression");
std::pair<uint32_t,uint32_t> dim
= nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
uint32_t msbdim = dim.first+dim.second;
@ -977,7 +979,8 @@ private:
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
else { // Need a runtime lookup table. Yuk.
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
"Unsized expression");
AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim);
AstNode* dimp = nodep->dimp()->unlinkFrBack();
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
@ -1083,7 +1086,7 @@ private:
if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep()));
// Effectively nodep->dtypeFrom(nodep->dtypeSkipRefp());
// But might be recursive, so instead manually recurse into the referenced type
if (!nodep->defp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->defp(), nodep, "Unlinked");
nodep->dtypeFrom(nodep->defp());
userIterate(nodep->defp(), NULL);
nodep->widthFromSub(nodep->subDTypep());
@ -1129,7 +1132,7 @@ private:
// The cast may change signing, but we don't know the sign yet. Make it so.
// Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting.
AstBasicDType* basicp = nodep->dtypep()->basicp();
if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type");
UASSERT_OBJ(basicp, nodep, "Unimplemented: Casting non-simple data type");
// When implement more complicated types need to convert childDTypep to
// dtypep() not as a child
if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) {
@ -1162,7 +1165,8 @@ 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 (!VN_IS(nodep->rhsp(), Const)) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
UASSERT_OBJ(VN_IS(nodep->rhsp(), Const), nodep,
"Unsupported: Non-const cast of size");
//if (debug()) nodep->dumpTree(cout, " CastSizePre: ");
if (m_vup->prelim()) {
int width = VN_CAST(nodep->rhsp(), Const)->toSInt();
@ -1215,7 +1219,7 @@ private:
// with non-constant range gets size 1, not size 0. So use didWidth().
if (nodep->didWidth()) return;
if (nodep->doingWidth()) { // Early exit if have circular parameter definition
if (!nodep->valuep()) nodep->v3fatalSrc("circular, but without value");
UASSERT_OBJ(nodep->valuep(), nodep, "circular, but without value");
nodep->v3error("Variable's initial value is circular: "<<nodep->prettyName());
pushDeletep(nodep->valuep()->unlinkFrBack());
nodep->valuep(new AstConst(nodep->fileline(), AstConst::LogicTrue()));
@ -1227,7 +1231,7 @@ private:
// Make sure dtype is sized
if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep));
nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep()));
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var");
UASSERT_OBJ(nodep->dtypep(), nodep, "No dtype determined for var");
if (VN_IS(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
if (!(m_ftaskp && m_ftaskp->dpiImport())) {
nodep->v3error("Unsized/open arrays ('[]') are only supported in DPI imports");
@ -1328,7 +1332,7 @@ private:
// Note genvar's are also entered as integers
nodep->dtypeFrom(nodep->varp());
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
UASSERT_OBJ(nodep->widthMin(), nodep, "LHS var should be size complete");
}
//if (debug()>=9) nodep->dumpTree(cout, " VRout ");
if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) {
@ -1397,7 +1401,7 @@ private:
virtual void visit(AstEnumItem* nodep) {
UINFO(5," ENUMITEM "<<nodep<<endl);
AstNodeDType* vdtypep = m_vup->dtypep();
if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM");
UASSERT_OBJ(vdtypep, nodep, "ENUMITEM not under ENUM");
nodep->dtypep(vdtypep);
if (nodep->valuep()) { // else the value will be assigned sequentially
// Default type is int, but common to assign narrower values, so minwidth from value
@ -1411,11 +1415,11 @@ private:
if (!nodep->itemp()->didWidth()) {
// We need to do the whole enum en-mass
AstNode* enump = nodep->itemp();
if (!enump) nodep->v3fatalSrc("EnumItemRef not linked");
UASSERT_OBJ(enump, nodep, "EnumItemRef not linked");
for (; enump; enump=enump->backp()) {
if (VN_IS(enump, EnumDType)) break;
}
if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum");
UASSERT_OBJ(enump, nodep, "EnumItemRef can't deref back to an Enum");
userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked
}
nodep->dtypeFrom(nodep->itemp());
@ -1424,7 +1428,7 @@ private:
// InitArray has type of the array; children are array values
if (m_vup->prelim()) { // First stage evaluation
AstNodeDType* vdtypep = m_vup->dtypep();
if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor");
UASSERT_OBJ(vdtypep, nodep, "InitArray type not assigned by AstPattern/Var visitor");
nodep->dtypep(vdtypep);
if (AstNodeArrayDType* arrayp = VN_CAST(vdtypep->skipRefp(), NodeArrayDType)) {
userIterateChildren(nodep, WidthVP(arrayp->subDTypep(), BOTH).p());
@ -1602,7 +1606,8 @@ private:
if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF, BOTH).p());
}
// Find the fromp dtype - should be a class
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
"Unsized expression");
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL;
UINFO(9," from dt "<<fromDtp<<endl);
@ -1632,7 +1637,7 @@ private:
nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
}
if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const");
UASSERT_OBJ(newp, nodep, "Enum method (perhaps enum item) not const");
newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables
nodep->replaceWith(newp);
pushDeletep(nodep); VL_DANGLING(nodep);
@ -1665,7 +1670,7 @@ private:
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");
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
}
if (adtypep->itemsp()->width() > 64 || msbdim >= (1<<16)) {
@ -2053,10 +2058,11 @@ private:
}
virtual void visit(AstPatMember* nodep) {
AstNodeDType* vdtypep = m_vup->dtypeNullp();
if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor");
UASSERT_OBJ(vdtypep, nodep, "Pattern member type not assigned by AstPattern visitor");
nodep->dtypep(vdtypep);
UINFO(9," PATMEMBER "<<nodep<<endl);
if (nodep->lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed");
UASSERT_OBJ(!nodep->lhssp()->nextp(), nodep,
"PatMember value should be singular w/replicates removed");
// Need to propagate assignment type downwards, even on prelim
userIterateChildren(nodep, WidthVP(nodep->dtypep(), PRELIM).p());
iterateCheck(nodep, "Pattern value", nodep->lhssp(), ASSIGN, FINAL, vdtypep, EXTEND_LHS);
@ -2174,8 +2180,9 @@ private:
{
//if (debug()) nodep->dumpTree(cout, "- assin: ");
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p());
if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?");
if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?");
UASSERT_OBJ(nodep->lhsp()->dtypep(), nodep, "How can LHS be untyped?");
UASSERT_OBJ(nodep->lhsp()->dtypep()->widthSized(), nodep,
"How can LHS be unsized?");
nodep->dtypeFrom(nodep->lhsp());
//
// AstPattern needs to know the proposed data type of the lhs, so pass on the prelim
@ -2559,7 +2566,7 @@ private:
userIterateChildren(nodep, NULL);
if (nodep->fvarp()) {
m_funcp = VN_CAST(nodep, Func);
if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function");
UASSERT_OBJ(m_funcp, nodep, "FTask with function variable, but isn't a function");
nodep->dtypeFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep()
}
nodep->didWidth(true);
@ -2599,7 +2606,7 @@ private:
// For arguments, is assignment-like context; see IEEE rules in AstNodeAssign
// Function hasn't been widthed, so make it so.
UINFO(5, " FTASKREF "<<nodep<<endl);
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked");
if (nodep->didWidth()) return;
userIterate(nodep->taskp(), NULL);
//
@ -2737,8 +2744,8 @@ private:
}
virtual void visit(AstNode* nodep) {
// Default: Just iterate
if (m_vup) nodep->v3fatalSrc("Visit function missing? Widthed expectation for this node: "
<<nodep);
UASSERT_OBJ(!m_vup, nodep,
"Visit function missing? Widthed expectation for this node: "<<nodep);
userIterateChildren(nodep, NULL);
}
@ -2799,7 +2806,7 @@ private:
// LHS is self-determined
// Width: 1 bit out
// Sign: unsigned out (11.8.1)
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
iterateCheckBool(nodep, "LHS", nodep->op1p(), BOTH);
nodep->dtypeSetLogicBool();
@ -2854,7 +2861,7 @@ private:
// TODO: chandle/class handle/iface handle: WildEq/WildNeq same as Eq/Neq
// TODO: chandle/class handle/iface handle only allowed to self-compare or against null
// TODO: chandle/class handle/iface handle no relational compares
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT, PRELIM).p());
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p());
@ -2895,7 +2902,7 @@ private:
// Real if and only if real_allow set
// IEEE, 11.4.4: relational compares (<,>,<=,>=,==,===,!=,!==) use
// "zero padding" on unsigned
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
if (m_vup->prelim()) {
// See similar handling in visit_cmp_eq_gt where created
iterateCheckReal(nodep, "LHS", nodep->lhsp(), BOTH);
@ -2908,7 +2915,7 @@ private:
// Widths: 1 bit out, lhs width == rhs width
// String compare (not output)
// Real if and only if real_allow set
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
if (m_vup->prelim()) {
// See similar handling in visit_cmp_eq_gt where created
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
@ -2919,7 +2926,7 @@ private:
void visit_Os32_string(AstNodeUniop* nodep) {
// CALLER: LenN
// Widths: 32 bit out
if (!nodep->lhsp()) nodep->v3fatalSrc("For unary ops only!");
UASSERT_OBJ(nodep->lhsp(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
// See similar handling in visit_cmp_eq_gt where created
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
@ -2933,7 +2940,7 @@ private:
// Signed: From lhs
// IEEE-2012 Table 11-21:
// Widths: out width = lhs width
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT, PRELIM).p());
if (!real_ok) checkCvtUS(nodep->lhsp());
@ -2968,7 +2975,7 @@ private:
// Width: Returns packed array, of size $bits(expression).
// Sign: Output sign is as specified by operation
// TODO: Type: Two-state if input is two-state, else four-state
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
checkCvtUS(nodep->lhsp());
@ -3039,7 +3046,7 @@ private:
// Signed: if lhs & rhs signed
// IEEE-2012 Table 11-21:
// Width: max(LHS, RHS)
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
// If errors are off, we need to follow the spec; thus we really need to do the max()
// because the rhs could be larger, and we need to have proper editing to get the widths
// to be the same for our operations.
@ -3152,12 +3159,15 @@ private:
bool widthBad(AstNode* nodep, AstNodeDType* expDTypep) {
int expWidth = expDTypep->width();
int expWidthMin = expDTypep->widthMin();
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
<<" has no dtype?? Missing Visitor func?");
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
UASSERT_OBJ(nodep->dtypep(), nodep,
"Under node "<<nodep->prettyTypeName()
<<" has no dtype?? Missing Visitor func?");
UASSERT_OBJ(nodep->width() != 0, nodep,
"Under node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
UASSERT_OBJ(expWidth != 0, nodep,
"Node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
if (expWidthMin==0) expWidthMin = expWidth;
if (nodep->dtypep()->width() == expWidth) return false;
if (nodep->dtypep()->widthSized() && nodep->width() != expWidthMin) return true;
@ -3296,7 +3306,7 @@ private:
return node1p->skipRefp()->similarDType(node2p->skipRefp());
}
void iterateCheckFileDesc(AstNode* nodep, AstNode* underp, Stage stage) {
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
UASSERT_OBJ(stage == BOTH, nodep, "Bad call");
// underp may change as a result of replacement
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
AstNodeDType* expDTypep = underp->findUInt32DType();
@ -3346,8 +3356,8 @@ private:
// Coerce child to any sized-number data type; child is self-determined
// i.e. isolated from expected type.
// e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs)
if (determ != SELF) nodep->v3fatalSrc("Bad call");
if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call");
UASSERT_OBJ(determ == SELF, nodep, "Bad call");
UASSERT_OBJ(stage == FINAL || stage == BOTH, nodep, "Bad call");
// underp may change as a result of replacement
if (stage & PRELIM) underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
underp = checkCvtUS(underp);
@ -3359,7 +3369,7 @@ private:
AstNode* rhsp, Stage stage, AstNodeDType* lhsDTypep) {
// Check using assignment-like context rules
//if (debug()) nodep->dumpTree(cout, "-checkass: ");
if (stage != FINAL) nodep->v3fatalSrc("Bad width call");
UASSERT_OBJ(stage == FINAL, nodep, "Bad width call");
// We iterate and size the RHS based on the result of RHS evaluation
bool lhsStream = (VN_IS(nodep, NodeAssign)
&& VN_IS(VN_CAST(nodep, NodeAssign)->lhsp(), NodeStream));
@ -3370,14 +3380,16 @@ private:
}
void iterateCheckBool(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once
UASSERT_OBJ(stage == BOTH, nodep,
"Bad call"); // Booleans always self-determined so do BOTH at once
// Underp is used in a self-determined but boolean context, reduce a
// multibit number to one bit
// stage is always BOTH so not passed as argument
// underp may change as a result of replacement
if (!underp) nodep->v3fatalSrc("Node has no type");
UASSERT_OBJ(underp, nodep, "Node has no type");
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, BOTH).p());
if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
UASSERT_OBJ(underp && underp->dtypep(), nodep,
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
//
// For DOUBLE under a logical op, add implied test against zero, never a warning
if (underp && underp->isDouble()) {
@ -3417,8 +3429,9 @@ private:
// Perform data type check on underp, which is underneath nodep used for error reporting
// Returns the new underp
// Conversion to/from doubles and integers are before iterating.
if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck");
if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
UASSERT_OBJ(stage == FINAL, nodep, "Bad state to iterateCheck");
UASSERT_OBJ(underp && underp->dtypep(), nodep,
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
if (expDTypep == underp->dtypep()) { // Perfect
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p());
} else if (expDTypep->isDouble() && underp->isDouble()) { // Also good
@ -3757,7 +3770,7 @@ private:
// DTypes at parse time get added as a childDType to some node types such as AstVars.
// We move them to global scope, so removing/changing a variable won't lose the dtype.
AstNodeDType* dtnodep = nodep->getChildDTypep();
if (!dtnodep) nodep->v3fatalSrc("Caller should check for NULL before calling moveChild");
UASSERT_OBJ(dtnodep, nodep, "Caller should check for NULL before calling moveChild");
UINFO(9,"moveChildDTypeEdit "<<dtnodep<<endl);
dtnodep->unlinkFrBack(); // Make non-child
v3Global.rootp()->typeTablep()->addTypesp(dtnodep);
@ -3773,7 +3786,7 @@ private:
// Alternative is to have WidthVP return information.
// or have a call outside of normal visitor land.
// or have a m_return type (but need to return if width called multiple times)
if (!nodep) parentp->v3fatalSrc("Null dtype when widthing dtype");
UASSERT_OBJ(nodep, parentp, "Null dtype when widthing dtype");
userIterate(nodep, NULL);
return nodep;
}
@ -3924,7 +3937,7 @@ private:
}
// Find valid values and populate
if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items");
UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items");
std::vector<AstNode*> values;
values.resize(msbdim+1);
for (unsigned i=0; i<(msbdim+1); ++i) {
@ -3937,7 +3950,7 @@ private:
for (AstEnumItem* itemp = firstp; itemp;) {
AstEnumItem* nextp = VN_CAST(itemp->nextp(), EnumItem);
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
uint32_t i = vconstp->toUInt();
if (attrType == AstAttrType::ENUM_NAME) {
values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name());
@ -3989,7 +4002,8 @@ private:
UINFO(4,"Replicate openarray function "<<nodep->taskp()<<endl);
AstNodeFTask* oldTaskp = nodep->taskp();
oldTaskp->dpiOpenParentInc();
if (oldTaskp->dpiOpenChild()) oldTaskp->v3fatalSrc("DPI task should be parent or child, not both");
UASSERT_OBJ(!oldTaskp->dpiOpenChild(), oldTaskp,
"DPI task should be parent or child, not both");
AstNodeFTask* newTaskp = oldTaskp->cloneTree(false);
newTaskp->dpiOpenChild(true);
newTaskp->dpiOpenParentClear();

View File

@ -115,7 +115,7 @@ private:
}
// VISITORS
virtual void visit(AstConst* nodep) {
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype");
UASSERT_OBJ(nodep->dtypep(), nodep, "No dtype");
iterate(nodep->dtypep()); // Do datatype first
if (AstConst* newp = newIfConstCommitSize(nodep)) {
nodep->replaceWith(newp);

View File

@ -84,7 +84,7 @@ private:
}
break;
}
if (!basefromp || !basefromp->dtypep()) nodep->v3fatalSrc("Select with no from dtype");
UASSERT_OBJ(basefromp && basefromp->dtypep(), nodep, "Select with no from dtype");
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
AstNode* errp = ddtypep;
UINFO(9," fromData.ddtypep = "<<ddtypep<<endl);
@ -96,10 +96,10 @@ private:
}
else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
if (adtypep->isRanged()) {
if (adtypep->rangep()
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|| !VN_IS(adtypep->rangep()->lsbp(), Const)))
nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
UASSERT_OBJ(!(adtypep->rangep()
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|| !VN_IS(adtypep->rangep()->lsbp(), Const))),
nodep, "Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
fromRange = adtypep->declRange();
} else {
nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is "
@ -227,11 +227,10 @@ private:
subp = newSubNeg(subp, fromRange.lo());
}
}
if (VL_UNCOVERABLE(!fromRange.elements()
|| (adtypep->width() % fromRange.elements())!=0)) {
adtypep->v3fatalSrc("Array extraction with width miscomputed "
<<adtypep->width()<<"/"<<fromRange.elements());
}
UASSERT_OBJ(!(!fromRange.elements()
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
"Array extraction with width miscomputed "
<<adtypep->width()<<"/"<<fromRange.elements());
int elwidth = adtypep->width() / fromRange.elements();
AstSel* newp
= new AstSel(nodep->fileline(),
@ -318,11 +317,10 @@ private:
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
// SELEXTRACT(array, msb, lsb) -> SEL(array,
// lsb*width-of-subindex, width-of-subindex*(msb-lsb))
if (VL_UNCOVERABLE(!fromRange.elements()
|| (adtypep->width() % fromRange.elements())!=0)) {
adtypep->v3fatalSrc("Array extraction with width miscomputed "
<<adtypep->width()<<"/"<<fromRange.elements());
}
UASSERT_OBJ(!(!fromRange.elements()
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
"Array extraction with width miscomputed "
<<adtypep->width()<<"/"<<fromRange.elements());
if (fromRange.littleEndian()) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
@ -344,7 +342,7 @@ private:
newp->declElWidth(elwidth);
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
//if (debug()>=9) newp->dumpTree(cout, "--EXTBTn: ");
if (newp->widthMin() != newp->widthConst()) nodep->v3fatalSrc("Width mismatch");
UASSERT_OBJ(newp->widthMin() == newp->widthConst(), nodep, "Width mismatch");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (VN_IS(ddtypep, BasicDType)) {

View File

@ -1945,7 +1945,7 @@ 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 = VN_CAST($9, Begin);
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
UASSERT_OBJ(!($9 && !lowerBegp), $9, "Child of GENFOR should have been begin");
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
AstNode* lowerNoBegp = lowerBegp->stmtsp();
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();