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