From 8102defc7356bd1940ef63b1512f538d2264077b Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 09:13:18 -0700 Subject: [PATCH 1/6] Add ability to print errors as json objects --- source/common.h | 51 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/source/common.h b/source/common.h index 392f82e969..78efdf8d97 100644 --- a/source/common.h +++ b/source/common.h @@ -986,6 +986,13 @@ static cmdline_processor::register_flag cmd_print_colon_errors( []{ flag_print_colon_errors = true; } ); +static auto flag_json_errors = false; +static cmdline_processor::register_flag cmd_json_errors( + 9, + "json-errors", + "Emit errors in json - for use in language server tools", + []{ flag_json_errors = true; } +); //----------------------------------------------------------------------- // @@ -1024,29 +1031,37 @@ struct error_entry auto print(auto& o, std::string const& file) const -> void { - o << file ; - if (where.lineno > 0) { - if (flag_print_colon_errors) { - o << ":" << (where.lineno); - if (where.colno >= 0) { - o << ":" << where.colno; + if (flag_json_errors) { + o << "{ \"file\": \"" << file << "\"" + << ", \"line\": " << where.lineno + << ", \"column\": " << where.colno + << ", \"error\": \"" << msg << "\"" + << "}\n"; + } + else { + o << file ; + if (where.lineno > 0) { + if (flag_print_colon_errors) { + o << ":" << (where.lineno); + if (where.colno >= 0) { + o << ":" << where.colno; + } } - } - else { - o << "("<< (where.lineno); - if (where.colno >= 0) { - o << "," << where.colno; + else { + o << "("<< (where.lineno); + if (where.colno >= 0) { + o << "," << where.colno; + } + o << ")"; } - o << ")"; } + o << ":"; + if (internal) { + o << " internal compiler"; + } + o << " error: " << msg << "\n"; } - o << ":"; - if (internal) { - o << " internal compiler"; - } - o << " error: " << msg << "\n"; } - }; From fbda4e9c900c84c6ca70b827f13c6d3edf07d336 Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 10:02:06 -0700 Subject: [PATCH 2/6] Add ability to track the symbol associated with an error --- source/common.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/common.h b/source/common.h index 78efdf8d97..62a309fe9a 100644 --- a/source/common.h +++ b/source/common.h @@ -1004,6 +1004,7 @@ struct error_entry { source_position where; std::string msg; + std::string symbol = std::string(""); bool internal = false; bool fallback = false; // only emit this message if there was nothing better @@ -1019,6 +1020,21 @@ struct error_entry , fallback{f} { } + /// An overload allowing the passing in of the symbol associated with the error + error_entry( + source_position w, + std::string_view m, + std::string_view s, + bool i = false, + bool f = false + ) + : where{w} + , msg{m} + , symbol{s} + , internal{i} + , fallback{f} + { } + auto operator==(error_entry const& that) -> bool { @@ -1036,6 +1052,7 @@ struct error_entry << ", \"line\": " << where.lineno << ", \"column\": " << where.colno << ", \"error\": \"" << msg << "\"" + << ", \"symbol\": \"" << symbol << "\"" << "}\n"; } else { From bb7c99e167211637a2f546a4a4c1d3f1604ae0b6 Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 10:07:12 -0700 Subject: [PATCH 3/6] Capture some symbol names in the errors There's probably more to be captured but I didn't want to start tearing through the code prematurely --- source/sema.h | 3 ++- source/to_cpp1.h | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/sema.h b/source/sema.h index d1b14e41b5..0e8291a5db 100644 --- a/source/sema.h +++ b/source/sema.h @@ -1264,7 +1264,8 @@ class sema errors.emplace_back( sym.identifier->position(), "local variable " + name - + " is used before it was initialized"); + + " is used before it was initialized", + name ); } return sym.standalone_assignment_to; } diff --git a/source/to_cpp1.h b/source/to_cpp1.h index 00ac1cdac0..32344469ce 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -5293,6 +5293,7 @@ class cppfront // so write it once to keep the guidance consistent assert (n.parent_declaration && n.parent_declaration->name()); auto error_msg = "an operator= body must start with a series of 'member = value;' initialization statements for each of the type-scope objects in the same order they are declared, or the member must have a default initializer (in type '" + n.parent_declaration->name()->to_string() + "')"; + auto error_symbol = n.parent_declaration->name()->to_string(); // If this constructor's type has data members, handle their initialization // - objects is the list of this type's declarations @@ -5441,7 +5442,8 @@ class cppfront ); errors.emplace_back( stmt_pos, - error_msg + error_msg, + error_symbol ); return; } @@ -5570,7 +5572,8 @@ class cppfront ); errors.emplace_back( (*object)->position(), - error_msg + error_msg, + error_symbol ); return; } From 04e56de26288bb57784a7928f529902fded4b707 Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 10:36:23 -0700 Subject: [PATCH 4/6] Add in one more symbol name capture --- source/parse.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/parse.h b/source/parse.h index a8ad4bd9e6..0b5916d5c7 100644 --- a/source/parse.h +++ b/source/parse.h @@ -6069,6 +6069,8 @@ class parser auto m = std::string{msg}; auto i = done() ? -1 : 0; assert (peek(i)); + auto s = peek(i)->to_string(); + if (include_curr_token) { m += std::string(" (at '") + peek(i)->to_string() + "')"; } @@ -6077,7 +6079,7 @@ class parser ) { err_pos = peek(i)->position(); } - errors.emplace_back( err_pos, m, false, fallback ); + errors.emplace_back( err_pos, m, s, false, fallback ); } auto error( From 46e4a6c74ad2f30d5201bd56d67a9ad81dfad061 Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 14:27:56 -0700 Subject: [PATCH 5/6] Just use the default constructor on `symbol` --- source/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common.h b/source/common.h index 9f7a2bd320..3b5c81f857 100644 --- a/source/common.h +++ b/source/common.h @@ -1004,7 +1004,7 @@ struct error_entry { source_position where; std::string msg; - std::string symbol = std::string(""); + std::string symbol; bool internal = false; bool fallback = false; // only emit this message if there was nothing better From 97525341dd9ab106519aadaccf22116bc3cf1955 Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Fri, 11 Oct 2024 14:28:34 -0700 Subject: [PATCH 6/6] Forgot to remove the duplicate Since I declared a variable s = peek(), its better to use it now instead of leaving the duplicate peek expression --- source/parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/parse.h b/source/parse.h index 0b5916d5c7..40a60ab209 100644 --- a/source/parse.h +++ b/source/parse.h @@ -6072,7 +6072,7 @@ class parser auto s = peek(i)->to_string(); if (include_curr_token) { - m += std::string(" (at '") + peek(i)->to_string() + "')"; + m += std::string(" (at '") + s + "')"; } if ( err_pos == source_position{}