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