Line data Source code
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 28928 : class gcc_rich_location : public rich_location 28 : { 29 : public: 30 : /* Constructors. */ 31 : 32 : /* Constructing from a location. */ 33 28718 : explicit gcc_rich_location (location_t loc, const range_label *label = NULL) 34 28718 : : 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 3138 : class range_label_for_type_mismatch : public range_label 155 : { 156 : public: 157 3138 : range_label_for_type_mismatch (tree labelled_type, tree other_type) 158 3138 : : 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 210 : 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 210 : 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 */