]>
Commit | Line | Data |
---|---|---|
8d08fdba MS |
1 | /* Call-backs for C++ error reporting. |
2 | This code is non-reentrant. | |
d479d37f | 3 | Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, |
e146f815 | 4 | 2003, 2004 Free Software Foundation, Inc. |
f5adbb8d | 5 | This file is part of GCC. |
8d08fdba | 6 | |
f5adbb8d | 7 | GCC is free software; you can redistribute it and/or modify |
8d08fdba MS |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
f5adbb8d | 12 | GCC is distributed in the hope that it will be useful, |
8d08fdba MS |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
f5adbb8d | 18 | along with GCC; see the file COPYING. If not, write to |
e9fa0c7c RK |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
8d08fdba MS |
21 | |
22 | #include "config.h" | |
8d052bc7 | 23 | #include "system.h" |
4977bab6 ZW |
24 | #include "coretypes.h" |
25 | #include "tm.h" | |
8d08fdba MS |
26 | #include "tree.h" |
27 | #include "cp-tree.h" | |
a1bda5f1 | 28 | #include "real.h" |
54f92bfb | 29 | #include "toplev.h" |
749ced52 | 30 | #include "flags.h" |
cb753e49 | 31 | #include "diagnostic.h" |
7cb32822 | 32 | #include "langhooks-def.h" |
e1a4dd13 | 33 | #include "cxx-pretty-print.h" |
8d08fdba | 34 | |
a1066c99 GDR |
35 | enum pad { none, before, after }; |
36 | ||
b6fe0bb8 GDR |
37 | #define pp_template_argument_list_start(PP) \ |
38 | pp_non_consecutive_character (PP, '<') | |
39 | #define pp_template_argument_list_end(PP) \ | |
40 | pp_non_consecutive_character (PP, '>') | |
41 | #define pp_separate_with_comma(PP) pp_string (PP, ", ") | |
a1066c99 | 42 | |
99885b3f GDR |
43 | /* The global buffer where we dump everything. It is there only for |
44 | transitional purpose. It is expected, in the near future, to be | |
45 | completely removed. */ | |
e1a4dd13 | 46 | static cxx_pretty_printer scratch_pretty_printer; |
b6fe0bb8 | 47 | #define cxx_pp (&scratch_pretty_printer) |
0aafb128 | 48 | |
b34c06e3 | 49 | # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T))) |
8d08fdba | 50 | |
99885b3f GDR |
51 | #define reinit_global_formatting_buffer() \ |
52 | output_clear_message_text (scratch_buffer) | |
53 | ||
3f8548e7 | 54 | static const char *args_to_string (tree, int); |
4e3f84b7 GDR |
55 | static const char *assop_to_string (enum tree_code); |
56 | static const char *code_to_string (enum tree_code); | |
3f8548e7 GDR |
57 | static const char *cv_to_string (tree, int); |
58 | static const char *decl_to_string (tree, int); | |
4e3f84b7 | 59 | static const char *expr_to_string (tree); |
3f8548e7 | 60 | static const char *fndecl_to_string (tree, int); |
4e3f84b7 GDR |
61 | static const char *op_to_string (enum tree_code); |
62 | static const char *parm_to_string (int); | |
3f8548e7 GDR |
63 | static const char *type_to_string (tree, int); |
64 | ||
65 | static void dump_type (tree, int); | |
66 | static void dump_typename (tree, int); | |
67 | static void dump_simple_decl (tree, tree, int); | |
68 | static void dump_decl (tree, int); | |
69 | static void dump_template_decl (tree, int); | |
70 | static void dump_function_decl (tree, int); | |
71 | static void dump_expr (tree, int); | |
72 | static void dump_unary_op (const char *, tree, int); | |
73 | static void dump_binary_op (const char *, tree, int); | |
74 | static void dump_aggr_type (tree, int); | |
75 | static enum pad dump_type_prefix (tree, int); | |
76 | static void dump_type_suffix (tree, int); | |
77 | static void dump_function_name (tree, int); | |
78 | static void dump_expr_list (tree, int); | |
79 | static void dump_global_iord (tree); | |
80 | static enum pad dump_qualifiers (tree, enum pad); | |
3f8548e7 GDR |
81 | static void dump_parameters (tree, int); |
82 | static void dump_exception_spec (tree, int); | |
83 | static const char *class_key_or_enum (tree); | |
84 | static void dump_template_argument (tree, int); | |
85 | static void dump_template_argument_list (tree, int); | |
86 | static void dump_template_parameter (tree, int); | |
87 | static void dump_template_bindings (tree, tree); | |
88 | static void dump_scope (tree, int); | |
89 | static void dump_template_parms (tree, int, int); | |
90 | ||
91 | static const char *function_category (tree); | |
92 | static void maybe_print_instantiation_context (diagnostic_context *); | |
93 | static void print_instantiation_full_context (diagnostic_context *); | |
94 | static void print_instantiation_partial_context (diagnostic_context *, | |
35773471 | 95 | tree, location_t); |
3f8548e7 GDR |
96 | static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *); |
97 | static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); | |
98 | static void cp_print_error_function (diagnostic_context *, diagnostic_info *); | |
99 | ||
b6fe0bb8 | 100 | static bool cp_printer (pretty_printer *, text_info *); |
e1a4dd13 | 101 | static void pp_non_consecutive_character (cxx_pretty_printer *, int); |
3f8548e7 | 102 | static tree locate_error (const char *, va_list); |
9a472a42 | 103 | static location_t location_of (tree); |
8d08fdba MS |
104 | |
105 | void | |
3f8548e7 | 106 | init_error (void) |
8d08fdba | 107 | { |
f68fc4db GDR |
108 | diagnostic_starter (global_dc) = cp_diagnostic_starter; |
109 | diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer; | |
749ced52 ZW |
110 | diagnostic_format_decoder (global_dc) = cp_printer; |
111 | ||
e1a4dd13 GDR |
112 | pp_construct (pp_base (cxx_pp), NULL, 0); |
113 | pp_cxx_pretty_printer_init (cxx_pp); | |
8d08fdba MS |
114 | } |
115 | ||
9e93bc9d | 116 | /* Dump a scope, if deemed necessary. */ |
bbcec105 | 117 | |
9e93bc9d | 118 | static void |
3f8548e7 | 119 | dump_scope (tree scope, int flags) |
bbcec105 | 120 | { |
55ace93c | 121 | int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF)); |
761f0855 | 122 | |
9e93bc9d NS |
123 | if (scope == NULL_TREE) |
124 | return; | |
bb20cc46 | 125 | |
9e93bc9d NS |
126 | if (TREE_CODE (scope) == NAMESPACE_DECL) |
127 | { | |
128 | if (scope != global_namespace) | |
129 | { | |
761f0855 | 130 | dump_decl (scope, f); |
b6fe0bb8 | 131 | pp_colon_colon (cxx_pp); |
9e93bc9d | 132 | } |
9e93bc9d NS |
133 | } |
134 | else if (AGGREGATE_TYPE_P (scope)) | |
135 | { | |
761f0855 | 136 | dump_type (scope, f); |
b6fe0bb8 | 137 | pp_colon_colon (cxx_pp); |
9e93bc9d | 138 | } |
761f0855 | 139 | else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL) |
9e93bc9d | 140 | { |
761f0855 | 141 | dump_function_decl (scope, f); |
b6fe0bb8 | 142 | pp_colon_colon (cxx_pp); |
9e93bc9d | 143 | } |
bbcec105 JM |
144 | } |
145 | ||
9e93bc9d NS |
146 | /* Dump type qualifiers, providing padding as requested. Return an |
147 | indication of whether we dumped something. */ | |
148 | ||
149 | static enum pad | |
3f8548e7 | 150 | dump_qualifiers (tree t, enum pad p) |
8d08fdba | 151 | { |
9e93bc9d NS |
152 | static const int masks[] = |
153 | {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT}; | |
154 | static const char *const names[] = | |
155 | {"const", "volatile", "__restrict"}; | |
156 | int ix; | |
157 | int quals = TYPE_QUALS (t); | |
158 | int do_after = p == after; | |
bb20cc46 | 159 | |
9e93bc9d | 160 | if (quals) |
8d08fdba | 161 | { |
9e93bc9d NS |
162 | for (ix = 0; ix != 3; ix++) |
163 | if (masks[ix] & quals) | |
164 | { | |
165 | if (p == before) | |
b6fe0bb8 | 166 | pp_space (cxx_pp); |
9e93bc9d | 167 | p = before; |
b6fe0bb8 | 168 | pp_identifier (cxx_pp, names[ix]); |
9e93bc9d NS |
169 | } |
170 | if (do_after) | |
b6fe0bb8 | 171 | pp_space (cxx_pp); |
8d08fdba | 172 | } |
9e93bc9d NS |
173 | else |
174 | p = none; | |
175 | return p; | |
8d08fdba MS |
176 | } |
177 | ||
612c671a | 178 | /* Dump the template ARGument under control of FLAGS. */ |
5f77d6cc GDR |
179 | |
180 | static void | |
3f8548e7 | 181 | dump_template_argument (tree arg, int flags) |
5f77d6cc | 182 | { |
2f939d94 | 183 | if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) |
761f0855 | 184 | dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM); |
5f77d6cc | 185 | else |
761f0855 | 186 | dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); |
5f77d6cc GDR |
187 | } |
188 | ||
612c671a GDR |
189 | /* Dump a template-argument-list ARGS (always a TREE_VEC) under control |
190 | of FLAGS. */ | |
191 | ||
192 | static void | |
3f8548e7 | 193 | dump_template_argument_list (tree args, int flags) |
612c671a GDR |
194 | { |
195 | int n = TREE_VEC_LENGTH (args); | |
196 | int need_comma = 0; | |
197 | int i; | |
198 | ||
199 | for (i = 0; i< n; ++i) | |
200 | { | |
201 | if (need_comma) | |
b6fe0bb8 | 202 | pp_separate_with_comma (cxx_pp); |
612c671a GDR |
203 | dump_template_argument (TREE_VEC_ELT (args, i), flags); |
204 | need_comma = 1; | |
205 | } | |
206 | } | |
207 | ||
208 | /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */ | |
209 | ||
210 | static void | |
3f8548e7 | 211 | dump_template_parameter (tree parm, int flags) |
612c671a GDR |
212 | { |
213 | tree p = TREE_VALUE (parm); | |
214 | tree a = TREE_PURPOSE (parm); | |
215 | ||
216 | if (TREE_CODE (p) == TYPE_DECL) | |
217 | { | |
761f0855 | 218 | if (flags & TFF_DECL_SPECIFIERS) |
612c671a | 219 | { |
b6fe0bb8 | 220 | pp_identifier (cxx_pp, "class"); |
612c671a GDR |
221 | if (DECL_NAME (p)) |
222 | { | |
b6fe0bb8 GDR |
223 | pp_space (cxx_pp); |
224 | pp_tree_identifier (cxx_pp, DECL_NAME (p)); | |
612c671a GDR |
225 | } |
226 | } | |
227 | else if (DECL_NAME (p)) | |
b6fe0bb8 | 228 | pp_tree_identifier (cxx_pp, DECL_NAME (p)); |
612c671a | 229 | else |
b2517173 | 230 | pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p)); |
612c671a GDR |
231 | } |
232 | else | |
761f0855 | 233 | dump_decl (p, flags | TFF_DECL_SPECIFIERS); |
612c671a | 234 | |
761f0855 | 235 | if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE) |
612c671a | 236 | { |
b6fe0bb8 | 237 | pp_string (cxx_pp, " = "); |
31bb3027 | 238 | if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) |
761f0855 | 239 | dump_type (a, flags & ~TFF_CHASE_TYPEDEF); |
612c671a | 240 | else |
761f0855 | 241 | dump_expr (a, flags | TFF_EXPR_IN_PARENS); |
612c671a GDR |
242 | } |
243 | } | |
244 | ||
245 | /* Dump, under control of FLAGS, a template-parameter-list binding. | |
246 | PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a | |
247 | TREE_VEC. */ | |
248 | ||
249 | static void | |
3f8548e7 | 250 | dump_template_bindings (tree parms, tree args) |
612c671a | 251 | { |
612c671a GDR |
252 | int need_comma = 0; |
253 | ||
254 | while (parms) | |
255 | { | |
256 | tree p = TREE_VALUE (parms); | |
b5ac18ea MM |
257 | int lvl = TMPL_PARMS_DEPTH (parms); |
258 | int arg_idx = 0; | |
612c671a GDR |
259 | int i; |
260 | ||
261 | for (i = 0; i < TREE_VEC_LENGTH (p); ++i) | |
b5ac18ea | 262 | { |
2bb5d995 JM |
263 | tree arg = NULL_TREE; |
264 | ||
265 | /* Don't crash if we had an invalid argument list. */ | |
266 | if (TMPL_ARGS_DEPTH (args) >= lvl) | |
267 | { | |
268 | tree lvl_args = TMPL_ARGS_LEVEL (args, lvl); | |
269 | if (NUM_TMPL_ARGS (lvl_args) > arg_idx) | |
270 | arg = TREE_VEC_ELT (lvl_args, arg_idx); | |
271 | } | |
b5ac18ea MM |
272 | |
273 | if (need_comma) | |
b6fe0bb8 | 274 | pp_separate_with_comma (cxx_pp); |
761f0855 | 275 | dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER); |
b6fe0bb8 | 276 | pp_string (cxx_pp, " = "); |
b5ac18ea | 277 | if (arg) |
761f0855 | 278 | dump_template_argument (arg, TFF_PLAIN_IDENTIFIER); |
b5ac18ea | 279 | else |
b6fe0bb8 | 280 | pp_identifier (cxx_pp, "<missing>"); |
bb20cc46 | 281 | |
b5ac18ea MM |
282 | ++arg_idx; |
283 | need_comma = 1; | |
284 | } | |
612c671a GDR |
285 | |
286 | parms = TREE_CHAIN (parms); | |
287 | } | |
288 | } | |
289 | ||
b3426eb9 GK |
290 | /* Dump a human-readable equivalent of TYPE. FLAGS controls the |
291 | format. */ | |
e92cc029 | 292 | |
8d08fdba | 293 | static void |
3f8548e7 | 294 | dump_type (tree t, int flags) |
8d08fdba MS |
295 | { |
296 | if (t == NULL_TREE) | |
297 | return; | |
bb20cc46 | 298 | |
8d08fdba MS |
299 | if (TYPE_PTRMEMFUNC_P (t)) |
300 | goto offset_type; | |
301 | ||
302 | switch (TREE_CODE (t)) | |
303 | { | |
8d08fdba | 304 | case UNKNOWN_TYPE: |
b6fe0bb8 | 305 | pp_identifier (cxx_pp, "<unknown type>"); |
8d08fdba MS |
306 | break; |
307 | ||
dcd08efc JM |
308 | case TREE_LIST: |
309 | /* A list of function parms. */ | |
9e93bc9d | 310 | dump_parameters (t, flags); |
dcd08efc JM |
311 | break; |
312 | ||
8d08fdba | 313 | case IDENTIFIER_NODE: |
b6fe0bb8 | 314 | pp_tree_identifier (cxx_pp, t); |
8d08fdba MS |
315 | break; |
316 | ||
317 | case TREE_VEC: | |
9e93bc9d | 318 | dump_type (BINFO_TYPE (t), flags); |
8d08fdba MS |
319 | break; |
320 | ||
321 | case RECORD_TYPE: | |
322 | case UNION_TYPE: | |
323 | case ENUMERAL_TYPE: | |
9e93bc9d | 324 | dump_aggr_type (t, flags); |
8d08fdba MS |
325 | break; |
326 | ||
327 | case TYPE_DECL: | |
761f0855 | 328 | if (flags & TFF_CHASE_TYPEDEF) |
9e93bc9d NS |
329 | { |
330 | dump_type (DECL_ORIGINAL_TYPE (t) | |
331 | ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); | |
332 | break; | |
333 | } | |
f4f206f4 | 334 | /* Else fall through. */ |
bb20cc46 | 335 | |
67c2a928 | 336 | case TEMPLATE_DECL: |
009425e1 | 337 | case NAMESPACE_DECL: |
761f0855 | 338 | dump_decl (t, flags & ~TFF_DECL_SPECIFIERS); |
8d08fdba | 339 | break; |
bb20cc46 | 340 | |
8d08fdba | 341 | case INTEGER_TYPE: |
8d08fdba MS |
342 | case REAL_TYPE: |
343 | case VOID_TYPE: | |
2986ae00 | 344 | case BOOLEAN_TYPE: |
53de5204 GDR |
345 | case COMPLEX_TYPE: |
346 | case VECTOR_TYPE: | |
347 | pp_base (cxx_pp)->padding = pp_none; | |
348 | pp_type_specifier_seq (cxx_pp, t); | |
8d08fdba MS |
349 | break; |
350 | ||
73b0fce8 | 351 | case TEMPLATE_TEMPLATE_PARM: |
c6002625 | 352 | /* For parameters inside template signature. */ |
a1281f45 | 353 | if (TYPE_IDENTIFIER (t)) |
b6fe0bb8 | 354 | pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); |
73b0fce8 | 355 | else |
b2517173 | 356 | pp_cxx_canonical_template_parameter (cxx_pp, t); |
a1281f45 KL |
357 | break; |
358 | ||
359 | case BOUND_TEMPLATE_TEMPLATE_PARM: | |
360 | { | |
361 | tree args = TYPE_TI_ARGS (t); | |
b6fe0bb8 GDR |
362 | pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); |
363 | pp_template_argument_list_start (cxx_pp); | |
a1281f45 | 364 | dump_template_argument_list (args, flags); |
b6fe0bb8 | 365 | pp_template_argument_list_end (cxx_pp); |
a1281f45 | 366 | } |
73b0fce8 KL |
367 | break; |
368 | ||
8d08fdba | 369 | case TEMPLATE_TYPE_PARM: |
91063b51 | 370 | dump_qualifiers (t, after); |
ec255269 | 371 | if (TYPE_IDENTIFIER (t)) |
b6fe0bb8 | 372 | pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); |
ec255269 | 373 | else |
b2517173 GDR |
374 | pp_cxx_canonical_template_parameter |
375 | (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t)); | |
8d08fdba MS |
376 | break; |
377 | ||
8d08fdba MS |
378 | /* This is not always necessary for pointers and such, but doing this |
379 | reduces code size. */ | |
380 | case ARRAY_TYPE: | |
381 | case POINTER_TYPE: | |
382 | case REFERENCE_TYPE: | |
383 | case OFFSET_TYPE: | |
384 | offset_type: | |
385 | case FUNCTION_TYPE: | |
386 | case METHOD_TYPE: | |
9e93bc9d NS |
387 | { |
388 | dump_type_prefix (t, flags); | |
389 | dump_type_suffix (t, flags); | |
8d08fdba | 390 | break; |
9e93bc9d | 391 | } |
5566b478 | 392 | case TYPENAME_TYPE: |
14d22dd6 | 393 | dump_qualifiers (t, after); |
b6fe0bb8 | 394 | pp_string (cxx_pp, "typename "); |
46e2747c | 395 | dump_typename (t, flags); |
5566b478 MS |
396 | break; |
397 | ||
b8c6534b KL |
398 | case UNBOUND_CLASS_TEMPLATE: |
399 | dump_type (TYPE_CONTEXT (t), flags); | |
b6fe0bb8 GDR |
400 | pp_colon_colon (cxx_pp); |
401 | pp_identifier (cxx_pp, "template "); | |
b8c6534b KL |
402 | dump_type (DECL_NAME (TYPE_NAME (t)), flags); |
403 | break; | |
404 | ||
b894fc05 | 405 | case TYPEOF_TYPE: |
b6fe0bb8 | 406 | pp_string (cxx_pp, "__typeof ("); |
eb34af89 | 407 | dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 408 | pp_right_paren (cxx_pp); |
b894fc05 JM |
409 | break; |
410 | ||
8d08fdba | 411 | default: |
b6fe0bb8 | 412 | pp_unsupported_tree (cxx_pp, t); |
c6002625 | 413 | /* Fall through to error. */ |
9e93bc9d NS |
414 | |
415 | case ERROR_MARK: | |
b6fe0bb8 | 416 | pp_identifier (cxx_pp, "<type error>"); |
9e93bc9d | 417 | break; |
8d08fdba MS |
418 | } |
419 | } | |
420 | ||
46e2747c NS |
421 | /* Dump a TYPENAME_TYPE. We need to notice when the context is itself |
422 | a TYPENAME_TYPE. */ | |
423 | ||
424 | static void | |
3f8548e7 | 425 | dump_typename (tree t, int flags) |
46e2747c NS |
426 | { |
427 | tree ctx = TYPE_CONTEXT (t); | |
bb20cc46 | 428 | |
46e2747c NS |
429 | if (TREE_CODE (ctx) == TYPENAME_TYPE) |
430 | dump_typename (ctx, flags); | |
431 | else | |
761f0855 | 432 | dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); |
b6fe0bb8 | 433 | pp_colon_colon (cxx_pp); |
46e2747c NS |
434 | dump_decl (TYPENAME_TYPE_FULLNAME (t), flags); |
435 | } | |
436 | ||
9e93bc9d NS |
437 | /* Return the name of the supplied aggregate, or enumeral type. */ |
438 | ||
9c0758dd | 439 | static const char * |
3f8548e7 | 440 | class_key_or_enum (tree t) |
8d08fdba | 441 | { |
8d08fdba | 442 | if (TREE_CODE (t) == ENUMERAL_TYPE) |
51c184be | 443 | return "enum"; |
8d08fdba | 444 | else if (TREE_CODE (t) == UNION_TYPE) |
51c184be | 445 | return "union"; |
8d08fdba | 446 | else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) |
51c184be | 447 | return "class"; |
8d08fdba | 448 | else |
51c184be MS |
449 | return "struct"; |
450 | } | |
451 | ||
9e93bc9d NS |
452 | /* Print out a class declaration T under the control of FLAGS, |
453 | in the form `class foo'. */ | |
e92cc029 | 454 | |
51c184be | 455 | static void |
3f8548e7 | 456 | dump_aggr_type (tree t, int flags) |
51c184be MS |
457 | { |
458 | tree name; | |
c3e76028 | 459 | const char *variety = class_key_or_enum (t); |
9e93bc9d NS |
460 | int typdef = 0; |
461 | int tmplate = 0; | |
8d08fdba | 462 | |
91063b51 | 463 | dump_qualifiers (t, after); |
8d08fdba | 464 | |
761f0855 | 465 | if (flags & TFF_CLASS_KEY_OR_ENUM) |
8d08fdba | 466 | { |
b6fe0bb8 GDR |
467 | pp_identifier (cxx_pp, variety); |
468 | pp_space (cxx_pp); | |
8d08fdba | 469 | } |
bb20cc46 | 470 | |
761f0855 | 471 | if (flags & TFF_CHASE_TYPEDEF) |
9e93bc9d | 472 | t = TYPE_MAIN_VARIANT (t); |
8d08fdba | 473 | |
9e93bc9d NS |
474 | name = TYPE_NAME (t); |
475 | ||
476 | if (name) | |
8d08fdba | 477 | { |
9e93bc9d NS |
478 | typdef = !DECL_ARTIFICIAL (name); |
479 | tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE | |
480 | && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) | |
370af2d5 | 481 | && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t) |
9e93bc9d NS |
482 | || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL |
483 | || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t)) | |
484 | || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); | |
761f0855 | 485 | dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); |
9e93bc9d NS |
486 | if (tmplate) |
487 | { | |
488 | /* Because the template names are mangled, we have to locate | |
489 | the most general template, and use that name. */ | |
490 | tree tpl = CLASSTYPE_TI_TEMPLATE (t); | |
bb20cc46 | 491 | |
9e93bc9d NS |
492 | while (DECL_TEMPLATE_INFO (tpl)) |
493 | tpl = DECL_TI_TEMPLATE (tpl); | |
494 | name = tpl; | |
495 | } | |
496 | name = DECL_NAME (name); | |
8d08fdba MS |
497 | } |
498 | ||
f30432d7 | 499 | if (name == 0 || ANON_AGGRNAME_P (name)) |
8d08fdba | 500 | { |
761f0855 | 501 | if (flags & TFF_CLASS_KEY_OR_ENUM) |
b6fe0bb8 | 502 | pp_identifier (cxx_pp, "<anonymous>"); |
99885b3f | 503 | else |
e1a4dd13 | 504 | pp_printf (pp_base (cxx_pp), "<anonymous %s>", variety); |
8d08fdba MS |
505 | } |
506 | else | |
b6fe0bb8 | 507 | pp_tree_identifier (cxx_pp, name); |
9e93bc9d NS |
508 | if (tmplate) |
509 | dump_template_parms (TYPE_TEMPLATE_INFO (t), | |
510 | !CLASSTYPE_USE_TEMPLATE (t), | |
761f0855 | 511 | flags & ~TFF_TEMPLATE_HEADER); |
8d08fdba MS |
512 | } |
513 | ||
514 | /* Dump into the obstack the initial part of the output for a given type. | |
515 | This is necessary when dealing with things like functions returning | |
516 | functions. Examples: | |
517 | ||
518 | return type of `int (* fee ())()': pointer -> function -> int. Both | |
519 | pointer (and reference and offset) and function (and member) types must | |
520 | deal with prefix and suffix. | |
521 | ||
522 | Arrays must also do this for DECL nodes, like int a[], and for things like | |
bb20cc46 AJ |
523 | int *[]&. |
524 | ||
9e93bc9d NS |
525 | Return indicates how you should pad an object name after this. I.e. you |
526 | want to pad non-*, non-& cores, but not pad * or & types. */ | |
8d08fdba | 527 | |
9e93bc9d | 528 | static enum pad |
3f8548e7 | 529 | dump_type_prefix (tree t, int flags) |
8d08fdba | 530 | { |
9e93bc9d | 531 | enum pad padding = before; |
bb20cc46 | 532 | |
8d08fdba MS |
533 | if (TYPE_PTRMEMFUNC_P (t)) |
534 | { | |
535 | t = TYPE_PTRMEMFUNC_FN_TYPE (t); | |
536 | goto offset_type; | |
537 | } | |
bb20cc46 | 538 | |
8d08fdba MS |
539 | switch (TREE_CODE (t)) |
540 | { | |
541 | case POINTER_TYPE: | |
91063b51 | 542 | case REFERENCE_TYPE: |
8d08fdba MS |
543 | { |
544 | tree sub = TREE_TYPE (t); | |
bb20cc46 | 545 | |
9e93bc9d | 546 | padding = dump_type_prefix (sub, flags); |
a5ac359a | 547 | if (TREE_CODE (sub) == ARRAY_TYPE) |
8d08fdba | 548 | { |
b6fe0bb8 GDR |
549 | pp_space (cxx_pp); |
550 | pp_left_paren (cxx_pp); | |
8d08fdba | 551 | } |
b6fe0bb8 | 552 | pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]); |
a5ac359a | 553 | padding = dump_qualifiers (t, before); |
8d08fdba | 554 | } |
8d08fdba MS |
555 | break; |
556 | ||
557 | case OFFSET_TYPE: | |
558 | offset_type: | |
9e93bc9d | 559 | padding = dump_type_prefix (TREE_TYPE (t), flags); |
51c184be MS |
560 | if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ |
561 | { | |
9e93bc9d | 562 | if (padding != none) |
b6fe0bb8 | 563 | pp_space (cxx_pp); |
9e93bc9d | 564 | dump_type (TYPE_OFFSET_BASETYPE (t), flags); |
b6fe0bb8 | 565 | pp_colon_colon (cxx_pp); |
51c184be | 566 | } |
b6fe0bb8 | 567 | pp_star (cxx_pp); |
9e93bc9d | 568 | padding = dump_qualifiers (t, none); |
8d08fdba MS |
569 | break; |
570 | ||
571 | /* Can only be reached through function pointer -- this would not be | |
572 | correct if FUNCTION_DECLs used it. */ | |
573 | case FUNCTION_TYPE: | |
9e93bc9d NS |
574 | padding = dump_type_prefix (TREE_TYPE (t), flags); |
575 | if (padding != none) | |
b6fe0bb8 GDR |
576 | pp_space (cxx_pp); |
577 | pp_left_paren (cxx_pp); | |
9e93bc9d | 578 | padding = none; |
8d08fdba MS |
579 | break; |
580 | ||
581 | case METHOD_TYPE: | |
9e93bc9d NS |
582 | padding = dump_type_prefix (TREE_TYPE (t), flags); |
583 | if (padding != none) | |
b6fe0bb8 GDR |
584 | pp_space (cxx_pp); |
585 | pp_left_paren (cxx_pp); | |
9e93bc9d NS |
586 | padding = none; |
587 | dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags); | |
b6fe0bb8 | 588 | pp_colon_colon (cxx_pp); |
8d08fdba MS |
589 | break; |
590 | ||
591 | case ARRAY_TYPE: | |
9e93bc9d | 592 | padding = dump_type_prefix (TREE_TYPE (t), flags); |
8d08fdba MS |
593 | break; |
594 | ||
595 | case ENUMERAL_TYPE: | |
8d08fdba MS |
596 | case IDENTIFIER_NODE: |
597 | case INTEGER_TYPE: | |
2986ae00 | 598 | case BOOLEAN_TYPE: |
8d08fdba MS |
599 | case REAL_TYPE: |
600 | case RECORD_TYPE: | |
601 | case TEMPLATE_TYPE_PARM: | |
73b0fce8 | 602 | case TEMPLATE_TEMPLATE_PARM: |
a1281f45 | 603 | case BOUND_TEMPLATE_TEMPLATE_PARM: |
8d08fdba MS |
604 | case TREE_LIST: |
605 | case TYPE_DECL: | |
606 | case TREE_VEC: | |
8d08fdba MS |
607 | case UNION_TYPE: |
608 | case UNKNOWN_TYPE: | |
609 | case VOID_TYPE: | |
5566b478 | 610 | case TYPENAME_TYPE: |
37c46b43 | 611 | case COMPLEX_TYPE: |
c00996a3 | 612 | case VECTOR_TYPE: |
0df4ae96 | 613 | case TYPEOF_TYPE: |
9e93bc9d NS |
614 | dump_type (t, flags); |
615 | padding = before; | |
8d08fdba | 616 | break; |
bb20cc46 | 617 | |
8d08fdba | 618 | default: |
b6fe0bb8 | 619 | pp_unsupported_tree (cxx_pp, t); |
99885b3f | 620 | /* fall through. */ |
9e93bc9d | 621 | case ERROR_MARK: |
b6fe0bb8 | 622 | pp_identifier (cxx_pp, "<typeprefixerror>"); |
9e93bc9d | 623 | break; |
8d08fdba | 624 | } |
9e93bc9d | 625 | return padding; |
8d08fdba MS |
626 | } |
627 | ||
9e93bc9d NS |
628 | /* Dump the suffix of type T, under control of FLAGS. This is the part |
629 | which appears after the identifier (or function parms). */ | |
630 | ||
8d08fdba | 631 | static void |
3f8548e7 | 632 | dump_type_suffix (tree t, int flags) |
8d08fdba MS |
633 | { |
634 | if (TYPE_PTRMEMFUNC_P (t)) | |
635 | t = TYPE_PTRMEMFUNC_FN_TYPE (t); | |
636 | ||
637 | switch (TREE_CODE (t)) | |
638 | { | |
639 | case POINTER_TYPE: | |
640 | case REFERENCE_TYPE: | |
641 | case OFFSET_TYPE: | |
39211cd5 | 642 | if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) |
b6fe0bb8 | 643 | pp_right_paren (cxx_pp); |
9e93bc9d | 644 | dump_type_suffix (TREE_TYPE (t), flags); |
8d08fdba MS |
645 | break; |
646 | ||
f4f206f4 | 647 | /* Can only be reached through function pointer. */ |
8d08fdba MS |
648 | case FUNCTION_TYPE: |
649 | case METHOD_TYPE: | |
650 | { | |
651 | tree arg; | |
b6fe0bb8 | 652 | pp_right_paren (cxx_pp); |
8d08fdba MS |
653 | arg = TYPE_ARG_TYPES (t); |
654 | if (TREE_CODE (t) == METHOD_TYPE) | |
655 | arg = TREE_CHAIN (arg); | |
656 | ||
4995028c NS |
657 | /* Function pointers don't have default args. Not in standard C++, |
658 | anyway; they may in g++, but we'll just pretend otherwise. */ | |
761f0855 | 659 | dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); |
4995028c | 660 | |
8d08fdba | 661 | if (TREE_CODE (t) == METHOD_TYPE) |
91063b51 | 662 | dump_qualifiers |
8d08fdba | 663 | (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); |
9e93bc9d | 664 | dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); |
ad6b1795 | 665 | dump_type_suffix (TREE_TYPE (t), flags); |
8d08fdba MS |
666 | break; |
667 | } | |
668 | ||
669 | case ARRAY_TYPE: | |
b6fe0bb8 | 670 | pp_left_bracket (cxx_pp); |
8d08fdba | 671 | if (TYPE_DOMAIN (t)) |
5156628f | 672 | { |
665f2503 | 673 | if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0)) |
b6fe0bb8 GDR |
674 | pp_wide_integer |
675 | (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1); | |
5156628f | 676 | else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) |
9e93bc9d | 677 | dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), |
761f0855 | 678 | flags & ~TFF_EXPR_IN_PARENS); |
5156628f | 679 | else |
ab76ca54 | 680 | dump_expr (fold (cp_build_binary_op |
5156628f | 681 | (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), |
9e93bc9d | 682 | integer_one_node)), |
761f0855 | 683 | flags & ~TFF_EXPR_IN_PARENS); |
5156628f | 684 | } |
b6fe0bb8 | 685 | pp_right_bracket (cxx_pp); |
9e93bc9d | 686 | dump_type_suffix (TREE_TYPE (t), flags); |
8d08fdba | 687 | break; |
bb20cc46 | 688 | |
8d08fdba | 689 | case ENUMERAL_TYPE: |
8d08fdba MS |
690 | case IDENTIFIER_NODE: |
691 | case INTEGER_TYPE: | |
2986ae00 | 692 | case BOOLEAN_TYPE: |
8d08fdba MS |
693 | case REAL_TYPE: |
694 | case RECORD_TYPE: | |
695 | case TEMPLATE_TYPE_PARM: | |
73b0fce8 | 696 | case TEMPLATE_TEMPLATE_PARM: |
a97d0689 | 697 | case BOUND_TEMPLATE_TEMPLATE_PARM: |
8d08fdba MS |
698 | case TREE_LIST: |
699 | case TYPE_DECL: | |
700 | case TREE_VEC: | |
8d08fdba MS |
701 | case UNION_TYPE: |
702 | case UNKNOWN_TYPE: | |
703 | case VOID_TYPE: | |
5566b478 | 704 | case TYPENAME_TYPE: |
37c46b43 | 705 | case COMPLEX_TYPE: |
c00996a3 | 706 | case VECTOR_TYPE: |
0df4ae96 | 707 | case TYPEOF_TYPE: |
8d08fdba MS |
708 | break; |
709 | ||
710 | default: | |
b6fe0bb8 | 711 | pp_unsupported_tree (cxx_pp, t); |
9e93bc9d NS |
712 | case ERROR_MARK: |
713 | /* Don't mark it here, we should have already done in | |
714 | dump_type_prefix. */ | |
715 | break; | |
8d08fdba MS |
716 | } |
717 | } | |
718 | ||
49c249e1 | 719 | static void |
3f8548e7 | 720 | dump_global_iord (tree t) |
8d08fdba | 721 | { |
99885b3f | 722 | const char *p = NULL; |
8d08fdba | 723 | |
92643fea | 724 | if (DECL_GLOBAL_CTOR_P (t)) |
99885b3f | 725 | p = "initializers"; |
92643fea | 726 | else if (DECL_GLOBAL_DTOR_P (t)) |
99885b3f | 727 | p = "destructors"; |
8d08fdba | 728 | else |
a98facb0 | 729 | abort (); |
bb20cc46 | 730 | |
e1a4dd13 | 731 | pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename); |
8d08fdba MS |
732 | } |
733 | ||
07389efe | 734 | static void |
3f8548e7 | 735 | dump_simple_decl (tree t, tree type, int flags) |
07389efe | 736 | { |
761f0855 | 737 | if (flags & TFF_DECL_SPECIFIERS) |
07389efe | 738 | { |
9e93bc9d | 739 | if (dump_type_prefix (type, flags) != none) |
b6fe0bb8 | 740 | pp_space (cxx_pp); |
07389efe | 741 | } |
9e93bc9d NS |
742 | if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) |
743 | dump_scope (CP_DECL_CONTEXT (t), flags); | |
07389efe | 744 | if (DECL_NAME (t)) |
9e93bc9d | 745 | dump_decl (DECL_NAME (t), flags); |
07389efe | 746 | else |
b6fe0bb8 | 747 | pp_identifier (cxx_pp, "<anonymous>"); |
761f0855 | 748 | if (flags & TFF_DECL_SPECIFIERS) |
9e93bc9d | 749 | dump_type_suffix (type, flags); |
07389efe MM |
750 | } |
751 | ||
9e93bc9d NS |
752 | /* Dump a human readable string for the decl T under control of FLAGS. */ |
753 | ||
8d08fdba | 754 | static void |
3f8548e7 | 755 | dump_decl (tree t, int flags) |
8d08fdba MS |
756 | { |
757 | if (t == NULL_TREE) | |
758 | return; | |
759 | ||
760 | switch (TREE_CODE (t)) | |
761 | { | |
7177d104 | 762 | case TYPE_DECL: |
8d2733ca MS |
763 | { |
764 | /* Don't say 'typedef class A' */ | |
fc378698 | 765 | if (DECL_ARTIFICIAL (t)) |
8d2733ca | 766 | { |
761f0855 | 767 | if ((flags & TFF_DECL_SPECIFIERS) |
9e93bc9d | 768 | && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) |
c6002625 | 769 | /* Say `class T' not just `T'. */ |
b6fe0bb8 | 770 | pp_string (cxx_pp, "class "); |
a9936d39 | 771 | |
9e93bc9d | 772 | dump_type (TREE_TYPE (t), flags); |
8d2733ca MS |
773 | break; |
774 | } | |
775 | } | |
761f0855 | 776 | if (flags & TFF_DECL_SPECIFIERS) |
b6fe0bb8 | 777 | pp_string (cxx_pp, "typedef "); |
bb20cc46 | 778 | dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) |
9e93bc9d NS |
779 | ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), |
780 | flags); | |
7177d104 | 781 | break; |
bb20cc46 | 782 | |
8d08fdba | 783 | case VAR_DECL: |
b7484fbe | 784 | if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) |
8d08fdba | 785 | { |
b6fe0bb8 | 786 | pp_string (cxx_pp, "vtable for "); |
c4372ef4 NS |
787 | my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720); |
788 | dump_type (DECL_CONTEXT (t), flags); | |
8d08fdba MS |
789 | break; |
790 | } | |
f4f206f4 | 791 | /* Else fall through. */ |
8d08fdba MS |
792 | case FIELD_DECL: |
793 | case PARM_DECL: | |
7162281a | 794 | case ALIAS_DECL: |
9e93bc9d | 795 | dump_simple_decl (t, TREE_TYPE (t), flags); |
8d08fdba MS |
796 | break; |
797 | ||
f6a898ba | 798 | case RESULT_DECL: |
b6fe0bb8 | 799 | pp_string (cxx_pp, "<return value> "); |
f6a898ba AO |
800 | dump_simple_decl (t, TREE_TYPE (t), flags); |
801 | break; | |
802 | ||
a9aedbc2 | 803 | case NAMESPACE_DECL: |
a2a9e21c GDR |
804 | if (flags & TFF_DECL_SPECIFIERS) |
805 | pp_cxx_declaration (cxx_pp, t); | |
0c8feefe | 806 | else |
a2a9e21c GDR |
807 | { |
808 | dump_scope (CP_DECL_CONTEXT (t), flags); | |
ed36980c | 809 | if (DECL_NAME (t) == NULL_TREE) |
a2a9e21c GDR |
810 | pp_identifier (cxx_pp, "<unnamed>"); |
811 | else | |
812 | pp_tree_identifier (cxx_pp, DECL_NAME (t)); | |
813 | } | |
a9aedbc2 MS |
814 | break; |
815 | ||
3e3f722c | 816 | case SCOPE_REF: |
761f0855 | 817 | dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS); |
b6fe0bb8 | 818 | pp_colon_colon (cxx_pp); |
9e93bc9d | 819 | dump_decl (TREE_OPERAND (t, 1), flags); |
bb20cc46 | 820 | break; |
3e3f722c | 821 | |
8d08fdba | 822 | case ARRAY_REF: |
9e93bc9d | 823 | dump_decl (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 824 | pp_left_bracket (cxx_pp); |
9e93bc9d | 825 | dump_decl (TREE_OPERAND (t, 1), flags); |
b6fe0bb8 | 826 | pp_right_bracket (cxx_pp); |
8d08fdba MS |
827 | break; |
828 | ||
9e93bc9d | 829 | /* So that we can do dump_decl on an aggr type. */ |
8d08fdba MS |
830 | case RECORD_TYPE: |
831 | case UNION_TYPE: | |
832 | case ENUMERAL_TYPE: | |
9e93bc9d | 833 | dump_type (t, flags); |
8d08fdba MS |
834 | break; |
835 | ||
814ae570 | 836 | case BIT_NOT_EXPR: |
82911f36 | 837 | /* This is a pseudo destructor call which has not been folded into |
814ae570 | 838 | a PSEUDO_DTOR_EXPR yet. */ |
b6fe0bb8 | 839 | pp_complement (cxx_pp); |
814ae570 GB |
840 | dump_type (TREE_OPERAND (t, 0), flags); |
841 | break; | |
842 | ||
8d08fdba | 843 | case TYPE_EXPR: |
a98facb0 | 844 | abort (); |
8d08fdba MS |
845 | break; |
846 | ||
847 | /* These special cases are duplicated here so that other functions | |
33bd39a2 | 848 | can feed identifiers to error and get them demangled properly. */ |
8d08fdba | 849 | case IDENTIFIER_NODE: |
dc5c569a JJ |
850 | if (IDENTIFIER_TYPENAME_P (t)) |
851 | { | |
b6fe0bb8 | 852 | pp_string (cxx_pp, "operator "); |
dc5c569a JJ |
853 | /* Not exactly IDENTIFIER_TYPE_VALUE. */ |
854 | dump_type (TREE_TYPE (t), flags); | |
855 | break; | |
856 | } | |
857 | else | |
b6fe0bb8 | 858 | pp_tree_identifier (cxx_pp, t); |
8d08fdba MS |
859 | break; |
860 | ||
8f032717 | 861 | case OVERLOAD: |
65a5559b MM |
862 | if (OVL_CHAIN (t)) |
863 | { | |
864 | t = OVL_CURRENT (t); | |
865 | if (DECL_CLASS_SCOPE_P (t)) | |
866 | { | |
867 | dump_type (DECL_CONTEXT (t), flags); | |
b6fe0bb8 | 868 | pp_colon_colon (cxx_pp); |
65a5559b MM |
869 | } |
870 | else if (DECL_CONTEXT (t)) | |
871 | { | |
872 | dump_decl (DECL_CONTEXT (t), flags); | |
b6fe0bb8 | 873 | pp_colon_colon (cxx_pp); |
65a5559b MM |
874 | } |
875 | dump_decl (DECL_NAME (t), flags); | |
876 | break; | |
877 | } | |
878 | ||
879 | /* If there's only one function, just treat it like an ordinary | |
880 | FUNCTION_DECL. */ | |
8f032717 MM |
881 | t = OVL_CURRENT (t); |
882 | /* Fall through. */ | |
883 | ||
8d08fdba | 884 | case FUNCTION_DECL: |
92643fea MM |
885 | if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) |
886 | dump_global_iord (t); | |
da20811c | 887 | else if (! DECL_LANG_SPECIFIC (t)) |
b6fe0bb8 | 888 | pp_identifier (cxx_pp, "<internal>"); |
8d08fdba | 889 | else |
9e93bc9d | 890 | dump_function_decl (t, flags); |
8d08fdba MS |
891 | break; |
892 | ||
893 | case TEMPLATE_DECL: | |
38066e83 | 894 | dump_template_decl (t, flags); |
8d08fdba MS |
895 | break; |
896 | ||
74cd8397 JM |
897 | case TEMPLATE_ID_EXPR: |
898 | { | |
aa36c081 | 899 | tree name = TREE_OPERAND (t, 0); |
bf12d54d | 900 | |
aa36c081 JM |
901 | if (is_overloaded_fn (name)) |
902 | name = DECL_NAME (get_first_fn (name)); | |
9e93bc9d | 903 | dump_decl (name, flags); |
b6fe0bb8 | 904 | pp_template_argument_list_start (cxx_pp); |
bf12d54d NS |
905 | if (TREE_OPERAND (t, 1)) |
906 | dump_template_argument_list (TREE_OPERAND (t, 1), flags); | |
b6fe0bb8 | 907 | pp_template_argument_list_end (cxx_pp); |
74cd8397 JM |
908 | } |
909 | break; | |
910 | ||
8d08fdba | 911 | case LABEL_DECL: |
b6fe0bb8 | 912 | pp_tree_identifier (cxx_pp, DECL_NAME (t)); |
8d08fdba MS |
913 | break; |
914 | ||
915 | case CONST_DECL: | |
6467930b | 916 | if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) |
03555413 | 917 | || (DECL_INITIAL (t) && |
f84b4be9 | 918 | TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) |
9e93bc9d | 919 | dump_simple_decl (t, TREE_TYPE (t), flags); |
224c649b | 920 | else if (DECL_NAME (t)) |
9e93bc9d | 921 | dump_decl (DECL_NAME (t), flags); |
03555413 | 922 | else if (DECL_INITIAL (t)) |
761f0855 | 923 | dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); |
03555413 | 924 | else |
b6fe0bb8 | 925 | pp_identifier (cxx_pp, "<enumerator>"); |
8d08fdba MS |
926 | break; |
927 | ||
cffa8729 | 928 | case USING_DECL: |
b6fe0bb8 | 929 | pp_string (cxx_pp, "using "); |
9e93bc9d | 930 | dump_type (DECL_INITIAL (t), flags); |
b6fe0bb8 | 931 | pp_colon_colon (cxx_pp); |
37198bc8 | 932 | dump_decl (DECL_NAME (t), flags); |
cffa8729 MS |
933 | break; |
934 | ||
50ad9642 MM |
935 | case BASELINK: |
936 | dump_decl (BASELINK_FUNCTIONS (t), flags); | |
937 | break; | |
938 | ||
d17811fd MM |
939 | case NON_DEPENDENT_EXPR: |
940 | dump_expr (t, flags); | |
941 | break; | |
942 | ||
bf3e8283 GDR |
943 | case TEMPLATE_TYPE_PARM: |
944 | if (flags & TFF_DECL_SPECIFIERS) | |
945 | pp_cxx_declaration (cxx_pp, t); | |
946 | else | |
947 | pp_type_id (cxx_pp, t); | |
948 | break; | |
949 | ||
8d08fdba | 950 | default: |
b6fe0bb8 | 951 | pp_unsupported_tree (cxx_pp, t); |
852dcbdd | 952 | /* Fall through to error. */ |
9e93bc9d NS |
953 | |
954 | case ERROR_MARK: | |
b6fe0bb8 | 955 | pp_identifier (cxx_pp, "<declaration error>"); |
9e93bc9d NS |
956 | break; |
957 | } | |
958 | } | |
959 | ||
960 | /* Dump a template declaration T under control of FLAGS. This means the | |
961 | 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ | |
962 | ||
963 | static void | |
3f8548e7 | 964 | dump_template_decl (tree t, int flags) |
9e93bc9d | 965 | { |
b5ac18ea MM |
966 | tree orig_parms = DECL_TEMPLATE_PARMS (t); |
967 | tree parms; | |
bb20cc46 AJ |
968 | int i; |
969 | ||
761f0855 | 970 | if (flags & TFF_TEMPLATE_HEADER) |
9e93bc9d | 971 | { |
bb20cc46 | 972 | for (parms = orig_parms = nreverse (orig_parms); |
b5ac18ea MM |
973 | parms; |
974 | parms = TREE_CHAIN (parms)) | |
9e93bc9d | 975 | { |
b5ac18ea MM |
976 | tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); |
977 | int len = TREE_VEC_LENGTH (inner_parms); | |
bb20cc46 | 978 | |
b6fe0bb8 | 979 | pp_string (cxx_pp, "template<"); |
38066e83 KL |
980 | |
981 | /* If we've shown the template prefix, we'd better show the | |
982 | parameters' and decl's type too. */ | |
983 | flags |= TFF_DECL_SPECIFIERS; | |
984 | ||
9e93bc9d NS |
985 | for (i = 0; i < len; i++) |
986 | { | |
9e93bc9d | 987 | if (i) |
b6fe0bb8 | 988 | pp_separate_with_comma (cxx_pp); |
b5ac18ea | 989 | dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags); |
9e93bc9d | 990 | } |
b6fe0bb8 GDR |
991 | pp_template_argument_list_end (cxx_pp); |
992 | pp_space (cxx_pp); | |
9e93bc9d | 993 | } |
b5ac18ea | 994 | nreverse(orig_parms); |
38066e83 KL |
995 | |
996 | if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) | |
c6002625 | 997 | /* Say `template<arg> class TT' not just `template<arg> TT'. */ |
b6fe0bb8 | 998 | pp_string (cxx_pp, "class "); |
9e93bc9d | 999 | } |
38066e83 | 1000 | |
9e93bc9d NS |
1001 | if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) |
1002 | dump_type (TREE_TYPE (t), | |
761f0855 GDR |
1003 | ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME |
1004 | | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); | |
9e93bc9d | 1005 | else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) |
761f0855 | 1006 | dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); |
9e93bc9d | 1007 | else if (TREE_TYPE (t) == NULL_TREE) |
a98facb0 | 1008 | abort (); |
9e93bc9d NS |
1009 | else |
1010 | switch (NEXT_CODE (t)) | |
1011 | { | |
1012 | case METHOD_TYPE: | |
1013 | case FUNCTION_TYPE: | |
761f0855 | 1014 | dump_function_decl (t, flags | TFF_TEMPLATE_NAME); |
9e93bc9d NS |
1015 | break; |
1016 | default: | |
0e339752 | 1017 | /* This case can occur with some invalid code. */ |
9e93bc9d | 1018 | dump_type (TREE_TYPE (t), |
761f0855 GDR |
1019 | (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME |
1020 | | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)); | |
8d08fdba MS |
1021 | } |
1022 | } | |
1023 | ||
4995028c | 1024 | /* Pretty print a function decl. There are several ways we want to print a |
761f0855 | 1025 | function declaration. The TFF_ bits in FLAGS tells us how to behave. |
33bd39a2 | 1026 | As error can only apply the '#' flag once to give 0 and 1 for V, there |
c6002625 | 1027 | is %D which doesn't print the throw specs, and %F which does. */ |
8d08fdba MS |
1028 | |
1029 | static void | |
3f8548e7 | 1030 | dump_function_decl (tree t, int flags) |
8d08fdba | 1031 | { |
98c1c668 JM |
1032 | tree fntype; |
1033 | tree parmtypes; | |
8d08fdba | 1034 | tree cname = NULL_TREE; |
612c671a GDR |
1035 | tree template_args = NULL_TREE; |
1036 | tree template_parms = NULL_TREE; | |
761f0855 | 1037 | int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; |
8d08fdba | 1038 | |
98c1c668 JM |
1039 | if (TREE_CODE (t) == TEMPLATE_DECL) |
1040 | t = DECL_TEMPLATE_RESULT (t); | |
1041 | ||
612c671a | 1042 | /* Pretty print template instantiations only. */ |
f9817201 | 1043 | if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)) |
612c671a | 1044 | { |
f9a7ae04 MM |
1045 | tree tmpl; |
1046 | ||
612c671a | 1047 | template_args = DECL_TI_ARGS (t); |
f9a7ae04 MM |
1048 | tmpl = most_general_template (t); |
1049 | if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL) | |
1050 | { | |
1051 | template_parms = DECL_TEMPLATE_PARMS (tmpl); | |
1052 | t = tmpl; | |
1053 | } | |
612c671a GDR |
1054 | } |
1055 | ||
98c1c668 | 1056 | fntype = TREE_TYPE (t); |
e0fff4b3 | 1057 | parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t); |
98c1c668 | 1058 | |
2642b9bf | 1059 | if (DECL_CLASS_SCOPE_P (t)) |
4f1c5b7d | 1060 | cname = DECL_CONTEXT (t); |
f4f206f4 | 1061 | /* This is for partially instantiated template methods. */ |
8d08fdba MS |
1062 | else if (TREE_CODE (fntype) == METHOD_TYPE) |
1063 | cname = TREE_TYPE (TREE_VALUE (parmtypes)); | |
1064 | ||
761f0855 | 1065 | if (!(flags & TFF_DECL_SPECIFIERS)) |
9e93bc9d NS |
1066 | /* OK */; |
1067 | else if (DECL_STATIC_FUNCTION_P (t)) | |
b6fe0bb8 | 1068 | pp_identifier (cxx_pp, "static "); |
00bb3dad | 1069 | else if (DECL_VIRTUAL_P (t)) |
b6fe0bb8 | 1070 | pp_identifier (cxx_pp, "virtual "); |
bb20cc46 | 1071 | |
9e93bc9d NS |
1072 | /* Print the return type? */ |
1073 | if (show_return) | |
1074 | show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) | |
1075 | && !DECL_DESTRUCTOR_P (t); | |
1076 | if (show_return) | |
8d08fdba | 1077 | { |
5f9cd837 | 1078 | dump_type_prefix (TREE_TYPE (fntype), flags); |
b6fe0bb8 | 1079 | pp_space (cxx_pp); |
8d08fdba MS |
1080 | } |
1081 | ||
61cd552e | 1082 | /* Print the function name. */ |
8d08fdba MS |
1083 | if (cname) |
1084 | { | |
9e93bc9d | 1085 | dump_type (cname, flags); |
b6fe0bb8 | 1086 | pp_colon_colon (cxx_pp); |
2642b9bf | 1087 | } |
9e93bc9d NS |
1088 | else |
1089 | dump_scope (CP_DECL_CONTEXT (t), flags); | |
8d08fdba | 1090 | |
9e93bc9d | 1091 | dump_function_name (t, flags); |
bb20cc46 | 1092 | |
303357a7 | 1093 | if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) |
ad50e811 | 1094 | { |
ad50e811 | 1095 | dump_parameters (parmtypes, flags); |
bb20cc46 | 1096 | |
ad50e811 MM |
1097 | if (TREE_CODE (fntype) == METHOD_TYPE) |
1098 | dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), | |
1099 | before); | |
bb20cc46 | 1100 | |
761f0855 | 1101 | if (flags & TFF_EXCEPTION_SPECIFICATION) |
ad50e811 | 1102 | dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags); |
ad6b1795 JM |
1103 | |
1104 | if (show_return) | |
1105 | dump_type_suffix (TREE_TYPE (fntype), flags); | |
ad50e811 | 1106 | } |
612c671a GDR |
1107 | |
1108 | /* If T is a template instantiation, dump the parameter binding. */ | |
1109 | if (template_parms != NULL_TREE && template_args != NULL_TREE) | |
1110 | { | |
b6fe0bb8 | 1111 | pp_string (cxx_pp, " [with "); |
b5ac18ea | 1112 | dump_template_bindings (template_parms, template_args); |
b6fe0bb8 | 1113 | pp_right_bracket (cxx_pp); |
612c671a | 1114 | } |
4995028c NS |
1115 | } |
1116 | ||
9e93bc9d NS |
1117 | /* Print a parameter list. If this is for a member function, the |
1118 | member object ptr (and any other hidden args) should have | |
c6002625 | 1119 | already been removed. */ |
4995028c NS |
1120 | |
1121 | static void | |
3f8548e7 | 1122 | dump_parameters (tree parmtypes, int flags) |
4995028c NS |
1123 | { |
1124 | int first; | |
99885b3f | 1125 | |
b6fe0bb8 | 1126 | pp_left_paren (cxx_pp); |
4995028c NS |
1127 | |
1128 | for (first = 1; parmtypes != void_list_node; | |
1129 | parmtypes = TREE_CHAIN (parmtypes)) | |
1130 | { | |
1131 | if (!first) | |
b6fe0bb8 | 1132 | pp_separate_with_comma (cxx_pp); |
4995028c NS |
1133 | first = 0; |
1134 | if (!parmtypes) | |
1135 | { | |
b6fe0bb8 | 1136 | pp_identifier (cxx_pp, "..."); |
4995028c NS |
1137 | break; |
1138 | } | |
9e93bc9d | 1139 | dump_type (TREE_VALUE (parmtypes), flags); |
bb20cc46 | 1140 | |
761f0855 | 1141 | if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) |
4995028c | 1142 | { |
b6fe0bb8 | 1143 | pp_string (cxx_pp, " = "); |
761f0855 | 1144 | dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); |
4995028c NS |
1145 | } |
1146 | } | |
1147 | ||
b6fe0bb8 | 1148 | pp_right_paren (cxx_pp); |
4995028c NS |
1149 | } |
1150 | ||
c6002625 | 1151 | /* Print an exception specification. T is the exception specification. */ |
4995028c NS |
1152 | |
1153 | static void | |
3f8548e7 | 1154 | dump_exception_spec (tree t, int flags) |
4995028c NS |
1155 | { |
1156 | if (t) | |
1157 | { | |
b6fe0bb8 | 1158 | pp_string (cxx_pp, " throw ("); |
4995028c NS |
1159 | if (TREE_VALUE (t) != NULL_TREE) |
1160 | while (1) | |
1161 | { | |
9e93bc9d | 1162 | dump_type (TREE_VALUE (t), flags); |
4995028c NS |
1163 | t = TREE_CHAIN (t); |
1164 | if (!t) | |
1165 | break; | |
b6fe0bb8 | 1166 | pp_separate_with_comma (cxx_pp); |
4995028c | 1167 | } |
b6fe0bb8 | 1168 | pp_right_paren (cxx_pp); |
4995028c | 1169 | } |
8d08fdba MS |
1170 | } |
1171 | ||
1172 | /* Handle the function name for a FUNCTION_DECL node, grokking operators | |
1173 | and destructors properly. */ | |
e92cc029 | 1174 | |
8d08fdba | 1175 | static void |
3f8548e7 | 1176 | dump_function_name (tree t, int flags) |
8d08fdba MS |
1177 | { |
1178 | tree name = DECL_NAME (t); | |
1179 | ||
78abea27 RS |
1180 | if (TREE_CODE (t) == TEMPLATE_DECL) |
1181 | t = DECL_TEMPLATE_RESULT (t); | |
1182 | ||
5e818b93 JM |
1183 | /* Don't let the user see __comp_ctor et al. */ |
1184 | if (DECL_CONSTRUCTOR_P (t) | |
1185 | || DECL_DESTRUCTOR_P (t)) | |
1186 | name = constructor_name (DECL_CONTEXT (t)); | |
1187 | ||
aa45967f | 1188 | if (DECL_DESTRUCTOR_P (t)) |
8d08fdba | 1189 | { |
b6fe0bb8 | 1190 | pp_complement (cxx_pp); |
761f0855 | 1191 | dump_decl (name, TFF_PLAIN_IDENTIFIER); |
8d08fdba | 1192 | } |
aa45967f | 1193 | else if (DECL_CONV_FN_P (t)) |
8d08fdba MS |
1194 | { |
1195 | /* This cannot use the hack that the operator's return | |
1196 | type is stashed off of its name because it may be | |
1197 | used for error reporting. In the case of conflicting | |
1198 | declarations, both will have the same name, yet | |
1199 | the types will be different, hence the TREE_TYPE field | |
1200 | of the first name will be clobbered by the second. */ | |
b6fe0bb8 | 1201 | pp_string (cxx_pp, "operator "); |
9e93bc9d | 1202 | dump_type (TREE_TYPE (TREE_TYPE (t)), flags); |
8d08fdba MS |
1203 | } |
1204 | else if (IDENTIFIER_OPNAME_P (name)) | |
b6fe0bb8 | 1205 | pp_tree_identifier (cxx_pp, name); |
8d08fdba | 1206 | else |
9e93bc9d | 1207 | dump_decl (name, flags); |
386b8a85 | 1208 | |
9e93bc9d | 1209 | if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t) |
05fd666b | 1210 | && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) |
bb20cc46 | 1211 | && (DECL_TEMPLATE_SPECIALIZATION (t) |
36a117a5 MM |
1212 | || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL |
1213 | || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t)) | |
1214 | || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) | |
9e93bc9d NS |
1215 | dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags); |
1216 | } | |
75650646 | 1217 | |
9e93bc9d NS |
1218 | /* Dump the template parameters from the template info INFO under control of |
1219 | FLAGS. PRIMARY indicates whether this is a primary template decl, or | |
1220 | specialization (partial or complete). For partial specializations we show | |
1221 | the specialized parameter values. For a primary template we show no | |
1222 | decoration. */ | |
1223 | ||
1224 | static void | |
3f8548e7 | 1225 | dump_template_parms (tree info, int primary, int flags) |
9e93bc9d NS |
1226 | { |
1227 | tree args = info ? TI_ARGS (info) : NULL_TREE; | |
bb20cc46 | 1228 | |
761f0855 | 1229 | if (primary && flags & TFF_TEMPLATE_NAME) |
9e93bc9d | 1230 | return; |
761f0855 | 1231 | flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); |
b6fe0bb8 | 1232 | pp_template_argument_list_start (cxx_pp); |
9e93bc9d NS |
1233 | |
1234 | /* Be careful only to print things when we have them, so as not | |
36a117a5 | 1235 | to crash producing error messages. */ |
9e93bc9d NS |
1236 | if (args && !primary) |
1237 | { | |
bf12d54d | 1238 | int len, ix; |
bb20cc46 | 1239 | |
bf12d54d NS |
1240 | if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) |
1241 | args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); | |
1242 | ||
1243 | len = TREE_VEC_LENGTH (args); | |
bb20cc46 | 1244 | |
bf12d54d | 1245 | for (ix = 0; ix != len; ix++) |
9e93bc9d | 1246 | { |
bf12d54d NS |
1247 | tree arg = TREE_VEC_ELT (args, ix); |
1248 | ||
1249 | if (ix) | |
b6fe0bb8 | 1250 | pp_separate_with_comma (cxx_pp); |
99885b3f | 1251 | |
9e93bc9d | 1252 | if (!arg) |
b6fe0bb8 | 1253 | pp_identifier (cxx_pp, "<template parameter error>"); |
9e93bc9d | 1254 | else |
612c671a | 1255 | dump_template_argument (arg, flags); |
9e93bc9d NS |
1256 | } |
1257 | } | |
9e93bc9d NS |
1258 | else if (primary) |
1259 | { | |
1260 | tree tpl = TI_TEMPLATE (info); | |
1261 | tree parms = DECL_TEMPLATE_PARMS (tpl); | |
1262 | int len, ix; | |
bb20cc46 | 1263 | |
9e93bc9d NS |
1264 | parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE; |
1265 | len = parms ? TREE_VEC_LENGTH (parms) : 0; | |
bb20cc46 | 1266 | |
9e93bc9d NS |
1267 | for (ix = 0; ix != len; ix++) |
1268 | { | |
1269 | tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix)); | |
1270 | ||
1271 | if (ix) | |
b6fe0bb8 | 1272 | pp_separate_with_comma (cxx_pp); |
bb20cc46 | 1273 | |
761f0855 | 1274 | dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS); |
9e93bc9d | 1275 | } |
386b8a85 | 1276 | } |
b6fe0bb8 | 1277 | pp_template_argument_list_end (cxx_pp); |
8d08fdba MS |
1278 | } |
1279 | ||
f4f206f4 | 1280 | /* Print out a list of initializers (subr of dump_expr). */ |
e92cc029 | 1281 | |
8d08fdba | 1282 | static void |
3f8548e7 | 1283 | dump_expr_list (tree l, int flags) |
8d08fdba MS |
1284 | { |
1285 | while (l) | |
1286 | { | |
761f0855 | 1287 | dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS); |
8d08fdba | 1288 | l = TREE_CHAIN (l); |
9e93bc9d | 1289 | if (l) |
b6fe0bb8 | 1290 | pp_separate_with_comma (cxx_pp); |
8d08fdba MS |
1291 | } |
1292 | } | |
1293 | ||
c6002625 | 1294 | /* Print out an expression E under control of FLAGS. */ |
e92cc029 | 1295 | |
8d08fdba | 1296 | static void |
3f8548e7 | 1297 | dump_expr (tree t, int flags) |
8d08fdba | 1298 | { |
8c048a52 GDR |
1299 | if (t == 0) |
1300 | return; | |
1301 | ||
8d08fdba MS |
1302 | switch (TREE_CODE (t)) |
1303 | { | |
1304 | case VAR_DECL: | |
1305 | case PARM_DECL: | |
1306 | case FIELD_DECL: | |
1307 | case CONST_DECL: | |
1308 | case FUNCTION_DECL: | |
ec255269 | 1309 | case TEMPLATE_DECL: |
6b57ac29 | 1310 | case NAMESPACE_DECL: |
5d73aa63 | 1311 | case OVERLOAD: |
a723baf1 | 1312 | case IDENTIFIER_NODE: |
303357a7 | 1313 | dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); |
8d08fdba MS |
1314 | break; |
1315 | ||
1316 | case INTEGER_CST: | |
4b780675 | 1317 | case STRING_CST: |
8d08fdba | 1318 | case REAL_CST: |
4b780675 | 1319 | pp_c_constant (pp_c_base (cxx_pp), t); |
8d08fdba MS |
1320 | break; |
1321 | ||
1c09c5e5 GDR |
1322 | case THROW_EXPR: |
1323 | pp_identifier (cxx_pp, "throw"); | |
1324 | dump_expr (TREE_OPERAND (t, 0), flags); | |
1325 | break; | |
1326 | ||
61a127b3 | 1327 | case PTRMEM_CST: |
b6fe0bb8 | 1328 | pp_ampersand (cxx_pp); |
9e93bc9d | 1329 | dump_type (PTRMEM_CST_CLASS (t), flags); |
b6fe0bb8 GDR |
1330 | pp_colon_colon (cxx_pp); |
1331 | pp_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t))); | |
61a127b3 MM |
1332 | break; |
1333 | ||
8d08fdba | 1334 | case COMPOUND_EXPR: |
b6fe0bb8 | 1335 | pp_left_paren (cxx_pp); |
7a3397c7 NS |
1336 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
1337 | pp_separate_with_comma (cxx_pp); | |
1338 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); | |
b6fe0bb8 | 1339 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1340 | break; |
1341 | ||
1342 | case COND_EXPR: | |
b6fe0bb8 | 1343 | pp_left_paren (cxx_pp); |
761f0855 | 1344 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1345 | pp_string (cxx_pp, " ? "); |
761f0855 | 1346 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1347 | pp_string (cxx_pp, " : "); |
761f0855 | 1348 | dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1349 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1350 | break; |
1351 | ||
1352 | case SAVE_EXPR: | |
1353 | if (TREE_HAS_CONSTRUCTOR (t)) | |
1354 | { | |
b6fe0bb8 | 1355 | pp_string (cxx_pp, "new "); |
9e93bc9d | 1356 | dump_type (TREE_TYPE (TREE_TYPE (t)), flags); |
8d08fdba MS |
1357 | } |
1358 | else | |
b6fe0bb8 | 1359 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
8d08fdba MS |
1360 | break; |
1361 | ||
02531345 | 1362 | case AGGR_INIT_EXPR: |
27b8d0cd MM |
1363 | { |
1364 | tree fn = NULL_TREE; | |
bb20cc46 | 1365 | |
27b8d0cd MM |
1366 | if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) |
1367 | fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0); | |
1368 | ||
1369 | if (fn && TREE_CODE (fn) == FUNCTION_DECL) | |
1370 | { | |
1371 | if (DECL_CONSTRUCTOR_P (fn)) | |
b6fe0bb8 | 1372 | pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (TREE_TYPE (t))); |
27b8d0cd MM |
1373 | else |
1374 | dump_decl (fn, 0); | |
1375 | } | |
1376 | else | |
1377 | dump_expr (TREE_OPERAND (t, 0), 0); | |
1378 | } | |
b6fe0bb8 | 1379 | pp_left_paren (cxx_pp); |
42976354 | 1380 | if (TREE_OPERAND (t, 1)) |
9e93bc9d | 1381 | dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); |
b6fe0bb8 | 1382 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1383 | break; |
1384 | ||
1385 | case CALL_EXPR: | |
1386 | { | |
1387 | tree fn = TREE_OPERAND (t, 0); | |
1388 | tree args = TREE_OPERAND (t, 1); | |
bb20cc46 | 1389 | |
8d08fdba MS |
1390 | if (TREE_CODE (fn) == ADDR_EXPR) |
1391 | fn = TREE_OPERAND (fn, 0); | |
1392 | ||
6467930b | 1393 | if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE) |
8d08fdba MS |
1394 | { |
1395 | tree ob = TREE_VALUE (args); | |
1396 | if (TREE_CODE (ob) == ADDR_EXPR) | |
1397 | { | |
761f0855 | 1398 | dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1399 | pp_dot (cxx_pp); |
8d08fdba MS |
1400 | } |
1401 | else if (TREE_CODE (ob) != PARM_DECL | |
1402 | || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) | |
1403 | { | |
761f0855 | 1404 | dump_expr (ob, flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1405 | pp_arrow (cxx_pp); |
8d08fdba MS |
1406 | } |
1407 | args = TREE_CHAIN (args); | |
1408 | } | |
761f0855 | 1409 | dump_expr (fn, flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1410 | pp_left_paren (cxx_pp); |
9e93bc9d | 1411 | dump_expr_list (args, flags); |
b6fe0bb8 | 1412 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1413 | } |
1414 | break; | |
1415 | ||
285baa06 JM |
1416 | case NEW_EXPR: |
1417 | { | |
1418 | tree type = TREE_OPERAND (t, 1); | |
60cde936 | 1419 | tree init = TREE_OPERAND (t, 2); |
285baa06 | 1420 | if (NEW_EXPR_USE_GLOBAL (t)) |
b6fe0bb8 GDR |
1421 | pp_colon_colon (cxx_pp); |
1422 | pp_string (cxx_pp, "new "); | |
285baa06 JM |
1423 | if (TREE_OPERAND (t, 0)) |
1424 | { | |
b6fe0bb8 | 1425 | pp_left_paren (cxx_pp); |
9e93bc9d | 1426 | dump_expr_list (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1427 | pp_string (cxx_pp, ") "); |
285baa06 JM |
1428 | } |
1429 | if (TREE_CODE (type) == ARRAY_REF) | |
1430 | type = build_cplus_array_type | |
1431 | (TREE_OPERAND (type, 0), | |
fed3cef0 RK |
1432 | build_index_type (fold (build (MINUS_EXPR, integer_type_node, |
1433 | TREE_OPERAND (type, 1), | |
1434 | integer_one_node)))); | |
9e93bc9d | 1435 | dump_type (type, flags); |
60cde936 | 1436 | if (init) |
285baa06 | 1437 | { |
b6fe0bb8 | 1438 | pp_left_paren (cxx_pp); |
60cde936 MM |
1439 | if (TREE_CODE (init) == TREE_LIST) |
1440 | dump_expr_list (init, flags); | |
1441 | else if (init == void_zero_node) | |
1442 | /* This representation indicates an empty initializer, | |
1443 | e.g.: "new int()". */ | |
1444 | ; | |
1445 | else | |
1446 | dump_expr (init, flags); | |
b6fe0bb8 | 1447 | pp_right_paren (cxx_pp); |
285baa06 JM |
1448 | } |
1449 | } | |
1450 | break; | |
1451 | ||
8d08fdba MS |
1452 | case TARGET_EXPR: |
1453 | /* Note that this only works for G++ target exprs. If somebody | |
1454 | builds a general TARGET_EXPR, there's no way to represent that | |
1455 | it initializes anything other that the parameter slot for the | |
1456 | default argument. Note we may have cleared out the first | |
1457 | operand in expand_expr, so don't go killing ourselves. */ | |
1458 | if (TREE_OPERAND (t, 1)) | |
761f0855 | 1459 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
8d08fdba MS |
1460 | break; |
1461 | ||
b3ab27f3 | 1462 | case INIT_EXPR: |
8d08fdba MS |
1463 | case MODIFY_EXPR: |
1464 | case PLUS_EXPR: | |
1465 | case MINUS_EXPR: | |
1466 | case MULT_EXPR: | |
1467 | case TRUNC_DIV_EXPR: | |
1468 | case TRUNC_MOD_EXPR: | |
1469 | case MIN_EXPR: | |
1470 | case MAX_EXPR: | |
1471 | case LSHIFT_EXPR: | |
1472 | case RSHIFT_EXPR: | |
1473 | case BIT_IOR_EXPR: | |
1474 | case BIT_XOR_EXPR: | |
1475 | case BIT_AND_EXPR: | |
8d08fdba MS |
1476 | case TRUTH_ANDIF_EXPR: |
1477 | case TRUTH_ORIF_EXPR: | |
1478 | case LT_EXPR: | |
1479 | case LE_EXPR: | |
1480 | case GT_EXPR: | |
1481 | case GE_EXPR: | |
1482 | case EQ_EXPR: | |
1483 | case NE_EXPR: | |
2adeacc9 | 1484 | case EXACT_DIV_EXPR: |
596ea4e5 | 1485 | dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags); |
8d08fdba MS |
1486 | break; |
1487 | ||
1488 | case CEIL_DIV_EXPR: | |
1489 | case FLOOR_DIV_EXPR: | |
1490 | case ROUND_DIV_EXPR: | |
9e93bc9d | 1491 | dump_binary_op ("/", t, flags); |
8d08fdba MS |
1492 | break; |
1493 | ||
1494 | case CEIL_MOD_EXPR: | |
1495 | case FLOOR_MOD_EXPR: | |
1496 | case ROUND_MOD_EXPR: | |
9e93bc9d | 1497 | dump_binary_op ("%", t, flags); |
8d08fdba MS |
1498 | break; |
1499 | ||
1500 | case COMPONENT_REF: | |
1501 | { | |
1502 | tree ob = TREE_OPERAND (t, 0); | |
1503 | if (TREE_CODE (ob) == INDIRECT_REF) | |
1504 | { | |
1505 | ob = TREE_OPERAND (ob, 0); | |
1506 | if (TREE_CODE (ob) != PARM_DECL | |
1507 | || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) | |
1508 | { | |
761f0855 | 1509 | dump_expr (ob, flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1510 | pp_arrow (cxx_pp); |
8d08fdba MS |
1511 | } |
1512 | } | |
1513 | else | |
1514 | { | |
761f0855 | 1515 | dump_expr (ob, flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1516 | pp_dot (cxx_pp); |
8d08fdba | 1517 | } |
761f0855 | 1518 | dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); |
8d08fdba MS |
1519 | } |
1520 | break; | |
1521 | ||
28cbf42c | 1522 | case ARRAY_REF: |
761f0855 | 1523 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1524 | pp_left_bracket (cxx_pp); |
761f0855 | 1525 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1526 | pp_right_bracket (cxx_pp); |
28cbf42c MS |
1527 | break; |
1528 | ||
8d08fdba | 1529 | case CONVERT_EXPR: |
03da5286 | 1530 | if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t))) |
df39af7d | 1531 | { |
b6fe0bb8 | 1532 | pp_left_paren (cxx_pp); |
b72801e2 | 1533 | dump_type (TREE_TYPE (t), flags); |
b6fe0bb8 | 1534 | pp_right_paren (cxx_pp); |
9e93bc9d | 1535 | dump_expr (TREE_OPERAND (t, 0), flags); |
df39af7d JM |
1536 | } |
1537 | else | |
9e93bc9d | 1538 | dump_unary_op ("+", t, flags); |
8d08fdba MS |
1539 | break; |
1540 | ||
1541 | case ADDR_EXPR: | |
1542 | if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL | |
fd74ca0b MM |
1543 | || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST |
1544 | /* An ADDR_EXPR can have reference type. In that case, we | |
1545 | shouldn't print the `&' doing so indicates to the user | |
1546 | that the expression has pointer type. */ | |
bb20cc46 | 1547 | || (TREE_TYPE (t) |
fd74ca0b | 1548 | && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) |
761f0855 | 1549 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
8d08fdba | 1550 | else |
9e93bc9d | 1551 | dump_unary_op ("&", t, flags); |
8d08fdba MS |
1552 | break; |
1553 | ||
1554 | case INDIRECT_REF: | |
1555 | if (TREE_HAS_CONSTRUCTOR (t)) | |
1556 | { | |
1557 | t = TREE_OPERAND (t, 0); | |
1558 | my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237); | |
761f0855 | 1559 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1560 | pp_left_paren (cxx_pp); |
9e93bc9d | 1561 | dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); |
b6fe0bb8 | 1562 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1563 | } |
1564 | else | |
1565 | { | |
6467930b | 1566 | if (TREE_OPERAND (t,0) != NULL_TREE |
5082a355 | 1567 | && TREE_TYPE (TREE_OPERAND (t, 0)) |
6467930b | 1568 | && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) |
9e93bc9d | 1569 | dump_expr (TREE_OPERAND (t, 0), flags); |
8d08fdba | 1570 | else |
9e93bc9d | 1571 | dump_unary_op ("*", t, flags); |
8d08fdba MS |
1572 | } |
1573 | break; | |
1574 | ||
1575 | case NEGATE_EXPR: | |
1576 | case BIT_NOT_EXPR: | |
1577 | case TRUTH_NOT_EXPR: | |
1578 | case PREDECREMENT_EXPR: | |
1579 | case PREINCREMENT_EXPR: | |
596ea4e5 | 1580 | dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags); |
8d08fdba MS |
1581 | break; |
1582 | ||
1583 | case POSTDECREMENT_EXPR: | |
1584 | case POSTINCREMENT_EXPR: | |
b6fe0bb8 | 1585 | pp_left_paren (cxx_pp); |
761f0855 | 1586 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 GDR |
1587 | pp_identifier (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name); |
1588 | pp_right_paren (cxx_pp); | |
8d08fdba MS |
1589 | break; |
1590 | ||
1591 | case NON_LVALUE_EXPR: | |
1592 | /* FIXME: This is a KLUDGE workaround for a parsing problem. There | |
1593 | should be another level of INDIRECT_REF so that I don't have to do | |
1594 | this. */ | |
6467930b | 1595 | if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) |
8d08fdba MS |
1596 | { |
1597 | tree next = TREE_TYPE (TREE_TYPE (t)); | |
1598 | ||
1599 | while (TREE_CODE (next) == POINTER_TYPE) | |
1600 | next = TREE_TYPE (next); | |
bb20cc46 | 1601 | |
8d08fdba MS |
1602 | if (TREE_CODE (next) == FUNCTION_TYPE) |
1603 | { | |
761f0855 | 1604 | if (flags & TFF_EXPR_IN_PARENS) |
b6fe0bb8 GDR |
1605 | pp_left_paren (cxx_pp); |
1606 | pp_star (cxx_pp); | |
761f0855 GDR |
1607 | dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); |
1608 | if (flags & TFF_EXPR_IN_PARENS) | |
b6fe0bb8 | 1609 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1610 | break; |
1611 | } | |
f4f206f4 | 1612 | /* Else fall through. */ |
8d08fdba | 1613 | } |
761f0855 | 1614 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
8d08fdba MS |
1615 | break; |
1616 | ||
1617 | case NOP_EXPR: | |
ffc76561 NS |
1618 | { |
1619 | tree op = TREE_OPERAND (t, 0); | |
1620 | ||
1621 | if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t))) | |
1622 | { | |
1623 | /* It is a cast, but we cannot tell whether it is a | |
1624 | reinterpret or static cast. Use the C style notation. */ | |
1625 | if (flags & TFF_EXPR_IN_PARENS) | |
1626 | pp_left_paren (cxx_pp); | |
1627 | pp_left_paren (cxx_pp); | |
1628 | dump_type (TREE_TYPE (t), flags); | |
1629 | pp_right_paren (cxx_pp); | |
1630 | dump_expr (op, flags | TFF_EXPR_IN_PARENS); | |
1631 | if (flags & TFF_EXPR_IN_PARENS) | |
1632 | pp_right_paren (cxx_pp); | |
1633 | } | |
1634 | else | |
1635 | dump_expr (op, flags); | |
1636 | break; | |
1637 | } | |
1638 | ||
89c6e7ac MM |
1639 | case EXPR_WITH_FILE_LOCATION: |
1640 | dump_expr (EXPR_WFL_NODE (t), flags); | |
1641 | break; | |
1642 | ||
8d08fdba | 1643 | case CONSTRUCTOR: |
9a3b49ac MS |
1644 | if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) |
1645 | { | |
50ad9642 | 1646 | tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); |
9a3b49ac | 1647 | |
c4372ef4 | 1648 | if (integer_zerop (idx)) |
e08a8f45 MM |
1649 | { |
1650 | /* A NULL pointer-to-member constant. */ | |
b6fe0bb8 GDR |
1651 | pp_left_paren (cxx_pp); |
1652 | pp_left_paren (cxx_pp); | |
9e93bc9d | 1653 | dump_type (TREE_TYPE (t), flags); |
b6fe0bb8 GDR |
1654 | pp_right_paren (cxx_pp); |
1655 | pp_string (cxx_pp, ")0)"); | |
e08a8f45 MM |
1656 | break; |
1657 | } | |
665f2503 | 1658 | else if (host_integerp (idx, 0)) |
9a3b49ac MS |
1659 | { |
1660 | tree virtuals; | |
1661 | unsigned HOST_WIDE_INT n; | |
1662 | ||
1663 | t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); | |
1664 | t = TYPE_METHOD_BASETYPE (t); | |
83f2ccf4 | 1665 | virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t)); |
bb20cc46 | 1666 | |
1f84ec23 | 1667 | n = tree_low_cst (idx, 0); |
9a3b49ac MS |
1668 | |
1669 | /* Map vtable index back one, to allow for the null pointer to | |
1670 | member. */ | |
1671 | --n; | |
1672 | ||
1673 | while (n > 0 && virtuals) | |
1674 | { | |
1675 | --n; | |
1676 | virtuals = TREE_CHAIN (virtuals); | |
1677 | } | |
1678 | if (virtuals) | |
1679 | { | |
31f8e4f3 | 1680 | dump_expr (BV_FN (virtuals), |
761f0855 | 1681 | flags | TFF_EXPR_IN_PARENS); |
9a3b49ac MS |
1682 | break; |
1683 | } | |
1684 | } | |
1685 | } | |
f3146d75 NS |
1686 | if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t)) |
1687 | { | |
1688 | dump_type (TREE_TYPE (t), 0); | |
b6fe0bb8 GDR |
1689 | pp_left_paren (cxx_pp); |
1690 | pp_right_paren (cxx_pp); | |
f3146d75 NS |
1691 | } |
1692 | else | |
1693 | { | |
b6fe0bb8 | 1694 | pp_left_brace (cxx_pp); |
f3146d75 | 1695 | dump_expr_list (CONSTRUCTOR_ELTS (t), flags); |
b6fe0bb8 | 1696 | pp_right_brace (cxx_pp); |
f3146d75 NS |
1697 | } |
1698 | ||
8d08fdba MS |
1699 | break; |
1700 | ||
51c184be MS |
1701 | case OFFSET_REF: |
1702 | { | |
1703 | tree ob = TREE_OPERAND (t, 0); | |
51924768 | 1704 | if (is_dummy_object (ob)) |
61a127b3 | 1705 | { |
05e0b2f4 JM |
1706 | t = TREE_OPERAND (t, 1); |
1707 | if (TREE_CODE (t) == FUNCTION_DECL) | |
61a127b3 | 1708 | /* A::f */ |
761f0855 | 1709 | dump_expr (t, flags | TFF_EXPR_IN_PARENS); |
05e0b2f4 | 1710 | else if (BASELINK_P (t)) |
da15dae6 MM |
1711 | dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), |
1712 | flags | TFF_EXPR_IN_PARENS); | |
61a127b3 | 1713 | else |
9e93bc9d | 1714 | dump_decl (t, flags); |
61a127b3 | 1715 | } |
51c184be MS |
1716 | else |
1717 | { | |
bbcec105 JM |
1718 | if (TREE_CODE (ob) == INDIRECT_REF) |
1719 | { | |
761f0855 | 1720 | dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1721 | pp_string (cxx_pp, "->*"); |
bbcec105 JM |
1722 | } |
1723 | else | |
1724 | { | |
761f0855 | 1725 | dump_expr (ob, flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1726 | pp_string (cxx_pp, ".*"); |
bbcec105 | 1727 | } |
761f0855 | 1728 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
51c184be MS |
1729 | } |
1730 | break; | |
1731 | } | |
1732 | ||
f84b4be9 | 1733 | case TEMPLATE_PARM_INDEX: |
761f0855 | 1734 | dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS); |
de22184b | 1735 | break; |
5566b478 | 1736 | |
5566b478 | 1737 | case SCOPE_REF: |
9e93bc9d | 1738 | dump_type (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1739 | pp_colon_colon (cxx_pp); |
761f0855 | 1740 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
5566b478 MS |
1741 | break; |
1742 | ||
1743 | case CAST_EXPR: | |
e349ee73 MS |
1744 | if (TREE_OPERAND (t, 0) == NULL_TREE |
1745 | || TREE_CHAIN (TREE_OPERAND (t, 0))) | |
e76a2646 | 1746 | { |
9e93bc9d | 1747 | dump_type (TREE_TYPE (t), flags); |
b6fe0bb8 | 1748 | pp_left_paren (cxx_pp); |
9e93bc9d | 1749 | dump_expr_list (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1750 | pp_right_paren (cxx_pp); |
e76a2646 MS |
1751 | } |
1752 | else | |
1753 | { | |
b6fe0bb8 | 1754 | pp_left_paren (cxx_pp); |
9e93bc9d | 1755 | dump_type (TREE_TYPE (t), flags); |
b6fe0bb8 | 1756 | pp_string (cxx_pp, ")("); |
9e93bc9d | 1757 | dump_expr_list (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1758 | pp_right_paren (cxx_pp); |
e76a2646 MS |
1759 | } |
1760 | break; | |
1761 | ||
477f6664 | 1762 | case STATIC_CAST_EXPR: |
b6fe0bb8 | 1763 | pp_string (cxx_pp, "static_cast<"); |
477f6664 JM |
1764 | goto cast; |
1765 | case REINTERPRET_CAST_EXPR: | |
b6fe0bb8 | 1766 | pp_string (cxx_pp, "reinterpret_cast<"); |
477f6664 JM |
1767 | goto cast; |
1768 | case CONST_CAST_EXPR: | |
b6fe0bb8 | 1769 | pp_string (cxx_pp, "const_cast<"); |
477f6664 JM |
1770 | goto cast; |
1771 | case DYNAMIC_CAST_EXPR: | |
b6fe0bb8 | 1772 | pp_string (cxx_pp, "dynamic_cast<"); |
477f6664 JM |
1773 | cast: |
1774 | dump_type (TREE_TYPE (t), flags); | |
b6fe0bb8 | 1775 | pp_string (cxx_pp, ">("); |
477f6664 | 1776 | dump_expr (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1777 | pp_right_paren (cxx_pp); |
477f6664 JM |
1778 | break; |
1779 | ||
5a11e05b | 1780 | case ARROW_EXPR: |
9e93bc9d | 1781 | dump_expr (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1782 | pp_arrow (cxx_pp); |
5a11e05b BK |
1783 | break; |
1784 | ||
e76a2646 | 1785 | case SIZEOF_EXPR: |
abff8e06 JM |
1786 | case ALIGNOF_EXPR: |
1787 | if (TREE_CODE (t) == SIZEOF_EXPR) | |
b6fe0bb8 | 1788 | pp_string (cxx_pp, "sizeof ("); |
bb20cc46 | 1789 | else |
abff8e06 JM |
1790 | { |
1791 | my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0); | |
b6fe0bb8 | 1792 | pp_string (cxx_pp, "__alignof__ ("); |
abff8e06 | 1793 | } |
2f939d94 | 1794 | if (TYPE_P (TREE_OPERAND (t, 0))) |
9e93bc9d | 1795 | dump_type (TREE_OPERAND (t, 0), flags); |
e76a2646 | 1796 | else |
44978276 | 1797 | dump_expr (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 | 1798 | pp_right_paren (cxx_pp); |
e76a2646 | 1799 | break; |
5566b478 | 1800 | |
19948e32 GDR |
1801 | case REALPART_EXPR: |
1802 | case IMAGPART_EXPR: | |
b6fe0bb8 GDR |
1803 | pp_identifier (cxx_pp, operator_name_info[TREE_CODE (t)].name); |
1804 | pp_space (cxx_pp); | |
19948e32 GDR |
1805 | dump_expr (TREE_OPERAND (t, 0), flags); |
1806 | break; | |
1807 | ||
da20811c | 1808 | case DEFAULT_ARG: |
b6fe0bb8 | 1809 | pp_identifier (cxx_pp, "<unparsed>"); |
da20811c JM |
1810 | break; |
1811 | ||
6748b643 JM |
1812 | case TRY_CATCH_EXPR: |
1813 | case WITH_CLEANUP_EXPR: | |
1814 | case CLEANUP_POINT_EXPR: | |
9e93bc9d | 1815 | dump_expr (TREE_OPERAND (t, 0), flags); |
6748b643 JM |
1816 | break; |
1817 | ||
40242ccf | 1818 | case PSEUDO_DTOR_EXPR: |
9e93bc9d | 1819 | dump_expr (TREE_OPERAND (t, 2), flags); |
b6fe0bb8 | 1820 | pp_dot (cxx_pp); |
9e93bc9d | 1821 | dump_type (TREE_OPERAND (t, 0), flags); |
b6fe0bb8 GDR |
1822 | pp_colon_colon (cxx_pp); |
1823 | pp_complement (cxx_pp); | |
9e93bc9d | 1824 | dump_type (TREE_OPERAND (t, 1), flags); |
40242ccf MM |
1825 | break; |
1826 | ||
7ac7b28f | 1827 | case TEMPLATE_ID_EXPR: |
9e93bc9d | 1828 | dump_decl (t, flags); |
7ac7b28f MM |
1829 | break; |
1830 | ||
558475f0 MM |
1831 | case STMT_EXPR: |
1832 | /* We don't yet have a way of dumping statements in a | |
1833 | human-readable format. */ | |
b6fe0bb8 | 1834 | pp_string (cxx_pp, "({...})"); |
558475f0 MM |
1835 | break; |
1836 | ||
0045e0bc | 1837 | case BIND_EXPR: |
b6fe0bb8 | 1838 | pp_left_brace (cxx_pp); |
761f0855 | 1839 | dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1840 | pp_right_brace (cxx_pp); |
0045e0bc | 1841 | break; |
bb20cc46 | 1842 | |
0045e0bc | 1843 | case LOOP_EXPR: |
b6fe0bb8 | 1844 | pp_string (cxx_pp, "while (1) { "); |
761f0855 | 1845 | dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1846 | pp_right_brace (cxx_pp); |
0045e0bc MM |
1847 | break; |
1848 | ||
1849 | case EXIT_EXPR: | |
b6fe0bb8 | 1850 | pp_string (cxx_pp, "if ("); |
761f0855 | 1851 | dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1852 | pp_string (cxx_pp, ") break; "); |
0045e0bc MM |
1853 | break; |
1854 | ||
a723baf1 | 1855 | case BASELINK: |
bd83b409 | 1856 | dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS); |
a723baf1 MM |
1857 | break; |
1858 | ||
98ed3906 GDR |
1859 | case EMPTY_CLASS_EXPR: |
1860 | dump_type (TREE_TYPE (t), flags); | |
b6fe0bb8 GDR |
1861 | pp_left_paren (cxx_pp); |
1862 | pp_right_paren (cxx_pp); | |
98ed3906 GDR |
1863 | break; |
1864 | ||
d17811fd | 1865 | case NON_DEPENDENT_EXPR: |
018a5803 | 1866 | dump_expr (TREE_OPERAND (t, 0), flags); |
d17811fd | 1867 | break; |
00595019 | 1868 | |
8d08fdba MS |
1869 | /* This list is incomplete, but should suffice for now. |
1870 | It is very important that `sorry' does not call | |
1871 | `report_error_function'. That could cause an infinite loop. */ | |
1872 | default: | |
b6fe0bb8 | 1873 | pp_unsupported_tree (cxx_pp, t); |
8d08fdba MS |
1874 | /* fall through to ERROR_MARK... */ |
1875 | case ERROR_MARK: | |
b6fe0bb8 | 1876 | pp_identifier (cxx_pp, "<expression error>"); |
8d08fdba MS |
1877 | break; |
1878 | } | |
1879 | } | |
1880 | ||
1881 | static void | |
3f8548e7 | 1882 | dump_binary_op (const char *opstring, tree t, int flags) |
8d08fdba | 1883 | { |
b6fe0bb8 | 1884 | pp_left_paren (cxx_pp); |
761f0855 | 1885 | dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1886 | pp_space (cxx_pp); |
2adeacc9 | 1887 | if (opstring) |
b6fe0bb8 | 1888 | pp_identifier (cxx_pp, opstring); |
2adeacc9 | 1889 | else |
b6fe0bb8 GDR |
1890 | pp_identifier (cxx_pp, "<unknown operator>"); |
1891 | pp_space (cxx_pp); | |
761f0855 | 1892 | dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
b6fe0bb8 | 1893 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1894 | } |
1895 | ||
1896 | static void | |
3f8548e7 | 1897 | dump_unary_op (const char *opstring, tree t, int flags) |
8d08fdba | 1898 | { |
761f0855 | 1899 | if (flags & TFF_EXPR_IN_PARENS) |
b6fe0bb8 GDR |
1900 | pp_left_paren (cxx_pp); |
1901 | pp_identifier (cxx_pp, opstring); | |
761f0855 GDR |
1902 | dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); |
1903 | if (flags & TFF_EXPR_IN_PARENS) | |
b6fe0bb8 | 1904 | pp_right_paren (cxx_pp); |
8d08fdba MS |
1905 | } |
1906 | ||
761f0855 | 1907 | /* Exported interface to stringifying types, exprs and decls under TFF_* |
9e93bc9d | 1908 | control. */ |
4995028c | 1909 | |
e1def31b | 1910 | const char * |
3f8548e7 | 1911 | type_as_string (tree typ, int flags) |
8d08fdba | 1912 | { |
b6fe0bb8 | 1913 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 1914 | dump_type (typ, flags); |
b6fe0bb8 | 1915 | return pp_formatted_text (cxx_pp); |
8d08fdba MS |
1916 | } |
1917 | ||
e1def31b | 1918 | const char * |
3f8548e7 | 1919 | expr_as_string (tree decl, int flags) |
8d08fdba | 1920 | { |
b6fe0bb8 | 1921 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 1922 | dump_expr (decl, flags); |
b6fe0bb8 | 1923 | return pp_formatted_text (cxx_pp); |
8d08fdba MS |
1924 | } |
1925 | ||
e1def31b | 1926 | const char * |
3f8548e7 | 1927 | decl_as_string (tree decl, int flags) |
8d08fdba | 1928 | { |
b6fe0bb8 | 1929 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 1930 | dump_decl (decl, flags); |
b6fe0bb8 | 1931 | return pp_formatted_text (cxx_pp); |
8d08fdba MS |
1932 | } |
1933 | ||
e1def31b | 1934 | const char * |
3f8548e7 | 1935 | context_as_string (tree context, int flags) |
8d08fdba | 1936 | { |
b6fe0bb8 | 1937 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 1938 | dump_scope (context, flags); |
b6fe0bb8 | 1939 | return pp_formatted_text (cxx_pp); |
8d08fdba MS |
1940 | } |
1941 | ||
7afff7cf | 1942 | /* Generate the three forms of printable names for cxx_printable_name. */ |
2ba25f50 | 1943 | |
e1def31b | 1944 | const char * |
3f8548e7 | 1945 | lang_decl_name (tree decl, int v) |
2ba25f50 MS |
1946 | { |
1947 | if (v >= 2) | |
761f0855 | 1948 | return decl_as_string (decl, TFF_DECL_SPECIFIERS); |
2ba25f50 | 1949 | |
b6fe0bb8 | 1950 | pp_clear_output_area (cxx_pp); |
6eb3bb27 | 1951 | if (v == 1 && DECL_CLASS_SCOPE_P (decl)) |
2ba25f50 | 1952 | { |
761f0855 | 1953 | dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); |
b6fe0bb8 | 1954 | pp_colon_colon (cxx_pp); |
2ba25f50 MS |
1955 | } |
1956 | ||
1957 | if (TREE_CODE (decl) == FUNCTION_DECL) | |
761f0855 | 1958 | dump_function_name (decl, TFF_PLAIN_IDENTIFIER); |
2ba25f50 | 1959 | else |
761f0855 | 1960 | dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); |
2ba25f50 | 1961 | |
b6fe0bb8 | 1962 | return pp_formatted_text (cxx_pp); |
2ba25f50 | 1963 | } |
2ba25f50 | 1964 | |
9a472a42 NS |
1965 | static location_t |
1966 | location_of (tree t) | |
8d08fdba | 1967 | { |
741f2839 | 1968 | if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) |
9a472a42 | 1969 | t = DECL_CONTEXT (t); |
2f939d94 | 1970 | else if (TYPE_P (t)) |
9a472a42 | 1971 | t = TYPE_MAIN_DECL (t); |
8f032717 | 1972 | else if (TREE_CODE (t) == OVERLOAD) |
9a472a42 NS |
1973 | t = OVL_FUNCTION (t); |
1974 | ||
f31686a3 | 1975 | return DECL_SOURCE_LOCATION (t); |
8d08fdba MS |
1976 | } |
1977 | ||
33bd39a2 | 1978 | /* Now the interfaces from error et al to dump_type et al. Each takes an |
761f0855 | 1979 | on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_ |
9e93bc9d NS |
1980 | function. */ |
1981 | ||
1982 | static const char * | |
3f8548e7 | 1983 | decl_to_string (tree decl, int verbose) |
9e93bc9d | 1984 | { |
761f0855 | 1985 | int flags = 0; |
d67cdbc3 | 1986 | |
9e93bc9d NS |
1987 | if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE |
1988 | || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE) | |
761f0855 | 1989 | flags = TFF_CLASS_KEY_OR_ENUM; |
9e93bc9d | 1990 | if (verbose) |
4a386498 | 1991 | flags |= TFF_DECL_SPECIFIERS; |
9e93bc9d | 1992 | else if (TREE_CODE (decl) == FUNCTION_DECL) |
761f0855 GDR |
1993 | flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE; |
1994 | flags |= TFF_TEMPLATE_HEADER; | |
bb20cc46 | 1995 | |
b6fe0bb8 | 1996 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 1997 | dump_decl (decl, flags); |
b6fe0bb8 | 1998 | return pp_formatted_text (cxx_pp); |
9e93bc9d NS |
1999 | } |
2000 | ||
2001 | static const char * | |
4e3f84b7 | 2002 | expr_to_string (tree decl) |
9e93bc9d | 2003 | { |
b6fe0bb8 | 2004 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 2005 | dump_expr (decl, 0); |
b6fe0bb8 | 2006 | return pp_formatted_text (cxx_pp); |
9e93bc9d NS |
2007 | } |
2008 | ||
2009 | static const char * | |
3f8548e7 | 2010 | fndecl_to_string (tree fndecl, int verbose) |
9e93bc9d | 2011 | { |
761f0855 | 2012 | int flags; |
bb20cc46 | 2013 | |
761f0855 | 2014 | flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS; |
9e93bc9d | 2015 | if (verbose) |
761f0855 | 2016 | flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS; |
b6fe0bb8 | 2017 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 2018 | dump_decl (fndecl, flags); |
b6fe0bb8 | 2019 | return pp_formatted_text (cxx_pp); |
9e93bc9d NS |
2020 | } |
2021 | ||
2022 | ||
2023 | static const char * | |
4e3f84b7 | 2024 | code_to_string (enum tree_code c) |
8d08fdba MS |
2025 | { |
2026 | return tree_code_name [c]; | |
2027 | } | |
2028 | ||
421844e7 | 2029 | const char * |
4e3f84b7 | 2030 | language_to_string (enum languages c) |
8d08fdba MS |
2031 | { |
2032 | switch (c) | |
2033 | { | |
2034 | case lang_c: | |
2035 | return "C"; | |
2036 | ||
2037 | case lang_cplusplus: | |
2038 | return "C++"; | |
2039 | ||
31b72b87 PB |
2040 | case lang_java: |
2041 | return "Java"; | |
2042 | ||
8d08fdba | 2043 | default: |
a98facb0 | 2044 | abort (); |
8926095f | 2045 | return 0; |
8d08fdba MS |
2046 | } |
2047 | } | |
2048 | ||
2049 | /* Return the proper printed version of a parameter to a C++ function. */ | |
e92cc029 | 2050 | |
9e93bc9d | 2051 | static const char * |
4e3f84b7 | 2052 | parm_to_string (int p) |
8d08fdba | 2053 | { |
b6fe0bb8 | 2054 | pp_clear_output_area (cxx_pp); |
8d08fdba | 2055 | if (p < 0) |
b6fe0bb8 | 2056 | pp_string (cxx_pp, "'this'"); |
4e3f84b7 | 2057 | else |
b6fe0bb8 GDR |
2058 | pp_decimal_int (cxx_pp, p + 1); |
2059 | return pp_formatted_text (cxx_pp); | |
8d08fdba MS |
2060 | } |
2061 | ||
9e93bc9d | 2062 | static const char * |
4e3f84b7 | 2063 | op_to_string (enum tree_code p) |
8d08fdba | 2064 | { |
b6fe0bb8 | 2065 | tree id = operator_name_info[(int) p].identifier; |
4e3f84b7 | 2066 | return id ? IDENTIFIER_POINTER (id) : "<unknown>"; |
8d08fdba MS |
2067 | } |
2068 | ||
9e93bc9d | 2069 | static const char * |
3f8548e7 | 2070 | type_to_string (tree typ, int verbose) |
9e93bc9d | 2071 | { |
b6fe0bb8 | 2072 | int flags = 0; |
9e93bc9d | 2073 | if (verbose) |
761f0855 GDR |
2074 | flags |= TFF_CLASS_KEY_OR_ENUM; |
2075 | flags |= TFF_TEMPLATE_HEADER; | |
bb20cc46 | 2076 | |
b6fe0bb8 | 2077 | pp_clear_output_area (cxx_pp); |
9e93bc9d | 2078 | dump_type (typ, flags); |
b6fe0bb8 | 2079 | return pp_formatted_text (cxx_pp); |
9e93bc9d NS |
2080 | } |
2081 | ||
2082 | static const char * | |
4e3f84b7 | 2083 | assop_to_string (enum tree_code p) |
c91a56d2 | 2084 | { |
b6fe0bb8 | 2085 | tree id = assignment_operator_name_info[(int) p].identifier; |
596ea4e5 | 2086 | return id ? IDENTIFIER_POINTER (id) : "{unknown}"; |
c91a56d2 MS |
2087 | } |
2088 | ||
9e93bc9d | 2089 | static const char * |
3f8548e7 | 2090 | args_to_string (tree p, int verbose) |
8d08fdba | 2091 | { |
761f0855 | 2092 | int flags = 0; |
9e93bc9d | 2093 | if (verbose) |
761f0855 | 2094 | flags |= TFF_CLASS_KEY_OR_ENUM; |
bb20cc46 | 2095 | |
8d08fdba | 2096 | if (p == NULL_TREE) |
c73964b2 | 2097 | return ""; |
8d08fdba | 2098 | |
2f939d94 | 2099 | if (TYPE_P (TREE_VALUE (p))) |
9e93bc9d | 2100 | return type_as_string (p, flags); |
c73964b2 | 2101 | |
b6fe0bb8 | 2102 | pp_clear_output_area (cxx_pp); |
c73964b2 MS |
2103 | for (; p; p = TREE_CHAIN (p)) |
2104 | { | |
a6967cc0 | 2105 | if (TREE_VALUE (p) == null_node) |
b6fe0bb8 | 2106 | pp_identifier (cxx_pp, "NULL"); |
a6967cc0 | 2107 | else |
9e93bc9d | 2108 | dump_type (error_type (TREE_VALUE (p)), flags); |
c73964b2 | 2109 | if (TREE_CHAIN (p)) |
b6fe0bb8 | 2110 | pp_separate_with_comma (cxx_pp); |
c73964b2 | 2111 | } |
b6fe0bb8 | 2112 | return pp_formatted_text (cxx_pp); |
8d08fdba | 2113 | } |
f30432d7 | 2114 | |
9e93bc9d | 2115 | static const char * |
3f8548e7 | 2116 | cv_to_string (tree p, int v) |
f30432d7 | 2117 | { |
b6fe0bb8 | 2118 | pp_clear_output_area (cxx_pp); |
ea50ad82 | 2119 | dump_qualifiers (p, v ? before : none); |
b6fe0bb8 | 2120 | return pp_formatted_text (cxx_pp); |
f30432d7 | 2121 | } |
cb753e49 | 2122 | |
7cb32822 NB |
2123 | /* Langhook for print_error_function. */ |
2124 | void | |
3f8548e7 | 2125 | cxx_print_error_function (diagnostic_context *context, const char *file) |
a72462a4 | 2126 | { |
7cb32822 | 2127 | lhd_print_error_function (context, file); |
e1a4dd13 | 2128 | pp_base_set_prefix (context->printer, file); |
47b69537 | 2129 | maybe_print_instantiation_context (context); |
a72462a4 GDR |
2130 | } |
2131 | ||
cb753e49 | 2132 | static void |
3f8548e7 GDR |
2133 | cp_diagnostic_starter (diagnostic_context *context, |
2134 | diagnostic_info *diagnostic) | |
cb753e49 | 2135 | { |
47b69537 GDR |
2136 | diagnostic_report_current_module (context); |
2137 | cp_print_error_function (context, diagnostic); | |
2138 | maybe_print_instantiation_context (context); | |
e1a4dd13 | 2139 | pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic)); |
cb753e49 GDR |
2140 | } |
2141 | ||
2142 | static void | |
3f8548e7 GDR |
2143 | cp_diagnostic_finalizer (diagnostic_context *context, |
2144 | diagnostic_info *diagnostic ATTRIBUTE_UNUSED) | |
cb753e49 | 2145 | { |
e1a4dd13 | 2146 | pp_base_destroy_prefix (context->printer); |
cb753e49 GDR |
2147 | } |
2148 | ||
2149 | /* Print current function onto BUFFER, in the process of reporting | |
2150 | a diagnostic message. Called from cp_diagnostic_starter. */ | |
2151 | static void | |
3f8548e7 GDR |
2152 | cp_print_error_function (diagnostic_context *context, |
2153 | diagnostic_info *diagnostic) | |
cb753e49 | 2154 | { |
47b69537 | 2155 | if (diagnostic_last_function_changed (context)) |
cb753e49 | 2156 | { |
b6fe0bb8 | 2157 | const char *old_prefix = context->printer->prefix; |
47b69537 GDR |
2158 | char *new_prefix = diagnostic->location.file |
2159 | ? file_name_as_prefix (diagnostic->location.file) | |
cb753e49 | 2160 | : NULL; |
cb753e49 | 2161 | |
e1a4dd13 | 2162 | pp_base_set_prefix (context->printer, new_prefix); |
bb20cc46 | 2163 | |
cb753e49 | 2164 | if (current_function_decl == NULL) |
e1a4dd13 | 2165 | pp_base_string (context->printer, "At global scope:"); |
cb753e49 | 2166 | else |
b6fe0bb8 GDR |
2167 | pp_printf (context->printer, "In %s `%s':", |
2168 | function_category (current_function_decl), | |
2169 | cxx_printable_name (current_function_decl, 2)); | |
e1a4dd13 | 2170 | pp_base_newline (context->printer); |
47b69537 GDR |
2171 | |
2172 | diagnostic_set_last_function (context); | |
e1a4dd13 | 2173 | pp_base_destroy_prefix (context->printer); |
b6fe0bb8 | 2174 | context->printer->prefix = old_prefix; |
cb753e49 GDR |
2175 | } |
2176 | } | |
2177 | ||
2178 | /* Returns a description of FUNCTION using standard terminology. */ | |
2179 | static const char * | |
3f8548e7 | 2180 | function_category (tree fn) |
cb753e49 GDR |
2181 | { |
2182 | if (DECL_FUNCTION_MEMBER_P (fn)) | |
2183 | { | |
2184 | if (DECL_STATIC_FUNCTION_P (fn)) | |
2185 | return "static member function"; | |
2186 | else if (DECL_COPY_CONSTRUCTOR_P (fn)) | |
2187 | return "copy constructor"; | |
2188 | else if (DECL_CONSTRUCTOR_P (fn)) | |
2189 | return "constructor"; | |
2190 | else if (DECL_DESTRUCTOR_P (fn)) | |
2191 | return "destructor"; | |
2192 | else | |
2193 | return "member function"; | |
2194 | } | |
2195 | else | |
2196 | return "function"; | |
2197 | } | |
2198 | ||
2199 | /* Report the full context of a current template instantiation, | |
2200 | onto BUFFER. */ | |
2201 | static void | |
3f8548e7 | 2202 | print_instantiation_full_context (diagnostic_context *context) |
cb753e49 GDR |
2203 | { |
2204 | tree p = current_instantiation (); | |
82a98427 NS |
2205 | location_t location = input_location; |
2206 | ||
cb753e49 GDR |
2207 | if (p) |
2208 | { | |
2209 | if (current_function_decl != TINST_DECL (p) | |
2210 | && current_function_decl != NULL_TREE) | |
2211 | /* We can get here during the processing of some synthesized | |
2212 | method. Then, TINST_DECL (p) will be the function that's causing | |
2213 | the synthesis. */ | |
2214 | ; | |
2215 | else | |
2216 | { | |
2217 | if (current_function_decl == TINST_DECL (p)) | |
2218 | /* Avoid redundancy with the the "In function" line. */; | |
bb20cc46 | 2219 | else |
b6fe0bb8 GDR |
2220 | pp_verbatim (context->printer, |
2221 | "%s: In instantiation of `%s':\n", location.file, | |
2222 | decl_as_string (TINST_DECL (p), | |
2223 | TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); | |
bb20cc46 | 2224 | |
82a98427 NS |
2225 | location.line = TINST_LINE (p); |
2226 | location.file = TINST_FILE (p); | |
cb753e49 GDR |
2227 | p = TREE_CHAIN (p); |
2228 | } | |
2229 | } | |
bb20cc46 | 2230 | |
35773471 | 2231 | print_instantiation_partial_context (context, p, location); |
cb753e49 GDR |
2232 | } |
2233 | ||
2234 | /* Same as above but less verbose. */ | |
2235 | static void | |
3f8548e7 | 2236 | print_instantiation_partial_context (diagnostic_context *context, |
35773471 | 2237 | tree t, location_t loc) |
cb753e49 GDR |
2238 | { |
2239 | for (; t; t = TREE_CHAIN (t)) | |
2240 | { | |
b6fe0bb8 GDR |
2241 | pp_verbatim (context->printer, "%s:%d: instantiated from `%s'\n", |
2242 | loc.file, loc.line, | |
2243 | decl_as_string (TINST_DECL (t), | |
2244 | TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); | |
35773471 NS |
2245 | loc.line = TINST_LINE (t); |
2246 | loc.file = TINST_FILE (t); | |
cb753e49 | 2247 | } |
b6fe0bb8 GDR |
2248 | pp_verbatim (context->printer, "%s:%d: instantiated from here\n", |
2249 | loc.file, loc.line); | |
cb753e49 GDR |
2250 | } |
2251 | ||
2252 | /* Called from cp_thing to print the template context for an error. */ | |
2253 | static void | |
3f8548e7 | 2254 | maybe_print_instantiation_context (diagnostic_context *context) |
cb753e49 GDR |
2255 | { |
2256 | if (!problematic_instantiation_changed () || current_instantiation () == 0) | |
2257 | return; | |
2258 | ||
2259 | record_last_problematic_instantiation (); | |
47b69537 | 2260 | print_instantiation_full_context (context); |
cb753e49 GDR |
2261 | } |
2262 | ||
2263 | /* Report the bare minimum context of a template instantiation. */ | |
2264 | void | |
3f8548e7 | 2265 | print_instantiation_context (void) |
cb753e49 GDR |
2266 | { |
2267 | print_instantiation_partial_context | |
35773471 | 2268 | (global_dc, current_instantiation (), input_location); |
47b69537 | 2269 | diagnostic_flush_buffer (global_dc); |
cb753e49 | 2270 | } |
a1066c99 GDR |
2271 | \f |
2272 | /* Called from output_format -- during diagnostic message processing -- | |
2273 | to handle C++ specific format specifier with the following meanings: | |
2274 | %A function argument-list. | |
749ced52 | 2275 | %C tree code. |
a1066c99 GDR |
2276 | %D declaration. |
2277 | %E expression. | |
2278 | %F function declaration. | |
749ced52 ZW |
2279 | %L language as used in extern "lang". |
2280 | %O binary operator. | |
a1066c99 | 2281 | %P function parameter whose position is indicated by an integer. |
749ced52 | 2282 | %Q assignment operator. |
a1066c99 GDR |
2283 | %T type. |
2284 | %V cv-qualifier. */ | |
47b69537 | 2285 | static bool |
b6fe0bb8 | 2286 | cp_printer (pretty_printer *pp, text_info *text) |
a1066c99 | 2287 | { |
749ced52 ZW |
2288 | int verbose = 0; |
2289 | const char *result; | |
47b69537 GDR |
2290 | #define next_tree va_arg (*text->args_ptr, tree) |
2291 | #define next_tcode va_arg (*text->args_ptr, enum tree_code) | |
2292 | #define next_lang va_arg (*text->args_ptr, enum languages) | |
2293 | #define next_int va_arg (*text->args_ptr, int) | |
2294 | ||
2295 | if (*text->format_spec == '+') | |
2296 | ++text->format_spec; | |
2297 | if (*text->format_spec == '#') | |
a1066c99 | 2298 | { |
749ced52 | 2299 | verbose = 1; |
47b69537 | 2300 | ++text->format_spec; |
a1066c99 GDR |
2301 | } |
2302 | ||
47b69537 | 2303 | switch (*text->format_spec) |
22a4158c | 2304 | { |
749ced52 | 2305 | case 'A': result = args_to_string (next_tree, verbose); break; |
4e3f84b7 | 2306 | case 'C': result = code_to_string (next_tcode); break; |
749ced52 | 2307 | case 'D': result = decl_to_string (next_tree, verbose); break; |
4e3f84b7 | 2308 | case 'E': result = expr_to_string (next_tree); break; |
749ced52 | 2309 | case 'F': result = fndecl_to_string (next_tree, verbose); break; |
4e3f84b7 GDR |
2310 | case 'L': result = language_to_string (next_lang); break; |
2311 | case 'O': result = op_to_string (next_tcode); break; | |
2312 | case 'P': result = parm_to_string (next_int); break; | |
2313 | case 'Q': result = assop_to_string (next_tcode); break; | |
749ced52 ZW |
2314 | case 'T': result = type_to_string (next_tree, verbose); break; |
2315 | case 'V': result = cv_to_string (next_tree, verbose); break; | |
2316 | ||
22a4158c | 2317 | default: |
47b69537 | 2318 | return false; |
a1066c99 | 2319 | } |
bb20cc46 | 2320 | |
e1a4dd13 | 2321 | pp_base_string (pp, result); |
47b69537 | 2322 | return true; |
749ced52 ZW |
2323 | #undef next_tree |
2324 | #undef next_tcode | |
2325 | #undef next_lang | |
2326 | #undef next_int | |
a1066c99 GDR |
2327 | } |
2328 | ||
a1066c99 | 2329 | static void |
e1a4dd13 | 2330 | pp_non_consecutive_character (cxx_pretty_printer *pp, int c) |
c3e76028 | 2331 | { |
b6fe0bb8 | 2332 | const char *p = pp_last_position_in_text (pp); |
c3e76028 | 2333 | |
749ced52 | 2334 | if (p != NULL && *p == c) |
b6fe0bb8 GDR |
2335 | pp_space (pp); |
2336 | pp_character (pp, c); | |
c3e76028 GDR |
2337 | } |
2338 | ||
749ced52 ZW |
2339 | /* These are temporary wrapper functions which handle the historic |
2340 | behavior of cp_*_at. */ | |
c3e76028 | 2341 | |
749ced52 | 2342 | static tree |
3f8548e7 | 2343 | locate_error (const char *msgid, va_list ap) |
c3e76028 | 2344 | { |
749ced52 ZW |
2345 | tree here = 0, t; |
2346 | int plus = 0; | |
2347 | const char *f; | |
c3e76028 | 2348 | |
749ced52 | 2349 | for (f = msgid; *f; f++) |
c3e76028 | 2350 | { |
749ced52 ZW |
2351 | plus = 0; |
2352 | if (*f == '%') | |
2353 | { | |
2354 | f++; | |
2355 | if (*f == '+') | |
2356 | f++, plus = 1; | |
2357 | if (*f == '#') | |
2358 | f++; | |
c3e76028 | 2359 | |
749ced52 ZW |
2360 | switch (*f) |
2361 | { | |
2362 | /* Just ignore these possibilities. */ | |
2363 | case '%': break; | |
b01b2484 | 2364 | case 'P': |
749ced52 ZW |
2365 | case 'd': (void) va_arg (ap, int); break; |
2366 | case 's': (void) va_arg (ap, char *); break; | |
2367 | case 'L': (void) va_arg (ap, enum languages); break; | |
2368 | case 'C': | |
2369 | case 'O': | |
2370 | case 'Q': (void) va_arg (ap, enum tree_code); break; | |
2371 | ||
2372 | /* These take a tree, which may be where the error is | |
2373 | located. */ | |
2374 | case 'A': | |
2375 | case 'D': | |
2376 | case 'E': | |
2377 | case 'F': | |
749ced52 ZW |
2378 | case 'T': |
2379 | case 'V': | |
2380 | t = va_arg (ap, tree); | |
2381 | if (!here || plus) | |
2382 | here = t; | |
2383 | break; | |
c3e76028 | 2384 | |
749ced52 ZW |
2385 | default: |
2386 | errorcount = 0; /* damn ICE suppression */ | |
2387 | internal_error ("unexpected letter `%c' in locate_error\n", *f); | |
2388 | } | |
2389 | } | |
c3e76028 GDR |
2390 | } |
2391 | ||
749ced52 ZW |
2392 | if (here == 0) |
2393 | here = va_arg (ap, tree); | |
c3e76028 | 2394 | |
749ced52 | 2395 | return here; |
c3e76028 GDR |
2396 | } |
2397 | ||
c3e76028 | 2398 | |
749ced52 | 2399 | void |
e34d07f2 | 2400 | cp_error_at (const char *msgid, ...) |
a1066c99 | 2401 | { |
749ced52 | 2402 | tree here; |
47b69537 | 2403 | diagnostic_info diagnostic; |
e34d07f2 | 2404 | va_list ap; |
bb20cc46 | 2405 | |
e34d07f2 | 2406 | va_start (ap, msgid); |
749ced52 | 2407 | here = locate_error (msgid, ap); |
e34d07f2 | 2408 | va_end (ap); |
c3e76028 | 2409 | |
e34d07f2 | 2410 | va_start (ap, msgid); |
47b69537 | 2411 | diagnostic_set_info (&diagnostic, msgid, &ap, |
9a472a42 | 2412 | location_of (here), DK_ERROR); |
47b69537 | 2413 | report_diagnostic (&diagnostic); |
e34d07f2 | 2414 | va_end (ap); |
c3e76028 GDR |
2415 | } |
2416 | ||
749ced52 | 2417 | void |
e34d07f2 | 2418 | cp_warning_at (const char *msgid, ...) |
c3e76028 | 2419 | { |
749ced52 | 2420 | tree here; |
47b69537 | 2421 | diagnostic_info diagnostic; |
e34d07f2 | 2422 | va_list ap; |
c3e76028 | 2423 | |
e34d07f2 | 2424 | va_start (ap, msgid); |
749ced52 | 2425 | here = locate_error (msgid, ap); |
e34d07f2 | 2426 | va_end (ap); |
c3e76028 | 2427 | |
e34d07f2 | 2428 | va_start (ap, msgid); |
47b69537 | 2429 | diagnostic_set_info (&diagnostic, msgid, &ap, |
9a472a42 | 2430 | location_of (here), DK_WARNING); |
47b69537 | 2431 | report_diagnostic (&diagnostic); |
e34d07f2 | 2432 | va_end (ap); |
c3e76028 GDR |
2433 | } |
2434 | ||
749ced52 | 2435 | void |
e34d07f2 | 2436 | cp_pedwarn_at (const char *msgid, ...) |
c3e76028 | 2437 | { |
749ced52 | 2438 | tree here; |
47b69537 | 2439 | diagnostic_info diagnostic; |
e34d07f2 | 2440 | va_list ap; |
c3e76028 | 2441 | |
e34d07f2 | 2442 | va_start (ap, msgid); |
749ced52 | 2443 | here = locate_error (msgid, ap); |
e34d07f2 | 2444 | va_end (ap); |
c3e76028 | 2445 | |
e34d07f2 | 2446 | va_start (ap, msgid); |
47b69537 | 2447 | diagnostic_set_info (&diagnostic, msgid, &ap, |
9a472a42 | 2448 | location_of (here), pedantic_error_kind()); |
47b69537 | 2449 | report_diagnostic (&diagnostic); |
e34d07f2 | 2450 | va_end (ap); |
c3e76028 | 2451 | } |