diff --git a/src/V3EmitCBase.cpp b/src/V3EmitCBase.cpp index 1e3e9383f..40198fa76 100644 --- a/src/V3EmitCBase.cpp +++ b/src/V3EmitCBase.cpp @@ -57,11 +57,11 @@ string EmitCBaseVisitor::funcNameProtect(const AstCFunc* nodep, const AstNodeMod return name; } -AstCFile* EmitCBaseVisitor::newCFile(const string& filename, bool slow, bool source) { +AstCFile* EmitCBaseVisitor::newCFile(const string& filename, bool slow, bool source, bool add) { AstCFile* const cfilep = new AstCFile(v3Global.rootp()->fileline(), filename); cfilep->slow(slow); cfilep->source(source); - v3Global.rootp()->addFilesp(cfilep); + if (add) v3Global.rootp()->addFilesp(cfilep); return cfilep; } diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index 66b954f35..2451cfdfc 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -100,7 +100,7 @@ public: && (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon } - static AstCFile* newCFile(const string& filename, bool slow, bool source); + 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); void emitCFuncDecl(const AstCFunc* funcp, const AstNodeModule* modp, bool cLinkage = false); diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index b31e30b88..988a8b7fd 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -148,6 +148,7 @@ class EmitCImp final : EmitCFunc { const std::set* m_requiredHeadersp; // Header files required by output file std::string m_subFileName; // substring added to output filenames V3UniqueNames m_uniqueNames; // For generating unique file names + std::deque& m_cfilesr; // cfiles generated by this emit // METHODS void openNextOutputFile(const std::set& headers, const string& subFileName) { @@ -160,7 +161,8 @@ class EmitCImp final : EmitCFunc { // Unfortunately we have some lint checks here, so we can't just skip processing. // We should move them to a different stage. const string filename = VL_DEV_NULL; - newCFile(filename, /* slow: */ m_slow, /* source: */ true); + m_cfilesr.push_back( + newCFile(filename, /* slow: */ m_slow, /* source: */ true, /* add */ false)); m_ofp = new V3OutCFile(filename); } else { string filename = v3Global.opt.makeDir() + "/" + prefixNameProtect(m_fileModp); @@ -170,7 +172,8 @@ class EmitCImp final : EmitCFunc { } if (m_slow) filename += "__Slow"; filename += ".cpp"; - newCFile(filename, /* slow: */ m_slow, /* source: */ true); + m_cfilesr.push_back( + newCFile(filename, /* slow: */ m_slow, /* source: */ true, /* add */ false)); m_ofp = v3Global.opt.systemC() ? new V3OutScFile(filename) : new V3OutCFile(filename); } @@ -522,9 +525,10 @@ class EmitCImp final : EmitCFunc { EmitCFunc::visit(nodep); } - explicit EmitCImp(const AstNodeModule* modp, bool slow) + explicit EmitCImp(const AstNodeModule* modp, bool slow, std::deque& cfilesr) : m_fileModp{modp} - , m_slow{slow} { + , m_slow{slow} + , m_cfilesr{cfilesr} { UINFO(5, " Emitting implementation of " << prefixNameProtect(modp) << endl); m_modp = modp; @@ -543,7 +547,9 @@ class EmitCImp final : EmitCFunc { virtual ~EmitCImp() override = default; public: - static void main(const AstNodeModule* modp, bool slow) { EmitCImp{modp, slow}; } + static void main(const AstNodeModule* modp, bool slow, std::deque& cfilesr) { + EmitCImp{modp, slow, cfilesr}; + } }; //###################################################################### @@ -558,6 +564,7 @@ class EmitCTrace final : EmitCFunc { int m_enumNum = 0; // Enumeration number (whole netlist) V3UniqueNames m_uniqueNames; // For generating unique file names std::unordered_map m_enumNumMap; // EnumDType to enumeration number + std::deque& m_cfilesr; // cfiles generated by this emit // METHODS void openNextOutputFile() { @@ -572,8 +579,9 @@ class EmitCTrace final : EmitCFunc { if (m_slow) filename += "__Slow"; filename += ".cpp"; - AstCFile* const cfilep = newCFile(filename, m_slow, true /*source*/); + AstCFile* const cfilep = newCFile(filename, m_slow, true /*source*/, false /*add*/); cfilep->support(true); + m_cfilesr.push_back(cfilep); if (optSystemC()) { m_ofp = new V3OutScFile(filename); @@ -862,8 +870,9 @@ class EmitCTrace final : EmitCFunc { } } - explicit EmitCTrace(AstNodeModule* modp, bool slow) - : m_slow{slow} { + explicit EmitCTrace(AstNodeModule* modp, bool slow, std::deque& cfilesr) + : m_slow{slow} + , m_cfilesr{cfilesr} { m_modp = modp; // Open output file openNextOutputFile(); @@ -877,7 +886,9 @@ class EmitCTrace final : EmitCFunc { virtual ~EmitCTrace() override = default; public: - static void main(AstNodeModule* modp, bool slow) { EmitCTrace{modp, slow}; } + static void main(AstNodeModule* modp, bool slow, std::deque& cfilesr) { + EmitCTrace{modp, slow, cfilesr}; + } }; //###################################################################### @@ -887,19 +898,27 @@ void V3EmitC::emitcImp() { UINFO(2, __FUNCTION__ << ": " << endl); // Make parent module pointers available. const EmitCParentModule emitCParentModule; + std::list> cfiles; // Process each module in turn for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) { if (VN_IS(nodep, Class)) continue; // Imped with ClassPackage const AstNodeModule* const modp = VN_AS(nodep, NodeModule); - EmitCImp::main(modp, /* slow: */ true); - EmitCImp::main(modp, /* slow: */ false); + cfiles.emplace_back(); + EmitCImp::main(modp, /* slow: */ true, cfiles.back()); + cfiles.emplace_back(); + EmitCImp::main(modp, /* slow: */ false, cfiles.back()); } // Emit trace routines (currently they can only exist in the top module) if (v3Global.opt.trace() && !v3Global.opt.lintOnly()) { - EmitCTrace::main(v3Global.rootp()->topModulep(), /* slow: */ true); - EmitCTrace::main(v3Global.rootp()->topModulep(), /* slow: */ false); + cfiles.emplace_back(); + EmitCTrace::main(v3Global.rootp()->topModulep(), /* slow: */ true, cfiles.back()); + cfiles.emplace_back(); + EmitCTrace::main(v3Global.rootp()->topModulep(), /* slow: */ false, cfiles.back()); + } + for (const auto& collr : cfiles) { + for (const auto cfilep : collr) v3Global.rootp()->addFilesp(cfilep); } }