// $Id$ //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.com/verilator // // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // //************************************************************************* // // Copyright 2003-2006 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // General Public License or the Perl Artistic License. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include "V3Error.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" #endif //====================================================================== // Statics FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret()); int V3Error::s_errcnt = 0; int V3Error::s_debugDefault = 0; ostringstream V3Error::s_errorStr; // Error string being formed V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL; bool V3Error::s_describedEachWarn[V3ErrorCode::MAX]; bool V3Error::s_describedWarnings = false; bool V3Error::s_pretendError[V3ErrorCode::MAX]; struct v3errorIniter { v3errorIniter() { V3Error::init(); }; }; v3errorIniter v3errorInit; //###################################################################### // ErrorCode class functions V3ErrorCode::V3ErrorCode(const char* msgp) { // Return error encoding for given string, or ERROR, which is a bad code for (int codei=V3ErrorCode::FIRST_WARN; codeilineno(atoi(ln)); } while (*textp && (isspace(*textp) || *textp=='"')) textp++; // Grab filename const char *fn = textp; while (*textp && !(isspace(*textp) || *textp=='"')) textp++; if (textp != fn) { string strfn = fn; strfn = strfn.substr(0, textp-fn); this->filename(strfn); } //printf ("PPLINE %d '%s'\n", s_lineno, s_filename.c_str()); } bool FileLine::warnOff(const string& msg, bool flag) { V3ErrorCode code (msg.c_str()); if (code == V3ErrorCode::ERROR) { return false; } else { warnOff(code, flag); return true; } } FileLine* FileLine::copyOrSameFileLine() { // Return this, or a copy of this // There are often more then one token per line, thus we use the // same pointer as long as we're on the same line. static FileLine* lastNewp = NULL; if (lastNewp && *lastNewp == *this) { return lastNewp; } FileLine* newp = new FileLine(this); lastNewp = newp; return newp; } const string FileLine::filebasename() const { string name = filename(); string::size_type pos; if ((pos = name.rfind("/")) != string::npos) { name.erase(0,pos+1); } return name; } const string FileLine::profileFuncname() const { // Return string that is OK as a function name - for profiling string name = filebasename(); string::size_type pos; if ((pos = name.find(".")) != string::npos) { name = name.substr(0,pos); } while ((pos = name.find_first_not_of("abcdefghijlkmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789_")) != string::npos) { name.replace(pos, 1, "_"); } name += "__"+cvtToStr(lineno()); return name; } string FileLine::ascii() const { return filename()+":"+cvtToStr(lineno()); } ostream& operator<<(ostream& os, FileLine* fileline) { os <ascii()<<": "<20) numsp = 20; out<<(spaces + numsp); return out.str(); } void V3Error::incErrors() { s_errcnt++; if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse v3fatal ("Exiting due to too many errors encountered\n"); } } void V3Error::abortIfErrors() { if (errorCount()) { v3fatal ("Exiting due to "<=V3ErrorCode::FIRST_WARN) { V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1); s_errorCode=V3ErrorCode::SUPPRESS; } } void V3Error::v3abort () { v3fatalSrc("v3abort called\n"); } void V3Error::v3errorEnd (ostringstream& sstr) { #ifdef __COVERITY__ if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x); #endif if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) { cerr<=V3ErrorCode::FIRST_WARN && !s_describedWarnings) { cerr<dumpTreeFile(v3Global.debugFilename("final.tree",99)); V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } #endif } if (V3Error::debugDefault()) { cerr<