From 45e8ed6b49465fc7844bc5a7b697218fc5c19796 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 24 Mar 2009 09:22:58 -0400 Subject: [PATCH] Internals: Cleanup what symbol lookups need to recurse up vs not. --- src/V3Link.cpp | 71 +++++++++++++++++---------------------------- src/V3LinkCells.cpp | 12 ++++---- src/V3LinkDot.cpp | 2 +- src/V3SymTable.h | 10 ++++--- 4 files changed, 41 insertions(+), 54 deletions(-) diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 9176d0360..f7ac5d750 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -101,7 +101,7 @@ private: void linkVarName (AstVarRef* nodep) { if (!nodep->varp()) { - AstVar* varp = m_curVarsp->findIdName(nodep->name())->castVar(); + AstVar* varp = m_curVarsp->findIdUpward(nodep->name())->castVar(); nodep->varp(varp); } } @@ -122,19 +122,19 @@ private: return out; } - void checkDuplicate(AstNode* nodep, AstNode* foundp) { - // Check if there's a duplicate and report error if so - V3SymTable* nodeSymsp = (V3SymTable*)nodep->user3p(); - V3SymTable* foundSymsp = (V3SymTable*)foundp->user3p(); - // nodeSymsp may not have been set yet because it wasn't inserted yet, - // if so, pretend for a moment it is inserted right here. - if (!nodeSymsp) nodeSymsp = m_curVarsp; + void findAndInsertAndCheck(AstNode* nodep, const string& name) { + // Lookup the given name under current symbol table + // Insert if not found + // Report error if there's a duplicate // - if (nodep==foundp) { // Good. - } else if ((nodep->castBegin() || foundp->castBegin()) - && nodeSymsp != foundSymsp) { - // Conflicts with begin at *different* level. Thus it isn't really a duplicate - // if "foo" is under a block called "foo" - it's "foo.foo"; that's fine. + // Note we only check for conflicts at the same level; it's ok if one block hides another + // We also wouldn't want to not insert it even though it's lower down + AstNode* foundp = m_curVarsp->findIdFlat(name); + if (!foundp) { + symsInsert(nodep->name(), nodep); + foundp = nodep; + } else if (nodep==foundp) { // Already inserted. + // Good. } else if ((nodep->castBegin() || foundp->castBegin()) && m_inGenerate) { // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks @@ -222,14 +222,14 @@ private: nodep->trace(false); } // Find under either a task or the module's vars - AstNode* findidp = m_curVarsp->findIdName(nodep->name()); - AstVar* findvarp = findidp->castVar(); + AstNode* foundp = m_curVarsp->findIdUpward(nodep->name()); + AstVar* findvarp = foundp->castVar(); bool ins=false; - if (!findidp) { + if (!foundp) { ins=true; } else if (!findvarp) { nodep->v3error("Unsupported in C: Variable has same name as " - <prettyName()); + <prettyName()); } else if (findvarp != nodep) { UINFO(4,"DupVar: "<user3p() == m_curVarsp) { // Only when on same level @@ -313,12 +313,7 @@ private: } m_curVarsp = upperVarsp; if (m_idState==ID_FIND) { - AstNode* findidp = m_curVarsp->findIdName(nodep->name()); - if (!findidp) { - symsInsert(nodep->name(), nodep); - } else { - checkDuplicate(nodep,findidp); - } + findAndInsertAndCheck(nodep, nodep->name()); } } virtual void visit(AstBegin* nodep, AstNUser*) { @@ -334,14 +329,7 @@ private: } // Check naming (we don't really care, but some tools do, so better to warn) if (m_idState==ID_FIND) { - // Note we only check for conflicts at the same level; it's ok if one block hides another - // We also wouldn't want to not insert it even though it's lower down - AstNode* foundp = m_curVarsp->findIdNameThisLevel(nodep->name()); - if (!foundp) { - symsInsert(nodep->name(), nodep); - } else { - checkDuplicate(nodep, foundp); - } + findAndInsertAndCheck(nodep, nodep->name()); } // Recurse int oldNum = m_beginNum; @@ -358,7 +346,7 @@ private: // NodeFTaskRef: Resolve its reference if (m_idState==ID_RESOLVE && !nodep->taskp()) { if (nodep->dotted() == "") { - AstNodeFTask* taskp = m_curVarsp->findIdName(nodep->name())->castNodeFTask(); + AstNodeFTask* taskp = m_curVarsp->findIdUpward(nodep->name())->castNodeFTask(); if (!taskp) { nodep->v3error("Can't find definition of task/function: "<prettyName()); } nodep->taskp(taskp); } @@ -370,12 +358,7 @@ private: // Cell: Resolve its filename. If necessary, parse it. if (m_idState==ID_FIND) { // Add to list of all cells, for error checking and defparam's - AstNode* findidp = m_curVarsp->findIdName(nodep->name()); - if (!findidp) { - symsInsert(nodep->name(), nodep); - } else { - checkDuplicate(nodep, findidp); - } + findAndInsertAndCheck(nodep, nodep->name()); } if (!nodep->modp()) { nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out @@ -399,11 +382,11 @@ private: if (m_idState==ID_PARAM) { // Need to set pin numbers after varnames are created // But before we do the final resolution based on names - AstVar* refp = m_curVarsp->findIdName(nodep->name())->castVar(); + AstVar* refp = m_curVarsp->findIdFlat(nodep->name())->castVar(); if (!refp) { nodep->v3error("Input/output/inout declaration not found for port: "<prettyName()); } else if (!refp->isIO()) { - nodep->v3error("Pin is not a in/out/inout: "<prettyName()); + nodep->v3error("Pin is not an in/out/inout: "<prettyName()); } else { symsInsert("__pinNumber"+cvtToStr(nodep->pinNum()), refp); refp->user2(true); @@ -433,11 +416,11 @@ private: // Pin: Link to submodule's pin if (!m_cellVarsp) nodep->v3fatalSrc("Pin not under cell?\n"); if (m_idState==ID_RESOLVE && !nodep->modVarp()) { - AstVar* refp = m_cellVarsp->findIdName(nodep->name())->castVar(); + AstVar* refp = m_cellVarsp->findIdFlat(nodep->name())->castVar(); if (!refp) { nodep->v3error("Pin not found: "<prettyName()); } else if (!refp->isIO() && !refp->isParam()) { - nodep->v3error("Pin is not a in/out/inout/param: "<prettyName()); + nodep->v3error("Pin is not an in/out/inout/param: "<prettyName()); } else { nodep->modVarp(refp); } @@ -463,8 +446,8 @@ private: virtual void visit(AstDefParam* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_idState==ID_PARAM) { - AstNode* findidp = m_curVarsp->findIdName(nodep->path()); - AstCell* cellp = findidp->castCell(); + AstNode* foundp = m_curVarsp->findIdUpward(nodep->path()); + AstCell* cellp = foundp->castCell(); if (!cellp) { nodep->v3error("In defparam, cell "<path()<<" never declared"); } else { diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 9d98240bd..12a851f0b 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -144,7 +144,9 @@ private: // Cell: Resolve its filename. If necessary, parse it. if (!nodep->modp()) { UINFO(4,"Link Cell: "<modName())->castModule(); + // Use findIdUpward instead of findIdFlat; it doesn't matter for now + // but we might support modules-under-modules someday. + AstModule* modp = m_mods.findIdUpward(nodep->modName())->castModule(); if (!modp) { // Read-subfile V3Read reader (v3Global.rootp()); @@ -153,7 +155,7 @@ private: // We've read new modules, grab new pointers to their names readModNames(); // Check again - modp = m_mods.findIdName(nodep->modName())->castModule(); + modp = m_mods.findIdUpward(nodep->modName())->castModule(); if (!modp) { nodep->v3error("Can't resolve module reference: "<modName()); } @@ -171,7 +173,7 @@ private: V3SymTable ports; // Symbol table of all connected port names for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells"); - if (!ports.findIdName(pinp->name())) { + if (!ports.findIdFlat(pinp->name())) { ports.insert(pinp->name(), pinp); } } @@ -179,7 +181,7 @@ private: // and it's easier to do it now than in V3Link when we'd need to repeat steps. for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) { if (AstPort* portp = portnodep->castPort()) { - if (!ports.findIdName(portp->name())) { + if (!ports.findIdFlat(portp->name())) { UINFO(9," need PORT "<fileline(),0,portp->name(), @@ -214,7 +216,7 @@ private: void readModNames() { // Look at all modules, and store pointers to all module names for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) { - AstNode* foundp = m_mods.findIdName(nodep->name()); + AstNode* foundp = m_mods.findIdUpward(nodep->name()); if (foundp && foundp != nodep) { nodep->v3error("Duplicate declaration of module: "<prettyName()); foundp->v3error("... Location of original declaration"); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index fe2914b7b..553a6f16f 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -360,7 +360,7 @@ public: <<((cellVxp->symPrefix()=="") ? "" : cellVxp->symPrefix()+dotname) <<" at "<syms().findIdName(cellVxp->symPrefix() + dotname); // Might be NULL + AstNode* nodep = cellVxp->syms().findIdFlat(cellVxp->symPrefix() + dotname); // Might be NULL if (!nodep) baddot = dotname; return nodep; } diff --git a/src/V3SymTable.h b/src/V3SymTable.h index 223f6a85f..207581813 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -56,18 +56,20 @@ class V3SymTable : public AstNUser { m_idNameMap.insert(make_pair(name, nodep)); } } - AstNode* findIdNameThisLevel(const string& name) { + AstNode* findIdFlat(const string& name) { + // Find identifier without looking upward through symbol hierarchy //UINFO(9, " SymFind "<second); return NULL; } - AstNode* findIdName(const string& name) { + AstNode* findIdUpward(const string& name) { + // Find identifier looking upward through symbol hierarchy // First, scan this begin/end block or module for the name - if (AstNode* nodep = findIdNameThisLevel(name)) return nodep; + if (AstNode* nodep = findIdFlat(name)) return nodep; // Then scan the upper begin/end block or module for the name - if (m_upperp) return m_upperp->findIdName(name); + if (m_upperp) return m_upperp->findIdUpward(name); return NULL; } };