Internals: Simplify AstScopeName (#6280)
Reduce reliance on AstText where not necessary.
This commit is contained in:
parent
0c712d7c60
commit
794247450f
|
|
@ -2060,13 +2060,13 @@ public:
|
|||
};
|
||||
class AstScopeName final : public AstNodeExpr {
|
||||
// For display %m and DPI context imports
|
||||
// Parents: DISPLAY
|
||||
// @astgen op1 := scopeAttrp : List[AstText]
|
||||
// @astgen op2 := scopeEntrp : List[AstText]
|
||||
// Parents: AstSFormatF, AstNodeFTaskRef, AstNodeFTask
|
||||
std::string m_scopeAttr;
|
||||
std::string m_scopeEntr;
|
||||
bool m_dpiExport = false; // Is for dpiExport
|
||||
const bool m_forFormat; // Is for a format %m
|
||||
string scopeNameFormatter(AstText* scopeTextp) const;
|
||||
string scopePrettyNameFormatter(AstText* scopeTextp) const;
|
||||
static std::string scopeNameFormatter(const std::string& text);
|
||||
static std::string scopePrettyNameFormatter(const std::string& text);
|
||||
|
||||
public:
|
||||
class ForFormat {};
|
||||
|
|
@ -2078,28 +2078,32 @@ public:
|
|||
ASTGEN_MEMBERS_AstScopeName;
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
const AstScopeName* const sp = VN_DBG_AS(samep, ScopeName);
|
||||
return (m_dpiExport == sp->m_dpiExport && m_forFormat == sp->m_forFormat);
|
||||
return m_scopeAttr == sp->m_scopeAttr //
|
||||
&& m_scopeEntr == sp->m_scopeEntr //
|
||||
&& m_dpiExport == sp->m_dpiExport //
|
||||
&& m_forFormat == sp->m_forFormat;
|
||||
}
|
||||
string emitVerilog() override { return ""; }
|
||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
bool cleanOut() const override { return true; }
|
||||
void dump(std::ostream& str = std::cout) const override;
|
||||
void dumpJson(std::ostream& str = std::cout) const override;
|
||||
string scopeSymName() const { // Name for __Vscope variable including children
|
||||
return scopeNameFormatter(scopeAttrp());
|
||||
}
|
||||
string scopeDpiName() const { // Name for DPI import scope
|
||||
return scopeNameFormatter(scopeEntrp());
|
||||
}
|
||||
string scopePrettySymName() const { // Name for __Vscope variable including children
|
||||
return scopePrettyNameFormatter(scopeAttrp());
|
||||
}
|
||||
string scopePrettyDpiName() const { // Name for __Vscope variable including children
|
||||
return scopePrettyNameFormatter(scopeEntrp());
|
||||
}
|
||||
// ACCESSORS
|
||||
const std::string& scopeAttr() const { return m_scopeAttr; }
|
||||
void scopeAttr(const std::string& val) { m_scopeAttr = val; }
|
||||
const std::string& scopeEntr() const { return m_scopeEntr; }
|
||||
void scopeEntr(const std::string& val) { m_scopeEntr = val; }
|
||||
bool dpiExport() const { return m_dpiExport; }
|
||||
void dpiExport(bool flag) { m_dpiExport = flag; }
|
||||
bool forFormat() const { return m_forFormat; }
|
||||
// Name for __Vscope variable including children
|
||||
string scopeSymName() const { return scopeNameFormatter(m_scopeAttr); }
|
||||
// Name for DPI import scope
|
||||
string scopeDpiName() const { return scopeNameFormatter(m_scopeEntr); }
|
||||
// Name for __Vscope variable including children
|
||||
string scopePrettySymName() const { return scopePrettyNameFormatter(m_scopeAttr); }
|
||||
// Name for __Vscope variable including children
|
||||
string scopePrettyDpiName() const { return scopePrettyNameFormatter(m_scopeEntr); }
|
||||
};
|
||||
class AstSelLoopVars final : public AstNodeExpr {
|
||||
// Parser only concept "[id, id, id]" for a foreach statement
|
||||
|
|
|
|||
|
|
@ -1211,28 +1211,22 @@ AstVarScope* AstScope::createTempLike(const string& name, const AstVarScope* vsc
|
|||
return createTemp(name, vscp->dtypep());
|
||||
}
|
||||
|
||||
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp = scopeTextp; textp; textp = VN_AS(textp->nextp(), Text)) {
|
||||
out += textp->text();
|
||||
}
|
||||
std::string AstScopeName::scopePrettyNameFormatter(const std::string& text) {
|
||||
std::string out = text;
|
||||
// TOP will be replaced by top->name()
|
||||
if (out.substr(0, 10) == "__DOT__TOP") out.replace(0, 10, "");
|
||||
if (out.substr(0, 7) == "__DOT__") out.replace(0, 7, "");
|
||||
if (out.substr(0, 1) == ".") out.replace(0, 1, "");
|
||||
return AstNode::prettyName(out);
|
||||
}
|
||||
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp = scopeTextp; textp; textp = VN_AS(textp->nextp(), Text)) {
|
||||
out += textp->text();
|
||||
}
|
||||
std::string AstScopeName::scopeNameFormatter(const std::string& text) {
|
||||
std::string out = text;
|
||||
if (out.substr(0, 10) == "__DOT__TOP") out.replace(0, 10, "");
|
||||
if (out.substr(0, 7) == "__DOT__") out.replace(0, 7, "");
|
||||
if (out.substr(0, 1) == ".") out.replace(0, 1, "");
|
||||
string::size_type pos;
|
||||
while ((pos = out.find('.')) != string::npos) out.replace(pos, 1, "__");
|
||||
while ((pos = out.find("__DOT__")) != string::npos) out.replace(pos, 7, "__");
|
||||
std::string::size_type pos;
|
||||
while ((pos = out.find('.')) != std::string::npos) out.replace(pos, 1, "__");
|
||||
while ((pos = out.find("__DOT__")) != std::string::npos) out.replace(pos, 7, "__");
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -2813,10 +2807,14 @@ void AstScopeName::dump(std::ostream& str) const {
|
|||
this->AstNodeExpr::dump(str);
|
||||
if (dpiExport()) str << " [DPIEX]";
|
||||
if (forFormat()) str << " [FMT]";
|
||||
str << " scopeAttr=\"" << m_scopeAttr << "\"";
|
||||
str << " scopeEntr=\"" << m_scopeEntr << "\"";
|
||||
}
|
||||
void AstScopeName::dumpJson(std::ostream& str) const {
|
||||
dumpJsonBoolFunc(str, dpiExport);
|
||||
dumpJsonBoolFunc(str, forFormat);
|
||||
dumpJsonStr(str, "scopeAttr", m_scopeAttr);
|
||||
dumpJsonStr(str, "scopeEntr", m_scopeEntr);
|
||||
dumpJsonGen(str);
|
||||
}
|
||||
void AstSenTree::dump(std::ostream& str) const {
|
||||
|
|
|
|||
|
|
@ -293,14 +293,9 @@ class BeginVisitor final : public VNVisitor {
|
|||
// Similar code in V3Inline
|
||||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
// DPI svGetScope doesn't include function name, but %m does
|
||||
const string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
|
||||
if (!scname.empty()) {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstText* const afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->addScopeAttrp(new AstText{nodep->fileline(), "__DOT__"s + scname});
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
}
|
||||
const std::string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
|
||||
// To keep correct visual order, must add before exising
|
||||
if (!scname.empty()) nodep->scopeAttr("__DOT__"s + scname + nodep->scopeAttr());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstNodeCoverDecl* nodep) override {
|
||||
|
|
|
|||
|
|
@ -393,15 +393,9 @@ class InlineRelinkVisitor final : public VNVisitor {
|
|||
void visit(AstScopeName* nodep) override {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Begin
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstText* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->addScopeAttrp(new AstText{nodep->fileline(), "__DOT__"s + m_cellp->name()});
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->addScopeEntrp(new AstText{nodep->fileline(), "__DOT__"s + m_cellp->name()});
|
||||
if (afterp) nodep->addScopeEntrp(afterp);
|
||||
// To keep correct visual order, must add before exising
|
||||
nodep->scopeAttr("__DOT__" + m_cellp->name() + nodep->scopeAttr());
|
||||
nodep->scopeEntr("__DOT__" + m_cellp->name() + nodep->scopeEntr());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstNodeCoverDecl* nodep) override {
|
||||
|
|
|
|||
|
|
@ -291,15 +291,9 @@ class ScopeVisitor final : public VNVisitor {
|
|||
const string prefix = "__DOT__"s + m_scopep->name();
|
||||
// TOP and above will be the user's name().
|
||||
// Note 'TOP.' is stripped by scopePrettyName
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstText* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->addScopeAttrp(new AstText{nodep->fileline(), prefix});
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->addScopeEntrp(new AstText{nodep->fileline(), prefix});
|
||||
if (afterp) nodep->addScopeEntrp(afterp);
|
||||
// To keep correct visual order, must add before existing
|
||||
nodep->scopeAttr(prefix + nodep->scopeAttr());
|
||||
nodep->scopeEntr(prefix + nodep->scopeEntr());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstScope* nodep) override {
|
||||
|
|
|
|||
|
|
@ -1303,8 +1303,8 @@ class TaskVisitor final : public VNVisitor {
|
|||
if (nodep->dpiExport()) {
|
||||
AstScopeName* const snp = nodep->scopeNamep();
|
||||
UASSERT_OBJ(snp, nodep, "Missing scoping context");
|
||||
snp->dpiExport(
|
||||
true); // The AstScopeName is really a statement(ish) for tracking, not a function
|
||||
// The AstScopeName is really a statement(ish) for tracking, not a function
|
||||
snp->dpiExport(true);
|
||||
snp->unlinkFrBack();
|
||||
cfuncp->addInitsp(snp);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue