Add internal assertion that VarScopes properly formed.

This commit is contained in:
Wilson Snyder 2020-11-14 16:13:06 -05:00
parent c64cc989f0
commit e74cc32f2d
4 changed files with 23 additions and 0 deletions

View File

@ -238,6 +238,8 @@ public:
// Broken state, as a visitor of each AstNode
class BrokenCheckVisitor : public AstNVisitor {
bool m_inScope = false; // Under AstScope
private:
static void checkWidthMin(const AstNode* nodep) {
UASSERT_OBJ(nodep->width() == nodep->widthMin()
@ -278,6 +280,22 @@ private:
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->access().isWriteOrRW()),
nodep, "Assignment LHS is not an lvalue");
}
virtual void visit(AstScope* nodep) override {
VL_RESTORER(m_inScope);
{
m_inScope = true;
processAndIterate(nodep);
}
}
virtual void visit(AstNodeVarRef* nodep) override {
processAndIterate(nodep);
// m_inScope because some Vars have initial variable references without scopes
// This might false fire with some debug flags, as not certain we don't have temporary
// clear varScopep's during some an infrequent dump just before we re-LinkDot.
UASSERT_OBJ(
!(v3Global.assertScoped() && m_inScope && nodep->varp() && !nodep->varScopep()), nodep,
"VarRef missing VarScope pointer");
}
virtual void visit(AstNode* nodep) override {
// Process not just iterate
processAndIterate(nodep);

View File

@ -304,6 +304,7 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
v3Global.assertScoped(false);
{ DescopeVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("descope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -95,6 +95,7 @@ class V3Global {
int m_debugFileNumber = 0; // Number to append to debug files created
bool m_assertDTypesResolved = false; // Tree should have dtypep()'s
bool m_assertScoped = false; // Tree is scoped
bool m_constRemoveXs = false; // Const needs to strip any Xs
bool m_needHeavy = false; // Need verilated_heavy.h include
bool m_needTraceDumper = false; // Need __Vm_dumperp in symbols
@ -125,6 +126,7 @@ public:
AstNetlist* rootp() const { return m_rootp; }
VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; }
bool assertDTypesResolved() const { return m_assertDTypesResolved; }
bool assertScoped() const { return m_assertScoped; }
// METHODS
void readFiles();
@ -132,6 +134,7 @@ public:
static void dumpCheckGlobalTree(const string& stagename, int newNumber = 0,
bool doDump = true);
void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; }
void assertScoped(bool flag) { m_assertScoped = flag; }
void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
bool constRemoveXs() const { return m_constRemoveXs; }
void constRemoveXs(bool flag) { m_constRemoveXs = flag; }

View File

@ -2947,6 +2947,7 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
// Well after the initial link when we're ready to operate on the flat design,
// process AstScope's. This needs to be separate pass after whole hierarchy graph created.
LinkDotScopeVisitor visitors(rootp, &state);
v3Global.assertScoped(true);
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));
}