diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 97852cc73..a9e6885c7 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -44,6 +44,7 @@ bool V3Error::s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; bool V3Error::s_describedWarnings = false; bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX]; V3Error::MessagesSet V3Error::s_messages; +V3Error::ErrorExitCb V3Error::s_errorExitCb = NULL; struct v3errorIniter { v3errorIniter() { V3Error::init(); } @@ -482,7 +483,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) { } #ifndef _V3ERROR_NO_GLOBAL_ if (debug()) { - v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",999)); + v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",990)); + if (s_errorExitCb) s_errorExitCb(); V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } diff --git a/src/V3Error.h b/src/V3Error.h index 1f9030c46..a4909c369 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -181,6 +181,7 @@ class V3Error { // Base class for any object that wants debugging and error reporting typedef set MessagesSet; + typedef void (*ErrorExitCb)(void); private: static bool s_describedWarnings; // Told user how to disable warns @@ -194,6 +195,8 @@ class V3Error { static V3ErrorCode s_errorCode; // Error string being formed will abort static bool s_errorSuppressed; // Error being formed should be suppressed static MessagesSet s_messages; // What errors we've outputted + static ErrorExitCb s_errorExitCb; // Callback when error occurs for dumping + enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors V3Error() { cerr<<("Static class"); abort(); } @@ -218,6 +221,7 @@ class V3Error { static bool isError(V3ErrorCode code, bool supp); static string lineStr (const char* filename, int lineno); static V3ErrorCode errorCode() { return s_errorCode; } + static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; } // When printing an error/warning, print prefix for multiline message static string warnMore(); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index cf009f9cb..cc1d664fb 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -80,6 +80,8 @@ private: typedef std::multimap NameScopeSymMap; typedef set > ImplicitNameSet; + static LinkDotState* s_errorThisp; // Last self, for error reporting only + // MEMBERS VSymGraph m_syms; // Symbol table VSymEnt* m_dunitEntp; // $unit entry @@ -88,6 +90,7 @@ private: bool m_forPrimary; // First link bool m_forPrearray; // Compress cell__[array] refs bool m_forScopeCreation; // Remove VarXRefs for V3Scope + public: static int debug() { @@ -98,6 +101,9 @@ public: void dump() { if (debug()>=6) m_syms.dumpFilePrefixed("linkdot"); } + static void preErrorDumpHandler() { + if (s_errorThisp) s_errorThisp->preErrorDump(); + } void preErrorDump() { static bool diddump = false; if (!diddump && v3Global.opt.dumpTree()) { @@ -115,8 +121,13 @@ public: m_forPrearray = (step == LDS_PARAMED || step==LDS_PRIMARY); m_forScopeCreation = (step == LDS_SCOPED); m_dunitEntp = NULL; + s_errorThisp = this; + V3Error::errorExitCb(preErrorDumpHandler); // If get error, dump self + } + ~LinkDotState() { + V3Error::errorExitCb(NULL); + s_errorThisp = NULL; } - ~LinkDotState() {} // ACCESSORS VSymGraph* symsp() { return &m_syms; } @@ -161,7 +172,6 @@ public: // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks // See t_gen_forif.v for an example. } else { - preErrorDump(); UINFO(4,"name "<name UINFO(4,"Var1 "<findDotted(aboveSymp, scope, baddot, okSymp); if (!aboveSymp) { - m_statep->preErrorDump(); nodep->v3fatalSrc("Can't find cell insertion point at '"<prettyName()); } } @@ -554,7 +565,6 @@ private: VSymEnt* okSymp; aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp); if (!aboveSymp) { - m_statep->preErrorDump(); nodep->v3fatalSrc("Can't find cellinline insertion point at '"<prettyName()); } m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident); @@ -666,7 +676,6 @@ private: if (!foundp) { ins=true; } else if (!findvarp && foundp && m_curSymp->findIdFlat(nodep->name())) { - m_statep->preErrorDump(); nodep->v3error("Unsupported in C: Variable has same name as " <nodep())<<": "<prettyName()); } else if (findvarp != nodep) { @@ -1087,7 +1096,6 @@ private: } inline void checkNoDot(AstNode* nodep) { if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) { - m_statep->preErrorDump(); UINFO(1,"ds="<v3error("Syntax Error: Not expecting "<type()<<" under a "<backp()->type()<<" in dotted expression"); m_ds.m_dotErr = true; @@ -1344,7 +1352,6 @@ private: bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText==""); bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name())); if (err) { - m_statep->preErrorDump(); if (foundp) { nodep->v3error("Found definition of '"<prettyName() <<"'"<<" as a "<nodep()->typeName() @@ -1388,7 +1395,6 @@ private: nodep->packagep(foundp->packagep()); // Generally set by parse, but might be an import } if (!nodep->varp()) { - m_statep->preErrorDump(); nodep->v3error("Can't find definition of signal, again: "<prettyName()); } } @@ -1412,7 +1418,6 @@ private: string inl = AstNode::dedotName(nodep->inlinedDots()); dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp); if (!dotSymp) { - m_statep->preErrorDump(); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<inlinedDots()); } } @@ -1423,7 +1428,6 @@ private: nodep->varp(varp); UINFO(7," Resolved "<varp()) { - m_statep->preErrorDump(); nodep->v3error("Can't find definition of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } @@ -1432,7 +1436,6 @@ private: VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); AstVarScope* vscp = foundp->nodep()->castVarScope(); // maybe NULL if (!vscp) { - m_statep->preErrorDump(); nodep->v3error("Can't find varpin scope of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } else { @@ -1499,7 +1502,6 @@ private: UINFO(8,"\t\tInlined "<findDotted(dotSymp, inl, baddot, okSymp); if (!dotSymp) { - m_statep->preErrorDump(); okSymp->cellErrorScopes(nodep); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<inlinedDots()); } @@ -1516,7 +1518,6 @@ private: UINFO(7," Resolved "<preErrorDump(); UINFO(7," ErrFtask curSymp=se"<<(void*)m_curSymp<<" dotSymp=se"<<(void*)dotSymp<v3error("Found definition of '"<prettyName() diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 8b6224ecd..6fc8596c9 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -676,7 +676,7 @@ int main(int argc, char** argv, char** env) { } // Final steps - V3Global::dumpGlobalTree("final.tree",999); + V3Global::dumpGlobalTree("final.tree",990); V3Error::abortIfWarnings(); if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc()