LCOV - code coverage report
Current view: top level - gcc - gcc-rich-location.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 50 50
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 6 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Implementation of gcc_rich_location class
       2              :    Copyright (C) 2014-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "tm.h"
      24              : #include "rtl.h"
      25              : #include "hash-set.h"
      26              : #include "vec.h"
      27              : #include "input.h"
      28              : #include "alias.h"
      29              : #include "symtab.h"
      30              : #include "inchash.h"
      31              : #include "tree-core.h"
      32              : #include "tree.h"
      33              : #include "diagnostic-core.h"
      34              : #include "gcc-rich-location.h"
      35              : #include "print-tree.h"
      36              : #include "pretty-print.h"
      37              : #include "intl.h"
      38              : #include "cpplib.h"
      39              : #include "diagnostic.h"
      40              : #include "diagnostics/file-cache.h"
      41              : 
      42              : /* Add a range to the rich_location, covering expression EXPR,
      43              :    using LABEL if non-NULL. */
      44              : 
      45              : void
      46         1081 : gcc_rich_location::add_expr (tree expr,
      47              :                              range_label *label,
      48              :                              const char *highlight_color)
      49              : {
      50         1081 :   gcc_assert (expr);
      51              : 
      52         1081 :   if (CAN_HAVE_RANGE_P (expr))
      53         1081 :     add_range (EXPR_LOCATION (expr), SHOW_RANGE_WITHOUT_CARET, label,
      54              :                highlight_color);
      55         1081 : }
      56              : 
      57              : /* If T is an expression, add a range for it to the rich_location,
      58              :    using LABEL if non-NULL. */
      59              : 
      60              : void
      61         1730 : gcc_rich_location::maybe_add_expr (tree t, range_label *label,
      62              :                                    const char *highlight_color)
      63              : {
      64         1730 :   if (EXPR_P (t))
      65         1073 :     add_expr (t, label, highlight_color);
      66         1730 : }
      67              : 
      68              : /* Add a fixit hint suggesting replacing the range at MISSPELLED_TOKEN_LOC
      69              :    with the identifier HINT_ID.  */
      70              : 
      71              : void
      72           67 : gcc_rich_location::add_fixit_misspelled_id (location_t misspelled_token_loc,
      73              :                                             tree hint_id)
      74              : {
      75           67 :   gcc_assert (TREE_CODE (hint_id) == IDENTIFIER_NODE);
      76              : 
      77           67 :   add_fixit_replace (misspelled_token_loc, IDENTIFIER_POINTER (hint_id));
      78           67 : }
      79              : 
      80              : /* Return true if there is nothing on LOC's line before LOC.  */
      81              : 
      82              : static bool
      83           11 : blank_line_before_p (diagnostics::file_cache &fc,
      84              :                      location_t loc)
      85              : {
      86           11 :   expanded_location exploc = expand_location (loc);
      87           11 :   diagnostics::char_span line = fc.get_source_line (exploc.file, exploc.line);
      88           11 :   if (!line)
      89              :     return false;
      90           11 :   if (line.length () < (size_t)exploc.column)
      91              :     return false;
      92              :   /* Columns are 1-based.  */
      93           31 :   for (int column = 1; column < exploc.column; ++column)
      94           21 :     if (!ISSPACE (line[column - 1]))
      95              :       return false;
      96              :   return true;
      97              : }
      98              : 
      99              : /* Subroutine of gcc_rich_location::add_fixit_insert_formatted.
     100              :    Return true if we should add the content on its own line,
     101              :    false otherwise.
     102              :    If true is returned then *OUT_START_OF_LINE is written to.  */
     103              : 
     104              : static bool
     105           20 : use_new_line (diagnostics::file_cache &fc,
     106              :               location_t insertion_point, location_t indent,
     107              :               location_t *out_start_of_line)
     108              : {
     109           20 :   if (indent == UNKNOWN_LOCATION)
     110              :     return false;
     111           11 :   const line_map *indent_map = linemap_lookup (line_table, indent);
     112           11 :   if (linemap_macro_expansion_map_p (indent_map))
     113              :     return false;
     114              : 
     115           11 :   if (!blank_line_before_p (fc, insertion_point))
     116              :     return false;
     117              : 
     118              :   /* Locate the start of the line containing INSERTION_POINT.  */
     119           10 :   const line_map *insertion_point_map
     120           10 :     = linemap_lookup (line_table, insertion_point);
     121           10 :   if (linemap_macro_expansion_map_p (insertion_point_map))
     122              :     return false;
     123           10 :   const line_map_ordinary *ordmap
     124           10 :     = linemap_check_ordinary (insertion_point_map);
     125           10 :   expanded_location exploc_insertion_point = expand_location (insertion_point);
     126           10 :   location_t start_of_line
     127           20 :     = linemap_position_for_line_and_column (line_table, ordmap,
     128           10 :                                             exploc_insertion_point.line, 1);
     129           10 :   *out_start_of_line = start_of_line;
     130           10 :   return true;
     131              : }
     132              : 
     133              : /* Add a fix-it hint suggesting the insertion of CONTENT before
     134              :    INSERTION_POINT.
     135              : 
     136              :    Attempt to handle formatting: if INSERTION_POINT is the first thing on
     137              :    its line, and INDENT is sufficiently sane, then add CONTENT on its own
     138              :    line, using the indentation of INDENT.
     139              :    Otherwise, add CONTENT directly before INSERTION_POINT.
     140              : 
     141              :    For example, adding "CONTENT;" with the closing brace as the insertion
     142              :    point and "INDENT;" as the indentation point:
     143              : 
     144              :    if ()
     145              :      {
     146              :        INDENT;
     147              :      }
     148              : 
     149              :   would lead to:
     150              : 
     151              :    if ()
     152              :      {
     153              :        INDENT;
     154              :        CONTENT;
     155              :      }
     156              : 
     157              :   but adding it to:
     158              : 
     159              :     if () {INDENT;}
     160              : 
     161              :   would lead to:
     162              : 
     163              :     if () {INDENT;CONTENT;}
     164              : */
     165              : 
     166              : void
     167           20 : gcc_rich_location::add_fixit_insert_formatted (const char *content,
     168              :                                                location_t insertion_point,
     169              :                                                location_t indent)
     170              : {
     171           20 :   location_t start_of_line;
     172           20 :   if (use_new_line (global_dc->get_file_cache (),
     173              :                     insertion_point, indent, &start_of_line))
     174              :     {
     175              :       /* Add CONTENT on its own line, using the indentation of INDENT.  */
     176              : 
     177              :       /* Generate an insertion string, indenting by the amount INDENT
     178              :          was indented.  */
     179           10 :       int indent_column = LOCATION_COLUMN (get_start (indent));
     180           10 :       pretty_printer tmp_pp;
     181           10 :       pretty_printer *pp = &tmp_pp;
     182              :       /* Columns are 1-based.  */
     183           48 :       for (int column = 1; column < indent_column; ++column)
     184           38 :         pp_space (pp);
     185           10 :       pp_string (pp, content);
     186           10 :       pp_newline (pp);
     187              : 
     188           10 :       add_fixit_insert_before (start_of_line, pp_formatted_text (pp));
     189           10 :     }
     190              :   else
     191           10 :     add_fixit_insert_before (insertion_point, content);
     192           20 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.