diff --git a/source/common.h b/source/common.h index 5839b4cd80..3b5c81f857 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; } +); //----------------------------------------------------------------------- // @@ -997,6 +1004,7 @@ struct error_entry { source_position where; std::string msg; + std::string symbol; bool internal = false; bool fallback = false; // only emit this message if there was nothing better @@ -1012,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 { @@ -1024,29 +1047,38 @@ 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 << "\"" + << ", \"symbol\": \"" << symbol << "\"" + << "}\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"; } - }; diff --git a/source/parse.h b/source/parse.h index a8ad4bd9e6..40a60ab209 100644 --- a/source/parse.h +++ b/source/parse.h @@ -6069,15 +6069,17 @@ 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() + "')"; + m += std::string(" (at '") + s + "')"; } if ( err_pos == source_position{} ) { err_pos = peek(i)->position(); } - errors.emplace_back( err_pos, m, false, fallback ); + errors.emplace_back( err_pos, m, s, false, fallback ); } auto error( diff --git a/source/sema.h b/source/sema.h index f3d8ac63f1..add780a1e0 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 3e08d83e6d..1b1b4e7152 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -5374,6 +5374,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 @@ -5522,7 +5523,8 @@ class cppfront ); errors.emplace_back( stmt_pos, - error_msg + error_msg, + error_symbol ); return; } @@ -5651,7 +5653,8 @@ class cppfront ); errors.emplace_back( (*object)->position(), - error_msg + error_msg, + error_symbol ); return; }