forked from github/verilator
Internals: Merge from struct branch, rename SymTable calls. No functional change intended.
This commit is contained in:
parent
09aa9f87d8
commit
365034d7dd
@ -125,7 +125,7 @@ private:
|
||||
bool linkVarName (AstVarRef* nodep) {
|
||||
// Return true if changed, and caller should end processing
|
||||
if (!nodep->varp()) {
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->name());
|
||||
AstNode* foundp = m_curVarsp->findIdFallback(nodep->name());
|
||||
if (AstVar* varp = foundp->castVar()) {
|
||||
nodep->varp(varp);
|
||||
nodep->packagep(packageFor(varp));
|
||||
@ -280,7 +280,7 @@ private:
|
||||
nodep->trace(false);
|
||||
}
|
||||
// Find under either a task or the module's vars
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->name());
|
||||
AstNode* foundp = m_curVarsp->findIdFallback(nodep->name());
|
||||
AstVar* findvarp = foundp->castVar();
|
||||
bool ins=false;
|
||||
if (!foundp) {
|
||||
@ -290,7 +290,7 @@ private:
|
||||
<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
} else if (findvarp != nodep) {
|
||||
UINFO(4,"DupVar: "<<nodep<<" ;; "<<foundp<<endl);
|
||||
if (findvarp && findvarp->user3p() == m_curVarsp) { // Only when on same level
|
||||
if (findvarp && findvarp->user3p()->castSymTable() == m_curVarsp) { // Only when on same level
|
||||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
@ -354,14 +354,14 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_idState==ID_FIND) {
|
||||
// Find under either a task or the module's vars
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->name());
|
||||
AstNode* foundp = m_curVarsp->findIdFallback(nodep->name());
|
||||
AstEnumItem* findvarp = foundp->castEnumItem();
|
||||
bool ins=false;
|
||||
if (!foundp) {
|
||||
ins=true;
|
||||
} else if (findvarp != nodep) {
|
||||
UINFO(4,"DupVar: "<<nodep<<" ;; "<<foundp<<endl);
|
||||
if (findvarp && findvarp->user3p() == m_curVarsp) { // Only when on same level
|
||||
if (findvarp && findvarp->user3p()->castSymTable() == m_curVarsp) { // Only when on same level
|
||||
nodep->v3error("Duplicate declaration of enum value: "<<nodep->prettyName()<<endl
|
||||
<<findvarp->warnMore()<<"... Location of original declaration");
|
||||
} else {
|
||||
@ -464,9 +464,9 @@ private:
|
||||
if (nodep->dotted() == "") {
|
||||
AstNodeFTask* taskp;
|
||||
if (nodep->packagep()) {
|
||||
taskp = symsFind(nodep->packagep())->findIdUpward(nodep->name())->castNodeFTask();
|
||||
taskp = symsFind(nodep->packagep())->findIdFallback(nodep->name())->castNodeFTask();
|
||||
} else {
|
||||
taskp = m_curVarsp->findIdUpward(nodep->name())->castNodeFTask();
|
||||
taskp = m_curVarsp->findIdFallback(nodep->name())->castNodeFTask();
|
||||
}
|
||||
if (!taskp) { nodep->v3error("Can't find definition of task/function: "<<nodep->prettyName()); }
|
||||
nodep->taskp(taskp);
|
||||
@ -481,7 +481,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_idState==ID_RESOLVE) {
|
||||
AstNodeFTask* taskp;
|
||||
taskp = m_curVarsp->findIdUpward(nodep->name())->castNodeFTask();
|
||||
taskp = m_curVarsp->findIdFallback(nodep->name())->castNodeFTask();
|
||||
if (!taskp) { nodep->v3error("Can't find definition of exported task/function: "<<nodep->prettyName()); }
|
||||
else if (taskp->dpiExport()) {
|
||||
nodep->v3error("Function was already DPI Exported, duplicate not allowed: "<<nodep->prettyName());
|
||||
@ -508,7 +508,7 @@ private:
|
||||
if (nodep->packagep()) {
|
||||
defp = symsFind(nodep->packagep())->findIdFlat(nodep->name())->castTypedef();
|
||||
} else {
|
||||
defp = m_curVarsp->findIdUpward(nodep->name())->castTypedef();
|
||||
defp = m_curVarsp->findIdFallback(nodep->name())->castTypedef();
|
||||
}
|
||||
if (!defp) { nodep->v3error("Can't find typedef: "<<nodep->prettyName()); }
|
||||
nodep->refDTypep(defp->subDTypep());
|
||||
@ -656,7 +656,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_idState==ID_PARAM) {
|
||||
nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<<nodep->name()<<"(...etc...))");
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->path());
|
||||
AstNode* foundp = m_curVarsp->findIdFallback(nodep->path());
|
||||
AstCell* cellp = foundp->castCell();
|
||||
if (!cellp) {
|
||||
nodep->v3error("In defparam, cell "<<nodep->path()<<" never declared");
|
||||
|
@ -195,9 +195,9 @@ private:
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
if (!nodep->modp()) {
|
||||
UINFO(4,"Link Cell: "<<nodep<<endl);
|
||||
// Use findIdUpward instead of findIdFlat; it doesn't matter for now
|
||||
// Use findIdFallback instead of findIdFlat; it doesn't matter for now
|
||||
// but we might support modules-under-modules someday.
|
||||
AstNodeModule* modp = m_mods.findIdUpward(nodep->modName())->castNodeModule();
|
||||
AstNodeModule* modp = m_mods.findIdFallback(nodep->modName())->castNodeModule();
|
||||
if (!modp) {
|
||||
// Read-subfile
|
||||
// If file not found, make AstNotFoundModule, rather than error out.
|
||||
@ -208,7 +208,7 @@ private:
|
||||
// We've read new modules, grab new pointers to their names
|
||||
readModNames();
|
||||
// Check again
|
||||
modp = m_mods.findIdUpward(nodep->modName())->castNodeModule();
|
||||
modp = m_mods.findIdFallback(nodep->modName())->castNodeModule();
|
||||
if (!modp) {
|
||||
nodep->v3error("Can't resolve module reference: "<<nodep->modName());
|
||||
}
|
||||
@ -251,20 +251,20 @@ private:
|
||||
}
|
||||
if (nodep->modp()) {
|
||||
// Note what pins exist
|
||||
V3SymTable ports; // Symbol table of all connected port names
|
||||
set<string> 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 (!pinp->exprp()) pinp->v3warn(PINNOCONNECT,"Cell pin is not connected: "<<pinp->prettyName());
|
||||
if (!ports.findIdFlat(pinp->name())) {
|
||||
ports.insert(pinp->name(), pinp);
|
||||
if (ports.find(pinp->name()) == ports.end()) {
|
||||
ports.insert(pinp->name());
|
||||
}
|
||||
}
|
||||
// We search ports, rather than in/out declarations as they aren't resolved yet,
|
||||
// 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.findIdFlat(portp->name())
|
||||
&& !ports.findIdFlat("__pinNumber"+cvtToStr(portp->pinNum()))) {
|
||||
if (ports.find(portp->name()) == ports.end()
|
||||
&& ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) {
|
||||
if (pinStar) {
|
||||
UINFO(9," need .* PORT "<<portp<<endl);
|
||||
// Create any not already connected
|
||||
@ -299,7 +299,7 @@ private:
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstNodeModule* nextp,* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nextp) {
|
||||
nextp = nodep->nextp()->castNodeModule();
|
||||
AstNode* foundp = m_mods.findIdUpward(nodep->name());
|
||||
AstNode* foundp = m_mods.findIdFallback(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) {
|
||||
nodep->v3warn(MODDUP,"Duplicate declaration of module: "<<nodep->prettyName()<<endl
|
||||
|
@ -27,6 +27,14 @@
|
||||
// VarXRef/Func's:
|
||||
// Find appropriate named cell and link to var they reference
|
||||
//*************************************************************************
|
||||
// Top
|
||||
// a (LinkDotCellVertex->AstCell)
|
||||
// aa (LinkDotCellVertex->AstCell)
|
||||
// var (AstVar) -- in syms(), not a vertex
|
||||
// beg (LinkDotBeginVertex->AstBegin) -- can see "upper" a's symbol table
|
||||
// a__DOT__aa (LinkDotInlineVertex->AstCellInline) -- points to a.aa's symbol table
|
||||
// b (LinkDotCellVertex->AstCell)
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
@ -65,8 +73,9 @@ public:
|
||||
virtual string cellName() const = 0;
|
||||
virtual V3SymTable& syms() = 0;
|
||||
string symPrefix() const { return m_symPrefix; }
|
||||
void insertSubcellName(const string& name, LinkDotBaseVertex* toVertexp) {
|
||||
m_nameToVtxMap.insert(make_pair(name,toVertexp));
|
||||
void insertSubcellName(LinkDotGraph* graphp, const string& name, LinkDotBaseVertex* toVertexp) {
|
||||
m_nameToVtxMap.insert(make_pair(name, toVertexp));
|
||||
new V3GraphEdge(graphp, this, toVertexp, 1, false);
|
||||
}
|
||||
LinkDotBaseVertex* findSubcell(const string& name, const string& altname) {
|
||||
// Find a vertex under this one by name.
|
||||
@ -104,27 +113,27 @@ public:
|
||||
};
|
||||
|
||||
class LinkDotCellVertex : public LinkDotBaseVertex {
|
||||
// A real point in the hierarchy, corresponding to a instantiated module
|
||||
// A real point in the hierarchy, corresponding to an instantiated module
|
||||
AstNodeModule* m_modp; // Module
|
||||
AstCell* m_cellp; // Cell creating this vertex **NULL AT TOP**
|
||||
AstCell* m_nodep; // Cell creating this vertex **NULL AT TOP**
|
||||
V3SymTable m_syms; // Symbol table of variable/task names for global lookup
|
||||
public:
|
||||
LinkDotCellVertex(V3Graph* graphp, AstCell* nodep)
|
||||
: LinkDotBaseVertex(graphp, ""), m_modp(nodep->modp()), m_cellp(nodep) {}
|
||||
: LinkDotBaseVertex(graphp, ""), m_modp(nodep->modp()), m_nodep(nodep) {}
|
||||
LinkDotCellVertex(V3Graph* graphp, AstNodeModule* nodep)
|
||||
: LinkDotBaseVertex(graphp, ""), m_modp(nodep), m_cellp(NULL) {}
|
||||
: LinkDotBaseVertex(graphp, ""), m_modp(nodep), m_nodep(NULL) {}
|
||||
virtual ~LinkDotCellVertex() {}
|
||||
AstNodeModule* modp() const { return m_modp; } // May be NULL
|
||||
AstCell* cellp() const { return m_cellp; } // Is NULL at TOP
|
||||
AstCell* nodep() const { return m_nodep; } // Is NULL at TOP
|
||||
virtual V3SymTable& syms() { return m_syms; }
|
||||
// We need to use origName as parameters may have renamed the modname
|
||||
virtual string modName() const { return (modp() ? modp()->origName() : "*NULL*"); }
|
||||
virtual string cellName() const { return (cellp() ? cellp()->origName() : "*NULL*"); }
|
||||
virtual string cellName() const { return (nodep() ? nodep()->origName() : "*NULL*"); }
|
||||
virtual string name() const { return (string)("C:")+cellName()+" M:"+modName(); }
|
||||
};
|
||||
|
||||
class LinkDotInlineVertex : public LinkDotBaseVertex {
|
||||
// A fake point in the hierarchy, corresponding to a inlined module
|
||||
// A fake point in the hierarchy, corresponding to an inlined module
|
||||
// This refrences to another vertex, and eventually resolves to a module with a prefix
|
||||
string m_basename; // Name with dotteds stripped
|
||||
AstCellInline* m_cellInlinep; // Inlined cell
|
||||
@ -198,9 +207,6 @@ public:
|
||||
UINFO(4,__FUNCTION__<<": "<<endl);
|
||||
m_forPrearray = forPrearray;
|
||||
m_forScopeCreation = forScopeCreation;
|
||||
//VV***** We reset all userp() on each netlist!!!
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
}
|
||||
~LinkDotState() {}
|
||||
|
||||
@ -221,11 +227,10 @@ public:
|
||||
UINFO(9," INSERTcell "<<scopename<<" "<<nodep<<endl);
|
||||
LinkDotCellVertex* vxp = new LinkDotCellVertex(&m_graph, nodep);
|
||||
if (nodep->modp()) nodep->modp()->user1p(vxp);
|
||||
new V3GraphEdge(&m_graph, abovep, vxp, 1, false);
|
||||
abovep->insertSubcellName(nodep->origName(), vxp);
|
||||
abovep->insertSubcellName(&m_graph, nodep->origName(), vxp);
|
||||
if (abovep != cellVxp) {
|
||||
// If it's foo_DOT_bar, we need to be able to find it under that too.
|
||||
cellVxp->insertSubcellName(nodep->name(), vxp);
|
||||
cellVxp->insertSubcellName(&m_graph, nodep->name(), vxp);
|
||||
}
|
||||
if (forScopeCreation()) m_nameScopeMap.insert(make_pair(scopename, vxp));
|
||||
return vxp;
|
||||
@ -234,11 +239,10 @@ public:
|
||||
AstCellInline* nodep, const string& basename) {
|
||||
UINFO(9," INSERTcinl "<<nodep<<endl);
|
||||
LinkDotInlineVertex* vxp = new LinkDotInlineVertex(&m_graph, nodep, cellVxp, basename);
|
||||
new V3GraphEdge(&m_graph, abovep, vxp, 1, false);
|
||||
abovep->insertSubcellName(basename, vxp);
|
||||
abovep->insertSubcellName(&m_graph, basename, vxp);
|
||||
if (abovep != cellVxp) {
|
||||
// If it's foo_DOT_bar, we need to be able to find it under that too.
|
||||
cellVxp->insertSubcellName(nodep->name(), vxp);
|
||||
cellVxp->insertSubcellName(&m_graph, nodep->name(), vxp);
|
||||
}
|
||||
return vxp;
|
||||
}
|
||||
@ -246,8 +250,7 @@ public:
|
||||
AstBegin* nodep) {
|
||||
UINFO(9," INSERTbeg "<<nodep<<endl);
|
||||
LinkDotBeginVertex* vxp = new LinkDotBeginVertex(&m_graph, nodep, cellVxp);
|
||||
new V3GraphEdge(&m_graph, abovep, vxp, 1, false);
|
||||
abovep->insertSubcellName(nodep->name(), vxp);
|
||||
abovep->insertSubcellName(&m_graph, nodep->name(), vxp);
|
||||
return vxp;
|
||||
}
|
||||
void insertSym(LinkDotCellVertex* abovep, const string& name, AstNode* nodep) {
|
||||
|
@ -92,11 +92,11 @@ class V3ParseSym {
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
static int s_anonNum; // Number of next anonymous object
|
||||
V3SymTable* m_symTableNextId; // Symbol table for next lexer lookup
|
||||
static int s_anonNum; // Number of next anonymous object (parser use only)
|
||||
V3SymTable* m_symTableNextId; // Symbol table for next lexer lookup (parser use only)
|
||||
V3SymTable* m_symCurrentp; // Active symbol table for additions/lookups
|
||||
V3SymTable* m_symRootp; // Root symbol table
|
||||
SymStack m_sympStack; // Stack of nodes with symbol tables
|
||||
SymStack m_sympStack; // Stack of upper nodes with pending symbol tables
|
||||
SymStack m_symsp; // All symbol tables, to cleanup
|
||||
|
||||
private:
|
||||
@ -175,7 +175,7 @@ public:
|
||||
}
|
||||
AstNode* findEntUpward (const string& name) {
|
||||
// Lookup the given string as an identifier, return type of the id, scanning upward
|
||||
return symCurrentp()->findIdUpward(name);
|
||||
return symCurrentp()->findIdFallback(name);
|
||||
}
|
||||
void import(AstNode* packagep, const string& id_or_star) {
|
||||
// Import from package::id_or_star to this
|
||||
|
@ -35,20 +35,20 @@
|
||||
//######################################################################
|
||||
// Symbol table
|
||||
|
||||
class V3SymTable : public AstNUser {
|
||||
class V3SymTable {
|
||||
// Symbol table that can have a "superior" table for resolving upper references
|
||||
private:
|
||||
// MEMBERS
|
||||
typedef std::map<string,AstNode*> IdNameMap;
|
||||
IdNameMap m_idNameMap; // Hash of variables by name
|
||||
AstNode* m_ownerp; // Node that table belongs to
|
||||
V3SymTable* m_upperp; // Table "above" this one in name scope
|
||||
V3SymTable* m_fallbackp; // Table "above" this one in name scope
|
||||
public:
|
||||
// METHODS
|
||||
V3SymTable(AstNode* ownerp, V3SymTable* upperTablep) {
|
||||
m_ownerp = ownerp; m_upperp = upperTablep; }
|
||||
m_ownerp = ownerp; m_fallbackp = upperTablep; }
|
||||
V3SymTable() {
|
||||
m_ownerp = NULL; m_upperp = NULL; }
|
||||
m_ownerp = NULL; m_fallbackp = NULL; }
|
||||
~V3SymTable() {}
|
||||
AstNode* ownerp() const { return m_ownerp; }
|
||||
void insert(const string& name, AstNode* nodep) {
|
||||
@ -78,12 +78,12 @@ class V3SymTable : public AstNUser {
|
||||
if (iter != m_idNameMap.end()) return (iter->second);
|
||||
return NULL;
|
||||
}
|
||||
AstNode* findIdUpward(const string& name) const {
|
||||
AstNode* findIdFallback(const string& name) const {
|
||||
// Find identifier looking upward through symbol hierarchy
|
||||
// First, scan this begin/end block or module for the name
|
||||
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->findIdUpward(name);
|
||||
if (m_fallbackp) return m_fallbackp->findIdFallback(name);
|
||||
return NULL;
|
||||
}
|
||||
bool import(const V3SymTable* srcp, const string& id_or_star) {
|
||||
|
@ -538,7 +538,7 @@ word [a-zA-Z0-9_]+
|
||||
"$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng);
|
||||
yylval.strp = PARSEP->newString(AstNode::encodeName(str));
|
||||
// Lookup unencoded name including the $, to avoid hitting normal signals
|
||||
if (SYMP->symCurrentp()->findIdUpward(str)) {
|
||||
if (SYMP->symCurrentp()->findIdFallback(str)) {
|
||||
FL; return yaD_DPI;
|
||||
} else { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported or unknown PLI call: %s",yytext); }
|
||||
}
|
||||
@ -1120,13 +1120,13 @@ int V3ParseImp::lexToken() {
|
||||
AstNode* scp;
|
||||
if (V3SymTable* look_underp = SYMP->nextId()) {
|
||||
if (debugFlex()) { cout<<" lexToken: next id lookup forced under "<<look_underp<<endl; }
|
||||
scp = look_underp->findIdUpward(*(yylval.strp));
|
||||
scp = look_underp->findIdFallback(*(yylval.strp));
|
||||
// "consume" it. Must set again if want another token under temp scope
|
||||
SYMP->nextId(NULL);
|
||||
} else {
|
||||
UINFO(7," lexToken: find upward "<<SYMP->symCurrentp()<<" for '"<<*(yylval.strp)<<"'"<<endl);
|
||||
//if (debug()>=9) SYMP->symCurrentp()->dump(cout," -findtree: ",true);
|
||||
scp = SYMP->symCurrentp()->findIdUpward(*(yylval.strp));
|
||||
scp = SYMP->symCurrentp()->findIdFallback(*(yylval.strp));
|
||||
}
|
||||
yylval.scp = scp;
|
||||
if (scp) {
|
||||
|
Loading…
Reference in New Issue
Block a user