Internals: Avoid emit inheritance in V3EmitCBase. No functional change intended.

This commit is contained in:
Wilson Snyder 2023-03-18 12:05:29 -04:00
parent 053f760e2a
commit 82e653a739
15 changed files with 61 additions and 62 deletions

View File

@ -735,9 +735,9 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const VL_M
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
info.m_type = "VlSampleQueue<" + sub.m_type + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) {
info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">";
info.m_type = "VlClassRef<" + EmitCBase::prefixNameProtect(adtypep) + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, IfaceRefDType)) {
info.m_type = EmitCBaseVisitor::prefixNameProtect(adtypep->ifaceViaCellp()) + "*";
info.m_type = EmitCBase::prefixNameProtect(adtypep->ifaceViaCellp()) + "*";
} else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
if (adtypep->isCompound()) compound = true;
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound);
@ -746,7 +746,7 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const VL_M
info.m_type += ">";
} else if (VN_IS(dtypep, NodeUOrStructDType) && !VN_AS(dtypep, NodeUOrStructDType)->packed()) {
const auto* const sdtypep = VN_AS(dtypep, NodeUOrStructDType);
info.m_type = EmitCBaseVisitor::prefixNameProtect(sdtypep);
info.m_type = EmitCBase::prefixNameProtect(sdtypep);
} else if (const AstBasicDType* const bdtypep = dtypep->basicp()) {
// We don't print msb()/lsb() as multidim packed would require recursion,
// and may confuse users as C++ data is stored always with bit 0 used

View File

@ -70,7 +70,7 @@ private:
funcp->slow(!m_type.isClass()); // Only classes construct on fast path
string preventUnusedStmt;
if (m_type.isClass()) {
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->argTypes(EmitCBase::symClassVar());
preventUnusedStmt = "if (false && vlSymsp) {} // Prevent unused\n";
} else if (m_type.isCoverage()) {
funcp->argTypes("bool first");

View File

@ -37,7 +37,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
static void makeVlToString(AstClass* nodep) {
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(nodep) + ">& obj");
funcp->argTypes("const VlClassRef<" + EmitCBase::prefixNameProtect(nodep) + ">& obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -51,7 +51,7 @@ static void makeVlToString(AstClass* nodep) {
static void makeVlToString(AstIface* nodep) {
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBaseVisitor::prefixNameProtect(nodep) + "* obj");
funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "* obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -65,7 +65,7 @@ static void makeVlToString(AstNodeUOrStructDType* nodep) {
AstNodeModule* const modp = nodep->classOrPackagep();
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBaseVisitor::prefixNameProtect(nodep) + "& obj");
funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "& obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -137,7 +137,7 @@ static void makeToStringMiddle(AstClass* nodep) {
string stmt = "out += ";
if (!comma.empty()) stmt += "\", \"+ ";
// comma = ", "; // Nothing further so not needed
stmt += EmitCBaseVisitor::prefixNameProtect(nodep->extendsp()->dtypep());
stmt += EmitCBase::prefixNameProtect(nodep->extendsp()->dtypep());
stmt += "::to_string_middle();\n";
nodep->user1(true); // So what we extend dumps this
funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -63,7 +63,7 @@ private:
AstCCall* const callp = new AstCCall{nodep->fileline(), funcp};
callp->dtypeSetVoid();
if (VN_IS(m_modp, Class)) {
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->argTypes(EmitCBase::symClassVar());
callp->argTypes("vlSymsp");
}
UINFO(6, " New " << callp << endl);

View File

@ -48,7 +48,36 @@ public:
//######################################################################
// Base Visitor class -- holds output file pointer
class EmitCBaseVisitor VL_NOT_FINAL : public VNVisitor {
class EmitCBase VL_NOT_FINAL {
public:
static string voidSelfAssign(const AstNodeModule* modp) {
const string className = prefixNameProtect(modp);
return className + "* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<" + className
+ "*>(voidSelf);\n";
}
static string symClassName() {
return v3Global.opt.prefix() + "_" + VIdProtect::protect("_Syms");
}
static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; }
static string symClassAssign() {
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
}
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
}
static bool isAnonOk(const AstVar* varp) {
return v3Global.opt.compLimitMembers() != 0 // Enabled
&& !varp->isStatic() // Not a static variable
&& !varp->isSc() // Aggregates can't be anon
&& !VN_IS(varp->dtypep()->skipRefp(), SampleQueueDType) // Aggregates can't be anon
&& (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon
}
static bool isConstPoolMod(const AstNode* modp) {
return modp == v3Global.rootp()->constPoolp()->modp();
}
};
class EmitCBaseVisitor VL_NOT_FINAL : public VNVisitor, public EmitCBase {
public:
// STATE
V3OutCFile* m_ofp = nullptr;
@ -63,9 +92,7 @@ public:
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
void ensureNewLine() { ofp()->ensureNewLine(); }
bool optSystemC() { return v3Global.opt.systemC(); }
static string protect(const string& name) VL_MT_SAFE {
return VIdProtect::protectIf(name, true);
}
static string protect(const string& name) VL_MT_SAFE { return VIdProtect::protect(name); }
static string protectIf(const string& name, bool doIt) {
return VIdProtect::protectIf(name, doIt);
}
@ -75,36 +102,10 @@ public:
static string ifNoProtect(const string& in) VL_MT_SAFE {
return v3Global.opt.protectIds() ? "" : in;
}
static string voidSelfAssign(const AstNodeModule* modp) {
const string className = prefixNameProtect(modp);
return className + "* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<" + className
+ "*>(voidSelf);\n";
}
static string symClassName() { return v3Global.opt.prefix() + "_" + protect("_Syms"); }
static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; }
static string symClassAssign() {
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
}
static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr);
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + protect(nodep->name());
}
static string topClassName() VL_MT_SAFE { // Return name of top wrapper module
return v3Global.opt.prefix();
}
static bool isConstPoolMod(const AstNode* modp) {
return modp == v3Global.rootp()->constPoolp()->modp();
}
static bool isAnonOk(const AstVar* varp) {
return v3Global.opt.compLimitMembers() != 0 // Enabled
&& !varp->isStatic() // Not a static variable
&& !varp->isSc() // Aggregates can't be anon
&& !VN_IS(varp->dtypep()->skipRefp(), SampleQueueDType) // Aggregates can't be anon
&& (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon
}
static AstCFile* newCFile(const string& filename, bool slow, bool source, bool add = true);
string cFuncArgs(const AstCFunc* nodep);
void emitCFuncHeader(const AstCFunc* funcp, const AstNodeModule* modp, bool withScope);

View File

@ -83,7 +83,7 @@ class EmitCLazyDecls final : public VNVisitorConst {
void visit(AstVarRef* nodep) override {
AstVar* const varp = nodep->varp();
// Only constant pool symbols are lazy declared for now ...
if (EmitCBaseVisitor::isConstPoolMod(EmitCParentModule::get(varp))) {
if (EmitCBase::isConstPoolMod(EmitCParentModule::get(varp))) {
lazyDeclareConstPoolVar(varp);
}
}

View File

@ -224,7 +224,7 @@ class EmitCHeader final : public EmitCConstInit {
}
}
puts(sdtypep->verilogKwd()); // "struct"/"union"
puts(" " + EmitCBaseVisitor::prefixNameProtect(sdtypep) + " {\n");
puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n");
for (const AstMemberDType* itemp = sdtypep->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) {
puts(itemp->dtypep()->cType(itemp->nameProtect(), false, false));

View File

@ -38,23 +38,22 @@ class EmitCGatherDependencies final : VNVisitorConst {
std::set<string> m_dependencies; // Header names to be included in output C++ file
// METHODS
void addSymsDependency() { m_dependencies.insert(EmitCBaseVisitor::symClassName()); }
void addSymsDependency() { m_dependencies.insert(EmitCBase::symClassName()); }
void addModDependency(const AstNodeModule* modp) {
if (const AstClass* const classp = VN_CAST(modp, Class)) {
m_dependencies.insert(EmitCBaseVisitor::prefixNameProtect(classp->classOrPackagep()));
m_dependencies.insert(EmitCBase::prefixNameProtect(classp->classOrPackagep()));
} else {
m_dependencies.insert(EmitCBaseVisitor::prefixNameProtect(modp));
m_dependencies.insert(EmitCBase::prefixNameProtect(modp));
}
}
void addDTypeDependency(const AstNodeDType* nodep) {
if (const AstClassRefDType* const dtypep = VN_CAST(nodep, ClassRefDType)) {
m_dependencies.insert(
EmitCBaseVisitor::prefixNameProtect(dtypep->classp()->classOrPackagep()));
EmitCBase::prefixNameProtect(dtypep->classp()->classOrPackagep()));
} else if (const AstNodeUOrStructDType* const dtypep
= VN_CAST(nodep, NodeUOrStructDType)) {
if (!dtypep->packed()) {
m_dependencies.insert(
EmitCBaseVisitor::prefixNameProtect(dtypep->classOrPackagep()));
m_dependencies.insert(EmitCBase::prefixNameProtect(dtypep->classOrPackagep()));
}
}
}

View File

@ -3129,8 +3129,8 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
funcp->argTypes("void* voidSelf, bool even_cycle");
// Setup vlSelf an vlSyms
funcp->addStmtsp(new AstCStmt{fl, EmitCBaseVisitor::voidSelfAssign(modp)});
funcp->addStmtsp(new AstCStmt{fl, EmitCBaseVisitor::symClassAssign()});
funcp->addStmtsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(modp)});
funcp->addStmtsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
// Invoke each mtask scheduled to this thread from the thread function
for (const ExecMTask* const mtaskp : thread) {

View File

@ -607,7 +607,7 @@ std::pair<AstVarScope*, AstNodeStmt*> makeEvalLoop(AstNetlist* netlistp, const s
AstTextBlock* const blockp = new AstTextBlock{flp};
failp->addThensp(blockp);
FileLine* const locp = netlistp->topModulep()->fileline();
const string& file = EmitCBaseVisitor::protect(locp->filename());
const string& file = VIdProtect::protect(locp->filename());
const string& line = cvtToStr(locp->lineno());
const auto add = [&](const string& text) { blockp->addText(flp, text, true); };
add("#ifdef VL_DEBUG\n");

View File

@ -362,7 +362,7 @@ void transformForks(AstNetlist* const netlistp) {
// If we're in a class, add a vlSymsp arg
if (m_inClass) {
newfuncp->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"});
newfuncp->argTypes(EmitCBaseVisitor::symClassVar());
newfuncp->argTypes(EmitCBase::symClassVar());
callp->argTypes("vlSymsp");
}
// Put the begin's statements in the function, delete the begin

View File

@ -802,7 +802,7 @@ private:
// Convert input/inout DPI arguments to Internal types
string args;
args += ("(" + EmitCBaseVisitor::symClassName()
args += ("(" + EmitCBase::symClassName()
+ "*)(__Vscopep->symsp())"); // Upcast w/o overhead
AstNode* argnodesp = nullptr;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
@ -1181,15 +1181,14 @@ private:
cfuncp->isConstructor(true);
AstClass* const classp = m_statep->getClassp(nodep);
if (classp->extendsp()) {
cfuncp->baseCtors(
EmitCBaseVisitor::prefixNameProtect(classp->extendsp()->classp()));
cfuncp->baseCtors(EmitCBase::prefixNameProtect(classp->extendsp()->classp()));
}
}
if (cfuncp->dpiExportImpl()) cfuncp->cname(nodep->cname());
if (!nodep->dpiImport() && !nodep->taskPublic()) {
// Need symbol table
cfuncp->argTypes(EmitCBaseVisitor::symClassVar());
cfuncp->argTypes(EmitCBase::symClassVar());
if (cfuncp->name() == "new") {
const string stmt = VIdProtect::protect("_ctor_var_reset") + "(vlSymsp);\n";
cfuncp->addInitsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -154,7 +154,7 @@ public:
//######################################################################
// Trace state, as a visitor of each AstNode
class TraceVisitor final : public EmitCBaseVisitor {
class TraceVisitor final : public VNVisitor {
private:
// NODE STATE
// V3Hasher in V3DupFinder
@ -511,8 +511,8 @@ private:
funcp->argTypes("void* voidSelf, " + v3Global.opt.traceClassBase()
+ "::" + (v3Global.opt.useTraceOffload() ? "OffloadBuffer" : "Buffer")
+ "* bufp");
addInitStr(voidSelfAssign(m_topModp));
addInitStr(symClassAssign());
addInitStr(EmitCBase::voidSelfAssign(m_topModp));
addInitStr(EmitCBase::symClassAssign());
// Add global activity check to change dump functions
if (!full) { //
addInitStr("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n");
@ -709,8 +709,8 @@ private:
cleanupFuncp->isStatic(true);
cleanupFuncp->isLoose(true);
m_topScopep->addBlocksp(cleanupFuncp);
cleanupFuncp->addInitsp(new AstCStmt{fl, voidSelfAssign(m_topModp)});
cleanupFuncp->addInitsp(new AstCStmt{fl, symClassAssign()});
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(m_topModp)});
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
// Register it
m_regFuncp->addStmtsp(new AstText{fl, "tracep->addCleanupCb(", true});

View File

@ -93,7 +93,7 @@ public:
//######################################################################
// TraceDecl state, as a visitor of each AstNode
class TraceDeclVisitor final : public EmitCBaseVisitor {
class TraceDeclVisitor final : public VNVisitor {
private:
// NODE STATE

View File

@ -169,7 +169,7 @@ class VariableOrder final {
: (sigbytes == 1) ? 2
: 10;
// Anonymous structure ok
attributes.anonOk = EmitCBaseVisitor::isAnonOk(varp);
attributes.anonOk = EmitCBase::isAnonOk(varp);
}
}