Internals: If registered, dump symtable on any error

This commit is contained in:
Wilson Snyder 2013-05-25 12:15:38 -04:00
parent 81bf95763c
commit 6b8d9b5c36
4 changed files with 22 additions and 15 deletions

View File

@ -44,6 +44,7 @@ bool V3Error::s_describedEachWarn[V3ErrorCode::_ENUM_MAX];
bool V3Error::s_describedWarnings = false; bool V3Error::s_describedWarnings = false;
bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX]; bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX];
V3Error::MessagesSet V3Error::s_messages; V3Error::MessagesSet V3Error::s_messages;
V3Error::ErrorExitCb V3Error::s_errorExitCb = NULL;
struct v3errorIniter { struct v3errorIniter {
v3errorIniter() { V3Error::init(); } v3errorIniter() { V3Error::init(); }
@ -482,7 +483,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
} }
#ifndef _V3ERROR_NO_GLOBAL_ #ifndef _V3ERROR_NO_GLOBAL_
if (debug()) { 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::statsFinalAll(v3Global.rootp());
V3Stats::statsReport(); V3Stats::statsReport();
} }

View File

@ -181,6 +181,7 @@ class V3Error {
// Base class for any object that wants debugging and error reporting // Base class for any object that wants debugging and error reporting
typedef set<string> MessagesSet; typedef set<string> MessagesSet;
typedef void (*ErrorExitCb)(void);
private: private:
static bool s_describedWarnings; // Told user how to disable warns 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 V3ErrorCode s_errorCode; // Error string being formed will abort
static bool s_errorSuppressed; // Error being formed should be suppressed static bool s_errorSuppressed; // Error being formed should be suppressed
static MessagesSet s_messages; // What errors we've outputted 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 enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
V3Error() { cerr<<("Static class"); abort(); } V3Error() { cerr<<("Static class"); abort(); }
@ -218,6 +221,7 @@ class V3Error {
static bool isError(V3ErrorCode code, bool supp); static bool isError(V3ErrorCode code, bool supp);
static string lineStr (const char* filename, int lineno); static string lineStr (const char* filename, int lineno);
static V3ErrorCode errorCode() { return s_errorCode; } static V3ErrorCode errorCode() { return s_errorCode; }
static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; }
// When printing an error/warning, print prefix for multiline message // When printing an error/warning, print prefix for multiline message
static string warnMore(); static string warnMore();

View File

@ -80,6 +80,8 @@ private:
typedef std::multimap<string,VSymEnt*> NameScopeSymMap; typedef std::multimap<string,VSymEnt*> NameScopeSymMap;
typedef set <pair<AstNodeModule*,string> > ImplicitNameSet; typedef set <pair<AstNodeModule*,string> > ImplicitNameSet;
static LinkDotState* s_errorThisp; // Last self, for error reporting only
// MEMBERS // MEMBERS
VSymGraph m_syms; // Symbol table VSymGraph m_syms; // Symbol table
VSymEnt* m_dunitEntp; // $unit entry VSymEnt* m_dunitEntp; // $unit entry
@ -88,6 +90,7 @@ private:
bool m_forPrimary; // First link bool m_forPrimary; // First link
bool m_forPrearray; // Compress cell__[array] refs bool m_forPrearray; // Compress cell__[array] refs
bool m_forScopeCreation; // Remove VarXRefs for V3Scope bool m_forScopeCreation; // Remove VarXRefs for V3Scope
public: public:
static int debug() { static int debug() {
@ -98,6 +101,9 @@ public:
void dump() { void dump() {
if (debug()>=6) m_syms.dumpFilePrefixed("linkdot"); if (debug()>=6) m_syms.dumpFilePrefixed("linkdot");
} }
static void preErrorDumpHandler() {
if (s_errorThisp) s_errorThisp->preErrorDump();
}
void preErrorDump() { void preErrorDump() {
static bool diddump = false; static bool diddump = false;
if (!diddump && v3Global.opt.dumpTree()) { if (!diddump && v3Global.opt.dumpTree()) {
@ -115,8 +121,13 @@ public:
m_forPrearray = (step == LDS_PARAMED || step==LDS_PRIMARY); m_forPrearray = (step == LDS_PARAMED || step==LDS_PRIMARY);
m_forScopeCreation = (step == LDS_SCOPED); m_forScopeCreation = (step == LDS_SCOPED);
m_dunitEntp = NULL; m_dunitEntp = NULL;
s_errorThisp = this;
V3Error::errorExitCb(preErrorDumpHandler); // If get error, dump self
}
~LinkDotState() {
V3Error::errorExitCb(NULL);
s_errorThisp = NULL;
} }
~LinkDotState() {}
// ACCESSORS // ACCESSORS
VSymGraph* symsp() { return &m_syms; } VSymGraph* symsp() { return &m_syms; }
@ -161,7 +172,6 @@ public:
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
// See t_gen_forif.v for an example. // See t_gen_forif.v for an example.
} else { } else {
preErrorDump();
UINFO(4,"name "<<name<<endl); // Not always same as nodep->name UINFO(4,"name "<<name<<endl); // Not always same as nodep->name
UINFO(4,"Var1 "<<nodep<<endl); UINFO(4,"Var1 "<<nodep<<endl);
UINFO(4,"Var2 "<<fnodep<<endl); UINFO(4,"Var2 "<<fnodep<<endl);
@ -399,6 +409,8 @@ public:
} }
}; };
LinkDotState* LinkDotState::s_errorThisp = NULL;
//====================================================================== //======================================================================
class LinkDotFindVisitor : public AstNVisitor { class LinkDotFindVisitor : public AstNVisitor {
@ -525,7 +537,6 @@ private:
VSymEnt* okSymp; VSymEnt* okSymp;
aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp); aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp);
if (!aboveSymp) { if (!aboveSymp) {
m_statep->preErrorDump();
nodep->v3fatalSrc("Can't find cell insertion point at '"<<baddot<<"' in: "<<nodep->prettyName()); nodep->v3fatalSrc("Can't find cell insertion point at '"<<baddot<<"' in: "<<nodep->prettyName());
} }
} }
@ -554,7 +565,6 @@ private:
VSymEnt* okSymp; VSymEnt* okSymp;
aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp); aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp);
if (!aboveSymp) { if (!aboveSymp) {
m_statep->preErrorDump();
nodep->v3fatalSrc("Can't find cellinline insertion point at '"<<baddot<<"' in: "<<nodep->prettyName()); nodep->v3fatalSrc("Can't find cellinline insertion point at '"<<baddot<<"' in: "<<nodep->prettyName());
} }
m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident); m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident);
@ -666,7 +676,6 @@ private:
if (!foundp) { if (!foundp) {
ins=true; ins=true;
} else if (!findvarp && foundp && m_curSymp->findIdFlat(nodep->name())) { } else if (!findvarp && foundp && m_curSymp->findIdFlat(nodep->name())) {
m_statep->preErrorDump();
nodep->v3error("Unsupported in C: Variable has same name as " nodep->v3error("Unsupported in C: Variable has same name as "
<<LinkDotState::nodeTextType(foundp->nodep())<<": "<<nodep->prettyName()); <<LinkDotState::nodeTextType(foundp->nodep())<<": "<<nodep->prettyName());
} else if (findvarp != nodep) { } else if (findvarp != nodep) {
@ -1087,7 +1096,6 @@ private:
} }
inline void checkNoDot(AstNode* nodep) { inline void checkNoDot(AstNode* nodep) {
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) { if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
m_statep->preErrorDump();
UINFO(1,"ds="<<m_ds.ascii()<<endl); UINFO(1,"ds="<<m_ds.ascii()<<endl);
nodep->v3error("Syntax Error: Not expecting "<<nodep->type()<<" under a "<<nodep->backp()->type()<<" in dotted expression"); nodep->v3error("Syntax Error: Not expecting "<<nodep->type()<<" under a "<<nodep->backp()->type()<<" in dotted expression");
m_ds.m_dotErr = true; m_ds.m_dotErr = true;
@ -1344,7 +1352,6 @@ private:
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText==""); bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="");
bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name())); bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
if (err) { if (err) {
m_statep->preErrorDump();
if (foundp) { if (foundp) {
nodep->v3error("Found definition of '"<<m_ds.m_dotText<<(m_ds.m_dotText==""?"":".")<<nodep->prettyName() nodep->v3error("Found definition of '"<<m_ds.m_dotText<<(m_ds.m_dotText==""?"":".")<<nodep->prettyName()
<<"'"<<" as a "<<foundp->nodep()->typeName() <<"'"<<" as a "<<foundp->nodep()->typeName()
@ -1388,7 +1395,6 @@ private:
nodep->packagep(foundp->packagep()); // Generally set by parse, but might be an import nodep->packagep(foundp->packagep()); // Generally set by parse, but might be an import
} }
if (!nodep->varp()) { if (!nodep->varp()) {
m_statep->preErrorDump();
nodep->v3error("Can't find definition of signal, again: "<<nodep->prettyName()); nodep->v3error("Can't find definition of signal, again: "<<nodep->prettyName());
} }
} }
@ -1412,7 +1418,6 @@ private:
string inl = AstNode::dedotName(nodep->inlinedDots()); string inl = AstNode::dedotName(nodep->inlinedDots());
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp); dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
if (!dotSymp) { if (!dotSymp) {
m_statep->preErrorDump();
nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots()); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
} }
} }
@ -1423,7 +1428,6 @@ private:
nodep->varp(varp); nodep->varp(varp);
UINFO(7," Resolved "<<nodep<<endl); // Also prints varp UINFO(7," Resolved "<<nodep<<endl); // Also prints varp
if (!nodep->varp()) { if (!nodep->varp()) {
m_statep->preErrorDump();
nodep->v3error("Can't find definition of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName()); nodep->v3error("Can't find definition of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep); okSymp->cellErrorScopes(nodep);
} }
@ -1432,7 +1436,6 @@ private:
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstVarScope* vscp = foundp->nodep()->castVarScope(); // maybe NULL AstVarScope* vscp = foundp->nodep()->castVarScope(); // maybe NULL
if (!vscp) { if (!vscp) {
m_statep->preErrorDump();
nodep->v3error("Can't find varpin scope of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName()); nodep->v3error("Can't find varpin scope of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep); okSymp->cellErrorScopes(nodep);
} else { } else {
@ -1499,7 +1502,6 @@ private:
UINFO(8,"\t\tInlined "<<inl<<endl); UINFO(8,"\t\tInlined "<<inl<<endl);
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp); dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
if (!dotSymp) { if (!dotSymp) {
m_statep->preErrorDump();
okSymp->cellErrorScopes(nodep); okSymp->cellErrorScopes(nodep);
nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots()); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
} }
@ -1516,7 +1518,6 @@ private:
UINFO(7," Resolved "<<nodep<<endl); // Also prints taskp UINFO(7," Resolved "<<nodep<<endl); // Also prints taskp
} else { } else {
// Note ParseRef has similar error handling/message output // Note ParseRef has similar error handling/message output
m_statep->preErrorDump();
UINFO(7," ErrFtask curSymp=se"<<(void*)m_curSymp<<" dotSymp=se"<<(void*)dotSymp<<endl); UINFO(7," ErrFtask curSymp=se"<<(void*)m_curSymp<<" dotSymp=se"<<(void*)dotSymp<<endl);
if (foundp) { if (foundp) {
nodep->v3error("Found definition of '"<<m_ds.m_dotText<<(m_ds.m_dotText==""?"":".")<<nodep->prettyName() nodep->v3error("Found definition of '"<<m_ds.m_dotText<<(m_ds.m_dotText==""?"":".")<<nodep->prettyName()

View File

@ -676,7 +676,7 @@ int main(int argc, char** argv, char** env) {
} }
// Final steps // Final steps
V3Global::dumpGlobalTree("final.tree",999); V3Global::dumpGlobalTree("final.tree",990);
V3Error::abortIfWarnings(); V3Error::abortIfWarnings();
if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc() if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc()