diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 12ab9539e..0e91f5fca 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -954,10 +954,10 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound, bool packe info.m_type = "VlSampleQueue<" + sub.m_type + ">"; } else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) { UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union"); - info.m_type = "VlClassRef<" + EmitCBase::prefixNameProtect(adtypep) + ">"; + info.m_type = "VlClassRef<" + EmitCUtil::prefixNameProtect(adtypep) + ">"; } else if (const auto* const adtypep = VN_CAST(dtypep, IfaceRefDType)) { UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union"); - info.m_type = EmitCBase::prefixNameProtect(adtypep->ifaceViaCellp()) + "*"; + info.m_type = EmitCUtil::prefixNameProtect(adtypep->ifaceViaCellp()) + "*"; } else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) { UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union"); if (adtypep->isCompound()) compound = true; @@ -991,7 +991,7 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound, bool packe const AstNodeUOrStructDType* const sdtypep = VN_AS(dtypep, NodeUOrStructDType); UASSERT_OBJ(!packed || sdtypep->packed(), this, "Unsupported type for packed struct or union"); - info.m_type = EmitCBase::prefixNameProtect(sdtypep); + info.m_type = EmitCUtil::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 diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index 319ca6e87..f82eb8717 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -67,7 +67,7 @@ class V3CCtorsBuilder final { funcp->slow(!m_type.isClass()); // Only classes construct on fast path string preventUnusedStmt; if (m_type.isClass()) { - funcp->argTypes(EmitCBase::symClassVar()); + funcp->argTypes(EmitCUtil::symClassVar()); preventUnusedStmt = "(void)vlSymsp; // Prevent unused variable warning\n"; } else if (m_type.isCoverage()) { funcp->argTypes("bool first"); diff --git a/src/V3Common.cpp b/src/V3Common.cpp index 08b310e2b..fd48b2028 100644 --- a/src/V3Common.cpp +++ b/src/V3Common.cpp @@ -52,7 +52,7 @@ string V3Common::makeToStringCall(AstNodeDType* nodep, const std::string& lhs) { static void makeVlToString(AstClass* nodep) { AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"}; - funcp->argTypes("const VlClassRef<" + EmitCBase::prefixNameProtect(nodep) + ">& obj"); + funcp->argTypes("const VlClassRef<" + EmitCUtil::prefixNameProtect(nodep) + ">& obj"); funcp->isMethod(false); funcp->isConst(false); funcp->isStatic(false); @@ -66,7 +66,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 " + EmitCBase::prefixNameProtect(nodep) + "* obj"); + funcp->argTypes("const " + EmitCUtil::prefixNameProtect(nodep) + "* obj"); funcp->isMethod(false); funcp->isConst(false); funcp->isStatic(false); @@ -81,7 +81,7 @@ static void makeVlToString(AstNodeUOrStructDType* nodep) { UASSERT_OBJ(modp, nodep, "Unlinked struct package"); AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"}; - funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "& obj"); + funcp->argTypes("const " + EmitCUtil::prefixNameProtect(nodep) + "& obj"); funcp->isMethod(false); funcp->isConst(false); funcp->isStatic(false); @@ -145,7 +145,7 @@ static void makeToStringMiddle(AstClass* nodep) { string stmt = "out += "; if (!comma.empty()) stmt += "\", \"+ "; // comma = ", "; // Nothing further so not needed - stmt += EmitCBase::prefixNameProtect(nodep->extendsp()->dtypep()); + stmt += EmitCUtil::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}); diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index cbd5bd771..8513e0abd 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -57,7 +57,7 @@ class DepthBlockVisitor final : public VNVisitor { AstCCall* const callp = new AstCCall{nodep->fileline(), funcp}; callp->dtypeSetVoid(); if (VN_IS(m_modp, Class)) { - funcp->argTypes(EmitCBase::symClassVar()); + funcp->argTypes(EmitCUtil::symClassVar()); callp->argTypes("vlSymsp"); } UINFO(6, " New " << callp); diff --git a/src/V3EmitCBase.cpp b/src/V3EmitCBase.cpp index ed88656af..a6530a2d1 100644 --- a/src/V3EmitCBase.cpp +++ b/src/V3EmitCBase.cpp @@ -36,9 +36,9 @@ EmitCParentModule::EmitCParentModule() { } //###################################################################### -// EmitCBase implementation +// EmitCUtil implementation -string EmitCBase::prefixNameProtect(const AstNode* nodep) VL_MT_STABLE { +string EmitCUtil::prefixNameProtect(const AstNode* nodep) VL_MT_STABLE { const string prefix = v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name()); // If all-uppercase prefix conflicts with a previous usage of the // prefix with different capitalization, rename to avoid conflict. @@ -78,13 +78,13 @@ string EmitCBaseVisitorConst::funcNameProtect(const AstCFunc* nodep, const AstNo modp = modp ? modp : EmitCParentModule::get(nodep); string name; if (nodep->isConstructor()) { - name += prefixNameProtect(modp); + name += EmitCUtil::prefixNameProtect(modp); } else if (nodep->isDestructor()) { name += "~"; - name += prefixNameProtect(modp); + name += EmitCUtil::prefixNameProtect(modp); } else { if (nodep->isLoose()) { - name += prefixNameProtect(modp); + name += EmitCUtil::prefixNameProtect(modp); name += "__"; } name += nodep->nameProtect(); @@ -112,7 +112,7 @@ string EmitCBaseVisitorConst::cFuncArgs(const AstCFunc* nodep) { string args; if (nodep->isLoose() && !nodep->isStatic()) { if (nodep->isConst().trueKnown()) args += "const "; - args += prefixNameProtect(EmitCParentModule::get(nodep)); + args += EmitCUtil::prefixNameProtect(EmitCParentModule::get(nodep)); args += "* vlSelf"; } if (nodep->needProcess()) { @@ -150,9 +150,9 @@ void EmitCBaseVisitorConst::emitCFuncHeader(const AstCFunc* funcp, const AstNode } if (withScope) { if (funcp->dpiExportDispatcher()) { - putns(funcp, topClassName() + "::"); + putns(funcp, EmitCUtil::topClassName() + "::"); } else if (funcp->isProperMethod()) { - putns(funcp, prefixNameProtect(modp) + "::"); + putns(funcp, EmitCUtil::prefixNameProtect(modp) + "::"); } } putns(funcp, funcNameProtect(funcp, modp)); @@ -313,7 +313,7 @@ std::pair EmitCBaseVisitorConst::textSection(const AstNodeMod string::size_type pos; while ((pos = text.find("`systemc_class_name")) != string::npos) { text.replace(pos, std::strlen("`systemc_class_name"), - EmitCBase::prefixNameProtect(modp)); + EmitCUtil::prefixNameProtect(modp)); } } return std::make_pair(text, fl); diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index e9baa02d0..c8b332e0b 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -45,9 +45,9 @@ public: }; //###################################################################### -// Base Visitor class -- holds output file pointer +// EmitC-related utility functions -class EmitCBase VL_NOT_FINAL { +class EmitCUtil final { public: static string voidSelfAssign(const AstNodeModule* modp) { const string className = prefixNameProtect(modp); @@ -81,7 +81,10 @@ public: } }; -class EmitCBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst, public EmitCBase { +//###################################################################### +// Base Visitor class -- holds output file pointer + +class EmitCBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst { public: // STATE V3OutCFile* m_ofp = nullptr; @@ -130,15 +133,6 @@ public: void ensureNewLine() { ofp()->ensureNewLine(); } bool optSystemC() { return v3Global.opt.systemC(); } 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); - } - static string protectWordsIf(const string& name, bool doIt) { - return VIdProtect::protectWordsIf(name, doIt); - } - static string ifNoProtect(const string& in) VL_MT_SAFE { - return v3Global.opt.protectIds() ? "" : in; - } static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr); static AstCFile* newCFile(const string& filename, bool slow, bool source); static AstCFile* createCFile(const string& filename, bool slow, bool source) VL_MT_SAFE; @@ -153,11 +147,11 @@ public: if (const AstCUse* const usep = VN_CAST(itemp, CUse)) { if (usep->useType().containsAny(useType)) { if (usep->useType().containsAny(VUseType::INT_INCLUDE)) { - action("#include \"" + prefixNameProtect(usep) + ".h\"\n"); + action("#include \"" + EmitCUtil::prefixNameProtect(usep) + ".h\"\n"); continue; // Forward declaration is not necessary } if (usep->useType().containsAny(VUseType::INT_FWD_CLASS)) { - action("class " + prefixNameProtect(usep) + ";\n"); + action("class " + EmitCUtil::prefixNameProtect(usep) + ";\n"); } } } diff --git a/src/V3EmitCConstInit.h b/src/V3EmitCConstInit.h index 051b75fb4..63c176350 100644 --- a/src/V3EmitCConstInit.h +++ b/src/V3EmitCConstInit.h @@ -32,7 +32,6 @@ class EmitCConstInit VL_NOT_FINAL : public EmitCBaseVisitorConst { bool m_inUnpacked = false; // METHODS - uint32_t tabModulus(const AstNodeDType* dtypep) { const uint32_t elemBytes = dtypep->widthTotalBytes(); return dtypep->isString() ? 1 // String @@ -99,6 +98,7 @@ protected: } // LCOV_EXCL_STOP void visit(AstConst* nodep) override { + // TODO merge with EmitCFunc::emitConstant const V3Number& num = nodep->num(); UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool"); const AstNodeDType* const dtypep = nodep->dtypep(); diff --git a/src/V3EmitCConstPool.cpp b/src/V3EmitCConstPool.cpp index 3f9565d0a..6dc2043c0 100644 --- a/src/V3EmitCConstPool.cpp +++ b/src/V3EmitCConstPool.cpp @@ -42,8 +42,8 @@ class EmitCConstPool final : public EmitCConstInit { // METHODS OutCFilePair newOutCFile() const { - const string fileName = v3Global.opt.makeDir() + "/" + topClassName() + "__ConstPool_" - + cvtToStr(m_outFileCount) + ".cpp"; + const string fileName = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + + "__ConstPool_" + cvtToStr(m_outFileCount) + ".cpp"; AstCFile* const cfilep = newCFile(fileName, /* slow: */ true, /* source: */ true); V3OutCFile* const ofp = new V3OutCFile{fileName}; ofp->putsHeader(); @@ -84,7 +84,8 @@ class EmitCConstPool final : public EmitCConstInit { for (const AstVar* varp : varps) { maybeSplitCFile(); - const string nameProtect = topClassName() + "__ConstPool__" + varp->nameProtect(); + const string nameProtect + = EmitCUtil::topClassName() + "__ConstPool__" + varp->nameProtect(); puts("\n"); putns(varp, "extern const "); putns(varp, varp->dtypep()->cType(nameProtect, false, false)); diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index 833127d24..05bb63602 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -488,6 +488,7 @@ void EmitCFunc::emitCvtWideArray(AstNode* nodep, AstNode* fromp) { void EmitCFunc::emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) { // Put out constant set to the specified variable, or given variable in a string + // TODO merge with V3EmitCConstInit::visit(AstConst) putns(nodep, ""); if (nodep->num().isNull()) { putns(nodep, "VlNull{}"); diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 46a42d316..5506ebb83 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -64,7 +64,7 @@ class EmitCLazyDecls final : public VNVisitorConst { void lazyDeclareConstPoolVar(AstVar* varp) { if (!declaredOnce(varp)) return; // Already declared const string nameProtect - = m_emitter.topClassName() + "__ConstPool__" + varp->nameProtect(); + = EmitCUtil::topClassName() + "__ConstPool__" + varp->nameProtect(); m_emitter.putns(varp, "extern const "); m_emitter.puts(varp->dtypep()->cType(nameProtect, false, false)); m_emitter.puts(";\n"); @@ -85,7 +85,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 (EmitCBase::isConstPoolMod(EmitCParentModule::get(varp))) { + if (EmitCUtil::isConstPoolMod(EmitCParentModule::get(varp))) { lazyDeclareConstPoolVar(varp); } } @@ -272,7 +272,7 @@ public: if (doneClasses.count(vbase)) continue; puts(doneClasses.empty() ? "" : "\n , "); doneClasses.emplace(vbase); - puts(prefixNameProtect(vbase)); + puts(EmitCUtil::EmitCUtil::prefixNameProtect(vbase)); if (constructorNeedsProcess(vbase)) { puts("(vlProcess, vlSymsp)"); } else { @@ -287,7 +287,7 @@ public: if (doneClasses.count(extp->classp())) continue; puts(doneClasses.empty() ? "" : "\n , "); doneClasses.emplace(extp->classp()); - puts(prefixNameProtect(extp->classp())); + puts(EmitCUtil::EmitCUtil::prefixNameProtect(extp->classp())); if (constructorNeedsProcess(extp->classp())) { puts("(vlProcess, vlSymsp"); } else { @@ -349,7 +349,7 @@ public: // "+" in the debug indicates a print from the model puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ "); for (int i = 0; i < m_modp->level(); ++i) puts(" "); - puts(prefixNameProtect(m_modp)); + puts(EmitCUtil::prefixNameProtect(m_modp)); puts(nodep->isLoose() ? "__" : "::"); puts(nodep->nameProtect() + "\\n\"); );\n"); @@ -358,7 +358,7 @@ public: if (!nodep->isStatic()) { // Standard prologue m_useSelfForThis = true; if (!VN_IS(m_modp, Class)) { - puts(symClassAssign()); // Uses vlSelf + puts(EmitCUtil::symClassAssign()); // Uses vlSelf } else { puts("(void)vlSelf; // Prevent unused variable warning\n"); } @@ -606,11 +606,11 @@ public: putns(nodep, funcp->name()); } else if (funcp->isProperMethod() && funcp->isStatic()) { // Call static method via the containing class - putns(funcModp, prefixNameProtect(funcModp) + "::"); + putns(funcModp, EmitCUtil::prefixNameProtect(funcModp) + "::"); putns(nodep, funcp->nameProtect()); } else if (nodep->superReference()) { // Calling superclass method - putns(funcModp, prefixNameProtect(funcModp) + "::"); + putns(funcModp, EmitCUtil::prefixNameProtect(funcModp) + "::"); putns(nodep, funcp->nameProtect()); } else if (funcp->isLoose()) { // Calling loose method @@ -642,7 +642,7 @@ public: return; } // assignment case; - putns(nodep, "VL_NEW(" + prefixNameProtect(nodep->dtypep()) + ", " + putns(nodep, "VL_NEW(" + EmitCUtil::prefixNameProtect(nodep->dtypep()) + ", " + optionalProcArg(nodep->dtypep()) + "vlSymsp"); putCommaIterateNext(nodep->argsp(), true); puts(")"); @@ -716,11 +716,11 @@ public: puts(cvtToStr(nodep->offset() + nodep->fileline()->firstColumn())); puts(", "); putsQuoted((!nodep->hier().empty() ? "." : "") - + protectWordsIf(nodep->hier(), nodep->protect())); + + VIdProtect::protectWordsIf(nodep->hier(), nodep->protect())); puts(", "); - putsQuoted(protectWordsIf(nodep->page(), nodep->protect())); + putsQuoted(VIdProtect::protectWordsIf(nodep->page(), nodep->protect())); puts(", "); - putsQuoted(protectWordsIf(nodep->comment(), nodep->protect())); + putsQuoted(VIdProtect::protectWordsIf(nodep->comment(), nodep->protect())); puts(", "); putsQuoted(nodep->linescov()); puts(");\n"); @@ -750,11 +750,11 @@ public: puts(cvtToStr(nodep->fileline()->firstColumn())); puts(", "); putsQuoted((!nodep->hier().empty() ? "." : "") - + protectWordsIf(nodep->hier(), nodep->protect())); + + VIdProtect::protectWordsIf(nodep->hier(), nodep->protect())); puts(", "); - putsQuoted(protectWordsIf(nodep->page(), nodep->protect())); + putsQuoted(VIdProtect::protectWordsIf(nodep->page(), nodep->protect())); puts(", "); - putsQuoted(protectWordsIf(nodep->comment(), nodep->protect())); + putsQuoted(VIdProtect::protectWordsIf(nodep->comment(), nodep->protect())); puts(");\n"); } void visit(AstCoverInc* nodep) override { @@ -1254,8 +1254,8 @@ public: VL_RESTORER(m_inUC); m_inUC = true; putnbs(nodep, ""); - putsDecoration(nodep, - ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n")); + putsDecoration(nodep, VIdProtect::ifNoProtect("// $c statement at " + + nodep->fileline()->ascii() + "\n")); iterateAndNextConstNull(nodep->exprsp()); puts("\n"); } @@ -1264,8 +1264,8 @@ public: m_inUC = true; puts("\n"); putnbs(nodep, ""); - putsDecoration(nodep, - ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n")); + putsDecoration(nodep, VIdProtect::ifNoProtect("// $c function at " + + nodep->fileline()->ascii() + "\n")); iterateAndNextConstNull(nodep->exprsp()); puts("\n"); } @@ -1385,7 +1385,7 @@ public: puts(")"); } void visit(AstNewCopy* nodep) override { - putns(nodep, "VL_NEW(" + prefixNameProtect(nodep->dtypep())); + putns(nodep, "VL_NEW(" + EmitCUtil::prefixNameProtect(nodep->dtypep())); puts(", *"); // i.e. make into a reference iterateAndNextConstNull(nodep->rhsp()); puts(")"); @@ -1467,15 +1467,15 @@ public: void visit(AstVarRef* nodep) override { const AstVar* const varp = nodep->varp(); const AstNodeModule* const varModp = EmitCParentModule::get(varp); - if (isConstPoolMod(varModp)) { + if (EmitCUtil::isConstPoolMod(varModp)) { // Reference to constant pool variable - putns(nodep, topClassName() + "__ConstPool__"); + putns(nodep, EmitCUtil::topClassName() + "__ConstPool__"); } else if (varp->isStatic()) { // Access static variable via the containing class - putns(nodep, prefixNameProtect(varModp) + "::"); + putns(nodep, EmitCUtil::prefixNameProtect(varModp) + "::"); } else if (VN_IS(varModp, Class) && varModp != m_modp) { // Superclass member reference - putns(nodep, prefixNameProtect(varModp) + "::"); + putns(nodep, EmitCUtil::prefixNameProtect(varModp) + "::"); } else if (varp->isIfaceRef()) { putns(nodep, nodep->selfPointerProtect(m_useSelfForThis)); return; diff --git a/src/V3EmitCHeaders.cpp b/src/V3EmitCHeaders.cpp index c7a5824f1..f3875a7e9 100644 --- a/src/V3EmitCHeaders.cpp +++ b/src/V3EmitCHeaders.cpp @@ -47,8 +47,8 @@ class EmitCHeader final : public EmitCConstInit { for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (const AstCell* const cellp = VN_CAST(nodep, Cell)) { decorateFirst(first, "// CELLS\n"); - putns(cellp, - prefixNameProtect(cellp->modp()) + "* " + cellp->nameProtect() + ";\n"); + putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* " + + cellp->nameProtect() + ";\n"); } } } @@ -111,7 +111,7 @@ class EmitCHeader final : public EmitCConstInit { if (const AstVar* const varp = VN_CAST(nodep, Var)) { if (varp->isIO() || varp->isSignal() || varp->isClassMember() || varp->isTemp() || varp->isGenVar()) { - const bool anon = isAnonOk(varp); + const bool anon = EmitCUtil::isAnonOk(varp); if (anon != lastAnon) emitCurrentList(); lastAnon = anon; varList.emplace_back(varp); @@ -130,7 +130,7 @@ class EmitCHeader final : public EmitCConstInit { } } else { // not class putsDecoration(nullptr, "\n// INTERNAL VARIABLES\n"); - puts(symClassName() + "* const vlSymsp;\n"); + puts(EmitCUtil::symClassName() + "* const vlSymsp;\n"); } } void emitParamDecls(const AstNodeModule* modp) { @@ -156,9 +156,10 @@ class EmitCHeader final : public EmitCConstInit { } void emitCtorDtorDecls(const AstNodeModule* modp) { if (!VN_IS(modp, Class)) { // Classes use CFuncs with isConstructor/isDestructor - const string& name = prefixNameProtect(modp); + const string& name = EmitCUtil::prefixNameProtect(modp); putsDecoration(nullptr, "\n// CONSTRUCTORS\n"); - putns(modp, name + "(" + symClassName() + "* symsp, const char* v__name);\n"); + putns(modp, + name + "(" + EmitCUtil::symClassName() + "* symsp, const char* v__name);\n"); putns(modp, "~" + name + "();\n"); putns(modp, "VL_UNCOPYABLE(" + name + ");\n"); } @@ -290,7 +291,7 @@ class EmitCHeader final : public EmitCConstInit { } void emitUnpackedUOrSBody(AstNodeUOrStructDType* sdtypep) { putns(sdtypep, sdtypep->verilogKwd()); // "struct"/"union" - puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n"); + puts(" " + EmitCUtil::prefixNameProtect(sdtypep) + " {\n"); for (const AstMemberDType* itemp = sdtypep->membersp(); itemp; itemp = VN_AS(itemp->nextp(), MemberDType)) { putns(itemp, itemp->dtypep()->cType(itemp->nameProtect(), false, false)); @@ -347,7 +348,7 @@ class EmitCHeader final : public EmitCConstInit { } puts(");\n}\n"); } - putns(sdtypep, "\nbool operator==(const " + EmitCBase::prefixNameProtect(sdtypep) + putns(sdtypep, "\nbool operator==(const " + EmitCUtil::prefixNameProtect(sdtypep) + "& rhs) const {\n"); puts("return "); for (const AstMemberDType* itemp = sdtypep->membersp(); itemp; @@ -357,10 +358,10 @@ class EmitCHeader final : public EmitCConstInit { } puts(";\n"); puts("}\n"); - putns(sdtypep, "bool operator!=(const " + EmitCBase::prefixNameProtect(sdtypep) + putns(sdtypep, "bool operator!=(const " + EmitCUtil::prefixNameProtect(sdtypep) + "& rhs) const {\n"); puts("return !(*this == rhs);\n}\n"); - putns(sdtypep, "\nbool operator<(const " + EmitCBase::prefixNameProtect(sdtypep) + putns(sdtypep, "\nbool operator<(const " + EmitCUtil::prefixNameProtect(sdtypep) + "& rhs) const {\n"); puts("return "); puts("std::tie("); @@ -379,7 +380,7 @@ class EmitCHeader final : public EmitCConstInit { puts("}\n"); puts("};\n"); puts("template <>\n"); - putns(sdtypep, "struct VlIsCustomStruct<" + EmitCBase::prefixNameProtect(sdtypep) + putns(sdtypep, "struct VlIsCustomStruct<" + EmitCUtil::prefixNameProtect(sdtypep) + "> : public std::true_type {};\n"); } @@ -457,7 +458,7 @@ class EmitCHeader final : public EmitCConstInit { } void emitPackedUOrSBody(AstNodeUOrStructDType* sdtypep) { putns(sdtypep, sdtypep->verilogKwd()); // "struct"/"union" - puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n"); + puts(" " + EmitCUtil::prefixNameProtect(sdtypep) + " {\n"); AstMemberDType* itemp; AstMemberDType* lastItemp; @@ -553,13 +554,14 @@ class EmitCHeader final : public EmitCConstInit { if (const AstClass* const classp = VN_CAST(modp, Class)) { for (const AstClassExtends* extp = classp->extendsp(); extp; extp = VN_AS(extp->nextp(), ClassExtends)) { - putns(extp, "#include \"" + prefixNameProtect(extp->classp()->classOrPackagep()) + putns(extp, "#include \"" + + EmitCUtil::prefixNameProtect(extp->classp()->classOrPackagep()) + ".h\"\n"); } } // Forward declarations required by this AstNodeModule - puts("\nclass " + symClassName() + ";\n"); + puts("\nclass " + EmitCUtil::symClassName() + ";\n"); // From `systemc_header emitTextSection(modp, VNType::atScHdr); @@ -570,7 +572,7 @@ class EmitCHeader final : public EmitCConstInit { puts("\n"); putns(modp, "class "); if (!VN_IS(modp, Class)) puts("alignas(VL_CACHE_LINE_BYTES) "); - puts(prefixNameProtect(modp)); + puts(EmitCUtil::prefixNameProtect(modp)); if (const AstClass* const classp = VN_CAST(modp, Class)) { puts(" : "); if (classp->extendsp()) { @@ -581,7 +583,7 @@ class EmitCHeader final : public EmitCConstInit { // Use virtual only for interfaces for class inheritance // (extends) puts(extp->classp()->useVirtualPublic() ? "virtual public " : "public "); - putns(extp, prefixNameProtect(extp->classp())); + putns(extp, EmitCUtil::prefixNameProtect(extp->classp())); needComma = true; } } else { @@ -618,10 +620,11 @@ class EmitCHeader final : public EmitCConstInit { } explicit EmitCHeader(const AstNodeModule* modp) { - UINFO(5, " Emitting header for " << prefixNameProtect(modp)); + UINFO(5, " Emitting header for " << EmitCUtil::prefixNameProtect(modp)); // Open output file - const string filename = v3Global.opt.makeDir() + "/" + prefixNameProtect(modp) + ".h"; + const string filename + = v3Global.opt.makeDir() + "/" + EmitCUtil::prefixNameProtect(modp) + ".h"; AstCFile* const cfilep = newCFile(filename, /* slow: */ false, /* source: */ false); V3OutCFile* const ofilep = v3Global.opt.systemC() ? new V3OutScFile{filename} : new V3OutCFile{filename}; @@ -630,7 +633,7 @@ class EmitCHeader final : public EmitCConstInit { ofp()->putsHeader(); puts("// DESCRIPTION: Verilator output: Design internal header\n"); - puts("// See " + topClassName() + ".h for the primary calling header\n"); + puts("// See " + EmitCUtil::topClassName() + ".h for the primary calling header\n"); ofp()->putsGuard(); diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index febb88222..dacde7180 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -35,23 +35,23 @@ class EmitCGatherDependencies final : VNVisitorConst { std::set m_dependencies; // Header names to be included in output C++ file // METHODS - void addSymsDependency() { m_dependencies.insert(EmitCBase::symClassName()); } + void addSymsDependency() { m_dependencies.insert(EmitCUtil::symClassName()); } void addModDependency(const AstNodeModule* modp) { if (const AstClass* const classp = VN_CAST(modp, Class)) { - m_dependencies.insert(EmitCBase::prefixNameProtect(classp->classOrPackagep())); + m_dependencies.insert(EmitCUtil::prefixNameProtect(classp->classOrPackagep())); } else { - m_dependencies.insert(EmitCBase::prefixNameProtect(modp)); + m_dependencies.insert(EmitCUtil::prefixNameProtect(modp)); } } void addDTypeDependency(const AstNodeDType* nodep) { if (const AstClassRefDType* const dtypep = VN_CAST(nodep, ClassRefDType)) { m_dependencies.insert( - EmitCBase::prefixNameProtect(dtypep->classp()->classOrPackagep())); + EmitCUtil::prefixNameProtect(dtypep->classp()->classOrPackagep())); } else if (const AstNodeUOrStructDType* const dtypep = VN_CAST(nodep, NodeUOrStructDType)) { if (!dtypep->packed()) { UASSERT_OBJ(dtypep->classOrPackagep(), nodep, "Unlinked struct package"); - m_dependencies.insert(EmitCBase::prefixNameProtect(dtypep->classOrPackagep())); + m_dependencies.insert(EmitCUtil::prefixNameProtect(dtypep->classOrPackagep())); } } } @@ -177,7 +177,8 @@ class EmitCImp final : EmitCFunc { V3OutCFile* const ofilep = new V3OutCFile{filename}; setOutputFile(ofilep, filep); } else { - string filename = v3Global.opt.makeDir() + "/" + prefixNameProtect(m_fileModp); + string filename + = v3Global.opt.makeDir() + "/" + EmitCUtil::prefixNameProtect(m_fileModp); if (!subFileName.empty()) { filename += "__" + subFileName; filename = m_uniqueNames.get(filename); @@ -193,10 +194,10 @@ class EmitCImp final : EmitCFunc { putsHeader(); puts("// DESCRIPTION: Verilator output: Design implementation internals\n"); - puts("// See " + topClassName() + ".h for the primary calling header\n"); + puts("// See " + EmitCUtil::topClassName() + ".h for the primary calling header\n"); puts("\n"); - puts("#include \"" + pchClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n"); for (const string& name : headers) puts("#include \"" + name + ".h\"\n"); emitTextSection(m_modp, VNType::atScImpHdr); @@ -204,7 +205,7 @@ class EmitCImp final : EmitCFunc { void emitStaticVarDefns(const AstNodeModule* modp) { // Emit static variable definitions - const string modName = prefixNameProtect(modp); + const string modName = EmitCUtil::prefixNameProtect(modp); for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (const AstVar* const varp = VN_CAST(nodep, Var)) { if (varp->isStatic()) { @@ -215,7 +216,7 @@ class EmitCImp final : EmitCFunc { } } void emitParamDefns(const AstNodeModule* modp) { - const string modName = prefixNameProtect(modp); + const string modName = EmitCUtil::prefixNameProtect(modp); bool first = true; for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (const AstVar* const varp = VN_CAST(nodep, Var)) { @@ -242,15 +243,15 @@ class EmitCImp final : EmitCFunc { if (!first) puts("\n"); } void emitCtorImp(const AstNodeModule* modp) { - const string modName = prefixNameProtect(modp); + const string modName = EmitCUtil::prefixNameProtect(modp); puts("\n"); m_lazyDecls.emit("void " + modName + "__", protect("_ctor_var_reset"), "(" + modName + "* vlSelf);"); puts("\n"); - putns(modp, - modName + "::" + modName + "(" + symClassName() + "* symsp, const char* v__name)\n"); + putns(modp, modName + "::" + modName + "(" + EmitCUtil::symClassName() + + "* symsp, const char* v__name)\n"); puts(" : VerilatedModule{v__name}\n"); ofp()->indentInc(); @@ -290,7 +291,7 @@ class EmitCImp final : EmitCFunc { puts("}\n"); } void emitConfigureImp(const AstNodeModule* modp) { - const string modName = prefixNameProtect(modp); + const string modName = EmitCUtil::prefixNameProtect(modp); if (v3Global.opt.coverage()) { puts("\n"); @@ -312,7 +313,7 @@ class EmitCImp final : EmitCFunc { // arguments. if (v3Global.opt.coverage()) { puts("\n// Coverage\n"); - puts("void " + prefixNameProtect(m_modp) + "::__vlCoverInsert("); + puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "::__vlCoverInsert("); puts(v3Global.opt.threads() > 1 ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); puts("const char* hierp, const char* pagep, const char* commentp, const char* " @@ -344,7 +345,7 @@ class EmitCImp final : EmitCFunc { } if (v3Global.opt.coverageToggle()) { puts("\n// Toggle Coverage\n"); - puts("void " + prefixNameProtect(m_modp) + "::__vlCoverToggleInsert("); + puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "::__vlCoverToggleInsert("); puts("int begin, int end, bool ranged, "); puts(v3Global.opt.threads() > 1 ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); @@ -390,7 +391,8 @@ class EmitCImp final : EmitCFunc { } void emitDestructorImp(const AstNodeModule* modp) { puts("\n"); - putns(modp, prefixNameProtect(modp) + "::~" + prefixNameProtect(modp) + "() {\n"); + putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp) + + "() {\n"); emitTextSection(modp, VNType::atScDtor); puts("}\n"); splitSizeInc(10); @@ -403,8 +405,8 @@ class EmitCImp final : EmitCFunc { const string funcname = de ? "__Vdeserialize" : "__Vserialize"; const string op = de ? ">>" : "<<"; // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - putns(modp, "void " + prefixNameProtect(modp) + "::" + protect(funcname) + "(" - + classname + "& os) {\n"); + putns(modp, "void " + EmitCUtil::prefixNameProtect(modp) + "::" + protect(funcname) + + "(" + classname + "& os) {\n"); // Place a computed checksum to ensure proper structure save/restore formatting // OK if this hash includes some things we won't dump, since // just looking for loading the wrong model @@ -514,8 +516,8 @@ class EmitCImp final : EmitCFunc { if (hasCommonImp(modp) || hasCommonImp(classp)) { std::set headers; - headers.insert(prefixNameProtect(m_fileModp)); - headers.insert(symClassName()); + headers.insert(EmitCUtil::prefixNameProtect(m_fileModp)); + headers.insert(EmitCUtil::symClassName()); openNextOutputFile(headers, ""); @@ -595,7 +597,7 @@ class EmitCImp final : EmitCFunc { : m_fileModp{modp} , m_slow{slow} , m_cfilesr{cfilesr} { - UINFO(5, " Emitting implementation of " << prefixNameProtect(modp)); + UINFO(5, " Emitting implementation of " << EmitCUtil::prefixNameProtect(modp)); m_modp = modp; @@ -644,7 +646,7 @@ class EmitCTrace final : EmitCFunc { m_lazyDecls.reset(); // Need to emit new lazy declarations string filename - = (v3Global.opt.makeDir() + "/" + topClassName() + "_" + protect("_Trace")); + = (v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "_" + protect("_Trace")); filename = m_uniqueNames.get(filename); if (m_slow) filename += "__Slow"; filename += ".cpp"; @@ -663,7 +665,7 @@ class EmitCTrace final : EmitCFunc { // Includes puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n"); - puts("#include \"" + symClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n"); puts("\n"); } @@ -672,8 +674,8 @@ class EmitCTrace final : EmitCFunc { void openNextTypesFile() { UASSERT(!m_typesFp, "Declarations output file already open"); - string filename - = (v3Global.opt.makeDir() + "/" + topClassName() + "_" + protect("_TraceDecls")); + string filename = (v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "_" + + protect("_TraceDecls")); filename = m_uniqueNames.get(filename); filename += "__Slow.cpp"; @@ -694,7 +696,7 @@ class EmitCTrace final : EmitCFunc { typesFp()->puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n"); typesFp()->puts("\n"); - typesFp()->puts("\nvoid " + prefixNameProtect(m_modp) + "__" + typesFp()->puts("\nvoid " + EmitCUtil::prefixNameProtect(m_modp) + "__" + protect("traceDeclTypesSub" + cvtToStr(m_traceTypeSubs++)) + "(" + v3Global.opt.traceClassBase() + "* tracep) {\n"); } @@ -709,15 +711,16 @@ class EmitCTrace final : EmitCFunc { // Forward declarations for subs in other files for (int i = 0; i < m_traceTypeSubs - 1; ++i) { - typesFp()->puts("void " + prefixNameProtect(m_modp) + "__" + typesFp()->puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "__" + protect("traceDeclTypesSub" + cvtToStr(i)) + "(" + v3Global.opt.traceClassBase() + "* tracep);\n"); } - typesFp()->puts("\nvoid " + prefixNameProtect(m_modp) + "__" + protect("trace_decl_types") - + "(" + v3Global.opt.traceClassBase() + "* tracep) {\n"); + typesFp()->puts("\nvoid " + EmitCUtil::prefixNameProtect(m_modp) + "__" + + protect("trace_decl_types") + "(" + v3Global.opt.traceClassBase() + + "* tracep) {\n"); for (int i = 0; i < m_traceTypeSubs; ++i) { - typesFp()->puts(prefixNameProtect(m_modp) + "__" + typesFp()->puts(EmitCUtil::prefixNameProtect(m_modp) + "__" + protect("traceDeclTypesSub" + cvtToStr(i)) + "(tracep);\n"); } } diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index 8ee6fe5a2..0648d4564 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -41,7 +41,8 @@ public: private: // MAIN METHOD void emitInt() { - const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__main.cpp"; + const string filename + = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__main.cpp"; AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/); V3OutCFile cf{filename}; setOutputFile(&cf, cfilep); @@ -59,7 +60,7 @@ private: puts("\n"); puts("#include \"verilated.h\"\n"); - puts("#include \"" + topClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n"); puts("\n//======================\n\n"); @@ -72,8 +73,8 @@ private: puts("\n"); puts("// Construct the Verilated model, from Vtop.h generated from Verilating\n"); - puts("const std::unique_ptr<" + topClassName() + "> topp{new " + topClassName() - + "{contextp.get(), \"" + topName + "\"}};\n"); + puts("const std::unique_ptr<" + EmitCUtil::topClassName() + "> topp{new " + + EmitCUtil::topClassName() + "{contextp.get(), \"" + topName + "\"}};\n"); puts("\n"); puts("// Simulate until $finish\n"); diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index 0b9f300de..73ecf202d 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -55,7 +55,7 @@ class EmitCModel final : public EmitCFunc { void emitHeader(AstNodeModule* modp) { UASSERT(!ofp(), "Output file should not be open"); - const string filename = v3Global.opt.makeDir() + "/" + topClassName() + ".h"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".h"; setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename} : new V3OutCFile{filename}, newCFile(filename, /* slow: */ false, /* source: */ false)); @@ -80,15 +80,16 @@ class EmitCModel final : public EmitCFunc { // Declare foreign instances up front to make C++ happy puts("\n"); - puts("class " + symClassName() + ";\n"); - puts("class " + prefixNameProtect(modp) + ";\n"); // For rootp pointer only + puts("class " + EmitCUtil::symClassName() + ";\n"); + puts("class " + EmitCUtil::prefixNameProtect(modp) + ";\n"); // For rootp pointer only if (v3Global.opt.trace()) puts("class " + v3Global.opt.traceClassLang() + ";\n"); emitModCUse(modp, VUseType::INT_FWD_CLASS); // Note: This is needed for cell forwarding puts("\n"); puts("// This class is the main interface to the Verilated model\n"); - putns(modp, "class alignas(VL_CACHE_LINE_BYTES) " + topClassName() + " VL_NOT_FINAL : "); + putns(modp, "class alignas(VL_CACHE_LINE_BYTES) " + EmitCUtil::topClassName() + + " VL_NOT_FINAL : "); if (optSystemC()) { // SC_MODULE, but with multiple-inheritance of VerilatedModel puts("public ::sc_core::sc_module, "); @@ -98,7 +99,7 @@ class EmitCModel final : public EmitCFunc { ofp()->putsPrivate(true); // private: puts("// Symbol table holding complete model state (owned by this class)\n"); - puts(symClassName() + "* const vlSymsp;\n"); + puts(EmitCUtil::symClassName() + "* const vlSymsp;\n"); puts("\n"); ofp()->putsPrivate(false); // public: @@ -138,36 +139,36 @@ class EmitCModel final : public EmitCFunc { "// Otherwise the application code can consider these internals.\n"); for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (const AstCell* const cellp = VN_CAST(nodep, Cell)) { - putns(cellp, prefixNameProtect(cellp->modp()) + "* const " + cellp->nameProtect() - + ";\n"); + putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* const " + + cellp->nameProtect() + ";\n"); } } // root instance pointer (for access to internals, including public_flat items). puts("\n// Root instance pointer to allow access to model internals,\n" "// including inlined /* verilator public_flat_* */ items.\n"); - puts(prefixNameProtect(modp) + "* const rootp;\n"); + puts(EmitCUtil::prefixNameProtect(modp) + "* const rootp;\n"); puts("\n"); ofp()->putsPrivate(false); // public: puts("// CONSTRUCTORS\n"); if (optSystemC()) { - puts("SC_CTOR(" + topClassName() + ");\n"); - puts("virtual ~" + topClassName() + "();\n"); + puts("SC_CTOR(" + EmitCUtil::topClassName() + ");\n"); + puts("virtual ~" + EmitCUtil::topClassName() + "();\n"); } else { puts("/// Construct the model; called by application code\n"); puts("/// If contextp is null, then the model will use the default global " "context\n"); puts("/// If name is \"\", then makes a wrapper with a\n"); puts("/// single model invisible with respect to DPI scope names.\n"); - puts("explicit " + topClassName() + "(VerilatedContext* contextp," + puts("explicit " + EmitCUtil::topClassName() + "(VerilatedContext* contextp," + " const char* name = \"TOP\");\n"); - puts("explicit " + topClassName() + "(const char* name = \"TOP\");\n"); + puts("explicit " + EmitCUtil::topClassName() + "(const char* name = \"TOP\");\n"); puts("/// Destroy the model; called (often implicitly) by application code\n"); - puts("virtual ~" + topClassName() + "();\n"); + puts("virtual ~" + EmitCUtil::topClassName() + "();\n"); } ofp()->putsPrivate(true); - puts("VL_UNCOPYABLE(" + topClassName() + "); ///< Copying not allowed\n"); + puts("VL_UNCOPYABLE(" + EmitCUtil::topClassName() + "); ///< Copying not allowed\n"); puts("\n"); ofp()->putsPrivate(false); // public: @@ -243,9 +244,9 @@ class EmitCModel final : public EmitCFunc { puts("\n"); puts("// Serialization functions\n"); puts("friend VerilatedSerialize& operator<<(VerilatedSerialize& os, " // - + topClassName() + "& rhs);\n"); + + EmitCUtil::topClassName() + "& rhs);\n"); puts("friend VerilatedDeserialize& operator>>(VerilatedDeserialize& os, " - + topClassName() + "& rhs);\n"); + + EmitCUtil::topClassName() + "& rhs);\n"); } puts("\n// Abstract methods from VerilatedModel\n"); @@ -277,15 +278,17 @@ class EmitCModel final : public EmitCFunc { putSectionDelimiter("Constructors"); puts("\n"); - putns(modp, topClassName() + "::" + topClassName()); + putns(modp, EmitCUtil::topClassName() + "::" + EmitCUtil::topClassName()); if (optSystemC()) { puts("(sc_core::sc_module_name /* unused */)\n"); puts(" : VerilatedModel{*Verilated::threadContextp()}\n"); - puts(" , vlSymsp{new " + symClassName() + "(contextp(), name(), this)}\n"); + puts(" , vlSymsp{new " + EmitCUtil::symClassName() + + "(contextp(), name(), this)}\n"); } else { puts(+"(VerilatedContext* _vcontextp__, const char* _vcname__)\n"); puts(" : VerilatedModel{*_vcontextp__}\n"); - puts(" , vlSymsp{new " + symClassName() + "(contextp(), _vcname__, this)}\n"); + puts(" , vlSymsp{new " + EmitCUtil::symClassName() + + "(contextp(), _vcname__, this)}\n"); } // Set up IO references @@ -356,8 +359,10 @@ class EmitCModel final : public EmitCFunc { if (!optSystemC()) { puts("\n"); - puts(topClassName() + "::" + topClassName() + "(const char* _vcname__)\n"); - puts(" : " + topClassName() + "(Verilated::threadContextp(), _vcname__)\n{\n}\n"); + puts(EmitCUtil::topClassName() + "::" + EmitCUtil::topClassName() + + "(const char* _vcname__)\n"); + puts(" : " + EmitCUtil::topClassName() + + "(Verilated::threadContextp(), _vcname__)\n{\n}\n"); } } @@ -365,7 +370,7 @@ class EmitCModel final : public EmitCFunc { putSectionDelimiter("Destructor"); puts("\n"); - puts(topClassName() + "::~" + topClassName() + "() {\n"); + puts(EmitCUtil::topClassName() + "::~" + EmitCUtil::topClassName() + "() {\n"); puts("delete vlSymsp;\n"); puts("}\n"); } @@ -373,7 +378,7 @@ class EmitCModel final : public EmitCFunc { void emitStandardMethods1(AstNodeModule* modp) { UASSERT_OBJ(modp->isTop(), modp, "Attempting to emitWrapEval for non-top class"); - const string topModNameProtected = prefixNameProtect(modp); + const string topModNameProtected = EmitCUtil::prefixNameProtect(modp); const string selfDecl = "(" + topModNameProtected + "* vlSelf)"; putSectionDelimiter("Evaluation function"); @@ -391,7 +396,7 @@ class EmitCModel final : public EmitCFunc { if (optSystemC() && v3Global.usesTiming()) { // ::eval - puts("\nvoid " + topClassName() + "::eval() {\n"); + puts("\nvoid " + EmitCUtil::topClassName() + "::eval() {\n"); puts("eval_step();\n"); puts("if (eventsPending()) {\n"); puts("sc_core::sc_time dt = sc_core::sc_time::from_value(nextTimeSlot() - " @@ -403,14 +408,14 @@ class EmitCModel final : public EmitCFunc { puts("}\n"); // ::eval_sens - puts("\nvoid " + topClassName() + "::eval_sens() {\n"); + puts("\nvoid " + EmitCUtil::topClassName() + "::eval_sens() {\n"); puts("trigger_eval.notify();\n"); puts("}\n"); } // ::eval_step - puts("\nvoid " + topClassName() + "::eval_step() {\n"); - puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate " + topClassName() + puts("\nvoid " + EmitCUtil::topClassName() + "::eval_step() {\n"); + puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate " + EmitCUtil::topClassName() + "::eval_step\\n\"); );\n"); puts("#ifdef VL_DEBUG\n"); @@ -445,14 +450,14 @@ class EmitCModel final : public EmitCFunc { } void emitStandardMethods2(AstNodeModule* modp) { - const string topModNameProtected = prefixNameProtect(modp); + const string topModNameProtected = EmitCUtil::prefixNameProtect(modp); const string selfDecl = "(" + topModNameProtected + "* vlSelf)"; // ::eval_end_step if (v3Global.needTraceDumper() && !optSystemC()) { puts("\n"); - putns(modp, "void " + topClassName() + "::eval_end_step() {\n"); - puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+eval_end_step " + topClassName() + putns(modp, "void " + EmitCUtil::topClassName() + "::eval_end_step() {\n"); + puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+eval_end_step " + EmitCUtil::topClassName() + "::eval_end_step\\n\"); );\n"); puts("#ifdef VM_TRACE\n"); putsDecoration(nullptr, "// Tracing\n"); @@ -464,16 +469,19 @@ class EmitCModel final : public EmitCFunc { putSectionDelimiter("Events and timing"); if (auto* const delaySchedp = v3Global.rootp()->delaySchedulerp()) { - putns(modp, "bool " + topClassName() + "::eventsPending() { return !vlSymsp->TOP."); + putns(modp, "bool " + EmitCUtil::topClassName() + + "::eventsPending() { return !vlSymsp->TOP."); puts(delaySchedp->nameProtect()); puts(".empty(); }\n\n"); - putns(modp, "uint64_t " + topClassName() + "::nextTimeSlot() { return vlSymsp->TOP."); + putns(modp, "uint64_t " + EmitCUtil::topClassName() + + "::nextTimeSlot() { return vlSymsp->TOP."); puts(delaySchedp->nameProtect()); puts(".nextTimeSlot(); }\n"); } else { - putns(modp, "bool " + topClassName() + "::eventsPending() { return false; }\n\n"); - puts("uint64_t " + topClassName() + "::nextTimeSlot() {\n"); + putns(modp, + "bool " + EmitCUtil::topClassName() + "::eventsPending() { return false; }\n\n"); + puts("uint64_t " + EmitCUtil::topClassName() + "::nextTimeSlot() {\n"); puts("VL_FATAL_MT(__FILE__, __LINE__, \"\", \"No delays in the design\");\n"); puts("return 0;\n}\n"); } @@ -483,7 +491,7 @@ class EmitCModel final : public EmitCFunc { if (!optSystemC()) { // ::name puts("\n"); - putns(modp, "const char* " + topClassName() + "::name() const {\n"); + putns(modp, "const char* " + EmitCUtil::topClassName() + "::name() const {\n"); puts(/**/ "return vlSymsp->name();\n"); puts("}\n"); } @@ -494,23 +502,23 @@ class EmitCModel final : public EmitCFunc { putns(modp, "void " + topModNameProtected + "__" + protect("_eval_final") + selfDecl + ";\n"); // ::final - puts("\nVL_ATTR_COLD void " + topClassName() + "::final() {\n"); + puts("\nVL_ATTR_COLD void " + EmitCUtil::topClassName() + "::final() {\n"); puts(/**/ topModNameProtected + "__" + protect("_eval_final") + "(&(vlSymsp->TOP));\n"); puts("}\n"); putSectionDelimiter("Implementations of abstract methods from VerilatedModel\n"); - putns(modp, "const char* " + topClassName() + putns(modp, "const char* " + EmitCUtil::topClassName() + "::hierName() const { return vlSymsp->name(); }\n"); - putns(modp, "const char* " + topClassName() + "::modelName() const { return \"" - + topClassName() + "\"; }\n"); + putns(modp, "const char* " + EmitCUtil::topClassName() + "::modelName() const { return \"" + + EmitCUtil::topClassName() + "\"; }\n"); const int threads = v3Global.opt.hierChild() ? v3Global.opt.threads() : std::max(v3Global.opt.threads(), v3Global.opt.hierThreads()); - putns(modp, "unsigned " + topClassName() + "::threads() const { return " + putns(modp, "unsigned " + EmitCUtil::topClassName() + "::threads() const { return " + cvtToStr(threads) + "; }\n"); - putns(modp, "void " + topClassName() + putns(modp, "void " + EmitCUtil::topClassName() + "::prepareClone() const { contextp()->prepareClone(); }\n"); - putns(modp, "void " + topClassName() + "::atClone() const {\n"); + putns(modp, "void " + EmitCUtil::topClassName() + "::atClone() const {\n"); if (v3Global.opt.threads() > 1) { puts("vlSymsp->__Vm_threadPoolp = static_cast("); } @@ -519,7 +527,7 @@ class EmitCModel final : public EmitCFunc { puts(";\n}\n"); if (v3Global.opt.trace()) { - putns(modp, "std::unique_ptr " + topClassName() + putns(modp, "std::unique_ptr " + EmitCUtil::topClassName() + "::traceConfig() const {\n"); puts("return std::unique_ptr{new VerilatedTraceConfig{"); puts(v3Global.opt.useTraceParallel() ? "true" : "false"); @@ -531,7 +539,7 @@ class EmitCModel final : public EmitCFunc { } void emitTraceMethods(AstNodeModule* modp) { - const string topModNameProtected = prefixNameProtect(modp); + const string topModNameProtected = EmitCUtil::prefixNameProtect(modp); putSectionDelimiter("Trace configuration"); @@ -547,8 +555,8 @@ class EmitCModel final : public EmitCFunc { putns(modp, "VL_ATTR_COLD static void " + protect("trace_init") + "(void* voidSelf, " + v3Global.opt.traceClassBase() + "* tracep, uint32_t code) {\n"); putsDecoration(modp, "// Callback from tracep->open()\n"); - puts(voidSelfAssign(modp)); - puts(symClassAssign()); + puts(EmitCUtil::voidSelfAssign(modp)); + puts(EmitCUtil::symClassAssign()); puts("if (!vlSymsp->_vm_contextp__->calcUnusedSigs()) {\n"); puts("VL_FATAL_MT(__FILE__, __LINE__, __FILE__,\n"); puts("\"Turning on wave traces requires Verilated::traceEverOn(true) call before time " @@ -570,11 +578,11 @@ class EmitCModel final : public EmitCFunc { // ::traceRegisterModel puts("\n"); - putns(modp, "VL_ATTR_COLD void " + topClassName() + "::traceBaseModel("); + putns(modp, "VL_ATTR_COLD void " + EmitCUtil::topClassName() + "::traceBaseModel("); puts("VerilatedTraceBaseC* tfp, int levels, int options) {\n"); if (optSystemC()) { puts(/**/ "if (!sc_core::sc_get_curr_simcontext()->elaboration_done()) {\n"); - puts(/****/ "vl_fatal(__FILE__, __LINE__, name(), \"" + topClassName() + puts(/****/ "vl_fatal(__FILE__, __LINE__, name(), \"" + EmitCUtil::topClassName() + +"::trace() is called before sc_core::sc_start(). " "Run sc_core::sc_start(sc_core::SC_ZERO_TIME) before trace() to complete " "elaboration.\");\n"); @@ -584,7 +592,7 @@ class EmitCModel final : public EmitCFunc { puts(/**/ v3Global.opt.traceClassBase() + "C* const stfp = dynamic_cast<" + v3Global.opt.traceClassBase() + "C*>(tfp);\n"); puts(/**/ "if (VL_UNLIKELY(!stfp)) {\n"); - puts(/****/ "vl_fatal(__FILE__, __LINE__, __FILE__,\"'" + topClassName() + puts(/****/ "vl_fatal(__FILE__, __LINE__, __FILE__,\"'" + EmitCUtil::topClassName() + "::trace()' called on non-" + v3Global.opt.traceClassBase() + "C object;\"\n" + "\" use --trace-fst with VerilatedFst object," + " and --trace-vcd with VerilatedVcd object\");\n"); @@ -600,15 +608,15 @@ class EmitCModel final : public EmitCFunc { void emitSerializationFunctions() { putSectionDelimiter("Model serialization"); - puts("\nVerilatedSerialize& operator<<(VerilatedSerialize& os, " + topClassName() - + "& rhs) {\n"); + puts("\nVerilatedSerialize& operator<<(VerilatedSerialize& os, " + + EmitCUtil::topClassName() + "& rhs) {\n"); puts(/**/ "Verilated::quiesce();\n"); puts(/**/ "rhs.vlSymsp->" + protect("__Vserialize") + "(os);\n"); puts(/**/ "return os;\n"); puts("}\n"); - puts("\nVerilatedDeserialize& operator>>(VerilatedDeserialize& os, " + topClassName() - + "& rhs) {\n"); + puts("\nVerilatedDeserialize& operator>>(VerilatedDeserialize& os, " + + EmitCUtil::topClassName() + "& rhs) {\n"); puts(/**/ "Verilated::quiesce();\n"); puts(/**/ "rhs.vlSymsp->" + protect("__Vdeserialize") + "(os);\n"); puts(/**/ "return os;\n"); @@ -618,7 +626,7 @@ class EmitCModel final : public EmitCFunc { void emitImplementation(AstNodeModule* modp) { UASSERT(!ofp(), "Output file should not be open"); - const string filename = v3Global.opt.makeDir() + "/" + topClassName() + ".cpp"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".cpp"; setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename} : new V3OutCFile{filename}, newCFile(filename, /* slow: */ false, /* source: */ true)); @@ -628,7 +636,7 @@ class EmitCModel final : public EmitCFunc { "Model implementation (design independent parts)\n"); puts("\n"); - puts("#include \"" + pchClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n"); if (v3Global.opt.trace()) { puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n"); } @@ -659,7 +667,8 @@ class EmitCModel final : public EmitCFunc { } if (!ofp()) { - string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi_Export"; + string filename + = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi_Export"; filename = m_uniqueNames.get(filename); filename += ".cpp"; setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename} @@ -671,8 +680,8 @@ class EmitCModel final : public EmitCFunc { puts( "// DESCRIPTION: Verilator output: Implementation of DPI export functions.\n"); puts("//\n"); - puts("#include \"" + topClassName() + ".h\"\n"); - puts("#include \"" + symClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n"); puts("#include \"verilated_dpi.h\"\n"); puts("\n"); } diff --git a/src/V3EmitCPch.cpp b/src/V3EmitCPch.cpp index e1c6df69b..fdac954d1 100644 --- a/src/V3EmitCPch.cpp +++ b/src/V3EmitCPch.cpp @@ -23,19 +23,19 @@ VL_DEFINE_DEBUG_FUNCTIONS; //###################################################################### // Precompiled header emitter -class EmitCPch final : EmitCBase { +class EmitCPch final { public: // METHODS void emitPch() { // Generate the makefile - V3OutCFile of{v3Global.opt.makeDir() + "/" + pchClassName() + ".h"}; + V3OutCFile of{v3Global.opt.makeDir() + "/" + EmitCUtil::pchClassName() + ".h"}; of.putsHeader(); of.puts("// DESCRIPTION: Verilator output: Precompiled header\n"); of.puts("//\n"); of.puts("// Internal details; most user sources do not need this header,\n"); of.puts("// unless using verilator public meta comments.\n"); - of.puts("// Suggest use " + topClassName() + ".h instead.\n"); + of.puts("// Suggest use " + EmitCUtil::topClassName() + ".h instead.\n"); of.puts("\n"); of.putsGuard(); @@ -54,8 +54,8 @@ public: if (v3Global.dpi()) of.puts("#include \"verilated_dpi.h\"\n"); of.puts("\n"); - of.puts("#include \"" + symClassName() + ".h\"\n"); - of.puts("#include \"" + topClassName() + ".h\"\n"); + of.puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n"); + of.puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n"); of.puts("\n// Additional include files added using '--compiler-include'\n"); for (const string& filename : v3Global.opt.compilerIncludes()) { diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 1f9f7cf28..f26d98d3b 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -399,7 +399,7 @@ public: void EmitCSyms::emitSymHdr() { UINFO(6, __FUNCTION__ << ": "); - const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".h"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + ".h"; AstCFile* const cfilep = newCFile(filename, true /*slow*/, false /*source*/); V3OutCFile* const ofilep = optSystemC() ? new V3OutScFile{filename} : new V3OutCFile{filename}; setOutputFile(ofilep, cfilep); @@ -421,13 +421,13 @@ void EmitCSyms::emitSymHdr() { if (v3Global.opt.usesProfiler()) puts("#include \"verilated_profiler.h\"\n"); puts("\n// INCLUDE MODEL CLASS\n"); - puts("\n#include \"" + topClassName() + ".h\"\n"); + puts("\n#include \"" + EmitCUtil::topClassName() + ".h\"\n"); puts("\n// INCLUDE MODULE CLASSES\n"); for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep = VN_AS(nodep->nextp(), NodeModule)) { if (VN_IS(nodep, Class)) continue; // Class included earlier - putns(nodep, "#include \"" + prefixNameProtect(nodep) + ".h\"\n"); + putns(nodep, "#include \"" + EmitCUtil::prefixNameProtect(nodep) + ".h\"\n"); } if (v3Global.dpi()) { @@ -446,12 +446,12 @@ void EmitCSyms::emitSymHdr() { } puts("\n// SYMS CLASS (contains all model state)\n"); - puts("class alignas(VL_CACHE_LINE_BYTES)" + symClassName() + puts("class alignas(VL_CACHE_LINE_BYTES)" + EmitCUtil::symClassName() + " final : public VerilatedSyms {\n"); ofp()->putsPrivate(false); // public: puts("// INTERNAL STATE\n"); - puts(topClassName() + "* const __Vm_modelp;\n"); + puts(EmitCUtil::topClassName() + "* const __Vm_modelp;\n"); if (v3Global.needTraceDumper()) { // __Vm_dumperp is local, otherwise we wouldn't know what design's eval() @@ -496,9 +496,9 @@ void EmitCSyms::emitSymHdr() { const AstScope* const scopep = i.first; const AstNodeModule* const modp = i.second; if (VN_IS(modp, Class)) continue; - const string name = prefixNameProtect(modp); + const string name = EmitCUtil::prefixNameProtect(modp); ofp()->printf("%-30s ", name.c_str()); - putns(scopep, protectIf(scopep->nameDotless(), scopep->protect()) + ";\n"); + putns(scopep, VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + ";\n"); } if (m_coverBins) { @@ -528,12 +528,12 @@ void EmitCSyms::emitSymHdr() { } puts("\n// CONSTRUCTORS\n"); - puts(symClassName() + "(VerilatedContext* contextp, const char* namep, " + topClassName() - + "* modelp);\n"); - puts("~"s + symClassName() + "();\n"); + puts(EmitCUtil::symClassName() + "(VerilatedContext* contextp, const char* namep, " + + EmitCUtil::topClassName() + "* modelp);\n"); + puts("~"s + EmitCUtil::symClassName() + "();\n"); for (const auto& i : m_usesVfinal) { - puts("void " + symClassName() + "_" + cvtToStr(i.first) + "("); + puts("void " + EmitCUtil::symClassName() + "_" + cvtToStr(i.first) + "("); if (i.second) puts("int __Vfinal"); puts(");\n"); } @@ -599,8 +599,8 @@ void EmitCSyms::checkSplit(bool usesVfinal) { v3Global.useParallelBuild(true); m_numStmts = 0; - const string filename - = v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + "__" + + cvtToStr(++m_funcNum) + ".cpp"; AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/); cfilep->support(true); m_usesVfinal[m_funcNum] = usesVfinal; @@ -609,12 +609,13 @@ void EmitCSyms::checkSplit(bool usesVfinal) { V3OutCFile* const ofilep = optSystemC() ? new V3OutScFile{filename} : new V3OutCFile{filename}; setOutputFile(ofilep, cfilep); - m_ofpBase->puts(symClassName() + "_" + cvtToStr(m_funcNum) + "("); + m_ofpBase->puts(EmitCUtil::symClassName() + "_" + cvtToStr(m_funcNum) + "("); if (usesVfinal) m_ofpBase->puts("__Vfinal"); m_ofpBase->puts(");\n"); emitSymImpPreamble(); - puts("void " + symClassName() + "::" + symClassName() + "_" + cvtToStr(m_funcNum) + "("); + puts("void " + EmitCUtil::symClassName() + "::" + EmitCUtil::symClassName() + "_" + + cvtToStr(m_funcNum) + "("); if (usesVfinal) puts("int __Vfinal"); puts(") {\n"); } @@ -626,12 +627,12 @@ void EmitCSyms::emitSymImpPreamble() { puts("\n"); // Includes - puts("#include \"" + pchClassName() + ".h\"\n"); - puts("#include \"" + topClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n"); for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep = VN_AS(nodep->nextp(), NodeModule)) { if (VN_IS(nodep, Class)) continue; // Class included earlier - putns(nodep, "#include \"" + prefixNameProtect(nodep) + ".h\"\n"); + putns(nodep, "#include \"" + EmitCUtil::prefixNameProtect(nodep) + ".h\"\n"); } puts("\n"); // Declarations for DPI Export implementation functions @@ -683,7 +684,7 @@ void EmitCSyms::emitScopeHier(bool destroy) { void EmitCSyms::emitSymImp() { UINFO(6, __FUNCTION__ << ": "); - const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + ".cpp"; AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/); cfilep->support(true); @@ -699,7 +700,7 @@ void EmitCSyms::emitSymImp() { const string funcname = de ? "__Vdeserialize" : "__Vserialize"; const string op = de ? ">>" : "<<"; // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - puts("void " + symClassName() + "::" + protect(funcname) + "(" + classname + puts("void " + EmitCUtil::symClassName() + "::" + protect(funcname) + "(" + classname + "& os) {\n"); puts("// Internal state\n"); if (v3Global.opt.trace()) puts("os" + op + "__Vm_activity;\n"); @@ -707,8 +708,8 @@ void EmitCSyms::emitSymImp() { puts("// Module instance state\n"); for (const auto& pair : m_scopes) { const AstScope* const scopep = pair.first; - puts(protectIf(scopep->nameDotless(), scopep->protect()) + "." + protect(funcname) - + "(os);\n"); + puts(VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + "." + + protect(funcname) + "(os);\n"); } puts("}\n"); } @@ -718,7 +719,7 @@ void EmitCSyms::emitSymImp() { puts("// FUNCTIONS\n"); // Destructor - puts(symClassName() + "::~" + symClassName() + "()\n"); + puts(EmitCUtil::symClassName() + "::~" + EmitCUtil::symClassName() + "()\n"); puts("{\n"); emitScopeHier(true); if (v3Global.needTraceDumper()) { @@ -730,21 +731,21 @@ void EmitCSyms::emitSymImp() { // Do not overwrite data during the last hierarchical stage. const string firstHierCall = (v3Global.opt.hierBlocks().empty() || v3Global.opt.hierChild()) ? "true" : "false"; - puts("_vm_pgoProfiler.write(\"" + topClassName() + puts("_vm_pgoProfiler.write(\"" + EmitCUtil::topClassName() + "\", _vm_contextp__->profVltFilename(), " + firstHierCall + ");\n"); } puts("}\n"); if (v3Global.needTraceDumper()) { if (!optSystemC()) { - puts("\nvoid " + symClassName() + "::_traceDump() {\n"); + puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDump() {\n"); // Caller checked for __Vm_dumperp non-nullptr puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n"); puts("__Vm_dumperp->dump(VL_TIME_Q());\n"); puts("}\n"); } - puts("\nvoid " + symClassName() + "::_traceDumpOpen() {\n"); + puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDumpOpen() {\n"); puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n"); puts("if (VL_UNLIKELY(!__Vm_dumperp)) {\n"); puts("__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n"); @@ -755,7 +756,7 @@ void EmitCSyms::emitSymImp() { puts("}\n"); puts("}\n"); - puts("\nvoid " + symClassName() + "::_traceDumpClose() {\n"); + puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDumpClose() {\n"); puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n"); puts("__Vm_dumping = false;\n"); puts("VL_DO_CLEAR(delete __Vm_dumperp, __Vm_dumperp = nullptr);\n"); @@ -764,8 +765,9 @@ void EmitCSyms::emitSymImp() { puts("\n"); // Constructor - puts(symClassName() + "::" + symClassName() - + "(VerilatedContext* contextp, const char* namep, " + topClassName() + "* modelp)\n"); + puts(EmitCUtil::symClassName() + "::" + EmitCUtil::symClassName() + + "(VerilatedContext* contextp, const char* namep, " + EmitCUtil::topClassName() + + "* modelp)\n"); puts(" : VerilatedSyms{contextp}\n"); puts(" // Setup internal state of the Syms class\n"); puts(" , __Vm_modelp{modelp}\n"); @@ -813,7 +815,7 @@ void EmitCSyms::emitSymImp() { } else { // The "." is added by catName puts(", Verilated::catName(namep, "); - putsQuoted(protectWordsIf(scopep->prettyName(), scopep->protect())); + putsQuoted(VIdProtect::protectWordsIf(scopep->prettyName(), scopep->protect())); puts(")"); } puts("}\n"); @@ -862,17 +864,18 @@ void EmitCSyms::emitSymImp() { const AstNodeModule* const modp = i.second; if (const AstScope* const aboveScopep = scopep->aboveScopep()) { checkSplit(false); - const string protName = protectWordsIf(scopep->name(), scopep->protect()); + const string protName = VIdProtect::protectWordsIf(scopep->name(), scopep->protect()); if (VN_IS(modp, ClassPackage)) { // ClassPackage modules seem to be a bit out of place, so hard code... putns(scopep, "TOP"); } else { - putns(scopep, protectIf(aboveScopep->nameDotless(), aboveScopep->protect())); + putns(scopep, + VIdProtect::protectIf(aboveScopep->nameDotless(), aboveScopep->protect())); } puts("."); puts(protName.substr(protName.rfind('.') + 1)); puts(" = &"); - puts(protectIf(scopep->nameDotless(), scopep->protect()) + ";\n"); + puts(VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + ";\n"); ++m_numStmts; } } @@ -885,7 +888,7 @@ void EmitCSyms::emitSymImp() { // first is used by AstCoverDecl's call to __vlCoverInsert const bool first = !modp->user1(); modp->user1(true); - putns(scopep, protectIf(scopep->nameDotless(), scopep->protect()) + "." + putns(scopep, VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + "." + protect("__Vconfigure") + "(" + (first ? "true" : "false") + ");\n"); ++m_numStmts; } @@ -896,7 +899,7 @@ void EmitCSyms::emitSymImp() { checkSplit(false); putns(it->second.m_nodep, protect("__Vscope_" + it->second.m_symName) + ".configure(this, name(), "); - putsQuoted(protectWordsIf(it->second.m_prettyName, true)); + putsQuoted(VIdProtect::protectWordsIf(it->second.m_prettyName, true)); puts(", "); putsQuoted(protect(scopeDecodeIdentifier(it->second.m_prettyName))); puts(", "); @@ -926,7 +929,7 @@ void EmitCSyms::emitSymImp() { protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, "); putsQuoted(funcp->cname()); // Not protected - user asked for import/export puts(", (void*)(&"); - puts(prefixNameProtect(modp)); + puts(EmitCUtil::prefixNameProtect(modp)); puts("__"); puts(funcp->nameProtect()); puts("));\n"); @@ -975,7 +978,7 @@ void EmitCSyms::emitSymImp() { putsQuoted(protect(it->second.m_varBasePretty)); std::string varName; - varName += protectIf(scopep->nameDotless(), scopep->protect()) + "."; + varName += VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + "."; varName += protect(varp->name()); if (varp->isParam()) { @@ -1022,7 +1025,7 @@ void EmitCSyms::emitSymImp() { void EmitCSyms::emitDpiHdr() { UINFO(6, __FUNCTION__ << ": "); - const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi.h"; AstCFile* const cfilep = newCFile(filename, false /*slow*/, false /*source*/); cfilep->support(true); V3OutCFile hf{filename}; @@ -1051,14 +1054,16 @@ void EmitCSyms::emitDpiHdr() { for (AstCFunc* nodep : m_dpis) { if (nodep->dpiExportDispatcher()) { if (!firstExp++) puts("\n// DPI EXPORTS\n"); - putsDecoration(nodep, "// DPI export" - + ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n"); + putsDecoration( + nodep, "// DPI export" + + VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n"); putns(nodep, "extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "(" + cFuncArgs(nodep) + ");\n"); } else if (nodep->dpiImportPrototype()) { if (!firstImp++) puts("\n// DPI IMPORTS\n"); - putsDecoration(nodep, "// DPI import" - + ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n"); + putsDecoration( + nodep, "// DPI import" + + VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n"); putns(nodep, "extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "(" + cFuncArgs(nodep) + ");\n"); } @@ -1077,7 +1082,7 @@ void EmitCSyms::emitDpiHdr() { void EmitCSyms::emitDpiImp() { UINFO(6, __FUNCTION__ << ": "); - const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp"; + const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi.cpp"; AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/); cfilep->support(true); V3OutCFile hf(filename); @@ -1092,14 +1097,14 @@ void EmitCSyms::emitDpiImp() { puts("// function names, you will get multiple definition link errors from here.\n"); puts("// This is an unfortunate result of the DPI specification.\n"); puts("// To solve this, either\n"); - puts("// 1. Call " + topClassName() + "::{export_function} instead,\n"); + puts("// 1. Call " + EmitCUtil::topClassName() + "::{export_function} instead,\n"); puts("// and do not even bother to compile this file\n"); puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n"); puts("// and #ifdefs already inserted here will sort everything out.\n"); puts("\n"); - puts("#include \"" + topClassName() + "__Dpi.h\"\n"); - puts("#include \"" + topClassName() + ".h\"\n"); + puts("#include \"" + EmitCUtil::topClassName() + "__Dpi.h\"\n"); + puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n"); puts("\n"); for (AstCFunc* nodep : m_dpis) { @@ -1109,8 +1114,9 @@ void EmitCSyms::emitDpiImp() { puts("#define VL_DPIDECL_" + nodep->name() + "_\n"); putns(nodep, nodep->rtnTypeVoid() + " " + nodep->name() + "(" + cFuncArgs(nodep) + ") {\n"); - puts("// DPI export" + ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n"); - putns(nodep, "return " + topClassName() + "::" + nodep->name() + "("); + puts("// DPI export" + VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii()) + + "\n"); + putns(nodep, "return " + EmitCUtil::topClassName() + "::" + nodep->name() + "("); string comma; for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) { if (const AstVar* const portp = VN_CAST(stmtp, Var)) { diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 4f730c348..e2058af3f 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -73,7 +73,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst { // VISITORS void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); } void visit(AstNodeModule* nodep) override { - putfs(nodep, nodep->verilogKwd() + " " + EmitCBase::prefixNameProtect(nodep) + ";\n"); + putfs(nodep, nodep->verilogKwd() + " " + EmitCUtil::prefixNameProtect(nodep) + ";\n"); iterateChildrenConst(nodep); putqs(nodep, "end" + nodep->verilogKwd() + "\n"); } diff --git a/src/V3ExecGraph.cpp b/src/V3ExecGraph.cpp index 69735a309..0e27a9356 100644 --- a/src/V3ExecGraph.cpp +++ b/src/V3ExecGraph.cpp @@ -982,8 +982,8 @@ const std::vector createThreadFunctions(const ThreadSchedule& schedul funcp->argTypes("void* voidSelf, bool even_cycle"); // Setup vlSelf and vlSyms - funcp->addStmtsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(modp)}); - funcp->addStmtsp(new AstCStmt{fl, EmitCBase::symClassAssign()}); + funcp->addStmtsp(new AstCStmt{fl, EmitCUtil::voidSelfAssign(modp)}); + funcp->addStmtsp(new AstCStmt{fl, EmitCUtil::symClassAssign()}); // Invoke each mtask scheduled to this thread from the thread function for (const ExecMTask* const mtaskp : thread) { diff --git a/src/V3File.cpp b/src/V3File.cpp index a0731db43..5b6f40e98 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -1118,6 +1118,9 @@ private: } }; +string VIdProtect::ifNoProtect(const string& in) VL_MT_SAFE { + return v3Global.opt.protectIds() ? "" : in; +} string VIdProtect::protectIf(const string& old, bool doIt) VL_MT_SAFE { return VIdProtectImp::singleton().protectIf(old, doIt); } diff --git a/src/V3File.h b/src/V3File.h index 746948386..54f532611 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -461,6 +461,8 @@ class VIdProtectImp; class VIdProtect final { public: // METHODS + // Return 'in' only if not protecting (e.g. for emitting a comment) + static string ifNoProtect(const string& in) VL_MT_SAFE; // Rename to a new encoded string (unless earlier passthru'ed) static string protect(const string& old) VL_MT_SAFE { return protectIf(old, true); } static string protectIf(const string& old, bool doIt = true) VL_MT_SAFE; diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp index 8fa275e2b..35fabd096 100644 --- a/src/V3SchedTiming.cpp +++ b/src/V3SchedTiming.cpp @@ -390,7 +390,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(EmitCBase::symClassVar()); + newfuncp->argTypes(EmitCUtil::symClassVar()); callp->argTypes("vlSymsp"); } // Put the begin's statements in the function, delete the begin diff --git a/src/V3Task.cpp b/src/V3Task.cpp index b9a00f833..df587935e 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -897,7 +897,7 @@ class TaskVisitor final : public VNVisitor { // Convert input/inout DPI arguments to Internal types string args; - args += ("(" + EmitCBase::symClassName() + args += ("(" + EmitCUtil::symClassName() + "*)(__Vscopep->symsp())"); // Upcast w/o overhead AstNode* argnodesp = nullptr; for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { @@ -1284,7 +1284,7 @@ class TaskVisitor final : public VNVisitor { if (!nodep->dpiImport() && !nodep->taskPublic()) { // Need symbol table - cfuncp->argTypes(EmitCBase::symClassVar()); + cfuncp->argTypes(EmitCUtil::symClassVar()); if (cfuncp->name() == "new") { const string stmt = VIdProtect::protect("_ctor_var_reset") + "(vlSymsp);\n"; cfuncp->addInitsp(new AstCStmt{nodep->fileline(), stmt}); diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 1a14843f4..f64ff7347 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -519,8 +519,8 @@ class TraceVisitor final : public VNVisitor { if (isTopFunc) { // Top functions funcp->argTypes("void* voidSelf, " + bufArg); - addInitStr(EmitCBase::voidSelfAssign(m_topModp)); - addInitStr(EmitCBase::symClassAssign()); + addInitStr(EmitCUtil::voidSelfAssign(m_topModp)); + addInitStr(EmitCUtil::symClassAssign()); // Add global activity check to change dump functions if (traceType == VTraceType::CHANGE) { // addInitStr("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n"); @@ -732,8 +732,8 @@ class TraceVisitor final : public VNVisitor { cleanupFuncp->isStatic(true); cleanupFuncp->isLoose(true); m_topScopep->addBlocksp(cleanupFuncp); - cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(m_topModp)}); - cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::symClassAssign()}); + cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCUtil::voidSelfAssign(m_topModp)}); + cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCUtil::symClassAssign()}); // Register it m_regFuncp->addStmtsp(new AstText{fl, "tracep->addCleanupCb(", true}); diff --git a/src/V3VariableOrder.cpp b/src/V3VariableOrder.cpp index b2f83c7d1..bf4c12554 100644 --- a/src/V3VariableOrder.cpp +++ b/src/V3VariableOrder.cpp @@ -231,7 +231,7 @@ class VariableOrder final { : (sigbytes == 2) ? 3 : (sigbytes == 1) ? 2 : 10; - m_attributes.emplace(varp, VarAttributes{stratum, EmitCBase::isAnonOk(varp)}); + m_attributes.emplace(varp, VarAttributes{stratum, EmitCUtil::isAnonOk(varp)}); } }