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