From 3f69a768f4aac3e1b95f830b13c866e20a0f073e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 02:30:12 +0000 Subject: [PATCH 01/14] Hide public `logv_` variant declarations that don't need to be public --- kernel/log.cc | 11 ++++++----- kernel/log.h | 5 ----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 3203ed3cf..1cd4a5449 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -102,7 +102,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) } #endif -void logv(const char *format, va_list ap) +static void logv(const char *format, va_list ap) { while (format[0] == '\n' && format[1] != 0) { log("\n"); @@ -204,7 +204,7 @@ void logv(const char *format, va_list ap) } } -void logv_header(RTLIL::Design *design, const char *format, va_list ap) +static void logv_header(RTLIL::Design *design, const char *format, va_list ap) { bool pop_errfile = false; @@ -305,12 +305,12 @@ static void logv_warning_with_prefix(const char *prefix, } } -void logv_warning(const char *format, va_list ap) +static void logv_warning(const char *format, va_list ap) { logv_warning_with_prefix("Warning: ", format, ap); } -void logv_warning_noprefix(const char *format, va_list ap) +static void logv_warning_noprefix(const char *format, va_list ap) { logv_warning_with_prefix("", format, ap); } @@ -390,7 +390,8 @@ static void logv_error_with_prefix(const char *prefix, #endif } -void logv_error(const char *format, va_list ap) +[[noreturn]] +static void logv_error(const char *format, va_list ap) { logv_error_with_prefix("ERROR: ", format, ap); } diff --git a/kernel/log.h b/kernel/log.h index 48997d250..27ee49d8f 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -119,11 +119,6 @@ extern int log_make_debug; extern int log_force_debug; extern int log_debug_suppressed; -void logv(const char *format, va_list ap); -void logv_header(RTLIL::Design *design, const char *format, va_list ap); -void logv_warning(const char *format, va_list ap); -void logv_warning_noprefix(const char *format, va_list ap); -[[noreturn]] void logv_error(const char *format, va_list ap); [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); From d34ac0c87d5a31eacfe9c8ae0ad350f72ba90349 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Thu, 10 Jul 2025 05:24:59 +0000 Subject: [PATCH 02/14] Make `log()` use the `FmtString` infrastructure. Now `log()` supports `std::string`. We have to fix a few places where the format parameter was not a compile time constant. This is mostly trivial. --- backends/cxxrtl/cxxrtl_backend.cc | 4 +-- kernel/io.h | 1 + kernel/log.cc | 45 +++++++++++++++++-------------- kernel/log.h | 35 +++++++++++++++++++----- passes/cmds/logcmd.cc | 10 +++---- passes/cmds/stat.cc | 2 +- passes/equiv/equiv_simple.cc | 2 +- passes/sat/sat.cc | 4 +-- passes/techmap/dfflibmap.cc | 14 +++++----- passes/tests/test_cell.cc | 2 +- 10 files changed, 74 insertions(+), 45 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 7080f54d5..0c9f6c054 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -3478,8 +3478,8 @@ struct CxxrtlWorker { }; struct CxxrtlBackend : public Backend { - static const int DEFAULT_OPT_LEVEL = 6; - static const int DEFAULT_DEBUG_LEVEL = 4; + static constexpr int DEFAULT_OPT_LEVEL = 6; + static constexpr int DEFAULT_DEBUG_LEVEL = 4; CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { } void help() override diff --git a/kernel/io.h b/kernel/io.h index 08c234d6e..2ad0a6466 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -437,6 +437,7 @@ public: { return format_emit_toplevel(fmt, has_escapes, specs, args...); } + std::string_view format_string() const { return fmt; } private: std::string_view fmt; bool has_escapes = false; diff --git a/kernel/log.cc b/kernel/log.cc index 1cd4a5449..0afc98cd0 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -102,17 +102,16 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) } #endif -static void logv(const char *format, va_list ap) -{ - while (format[0] == '\n' && format[1] != 0) { - log("\n"); - format++; +static void logv_string(std::string_view format, std::string str) { + size_t remove_leading = 0; + while (format.size() > 1 && format[0] == '\n') { + logv_string("\n", "\n"); + format = format.substr(1); + ++remove_leading; + } + if (remove_leading > 0) { + str = str.substr(remove_leading); } - - if (log_make_debug && !ys_debug(1)) - return; - - std::string str = vstringf(format, ap); if (str.empty()) return; @@ -145,13 +144,13 @@ static void logv(const char *format, va_list ap) time_str += stringf("[%05d.%06d] ", int(tv.tv_sec), int(tv.tv_usec)); } - if (format[0] && format[strlen(format)-1] == '\n') + if (!format.empty() && format[format.size() - 1] == '\n') next_print_log = true; // Special case to detect newlines in Python log output, since // the binding always calls `log("%s", payload)` and the newline // is then in the first formatted argument - if (!strcmp(format, "%s") && str.back() == '\n') + if (format == "%s" && str.back() == '\n') next_print_log = true; for (auto f : log_files) @@ -204,6 +203,20 @@ static void logv(const char *format, va_list ap) } } +static void logv(const char *format, va_list ap) +{ + if (log_make_debug && !ys_debug(1)) + return; + logv_string(format, vstringf(format, ap)); +} + +void log_formatted_string(std::string_view format, std::string str) +{ + if (log_make_debug && !ys_debug(1)) + return; + logv_string(format, std::move(str)); +} + static void logv_header(RTLIL::Design *design, const char *format, va_list ap) { bool pop_errfile = false; @@ -412,14 +425,6 @@ void log_file_error(const string &filename, int lineno, logv_file_error(filename, lineno, format, ap); } -void log(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - logv(format, ap); - va_end(ap); -} - void log_header(RTLIL::Design *design, const char *format, ...) { va_list ap; diff --git a/kernel/log.h b/kernel/log.h index 27ee49d8f..f58bf3afe 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -121,7 +121,7 @@ extern int log_debug_suppressed; [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); -void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); + void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3)); void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -145,6 +145,15 @@ static inline bool ys_debug(int = 0) { return false; } #endif # define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) +void log_formatted_string(std::string_view format, std::string str); +template +inline void log(FmtString...> fmt, const Args &... args) +{ + if (log_make_debug && !ys_debug(1)) + return; + log_formatted_string(fmt.format_string(), fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); @@ -346,8 +355,22 @@ static inline void log_dump_val_worker(unsigned long int v) { log("%lu", v); } static inline void log_dump_val_worker(long long int v) { log("%lld", v); } static inline void log_dump_val_worker(unsigned long long int v) { log("%lld", v); } #endif -static inline void log_dump_val_worker(char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); } -static inline void log_dump_val_worker(unsigned char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); } +static inline void log_dump_val_worker(char c) +{ + if (c >= 32 && c < 127) { + log("'%c'", c); + } else { + log("'\\x%02x'", c); + } +} +static inline void log_dump_val_worker(unsigned char c) +{ + if (c >= 32 && c < 127) { + log("'%c'", c); + } else { + log("'\\x%02x'", c); + } +} static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false"); } static inline void log_dump_val_worker(double v) { log("%f", v); } static inline void log_dump_val_worker(char *v) { log("%s", v); } @@ -369,7 +392,7 @@ static inline void log_dump_val_worker(dict &v) { log("{"); bool first = true; for (auto &it : v) { - log(first ? " " : ", "); + log("%s ", first ? "" : ","); log_dump_val_worker(it.first); log(": "); log_dump_val_worker(it.second); @@ -383,7 +406,7 @@ static inline void log_dump_val_worker(pool &v) { log("{"); bool first = true; for (auto &it : v) { - log(first ? " " : ", "); + log("%s ", first ? "" : ","); log_dump_val_worker(it); first = false; } @@ -395,7 +418,7 @@ static inline void log_dump_val_worker(std::vector &v) { log("{"); bool first = true; for (auto &it : v) { - log(first ? " " : ", "); + log("%s ", first ? "" : ","); log_dump_val_worker(it); first = false; } diff --git a/passes/cmds/logcmd.cc b/passes/cmds/logcmd.cc index 0238627d1..391eaea2e 100644 --- a/passes/cmds/logcmd.cc +++ b/passes/cmds/logcmd.cc @@ -101,13 +101,13 @@ struct LogPass : public Pass { text += args[argidx] + ' '; if (!text.empty()) text.resize(text.size()-1); - const char *fmtline = newline ? "%s\n" : "%s"; + const char *line_end = newline ? "\n" : ""; - if (to_stdout) fprintf(stdout, fmtline, text.c_str()); - if (to_stderr) fprintf(stderr, fmtline, text.c_str()); + if (to_stdout) fprintf(stdout, "%s%s", text.c_str(), line_end); + if (to_stderr) fprintf(stderr, "%s%s", text.c_str(), line_end); if (to_log) { - if (!header) log(fmtline, text.c_str()); - else log_header(design, fmtline, text.c_str()); + if (!header) log("%s%s", text.c_str(), line_end); + else log_header(design, "%s%s", text.c_str(), line_end); } } } LogPass; diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index ebbd10b5c..9281f3327 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -1017,7 +1017,7 @@ struct StatPass : public Pass { if (json_mode) { log("\n"); - log(top_mod == nullptr ? " }\n" : " },\n"); + log("%s", top_mod == nullptr ? " }\n" : " },\n"); } if (top_mod != nullptr) { diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 8ba42595e..9e3076077 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -331,7 +331,7 @@ struct EquivSimpleWorker construct_ezsat(input_bits, step); if (!ez->solve(ez_context)) { - log(cfg.verbose ? " Proved equivalence! Marking $equiv cell as proven.\n" : " success!\n"); + log("%s", cfg.verbose ? " Proved equivalence! Marking $equiv cell as proven.\n" : " success!\n"); // Replace $equiv cell with a short cell->setPort(ID::B, cell->getPort(ID::A)); ez->assume(ez->NOT(ez_context)); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 2f20880cb..60e099097 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -634,10 +634,10 @@ struct SatHelper "---------------------------------------------------------------------------------------------------" "---------------------------------------------------------------------------------------------------"; if (last_timestep == -2) { - log(max_timestep > 0 ? " Time " : " "); + log("%s", max_timestep > 0 ? " Time " : " "); log("%-*s %11s %9s %*s\n", maxModelName+5, "Signal Name", "Dec", "Hex", maxModelWidth+3, "Bin"); } - log(max_timestep > 0 ? " ---- " : " "); + log("%s", max_timestep > 0 ? " ---- " : " "); log("%*.*s %11.11s %9.9s %*.*s\n", maxModelName+5, maxModelName+5, hline, hline, hline, maxModelWidth+3, maxModelWidth+3, hline); last_timestep = info.timestep; diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index a2b9c3bff..70d0f4ef5 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -135,7 +135,7 @@ static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std if (ff == nullptr || ff->args.size() != 2) return false; auto ff_output = ff->args.at(0); - + // This test is redundant with the one in enable_pin, but we're in a // position that gives better diagnostics here. if (!pin_names.count(ff_output)) { @@ -166,23 +166,23 @@ static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std // the ff output Q is in a known bit location, so we now just have to compare the LUT mask to known values to find the enable pin and polarity. if (lut == 0xD8) { data_name = pins[1]; - enable_name = pins[0]; + enable_name = pins[0]; return true; } if (lut == 0xB8) { data_name = pins[0]; - enable_name = pins[1]; + enable_name = pins[1]; return true; } enable_not_inverted = false; if (lut == 0xE4) { data_name = pins[1]; - enable_name = pins[0]; + enable_name = pins[0]; return true; } if (lut == 0xE2) { data_name = pins[0]; - enable_name = pins[1]; + enable_name = pins[1]; return true; } // this does not match an enable flop. @@ -553,11 +553,11 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) new_cell->setPort("\\" + port.first, sig); } - stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type, new_cell->type)]++; + stats[stringf("%s cells to %s cells", cell_type, new_cell->type)]++; } for (auto &stat: stats) - log(stat.first.c_str(), stat.second); + log(" mapped %d %s.\n", stat.second, stat.first); } struct DfflibmapPass : public Pass { diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 87e0a00f8..a08a6ec29 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -620,7 +620,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: for (int i = 0; i < 64; i++) { - log(verbose ? "\n" : "."); + log("%s", verbose ? "\n" : "."); gold_ce.clear(); gate_ce.clear(); From 66d2c2af08447ce1d4f80e91579a7348d1c65381 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 02:26:50 +0000 Subject: [PATCH 03/14] Make `log_header()` use variadic templates. --- kernel/log.cc | 12 ++---------- kernel/log.h | 8 +++++++- passes/opt/opt.cc | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 0afc98cd0..bef3efb99 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -217,7 +217,7 @@ void log_formatted_string(std::string_view format, std::string str) logv_string(format, std::move(str)); } -static void logv_header(RTLIL::Design *design, const char *format, va_list ap) +void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str) { bool pop_errfile = false; @@ -236,7 +236,7 @@ static void logv_header(RTLIL::Design *design, const char *format, va_list ap) header_id += stringf("%s%d", header_id.empty() ? "" : ".", c); log("%s. ", header_id.c_str()); - logv(format, ap); + log_formatted_string(format, std::move(str)); log_flush(); if (log_hdump_all) @@ -425,14 +425,6 @@ void log_file_error(const string &filename, int lineno, logv_file_error(filename, lineno, format, ap); } -void log_header(RTLIL::Design *design, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - logv_header(design, format, ap); - va_end(ap); -} - void log_warning(const char *format, ...) { va_list ap; diff --git a/kernel/log.h b/kernel/log.h index f58bf3afe..55fa58a34 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -122,7 +122,6 @@ extern int log_debug_suppressed; [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); -void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3)); void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -154,6 +153,13 @@ inline void log(FmtString...> fmt, const Args &... args) log_formatted_string(fmt.format_string(), fmt.format(args...)); } +void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str); +template +inline void log_header(RTLIL::Design *design, FmtString...> fmt, const Args &... args) +{ + log_formatted_header(design, fmt.format_string(), fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 146c21cce..ec5760cd9 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -196,7 +196,7 @@ struct OptPass : public Pass { design->sort(); design->check(); - log_header(design, fast_mode ? "Finished fast OPT passes.\n" : "Finished OPT passes. (There is nothing left to do.)\n"); + log_header(design, "Finished fast OPT passes.%s\n", fast_mode ? "" : " (There is nothing left to do.)"); log_pop(); } } OptPass; From 25cba6181e533f41474e7e87f465b13616931651 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 03:14:15 +0000 Subject: [PATCH 04/14] Make log_warning()/log_warning_noprefix() use variadic templates. --- kernel/log.cc | 38 +++++--------------------------------- kernel/log.h | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index bef3efb99..18de1296a 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -256,10 +256,8 @@ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::s log_files.pop_back(); } -static void logv_warning_with_prefix(const char *prefix, - const char *format, va_list ap) +void log_formatted_warning(std::string_view prefix, std::string message) { - std::string message = vstringf(format, ap); bool suppressed = false; for (auto &re : log_nowarn_regexes) @@ -268,7 +266,7 @@ static void logv_warning_with_prefix(const char *prefix, if (suppressed) { - log("Suppressed %s%s", prefix, message.c_str()); + log("Suppressed %s%s", prefix, message); } else { @@ -294,7 +292,7 @@ static void logv_warning_with_prefix(const char *prefix, if (log_warnings.count(message)) { - log("%s%s", prefix, message.c_str()); + log("%s%s", prefix, message); log_flush(); } else @@ -302,7 +300,7 @@ static void logv_warning_with_prefix(const char *prefix, if (log_errfile != NULL && !log_quiet_warnings) log_files.push_back(log_errfile); - log("%s%s", prefix, message.c_str()); + log("%s%s", prefix, message); log_flush(); if (log_errfile != NULL && !log_quiet_warnings) @@ -318,16 +316,6 @@ static void logv_warning_with_prefix(const char *prefix, } } -static void logv_warning(const char *format, va_list ap) -{ - logv_warning_with_prefix("Warning: ", format, ap); -} - -static void logv_warning_noprefix(const char *format, va_list ap) -{ - logv_warning_with_prefix("", format, ap); -} - void log_file_warning(const std::string &filename, int lineno, const char *format, ...) { @@ -335,7 +323,7 @@ void log_file_warning(const std::string &filename, int lineno, va_start(ap, format); std::string prefix = stringf("%s:%d: Warning: ", filename.c_str(), lineno); - logv_warning_with_prefix(prefix.c_str(), format, ap); + log_formatted_warning(prefix, vstringf(format, ap)); va_end(ap); } @@ -425,14 +413,6 @@ void log_file_error(const string &filename, int lineno, logv_file_error(filename, lineno, format, ap); } -void log_warning(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - logv_warning(format, ap); - va_end(ap); -} - void log_experimental(const char *format, ...) { va_list ap; @@ -446,14 +426,6 @@ void log_experimental(const char *format, ...) } } -void log_warning_noprefix(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - logv_warning_noprefix(format, ap); - va_end(ap); -} - void log_error(const char *format, ...) { va_list ap; diff --git a/kernel/log.h b/kernel/log.h index 55fa58a34..c8277f365 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -122,7 +122,6 @@ extern int log_debug_suppressed; [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); -void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); @@ -132,7 +131,6 @@ extern void (*log_verific_callback)(int msg_type, const char *message_id, const void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); -void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); [[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); [[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); [[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -160,6 +158,18 @@ inline void log_header(RTLIL::Design *design, FmtString...> f log_formatted_header(design, fmt.format_string(), fmt.format(args...)); } +void log_formatted_warning(std::string_view prefix, std::string str); +template +inline void log_warning(FmtString...> fmt, const Args &... args) +{ + log_formatted_warning("Warning: ", fmt.format(args...)); +} +template +inline void log_warning_noprefix(FmtString...> fmt, const Args &... args) +{ + log_formatted_warning("", fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From 2a2c586e2c6ff1d1cca63aefc6df3ba337fa87a7 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 03:51:29 +0000 Subject: [PATCH 05/14] Make log_experimental() just take an std::string, since it doesn't need to be varargs. --- kernel/log.cc | 13 ++++--------- kernel/log.h | 5 ++--- kernel/register.cc | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 18de1296a..e5715425a 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -413,16 +413,11 @@ void log_file_error(const string &filename, int lineno, logv_file_error(filename, lineno, format, ap); } -void log_experimental(const char *format, ...) +void log_experimental(const std::string &str) { - va_list ap; - va_start(ap, format); - string s = vstringf(format, ap); - va_end(ap); - - if (log_experimentals_ignored.count(s) == 0 && log_experimentals.count(s) == 0) { - log_warning("Feature '%s' is experimental.\n", s.c_str()); - log_experimentals.insert(s); + if (log_experimentals_ignored.count(str) == 0 && log_experimentals.count(str) == 0) { + log_warning("Feature '%s' is experimental.\n", str); + log_experimentals.insert(str); } } diff --git a/kernel/log.h b/kernel/log.h index c8277f365..af30d9cfa 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -121,9 +121,6 @@ extern int log_debug_suppressed; [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); - -void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); - void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); @@ -170,6 +167,8 @@ inline void log_warning_noprefix(FmtString...> fmt, const Arg log_formatted_warning("", fmt.format(args...)); } +void log_experimental(const std::string &str); + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); diff --git a/kernel/register.cc b/kernel/register.cc index 0b02a6aa5..c82620f40 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -265,7 +265,7 @@ void Pass::call(RTLIL::Design *design, std::vector args) log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str()); if (pass_register[args[0]]->experimental_flag) - log_experimental("%s", args[0].c_str()); + log_experimental(args[0]); size_t orig_sel_stack_pos = design->selection_stack.size(); auto state = pass_register[args[0]]->pre_execute(); From 9764fa5c41c39d704762c961fbba3db4008d41e2 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:01:02 +0000 Subject: [PATCH 06/14] Remove superfluous/wasteful .c_str()s in log_file_warning() filename parameter --- frontends/verilog/verilog_lexer.l | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 8280c0067..fbc9fca07 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -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->c_str(), loc.begin.line, "'%c' not a valid digit in hex escape sequence.\n", c); + log_file_warning(*loc.begin.filename, loc.begin.line, "'%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->c_str(), loc.begin.line, "'%c' not a valid digit in octal escape sequence.\n", c); + log_file_warning(*loc.begin.filename, loc.begin.line, "'%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->c_str(), loc.begin.line, "Multi-line string literals should be triple-quoted or escaped.\n"); + log_file_warning(*loc.begin.filename, loc.begin.line, "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->c_str(), loc.begin.line, "ignoring invalid hex escape.\n"); + log_file_warning(*loc.begin.filename, loc.begin.line, "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->c_str(), loc.begin.line, "octal escape exceeds \\377\n"); + log_file_warning(*loc.begin.filename, loc.begin.line, "octal escape exceeds \\377\n"); *out = *out * 010 + val; in++; } From ec5f62e6d4b3a4a207935ff6d94bbb9c0508cc75 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:03:43 +0000 Subject: [PATCH 07/14] Make log_file_warning() use variadic templates. --- kernel/log.cc | 11 +++-------- kernel/log.h | 10 ++++++++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index e5715425a..911afbe9d 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -316,15 +316,10 @@ void log_formatted_warning(std::string_view prefix, std::string message) } } -void log_file_warning(const std::string &filename, int lineno, - const char *format, ...) +void log_formatted_file_warning(std::string_view filename, int lineno, std::string str) { - va_list ap; - va_start(ap, format); - std::string prefix = stringf("%s:%d: Warning: ", - filename.c_str(), lineno); - log_formatted_warning(prefix, vstringf(format, ap)); - va_end(ap); + std::string prefix = stringf("%s:%d: Warning: ", filename, lineno); + log_formatted_warning(prefix, std::move(str)); } void log_file_info(const std::string &filename, int lineno, diff --git a/kernel/log.h b/kernel/log.h index af30d9cfa..694b238df 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,8 +124,6 @@ extern int log_debug_suppressed; void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); -// Log with filename to report a problem in a source file. -void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); [[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -169,6 +167,14 @@ inline void log_warning_noprefix(FmtString...> fmt, const Arg void log_experimental(const std::string &str); +// Log with filename to report a problem in a source file. +void log_formatted_file_warning(std::string_view filename, int lineno, std::string str); +template +void log_file_warning(std::string_view filename, int lineno, FmtString...> fmt, const Args &... args) +{ + log_formatted_file_warning(filename, lineno, fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From ea2bb5b79aac400f473035e16094d664405477f2 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:15:30 +0000 Subject: [PATCH 08/14] Make log_file_info() use variadic templates. --- kernel/log.cc | 17 ++--------------- kernel/log.h | 11 +++++++++-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 911afbe9d..27d58b45b 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -203,13 +203,6 @@ static void logv_string(std::string_view format, std::string str) { } } -static void logv(const char *format, va_list ap) -{ - if (log_make_debug && !ys_debug(1)) - return; - logv_string(format, vstringf(format, ap)); -} - void log_formatted_string(std::string_view format, std::string str) { if (log_make_debug && !ys_debug(1)) @@ -322,15 +315,9 @@ void log_formatted_file_warning(std::string_view filename, int lineno, std::stri log_formatted_warning(prefix, std::move(str)); } -void log_file_info(const std::string &filename, int lineno, - const char *format, ...) +void log_formatted_file_info(std::string_view filename, int lineno, std::string str) { - va_list ap; - va_start(ap, format); - std::string fmt = stringf("%s:%d: Info: %s", - filename.c_str(), lineno, format); - logv(fmt.c_str(), ap); - va_end(ap); + log("%s:%d: Info: %s", filename, lineno, str); } [[noreturn]] diff --git a/kernel/log.h b/kernel/log.h index 694b238df..c3cbbc04a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,8 +124,6 @@ extern int log_debug_suppressed; void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); -void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); - [[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); [[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); [[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -175,6 +173,15 @@ void log_file_warning(std::string_view filename, int lineno, FmtString +void log_file_info(std::string_view filename, int lineno, FmtString...> fmt, const Args &... args) +{ + if (log_make_debug && !ys_debug(1)) + return; + log_formatted_file_info(filename, lineno, fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From 1b5373de0d4137c671c298cbf6e5530178a10ab8 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Sat, 23 Aug 2025 18:21:33 +1200 Subject: [PATCH 09/14] Move log_assert_worker()'s call to log_error() into an out-of-line non-varags function --- kernel/log.cc | 5 +++++ kernel/log.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/log.cc b/kernel/log.cc index 27d58b45b..1e95ea5c5 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -410,6 +410,11 @@ void log_error(const char *format, ...) logv_error(format, ap); } +void log_assert_failure(const char *expr, const char *file, int line) +{ + log_error("Assert `%s' failed in %s:%d.\n", expr, file, line); +} + void log_cmd_error(const char *format, ...) { va_list ap; diff --git a/kernel/log.h b/kernel/log.h index c3cbbc04a..40e1f02ff 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -252,9 +252,11 @@ void log_module(RTLIL::Module *module, std::string indent = ""); void log_cell(RTLIL::Cell *cell, std::string indent = ""); void log_wire(RTLIL::Wire *wire, std::string indent = ""); +[[noreturn]] +void log_assert_failure(const char *expr, const char *file, int line); #ifndef NDEBUG static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { - if (!cond) log_error("Assert `%s' failed in %s:%d.\n", expr, file, line); + if (!cond) log_assert_failure(expr, file, line); } # define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) #else From c3924d06169d4172a336c4ac39766f2bb969c6af Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Sat, 23 Aug 2025 18:30:07 +1200 Subject: [PATCH 10/14] Move log_abort()'s call to log_error() into an out-of-line non-varargs function --- kernel/log.cc | 5 +++++ kernel/log.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/log.cc b/kernel/log.cc index 1e95ea5c5..6bab033de 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -415,6 +415,11 @@ void log_assert_failure(const char *expr, const char *file, int line) log_error("Assert `%s' failed in %s:%d.\n", expr, file, line); } +void log_abort_internal(const char *file, int line) +{ + log_error("Abort in %s:%d.\n", file, line); +} + void log_cmd_error(const char *format, ...) { va_list ap; diff --git a/kernel/log.h b/kernel/log.h index 40e1f02ff..653a73ba3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -263,7 +263,9 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi # define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0) #endif -#define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) +[[noreturn]] +void log_abort_internal(const char *file, int line); +#define log_abort() YOSYS_NAMESPACE_PREFIX log_abort_internal(__FILE__, __LINE__) #define log_ping() YOSYS_NAMESPACE_PREFIX log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) From 974455378b14e0aa71a7fc55517209bf1cdd0a6c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:28:32 +0000 Subject: [PATCH 11/14] Make log_error() use variadic templates. --- kernel/log.cc | 25 ++++++++----------------- kernel/log.h | 8 +++++++- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 6bab033de..55e721768 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -268,7 +268,7 @@ void log_formatted_warning(std::string_view prefix, std::string message) for (auto &re : log_werror_regexes) if (std::regex_search(message, re)) - log_error("%s", message.c_str()); + log_error("%s", message); bool warning_match = false; for (auto &[_, item] : log_expect_warning) @@ -321,8 +321,7 @@ void log_formatted_file_info(std::string_view filename, int lineno, std::string } [[noreturn]] -static void logv_error_with_prefix(const char *prefix, - const char *format, va_list ap) +static void log_error_with_prefix(std::string_view prefix, std::string str) { #ifdef EMSCRIPTEN auto backup_log_files = log_files; @@ -339,8 +338,8 @@ static void logv_error_with_prefix(const char *prefix, if (f == stdout) f = stderr; - log_last_error = vstringf(format, ap); - log("%s%s", prefix, log_last_error.c_str()); + log_last_error = std::move(str); + log("%s%s", prefix, log_last_error); log_flush(); log_make_debug = bak_log_make_debug; @@ -373,18 +372,12 @@ static void logv_error_with_prefix(const char *prefix, #endif } -[[noreturn]] -static void logv_error(const char *format, va_list ap) -{ - logv_error_with_prefix("ERROR: ", format, ap); -} - void logv_file_error(const string &filename, int lineno, const char *format, va_list ap) { std::string prefix = stringf("%s:%d: ERROR: ", filename.c_str(), lineno); - logv_error_with_prefix(prefix.c_str(), format, ap); + log_error_with_prefix(prefix, vstringf(format, ap)); } void log_file_error(const string &filename, int lineno, @@ -403,11 +396,9 @@ void log_experimental(const std::string &str) } } -void log_error(const char *format, ...) +void log_formatted_error(std::string str) { - va_list ap; - va_start(ap, format); - logv_error(format, ap); + log_error_with_prefix("ERROR: ", std::move(str)); } void log_assert_failure(const char *expr, const char *file, int line) @@ -445,7 +436,7 @@ void log_cmd_error(const char *format, ...) throw log_cmd_error_exception(); } - logv_error(format, ap); + log_formatted_error(vstringf(format, ap)); } void log_spacer() diff --git a/kernel/log.h b/kernel/log.h index 653a73ba3..396a24efa 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,7 +124,6 @@ extern int log_debug_suppressed; void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); -[[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); [[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); [[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); @@ -182,6 +181,13 @@ void log_file_info(std::string_view filename, int lineno, FmtString +[[noreturn]] void log_error(FmtString...> fmt, const Args &... args) +{ + log_formatted_error(fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From 243f5f52013a4dd7efcb44b564d916c2c094435c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:35:30 +0000 Subject: [PATCH 12/14] Make log_file_error() use variadic templates. --- kernel/log.cc | 18 +++++++----------- kernel/log.h | 8 +++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 55e721768..ceebc3a86 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -372,20 +372,16 @@ static void log_error_with_prefix(std::string_view prefix, std::string str) #endif } +void log_formatted_file_error(std::string_view filename, int lineno, std::string str) +{ + std::string prefix = stringf("%s:%d: ERROR: ", filename, lineno); + log_error_with_prefix(prefix, str); +} + void logv_file_error(const string &filename, int lineno, const char *format, va_list ap) { - std::string prefix = stringf("%s:%d: ERROR: ", - filename.c_str(), lineno); - log_error_with_prefix(prefix, vstringf(format, ap)); -} - -void log_file_error(const string &filename, int lineno, - const char *format, ...) -{ - va_list ap; - va_start(ap, format); - logv_file_error(filename, lineno, format, ap); + log_formatted_file_error(filename, lineno, vstringf(format, ap)); } void log_experimental(const std::string &str) diff --git a/kernel/log.h b/kernel/log.h index 396a24efa..6cd97ce11 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,7 +124,6 @@ extern int log_debug_suppressed; void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); -[[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); [[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); #ifndef NDEBUG @@ -188,6 +187,13 @@ template log_formatted_error(fmt.format(args...)); } +[[noreturn]] void log_formatted_file_error(std::string_view filename, int lineno, std::string str); +template +[[noreturn]] void log_file_error(std::string_view filename, int lineno, FmtString...> fmt, const Args &... args) +{ + log_formatted_file_error(filename, lineno, fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From a137d03c329393397ea42f342efa44002f5a6f9f Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 22 Jul 2025 04:42:43 +0000 Subject: [PATCH 13/14] Make log_cmd_error() use variadic templates. --- kernel/log.cc | 11 ++++------- kernel/log.h | 9 +++++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index ceebc3a86..0dd56a04f 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -407,13 +407,10 @@ void log_abort_internal(const char *file, int line) log_error("Abort in %s:%d.\n", file, line); } -void log_cmd_error(const char *format, ...) +void log_formatted_cmd_error(std::string str) { - va_list ap; - va_start(ap, format); - if (log_cmd_error_throw) { - log_last_error = vstringf(format, ap); + log_last_error = str; // Make sure the error message gets through any selective silencing // of log output @@ -423,7 +420,7 @@ void log_cmd_error(const char *format, ...) pop_errfile = true; } - log("ERROR: %s", log_last_error.c_str()); + log("ERROR: %s", log_last_error); log_flush(); if (pop_errfile) @@ -432,7 +429,7 @@ void log_cmd_error(const char *format, ...) throw log_cmd_error_exception(); } - log_formatted_error(vstringf(format, ap)); + log_formatted_error(str); } void log_spacer() diff --git a/kernel/log.h b/kernel/log.h index 6cd97ce11..5143524bf 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,8 +124,6 @@ extern int log_debug_suppressed; void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); -[[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); - #ifndef NDEBUG static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; } #else @@ -194,6 +192,13 @@ template log_formatted_file_error(filename, lineno, fmt.format(args...)); } +[[noreturn]] void log_formatted_cmd_error(std::string str); +template +[[noreturn]] void log_cmd_error(FmtString...> fmt, const Args &... args) +{ + log_formatted_cmd_error(fmt.format(args...)); +} + static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { log("\n", log_debug_suppressed); From 75a97241fabeb898e0c801349350912cd03cf7d0 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 9 Sep 2025 10:23:15 +0200 Subject: [PATCH 14/14] Maintain logging ABI compatiblity with YosysHQ Verific Extensions The YosysHQ Verific Extensions are compiled separately using their own stripped-down version of the Yosys headers. To maintain ABI compatibility with older extension builds post C++-ification of Yosys's logging APIs, which are backwards compatible on the API but not ABI level, this commit adds ABI compatible versions of a subset of the old logging API used by the extensions. --- Makefile | 3 ++ kernel/log_compat.cc | 86 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 kernel/log_compat.cc diff --git a/Makefile b/Makefile index aedcd4d3b..fc8d361e6 100644 --- a/Makefile +++ b/Makefile @@ -633,6 +633,9 @@ $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o OBJS += kernel/log_help.o +ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) +OBJS += kernel/log_compat.o +endif OBJS += kernel/binding.o kernel/tclapi.o OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o OBJS += kernel/drivertools.o kernel/functional.o diff --git a/kernel/log_compat.cc b/kernel/log_compat.cc new file mode 100644 index 000000000..e93714873 --- /dev/null +++ b/kernel/log_compat.cc @@ -0,0 +1,86 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + + +#include "kernel/log.h" + +YOSYS_NAMESPACE_BEGIN + +// ABI compatibility for the YosysHQ Verific Extensions + +// The YosysHQ Verific Extensions are compiled separately using their own +// stripped-down version of the Yosys headers. To maintain ABI compatibility +// with older extension builds post C++-ification of Yosys's logging APIs, +// which are backwards compatible on the API but not ABI level, this file +// provides ABI compatible versions of a subset of the old logging API used by +// the extensions. + +void log_cmd_error(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string formatted = vstringf(format, ap); + va_end(ap); + log_formatted_cmd_error(formatted); +} + +void log_warning(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string formatted = vstringf(format, ap); + va_end(ap); + log_formatted_warning("Warning: ", formatted); +} + +void log_warning_noprefix(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string formatted = vstringf(format, ap); + va_end(ap); + log_formatted_warning("", formatted); +} + +void log_error(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string formatted = vstringf(format, ap); + va_end(ap); + log_formatted_error(formatted); +} + +static inline void log_formatted(std::string const &str) +{ + // We use this inline wrapper as the following becomes ambiguous as soon as + // the `log` function below is declared. + return log("%s", str); +} + +void log(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string formatted = vstringf(format, ap); + va_end(ap); + log_formatted(formatted); +} + +YOSYS_NAMESPACE_END