Mercurial > hg > CbC > CbC_gcc
diff gcc/gcc-rich-location.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/gcc-rich-location.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/gcc-rich-location.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Implementation of gcc_rich_location class - Copyright (C) 2014-2017 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -38,24 +38,26 @@ #include "cpplib.h" #include "diagnostic.h" -/* Add a range to the rich_location, covering expression EXPR. */ +/* Add a range to the rich_location, covering expression EXPR, + using LABEL if non-NULL. */ void -gcc_rich_location::add_expr (tree expr) +gcc_rich_location::add_expr (tree expr, range_label *label) { gcc_assert (expr); if (CAN_HAVE_RANGE_P (expr)) - add_range (EXPR_LOCATION (expr), false); + add_range (EXPR_LOCATION (expr), SHOW_RANGE_WITHOUT_CARET, label); } -/* If T is an expression, add a range for it to the rich_location. */ +/* If T is an expression, add a range for it to the rich_location, + using LABEL if non-NULL. */ void -gcc_rich_location::maybe_add_expr (tree t) +gcc_rich_location::maybe_add_expr (tree t, range_label *label) { if (EXPR_P (t)) - add_expr (t); + add_expr (t, label); } /* Add a fixit hint suggesting replacing the range at MISSPELLED_TOKEN_LOC @@ -69,3 +71,114 @@ add_fixit_replace (misspelled_token_loc, IDENTIFIER_POINTER (hint_id)); } + +/* Return true if there is nothing on LOC's line before LOC. */ + +static bool +blank_line_before_p (location_t loc) +{ + expanded_location exploc = expand_location (loc); + char_span line = location_get_source_line (exploc.file, exploc.line); + if (!line) + return false; + if (line.length () < (size_t)exploc.column) + return false; + /* Columns are 1-based. */ + for (int column = 1; column < exploc.column; ++column) + if (!ISSPACE (line[column - 1])) + return false; + return true; +} + +/* Subroutine of gcc_rich_location::add_fixit_insert_formatted. + Return true if we should add the content on its own line, + false otherwise. + If true is returned then *OUT_START_OF_LINE is written to. */ + +static bool +use_new_line (location_t insertion_point, location_t indent, + location_t *out_start_of_line) +{ + if (indent == UNKNOWN_LOCATION) + return false; + const line_map *indent_map = linemap_lookup (line_table, indent); + if (linemap_macro_expansion_map_p (indent_map)) + return false; + + if (!blank_line_before_p (insertion_point)) + return false; + + /* Locate the start of the line containing INSERTION_POINT. */ + const line_map *insertion_point_map + = linemap_lookup (line_table, insertion_point); + if (linemap_macro_expansion_map_p (insertion_point_map)) + return false; + const line_map_ordinary *ordmap + = linemap_check_ordinary (insertion_point_map); + expanded_location exploc_insertion_point = expand_location (insertion_point); + location_t start_of_line + = linemap_position_for_line_and_column (line_table, ordmap, + exploc_insertion_point.line, 1); + *out_start_of_line = start_of_line; + return true; +} + +/* Add a fix-it hint suggesting the insertion of CONTENT before + INSERTION_POINT. + + Attempt to handle formatting: if INSERTION_POINT is the first thing on + its line, and INDENT is sufficiently sane, then add CONTENT on its own + line, using the indentation of INDENT. + Otherwise, add CONTENT directly before INSERTION_POINT. + + For example, adding "CONTENT;" with the closing brace as the insertion + point and "INDENT;" as the indentation point: + + if () + { + INDENT; + } + + would lead to: + + if () + { + INDENT; + CONTENT; + } + + but adding it to: + + if () {INDENT;} + + would lead to: + + if () {INDENT;CONTENT;} +*/ + +void +gcc_rich_location::add_fixit_insert_formatted (const char *content, + location_t insertion_point, + location_t indent) +{ + location_t start_of_line; + if (use_new_line (insertion_point, indent, &start_of_line)) + { + /* Add CONTENT on its own line, using the indentation of INDENT. */ + + /* Generate an insertion string, indenting by the amount INDENT + was indented. */ + int indent_column = LOCATION_COLUMN (get_start (indent)); + pretty_printer tmp_pp; + pretty_printer *pp = &tmp_pp; + /* Columns are 1-based. */ + for (int column = 1; column < indent_column; ++column) + pp_space (pp); + pp_string (pp, content); + pp_newline (pp); + + add_fixit_insert_before (start_of_line, pp_formatted_text (pp)); + } + else + add_fixit_insert_before (insertion_point, content); +}