Internal: Optimize program size by refactoring error reporting routines (#4446)
This commit is contained in:
parent
c3e19f2821
commit
cf6566b9bc
|
|
@ -1341,12 +1341,6 @@ bool AstNode::isTreePureRecurse() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void AstNode::v3errorEndFatal(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
}
|
||||
|
||||
string AstNode::instanceStr() const {
|
||||
// Max iterations before giving up on location search,
|
||||
// in case we have some circular reference bug.
|
||||
|
|
@ -1371,9 +1365,9 @@ string AstNode::instanceStr() const {
|
|||
|
||||
return "";
|
||||
}
|
||||
void AstNode::v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
void AstNode::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
|
||||
if (!m_fileline) {
|
||||
V3Error::s().v3errorEnd(str, instanceStr());
|
||||
V3Error::v3errorEnd(str, instanceStr());
|
||||
} else {
|
||||
std::ostringstream nsstr;
|
||||
nsstr << str.str();
|
||||
|
|
@ -1390,6 +1384,11 @@ void AstNode::v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s()
|
|||
nsstr, m_fileline->warnIsOff(V3Error::s().errorCode()) ? "" : instanceStr());
|
||||
}
|
||||
}
|
||||
void AstNode::v3errorEndFatal(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Data type conversion
|
||||
|
|
|
|||
|
|
@ -1916,9 +1916,9 @@ public:
|
|||
static AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
||||
|
||||
// METHODS - dump and error
|
||||
void v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex);
|
||||
void v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(std::ostringstream& str) const VL_ATTR_NORETURN
|
||||
VL_REQUIRES(V3Error::s().m_mutex);
|
||||
VL_RELEASE(V3Error::s().m_mutex);
|
||||
string warnContextPrimary() const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
return fileline()->warnContextPrimary();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,11 +503,11 @@ public:
|
|||
inline bool inlined() const;
|
||||
|
||||
// Methods that allow DfgVertex to participate in error reporting/messaging
|
||||
void v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
void v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
|
||||
m_filelinep->v3errorEnd(str);
|
||||
}
|
||||
void v3errorEndFatal(std::ostringstream& str) const VL_ATTR_NORETURN
|
||||
VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
VL_RELEASE(V3Error::s().m_mutex) {
|
||||
m_filelinep->v3errorEndFatal(str);
|
||||
}
|
||||
string warnContextPrimary() const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
|
|
|
|||
|
|
@ -291,3 +291,35 @@ void V3Error::vlAbort() {
|
|||
VL_GCOV_DUMP();
|
||||
std::abort();
|
||||
}
|
||||
void V3Error::v3errorAcquireLock() VL_ACQUIRE(s().m_mutex) {
|
||||
#ifndef V3ERROR_NO_GLOBAL_
|
||||
V3Error::s().m_mutex.lockCheckStopRequest(
|
||||
[]() -> void { V3ThreadPool::s().waitIfStopRequested(); });
|
||||
#else
|
||||
V3Error::s().m_mutex.lock();
|
||||
#endif
|
||||
}
|
||||
std::ostringstream& V3Error::v3errorPrep(V3ErrorCode code) VL_ACQUIRE(s().m_mutex) {
|
||||
v3errorAcquireLock();
|
||||
s().v3errorPrep(code);
|
||||
return v3errorStr();
|
||||
}
|
||||
std::ostringstream& V3Error::v3errorPrepFileLine(V3ErrorCode code, const char* file, int line)
|
||||
VL_ACQUIRE(s().m_mutex) {
|
||||
v3errorPrep(code) << file << ":" << std::dec << line << ": ";
|
||||
return v3errorStr();
|
||||
}
|
||||
std::ostringstream& V3Error::v3errorStr() VL_REQUIRES(s().m_mutex) { return s().v3errorStr(); }
|
||||
void V3Error::v3errorEnd(std::ostringstream& sstr, const string& extra) VL_RELEASE(s().m_mutex) {
|
||||
s().v3errorEnd(sstr, extra);
|
||||
V3Error::s().m_mutex.unlock();
|
||||
}
|
||||
|
||||
void v3errorEnd(std::ostringstream& sstr) VL_RELEASE(V3Error::s().m_mutex) {
|
||||
V3Error::v3errorEnd(sstr);
|
||||
}
|
||||
void v3errorEndFatal(std::ostringstream& sstr) VL_RELEASE(V3Error::s().m_mutex) {
|
||||
V3Error::v3errorEnd(sstr);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
}
|
||||
|
|
|
|||
103
src/V3Error.h
103
src/V3Error.h
|
|
@ -286,9 +286,13 @@ inline std::ostream& operator<<(std::ostream& os, const V3ErrorCode& rhs) {
|
|||
}
|
||||
|
||||
// ######################################################################
|
||||
class V3Error;
|
||||
|
||||
class V3ErrorGuarded final {
|
||||
// Should only be used by V3ErrorGuarded::m_mutex is already locked
|
||||
// contains guarded members
|
||||
friend class V3Error;
|
||||
|
||||
public:
|
||||
using MessagesSet = std::set<std::string>;
|
||||
using ErrorExitCb = void (*)(void);
|
||||
|
|
@ -319,6 +323,16 @@ private:
|
|||
= MAX_ERRORS; // Option: --error-limit Number of errors before exit
|
||||
bool m_warnFatal VL_GUARDED_BY(m_mutex) = true; // Option: --warnFatal Warnings are fatal
|
||||
std::ostringstream m_errorStr VL_GUARDED_BY(m_mutex); // Error string being formed
|
||||
|
||||
void v3errorPrep(V3ErrorCode code) VL_REQUIRES(m_mutex) {
|
||||
m_errorStr.str("");
|
||||
m_errorCode = code;
|
||||
m_errorContexted = false;
|
||||
m_errorSuppressed = false;
|
||||
}
|
||||
std::ostringstream& v3errorStr() VL_REQUIRES(m_mutex) { return m_errorStr; }
|
||||
void v3errorEnd(std::ostringstream& sstr, const string& extra = "") VL_REQUIRES(m_mutex);
|
||||
|
||||
public:
|
||||
V3RecursiveMutex m_mutex; // Make sure only single thread is in class
|
||||
|
||||
|
|
@ -361,13 +375,6 @@ public:
|
|||
int errorLimit() VL_REQUIRES(m_mutex) { return m_errorLimit; }
|
||||
void warnFatal(bool flag) VL_REQUIRES(m_mutex) { m_warnFatal = flag; }
|
||||
bool warnFatal() VL_REQUIRES(m_mutex) { return m_warnFatal; }
|
||||
void v3errorPrep(V3ErrorCode code) VL_REQUIRES(m_mutex) {
|
||||
m_errorStr.str("");
|
||||
m_errorCode = code;
|
||||
m_errorContexted = false;
|
||||
m_errorSuppressed = false;
|
||||
}
|
||||
std::ostringstream& v3errorStr() VL_REQUIRES(m_mutex) { return m_errorStr; }
|
||||
V3ErrorCode errorCode() VL_REQUIRES(m_mutex) { return m_errorCode; }
|
||||
bool errorContexted() VL_REQUIRES(m_mutex) { return m_errorContexted; }
|
||||
int warnCount() VL_REQUIRES(m_mutex) { return m_warnCount; }
|
||||
|
|
@ -385,7 +392,6 @@ public:
|
|||
void describedWarnings(bool flag) VL_REQUIRES(m_mutex) { m_describedWarnings = flag; }
|
||||
int tellManual() VL_REQUIRES(m_mutex) { return m_tellManual; }
|
||||
void tellManual(int level) VL_REQUIRES(m_mutex) { m_tellManual = level; }
|
||||
void v3errorEnd(std::ostringstream& sstr, const string& extra = "") VL_REQUIRES(m_mutex);
|
||||
void suppressThisWarning() VL_REQUIRES(m_mutex);
|
||||
string warnContextNone() VL_REQUIRES(m_mutex) {
|
||||
errorContexted(true);
|
||||
|
|
@ -512,66 +518,32 @@ public:
|
|||
|
||||
// Internals for v3error()/v3fatal() macros only
|
||||
// Error end takes the string stream to output, be careful to seek() as needed
|
||||
static void v3errorPrep(V3ErrorCode code) VL_MT_SAFE_EXCLUDES(s().m_mutex) {
|
||||
const V3RecursiveLockGuard guard{s().m_mutex};
|
||||
s().v3errorPrep(code);
|
||||
}
|
||||
static std::ostringstream& v3errorStr() VL_MT_SAFE_EXCLUDES(s().m_mutex) {
|
||||
const V3RecursiveLockGuard guard{s().m_mutex};
|
||||
return s().v3errorStr();
|
||||
}
|
||||
static void vlAbort();
|
||||
static void v3errorAcquireLock() VL_ACQUIRE(s().m_mutex);
|
||||
static std::ostringstream& v3errorPrep(V3ErrorCode code) VL_ACQUIRE(s().m_mutex);
|
||||
static std::ostringstream& v3errorPrepFileLine(V3ErrorCode code, const char* file, int line)
|
||||
VL_ACQUIRE(s().m_mutex);
|
||||
static std::ostringstream& v3errorStr() VL_REQUIRES(s().m_mutex);
|
||||
// static, but often overridden in classes.
|
||||
static void v3errorEnd(std::ostringstream& sstr, const string& extra = "")
|
||||
VL_MT_SAFE_EXCLUDES(s().m_mutex) VL_MT_SAFE {
|
||||
const V3RecursiveLockGuard guard{s().m_mutex};
|
||||
s().v3errorEnd(sstr, extra);
|
||||
}
|
||||
// We can't call 's().v3errorEnd' directly in 'v3ErrorEnd'/'v3errorEndFatal',
|
||||
// due to bug in GCC (tested on 11.3.0 version with --enable-m32)
|
||||
// causing internal error when backtrace is printed.
|
||||
// Instead use this wrapper.
|
||||
static void v3errorEndGuardedCall(std::ostringstream& sstr, const string& extra = "")
|
||||
VL_REQUIRES(s().m_mutex) VL_MT_SAFE {
|
||||
s().v3errorEnd(sstr, extra);
|
||||
}
|
||||
VL_RELEASE(s().m_mutex);
|
||||
static void vlAbort();
|
||||
};
|
||||
|
||||
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
|
||||
inline void v3errorEnd(std::ostringstream& sstr) VL_REQUIRES(V3Error::s().m_mutex) VL_MT_SAFE {
|
||||
V3Error::v3errorEndGuardedCall(sstr);
|
||||
}
|
||||
inline void v3errorEndFatal(std::ostringstream& sstr)
|
||||
VL_REQUIRES(V3Error::s().m_mutex) VL_MT_SAFE {
|
||||
V3Error::v3errorEndGuardedCall(sstr);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
}
|
||||
|
||||
#ifndef V3ERROR_NO_GLOBAL_
|
||||
#define V3ErrorLockAndCheckStopRequested \
|
||||
V3Error::s().m_mutex.lockCheckStopRequest( \
|
||||
[]() -> void { V3ThreadPool::s().waitIfStopRequested(); })
|
||||
#else
|
||||
#define V3ErrorLockAndCheckStopRequested V3Error::s().m_mutex.lock()
|
||||
#endif
|
||||
// Global versions, so that if the class doesn't define an operator, we get the functions anyway.
|
||||
void v3errorEnd(std::ostringstream& sstr) VL_RELEASE(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(std::ostringstream& sstr) VL_RELEASE(V3Error::s().m_mutex);
|
||||
|
||||
// Theses allow errors using << operators: v3error("foo"<<"bar");
|
||||
// Careful, you can't put () around msg, as you would in most macro definitions
|
||||
// Note the commas are the comma operator, not separating arguments. These are needed to ensure
|
||||
// evaluation order as otherwise we couldn't ensure v3errorPrep is called first.
|
||||
// Note: due to limitations of clang thread-safety analysis, we can't use
|
||||
// lock guard here, instead we are locking the mutex as first operation in temporary,
|
||||
// but we are unlocking the mutex after function using comma operator.
|
||||
// This way macros should also work when they are in 'if' stmt without '{}'.
|
||||
#define v3warnCode(code, msg) \
|
||||
v3errorEnd((V3ErrorLockAndCheckStopRequested, V3Error::s().v3errorPrep(code), \
|
||||
(V3Error::s().v3errorStr() << msg), V3Error::s().v3errorStr())), \
|
||||
V3Error::s().m_mutex.unlock()
|
||||
// Careful, you can't put () around msg, as you would in most macro definitions.
|
||||
// 'V3Error::v3errorPrep(code) << msg' could be more efficient but the order of function calls in a
|
||||
// single statement can be arbitrary until C++17, thus make it possible to execute
|
||||
// V3Error::v3errorPrep that acquires the lock after functions in the msg may require it. So we use
|
||||
// the comma operator (,) to guarantee the execution order here.
|
||||
#define v3errorBuildMessage(prep, msg) \
|
||||
(prep, static_cast<std::ostringstream&>(V3Error::v3errorStr() << msg))
|
||||
#define v3warnCode(code, msg) v3errorEnd(v3errorBuildMessage(V3Error::v3errorPrep(code), msg))
|
||||
#define v3warnCodeFatal(code, msg) \
|
||||
v3errorEndFatal((V3ErrorLockAndCheckStopRequested, V3Error::s().v3errorPrep(code), \
|
||||
(V3Error::s().v3errorStr() << msg), V3Error::s().v3errorStr())), \
|
||||
V3Error::s().m_mutex.unlock()
|
||||
v3errorEndFatal(v3errorBuildMessage(V3Error::v3errorPrep(code), msg))
|
||||
#define v3warn(code, msg) v3warnCode(V3ErrorCode::code, msg)
|
||||
#define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg)
|
||||
#define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg)
|
||||
|
|
@ -580,14 +552,11 @@ inline void v3errorEndFatal(std::ostringstream& sstr)
|
|||
#define v3fatalExit(msg) v3warnCodeFatal(V3ErrorCode::EC_FATALEXIT, msg)
|
||||
// Use this instead of fatal() to mention the source code line.
|
||||
#define v3fatalSrc(msg) \
|
||||
v3warnCodeFatal(V3ErrorCode::EC_FATALSRC, \
|
||||
__FILE__ << ":" << std::dec << __LINE__ << ": " << msg)
|
||||
v3errorEndFatal(v3errorBuildMessage( \
|
||||
V3Error::v3errorPrepFileLine(V3ErrorCode::EC_FATALSRC, __FILE__, __LINE__), msg))
|
||||
// Use this when normal v3fatal is called in static method that overrides fileline.
|
||||
#define v3fatalStatic(msg) \
|
||||
(::v3errorEndFatal((V3ErrorLockAndCheckStopRequested, \
|
||||
V3Error::s().v3errorPrep(V3ErrorCode::EC_FATAL), \
|
||||
(V3Error::s().v3errorStr() << msg), V3Error::s().v3errorStr()))), \
|
||||
V3Error::s().m_mutex.unlock()
|
||||
::v3errorEndFatal(v3errorBuildMessage(V3Error::v3errorPrep(V3ErrorCode::EC_FATAL), msg))
|
||||
|
||||
#define UINFO(level, stmsg) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ bool FileLine::warnIsOff(V3ErrorCode code) const {
|
|||
|
||||
// cppverilator-suppress constParameter
|
||||
void FileLine::v3errorEnd(std::ostringstream& sstr, const string& extra)
|
||||
VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
VL_RELEASE(V3Error::s().m_mutex) {
|
||||
std::ostringstream nsstr;
|
||||
if (lastLineno()) nsstr << this;
|
||||
nsstr << sstr.str();
|
||||
|
|
@ -396,7 +396,7 @@ void FileLine::v3errorEnd(std::ostringstream& sstr, const string& extra)
|
|||
nsstr << warnContextPrimary();
|
||||
}
|
||||
if (!m_waive) V3Waiver::addEntry(V3Error::s().errorCode(), filename(), sstr.str());
|
||||
V3Error::s().v3errorEnd(nsstr, lstr.str());
|
||||
V3Error::v3errorEnd(nsstr, lstr.str());
|
||||
}
|
||||
|
||||
string FileLine::warnMore() const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
|
|
|
|||
|
|
@ -318,9 +318,9 @@ public:
|
|||
|
||||
// OPERATORS
|
||||
void v3errorEnd(std::ostringstream& str, const string& extra = "")
|
||||
VL_REQUIRES(V3Error::s().m_mutex);
|
||||
VL_RELEASE(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(std::ostringstream& str) VL_ATTR_NORETURN
|
||||
VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
VL_RELEASE(V3Error::s().m_mutex) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ V3GraphEdge* V3GraphVertex::findConnectingEdgep(GraphWay way, const V3GraphVerte
|
|||
}
|
||||
|
||||
// cppcheck-has-bug-suppress constParameter
|
||||
void V3GraphVertex::v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
void V3GraphVertex::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
|
||||
std::ostringstream nsstr;
|
||||
nsstr << str.str();
|
||||
if (debug()) {
|
||||
|
|
@ -139,11 +139,11 @@ void V3GraphVertex::v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Erro
|
|||
if (FileLine* const flp = fileline()) {
|
||||
flp->v3errorEnd(nsstr);
|
||||
} else {
|
||||
V3Error::s().v3errorEnd(nsstr);
|
||||
V3Error::v3errorEnd(nsstr);
|
||||
}
|
||||
}
|
||||
void V3GraphVertex::v3errorEndFatal(std::ostringstream& str) const
|
||||
VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
VL_RELEASE(V3Error::s().m_mutex) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
|
|
|
|||
|
|
@ -248,8 +248,8 @@ public:
|
|||
V3GraphEdge* beginp(GraphWay way) const { return way.forward() ? outBeginp() : inBeginp(); }
|
||||
// METHODS
|
||||
/// Error reporting
|
||||
void v3errorEnd(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex);
|
||||
void v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex);
|
||||
/// Edges are routed around this vertex to point from "from" directly to "to"
|
||||
void rerouteEdges(V3Graph* graphp);
|
||||
/// Find the edge connecting ap and bp, where bp is wayward from ap.
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ constexpr int MAX_SPRINTF_DOUBLE_SIZE
|
|||
//======================================================================
|
||||
// Errors
|
||||
|
||||
void V3Number::v3errorEnd(const std::ostringstream& str) const VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
void V3Number::v3errorEnd(const std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
|
||||
std::ostringstream nsstr;
|
||||
nsstr << str.str();
|
||||
if (m_nodep) {
|
||||
|
|
@ -84,12 +84,12 @@ void V3Number::v3errorEnd(const std::ostringstream& str) const VL_REQUIRES(V3Err
|
|||
} else if (m_fileline) {
|
||||
m_fileline->v3errorEnd(nsstr);
|
||||
} else {
|
||||
V3Error::s().v3errorEnd(nsstr);
|
||||
V3Error::v3errorEnd(nsstr);
|
||||
}
|
||||
}
|
||||
|
||||
void V3Number::v3errorEndFatal(const std::ostringstream& str) const
|
||||
VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
VL_RELEASE(V3Error::s().m_mutex) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE;
|
||||
|
|
|
|||
|
|
@ -566,9 +566,9 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
void v3errorEnd(const std::ostringstream& sstr) const VL_REQUIRES(V3Error::s().m_mutex);
|
||||
void v3errorEnd(const std::ostringstream& sstr) const VL_RELEASE(V3Error::s().m_mutex);
|
||||
void v3errorEndFatal(const std::ostringstream& sstr) const VL_ATTR_NORETURN
|
||||
VL_REQUIRES(V3Error::s().m_mutex);
|
||||
VL_RELEASE(V3Error::s().m_mutex);
|
||||
void width(int width, bool sized = true) {
|
||||
m_data.m_sized = sized;
|
||||
m_data.resize(width);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ public:
|
|||
// For getline()
|
||||
string m_lineChars; ///< Characters left for next line
|
||||
|
||||
void v3errorEnd(std::ostringstream& str) VL_REQUIRES(V3Error::s().m_mutex) {
|
||||
void v3errorEnd(std::ostringstream& str) VL_RELEASE(V3Error::s().m_mutex) {
|
||||
fileline()->v3errorEnd(str);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,12 +121,11 @@ std::ostream& operator<<(std::ostream& str, const Castable& rhs) {
|
|||
}
|
||||
|
||||
#define v3widthWarn(lhs, rhs, msg) \
|
||||
v3errorEnd((V3Error::s().m_mutex.lock(), \
|
||||
V3Error::s().v3errorPrep((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \
|
||||
: (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \
|
||||
: V3ErrorCode::WIDTH), \
|
||||
(V3Error::s().v3errorStr() << msg), V3Error::s().v3errorStr())), \
|
||||
V3Error::s().m_mutex.unlock()
|
||||
v3errorEnd( \
|
||||
v3errorBuildMessage(V3Error::v3errorPrep((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \
|
||||
: (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \
|
||||
: V3ErrorCode::WIDTH), \
|
||||
msg))
|
||||
|
||||
//######################################################################
|
||||
// Width state, as a visitor of each AstNode
|
||||
|
|
|
|||
Loading…
Reference in New Issue