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 << "-node: ";
const_cast<AstNode*>(this)->dump(nsstr);
nsstr << endl;
nsstr << '\n';
}
m_fileline->v3errorEnd(nsstr, instanceStrExtra);
}

View File

@ -50,7 +50,7 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
}
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;
} else {
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) {
if (code.hardError()) return true;
if (supp) return false;
if (code == V3ErrorCode::USERINFO || code == V3ErrorCode::EC_INFO) return false;
if (code.severityInfo()) return false;
if (pretendError(code)) return true;
return false;
}
@ -74,9 +74,7 @@ string V3ErrorGuarded::msgPrefix() VL_REQUIRES(m_mutex) {
const bool supp = m_errorSuppressed;
if (supp) {
return "-arning-suppressed: ";
} else if (code == V3ErrorCode::USERINFO) {
return "-Info: ";
} else if (code == V3ErrorCode::EC_INFO) {
} else if (code.severityInfo()) {
return "-Info: ";
} else if (code == V3ErrorCode::EC_FATAL) {
return "%Error: ";
@ -208,8 +206,7 @@ void V3ErrorGuarded::v3errorEndGuts(std::ostringstream& sstr, const string& extr
) {
std::cerr << msg;
}
if (!m_errorSuppressed
&& !(m_errorCode == V3ErrorCode::EC_INFO || m_errorCode == V3ErrorCode::USERINFO)) {
if (!m_errorSuppressed && !m_errorCode.severityInfo()) {
const bool anError = isError(m_errorCode, m_errorSuppressed);
if (m_errorCode != V3ErrorCode::EC_FATALMANY // Not verbose on final too-many-errors error
&& !m_describedEachWarn[m_errorCode]) {
@ -217,11 +214,7 @@ void V3ErrorGuarded::v3errorEndGuts(std::ostringstream& sstr, const string& extr
if (m_errorCode >= V3ErrorCode::EC_FIRST_NAMED) {
std::cerr << warnMoreSpaces() << "... For " << (anError ? "error" : "warning")
<< " description see " << m_errorCode.url() << endl;
} else if (m_errCount >= 1
&& (m_errorCode == V3ErrorCode::EC_FATAL
|| m_errorCode == V3ErrorCode::EC_FATALMANY
|| m_errorCode == V3ErrorCode::EC_FATALSRC)
&& !m_tellInternal) {
} else if (m_errCount >= 1 && m_errorCode.severityFatal() && !m_tellInternal) {
m_tellInternal = true;
std::cerr << warnMoreSpaces()
<< "... 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 {
incWarnings();
}
if (m_errorCode == V3ErrorCode::EC_FATAL || m_errorCode == V3ErrorCode::EC_FATALMANY
|| m_errorCode == V3ErrorCode::EC_FATALSRC) {
if (m_errorCode.severityFatal()) {
static bool inFatal = false;
if (!inFatal) {
inFatal = true;

View File

@ -234,6 +234,15 @@ public:
bool hardError() const VL_MT_SAFE {
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
// Later -Werror- options may make more of these.
bool pretendError() const VL_MT_SAFE {
@ -279,6 +288,7 @@ public:
if (m_e == LITENDIAN) return V3ErrorCode{ASCRANGE};
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 isUnder(V3ErrorCode other) {
// backwards compatibility inheritance-like warnings

View File

@ -296,7 +296,10 @@ public:
: V3OutFile{filename, V3OutFormatter::LA_JSON} {
begin();
}
~V3OutJsonFile() override { end(); }
~V3OutJsonFile() override {
end();
puts("\n");
}
virtual void putsHeader() {}
void puts(const char* strg) { putsNoTracking(strg); }
void puts(const string& strg) { putsNoTracking(strg); }
@ -317,43 +320,25 @@ public:
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) {
comma();
puts(m_prefix + "\"" + name + "\": \"" + value + "\"");
m_empty = false;
return *this;
return putNamed(name, value, true);
}
V3OutJsonFile& put(const std::string& name, bool value) {
comma();
puts(m_prefix + "\"" + name + "\": " + (value ? "true" : "false"));
m_empty = false;
return *this;
return putNamed(name, value ? "true" : "false", false);
}
V3OutJsonFile& put(const std::string& name, int value) {
comma();
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;
return putNamed(name, std::to_string(value), false);
}
// 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>
V3OutJsonFile& putList(const std::string& name, const T& list) {
if (list.empty()) return *this;
@ -363,9 +348,9 @@ public:
}
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());
assert(!m_scope.empty());
UASSERT(!m_scope.empty(), "end() without begin()");
puts("\n" + m_prefix + m_scope.top());
m_scope.pop();
return *this;
@ -381,6 +366,18 @@ private:
if (!m_empty) puts(",\n");
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 {

View File

@ -524,6 +524,7 @@ string FileLine::warnContextParent() const VL_REQUIRES(V3Error::s().m_mutex) {
}
return result;
}
#ifdef VL_LEAK_CHECKS
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) {
std::ostringstream nsstr;
nsstr << str.str();
if (debug()) {
nsstr << endl;
nsstr << "-vertex: " << this << endl;
}
if (debug()) nsstr << "\n-vertex: " << this << '\n';
if (FileLine* const flp = fileline()) {
flp->v3errorEnd(nsstr);
} else {

View File

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