(root)/
gcc-13.2.0/
gcc/
gcc-rich-location.h
       1  /* Declarations relating to class gcc_rich_location
       2     Copyright (C) 2014-2023 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  #ifndef GCC_RICH_LOCATION_H
      21  #define GCC_RICH_LOCATION_H
      22  
      23  /* A gcc_rich_location is libcpp's rich_location with additional
      24     helper methods for working with gcc's types.  The class is not
      25     copyable or assignable because rich_location isn't. */
      26  
      27  class gcc_rich_location : public rich_location
      28  {
      29   public:
      30    /* Constructors.  */
      31  
      32    /* Constructing from a location.  */
      33    explicit gcc_rich_location (location_t loc, const range_label *label = NULL)
      34    : rich_location (line_table, loc, label)
      35    {
      36    }
      37  
      38    /* Methods for adding ranges via gcc entities.  */
      39    void
      40    add_expr (tree expr, range_label *label);
      41  
      42    void
      43    maybe_add_expr (tree t, range_label *label);
      44  
      45    void add_fixit_misspelled_id (location_t misspelled_token_loc,
      46  				tree hint_id);
      47  
      48    /* If LOC is within the spans of lines that will already be printed for
      49       this gcc_rich_location, then add it as a secondary location
      50       and return true.
      51  
      52       Otherwise return false.
      53  
      54       This allows for a diagnostic to compactly print secondary locations
      55       in one diagnostic when these are near enough the primary locations for
      56       diagnostics-show-locus.c to cope with them, and to fall back to
      57       printing them via a note otherwise e.g.:
      58  
      59  	gcc_rich_location richloc (primary_loc);
      60  	bool added secondary = richloc.add_location_if_nearby (secondary_loc);
      61  	error_at (&richloc, "main message");
      62  	if (!added secondary)
      63  	  inform (secondary_loc, "message for secondary");
      64  
      65       Implemented in diagnostic-show-locus.cc.  */
      66  
      67    bool add_location_if_nearby (location_t loc,
      68  			       bool restrict_to_current_line_spans = true,
      69  			       const range_label *label = NULL);
      70  
      71    /* Add a fix-it hint suggesting the insertion of CONTENT before
      72       INSERTION_POINT.
      73  
      74       Attempt to handle formatting: if INSERTION_POINT is the first thing on
      75       its line, and INDENT is sufficiently sane, then add CONTENT on its own
      76       line, using the indentation of INDENT.
      77       Otherwise, add CONTENT directly before INSERTION_POINT.
      78  
      79       For example, adding "CONTENT;" with the closing brace as the insertion
      80       point and using "INDENT;" for indentation:
      81  
      82         if ()
      83           {
      84             INDENT;
      85           }
      86  
      87       would lead to:
      88  
      89         if ()
      90           {
      91             INDENT;
      92             CONTENT;
      93           }
      94  
      95       but adding it to:
      96  
      97         if () {INDENT;}
      98  
      99       would lead to:
     100  
     101         if () {INDENT;CONTENT;}
     102    */
     103    void add_fixit_insert_formatted (const char *content,
     104  				   location_t insertion_point,
     105  				   location_t indent);
     106  };
     107  
     108  /* Concrete subclass of libcpp's range_label.
     109     Simple implementation using a string literal.  */
     110  
     111  class text_range_label : public range_label
     112  {
     113   public:
     114    text_range_label (const char *text) : m_text (text) {}
     115  
     116    label_text get_text (unsigned /*range_idx*/) const final override
     117    {
     118      return label_text::borrow (m_text);
     119    }
     120  
     121   private:
     122    const char *m_text;
     123  };
     124  
     125  /* Concrete subclass of libcpp's range_label for use in
     126     diagnostics involving mismatched types.
     127  
     128     Each frontend that uses this should supply its own implementation.
     129  
     130     Generate a label describing LABELLED_TYPE.  The frontend may use
     131     OTHER_TYPE where appropriate for highlighting the differences between
     132     the two types (analogous to C++'s use of %H and %I with
     133     template types).
     134  
     135     Either or both of LABELLED_TYPE and OTHER_TYPE may be NULL_TREE.
     136     If LABELLED_TYPE is NULL_TREE, then there is no label.
     137  
     138     For example, this rich_location could use two instances of
     139     range_label_for_type_mismatch:
     140  
     141        printf ("arg0: %i  arg1: %s arg2: %i",
     142                                 ^~
     143                                 |
     144                                 const char *
     145                100, 101, 102);
     146                     ~~~
     147                     |
     148                     int
     149  
     150     (a) the label for "%s" with LABELLED_TYPE for "const char*" and
     151     (b) the label for "101" with LABELLED TYPE for "int"
     152     where each one uses the other's type as OTHER_TYPE.  */
     153  
     154  class range_label_for_type_mismatch : public range_label
     155  {
     156   public:
     157    range_label_for_type_mismatch (tree labelled_type, tree other_type)
     158    : m_labelled_type (labelled_type), m_other_type (other_type)
     159    {
     160    }
     161  
     162    label_text get_text (unsigned range_idx) const override;
     163  
     164   protected:
     165    tree m_labelled_type;
     166    tree m_other_type;
     167  };
     168  
     169  /* Subclass of range_label for labelling the type of EXPR when reporting
     170     a type mismatch between EXPR and OTHER_EXPR.
     171     Either or both of EXPR and OTHER_EXPR could be NULL.  */
     172  
     173  class maybe_range_label_for_tree_type_mismatch : public range_label
     174  {
     175   public:
     176    maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr)
     177    : m_expr (expr), m_other_expr (other_expr)
     178    {
     179    }
     180  
     181    label_text get_text (unsigned range_idx) const final override;
     182  
     183   private:
     184    tree m_expr;
     185    tree m_other_expr;
     186  };
     187  
     188  class op_location_t;
     189  
     190  /* A subclass of rich_location for showing problems with binary operations.
     191  
     192     If enough location information is available, the ctor will make a
     193     3-location rich_location of the form:
     194  
     195       arg_0 op arg_1
     196       ~~~~~ ^~ ~~~~~
     197         |        |
     198         |        arg1 type
     199         arg0 type
     200  
     201     labelling the types of the arguments if SHOW_TYPES is true.
     202  
     203     Otherwise, it will fall back to a 1-location rich_location using the
     204     compound location within LOC:
     205  
     206       arg_0 op arg_1
     207       ~~~~~~^~~~~~~~
     208  
     209     for which we can't label the types.  */
     210  
     211  class binary_op_rich_location : public gcc_rich_location
     212  {
     213   public:
     214    binary_op_rich_location (const op_location_t &loc,
     215  			   tree arg0, tree arg1,
     216  			   bool show_types);
     217  
     218   private:
     219    static bool use_operator_loc_p (const op_location_t &loc,
     220  				  tree arg0, tree arg1);
     221  
     222    maybe_range_label_for_tree_type_mismatch m_label_for_arg0;
     223    maybe_range_label_for_tree_type_mismatch m_label_for_arg1;
     224  };
     225  
     226  #endif /* GCC_RICH_LOCATION_H */