Internals: Refactor some JSON and error code

This commit is contained in:
Wilson Snyder 2025-05-13 22:26:15 -04:00
parent 3dfd53a549
commit 4c4fdb5dfe
7 changed files with 53 additions and 57 deletions

View File

@ -1461,7 +1461,7 @@ void AstNode::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().
nsstr << '\n'; nsstr << '\n';
nsstr << "-node: "; nsstr << "-node: ";
const_cast<AstNode*>(this)->dump(nsstr); const_cast<AstNode*>(this)->dump(nsstr);
nsstr << endl; nsstr << '\n';
} }
m_fileline->v3errorEnd(nsstr, instanceStrExtra); m_fileline->v3errorEnd(nsstr, instanceStrExtra);
} }

View File

@ -50,7 +50,7 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
} }
string V3ErrorCode::url() const { string V3ErrorCode::url() const {
if (m_e < V3ErrorCode::EC_FIRST_NAMED) { if (!isNamed()) {
return "https://verilator.org/verilator_doc.html"s + "?v=" + PACKAGE_VERSION_NUMBER_STRING; return "https://verilator.org/verilator_doc.html"s + "?v=" + PACKAGE_VERSION_NUMBER_STRING;
} else { } else {
return "https://verilator.org/warn/"s + ascii() + "?v=" + PACKAGE_VERSION_NUMBER_STRING; return "https://verilator.org/warn/"s + ascii() + "?v=" + PACKAGE_VERSION_NUMBER_STRING;
@ -64,7 +64,7 @@ string V3ErrorCode::url() const {
bool V3ErrorGuarded::isError(V3ErrorCode code, bool supp) VL_REQUIRES(m_mutex) { bool V3ErrorGuarded::isError(V3ErrorCode code, bool supp) VL_REQUIRES(m_mutex) {
if (code.hardError()) return true; if (code.hardError()) return true;
if (supp) return false; if (supp) return false;
if (code == V3ErrorCode::USERINFO || code == V3ErrorCode::EC_INFO) return false; if (code.severityInfo()) return false;
if (pretendError(code)) return true; if (pretendError(code)) return true;
return false; return false;
} }
@ -74,9 +74,7 @@ string V3ErrorGuarded::msgPrefix() VL_REQUIRES(m_mutex) {
const bool supp = m_errorSuppressed; const bool supp = m_errorSuppressed;
if (supp) { if (supp) {
return "-arning-suppressed: "; return "-arning-suppressed: ";
} else if (code == V3ErrorCode::USERINFO) { } else if (code.severityInfo()) {
return "-Info: ";
} else if (code == V3ErrorCode::EC_INFO) {
return "-Info: "; return "-Info: ";
} else if (code == V3ErrorCode::EC_FATAL) { } else if (code == V3ErrorCode::EC_FATAL) {
return "%Error: "; return "%Error: ";
@ -208,8 +206,7 @@ void V3ErrorGuarded::v3errorEndGuts(std::ostringstream& sstr, const string& extr
) { ) {
std::cerr << msg; std::cerr << msg;
} }
if (!m_errorSuppressed if (!m_errorSuppressed && !m_errorCode.severityInfo()) {
&& !(m_errorCode == V3ErrorCode::EC_INFO || m_errorCode == V3ErrorCode::USERINFO)) {
const bool anError = isError(m_errorCode, m_errorSuppressed); const bool anError = isError(m_errorCode, m_errorSuppressed);
if (m_errorCode != V3ErrorCode::EC_FATALMANY // Not verbose on final too-many-errors error if (m_errorCode != V3ErrorCode::EC_FATALMANY // Not verbose on final too-many-errors error
&& !m_describedEachWarn[m_errorCode]) { && !m_describedEachWarn[m_errorCode]) {
@ -217,11 +214,7 @@ void V3ErrorGuarded::v3errorEndGuts(std::ostringstream& sstr, const string& extr
if (m_errorCode >= V3ErrorCode::EC_FIRST_NAMED) { if (m_errorCode >= V3ErrorCode::EC_FIRST_NAMED) {
std::cerr << warnMoreSpaces() << "... For " << (anError ? "error" : "warning") std::cerr << warnMoreSpaces() << "... For " << (anError ? "error" : "warning")
<< " description see " << m_errorCode.url() << endl; << " description see " << m_errorCode.url() << endl;
} else if (m_errCount >= 1 } else if (m_errCount >= 1 && m_errorCode.severityFatal() && !m_tellInternal) {
&& (m_errorCode == V3ErrorCode::EC_FATAL
|| m_errorCode == V3ErrorCode::EC_FATALMANY
|| m_errorCode == V3ErrorCode::EC_FATALSRC)
&& !m_tellInternal) {
m_tellInternal = true; m_tellInternal = true;
std::cerr << warnMoreSpaces() std::cerr << warnMoreSpaces()
<< "... This fatal error may be caused by the earlier error(s);" << "... This fatal error may be caused by the earlier error(s);"
@ -250,8 +243,7 @@ void V3ErrorGuarded::v3errorEndGuts(std::ostringstream& sstr, const string& extr
} else { } else {
incWarnings(); incWarnings();
} }
if (m_errorCode == V3ErrorCode::EC_FATAL || m_errorCode == V3ErrorCode::EC_FATALMANY if (m_errorCode.severityFatal()) {
|| m_errorCode == V3ErrorCode::EC_FATALSRC) {
static bool inFatal = false; static bool inFatal = false;
if (!inFatal) { if (!inFatal) {
inFatal = true; inFatal = true;

View File

@ -234,6 +234,15 @@ public:
bool hardError() const VL_MT_SAFE { bool hardError() const VL_MT_SAFE {
return (m_e != EC_INFO && m_e < V3ErrorCode::EC_FIRST_WARN); return (m_e != EC_INFO && m_e < V3ErrorCode::EC_FIRST_WARN);
} }
// Warning is fatal error, don't continue
bool severityFatal() const VL_MT_SAFE {
return m_e == V3ErrorCode::EC_FATAL || m_e == V3ErrorCode::EC_FATALMANY
|| m_e == V3ErrorCode::EC_FATALSRC;
}
// Warning is -Info informational
bool severityInfo() const VL_MT_SAFE {
return m_e == V3ErrorCode::USERINFO || m_e == V3ErrorCode::EC_INFO;
}
// Warnings we'll present to the user as errors // Warnings we'll present to the user as errors
// Later -Werror- options may make more of these. // Later -Werror- options may make more of these.
bool pretendError() const VL_MT_SAFE { bool pretendError() const VL_MT_SAFE {
@ -279,6 +288,7 @@ public:
if (m_e == LITENDIAN) return V3ErrorCode{ASCRANGE}; if (m_e == LITENDIAN) return V3ErrorCode{ASCRANGE};
return V3ErrorCode{EC_MIN}; // Not renamed; see isRenamed() return V3ErrorCode{EC_MIN}; // Not renamed; see isRenamed()
} }
bool isNamed() const { return m_e >= EC_FIRST_NAMED; }
bool isRenamed() const { return renamedTo() != V3ErrorCode{EC_MIN}; } bool isRenamed() const { return renamedTo() != V3ErrorCode{EC_MIN}; }
bool isUnder(V3ErrorCode other) { bool isUnder(V3ErrorCode other) {
// backwards compatibility inheritance-like warnings // backwards compatibility inheritance-like warnings

View File

@ -296,7 +296,10 @@ public:
: V3OutFile{filename, V3OutFormatter::LA_JSON} { : V3OutFile{filename, V3OutFormatter::LA_JSON} {
begin(); begin();
} }
~V3OutJsonFile() override { end(); } ~V3OutJsonFile() override {
end();
puts("\n");
}
virtual void putsHeader() {} virtual void putsHeader() {}
void puts(const char* strg) { putsNoTracking(strg); } void puts(const char* strg) { putsNoTracking(strg); }
void puts(const string& strg) { putsNoTracking(strg); } void puts(const string& strg) { putsNoTracking(strg); }
@ -317,43 +320,25 @@ public:
return *this; return *this;
} }
// Put a named value
V3OutJsonFile& put(const std::string& name, const char* valuep) {
return putNamed(name, std::string{valuep}, true);
}
V3OutJsonFile& put(const std::string& name, const std::string& value) { V3OutJsonFile& put(const std::string& name, const std::string& value) {
comma(); return putNamed(name, value, true);
puts(m_prefix + "\"" + name + "\": \"" + value + "\"");
m_empty = false;
return *this;
} }
V3OutJsonFile& put(const std::string& name, bool value) { V3OutJsonFile& put(const std::string& name, bool value) {
comma(); return putNamed(name, value ? "true" : "false", false);
puts(m_prefix + "\"" + name + "\": " + (value ? "true" : "false"));
m_empty = false;
return *this;
} }
V3OutJsonFile& put(const std::string& name, int value) { V3OutJsonFile& put(const std::string& name, int value) {
comma(); return putNamed(name, std::to_string(value), false);
puts(m_prefix + "\"" + name + "\": " + std::to_string(value));
m_empty = false;
return *this;
}
V3OutJsonFile& put(const std::string& value) {
comma();
puts(m_prefix + "\"" + value + "\"");
m_empty = false;
return *this;
}
V3OutJsonFile& put(bool value) {
comma();
puts(m_prefix + (value ? "true" : "false"));
m_empty = false;
return *this;
}
V3OutJsonFile& put(int value) {
comma();
puts(m_prefix + std::to_string(value));
m_empty = false;
return *this;
} }
// Put unnamed value
V3OutJsonFile& put(const std::string& value) { return putNamed("", value, true); }
V3OutJsonFile& put(bool value) { return putNamed("", value ? "true" : "false", false); }
V3OutJsonFile& put(int value) { return putNamed("", std::to_string(value), false); }
template <typename T> template <typename T>
V3OutJsonFile& putList(const std::string& name, const T& list) { V3OutJsonFile& putList(const std::string& name, const T& list) {
if (list.empty()) return *this; if (list.empty()) return *this;
@ -363,9 +348,9 @@ public:
} }
V3OutJsonFile& end() { V3OutJsonFile& end() {
assert(m_prefix.length() >= strlen(INDENT)); UASSERT(m_prefix.length() >= strlen(INDENT), "prefix underflow");
m_prefix.erase(m_prefix.end() - strlen(INDENT), m_prefix.end()); m_prefix.erase(m_prefix.end() - strlen(INDENT), m_prefix.end());
assert(!m_scope.empty()); UASSERT(!m_scope.empty(), "end() without begin()");
puts("\n" + m_prefix + m_scope.top()); puts("\n" + m_prefix + m_scope.top());
m_scope.pop(); m_scope.pop();
return *this; return *this;
@ -381,6 +366,18 @@ private:
if (!m_empty) puts(",\n"); if (!m_empty) puts(",\n");
m_empty = true; m_empty = true;
} }
V3OutJsonFile& putNamed(const std::string& name, const std::string& value, bool quoted) {
comma();
const string valueQ
= quoted ? "\""s + V3OutFormatter::quoteNameControls(value) + "\"" : value;
if (name.empty()) {
puts(m_prefix + valueQ);
} else {
puts(m_prefix + "\"" + name + "\": " + valueQ);
}
m_empty = false;
return *this;
}
}; };
class V3OutMkFile final : public V3OutFile { class V3OutMkFile final : public V3OutFile {

View File

@ -524,6 +524,7 @@ string FileLine::warnContextParent() const VL_REQUIRES(V3Error::s().m_mutex) {
} }
return result; return result;
} }
#ifdef VL_LEAK_CHECKS #ifdef VL_LEAK_CHECKS
std::unordered_set<FileLine*> fileLineLeakChecks; std::unordered_set<FileLine*> fileLineLeakChecks;

View File

@ -108,10 +108,7 @@ template V3GraphEdge* V3GraphVertex::findConnectingEdgep<GraphWay::REVERSE>(V3Gr
void V3GraphVertex::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) { void V3GraphVertex::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) {
std::ostringstream nsstr; std::ostringstream nsstr;
nsstr << str.str(); nsstr << str.str();
if (debug()) { if (debug()) nsstr << "\n-vertex: " << this << '\n';
nsstr << endl;
nsstr << "-vertex: " << this << endl;
}
if (FileLine* const flp = fileline()) { if (FileLine* const flp = fileline()) {
flp->v3errorEnd(nsstr); flp->v3errorEnd(nsstr);
} else { } else {

View File

@ -108,11 +108,10 @@ std::ostream& operator<<(std::ostream& str, const Determ& rhs) {
} }
#define v3widthWarn(lhs, rhs, msg) \ #define v3widthWarn(lhs, rhs, msg) \
v3errorEnd( \ v3warnCode(((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \
v3errorBuildMessage(V3Error::v3errorPrep((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \ : (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \
: (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \ : V3ErrorCode::WIDTH), \
: V3ErrorCode::WIDTH), \ msg)
msg))
//###################################################################### //######################################################################
// Width state, as a visitor of each AstNode // Width state, as a visitor of each AstNode