diff --git a/src/V3Ast.h b/src/V3Ast.h index 564f19ef9..05b5b1b8f 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1966,7 +1966,7 @@ class AstNodeFTaskRef : public AstNode { private: AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced string m_name; // Name of variable - string m_dotted; // Dotted part of scope to task or "" + string m_dotted; // Dotted part of scope the name()ed task/func is under or "" string m_inlinedDots; // Dotted hierarchy flattened out AstPackage* m_packagep; // Package hierarchy public: diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 90383f3c2..b1b2b2e75 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1024,7 +1024,7 @@ void AstVarXRef::dump(ostream& str) { if (packagep()) { str<<" pkg="<<(void*)packagep(); } if (lvalue()) str<<" [LV] => "; else str<<" [RV] <- "; - str<dump(str); } else if (varp()) { varp()->dump(str); } @@ -1095,7 +1095,7 @@ void AstNodeFTaskRef::dump(ostream& str) { this->AstNode::dump(str); if (packagep()) { str<<" pkg="<<(void*)packagep(); } str<<" -> "; - if (dotted()!="") { str<dump(str); } else { str<<"UNLINKED"; } } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index cffc5d07b..7c1617bad 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1484,7 +1484,7 @@ class AstVarXRef : public AstNodeVarRef { // A VarRef to something in another module before AstScope. // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope private: - string m_dotted; // Scope name to connected to + string m_dotted; // Dotted part of scope the name()'ed reference is under or "" string m_inlinedDots; // Dotted hierarchy flattened out public: AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue) diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 75bfb2c8d..3306af082 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -42,6 +42,7 @@ #include "V3Inst.h" #include "V3Stats.h" #include "V3Ast.h" +#include "V3String.h" // CONFIG static const int INLINE_MODS_SMALLER = 100; // If a mod is < this # nodes, can always inline it @@ -270,14 +271,14 @@ public: class InlineRelinkVisitor : public AstNVisitor { private: - typedef vl_unordered_set RenamedInterfacesSet; + typedef vl_unordered_set StringSet; // NODE STATE // Input: // See InlineVisitor // STATE - RenamedInterfacesSet m_renamedInterfaces; // Name of renamed interface variables + StringSet m_renamedInterfaces; // Name of renamed interface variables AstNodeModule* m_modp; // Current module AstCell* m_cellp; // Cell being cloned @@ -410,9 +411,8 @@ private: } virtual void visit(AstVarXRef* nodep) { // Track what scope it was originally under so V3LinkDot can resolve it - string newname = m_cellp->name(); - if (nodep->inlinedDots() != "") { newname += "." + nodep->inlinedDots(); } - nodep->inlinedDots(newname); + string newdots = VString::dot(m_cellp->name(), ".", nodep->inlinedDots()); + nodep->inlinedDots(newdots); for (string tryname = nodep->dotted(); 1;) { if (m_renamedInterfaces.count(tryname)) { nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted()); @@ -430,9 +430,8 @@ private: } virtual void visit(AstNodeFTaskRef* nodep) { // Track what scope it was originally under so V3LinkDot can resolve it - string newname = m_cellp->name(); - if (nodep->inlinedDots() != "") { newname += "." + nodep->inlinedDots(); } - nodep->inlinedDots(newname); + string newdots = VString::dot(m_cellp->name(), ".", nodep->inlinedDots()); + nodep->inlinedDots(newdots); if (m_renamedInterfaces.count(nodep->dotted())) { nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted()); } @@ -459,9 +458,7 @@ private: } virtual void visit(AstCoverDecl* nodep) { // Fix path in coverage statements - nodep->hier(m_cellp->prettyName() - + (nodep->hier()!="" ? ".":"") - + nodep->hier()); + nodep->hier(VString::dot(m_cellp->prettyName(), ".", nodep->hier())); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 29b9d56bf..f2e62b132 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -78,6 +78,7 @@ #include "V3Graph.h" #include "V3Ast.h" #include "V3ParseImp.h" +#include "V3String.h" //###################################################################### // LinkDot state, as a visitor of each AstNode @@ -1807,8 +1808,7 @@ private: || foundp->nodep()->castModule()) { // if top if (allowScope) { ok = true; - if (m_ds.m_dotText!="") m_ds.m_dotText += "."; - m_ds.m_dotText += nodep->name(); + m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; // Upper AstDot visitor will handle it from here @@ -1827,8 +1827,7 @@ private: if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<name(); + m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; UINFO(9," cell -> iface varref "<nodep()<ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface"); // Really this is a scope reference into an interface UINFO(9,"varref-ifaceref "<name(); + m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotSymp = m_statep->getNodeSym(ifacerefp->ifaceViaCellp()); m_ds.m_dotPos = DP_SCOPE; ok = true; @@ -1897,8 +1895,7 @@ private: if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell"); AstIface* ifacep = cellp->modp()->castIface(); //string cellName = m_ds.m_dotText; // Use cellp->name - if (m_ds.m_dotText!="") m_ds.m_dotText += "."; - m_ds.m_dotText += nodep->name(); + m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotSymp = m_statep->getNodeSym(modportp); m_ds.m_dotPos = DP_SCOPE; ok = true; diff --git a/src/V3String.cpp b/src/V3String.cpp index 6471906be..4562ca9f8 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -69,6 +69,12 @@ bool VString::wildmatch(const char* s, const char* p) { return (*s == '\0'); } +string VString::dot(const string& a, const string& dot, const string& b) { + if (b=="") return a; + if (a=="") return b; + return a+dot+b; +} + string VString::downcase(const string& str) { string out = str; for (string::iterator pos = out.begin(); pos != out.end(); ++pos) { diff --git a/src/V3String.h b/src/V3String.h index 452d45c79..a077b514f 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -33,8 +33,13 @@ class VString { static bool wildmatchi(const char* s, const char* p); public: // METHODS (generic string utilities) + // Return true if p with ? or *'s matches s static bool wildmatch(const char* s, const char* p); + // Return {a}{dot}{b}, omitting dot if a or b are empty + static string dot(const string& a, const string& dot, const string& b); + // Convert string to lowercase static string downcase(const string& str); + // Replace any %'s with %% static string quotePercent(const string& str); }; diff --git a/src/V3SymTable.h b/src/V3SymTable.h index 56615709a..479f96de3 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -71,6 +71,7 @@ public: os<