2012-04-13 01:08:20 +00:00
|
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Error handling
|
|
|
|
|
//
|
2008-04-25 12:14:27 +00:00
|
|
|
|
// Code available from: http://www.veripool.org/verilator
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2013-01-01 14:42:59 +00:00
|
|
|
|
// Copyright 2003-2013 by Wilson Snyder. This program is free software; you can
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 21:07:57 +00:00
|
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
// 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
|
2006-12-18 19:20:45 +00:00
|
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#include <string>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <bitset>
|
2011-10-11 11:07:24 +00:00
|
|
|
|
#include <map>
|
2012-05-22 01:31:52 +00:00
|
|
|
|
#include <set>
|
2011-10-11 11:07:24 +00:00
|
|
|
|
#include <deque>
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2012-11-14 01:12:23 +00:00
|
|
|
|
#include "V3LangCode.h"
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
class V3ErrorCode {
|
|
|
|
|
public:
|
|
|
|
|
enum en {
|
2010-02-02 01:15:48 +00:00
|
|
|
|
EC_MIN=0, // Keep first
|
2008-12-11 20:23:44 +00:00
|
|
|
|
//
|
2010-02-02 01:15:48 +00:00
|
|
|
|
EC_INFO, // General information out
|
|
|
|
|
EC_FATAL, // Kill the program
|
|
|
|
|
EC_FATALSRC, // Kill the program, for internal source errors
|
|
|
|
|
EC_ERROR, // General error out, can't suppress
|
2008-12-11 21:01:41 +00:00
|
|
|
|
// 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*/
|
2010-12-30 11:58:02 +00:00
|
|
|
|
I_LINT, // All lint messages
|
2010-02-23 14:27:16 +00:00
|
|
|
|
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
|
2006-10-18 13:45:50 +00:00
|
|
|
|
// Error codes:
|
2011-10-25 22:57:49 +00:00
|
|
|
|
E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops
|
2011-11-30 21:20:43 +00:00
|
|
|
|
E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable
|
2009-11-30 23:36:31 +00:00
|
|
|
|
E_MULTITOP, // Error: Multiple top level modules
|
|
|
|
|
E_TASKNSVAR, // Error: Task I/O not simple
|
2010-12-25 20:13:56 +00:00
|
|
|
|
//
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Warning codes:
|
2010-02-02 01:15:48 +00:00
|
|
|
|
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
|
2006-10-18 13:45:50 +00:00
|
|
|
|
//
|
2013-05-01 02:55:28 +00:00
|
|
|
|
ALWCOMBORDER, // Always_comb with unordered statements
|
2011-10-21 00:50:42 +00:00
|
|
|
|
ASSIGNDLY, // Assignment delays
|
2011-10-25 22:57:49 +00:00
|
|
|
|
ASSIGNIN, // Assigning to input
|
2006-08-26 11:35:28 +00:00
|
|
|
|
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
2010-12-31 23:36:29 +00:00
|
|
|
|
BLKSEQ, // Blocking assignments in sequential block
|
2006-08-26 11:35:28 +00:00
|
|
|
|
CASEINCOMPLETE, // Case statement has missing values
|
|
|
|
|
CASEOVERLAP, // Case statements overlap
|
2008-07-22 17:07:19 +00:00
|
|
|
|
CASEWITHX, // Case with X values
|
2006-08-26 11:35:28 +00:00
|
|
|
|
CASEX, // Casex
|
2010-01-07 21:41:19 +00:00
|
|
|
|
CDCRSTLOGIC, // Logic in async reset path
|
2006-08-26 11:35:28 +00:00
|
|
|
|
CMPCONST, // Comparison is constant due to limited range
|
|
|
|
|
COMBDLY, // Combinatorial delayed assignment
|
2010-12-25 20:13:56 +00:00
|
|
|
|
DEFPARAM, // Style: Defparam
|
2010-12-25 21:31:22 +00:00
|
|
|
|
DECLFILENAME, // Declaration doesn't match filename
|
2012-03-08 01:14:18 +00:00
|
|
|
|
ENDLABEL, // End lable name mismatch
|
2006-08-26 11:35:28 +00:00
|
|
|
|
GENCLK, // Generated Clock
|
2010-12-26 14:31:09 +00:00
|
|
|
|
IFDEPTH, // If statements too deep
|
2008-08-05 17:41:53 +00:00
|
|
|
|
IMPERFECTSCH, // Imperfect schedule (disabled by default)
|
2006-08-26 11:35:28 +00:00
|
|
|
|
IMPLICIT, // Implicit wire
|
2006-10-11 15:41:42 +00:00
|
|
|
|
IMPURE, // Impure function not being inlined
|
2010-12-25 20:50:07 +00:00
|
|
|
|
INCABSPATH, // Include has absolute path
|
2012-04-27 00:40:13 +00:00
|
|
|
|
INITIALDLY, // Initial delayed statement
|
2009-10-25 20:53:55 +00:00
|
|
|
|
LITENDIAN, // Little bit endian vector
|
2010-01-08 01:25:15 +00:00
|
|
|
|
MODDUP, // Duplicate module
|
2006-08-26 11:35:28 +00:00
|
|
|
|
MULTIDRIVEN, // Driven from multiple blocks
|
2012-04-26 22:43:12 +00:00
|
|
|
|
PINMISSING, // Cell pin not specified
|
|
|
|
|
PINNOCONNECT, // Cell pin not connected
|
2011-07-24 19:01:51 +00:00
|
|
|
|
REALCVT, // Real conversion
|
2008-03-19 15:05:08 +00:00
|
|
|
|
REDEFMACRO, // Redefining existing define macro
|
2012-04-05 01:55:20 +00:00
|
|
|
|
SELRANGE, // Selection index out of range
|
2010-12-26 14:31:09 +00:00
|
|
|
|
STMTDLY, // Delayed statement
|
|
|
|
|
SYMRSVDWORD, // Symbol is Reserved Word
|
2010-12-31 12:51:14 +00:00
|
|
|
|
SYNCASYNCNET, // Mixed sync + async reset
|
2006-08-26 11:35:28 +00:00
|
|
|
|
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
|
2008-04-02 12:53:53 +00:00
|
|
|
|
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
|
2010-02-02 01:15:48 +00:00
|
|
|
|
_ENUM_MAX
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// ***Add new elements below also***
|
|
|
|
|
};
|
|
|
|
|
enum en m_e;
|
2011-08-05 01:58:45 +00:00
|
|
|
|
inline V3ErrorCode () : m_e(EC_MIN) {}
|
2009-07-22 18:38:20 +00:00
|
|
|
|
inline V3ErrorCode (en _e) : m_e(_e) {}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
V3ErrorCode (const char* msgp); // Matching code or ERROR
|
2009-07-22 18:38:20 +00:00
|
|
|
|
explicit inline V3ErrorCode (int _e) : m_e(static_cast<en>(_e)) {}
|
|
|
|
|
operator en () const { return m_e; }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
const char* ascii() const {
|
|
|
|
|
const char* names[] = {
|
|
|
|
|
// Leading spaces indicate it can't be disabled.
|
2010-12-30 13:41:23 +00:00
|
|
|
|
" MIN", " INFO", " FATAL", " FATALSRC", " ERROR",
|
2008-12-11 21:01:41 +00:00
|
|
|
|
// Boolean
|
2010-12-30 11:58:02 +00:00
|
|
|
|
" I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE",
|
2008-12-11 21:01:41 +00:00
|
|
|
|
// Errors
|
2011-11-30 21:20:43 +00:00
|
|
|
|
"BLKLOOPINIT", "DETECTARRAY", "MULTITOP", "TASKNSVAR",
|
2008-12-11 21:01:41 +00:00
|
|
|
|
// Warnings
|
2010-12-25 20:13:56 +00:00
|
|
|
|
" EC_FIRST_WARN",
|
2013-05-01 02:55:28 +00:00
|
|
|
|
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN",
|
2010-12-31 23:36:29 +00:00
|
|
|
|
"BLKANDNBLK", "BLKSEQ",
|
2010-01-07 21:41:19 +00:00
|
|
|
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
2010-12-25 21:31:22 +00:00
|
|
|
|
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
2012-03-08 01:14:18 +00:00
|
|
|
|
"ENDLABEL", "GENCLK",
|
2012-04-27 00:40:13 +00:00
|
|
|
|
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
|
|
|
|
|
"INCABSPATH", "INITIALDLY",
|
2010-01-08 01:25:15 +00:00
|
|
|
|
"LITENDIAN", "MODDUP",
|
2010-12-31 23:36:29 +00:00
|
|
|
|
"MULTIDRIVEN",
|
2012-04-26 22:43:12 +00:00
|
|
|
|
"PINMISSING", "PINNOCONNECT",
|
2011-07-24 19:01:51 +00:00
|
|
|
|
"REALCVT", "REDEFMACRO",
|
2012-04-05 01:55:20 +00:00
|
|
|
|
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
2006-08-26 11:35:28 +00:00
|
|
|
|
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
2008-04-02 12:53:53 +00:00
|
|
|
|
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
2006-08-26 11:35:28 +00:00
|
|
|
|
" MAX"
|
|
|
|
|
};
|
|
|
|
|
return names[m_e];
|
2009-07-22 18:38:20 +00:00
|
|
|
|
}
|
2008-08-05 17:41:53 +00:00
|
|
|
|
// Warnings that default to off
|
2010-12-25 20:13:56 +00:00
|
|
|
|
bool defaultsOff() const { return ( m_e==IMPERFECTSCH || styleError()); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Warnings that warn about nasty side effects
|
2009-07-22 18:38:20 +00:00
|
|
|
|
bool dangerous() const { return ( m_e==COMBDLY ); }
|
2006-10-11 15:41:42 +00:00
|
|
|
|
// Warnings we'll present to the user as errors
|
|
|
|
|
// Later -Werror- options may make more of these.
|
2011-10-25 22:57:49 +00:00
|
|
|
|
bool pretendError() const { return ( m_e==ASSIGNIN || m_e==BLKANDNBLK
|
|
|
|
|
|| m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); }
|
2009-07-22 18:38:20 +00:00
|
|
|
|
// Warnings to mention manual
|
2010-02-02 01:15:48 +00:00
|
|
|
|
bool mentionManual() const { return ( m_e==EC_FATALSRC || pretendError() ); }
|
2009-07-22 18:38:20 +00:00
|
|
|
|
|
2007-10-31 21:17:23 +00:00
|
|
|
|
// Warnings that are lint only
|
2013-05-01 02:55:28 +00:00
|
|
|
|
bool lintError() const { return ( m_e==ALWCOMBORDER
|
|
|
|
|
|| m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|
2008-07-22 17:07:19 +00:00
|
|
|
|
|| m_e==CASEWITHX || m_e==CASEX
|
|
|
|
|
|| m_e==CMPCONST
|
2012-03-08 01:14:18 +00:00
|
|
|
|
|| m_e==ENDLABEL
|
2007-10-31 21:17:23 +00:00
|
|
|
|
|| m_e==IMPLICIT
|
2009-10-25 20:53:55 +00:00
|
|
|
|
|| m_e==LITENDIAN
|
2012-04-26 22:43:12 +00:00
|
|
|
|
|| m_e==PINMISSING
|
2011-07-24 19:01:51 +00:00
|
|
|
|
|| m_e==REALCVT
|
2010-12-26 15:17:35 +00:00
|
|
|
|
|| m_e==UNSIGNED
|
2009-07-22 18:38:20 +00:00
|
|
|
|
|| m_e==WIDTH); }
|
2010-12-25 20:13:56 +00:00
|
|
|
|
// Warnings that are style only
|
2011-10-21 00:50:42 +00:00
|
|
|
|
bool styleError() const { return ( m_e==ASSIGNDLY // More than style, but for backward compatibility
|
|
|
|
|
|| m_e==BLKSEQ
|
2010-12-31 23:36:29 +00:00
|
|
|
|
|| m_e==DEFPARAM
|
2010-12-25 21:31:22 +00:00
|
|
|
|
|| m_e==DECLFILENAME
|
2010-12-25 20:50:07 +00:00
|
|
|
|
|| m_e==INCABSPATH
|
2012-04-26 22:43:12 +00:00
|
|
|
|
|| m_e==PINNOCONNECT
|
2010-12-31 12:51:14 +00:00
|
|
|
|
|| m_e==SYNCASYNCNET
|
2010-12-26 15:17:35 +00:00
|
|
|
|
|| m_e==UNDRIVEN
|
|
|
|
|
|| m_e==UNUSED
|
2010-12-25 20:28:13 +00:00
|
|
|
|
|| m_e==VARHIDDEN ); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
};
|
|
|
|
|
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<<rhs.ascii(); }
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
class V3Error {
|
|
|
|
|
// Base class for any object that wants debugging and error reporting
|
2012-05-22 01:31:52 +00:00
|
|
|
|
|
|
|
|
|
typedef set<string> MessagesSet;
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
private:
|
|
|
|
|
static bool s_describedWarnings; // Told user how to disable warns
|
2010-02-02 01:15:48 +00:00
|
|
|
|
static bool s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; // Told user specifics about this warning
|
|
|
|
|
static bool s_pretendError[V3ErrorCode::_ENUM_MAX]; // Pretend this warning is an error
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static int s_debugDefault; // Default debugging level
|
2007-06-12 19:39:10 +00:00
|
|
|
|
static int s_errCount; // Error count
|
|
|
|
|
static int s_warnCount; // Error count
|
2009-06-21 23:37:15 +00:00
|
|
|
|
static int s_tellManual; // Tell user to see manual, 0=not yet, 1=doit, 2=disable
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static ostringstream s_errorStr; // Error string being formed
|
|
|
|
|
static V3ErrorCode s_errorCode; // Error string being formed will abort
|
2010-12-30 13:41:23 +00:00
|
|
|
|
static bool s_errorSuppressed; // Error being formed should be suppressed
|
2012-05-22 01:31:52 +00:00
|
|
|
|
static MessagesSet s_messages; // What errors we've outputted
|
2006-08-26 11:35:28 +00:00
|
|
|
|
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
|
|
|
|
|
|
|
|
|
|
V3Error() { cerr<<("Static class"); abort(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// CREATORS
|
|
|
|
|
// ACCESSORS
|
|
|
|
|
static void debugDefault(int level) { s_debugDefault = level; }
|
|
|
|
|
static int debugDefault() { return s_debugDefault; }
|
2012-05-22 01:24:17 +00:00
|
|
|
|
static string msgPrefix(); // returns %Error/%Warn
|
2007-06-12 19:39:10 +00:00
|
|
|
|
static int errorCount() { return s_errCount; }
|
|
|
|
|
static int warnCount() { return s_warnCount; }
|
|
|
|
|
static int errorOrWarnCount() { return errorCount()+warnCount(); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// METHODS
|
2007-11-02 11:23:03 +00:00
|
|
|
|
static void incErrors();
|
|
|
|
|
static void incWarnings();
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static void init();
|
|
|
|
|
static void abortIfErrors();
|
2007-06-12 19:39:10 +00:00
|
|
|
|
static void abortIfWarnings();
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
|
|
|
|
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
|
2010-12-30 13:41:23 +00:00
|
|
|
|
static bool isError(V3ErrorCode code, bool supp);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static string lineStr (const char* filename, int lineno);
|
|
|
|
|
static V3ErrorCode errorCode() { return s_errorCode; }
|
|
|
|
|
|
2012-05-22 01:24:17 +00:00
|
|
|
|
// When printing an error/warning, print prefix for multiline message
|
|
|
|
|
static string warnMore();
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Internals for v3error()/v3fatal() macros only
|
|
|
|
|
// Error end takes the string stream to output, be careful to seek() as needed
|
2012-05-22 01:24:17 +00:00
|
|
|
|
static void v3errorPrep(V3ErrorCode code) {
|
|
|
|
|
s_errorStr.str(""); s_errorCode=code; s_errorSuppressed=false; }
|
|
|
|
|
static ostringstream& v3errorStr() { return s_errorStr; }
|
2009-10-04 21:01:28 +00:00
|
|
|
|
static void vlAbort();
|
2006-08-26 11:35:28 +00:00
|
|
|
|
static void v3errorEnd(ostringstream& sstr); // static, but often overridden in classes.
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
|
|
|
|
|
inline int debug() { return V3Error::debugDefault(); }
|
|
|
|
|
inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
|
|
|
|
|
|
|
|
|
|
// These allow errors using << operators: v3error("foo"<<"bar");
|
|
|
|
|
// Careful, you can't put () around msg, as you would in most macro definitions
|
2012-05-22 01:24:17 +00:00
|
|
|
|
// Note the commas are the comma operator, not separating arguments. These are needed to insure
|
|
|
|
|
// evaluation order as otherwise we couldn't insure v3errorPrep is called first.
|
|
|
|
|
#define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
|
2010-01-07 21:41:19 +00:00
|
|
|
|
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code,msg)
|
2010-02-02 01:15:48 +00:00
|
|
|
|
#define v3info(msg) v3warn(EC_INFO,msg)
|
|
|
|
|
#define v3fatal(msg) v3warn(EC_FATAL,msg)
|
|
|
|
|
#define v3error(msg) v3warn(EC_ERROR,msg)
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Use this instead of fatal() to mention the source code line.
|
2010-02-02 01:15:48 +00:00
|
|
|
|
#define v3fatalSrc(msg) v3warn(EC_FATALSRC,__FILE__<<":"<<dec<<__LINE__<<": "<<msg)
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-08-10 15:19:45 +00:00
|
|
|
|
#define UINFO(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<"- "<<V3Error::lineStr(__FILE__,__LINE__)<<stmsg; }}
|
|
|
|
|
#define UINFONL(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<stmsg; } }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
#define UDEBUGONLY(stmts) {stmts}
|
2010-08-10 15:19:45 +00:00
|
|
|
|
#define UASSERT(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { v3fatalSrc(stmsg); }}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// For use in V3Ast static functions only
|
2010-08-10 15:19:45 +00:00
|
|
|
|
#define UASSERT_STATIC(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { cerr<<"Internal Error: "<<__FILE__<<":"<<dec<<__LINE__<<":"<<(stmsg)<<endl; abort(); } }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-01-17 19:48:39 +00:00
|
|
|
|
#define V3ERROR_NA { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
template< class T> std::string cvtToStr (const T& t) {
|
|
|
|
|
ostringstream os; os<<t; return os.str();
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-02 01:04:28 +00:00
|
|
|
|
inline uint32_t cvtToHash(const void* vp) {
|
2008-11-20 14:04:29 +00:00
|
|
|
|
// We can shove a 64 bit pointer into a 32 bit bucket
|
|
|
|
|
// On 32 bit systems, lower is always 0, but who cares?
|
2012-04-02 01:04:28 +00:00
|
|
|
|
union { const void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
|
2008-11-20 14:04:29 +00:00
|
|
|
|
u.l.upper=0; u.l.lower=0; u.up=vp;
|
|
|
|
|
return u.l.upper^u.l.lower;
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//######################################################################
|
|
|
|
|
|
2011-10-11 11:07:24 +00:00
|
|
|
|
class FileLine;
|
|
|
|
|
|
2012-11-14 01:12:23 +00:00
|
|
|
|
//! Singleton class with tables of per-file data.
|
|
|
|
|
|
|
|
|
|
//! This singleton class contains tables of data that are unchanging in each
|
|
|
|
|
//! source file (each with its own unique filename number).
|
2011-10-11 11:07:24 +00:00
|
|
|
|
class FileLineSingleton {
|
2012-03-20 19:57:29 +00:00
|
|
|
|
// TYPES
|
|
|
|
|
typedef map<string,int> FileNameNumMap;
|
2012-11-14 01:12:23 +00:00
|
|
|
|
typedef map<string,V3LangCode> FileLangNumMap;
|
2012-03-20 19:57:29 +00:00
|
|
|
|
// MEMBERS
|
|
|
|
|
FileNameNumMap m_namemap; // filenameno for each filename
|
2011-10-25 22:41:04 +00:00
|
|
|
|
deque<string> m_names; // filename text for each filenameno
|
2012-11-14 01:12:23 +00:00
|
|
|
|
deque<V3LangCode> m_languages; // language for each filenameno
|
2011-10-25 22:41:04 +00:00
|
|
|
|
// COSNTRUCTORS
|
|
|
|
|
FileLineSingleton() { }
|
|
|
|
|
~FileLineSingleton() { }
|
2011-10-11 11:07:24 +00:00
|
|
|
|
protected:
|
|
|
|
|
friend class FileLine;
|
2011-10-25 22:41:04 +00:00
|
|
|
|
// METHODS
|
|
|
|
|
int nameToNumber(const string& filename);
|
2011-12-27 17:15:20 +00:00
|
|
|
|
const string numberToName(int filenameno) const { return m_names[filenameno]; }
|
2012-11-14 01:12:23 +00:00
|
|
|
|
const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; }
|
2013-02-03 18:27:37 +00:00
|
|
|
|
void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; }
|
2012-11-14 01:12:23 +00:00
|
|
|
|
void clear() { m_namemap.clear(); m_names.clear(); m_languages.clear(); }
|
2012-03-20 20:13:10 +00:00
|
|
|
|
void fileNameNumMapDumpXml(ostream& os);
|
2012-03-20 19:57:29 +00:00
|
|
|
|
static const string filenameLetters(int fileno);
|
2011-10-11 11:07:24 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-11-14 01:12:23 +00:00
|
|
|
|
//! File and line number of an object, mostly for error reporting
|
|
|
|
|
|
|
|
|
|
//! This class is instantiated for every source code line (potentially
|
|
|
|
|
//! millions). To save space, per-file information (e.g. filename, source
|
|
|
|
|
//! language is held in tables in the FileLineSingleton class.
|
2006-08-26 11:35:28 +00:00
|
|
|
|
class FileLine {
|
|
|
|
|
int m_lineno;
|
2011-10-11 11:07:24 +00:00
|
|
|
|
int m_filenameno;
|
2010-02-02 01:15:48 +00:00
|
|
|
|
bitset<V3ErrorCode::_ENUM_MAX> m_warnOn;
|
2011-10-11 11:07:24 +00:00
|
|
|
|
|
2011-10-25 22:41:04 +00:00
|
|
|
|
private:
|
2006-08-26 11:35:28 +00:00
|
|
|
|
struct EmptySecret {};
|
2011-10-25 22:41:04 +00:00
|
|
|
|
inline static FileLineSingleton& singleton() {
|
|
|
|
|
static FileLineSingleton s;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
inline static FileLine& defaultFileLine() {
|
|
|
|
|
static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret());
|
|
|
|
|
return *defFilelinep;
|
|
|
|
|
}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
protected:
|
|
|
|
|
// User routines should never need to change line numbers
|
|
|
|
|
// We are storing pointers, so we CAN'T change them after initial reading.
|
2011-10-25 22:41:04 +00:00
|
|
|
|
friend class FileLineSingleton;
|
2009-10-31 14:08:38 +00:00
|
|
|
|
friend class V3ParseImp;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
friend class V3PreLex;
|
2010-07-09 00:31:41 +00:00
|
|
|
|
friend class V3PreProcImp;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
void lineno(int num) { m_lineno = num; }
|
2012-11-14 01:12:23 +00:00
|
|
|
|
void language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
|
2011-10-25 22:41:04 +00:00
|
|
|
|
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
|
2010-07-07 00:29:12 +00:00
|
|
|
|
void lineDirective(const char* textp, int& enterExitRef);
|
2010-07-09 00:31:41 +00:00
|
|
|
|
void linenoInc() { m_lineno++; }
|
|
|
|
|
void linenoIncInPlace() { m_lineno++; }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
FileLine* copyOrSameFileLine();
|
|
|
|
|
public:
|
2011-10-11 11:07:24 +00:00
|
|
|
|
FileLine (const string& filename, int lineno) {
|
2011-10-25 22:41:04 +00:00
|
|
|
|
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
|
|
|
|
|
m_warnOn=defaultFileLine().m_warnOn; }
|
2011-10-11 11:07:24 +00:00
|
|
|
|
FileLine (FileLine* fromp) {
|
|
|
|
|
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
|
2008-08-05 17:41:53 +00:00
|
|
|
|
FileLine (EmptySecret);
|
2007-11-02 11:23:03 +00:00
|
|
|
|
~FileLine() { }
|
2010-07-09 00:31:41 +00:00
|
|
|
|
FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); }
|
|
|
|
|
FileLine* create(int lineno) { return create(filename(), lineno); }
|
2010-01-20 02:30:12 +00:00
|
|
|
|
static void deleteAllRemaining();
|
2007-11-02 11:23:03 +00:00
|
|
|
|
#ifdef VL_LEAK_CHECKS
|
|
|
|
|
static void* operator new(size_t size);
|
|
|
|
|
static void operator delete(void* obj, size_t size);
|
|
|
|
|
#endif
|
2010-07-09 00:31:41 +00:00
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
int lineno () const { return m_lineno; }
|
2012-11-14 01:12:23 +00:00
|
|
|
|
V3LangCode language () const { return singleton().numberToLang(m_filenameno); }
|
|
|
|
|
void updateLanguage ();
|
2006-08-26 11:35:28 +00:00
|
|
|
|
string ascii() const;
|
2011-10-25 22:41:04 +00:00
|
|
|
|
const string filename () const { return singleton().numberToName(m_filenameno); }
|
2012-03-20 19:57:29 +00:00
|
|
|
|
const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
const string filebasename () const;
|
2010-12-25 21:31:22 +00:00
|
|
|
|
const string filebasenameNoExt () const;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
const string profileFuncname() const;
|
2012-03-20 20:13:10 +00:00
|
|
|
|
const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
|
2010-07-07 00:29:12 +00:00
|
|
|
|
string lineDirectiveStrg(int enter_exit_level) const;
|
2010-01-21 11:11:30 +00:00
|
|
|
|
void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line.
|
|
|
|
|
void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
bool warnOff(const string& code, bool flag); // Returns 1 if ok
|
2008-08-01 19:30:17 +00:00
|
|
|
|
bool warnIsOff(V3ErrorCode code) const;
|
2007-10-31 21:17:23 +00:00
|
|
|
|
void warnLintOff(bool flag);
|
2010-12-25 20:13:56 +00:00
|
|
|
|
void warnStyleOff(bool flag);
|
2008-12-11 20:23:44 +00:00
|
|
|
|
void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; }
|
2011-10-25 22:41:04 +00:00
|
|
|
|
void warnResetDefault() { warnStateFrom(defaultFileLine()); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-01-20 02:30:12 +00:00
|
|
|
|
// Specific flag ACCESSORS/METHODS
|
2008-12-11 21:01:41 +00:00
|
|
|
|
bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); }
|
2010-01-21 11:11:30 +00:00
|
|
|
|
void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); }
|
2008-12-11 21:01:41 +00:00
|
|
|
|
bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); }
|
2010-01-21 11:11:30 +00:00
|
|
|
|
void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); }
|
|
|
|
|
|
|
|
|
|
// METHODS - Global
|
2011-10-11 11:07:24 +00:00
|
|
|
|
static void globalWarnLintOff(bool flag) {
|
2011-10-25 22:41:04 +00:00
|
|
|
|
defaultFileLine().warnLintOff(flag); }
|
2011-10-11 11:07:24 +00:00
|
|
|
|
static void globalWarnStyleOff(bool flag) {
|
2011-10-25 22:41:04 +00:00
|
|
|
|
defaultFileLine().warnStyleOff(flag); }
|
2011-10-11 11:07:24 +00:00
|
|
|
|
static void globalWarnOff(V3ErrorCode code, bool flag) {
|
2011-10-25 22:41:04 +00:00
|
|
|
|
defaultFileLine().warnOff(code, flag); }
|
2011-10-11 11:07:24 +00:00
|
|
|
|
static bool globalWarnOff(const string& code, bool flag) {
|
2011-10-25 22:41:04 +00:00
|
|
|
|
return defaultFileLine().warnOff(code, flag); }
|
2012-03-20 20:13:10 +00:00
|
|
|
|
static void fileNameNumMapDumpXml(ostream& os) {
|
|
|
|
|
singleton().fileNameNumMapDumpXml(os); }
|
2008-12-11 21:01:41 +00:00
|
|
|
|
|
2010-01-20 02:30:12 +00:00
|
|
|
|
// METHODS - Called from netlist
|
|
|
|
|
// Merge warning disables from another fileline
|
|
|
|
|
void modifyStateInherit(const FileLine* fromp);
|
|
|
|
|
// Change the current fileline due to actions discovered after parsing
|
|
|
|
|
// and may have side effects on other nodes sharing this FileLine.
|
2012-03-20 20:01:53 +00:00
|
|
|
|
// Use only when this is intended
|
2010-01-20 02:30:12 +00:00
|
|
|
|
void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); }
|
|
|
|
|
|
|
|
|
|
// OPERATORS
|
|
|
|
|
void v3errorEnd(ostringstream& str);
|
2012-05-22 01:24:17 +00:00
|
|
|
|
string warnMore() const;
|
2011-08-05 01:58:45 +00:00
|
|
|
|
inline bool operator==(FileLine rhs) const {
|
2011-10-11 11:07:24 +00:00
|
|
|
|
return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn);
|
2010-01-09 17:31:58 +00:00
|
|
|
|
}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
};
|
|
|
|
|
ostream& operator<<(ostream& os, FileLine* fileline);
|
|
|
|
|
|
|
|
|
|
#endif // Guard
|