diff options
author | Lewis Hyatt <lhyatt@gmail.com> | 2020-07-14 12:05:56 -0400 |
---|---|---|
committer | Lewis Hyatt <lhyatt@gmail.com> | 2020-07-14 12:05:56 -0400 |
commit | 004bb936d6d5f177af26ad4905595e843d5665a5 (patch) | |
tree | fe3ee343abc249a14509943f4e731f8fb73f6206 /gcc/diagnostic-format-json.cc | |
parent | 5f809982e8e05c39029431363e08759d6c750f0e (diff) | |
download | gcc-004bb936d6d5f177af26ad4905595e843d5665a5.zip gcc-004bb936d6d5f177af26ad4905595e843d5665a5.tar.gz gcc-004bb936d6d5f177af26ad4905595e843d5665a5.tar.bz2 |
diagnostics: Support conversion of tabs to spaces [PR49973] [PR86904]
Supports conversion of tabs to spaces when outputting diagnostics. Also
adds -fdiagnostics-column-unit and -fdiagnostics-column-origin options to
control how the column number is output, thereby resolving the two PRs.
gcc/c-family/ChangeLog:
PR other/86904
* c-indentation.c (should_warn_for_misleading_indentation): Get
global tabstop from the new source.
* c-opts.c (c_common_handle_option): Remove handling of -ftabstop, which
is now a common option.
* c.opt: Likewise.
gcc/ChangeLog:
PR preprocessor/49973
PR other/86904
* common.opt: Handle -ftabstop here instead of in c-family
options. Add -fdiagnostics-column-unit= and
-fdiagnostics-column-origin= options.
* opts.c (common_handle_option): Handle the new options.
* diagnostic-format-json.cc (json_from_expanded_location): Add
diagnostic_context argument. Use it to convert column numbers as per
the new options.
(json_from_location_range): Likewise.
(json_from_fixit_hint): Likewise.
(json_end_diagnostic): Pass the new context argument to helper
functions above. Add "column-origin" field to the output.
(test_unknown_location): Add the new context argument to calls to
helper functions.
(test_bad_endpoints): Likewise.
* diagnostic-show-locus.c
(exploc_with_display_col::exploc_with_display_col): Support
tabstop parameter.
(layout_point::layout_point): Make use of class
exploc_with_display_col.
(layout_range::layout_range): Likewise.
(struct line_bounds): Clarify that the units are now always
display columns. Rename members accordingly. Add constructor.
(layout::print_source_line): Add support for tab expansion.
(make_range): Adapt to class layout_range changes.
(layout::maybe_add_location_range): Likewise.
(layout::layout): Adapt to class exploc_with_display_col changes.
(layout::calculate_x_offset_display): Support tabstop parameter.
(layout::print_annotation_line): Adapt to struct line_bounds changes.
(layout::print_line): Likewise.
(line_label::line_label): Add diagnostic_context argument.
(get_affected_range): Likewise.
(get_printed_columns): Likewise.
(layout::print_any_labels): Adapt to struct line_label changes.
(class correction): Add m_tabstop member.
(correction::correction): Add tabstop argument.
(correction::compute_display_cols): Use m_tabstop.
(class line_corrections): Add m_context member.
(line_corrections::line_corrections): Add diagnostic_context argument.
(line_corrections::add_hint): Use m_context to handle tabstops.
(layout::print_trailing_fixits): Adapt to class line_corrections
changes.
(test_layout_x_offset_display_utf8): Support tabstop parameter.
(test_layout_x_offset_display_tab): New selftest.
(test_one_liner_colorized_utf8): Likewise.
(test_tab_expansion): Likewise.
(test_diagnostic_show_locus_one_liner_utf8): Call the new tests.
(diagnostic_show_locus_c_tests): Likewise.
(test_overlapped_fixit_printing): Adapt to helper class and
function changes.
(test_overlapped_fixit_printing_utf8): Likewise.
(test_overlapped_fixit_printing_2): Likewise.
* diagnostic.h (enum diagnostics_column_unit): New enum.
(struct diagnostic_context): Add members for the new options.
(diagnostic_converted_column): Declare.
(json_from_expanded_location): Add new context argument.
* diagnostic.c (diagnostic_initialize): Initialize new members.
(diagnostic_converted_column): New function.
(maybe_line_and_column): Be willing to output a column of 0.
(diagnostic_get_location_text): Convert column number as per the new
options.
(diagnostic_report_current_module): Likewise.
(assert_location_text): Add origin and column_unit arguments for
testing the new functionality.
(test_diagnostic_get_location_text): Test the new functionality.
* doc/invoke.texi: Document the new options and behavior.
* input.h (location_compute_display_column): Add tabstop argument.
* input.c (location_compute_display_column): Likewise.
(test_cpp_utf8): Add selftests for tab expansion.
* tree-diagnostic-path.cc (default_tree_make_json_for_path): Pass the
new context argument to json_from_expanded_location().
libcpp/ChangeLog:
PR preprocessor/49973
PR other/86904
* include/cpplib.h (struct cpp_options): Removed support for -ftabstop,
which is now handled by diagnostic_context.
(class cpp_display_width_computation): New class.
(cpp_byte_column_to_display_column): Add optional tabstop argument.
(cpp_display_width): Likewise.
(cpp_display_column_to_byte_column): Likewise.
* charset.c
(cpp_display_width_computation::cpp_display_width_computation): New
function.
(cpp_display_width_computation::advance_display_cols): Likewise.
(compute_next_display_width): Removed and implemented this
functionality in a new function...
(cpp_display_width_computation::process_next_codepoint): ...here.
(cpp_byte_column_to_display_column): Added tabstop argument.
Reimplemented in terms of class cpp_display_width_computation.
(cpp_display_column_to_byte_column): Likewise.
* init.c (cpp_create_reader): Remove handling of -ftabstop, which is now
handled by diagnostic_context.
gcc/testsuite/ChangeLog:
PR preprocessor/49973
PR other/86904
* c-c++-common/Wmisleading-indentation-3.c: Adjust expected output
for new defaults.
* c-c++-common/Wmisleading-indentation.c: Likewise.
* c-c++-common/diagnostic-format-json-1.c: Likewise.
* c-c++-common/diagnostic-format-json-2.c: Likewise.
* c-c++-common/diagnostic-format-json-3.c: Likewise.
* c-c++-common/diagnostic-format-json-4.c: Likewise.
* c-c++-common/diagnostic-format-json-5.c: Likewise.
* c-c++-common/missing-close-symbol.c: Likewise.
* g++.dg/diagnostic/bad-binary-ops.C: Likewise.
* g++.dg/parse/error4.C: Likewise.
* g++.old-deja/g++.brendan/crash11.C: Likewise.
* g++.old-deja/g++.pt/overload2.C: Likewise.
* g++.old-deja/g++.robertl/eb109.C: Likewise.
* gcc.dg/analyzer/malloc-paths-9.c: Likewise.
* gcc.dg/bad-binary-ops.c: Likewise.
* gcc.dg/format/branch-1.c: Likewise.
* gcc.dg/format/pr79210.c: Likewise.
* gcc.dg/plugin/diagnostic-test-expressions-1.c: Likewise.
* gcc.dg/plugin/diagnostic-test-string-literals-1.c: Likewise.
* gcc.dg/redecl-4.c: Likewise.
* gfortran.dg/diagnostic-format-json-1.F90: Likewise.
* gfortran.dg/diagnostic-format-json-2.F90: Likewise.
* gfortran.dg/diagnostic-format-json-3.F90: Likewise.
* go.dg/arrayclear.go: Add a comment explaining why adding a
comment was necessary to work around a dejagnu bug.
* c-c++-common/diagnostic-units-1.c: New test.
* c-c++-common/diagnostic-units-2.c: New test.
* c-c++-common/diagnostic-units-3.c: New test.
* c-c++-common/diagnostic-units-4.c: New test.
* c-c++-common/diagnostic-units-5.c: New test.
* c-c++-common/diagnostic-units-6.c: New test.
* c-c++-common/diagnostic-units-7.c: New test.
* c-c++-common/diagnostic-units-8.c: New test.
Diffstat (limited to 'gcc/diagnostic-format-json.cc')
-rw-r--r-- | gcc/diagnostic-format-json.cc | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index 7bda5c4..465c42f 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "diagnostic.h" +#include "selftest-diagnostic.h" #include "diagnostic-metadata.h" #include "json.h" #include "selftest.h" @@ -43,21 +44,43 @@ static json::array *cur_children_array; /* Generate a JSON object for LOC. */ json::value * -json_from_expanded_location (location_t loc) +json_from_expanded_location (diagnostic_context *context, location_t loc) { expanded_location exploc = expand_location (loc); json::object *result = new json::object (); if (exploc.file) result->set ("file", new json::string (exploc.file)); result->set ("line", new json::integer_number (exploc.line)); - result->set ("column", new json::integer_number (exploc.column)); + + const enum diagnostics_column_unit orig_unit = context->column_unit; + struct + { + const char *name; + enum diagnostics_column_unit unit; + } column_fields[] = { + {"display-column", DIAGNOSTICS_COLUMN_UNIT_DISPLAY}, + {"byte-column", DIAGNOSTICS_COLUMN_UNIT_BYTE} + }; + int the_column = INT_MIN; + for (int i = 0; i != sizeof column_fields / sizeof (*column_fields); ++i) + { + context->column_unit = column_fields[i].unit; + const int col = diagnostic_converted_column (context, exploc); + result->set (column_fields[i].name, new json::integer_number (col)); + if (column_fields[i].unit == orig_unit) + the_column = col; + } + gcc_assert (the_column != INT_MIN); + result->set ("column", new json::integer_number (the_column)); + context->column_unit = orig_unit; return result; } /* Generate a JSON object for LOC_RANGE. */ static json::object * -json_from_location_range (const location_range *loc_range, unsigned range_idx) +json_from_location_range (diagnostic_context *context, + const location_range *loc_range, unsigned range_idx) { location_t caret_loc = get_pure_location (loc_range->m_loc); @@ -68,13 +91,13 @@ json_from_location_range (const location_range *loc_range, unsigned range_idx) location_t finish_loc = get_finish (loc_range->m_loc); json::object *result = new json::object (); - result->set ("caret", json_from_expanded_location (caret_loc)); + result->set ("caret", json_from_expanded_location (context, caret_loc)); if (start_loc != caret_loc && start_loc != UNKNOWN_LOCATION) - result->set ("start", json_from_expanded_location (start_loc)); + result->set ("start", json_from_expanded_location (context, start_loc)); if (finish_loc != caret_loc && finish_loc != UNKNOWN_LOCATION) - result->set ("finish", json_from_expanded_location (finish_loc)); + result->set ("finish", json_from_expanded_location (context, finish_loc)); if (loc_range->m_label) { @@ -91,14 +114,14 @@ json_from_location_range (const location_range *loc_range, unsigned range_idx) /* Generate a JSON object for HINT. */ static json::object * -json_from_fixit_hint (const fixit_hint *hint) +json_from_fixit_hint (diagnostic_context *context, const fixit_hint *hint) { json::object *fixit_obj = new json::object (); location_t start_loc = hint->get_start_loc (); - fixit_obj->set ("start", json_from_expanded_location (start_loc)); + fixit_obj->set ("start", json_from_expanded_location (context, start_loc)); location_t next_loc = hint->get_next_loc (); - fixit_obj->set ("next", json_from_expanded_location (next_loc)); + fixit_obj->set ("next", json_from_expanded_location (context, next_loc)); fixit_obj->set ("string", new json::string (hint->get_string ())); return fixit_obj; @@ -190,11 +213,13 @@ json_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic, else { /* Otherwise, make diag_obj be the top-level object within the group; - add a "children" array. */ + add a "children" array and record the column origin. */ toplevel_array->append (diag_obj); cur_group = diag_obj; cur_children_array = new json::array (); diag_obj->set ("children", cur_children_array); + diag_obj->set ("column-origin", + new json::integer_number (context->column_origin)); } const rich_location *richloc = diagnostic->richloc; @@ -205,7 +230,7 @@ json_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic, for (unsigned int i = 0; i < richloc->get_num_locations (); i++) { const location_range *loc_range = richloc->get_range (i); - json::object *loc_obj = json_from_location_range (loc_range, i); + json::object *loc_obj = json_from_location_range (context, loc_range, i); if (loc_obj) loc_array->append (loc_obj); } @@ -217,7 +242,7 @@ json_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic, for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++) { const fixit_hint *hint = richloc->get_fixit_hint (i); - json::object *fixit_obj = json_from_fixit_hint (hint); + json::object *fixit_obj = json_from_fixit_hint (context, hint); fixit_array->append (fixit_obj); } } @@ -320,7 +345,8 @@ namespace selftest { static void test_unknown_location () { - delete json_from_expanded_location (UNKNOWN_LOCATION); + test_diagnostic_context dc; + delete json_from_expanded_location (&dc, UNKNOWN_LOCATION); } /* Verify that we gracefully handle attempts to serialize bad @@ -338,7 +364,8 @@ test_bad_endpoints () loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET; loc_range.m_label = NULL; - json::object *obj = json_from_location_range (&loc_range, 0); + test_diagnostic_context dc; + json::object *obj = json_from_location_range (&dc, &loc_range, 0); /* We should have a "caret" value, but no "start" or "finish" values. */ ASSERT_TRUE (obj != NULL); ASSERT_TRUE (obj->get ("caret") != NULL); |