diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 995fd1b5c02..3735316a864 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1273,34 +1273,6 @@ void AstNode::dumpTreeAndNext(std::ostream& os, const string& indent, int maxDep } } -void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump, bool doCheck) { - // Not const function as calls checkTree - if (doDump) { - { // Write log & close - UINFO(2, "Dumping " << filename << endl); - const std::unique_ptr logsp{V3File::new_ofstream(filename, append)}; - if (logsp->fail()) v3fatal("Can't write " << filename); - *logsp << "Verilator Tree Dump (format 0x3900) from to \n"; - if (editCountGbl() == editCountLast() && ::dumpTreeLevel() < 9) { - *logsp << '\n'; - *logsp << "No changes since last dump!\n"; - } else { - dumpTree(*logsp); - editCountSetLast(); // Next dump can indicate start from here - } - } - } - if (doDump && v3Global.opt.debugEmitV()) V3EmitV::debugEmitV(filename + ".v"); - if (doCheck && (v3Global.opt.debugCheck() || ::dumpTreeLevel())) { - // Error check - checkTree(); - // Broken isn't part of check tree because it can munge iterp's - // set by other steps if it is called in the middle of other operations - if (AstNetlist* const netp = VN_CAST(this, Netlist)) V3Broken::brokenAll(netp); - } -} - static void drawChildren(std::ostream& os, const AstNode* thisp, const AstNode* childp, const std::string& childName) { if (childp) { diff --git a/src/V3Ast.h b/src/V3Ast.h index 61b4f7e572a..92f0d33321f 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2210,8 +2210,6 @@ class AstNode VL_NOT_FINAL { static void dumpTreeGdb(const AstNode* nodep); // For GDB only void dumpTreeAndNext(std::ostream& os = std::cout, const string& indent = " ", int maxDepth = 0) const; - void dumpTreeFile(const string& filename, bool append = false, bool doDump = true, - bool doCheck = true); static void dumpTreeFileGdb(const AstNode* nodep, const char* filenamep = nullptr); void dumpTreeDot(std::ostream& os = std::cout) const; void dumpTreeDotFile(const string& filename, bool append = false, bool doDump = true); diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 97a29e8fc1e..b315075d611 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1266,6 +1266,9 @@ class AstNetlist final : public AstNode { uint32_t allocNextMTaskID() { return m_nextFreeMTaskID++; } uint32_t allocNextMTaskProfilingID() { return m_nextFreeMTaskProfilingID++; } uint32_t usedMTaskProfilingIDs() const { return m_nextFreeMTaskProfilingID; } + + void dumpTreeFile(const string& filename, bool append = false, bool doDump = true, + bool doCheck = true); }; class AstPackageExport final : public AstNode { private: diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index d9cef86c28c..1422ececefa 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -17,6 +17,7 @@ #include "V3PchAstMT.h" #include "V3EmitCBase.h" +#include "V3EmitV.h" #include "V3File.h" #include "V3Graph.h" #include "V3Hasher.h" @@ -29,6 +30,8 @@ #include #include +VL_DEFINE_DEBUG_FUNCTIONS; + //====================================================================== // Special methods @@ -1956,6 +1959,59 @@ void AstNetlist::createTopScope(AstScope* scopep) { m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep}; scopep->modp()->addStmtsp(v3Global.rootp()->topScopep()); } +void AstNetlist::dumpTreeFile(const string& filename, bool append, bool doDump, bool doCheck) { + // Not const function as calls brokenAll + if (doDump) { + { // Write log & close + UINFO(2, "Dumping " << filename << endl); + const std::unique_ptr logsp{V3File::new_ofstream(filename, append)}; + if (logsp->fail()) v3fatal("Can't write " << filename); + *logsp << "Verilator Tree Dump (format 0x3900) from to \n"; + if (editCountGbl() == editCountLast() && ::dumpTreeLevel() < 9) { + *logsp << '\n'; + *logsp << "No changes since last dump!\n"; + } else { + { + // Code in this scope is a copy of dumpTree() with minor changes. + // TODO(mglb): look into integration of this code with the original dumpTree(). + + std::ostream& os = *logsp; + const std::string indent = " "; + + static int s_debugFileline = v3Global.opt.debugSrcLevel("fileline"); // --debugi-fileline 9 + os << indent << " " << this << '\n'; + if (debug() > 8) { + // TODO(mglb): implement dedicated dumpPtrs for AstNetlist + // os << indent << " "; + // dumpPtrs(os); + } + if (s_debugFileline >= 9) os << fileline()->warnContextSecondary(); + for (const AstNode* nodep = modulesp(); nodep; nodep = nodep->nextp()) { + nodep->dumpTree(os, indent + "1:"); + } + for (const AstNode* nodep = filesp(); nodep; nodep = nodep->nextp()) { + nodep->dumpTree(os, indent + "2:"); + } + typeTablep()->dumpTree(os, indent + "3:"); + constPoolp()->dumpTree(os, indent + "3:"); + } + editCountSetLast(); // Next dump can indicate start from here + } + } + } + if (doDump && v3Global.opt.debugEmitV()) V3EmitV::debugEmitV(filename + ".v"); + if (doCheck && (v3Global.opt.debugCheck() || ::dumpTreeLevel())) { + // Error check + if (modulesp()) modulesp()->checkTree(); + if (filesp()) filesp()->checkTree(); + typeTablep()->checkTree(); + constPoolp()->checkTree(); + // Broken isn't part of check tree because it can munge iterp's + // set by other steps if it is called in the middle of other operations + V3Broken::brokenAll(this); + } +} void AstNodeModule::dump(std::ostream& str) const { this->AstNode::dump(str); str << " L" << level();