// -*- C++ -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // //************************************************************************* // // Copyright 2003-2008 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. // //************************************************************************* #ifndef _V3ERROR_H_ #define _V3ERROR_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include //###################################################################### class V3ErrorCode { public: enum en { MIN=0, // Keep first // SUPPRESS, // Warning suppressed by user INFO, // General information out FATAL, // Kill the program ERROR, // General error out, can't suppress // Boolean information we track per-line, but aren't errors I_COVERAGE, // Coverage is on/off from /*verilator coverage_on/off*/ I_TRACING, // Tracing is on/off from /*verilator tracing_on/off*/ // Error codes: MULTITOP, // Error: Multiple top level modules TASKNSVAR, // Error: Task I/O not simple // Warning codes: FIRST_WARN, // Just a code so the program knows where to start warnings // BLKANDNBLK, // Blocked and non-blocking assignments to same variable CASEINCOMPLETE, // Case statement has missing values CASEOVERLAP, // Case statements overlap CASEWITHX, // Case with X values CASEX, // Casex CMPCONST, // Comparison is constant due to limited range COMBDLY, // Combinatorial delayed assignment STMTDLY, // Delayed statement GENCLK, // Generated Clock IMPERFECTSCH, // Imperfect schedule (disabled by default) IMPLICIT, // Implicit wire IMPURE, // Impure function not being inlined MULTIDRIVEN, // Driven from multiple blocks REDEFMACRO, // Redefining existing define macro UNDRIVEN, // No drivers UNOPT, // Unoptimizable block UNOPTFLAT, // Unoptimizable block after flattening UNSIGNED, // Comparison is constant due to unsigned arithmetic UNUSED, // No receivers VARHIDDEN, // Hiding variable WIDTH, // Width mismatch WIDTHCONCAT, // Unsized numbers/parameters in concatenations MAX // ***Add new elements below also*** }; enum en m_e; inline V3ErrorCode () {}; inline V3ErrorCode (en _e) : m_e(_e) {}; V3ErrorCode (const char* msgp); // Matching code or ERROR explicit inline V3ErrorCode (int _e) : m_e(static_cast(_e)) {}; operator en () const { return m_e; }; const char* ascii() const { const char* names[] = { // Leading spaces indicate it can't be disabled. " MIN", " SUPPRESS", " INFO", " FATAL", " ERROR", // Boolean " I_COVERAGE", " I_TRACING", // Errors "MULTITOP", "TASKNSVAR", // Warnings " FIRST_WARN", "BLKANDNBLK", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CMPCONST", "COMBDLY", "STMTDLY", "GENCLK", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "MULTIDRIVEN", "REDEFMACRO", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED", "VARHIDDEN", "WIDTH", "WIDTHCONCAT", " MAX" }; return names[m_e]; }; // Warnings that default to off bool defaultsOff() const { return ( m_e==IMPERFECTSCH );}; // Warnings that warn about nasty side effects bool dangerous() const { return ( m_e==COMBDLY );}; // Warnings we'll present to the user as errors // Later -Werror- options may make more of these. bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); }; // Warnings that are lint only bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP || m_e==CASEWITHX || m_e==CASEX || m_e==CMPCONST || m_e==IMPLICIT || m_e==UNDRIVEN || m_e==UNSIGNED || m_e==UNUSED || m_e==VARHIDDEN || m_e==WIDTH); }; }; inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (V3ErrorCode::en lhs, V3ErrorCode rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, V3ErrorCode rhs) { return os<=(level)) { cout<<"- "<=(level)) { cout< std::string cvtToStr (const T& t) { ostringstream os; os< m_warnOn; static FileLine s_defaultFileLine; struct EmptySecret {}; protected: // User routines should never need to change line numbers // We are storing pointers, so we CAN'T change them after initial reading. friend class V3Read; friend class V3PreLex; void lineno(int num) { m_lineno = num; } void filename(const string& name) { m_filename = name; } void lineDirective(const char* textp); void incLineno() { m_lineno++; } FileLine* copyOrSameFileLine(); public: FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOn=s_defaultFileLine.m_warnOn; } FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOn=fromp->m_warnOn; } FileLine (EmptySecret); ~FileLine() { } #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif static FileLine& defaultFileLine() { return s_defaultFileLine; } int lineno () const { return m_lineno; } string ascii() const; const string filename () const { return m_filename; } const string filebasename () const; const char* cfilename () const { return m_filename.c_str(); } const string profileFuncname() const; void warnOff(V3ErrorCode code, bool flag) { m_warnOn.set(code,!flag); } // Turn on/off warning messages on this line. bool warnOff(const string& code, bool flag); // Returns 1 if ok bool warnIsOff(V3ErrorCode code) const; void warnLintOff(bool flag); void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; } void warnStateInherit(const FileLine& from); void warnResetDefault() { warnStateFrom(s_defaultFileLine); } // Boolean ACCESSORS/METHODS bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); } void coverageOn(bool flag) { m_warnOn.set(V3ErrorCode::I_COVERAGE,flag); } bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); } void tracingOn(bool flag) { m_warnOn.set(V3ErrorCode::I_TRACING,flag); } // METHODS void v3errorEnd(ostringstream& str); inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); } static void deleteAllRemaining(); }; ostream& operator<<(ostream& os, FileLine* fileline); #endif // Guard