diff --git a/Changes b/Changes index bfb5c7cdc..d013f6335 100644 --- a/Changes +++ b/Changes @@ -19,7 +19,7 @@ indicates the contributor was also the author of the fix; Thanks! *** Add PINMISSING and PINNOCONNECT lint checks. -*** Add --converge-limit option. [Holger Waechtler] +*** Add --converge-limit option. *** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett] @@ -39,7 +39,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix loop error message to report line, bug513. [Jeremy Bennett] -**** Fix false UNUSED warning on file system calls. [Holger Waechtler] +**** Fix false UNUSED warning on file system calls. **** Fix GCC 4.7.0 compile warnings, bug530. [Jeremy Bennett] diff --git a/src/V3Case.cpp b/src/V3Case.cpp index d5b37311f..3a5304bb6 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -196,7 +196,7 @@ private: } } } - // Defaults were moved to last in the caseitem list by V3Link + // Defaults were moved to last in the caseitem list by V3LinkDot if (itemp->isDefault()) { // Case statement's default... Fill the table for (uint32_t i=0; i<(1UL<modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) { if (AstPort* portp = portnodep->castPort()) { if (ports.find(portp->name()) == ports.end() diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 3d43917e6..9d0f6ac52 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -95,7 +95,7 @@ public: // METHODS private: - VSymEnt* findSubcell(VSymEnt* symp, const string& name, const string& altname) { + VSymEnt* findWithAltFallback(VSymEnt* symp, const string& name, const string& altname) { VSymEnt* findp = symp->findIdFallback(name); if (findp) return findp; findp = symp->findIdFallback(altname); @@ -169,12 +169,12 @@ public: bool existsModScope(AstNodeModule* nodep) { return nodep->user1p()!=NULL; } - VSymEnt* findModScope(AstNodeModule* nodep) { + VSymEnt* getNodeSym(AstNodeModule* nodep) { VSymEnt* symp = nodep->user1p()->castSymEnt(); if (!symp) nodep->v3fatalSrc("Module never assigned a symbol entry?"); return symp; } - VSymEnt* findScopeSym(AstScope* nodep) { + VSymEnt* getScopeSym(AstScope* nodep) { NameScopeMap::iterator iter = m_nameScopeMap.find(nodep->name()); if (iter == m_nameScopeMap.end()) { nodep->v3fatalSrc("Scope never assigned a symbol entry?"); @@ -225,7 +225,7 @@ public: // Check this module - subcellnames AstCell* cellp = cellSymp->nodep()->castCell(); // Replicated below AstCellInline* inlinep = cellSymp->nodep()->castCellInline(); // Replicated below - if (VSymEnt* findSymp = findSubcell(cellSymp, ident, altIdent)) { + if (VSymEnt* findSymp = findWithAltFallback(cellSymp, ident, altIdent)) { cellSymp = findSymp; } // Check this module - cur modname @@ -243,7 +243,7 @@ public: || (inlinep && inlinep->origModName() == ident)) { break; } - else if (VSymEnt* findSymp = findSubcell(cellSymp, ident, altIdent)) { + else if (VSymEnt* findSymp = findWithAltFallback(cellSymp, ident, altIdent)) { cellSymp = findSymp; break; } @@ -252,7 +252,7 @@ public: if (!cellSymp) return NULL; // Not found } } else { // Searching for middle submodule, must be a cell name - if (VSymEnt* findSymp = findSubcell(cellSymp, ident, altIdent)) { + if (VSymEnt* findSymp = findWithAltFallback(cellSymp, ident, altIdent)) { cellSymp = findSymp; } else { return NULL; // Not found @@ -263,11 +263,11 @@ public: return cellSymp; } - AstNode* findSym(VSymEnt* cellSymp, const string& dotname, string& baddot) { + AstNode* findSymPrefixed(VSymEnt* cellSymp, const string& dotname, string& baddot) { // Find symbol in given point in hierarchy // For simplicity cellSymp may be passed NULL result from findDotted if (!cellSymp) return NULL; - UINFO(8,"\t\tfindSym "<symPrefix()=="") ? "" : " as ") <<((cellSymp->symPrefix()=="") ? "" : cellSymp->symPrefix()+dotname) <<" at "<insertTopCell(topmodp, m_scope); - m_inlineSymp = m_cellSymp; + m_curSymp = m_modSymp = m_statep->insertTopCell(topmodp, m_scope); { topmodp->accept(*this); } m_scope = ""; - m_cellSymp = NULL; - m_inlineSymp = m_cellSymp; + m_curSymp = m_modSymp = NULL; } } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Called on top module from Netlist, other modules from the cell creating them, // and packages UINFO(8," "<iterateChildren(*this); // Recurse in, preserving state string oldscope = m_scope; AstBegin* oldbeginp = m_beginp; - VSymEnt* oldSymp = m_cellSymp; - VSymEnt* oldInlineSymp = m_inlineSymp; + VSymEnt* oldModSymp = m_modSymp; + VSymEnt* oldCurSymp = m_curSymp; // Where do we add it? - VSymEnt* aboveSymp = m_inlineSymp; + VSymEnt* aboveSymp = m_curSymp; string origname = AstNode::dedotName(nodep->name()); string::size_type pos; if ((pos = origname.rfind(".")) != string::npos) { @@ -355,19 +353,18 @@ private: } { m_scope = m_scope+"."+nodep->name(); - m_cellSymp = m_statep->insertCell(aboveSymp, m_cellSymp, nodep, m_scope); - m_inlineSymp = m_cellSymp; + m_curSymp = m_modSymp = m_statep->insertCell(aboveSymp, m_modSymp, nodep, m_scope); m_beginp = NULL; if (nodep->modp()) nodep->modp()->accept(*this); } m_scope = oldscope; m_beginp = oldbeginp; - m_cellSymp = oldSymp; - m_inlineSymp = oldInlineSymp; + m_modSymp = oldModSymp; + m_curSymp = oldCurSymp; } virtual void visit(AstCellInline* nodep, AstNUser*) { UINFO(5," CELLINLINE under "<name(); string::size_type pos; @@ -378,29 +375,29 @@ private: VSymEnt* okSymp; aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp); if (!aboveSymp) nodep->v3fatalSrc("Can't find cellinline insertion point at '"<prettyName()); - m_statep->insertInline(aboveSymp, m_cellSymp, nodep, ident); + m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident); } else { // No __DOT__, just directly underneath - m_statep->insertInline(aboveSymp, m_cellSymp, nodep, nodep->name()); + m_statep->insertInline(aboveSymp, m_modSymp, nodep, nodep->name()); } } virtual void visit(AstBegin* nodep, AstNUser*) { UINFO(5," "<insertBegin(m_inlineSymp, m_cellSymp, nodep); + m_curSymp = m_statep->insertBegin(m_curSymp, m_modSymp, nodep); nodep->stmtsp()->iterateAndNext(*this); } - m_inlineSymp = oldSymp; + m_curSymp = oldSymp; m_beginp = oldbegin; // nodep->flatsp()->iterateAndNext(*this); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { if (!m_beginp) { // For now, we don't support xrefs into functions inside begin blocks - m_statep->insertSym(m_cellSymp, nodep->name(), nodep); + m_statep->insertSym(m_modSymp, nodep->name(), nodep); } // No recursion, we don't want to pick up variables } @@ -408,7 +405,7 @@ private: if (!m_statep->forScopeCreation() && !m_beginp // For now, we don't support xrefs into begin blocks && !nodep->isFuncLocal()) { - m_statep->insertSym(m_cellSymp, nodep->name(), nodep); + m_statep->insertSym(m_modSymp, nodep->name(), nodep); } else { UINFO(9," Not allowing dot refs to: "<forScopeCreation()) v3fatalSrc("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_cellSymp = m_statep->findScopeSym(nodep); + m_modSymp = m_statep->getScopeSym(nodep); nodep->iterateChildren(*this); - m_cellSymp = NULL; + m_modSymp = NULL; } virtual void visit(AstVarScope* nodep, AstNUser*) { if (!nodep->varp()->isFuncLocal()) { - m_statep->insertSym(m_cellSymp, nodep->varp()->name(), nodep); + m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep); } } virtual void visit(AstNodeFTask* nodep, AstNUser*) { - m_statep->insertSym(m_cellSymp, nodep->name(), nodep); + m_statep->insertSym(m_modSymp, nodep->name(), nodep); // No recursion, we don't want to pick up variables } virtual void visit(AstAssignAlias* nodep, AstNUser*) { @@ -494,7 +490,7 @@ public: // CONSTUCTORS LinkDotScopeVisitor(AstNetlist* rootp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); @@ -508,7 +504,7 @@ class LinkDotResolveVisitor : public AstNVisitor { private: // STATE LinkDotState* m_statep; // State, including dotted symbol table - VSymEnt* m_cellSymp; // SymEnt for current module + VSymEnt* m_modSymp; // SymEnt for current module int debug() { return LinkDotState::debug(); } @@ -519,18 +515,18 @@ private: UINFO(8," "<existsModScope(nodep)) { UINFO(5,"Dead module for "<findModScope(nodep); + m_modSymp = m_statep->getNodeSym(nodep); } nodep->iterateChildren(*this); - m_cellSymp = NULL; + m_modSymp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(8," "<findScopeSym(nodep); + m_modSymp = m_statep->getScopeSym(nodep); nodep->iterateChildren(*this); - m_cellSymp = NULL; + m_modSymp = NULL; } virtual void visit(AstCellInline* nodep, AstNUser*) { if (m_statep->forScopeCreation()) { @@ -542,13 +538,13 @@ private: // We always link even if varp() is set, because the module we choose may change // due to creating new modules, flattening, etc. UINFO(8," "<varp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later. } else { string baddot; VSymEnt* okSymp; - VSymEnt* dotSymp = m_cellSymp; // Start search at current scope + VSymEnt* dotSymp = m_modSymp; // Start search at current scope if (nodep->inlinedDots()!="") { // Correct for current scope string inl = AstNode::dedotName(nodep->inlinedDots()); dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp); @@ -559,7 +555,7 @@ private: } dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL if (!m_statep->forScopeCreation()) { - AstVar* varp = (m_statep->findSym(dotSymp, nodep->name(), baddot) + AstVar* varp = (m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot) ->castVar()); // maybe NULL nodep->varp(varp); UINFO(7," Resolved "<findSym(dotSymp, nodep->name(), baddot) + AstVarScope* vscp = (m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot) ->castVarScope()); // maybe NULL if (!vscp) { m_statep->preErrorDump(); @@ -596,16 +592,16 @@ private: UINFO(8," "<packagep()) { // References into packages don't care about cell hierarchy. - } else if (!m_cellSymp) { + } else if (!m_modSymp) { UINFO(9,"Dead module for "<taskp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later. } else if (nodep->dotted()=="" && nodep->taskp()) { - // V3Link should have setup the links + // Earlier should have setup the links // Might be under a BEGIN we're not processing, so don't relink it } else { string baddot; VSymEnt* okSymp; - VSymEnt* dotSymp = m_cellSymp; // Start search at current scope + VSymEnt* dotSymp = m_modSymp; // Start search at current scope if (nodep->inlinedDots()!="") { // Correct for current scope string inl = AstNode::dedotName(nodep->inlinedDots()); UINFO(8,"\t\tInlined "<findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL - AstNodeFTask* taskp = (m_statep->findSym(dotSymp, nodep->name(), baddot) + AstNodeFTask* taskp = (m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot) ->castNode()->castNodeFTask()); // maybe NULL nodep->taskp(taskp); UINFO(7," Resolved "<accept(*this); } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 0c9c6a982..728a8aa8e 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -183,7 +183,7 @@ public: return; } // Walk old sym table and reinsert into current table - // We let V3Link report the error instead of us + // We let V3LinkDot report the error instead of us symCurrentp()->import(symp, id_or_star); } public: diff --git a/src/V3SymTable.h b/src/V3SymTable.h index 81fb8d3a6..bfcb8e1f8 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -35,47 +35,61 @@ #include "V3File.h" class VSymGraph; +class VSymEnt; //###################################################################### // Symbol table +typedef set VSymMap; + class VSymEnt { // Symbol table that can have a "superior" table for resolving upper references private: // MEMBERS - typedef std::map IdNameMap; + typedef std::multimap IdNameMap; IdNameMap m_idNameMap; // Hash of variables by name AstNode* m_nodep; // Node that entry belongs to VSymEnt* m_fallbackp; // Table "above" this one in name scope, for fallback resolution VSymEnt* m_parentp; // Table that created this table, dot notation needed to resolve into it + AstPackage* m_packagep; // Package node is in (for V3LinkDot, unused here) string m_symPrefix; // String to prefix symbols with (for V3LinkDot, unused here) static int debug() { return 0; } // NOT runtime, too hot of a function -private: - void dumpIterate(ostream& os, const string& indent, int numLevels, const string& searchName) const { - os<first); + if (doneSymsr.find(this) != doneSymsr.end()) { + os<= 1) { + it->second->dumpIterate(os, doneSymsr, indent+"| ", numLevels-1, it->first); + } } } } + void dump(ostream& os, const string& indent="", int numLevels=1) { + VSymMap doneSyms; + dumpIterate(os, doneSyms, indent, numLevels, "TOP"); + } -public: // METHODS VSymEnt(VSymGraph* graphp, AstNode* nodep); // Below ~VSymEnt() {} void fallbackp(VSymEnt* entp) { m_fallbackp = entp; } void parentp(VSymEnt* entp) { m_parentp = entp; } VSymEnt* parentp() const { return m_parentp; } + void packagep(AstPackage* entp) { m_packagep = entp; } + AstPackage* packagep() const { return m_packagep; } AstNode* nodep() const { if (!this) return NULL; else return m_nodep; } // null check so can call .findId(...)->nodep() string symPrefix() const { return m_symPrefix; } void symPrefix(const string& name) { m_symPrefix = name; } void insert(const string& name, VSymEnt* entp) { UINFO(9, " SymInsert "<nodep()<=9 || V3Error::debugDefault()) dump(cout,"- err-dump: ", 1); entp->nodep()->v3fatalSrc("Inserting two symbols with same name: "<nodep()<second = entp; // Replace } else { @@ -141,9 +155,6 @@ public: <dump(os, indent, 9999); + m_symRootp->dumpIterate(os, doneSyms, indent, 9999, "TOP"); + bool first = false; + for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) { + if (doneSyms.find(*it) == doneSyms.end()) { + if (!first++) os<<"%%Warning: SymEnt Orphans:\n"; + (*it)->dumpIterate(os, doneSyms, indent, 9999, "Orphan"); + } + } } void dumpFilePrefixed(const string& nameComment) { if (v3Global.opt.dumpTree()) { @@ -199,6 +218,7 @@ inline VSymEnt::VSymEnt(VSymGraph* m_graphp, AstNode* nodep) // by an earlier search insertion. m_fallbackp = NULL; m_parentp = NULL; + m_packagep = NULL; m_graphp->pushNewEnt(this); }