Internals: Refactor some JSON and error code
This commit is contained in:
parent
3dfd53a549
commit
4c4fdb5dfe
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
63
src/V3File.h
63
src/V3File.h
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue