aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostic-format-json.cc
diff options
context:
space:
mode:
authorLewis Hyatt <lhyatt@gmail.com>2020-07-14 12:05:56 -0400
committerLewis Hyatt <lhyatt@gmail.com>2020-07-14 12:05:56 -0400
commit004bb936d6d5f177af26ad4905595e843d5665a5 (patch)
treefe3ee343abc249a14509943f4e731f8fb73f6206 /gcc/diagnostic-format-json.cc
parent5f809982e8e05c39029431363e08759d6c750f0e (diff)
downloadgcc-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.cc55
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);