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_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();
}

View File

@ -181,6 +181,7 @@ class V3Error {
// Base class for any object that wants debugging and error reporting
typedef set<string> 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();

View File

@ -80,6 +80,8 @@ private:
typedef std::multimap<string,VSymEnt*> NameScopeSymMap;
typedef set <pair<AstNodeModule*,string> > 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<<endl); // Not always same as nodep->name
UINFO(4,"Var1 "<<nodep<<endl);
UINFO(4,"Var2 "<<fnodep<<endl);
@ -399,6 +409,8 @@ public:
}
};
LinkDotState* LinkDotState::s_errorThisp = NULL;
//======================================================================
class LinkDotFindVisitor : public AstNVisitor {
@ -525,7 +537,6 @@ private:
VSymEnt* okSymp;
aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp);
if (!aboveSymp) {
m_statep->preErrorDump();
nodep->v3fatalSrc("Can't find cell insertion point at '"<<baddot<<"' in: "<<nodep->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 '"<<baddot<<"' in: "<<nodep->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 "
<<LinkDotState::nodeTextType(foundp->nodep())<<": "<<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="<<m_ds.ascii()<<endl);
nodep->v3error("Syntax Error: Not expecting "<<nodep->type()<<" under a "<<nodep->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 '"<<m_ds.m_dotText<<(m_ds.m_dotText==""?"":".")<<nodep->prettyName()
<<"'"<<" as a "<<foundp->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: "<<nodep->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 '"<<baddot<<"' in: "<<nodep->inlinedDots());
}
}
@ -1423,7 +1428,6 @@ private:
nodep->varp(varp);
UINFO(7," Resolved "<<nodep<<endl); // Also prints varp
if (!nodep->varp()) {
m_statep->preErrorDump();
nodep->v3error("Can't find definition of '"<<baddot<<"' in dotted signal: "<<nodep->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 '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep);
} else {
@ -1499,7 +1502,6 @@ private:
UINFO(8,"\t\tInlined "<<inl<<endl);
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
if (!dotSymp) {
m_statep->preErrorDump();
okSymp->cellErrorScopes(nodep);
nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
}
@ -1516,7 +1518,6 @@ private:
UINFO(7," Resolved "<<nodep<<endl); // Also prints taskp
} else {
// Note ParseRef has similar error handling/message output
m_statep->preErrorDump();
UINFO(7," ErrFtask curSymp=se"<<(void*)m_curSymp<<" dotSymp=se"<<(void*)dotSymp<<endl);
if (foundp) {
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
V3Global::dumpGlobalTree("final.tree",999);
V3Global::dumpGlobalTree("final.tree",990);
V3Error::abortIfWarnings();
if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc()