forked from github/verilator
Internals: Avoid emit inheritance in V3EmitCBase. No functional change intended.
This commit is contained in:
parent
053f760e2a
commit
82e653a739
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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});
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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});
|
||||
|
@ -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});
|
||||
|
@ -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
|
||||
|
||||
|
@ -169,7 +169,7 @@ class VariableOrder final {
|
||||
: (sigbytes == 1) ? 2
|
||||
: 10;
|
||||
// Anonymous structure ok
|
||||
attributes.anonOk = EmitCBaseVisitor::isAnonOk(varp);
|
||||
attributes.anonOk = EmitCBase::isAnonOk(varp);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user