logger: add LogSourceLocation

This commit is contained in:
Miodrag Milanovic
2026-09-15 14:29:36 +02:00
parent d85872386a
commit 18239a6fbb
15 changed files with 124 additions and 128 deletions
+2 -2
View File
@@ -1460,7 +1460,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump
if (design->has(child->str)) {
RTLIL::Module *existing_mod = design->module(child->str);
if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str);
log_file_error(child->location.to_src(), "Re-definition of module `%s'!\n", child->str);
} else if (nooverwrite) {
log("Ignoring re-definition of module `%s' at %s.\n",
child->str.c_str(), child->loc_string().c_str());
@@ -1938,7 +1938,7 @@ void AstModule::loadconfig() const
void AstNode::formatted_input_error(std::string_view format, std::string str) const
{
logger().formatted_file_error(*location.begin.filename, location.begin.line, format, std::move(str));
logger().formatted_error(location.to_src(), "ERROR:", format, std::move(str));
}
YOSYS_NAMESPACE_END
+15 -16
View File
@@ -840,8 +840,7 @@ struct AST_INTERNAL::ProcessGenerator
node->detectSignWidth(width, is_signed, nullptr);
VerilogFmtArg arg = {};
arg.filename = *node->location.begin.filename;
arg.first_line = node->location.begin.line;
arg.src = node->location.to_src();
if (node->type == AST_CONSTANT && node->is_string) {
arg.type = VerilogFmtArg::STRING;
arg.str = node->bitsAsConst().decode_string();
@@ -867,7 +866,7 @@ struct AST_INTERNAL::ProcessGenerator
fmt.append_literal("\n");
fmt.emit_rtlil(cell);
} else if (!ast->str.empty()) {
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str);
log_file_error(ast->location.to_src(), "Found unsupported invocation of system task `%s'!\n", ast->str);
}
break;
@@ -919,7 +918,7 @@ struct AST_INTERNAL::ProcessGenerator
cell->set_bool_attribute(ID(keep));
for (auto &attr : ast->attributes) {
if (attr.second->type != AST_CONSTANT)
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first);
log_file_error(ast->location.to_src(), "Attribute `%s' with non-constant value!\n", attr.first);
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->setParam(ID::FLAVOR, flavor);
@@ -1529,7 +1528,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
RTLIL::SigSpec sig = realAsConst(width_hint);
log_file_warning(*location.begin.filename, location.begin.line, "converting real value %e to binary %s.\n", realvalue, log_signal(sig));
log_file_warning(location.to_src(), "converting real value %e to binary %s.\n", realvalue, log_signal(sig));
return sig;
}
@@ -1554,7 +1553,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->name = str;
if (flag_autowire)
log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str);
log_file_warning(location.to_src(), "Identifier `%s' is implicitly declared.\n", str);
else
input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str);
}
@@ -1659,10 +1658,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk.offset = source_width - (chunk.offset + chunk.width);
if (chunk.offset > chunk_left || chunk.offset + chunk.width < chunk_right) {
if (chunk.width == 1)
log_file_warning(*location.begin.filename, location.begin.line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
log_file_warning(location.to_src(), "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
str.c_str());
else
log_file_warning(*location.begin.filename, location.begin.line, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n",
log_file_warning(location.to_src(), "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width);
chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
} else {
@@ -1676,10 +1675,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk.offset += add_undef_bits_lsb;
}
if (add_undef_bits_lsb)
log_file_warning(*location.begin.filename, location.begin.line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
log_file_warning(location.to_src(), "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb);
if (add_undef_bits_msb)
log_file_warning(*location.begin.filename, location.begin.line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
log_file_warning(location.to_src(), "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb);
}
}
@@ -2082,7 +2081,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
new_left.append(left[i]);
new_right.append(right[i]);
}
log_file_warning(*location.begin.filename, location.begin.line, "Ignoring assignment to constant bits:\n"
log_file_warning(location.to_src(), "Ignoring assignment to constant bits:\n"
" old assignment: %s = %s\n new assignment: %s = %s.\n",
log_signal(left), log_signal(right),
log_signal(new_left), log_signal(new_right));
@@ -2115,7 +2114,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
const auto* value = child->children[0].get();
if (value->type == AST_REALVALUE)
log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n",
log_file_warning(location.to_src(), "Replacing floating point parameter %s.%s = %f with string.\n",
cell, paraname.unescape(), value->realvalue);
else if (value->type != AST_CONSTANT)
input_error("Parameter %s.%s with non-constant value!\n",
@@ -2216,14 +2215,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int sz = children.size();
if (str == "$info") {
if (sz > 0)
log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str);
log_file_info(location.to_src(), "%s.\n", children[0]->str);
else
log_file_info(*location.begin.filename, location.begin.line, "\n");
log_file_info(location.to_src(), "\n");
} else if (str == "$warning") {
if (sz > 0)
log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str);
log_file_warning(location.to_src(), "%s.\n", children[0]->str);
else
log_file_warning(*location.begin.filename, location.begin.line, "\n");
log_file_warning(location.to_src(), "\n");
} else if (str == "$error") {
if (sz > 0)
input_error("%s.\n", children[0]->str);
+6 -7
View File
@@ -149,8 +149,7 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_
while (node_arg->simplify(true, stage, -1, false)) { }
VerilogFmtArg arg = {};
arg.filename = *location.begin.filename;
arg.first_line = location.begin.line;
arg.src = location.to_src();
if (node_arg->type == AST_CONSTANT && node_arg->is_string) {
arg.type = VerilogFmtArg::STRING;
arg.str = node_arg->bitsAsConst().decode_string();
@@ -167,10 +166,10 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_
arg.sig = node_arg->bitsAsConst();
arg.signed_ = node_arg->is_signed;
} else if (may_fail) {
log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
log_file_info(arg.src, "Skipping system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
return Fmt();
} else {
log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
log_file_error(arg.src, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
}
args.push_back(arg);
}
@@ -1178,7 +1177,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
// note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||
str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) {
log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str);
log_file_warning(location.to_src(), "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str);
delete_children();
str = std::string();
}
@@ -1188,7 +1187,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo"))
{
if (!current_always) {
log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str);
log_file_warning(location.to_src(), "System task `%s' outside initial or always block is unsupported.\n", str);
delete_children();
str = std::string();
} else {
@@ -2362,7 +2361,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
if (children[0]->type == AST_REALVALUE) {
RTLIL::Const constvalue = children[0]->realAsConst(width);
log_file_warning(*location.begin.filename, location.begin.line, "converting real value %e to binary %s.\n",
log_file_warning(location.to_src(), "converting real value %e to binary %s.\n",
children[0]->realvalue, log_signal(constvalue));
children[0] = mkconst_bits(location, constvalue.to_bits(), sign_hint);
fixup_hierarchy_flags();
+4 -4
View File
@@ -47,9 +47,9 @@ using namespace VERILOG_FRONTEND;
void ConstParser::log_maybe_loc_error(std::string msg) {
if (loc.begin.filename)
log_file_error(*loc.begin.filename, loc.begin.line, "%s", msg);
log_file_error(loc.to_src(), "%s", msg);
else if (!Frontend::current_script_filename.empty())
log_file_error(Frontend::current_script_filename, Frontend::current_script_lineno,
log_file_error(LogSourceLocation(Frontend::current_script_filename, Frontend::current_script_lineno),
"Failed to parse constant `%s': %s", code_str, msg);
else
log_error("Failed to parse constant `%s': %s", code_str, msg);
@@ -57,9 +57,9 @@ void ConstParser::log_maybe_loc_error(std::string msg) {
void ConstParser::log_maybe_loc_warn(std::string msg) {
if (loc.begin.filename)
log_file_warning(*loc.begin.filename, loc.begin.line, "%s", msg);
log_file_warning(loc.to_src(), "%s", msg);
else if (!Frontend::current_script_filename.empty())
log_file_warning(Frontend::current_script_filename, Frontend::current_script_lineno,
log_file_warning(LogSourceLocation(Frontend::current_script_filename, Frontend::current_script_lineno),
"While parsing constant `%s': %s", code_str, msg);
else
log_warning("While parsing constant `%s': %s", code_str, msg);
+1 -1
View File
@@ -741,7 +741,7 @@ read_define(const std::string &filename,
defines_map.add(name, value, (state == 2) ? &args : nullptr);
global_defines_cache.add(name, value, (state == 2) ? &args : nullptr);
} else {
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name);
log_file_error(LogSourceLocation(filename), "Invalid name for macro definition: >>%s<<.\n", name);
}
}
+2 -4
View File
@@ -34,12 +34,10 @@ USING_YOSYS_NAMESPACE
[[noreturn]]
void VERILOG_FRONTEND::formatted_err_at_loc(Location loc, std::string str)
{
YOSYS_NAMESPACE_PREFIX log_file_error(loc.begin.filename ? *(loc.begin.filename) : "UNKNOWN", loc.begin.line,
"%s\n", std::move(str));
YOSYS_NAMESPACE_PREFIX log_file_error(loc.to_src(), "%s\n", std::move(str));
}
void VERILOG_FRONTEND::formatted_warn_at_loc(Location loc, std::string str)
{
YOSYS_NAMESPACE_PREFIX log_file_warning(loc.begin.filename ? *(loc.begin.filename) : "UNKNOWN", loc.begin.line,
"%s\n", std::move(str));
YOSYS_NAMESPACE_PREFIX log_file_warning(loc.to_src(), "%s\n", std::move(str));
}
+5 -5
View File
@@ -162,7 +162,7 @@ static bool is_hex_dig(char c, int *val, parser::location_type loc)
*val = c - 'A' + 0xA;
return true;
} else if (c == 'x' || c == 'X' || c == 'z' || c == 'Z' || c == '?') {
log_file_warning(*loc.begin.filename, loc.begin.line, "'%c' not a valid digit in hex escape sequence.\n", c);
log_file_warning(loc.to_src(), "'%c' not a valid digit in hex escape sequence.\n", c);
*val = 0; // not semantically valid in hex escape...
return true; // ...but still processed as part of hex token
}
@@ -176,7 +176,7 @@ static bool is_oct_dig(char c, int *val, parser::location_type loc)
*val = c - '0';
return true;
} else if (c == 'x' || c == 'X' || c == 'z' || c == 'Z' || c == '?') {
log_file_warning(*loc.begin.filename, loc.begin.line, "'%c' not a valid digit in octal escape sequence.\n", c);
log_file_warning(loc.to_src(), "'%c' not a valid digit in octal escape sequence.\n", c);
*val = 0; // not semantically valid in octal escape...
return true; // ...but still processed as part of octal token
}
@@ -196,7 +196,7 @@ static parser::symbol_type process_str(char *str, int len, bool triple, parser::
if (in + 1 < str + len && (in[1] ^ *in) == ('\n' ^ '\r'))
in++;
if (!triple)
log_file_warning(*loc.begin.filename, loc.begin.line, "Multi-line string literals should be triple-quoted or escaped.\n");
log_file_warning(loc.to_src(), "Multi-line string literals should be triple-quoted or escaped.\n");
*out++ = '\n';
break;
case '\\':
@@ -233,7 +233,7 @@ static parser::symbol_type process_str(char *str, int len, bool triple, parser::
}
out++;
} else
log_file_warning(*loc.begin.filename, loc.begin.line, "ignoring invalid hex escape.\n");
log_file_warning(loc.to_src(), "ignoring invalid hex escape.\n");
break;
case '\\':
*out++ = '\\';
@@ -256,7 +256,7 @@ static parser::symbol_type process_str(char *str, int len, bool triple, parser::
in++;
if (in + 1 < str + len && is_oct_dig(in[1], &val, loc)) {
if (*out >= 040)
log_file_warning(*loc.begin.filename, loc.begin.line, "octal escape exceeds \\377\n");
log_file_warning(loc.to_src(), "octal escape exceeds \\377\n");
*out = *out * 010 + val;
in++;
}
+4
View File
@@ -88,6 +88,10 @@ struct Location {
return oss.str();
}
YOSYS_NAMESPACE_PREFIX LogSourceLocation to_src() const {
return YOSYS_NAMESPACE_PREFIX LogSourceLocation(begin.filename ? *(begin.filename) : "UNKNOWN", begin.line, begin.column, end.line, end.column);
}
};
static inline std::ostream& operator<<(std::ostream& os, const Location& loc) {
+3
View File
@@ -166,6 +166,9 @@ void ColorConsoleLogSink::log(const LogMessage &msg)
fmt::print(f, fg(fmt::terminal_color::blue), "{}", time_str);
}
if (!msg.src.filename.empty())
fmt::print(f, fg(fmt::terminal_color::bright_cyan), "{}:{}: ", msg.src.filename, msg.src.start_line);
switch (msg.severity) {
case LogSeverity::Warning:
fmt::print(f, fg(fmt::terminal_color::bright_yellow), "{}", msg.prefix);
+7 -7
View File
@@ -401,11 +401,11 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
part = {};
}
if (++i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
if (++arg == args.end()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name, fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name, fmtarg - args.begin() + 1);
}
part.sig = arg->sig;
part.signed_ = arg->signed_;
@@ -420,7 +420,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
} else break;
}
if (i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
bool has_leading_zero = false, has_width = false;
@@ -465,15 +465,15 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
if (!has_width && !has_leading_zero)
part.width = 20;
} else {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
}
} else {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
}
break;
}
if (i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
if (part.padding == '\0') {
@@ -486,7 +486,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
}
if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
log_file_error(fmtarg->src, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
if (part.base != 10)
part.signed_ = false;
+1 -2
View File
@@ -34,8 +34,7 @@ struct VerilogFmtArg {
} type;
// All types
std::string filename;
unsigned first_line;
LogSourceLocation src;
// STRING type
std::string str;
+29 -45
View File
@@ -130,12 +130,13 @@ void ScratchPadLogSink::log(const LogMessage &msg)
design->scratchpad[scratchpad].append(msg.cached_msg);
}
LogMessage::LogMessage(LogSeverity severity, std::string_view prefix, std::string_view format, std::string_view message) :
LogMessage::LogMessage(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string_view message) :
severity(severity),
prefix(prefix),
format(format),
message(message),
timestamp(std::chrono::steady_clock::now())
timestamp(std::chrono::steady_clock::now()),
src(src)
{
std::string time_str;
if (logger().get_log_time())
@@ -156,7 +157,8 @@ LogMessage::LogMessage(LogSeverity severity, std::string_view prefix, std::strin
if (format == "%s" && !message.empty() && message.back() == '\n')
next_print_log = true;
}
cached_msg = stringf("%s%s%s", time_str, prefix, message);
std::string loc = !src.filename.empty() ? stringf("%s:%d: ", src.filename, src.start_line) : "";
cached_msg = stringf("%s%s%s%s", loc, time_str, prefix, message);
}
static void log_id_cache_clear()
@@ -166,10 +168,10 @@ static void log_id_cache_clear()
log_id_cache.clear();
}
void LogManager::logv_string(LogSeverity severity, std::string_view prefix, std::string_view format, std::string str_in) {
void LogManager::logv_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string str_in) {
size_t remove_leading = 0;
while (format.size() > 1 && format[0] == '\n') {
logv_string(severity, prefix, "\n", "\n");
logv_string(severity, src, prefix, "\n", "\n");
format = format.substr(1);
++remove_leading;
}
@@ -177,7 +179,8 @@ void LogManager::logv_string(LogSeverity severity, std::string_view prefix, std:
str_in = str_in.substr(remove_leading);
}
std::string str = stringf("%s%s",prefix,str_in);
std::string loc = !src.filename.empty() ? stringf("%s:%d: ", src.filename, src.start_line) : "";
std::string str = stringf("%s%s%s",loc,prefix,str_in);
if (str.empty())
return;
@@ -191,7 +194,7 @@ void LogManager::logv_string(LogSeverity severity, std::string_view prefix, std:
if (hasher)
hasher->update(str);
auto msg = LogMessage(severity, prefix, format, str_in);
auto msg = LogMessage(severity, src, prefix, format, str_in);
for (auto &sink : sinks) {
if (sink->should_log(msg))
sink->log(msg);
@@ -232,13 +235,13 @@ void LogManager::logv_string(LogSeverity severity, std::string_view prefix, std:
}
}
void LogManager::formatted_string(LogSeverity severity, std::string_view prefix, std::string_view format, std::string str)
void LogManager::formatted_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string str)
{
log_assert(!Multithreading::active());
if (make_debug && !is_debug(1))
return;
logv_string(severity, prefix, format, std::move(str));
logv_string(severity, src, prefix, format, std::move(str));
}
void LogManager::formatted_header(RTLIL::Design *design, std::string_view format, std::string str)
@@ -258,7 +261,7 @@ void LogManager::formatted_header(RTLIL::Design *design, std::string_view format
for (int c : header_count)
header_id += stringf("%s%d", header_id.empty() ? "" : ".", c);
formatted_string(LogSeverity::Header, stringf("%s. ", header_id), format, std::move(str));
formatted_string(LogSeverity::Header, LogSourceLocation{}, stringf("%s. ", header_id), format, std::move(str));
flush();
if (hdump_all)
@@ -276,7 +279,7 @@ void LogManager::formatted_header(RTLIL::Design *design, std::string_view format
log_stderr_sink_forced = false;
}
void LogManager::formatted_warning(std::string_view prefix, std::string_view format, std::string message)
void LogManager::formatted_warning(LogSourceLocation src, std::string_view prefix, std::string_view format, std::string message)
{
log_assert(!Multithreading::active());
@@ -286,9 +289,10 @@ void LogManager::formatted_warning(std::string_view prefix, std::string_view for
if (std::regex_search(message, re))
suppressed = true;
std::string loc = !src.filename.empty() ? stringf("%s:%d: ", src.filename, src.start_line) : "";
if (suppressed)
{
log("Suppressed %s%s", prefix, message);
log("Suppressed %s%s%s", loc, prefix, message);
}
else
{
@@ -297,7 +301,7 @@ void LogManager::formatted_warning(std::string_view prefix, std::string_view for
for (auto &re : werror_regexes)
if (std::regex_search(message, re))
formatted_error(format, message);
formatted_error(src, "ERROR: ", format, message);
bool warning_match = false;
for (auto &[_, item] : expect_warning)
@@ -306,20 +310,21 @@ void LogManager::formatted_warning(std::string_view prefix, std::string_view for
warning_match = true;
}
std::string pattern = loc + string(prefix) + message;
for (auto &[_, item] : expect_prefix_warning)
if (std::regex_search(string(prefix) + message, item.pattern)) {
if (std::regex_search(pattern, item.pattern)) {
item.current_count++;
warning_match = true;
}
if (warnings.count(message))
{
formatted_string(LogSeverity::Info, prefix, format, message);
formatted_string(LogSeverity::Info, src, prefix, format, message);
flush();
}
else
{
formatted_string(LogSeverity::Warning, prefix, format, message);
formatted_string(LogSeverity::Warning, src, prefix, format, message);
flush();
warnings.insert(message);
}
@@ -331,34 +336,22 @@ void LogManager::formatted_warning(std::string_view prefix, std::string_view for
}
}
void LogManager::formatted_file_warning(std::string_view filename, int lineno, std::string_view format, std::string str)
{
std::string prefix = stringf("%s:%d: Warning: ", filename, lineno);
formatted_warning(prefix, format, std::move(str));
}
void LogManager::formatted_file_info(std::string_view filename, int lineno, std::string_view format, std::string str)
{
std::string prefix = stringf("%s:%d: Info: ", filename, lineno);
formatted_string(LogSeverity::Info, prefix, format, std::move(str));
}
void LogManager::suppressed() {
if (debug_suppressed && !make_debug) {
constexpr const char* format = "<suppressed ~%d debug messages>\n";
logv_string(LogSeverity::Info, {}, format, stringf(format, debug_suppressed));
logv_string(LogSeverity::Info, LogSourceLocation{}, {}, format, stringf(format, debug_suppressed));
debug_suppressed = 0;
}
}
[[noreturn]]
void LogManager::error_with_prefix(std::string_view prefix, std::string_view format, std::string message)
void LogManager::formatted_error(LogSourceLocation src, std::string_view prefix, std::string_view format, std::string message)
{
int bak_make_debug = make_debug;
make_debug = 0;
suppressed();
formatted_string(LogSeverity::Error, prefix, format, message);
formatted_string(LogSeverity::Error, src, prefix, format, message);
flush();
make_debug = bak_make_debug;
@@ -367,8 +360,10 @@ void LogManager::error_with_prefix(std::string_view prefix, std::string_view for
if (std::regex_search(message, item.pattern))
item.current_count++;
std::string loc = !src.filename.empty() ? stringf("%s:%d: ", src.filename, src.start_line) : "";
std::string pattern = loc + string(prefix) + message;
for (auto &[_, item] : expect_prefix_error)
if (std::regex_search(string(prefix) + message, item.pattern))
if (std::regex_search(pattern, item.pattern))
item.current_count++;
errors_count++;
@@ -390,12 +385,6 @@ void LogManager::error_with_prefix(std::string_view prefix, std::string_view for
#endif
}
void LogManager::formatted_file_error(std::string_view filename, int lineno, std::string_view format, std::string str)
{
std::string prefix = stringf("%s:%d: ERROR: ", filename, lineno);
error_with_prefix(prefix, format, str);
}
void LogManager::add_experimental(const std::string &str)
{
if (experimental_ignored.count(str) == 0 && experimental.count(str) == 0) {
@@ -412,11 +401,6 @@ void LogManager::add_deprecated(const std::string &str)
}
}
void LogManager::formatted_error(std::string_view format, std::string str)
{
error_with_prefix("ERROR: ", format, std::move(str));
}
void log_assert_failure(const char *expr, const char *file, int line)
{
log_error("Assert `%s' failed in %s:%d.\n", expr, file, line);
@@ -435,13 +419,13 @@ void log_yosys_abort_message(std::string_view file, int line, std::string_view f
void LogManager::formatted_cmd_error(std::string_view format, std::string message)
{
if (cmd_error_throw) {
formatted_string(LogSeverity::Error, "ERROR: ", format, message);
formatted_string(LogSeverity::Error, LogSourceLocation{}, "ERROR: ", format, message);
flush();
throw log_cmd_error_exception();
}
formatted_error(format, message);
formatted_error(LogSourceLocation{}, "ERROR: ", format, message);
}
void LogManager::spacer()
+33 -23
View File
@@ -95,13 +95,27 @@ enum class LogSeverity {
Error
};
struct LogSourceLocation {
LogSourceLocation() : filename({}),start_line(-1),start_col(-1),end_line(-1),end_col(-1) { }
LogSourceLocation(std::string filename) : filename(filename),start_line(-1),start_col(-1),end_line(-1),end_col(-1) { }
LogSourceLocation(std::string filename,int start_line) : filename(filename),start_line(start_line),start_col(-1),end_line(-1),end_col(-1) { }
LogSourceLocation(std::string filename,int start_line,int start_col,int end_line,int end_col) :
filename(filename),start_line(start_line),start_col(start_col),end_line(end_line),end_col(end_col) { }
std::string filename;
int start_line;
int start_col;
int end_line;
int end_col;
};
struct LogMessage {
LogMessage(LogSeverity severity, std::string_view prefix, std::string_view format, std::string_view message);
LogMessage(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string_view message);
LogSeverity severity;
std::string prefix;
std::string format;
std::string message;
std::chrono::steady_clock::time_point timestamp;
LogSourceLocation src;
std::string cached_msg;
};
@@ -399,13 +413,10 @@ public:
void add_hdump(std::string name, std::string value) { hdump[name].insert(value); }
void formatted_string(LogSeverity severity, std::string_view prefix, std::string_view format, std::string str);
void formatted_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string str);
void formatted_header(RTLIL::Design *design, std::string_view format, std::string str);
void formatted_warning(std::string_view prefix, std::string_view format, std::string message);
void formatted_file_warning(std::string_view filename, int lineno, std::string_view format, std::string str);
void formatted_file_info(std::string_view filename, int lineno, std::string_view format, std::string str);
[[noreturn]] void formatted_file_error(std::string_view filename, int lineno, std::string_view format, std::string str);
[[noreturn]] void formatted_error(std::string_view format, std::string str);
void formatted_warning(LogSourceLocation src, std::string_view prefix, std::string_view format, std::string message);
[[noreturn]] void formatted_error(LogSourceLocation src, std::string_view prefix, std::string_view format, std::string message);
[[noreturn]] void formatted_cmd_error(std::string_view format, std::string message);
void suppressed();
void add_experimental(const std::string &str);
@@ -427,8 +438,7 @@ public:
std::string finish_hasher();
private:
void logv_string(LogSeverity severity, std::string_view prefix, std::string_view format, std::string str_in);
[[noreturn]] void error_with_prefix(std::string_view prefix, std::string_view format, std::string message);
void logv_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix, std::string_view format, std::string str_in);
std::vector<std::unique_ptr<LogSink>> sinks;
int verbose_level = 0;
@@ -470,23 +480,23 @@ static inline bool ys_debug(int = 0) { return false; }
template <typename... Args>
inline void log(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_string(LogSeverity::Info, {}, fmt.format_string(), fmt.format(args...));
logger().formatted_string(LogSeverity::Info, LogSourceLocation{}, {}, fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
inline void log_comment(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_string(LogSeverity::Comment, {}, fmt.format_string(), fmt.format(args...));
logger().formatted_string(LogSeverity::Comment, LogSourceLocation{}, {}, fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
inline void log_formatted_string(LogSeverity severity, std::string_view prefix,
inline void log_formatted_string(LogSeverity severity, LogSourceLocation src, std::string_view prefix,
FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_string(severity, prefix, fmt.format_string(), fmt.format(args...));
logger().formatted_string(severity, src, prefix, fmt.format_string(), fmt.format(args...));
}
#define log_debug(...) do { if (ys_debug(1)) YOSYS_NAMESPACE_PREFIX log_formatted_string(YOSYS_NAMESPACE_PREFIX LogSeverity::Debug, {}, __VA_ARGS__); } while (0)
#define log_debug(...) do { if (ys_debug(1)) YOSYS_NAMESPACE_PREFIX log_formatted_string(YOSYS_NAMESPACE_PREFIX LogSeverity::Debug, {}, {}, __VA_ARGS__); } while (0)
template <typename... Args>
inline void log_header(RTLIL::Design *design, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
@@ -497,13 +507,13 @@ inline void log_header(RTLIL::Design *design, FmtString<TypeIdentity<Args>...> f
template <typename... Args>
inline void log_warning(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_warning("Warning: ", fmt.format_string(), fmt.format(args...));
logger().formatted_warning(LogSourceLocation{}, "Warning: ", fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
inline void log_warning_noprefix(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_warning({}, fmt.format_string(), fmt.format(args...));
logger().formatted_warning(LogSourceLocation{}, {}, fmt.format_string(), fmt.format(args...));
}
inline void log_experimental(const std::string &str)
@@ -518,27 +528,27 @@ inline void log_deprecated(const std::string &str)
// Log with filename to report a problem in a source file.
template <typename... Args>
void log_file_warning(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
void log_file_warning(LogSourceLocation src, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_file_warning(filename, lineno, fmt.format_string(), fmt.format(args...));
logger().formatted_warning(src, "Warning: ", fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
void log_file_info(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
void log_file_info(LogSourceLocation src, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_file_info(filename, lineno, fmt.format_string(), fmt.format(args...));
logger().formatted_string(LogSeverity::Info, src, "Info: ", fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
[[noreturn]] void log_error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_error(fmt.format_string(), fmt.format(args...));
logger().formatted_error(LogSourceLocation{}, "ERROR: ", fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
[[noreturn]] void log_file_error(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
[[noreturn]] void log_file_error(LogSourceLocation src, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
logger().formatted_file_error(filename, lineno, fmt.format_string(), fmt.format(args...));
logger().formatted_error(src, "ERROR: ", fmt.format_string(), fmt.format(args...));
}
template <typename... Args>
+5 -5
View File
@@ -46,7 +46,7 @@ void log_warning(const char *format, ...)
va_start(ap, format);
std::string formatted = vstringf(format, ap);
va_end(ap);
logger().formatted_warning("Warning: ", format, formatted);
logger().formatted_warning(LogSourceLocation{}, "Warning: ", format, formatted);
}
void log_warning_noprefix(const char *format, ...)
@@ -55,7 +55,7 @@ void log_warning_noprefix(const char *format, ...)
va_start(ap, format);
std::string formatted = vstringf(format, ap);
va_end(ap);
logger().formatted_warning({}, format, formatted);
logger().formatted_warning(LogSourceLocation{}, {}, format, formatted);
}
void log_error(const char *format, ...)
@@ -64,7 +64,7 @@ void log_error(const char *format, ...)
va_start(ap, format);
std::string formatted = vstringf(format, ap);
va_end(ap);
logger().formatted_error(format, formatted);
logger().formatted_error(LogSourceLocation{}, "ERROR:", format, formatted);
}
void log(const char *format, ...)
@@ -73,7 +73,7 @@ void log(const char *format, ...)
va_start(ap, format);
std::string formatted = vstringf(format, ap);
va_end(ap);
logger().formatted_string(LogSeverity::Info, {}, format, formatted);
logger().formatted_string(LogSeverity::Info, LogSourceLocation{}, {}, format, formatted);
}
void log_compat(const char *format, ...)
@@ -82,7 +82,7 @@ void log_compat(const char *format, ...)
va_start(ap, format);
std::string formatted = vstringf(format, ap);
va_end(ap);
logger().formatted_string(LogSeverity::Info, {}, format, formatted);
logger().formatted_string(LogSeverity::Info, LogSourceLocation{}, {}, format, formatted);
}
YOSYS_NAMESPACE_END
+7 -7
View File
@@ -179,13 +179,13 @@ namespace pyosys {
// Logging Methods
m.def("log_header", [](Design *d, std::string s) { logger().formatted_header(d, "%s", s); });
m.def("log", [](std::string s) { logger().formatted_string(LogSeverity::Info, {}, "%s", s); });
m.def("log_file_info", [](std::string_view file, int line, std::string s) { logger().formatted_file_info(file, line, "%s", s); });
m.def("log_warning", [](std::string s) { logger().formatted_warning("Warning: ", "%s", s); });
m.def("log_warning_noprefix", [](std::string s) { logger().formatted_warning("", "%s", s); });
m.def("log_file_warning", [](std::string_view file, int line, std::string s) { logger().formatted_file_warning(file, line, "%s", s); });
m.def("log_error", [](std::string s) { logger().formatted_error("%s", s); });
m.def("log_file_error", [](std::string_view file, int line, std::string s) { logger().formatted_file_error(file, line, "%s", s); });
m.def("log", [](std::string s) { logger().formatted_string(LogSeverity::Info, LogSourceLocation{}, {}, "%s", s); });
m.def("log_file_info", [](std::string file, int line, std::string s) { logger().formatted_string(LogSeverity::Info, LogSourceLocation(file,line), "Info: ", "%s", s); });
m.def("log_warning", [](std::string s) { logger().formatted_warning(LogSourceLocation{}, "Warning: ", "%s", s); });
m.def("log_warning_noprefix", [](std::string s) { logger().formatted_warning(LogSourceLocation{}, "", "%s", s); });
m.def("log_file_warning", [](std::string file, int line, std::string s) { logger().formatted_warning(LogSourceLocation(file,line), "Warning: ", "%s", s); });
m.def("log_error", [](std::string s) { logger().formatted_error(LogSourceLocation{}, "ERROR: ", "%s", s); });
m.def("log_file_error", [](std::string file, int line, std::string s) { logger().formatted_error(LogSourceLocation(file,line), "ERROR: ", "%s", s); });
// Namespace to host global objects
auto global_variables = py::class_<Globals>(m, "Globals");