1*e4b17023SJohn Marino /* Language-independent diagnostic subroutines for the GNU Compiler
2*e4b17023SJohn Marino Collection that are only for use in the compilers proper and not
3*e4b17023SJohn Marino the driver or other programs.
4*e4b17023SJohn Marino Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5*e4b17023SJohn Marino 2009, 2010 Free Software Foundation, Inc.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino This file is part of GCC.
8*e4b17023SJohn Marino
9*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
10*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
11*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
12*e4b17023SJohn Marino version.
13*e4b17023SJohn Marino
14*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
16*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17*e4b17023SJohn Marino for more details.
18*e4b17023SJohn Marino
19*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
21*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
22*e4b17023SJohn Marino
23*e4b17023SJohn Marino #include "config.h"
24*e4b17023SJohn Marino #include "system.h"
25*e4b17023SJohn Marino #include "coretypes.h"
26*e4b17023SJohn Marino #include "tree.h"
27*e4b17023SJohn Marino #include "diagnostic.h"
28*e4b17023SJohn Marino #include "tree-diagnostic.h"
29*e4b17023SJohn Marino #include "langhooks.h"
30*e4b17023SJohn Marino #include "langhooks-def.h"
31*e4b17023SJohn Marino #include "vec.h"
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino /* Prints out, if necessary, the name of the current function
34*e4b17023SJohn Marino that caused an error. Called from all error and warning functions. */
35*e4b17023SJohn Marino void
diagnostic_report_current_function(diagnostic_context * context,diagnostic_info * diagnostic)36*e4b17023SJohn Marino diagnostic_report_current_function (diagnostic_context *context,
37*e4b17023SJohn Marino diagnostic_info *diagnostic)
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino diagnostic_report_current_module (context, diagnostic->location);
40*e4b17023SJohn Marino lang_hooks.print_error_function (context, input_filename, diagnostic);
41*e4b17023SJohn Marino }
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino void
default_tree_diagnostic_starter(diagnostic_context * context,diagnostic_info * diagnostic)44*e4b17023SJohn Marino default_tree_diagnostic_starter (diagnostic_context *context,
45*e4b17023SJohn Marino diagnostic_info *diagnostic)
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino diagnostic_report_current_function (context, diagnostic);
48*e4b17023SJohn Marino pp_set_prefix (context->printer, diagnostic_build_prefix (context,
49*e4b17023SJohn Marino diagnostic));
50*e4b17023SJohn Marino }
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino /* This is a pair made of a location and the line map it originated
53*e4b17023SJohn Marino from. It's used in the maybe_unwind_expanded_macro_loc function
54*e4b17023SJohn Marino below. */
55*e4b17023SJohn Marino typedef struct
56*e4b17023SJohn Marino {
57*e4b17023SJohn Marino const struct line_map *map;
58*e4b17023SJohn Marino source_location where;
59*e4b17023SJohn Marino } loc_map_pair;
60*e4b17023SJohn Marino
61*e4b17023SJohn Marino DEF_VEC_O (loc_map_pair);
62*e4b17023SJohn Marino DEF_VEC_ALLOC_O (loc_map_pair, heap);
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino /* Unwind the different macro expansions that lead to the token which
65*e4b17023SJohn Marino location is WHERE and emit diagnostics showing the resulting
66*e4b17023SJohn Marino unwound macro expansion trace. Let's look at an example to see how
67*e4b17023SJohn Marino the trace looks like. Suppose we have this piece of code,
68*e4b17023SJohn Marino artificially annotated with the line numbers to increase
69*e4b17023SJohn Marino legibility:
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino $ cat -n test.c
72*e4b17023SJohn Marino 1 #define OPERATE(OPRD1, OPRT, OPRD2) \
73*e4b17023SJohn Marino 2 OPRD1 OPRT OPRD2;
74*e4b17023SJohn Marino 3
75*e4b17023SJohn Marino 4 #define SHIFTL(A,B) \
76*e4b17023SJohn Marino 5 OPERATE (A,<<,B)
77*e4b17023SJohn Marino 6
78*e4b17023SJohn Marino 7 #define MULT(A) \
79*e4b17023SJohn Marino 8 SHIFTL (A,1)
80*e4b17023SJohn Marino 9
81*e4b17023SJohn Marino 10 void
82*e4b17023SJohn Marino 11 g ()
83*e4b17023SJohn Marino 12 {
84*e4b17023SJohn Marino 13 MULT (1.0);// 1.0 << 1; <-- so this is an error.
85*e4b17023SJohn Marino 14 }
86*e4b17023SJohn Marino
87*e4b17023SJohn Marino Here is the diagnostic that we want the compiler to generate:
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino test.c: In function 'g':
90*e4b17023SJohn Marino test.c:5:14: error: invalid operands to binary << (have 'double' and 'int')
91*e4b17023SJohn Marino test.c:2:9: note: in expansion of macro 'OPERATE'
92*e4b17023SJohn Marino test.c:5:3: note: expanded from here
93*e4b17023SJohn Marino test.c:5:14: note: in expansion of macro 'SHIFTL'
94*e4b17023SJohn Marino test.c:8:3: note: expanded from here
95*e4b17023SJohn Marino test.c:8:3: note: in expansion of macro 'MULT2'
96*e4b17023SJohn Marino test.c:13:3: note: expanded from here
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino The part that goes from the third to the eighth line of this
99*e4b17023SJohn Marino diagnostic (the lines containing the 'note:' string) is called the
100*e4b17023SJohn Marino unwound macro expansion trace. That's the part generated by this
101*e4b17023SJohn Marino function.
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino If FIRST_EXP_POINT_MAP is non-null, *FIRST_EXP_POINT_MAP is set to
104*e4b17023SJohn Marino the map of the location in the source that first triggered the
105*e4b17023SJohn Marino macro expansion. This must be an ordinary map. */
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino static void
maybe_unwind_expanded_macro_loc(diagnostic_context * context,diagnostic_info * diagnostic,source_location where,const struct line_map ** first_exp_point_map)108*e4b17023SJohn Marino maybe_unwind_expanded_macro_loc (diagnostic_context *context,
109*e4b17023SJohn Marino diagnostic_info *diagnostic,
110*e4b17023SJohn Marino source_location where,
111*e4b17023SJohn Marino const struct line_map **first_exp_point_map)
112*e4b17023SJohn Marino {
113*e4b17023SJohn Marino const struct line_map *map;
114*e4b17023SJohn Marino VEC(loc_map_pair,heap) *loc_vec = NULL;
115*e4b17023SJohn Marino unsigned ix;
116*e4b17023SJohn Marino loc_map_pair loc, *iter;
117*e4b17023SJohn Marino
118*e4b17023SJohn Marino map = linemap_lookup (line_table, where);
119*e4b17023SJohn Marino if (!linemap_macro_expansion_map_p (map))
120*e4b17023SJohn Marino return;
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino /* Let's unwind the macros that got expanded and led to the token
123*e4b17023SJohn Marino which location is WHERE. We are going to store these macros into
124*e4b17023SJohn Marino LOC_VEC, so that we can later walk it at our convenience to
125*e4b17023SJohn Marino display a somewhat meaningful trace of the macro expansion
126*e4b17023SJohn Marino history to the user. Note that the first macro of the trace
127*e4b17023SJohn Marino (which is OPERATE in the example above) is going to be stored at
128*e4b17023SJohn Marino the beginning of LOC_VEC. */
129*e4b17023SJohn Marino
130*e4b17023SJohn Marino do
131*e4b17023SJohn Marino {
132*e4b17023SJohn Marino loc.where = where;
133*e4b17023SJohn Marino loc.map = map;
134*e4b17023SJohn Marino
135*e4b17023SJohn Marino VEC_safe_push (loc_map_pair, heap, loc_vec, &loc);
136*e4b17023SJohn Marino
137*e4b17023SJohn Marino /* WHERE is the location of a token inside the expansion of a
138*e4b17023SJohn Marino macro. MAP is the map holding the locations of that macro
139*e4b17023SJohn Marino expansion. Let's get the location of the token inside the
140*e4b17023SJohn Marino context that triggered the expansion of this macro.
141*e4b17023SJohn Marino This is basically how we go "down" in the trace of macro
142*e4b17023SJohn Marino expansions that led to WHERE. */
143*e4b17023SJohn Marino where = linemap_unwind_toward_expansion (line_table, where, &map);
144*e4b17023SJohn Marino } while (linemap_macro_expansion_map_p (map));
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino if (first_exp_point_map)
147*e4b17023SJohn Marino *first_exp_point_map = map;
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /* Walk LOC_VEC and print the macro expansion trace, unless the
150*e4b17023SJohn Marino first macro which expansion triggered this trace was expanded
151*e4b17023SJohn Marino inside a system header. */
152*e4b17023SJohn Marino if (!LINEMAP_SYSP (map))
153*e4b17023SJohn Marino FOR_EACH_VEC_ELT (loc_map_pair, loc_vec, ix, iter)
154*e4b17023SJohn Marino {
155*e4b17023SJohn Marino source_location resolved_def_loc = 0, resolved_exp_loc = 0;
156*e4b17023SJohn Marino diagnostic_t saved_kind;
157*e4b17023SJohn Marino const char *saved_prefix;
158*e4b17023SJohn Marino source_location saved_location;
159*e4b17023SJohn Marino
160*e4b17023SJohn Marino /* Okay, now here is what we want. For each token resulting
161*e4b17023SJohn Marino from macro expansion we want to show: 1/ where in the
162*e4b17023SJohn Marino definition of the macro the token comes from; 2/ where the
163*e4b17023SJohn Marino macro got expanded. */
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino /* Resolve the location iter->where into the locus 1/ of the
166*e4b17023SJohn Marino comment above. */
167*e4b17023SJohn Marino resolved_def_loc =
168*e4b17023SJohn Marino linemap_resolve_location (line_table, iter->where,
169*e4b17023SJohn Marino LRK_MACRO_DEFINITION_LOCATION, NULL);
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino /* Resolve the location of the expansion point of the macro
172*e4b17023SJohn Marino which expansion gave the token represented by def_loc.
173*e4b17023SJohn Marino This is the locus 2/ of the earlier comment. */
174*e4b17023SJohn Marino resolved_exp_loc =
175*e4b17023SJohn Marino linemap_resolve_location (line_table,
176*e4b17023SJohn Marino MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map),
177*e4b17023SJohn Marino LRK_MACRO_DEFINITION_LOCATION, NULL);
178*e4b17023SJohn Marino
179*e4b17023SJohn Marino saved_kind = diagnostic->kind;
180*e4b17023SJohn Marino saved_prefix = context->printer->prefix;
181*e4b17023SJohn Marino saved_location = diagnostic->location;
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino diagnostic->kind = DK_NOTE;
184*e4b17023SJohn Marino diagnostic->location = resolved_def_loc;
185*e4b17023SJohn Marino pp_base_set_prefix (context->printer,
186*e4b17023SJohn Marino diagnostic_build_prefix (context,
187*e4b17023SJohn Marino diagnostic));
188*e4b17023SJohn Marino pp_newline (context->printer);
189*e4b17023SJohn Marino pp_printf (context->printer, "in expansion of macro '%s'",
190*e4b17023SJohn Marino linemap_map_get_macro_name (iter->map));
191*e4b17023SJohn Marino pp_destroy_prefix (context->printer);
192*e4b17023SJohn Marino
193*e4b17023SJohn Marino diagnostic->location = resolved_exp_loc;
194*e4b17023SJohn Marino pp_base_set_prefix (context->printer,
195*e4b17023SJohn Marino diagnostic_build_prefix (context,
196*e4b17023SJohn Marino diagnostic));
197*e4b17023SJohn Marino pp_newline (context->printer);
198*e4b17023SJohn Marino pp_printf (context->printer, "expanded from here");
199*e4b17023SJohn Marino pp_destroy_prefix (context->printer);
200*e4b17023SJohn Marino
201*e4b17023SJohn Marino diagnostic->kind = saved_kind;
202*e4b17023SJohn Marino diagnostic->location = saved_location;
203*e4b17023SJohn Marino context->printer->prefix = saved_prefix;
204*e4b17023SJohn Marino }
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino VEC_free (loc_map_pair, heap, loc_vec);
207*e4b17023SJohn Marino }
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino /* This is a diagnostic finalizer implementation that is aware of
210*e4b17023SJohn Marino virtual locations produced by libcpp.
211*e4b17023SJohn Marino
212*e4b17023SJohn Marino It has to be called by the diagnostic finalizer of front ends that
213*e4b17023SJohn Marino uses libcpp and wish to get diagnostics involving tokens resulting
214*e4b17023SJohn Marino from macro expansion.
215*e4b17023SJohn Marino
216*e4b17023SJohn Marino For a given location, if said location belongs to a token
217*e4b17023SJohn Marino resulting from a macro expansion, this starter prints the context
218*e4b17023SJohn Marino of the token. E.g, for multiply nested macro expansion, it
219*e4b17023SJohn Marino unwinds the nested macro expansions and prints them in a manner
220*e4b17023SJohn Marino that is similar to what is done for function call stacks, or
221*e4b17023SJohn Marino template instantiation contexts. */
222*e4b17023SJohn Marino void
virt_loc_aware_diagnostic_finalizer(diagnostic_context * context,diagnostic_info * diagnostic)223*e4b17023SJohn Marino virt_loc_aware_diagnostic_finalizer (diagnostic_context *context,
224*e4b17023SJohn Marino diagnostic_info *diagnostic)
225*e4b17023SJohn Marino {
226*e4b17023SJohn Marino maybe_unwind_expanded_macro_loc (context, diagnostic,
227*e4b17023SJohn Marino diagnostic->location,
228*e4b17023SJohn Marino NULL);
229*e4b17023SJohn Marino }
230