Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-diagnostic.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 /* Language-independent diagnostic subroutines for the GNU Compiler |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 Collection that are only for use in the compilers proper and not |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 the driver or other programs. |
131 | 4 Copyright (C) 1999-2018 Free Software Foundation, Inc. |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 This file is part of GCC. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 GCC is free software; you can redistribute it and/or modify it under |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 the terms of the GNU General Public License as published by the Free |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 Software Foundation; either version 3, or (at your option) any later |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 version. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 for more details. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 You should have received a copy of the GNU General Public License |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 along with GCC; see the file COPYING3. If not see |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 <http://www.gnu.org/licenses/>. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "config.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 #include "system.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 #include "coretypes.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 #include "tree.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 #include "diagnostic.h" |
111 | 27 #include "tree-pretty-print.h" |
28 #include "gimple-pretty-print.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 #include "tree-diagnostic.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
30 #include "langhooks.h" |
111 | 31 #include "intl.h" |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33 /* Prints out, if necessary, the name of the current function |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 that caused an error. Called from all error and warning functions. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35 void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 diagnostic_report_current_function (diagnostic_context *context, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37 diagnostic_info *diagnostic) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 { |
111 | 39 diagnostic_report_current_module (context, diagnostic_location (diagnostic)); |
40 lang_hooks.print_error_function (context, LOCATION_FILE (input_location), | |
41 diagnostic); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
42 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 |
111 | 44 static void |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 default_tree_diagnostic_starter (diagnostic_context *context, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 diagnostic_info *diagnostic) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 diagnostic_report_current_function (context, diagnostic); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
49 pp_set_prefix (context->printer, diagnostic_build_prefix (context, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
50 diagnostic)); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 } |
111 | 52 |
53 /* This is a pair made of a location and the line map it originated | |
54 from. It's used in the maybe_unwind_expanded_macro_loc function | |
55 below. */ | |
56 struct loc_map_pair | |
57 { | |
58 const line_map_macro *map; | |
59 source_location where; | |
60 }; | |
61 | |
62 | |
63 /* Unwind the different macro expansions that lead to the token which | |
64 location is WHERE and emit diagnostics showing the resulting | |
65 unwound macro expansion trace. Let's look at an example to see how | |
66 the trace looks like. Suppose we have this piece of code, | |
67 artificially annotated with the line numbers to increase | |
68 legibility: | |
69 | |
70 $ cat -n test.c | |
71 1 #define OPERATE(OPRD1, OPRT, OPRD2) \ | |
72 2 OPRD1 OPRT OPRD2; | |
73 3 | |
74 4 #define SHIFTL(A,B) \ | |
75 5 OPERATE (A,<<,B) | |
76 6 | |
77 7 #define MULT(A) \ | |
78 8 SHIFTL (A,1) | |
79 9 | |
80 10 void | |
81 11 g () | |
82 12 { | |
83 13 MULT (1.0);// 1.0 << 1; <-- so this is an error. | |
84 14 } | |
85 | |
86 Here is the diagnostic that we want the compiler to generate: | |
87 | |
88 test.c: In function ‘g’: | |
89 test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’) | |
90 test.c:2:9: note: in definition of macro 'OPERATE' | |
91 test.c:8:3: note: in expansion of macro 'SHIFTL' | |
92 test.c:13:3: note: in expansion of macro 'MULT' | |
93 | |
94 The part that goes from the third to the fifth line of this | |
95 diagnostic (the lines containing the 'note:' string) is called the | |
96 unwound macro expansion trace. That's the part generated by this | |
97 function. */ | |
98 | |
99 static void | |
100 maybe_unwind_expanded_macro_loc (diagnostic_context *context, | |
101 const diagnostic_info *diagnostic, | |
102 source_location where) | |
103 { | |
104 const struct line_map *map; | |
105 auto_vec<loc_map_pair> loc_vec; | |
106 unsigned ix; | |
107 loc_map_pair loc, *iter; | |
108 | |
109 map = linemap_lookup (line_table, where); | |
110 if (!linemap_macro_expansion_map_p (map)) | |
111 return; | |
112 | |
113 /* Let's unwind the macros that got expanded and led to the token | |
114 which location is WHERE. We are going to store these macros into | |
115 LOC_VEC, so that we can later walk it at our convenience to | |
116 display a somewhat meaningful trace of the macro expansion | |
117 history to the user. Note that the first macro of the trace | |
118 (which is OPERATE in the example above) is going to be stored at | |
119 the beginning of LOC_VEC. */ | |
120 | |
121 do | |
122 { | |
123 loc.where = where; | |
124 loc.map = linemap_check_macro (map); | |
125 | |
126 loc_vec.safe_push (loc); | |
127 | |
128 /* WHERE is the location of a token inside the expansion of a | |
129 macro. MAP is the map holding the locations of that macro | |
130 expansion. Let's get the location of the token inside the | |
131 context that triggered the expansion of this macro. | |
132 This is basically how we go "down" in the trace of macro | |
133 expansions that led to WHERE. */ | |
134 where = linemap_unwind_toward_expansion (line_table, where, &map); | |
135 } while (linemap_macro_expansion_map_p (map)); | |
136 | |
137 /* Now map is set to the map of the location in the source that | |
138 first triggered the macro expansion. This must be an ordinary map. */ | |
139 const line_map_ordinary *ord_map = linemap_check_ordinary (map); | |
140 | |
141 /* Walk LOC_VEC and print the macro expansion trace, unless the | |
142 first macro which expansion triggered this trace was expanded | |
143 inside a system header. */ | |
144 int saved_location_line = | |
145 expand_location_to_spelling_point (diagnostic_location (diagnostic)).line; | |
146 | |
147 if (!LINEMAP_SYSP (ord_map)) | |
148 FOR_EACH_VEC_ELT (loc_vec, ix, iter) | |
149 { | |
150 /* Sometimes, in the unwound macro expansion trace, we want to | |
151 print a part of the context that shows where, in the | |
152 definition of the relevant macro, is the token (we are | |
153 looking at) used. That is the case in the introductory | |
154 comment of this function, where we print: | |
155 | |
156 test.c:2:9: note: in definition of macro 'OPERATE'. | |
157 | |
158 We print that "macro definition context" because the | |
159 diagnostic line (emitted by the call to | |
160 pp_ouput_formatted_text in diagnostic_report_diagnostic): | |
161 | |
162 test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’) | |
163 | |
164 does not point into the definition of the macro where the | |
165 token '<<' (that is an argument to the function-like macro | |
166 OPERATE) is used. So we must "display" the line of that | |
167 macro definition context to the user somehow. | |
168 | |
169 A contrario, when the first interesting diagnostic line | |
170 points into the definition of the macro, we don't need to | |
171 display any line for that macro definition in the trace | |
172 anymore, otherwise it'd be redundant. */ | |
173 | |
174 /* Okay, now here is what we want. For each token resulting | |
175 from macro expansion we want to show: 1/ where in the | |
176 definition of the macro the token comes from; 2/ where the | |
177 macro got expanded. */ | |
178 | |
179 /* Resolve the location iter->where into the locus 1/ of the | |
180 comment above. */ | |
181 source_location resolved_def_loc = | |
182 linemap_resolve_location (line_table, iter->where, | |
183 LRK_MACRO_DEFINITION_LOCATION, NULL); | |
184 | |
185 /* Don't print trace for locations that are reserved or from | |
186 within a system header. */ | |
187 const line_map_ordinary *m = NULL; | |
188 source_location l = | |
189 linemap_resolve_location (line_table, resolved_def_loc, | |
190 LRK_SPELLING_LOCATION, &m); | |
191 if (l < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m)) | |
192 continue; | |
193 | |
194 /* We need to print the context of the macro definition only | |
195 when the locus of the first displayed diagnostic (displayed | |
196 before this trace) was inside the definition of the | |
197 macro. */ | |
198 int resolved_def_loc_line = SOURCE_LINE (m, l); | |
199 if (ix == 0 && saved_location_line != resolved_def_loc_line) | |
200 { | |
201 diagnostic_append_note (context, resolved_def_loc, | |
202 "in definition of macro %qs", | |
203 linemap_map_get_macro_name (iter->map)); | |
204 /* At this step, as we've printed the context of the macro | |
205 definition, we don't want to print the context of its | |
206 expansion, otherwise, it'd be redundant. */ | |
207 continue; | |
208 } | |
209 | |
210 /* Resolve the location of the expansion point of the macro | |
211 which expansion gave the token represented by def_loc. | |
212 This is the locus 2/ of the earlier comment. */ | |
213 source_location resolved_exp_loc = | |
214 linemap_resolve_location (line_table, | |
215 MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map), | |
216 LRK_MACRO_DEFINITION_LOCATION, NULL); | |
217 | |
218 diagnostic_append_note (context, resolved_exp_loc, | |
219 "in expansion of macro %qs", | |
220 linemap_map_get_macro_name (iter->map)); | |
221 } | |
222 } | |
223 | |
224 /* This is a diagnostic finalizer implementation that is aware of | |
225 virtual locations produced by libcpp. | |
226 | |
227 It has to be called by the diagnostic finalizer of front ends that | |
228 uses libcpp and wish to get diagnostics involving tokens resulting | |
229 from macro expansion. | |
230 | |
231 For a given location, if said location belongs to a token | |
232 resulting from a macro expansion, this starter prints the context | |
233 of the token. E.g, for multiply nested macro expansion, it | |
234 unwinds the nested macro expansions and prints them in a manner | |
235 that is similar to what is done for function call stacks, or | |
236 template instantiation contexts. */ | |
237 void | |
238 virt_loc_aware_diagnostic_finalizer (diagnostic_context *context, | |
239 diagnostic_info *diagnostic) | |
240 { | |
241 maybe_unwind_expanded_macro_loc (context, diagnostic, | |
242 diagnostic_location (diagnostic)); | |
243 } | |
244 | |
245 /* Default tree printer. Handles declarations only. */ | |
246 bool | |
247 default_tree_printer (pretty_printer *pp, text_info *text, const char *spec, | |
248 int precision, bool wide, bool set_locus, bool hash, | |
131 | 249 bool *, const char **) |
111 | 250 { |
251 tree t; | |
252 | |
253 /* FUTURE: %+x should set the locus. */ | |
254 if (precision != 0 || wide || hash) | |
255 return false; | |
256 | |
257 switch (*spec) | |
258 { | |
259 case 'E': | |
260 t = va_arg (*text->args_ptr, tree); | |
261 if (TREE_CODE (t) == IDENTIFIER_NODE) | |
262 { | |
263 pp_identifier (pp, IDENTIFIER_POINTER (t)); | |
264 return true; | |
265 } | |
266 break; | |
267 | |
268 case 'D': | |
269 t = va_arg (*text->args_ptr, tree); | |
270 if (VAR_P (t) && DECL_HAS_DEBUG_EXPR_P (t)) | |
271 t = DECL_DEBUG_EXPR (t); | |
272 break; | |
273 | |
274 case 'F': | |
275 case 'T': | |
276 t = va_arg (*text->args_ptr, tree); | |
277 break; | |
278 | |
279 case 'G': | |
280 percent_G_format (text); | |
281 return true; | |
282 | |
283 case 'K': | |
284 t = va_arg (*text->args_ptr, tree); | |
131 | 285 percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t)); |
111 | 286 return true; |
287 | |
288 default: | |
289 return false; | |
290 } | |
291 | |
292 if (set_locus) | |
131 | 293 text->set_location (0, DECL_SOURCE_LOCATION (t), SHOW_RANGE_WITH_CARET); |
111 | 294 |
295 if (DECL_P (t)) | |
296 { | |
297 const char *n = DECL_NAME (t) | |
298 ? identifier_to_locale (lang_hooks.decl_printable_name (t, 2)) | |
299 : _("<anonymous>"); | |
300 pp_string (pp, n); | |
301 } | |
302 else | |
303 dump_generic_node (pp, t, 0, TDF_SLIM, 0); | |
304 | |
305 return true; | |
306 } | |
307 | |
308 /* Sets CONTEXT to use language independent diagnostics. */ | |
309 void | |
310 tree_diagnostics_defaults (diagnostic_context *context) | |
311 { | |
312 diagnostic_starter (context) = default_tree_diagnostic_starter; | |
313 diagnostic_finalizer (context) = default_diagnostic_finalizer; | |
314 diagnostic_format_decoder (context) = default_tree_printer; | |
315 } |