1 /* Declarations relating to class gcc_rich_location 2 Copyright (C) 2014-2021 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) rich_location(line_table,loc,label)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.c. */ 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: text_range_label(const char * text)114 text_range_label (const char *text) : m_text (text) {} 115 get_text(unsigned)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: range_label_for_type_mismatch(tree labelled_type,tree other_type)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: maybe_range_label_for_tree_type_mismatch(tree expr,tree other_expr)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 */ 227