]>
Commit | Line | Data |
---|---|---|
471086d6 | 1 | /* Call-backs for C++ error reporting. |
2 | This code is non-reentrant. | |
aad93da1 | 3 | Copyright (C) 1993-2017 Free Software Foundation, Inc. |
6f0d25a6 | 4 | This file is part of GCC. |
471086d6 | 5 | |
6f0d25a6 | 6 | GCC is free software; you can redistribute it and/or modify |
471086d6 | 7 | it under the terms of the GNU General Public License as published by |
aa139c3f | 8 | the Free Software Foundation; either version 3, or (at your option) |
471086d6 | 9 | any later version. |
10 | ||
6f0d25a6 | 11 | GCC is distributed in the hope that it will be useful, |
471086d6 | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
aa139c3f | 17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
471086d6 | 19 | |
20 | #include "config.h" | |
b3ef7553 | 21 | #include "system.h" |
805e22b2 | 22 | #include "coretypes.h" |
471086d6 | 23 | #include "cp-tree.h" |
4cba6f60 | 24 | #include "stringpool.h" |
ce084dfc | 25 | #include "tree-diagnostic.h" |
6c7ff025 | 26 | #include "langhooks-def.h" |
1e00012f | 27 | #include "intl.h" |
0de2b732 | 28 | #include "cxx-pretty-print.h" |
ce084dfc | 29 | #include "tree-pretty-print.h" |
c8616982 | 30 | #include "gimple-pretty-print.h" |
6c536c4f | 31 | #include "c-family/c-objc.h" |
9e46467d | 32 | #include "ubsan.h" |
6b71bdb4 | 33 | #include "internal-fn.h" |
471086d6 | 34 | |
573c13ef | 35 | #define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',') |
180b6c86 | 36 | #define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';') |
326f388b | 37 | |
32ecf960 | 38 | /* cxx_pp is a C++ front-end-specific pretty printer: this is where we |
39 | dump C++ ASTs as strings. It is mostly used only by the various | |
40 | tree -> string functions that are occasionally called from the | |
41 | debugger or by the front-end for things like | |
42 | __PRETTY_FUNCTION__. */ | |
350d0f53 | 43 | static cxx_pretty_printer actual_pretty_printer; |
44 | static cxx_pretty_printer * const cxx_pp = &actual_pretty_printer; | |
cec1f6a6 | 45 | |
a608187f | 46 | /* Translate if being used for diagnostics, but not for dump files or |
47 | __PRETTY_FUNCTION. */ | |
48 | #define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid)) | |
49 | ||
bf16fecd | 50 | # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T))) |
471086d6 | 51 | |
f01d4233 | 52 | static const char *args_to_string (tree, int); |
240171a9 | 53 | static const char *code_to_string (enum tree_code); |
f01d4233 | 54 | static const char *cv_to_string (tree, int); |
55 | static const char *decl_to_string (tree, int); | |
240171a9 | 56 | static const char *expr_to_string (tree); |
f01d4233 | 57 | static const char *fndecl_to_string (tree, int); |
ca16a224 | 58 | static const char *op_to_string (bool, enum tree_code); |
240171a9 | 59 | static const char *parm_to_string (int); |
8e4391a5 | 60 | static const char *type_to_string (tree, int, bool, bool *, bool); |
f01d4233 | 61 | |
4a5e902c | 62 | static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int); |
63 | static void dump_type (cxx_pretty_printer *, tree, int); | |
64 | static void dump_typename (cxx_pretty_printer *, tree, int); | |
65 | static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int); | |
66 | static void dump_decl (cxx_pretty_printer *, tree, int); | |
67 | static void dump_template_decl (cxx_pretty_printer *, tree, int); | |
68 | static void dump_function_decl (cxx_pretty_printer *, tree, int); | |
69 | static void dump_expr (cxx_pretty_printer *, tree, int); | |
70 | static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int); | |
71 | static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int); | |
72 | static void dump_aggr_type (cxx_pretty_printer *, tree, int); | |
73 | static void dump_type_prefix (cxx_pretty_printer *, tree, int); | |
74 | static void dump_type_suffix (cxx_pretty_printer *, tree, int); | |
75 | static void dump_function_name (cxx_pretty_printer *, tree, int); | |
76 | static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool); | |
77 | static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool); | |
78 | static void dump_expr_list (cxx_pretty_printer *, tree, int); | |
79 | static void dump_global_iord (cxx_pretty_printer *, tree); | |
80 | static void dump_parameters (cxx_pretty_printer *, tree, int); | |
81 | static void dump_ref_qualifier (cxx_pretty_printer *, tree, int); | |
82 | static void dump_exception_spec (cxx_pretty_printer *, tree, int); | |
83 | static void dump_template_argument (cxx_pretty_printer *, tree, int); | |
84 | static void dump_template_argument_list (cxx_pretty_printer *, tree, int); | |
85 | static void dump_template_parameter (cxx_pretty_printer *, tree, int); | |
86 | static void dump_template_bindings (cxx_pretty_printer *, tree, tree, | |
87 | vec<tree, va_gc> *); | |
88 | static void dump_scope (cxx_pretty_printer *, tree, int); | |
89 | static void dump_template_parms (cxx_pretty_printer *, tree, int, int); | |
94c17f03 | 90 | static int get_non_default_template_args_count (tree, int); |
f01d4233 | 91 | static const char *function_category (tree); |
0a32318d | 92 | static void maybe_print_constexpr_context (diagnostic_context *); |
f01d4233 | 93 | static void maybe_print_instantiation_context (diagnostic_context *); |
94 | static void print_instantiation_full_context (diagnostic_context *); | |
95 | static void print_instantiation_partial_context (diagnostic_context *, | |
c5dd8e06 | 96 | struct tinst_level *, |
97 | location_t); | |
f01d4233 | 98 | static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *); |
f01d4233 | 99 | static void cp_print_error_function (diagnostic_context *, diagnostic_info *); |
100 | ||
c907c5b1 | 101 | static bool cp_printer (pretty_printer *, text_info *, const char *, |
8e4391a5 | 102 | int, bool, bool, bool, bool *, const char **); |
4d1eda3a | 103 | |
104 | /* Struct for handling %H or %I, which require delaying printing the | |
105 | type until a postprocessing stage. */ | |
106 | ||
107 | struct deferred_printed_type | |
108 | { | |
109 | deferred_printed_type () | |
110 | : m_tree (NULL_TREE), m_buffer_ptr (NULL), m_verbose (false), m_quote (false) | |
111 | {} | |
112 | ||
113 | deferred_printed_type (tree type, const char **buffer_ptr, bool verbose, | |
114 | bool quote) | |
115 | : m_tree (type), m_buffer_ptr (buffer_ptr), m_verbose (verbose), | |
116 | m_quote (quote) | |
117 | { | |
118 | gcc_assert (type); | |
119 | gcc_assert (buffer_ptr); | |
120 | } | |
121 | ||
122 | /* The tree is not GTY-marked: they are only non-NULL within a | |
123 | call to pp_format. */ | |
124 | tree m_tree; | |
125 | const char **m_buffer_ptr; | |
126 | bool m_verbose; | |
127 | bool m_quote; | |
128 | }; | |
129 | ||
130 | /* Subclass of format_postprocessor for the C++ frontend. | |
131 | This handles the %H and %I formatting codes, printing them | |
132 | in a postprocessing phase (since they affect each other). */ | |
133 | ||
134 | class cxx_format_postprocessor : public format_postprocessor | |
135 | { | |
136 | public: | |
137 | cxx_format_postprocessor () | |
138 | : m_type_a (), m_type_b () | |
139 | {} | |
140 | ||
141 | void handle (pretty_printer *pp) FINAL OVERRIDE; | |
142 | ||
143 | deferred_printed_type m_type_a; | |
144 | deferred_printed_type m_type_b; | |
145 | }; | |
471086d6 | 146 | |
32ecf960 | 147 | /* CONTEXT->printer is a basic pretty printer that was constructed |
148 | presumably by diagnostic_initialize(), called early in the | |
149 | compiler's initialization process (in general_init) Before the FE | |
150 | is initialized. This (C++) FE-specific diagnostic initializer is | |
151 | thus replacing the basic pretty printer with one that has C++-aware | |
152 | capacities. */ | |
153 | ||
471086d6 | 154 | void |
32ecf960 | 155 | cxx_initialize_diagnostics (diagnostic_context *context) |
471086d6 | 156 | { |
32ecf960 | 157 | pretty_printer *base = context->printer; |
158 | cxx_pretty_printer *pp = XNEW (cxx_pretty_printer); | |
159 | context->printer = new (pp) cxx_pretty_printer (); | |
160 | ||
161 | /* It is safe to free this object because it was previously XNEW()'d. */ | |
162 | base->~pretty_printer (); | |
163 | XDELETE (base); | |
164 | ||
165 | c_common_diagnostics_set_defaults (context); | |
166 | diagnostic_starter (context) = cp_diagnostic_starter; | |
399d4f80 | 167 | /* diagnostic_finalizer is already c_diagnostic_finalizer. */ |
32ecf960 | 168 | diagnostic_format_decoder (context) = cp_printer; |
4d1eda3a | 169 | pp->m_format_postprocessor = new cxx_format_postprocessor (); |
32ecf960 | 170 | } |
5124a2c8 | 171 | |
d04f0501 | 172 | /* Dump a scope, if deemed necessary. */ |
4b5bcd15 | 173 | |
d04f0501 | 174 | static void |
4a5e902c | 175 | dump_scope (cxx_pretty_printer *pp, tree scope, int flags) |
4b5bcd15 | 176 | { |
6d00b16b | 177 | int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF); |
682959c4 | 178 | |
d04f0501 | 179 | if (scope == NULL_TREE) |
180 | return; | |
50cd3f45 | 181 | |
d04f0501 | 182 | if (TREE_CODE (scope) == NAMESPACE_DECL) |
183 | { | |
184 | if (scope != global_namespace) | |
653e5405 | 185 | { |
4a5e902c | 186 | dump_decl (pp, scope, f); |
187 | pp_cxx_colon_colon (pp); | |
653e5405 | 188 | } |
d04f0501 | 189 | } |
190 | else if (AGGREGATE_TYPE_P (scope)) | |
191 | { | |
4a5e902c | 192 | dump_type (pp, scope, f); |
193 | pp_cxx_colon_colon (pp); | |
d04f0501 | 194 | } |
682959c4 | 195 | else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL) |
d04f0501 | 196 | { |
4a5e902c | 197 | dump_function_decl (pp, scope, f); |
198 | pp_cxx_colon_colon (pp); | |
d04f0501 | 199 | } |
4b5bcd15 | 200 | } |
201 | ||
a2a627ce | 202 | /* Dump the template ARGument under control of FLAGS. */ |
85918456 | 203 | |
204 | static void | |
4a5e902c | 205 | dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags) |
85918456 | 206 | { |
d95d815d | 207 | if (ARGUMENT_PACK_P (arg)) |
4a5e902c | 208 | dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg), |
9c82e807 | 209 | /* No default args in argument packs. */ |
210 | flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); | |
d95d815d | 211 | else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) |
4a5e902c | 212 | dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM); |
85918456 | 213 | else |
afc0e339 | 214 | { |
215 | if (TREE_CODE (arg) == TREE_LIST) | |
216 | arg = TREE_VALUE (arg); | |
217 | ||
f0474a47 | 218 | /* Strip implicit conversions. */ |
219 | while (CONVERT_EXPR_P (arg)) | |
220 | arg = TREE_OPERAND (arg, 0); | |
221 | ||
4a5e902c | 222 | dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); |
afc0e339 | 223 | } |
85918456 | 224 | } |
225 | ||
2783c778 | 226 | /* Count the number of template arguments ARGS whose value does not |
227 | match the (optional) default template parameter in PARAMS */ | |
228 | ||
229 | static int | |
94c17f03 | 230 | get_non_default_template_args_count (tree args, int flags) |
2783c778 | 231 | { |
94c17f03 | 232 | int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args)); |
2783c778 | 233 | |
94c17f03 | 234 | if (/* We use this flag when generating debug information. We don't |
9845d120 | 235 | want to expand templates at this point, for this may generate |
236 | new decls, which gets decl counts out of sync, which may in | |
237 | turn cause codegen differences between compilations with and | |
238 | without -g. */ | |
94c17f03 | 239 | (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0 |
9845d120 | 240 | || !flag_pretty_templates) |
2783c778 | 241 | return n; |
242 | ||
94c17f03 | 243 | return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args)); |
2783c778 | 244 | } |
245 | ||
a2a627ce | 246 | /* Dump a template-argument-list ARGS (always a TREE_VEC) under control |
247 | of FLAGS. */ | |
248 | ||
249 | static void | |
4a5e902c | 250 | dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags) |
a2a627ce | 251 | { |
94c17f03 | 252 | int n = get_non_default_template_args_count (args, flags); |
a2a627ce | 253 | int need_comma = 0; |
254 | int i; | |
255 | ||
2783c778 | 256 | for (i = 0; i < n; ++i) |
a2a627ce | 257 | { |
d95d815d | 258 | tree arg = TREE_VEC_ELT (args, i); |
259 | ||
260 | /* Only print a comma if we know there is an argument coming. In | |
261 | the case of an empty template argument pack, no actual | |
262 | argument will be printed. */ | |
263 | if (need_comma | |
264 | && (!ARGUMENT_PACK_P (arg) | |
265 | || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) | |
4a5e902c | 266 | pp_separate_with_comma (pp); |
d95d815d | 267 | |
4a5e902c | 268 | dump_template_argument (pp, arg, flags); |
a2a627ce | 269 | need_comma = 1; |
270 | } | |
271 | } | |
272 | ||
273 | /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */ | |
274 | ||
275 | static void | |
4a5e902c | 276 | dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags) |
a2a627ce | 277 | { |
508c7aa7 | 278 | tree p; |
279 | tree a; | |
280 | ||
281 | if (parm == error_mark_node) | |
282 | return; | |
283 | ||
284 | p = TREE_VALUE (parm); | |
285 | a = TREE_PURPOSE (parm); | |
a2a627ce | 286 | |
287 | if (TREE_CODE (p) == TYPE_DECL) | |
288 | { | |
682959c4 | 289 | if (flags & TFF_DECL_SPECIFIERS) |
653e5405 | 290 | { |
4a5e902c | 291 | pp_cxx_ws_string (pp, "class"); |
d95d815d | 292 | if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p))) |
4a5e902c | 293 | pp_cxx_ws_string (pp, "..."); |
653e5405 | 294 | if (DECL_NAME (p)) |
4a5e902c | 295 | pp_cxx_tree_identifier (pp, DECL_NAME (p)); |
653e5405 | 296 | } |
a2a627ce | 297 | else if (DECL_NAME (p)) |
4a5e902c | 298 | pp_cxx_tree_identifier (pp, DECL_NAME (p)); |
a2a627ce | 299 | else |
4a5e902c | 300 | pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p)); |
a2a627ce | 301 | } |
302 | else | |
4a5e902c | 303 | dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS); |
a2a627ce | 304 | |
682959c4 | 305 | if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE) |
a2a627ce | 306 | { |
4a5e902c | 307 | pp_cxx_whitespace (pp); |
308 | pp_equal (pp); | |
309 | pp_cxx_whitespace (pp); | |
551b77a5 | 310 | if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) |
4a5e902c | 311 | dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF); |
a2a627ce | 312 | else |
4a5e902c | 313 | dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS); |
a2a627ce | 314 | } |
315 | } | |
316 | ||
317 | /* Dump, under control of FLAGS, a template-parameter-list binding. | |
318 | PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a | |
319 | TREE_VEC. */ | |
320 | ||
321 | static void | |
4a5e902c | 322 | dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, |
323 | vec<tree, va_gc> *typenames) | |
a2a627ce | 324 | { |
180b6c86 | 325 | bool need_semicolon = false; |
40c700ab | 326 | int i; |
327 | tree t; | |
a2a627ce | 328 | |
329 | while (parms) | |
330 | { | |
331 | tree p = TREE_VALUE (parms); | |
a6604172 | 332 | int lvl = TMPL_PARMS_DEPTH (parms); |
333 | int arg_idx = 0; | |
a2a627ce | 334 | int i; |
2783c778 | 335 | tree lvl_args = NULL_TREE; |
336 | ||
337 | /* Don't crash if we had an invalid argument list. */ | |
338 | if (TMPL_ARGS_DEPTH (args) >= lvl) | |
339 | lvl_args = TMPL_ARGS_LEVEL (args, lvl); | |
a2a627ce | 340 | |
341 | for (i = 0; i < TREE_VEC_LENGTH (p); ++i) | |
a6604172 | 342 | { |
f9b9bf39 | 343 | tree arg = NULL_TREE; |
344 | ||
345 | /* Don't crash if we had an invalid argument list. */ | |
2783c778 | 346 | if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx) |
347 | arg = TREE_VEC_ELT (lvl_args, arg_idx); | |
a6604172 | 348 | |
180b6c86 | 349 | if (need_semicolon) |
4a5e902c | 350 | pp_separate_with_semicolon (pp); |
351 | dump_template_parameter (pp, TREE_VEC_ELT (p, i), | |
352 | TFF_PLAIN_IDENTIFIER); | |
353 | pp_cxx_whitespace (pp); | |
354 | pp_equal (pp); | |
355 | pp_cxx_whitespace (pp); | |
a6604172 | 356 | if (arg) |
89cc0cff | 357 | { |
358 | if (ARGUMENT_PACK_P (arg)) | |
4a5e902c | 359 | pp_cxx_left_brace (pp); |
360 | dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER); | |
89cc0cff | 361 | if (ARGUMENT_PACK_P (arg)) |
4a5e902c | 362 | pp_cxx_right_brace (pp); |
89cc0cff | 363 | } |
a6604172 | 364 | else |
4a5e902c | 365 | pp_string (pp, M_("<missing>")); |
50cd3f45 | 366 | |
a6604172 | 367 | ++arg_idx; |
180b6c86 | 368 | need_semicolon = true; |
a6604172 | 369 | } |
a2a627ce | 370 | |
371 | parms = TREE_CHAIN (parms); | |
372 | } | |
40c700ab | 373 | |
673064cf | 374 | /* Don't bother with typenames for a partial instantiation. */ |
f1f41a6c | 375 | if (vec_safe_is_empty (typenames) || uses_template_parms (args)) |
673064cf | 376 | return; |
377 | ||
aa2aac02 | 378 | /* Don't try to print typenames when we're processing a clone. */ |
379 | if (current_function_decl | |
380 | && !DECL_LANG_SPECIFIC (current_function_decl)) | |
381 | return; | |
382 | ||
9f2b92c4 | 383 | /* Don't try to do this once cgraph starts throwing away front-end |
384 | information. */ | |
385 | if (at_eof >= 2) | |
386 | return; | |
387 | ||
f1f41a6c | 388 | FOR_EACH_VEC_SAFE_ELT (typenames, i, t) |
40c700ab | 389 | { |
180b6c86 | 390 | if (need_semicolon) |
4a5e902c | 391 | pp_separate_with_semicolon (pp); |
392 | dump_type (pp, t, TFF_PLAIN_IDENTIFIER); | |
393 | pp_cxx_whitespace (pp); | |
394 | pp_equal (pp); | |
395 | pp_cxx_whitespace (pp); | |
c9fc4edc | 396 | push_deferring_access_checks (dk_no_check); |
a409f927 | 397 | t = tsubst (t, args, tf_none, NULL_TREE); |
c9fc4edc | 398 | pop_deferring_access_checks (); |
a409f927 | 399 | /* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because |
400 | pp_simple_type_specifier doesn't know about it. */ | |
2fb61329 | 401 | t = strip_typedefs (t); |
4a5e902c | 402 | dump_type (pp, t, TFF_PLAIN_IDENTIFIER); |
40c700ab | 403 | } |
a2a627ce | 404 | } |
405 | ||
370478b1 | 406 | /* Dump a human-readable equivalent of the alias template |
407 | specialization of T. */ | |
408 | ||
409 | static void | |
4a5e902c | 410 | dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags) |
370478b1 | 411 | { |
370478b1 | 412 | gcc_assert (alias_template_specialization_p (t)); |
413 | ||
4f517a45 | 414 | tree decl = TYPE_NAME (t); |
7961105f | 415 | if (!(flags & TFF_UNQUALIFIED_NAME)) |
4f517a45 | 416 | dump_scope (pp, CP_DECL_CONTEXT (decl), flags); |
417 | pp_cxx_tree_identifier (pp, DECL_NAME (decl)); | |
418 | dump_template_parms (pp, DECL_TEMPLATE_INFO (decl), | |
370478b1 | 419 | /*primary=*/false, |
420 | flags & ~TFF_TEMPLATE_HEADER); | |
421 | } | |
422 | ||
d531c71f | 423 | /* Dump a human-readable equivalent of TYPE. FLAGS controls the |
424 | format. */ | |
96624a9e | 425 | |
471086d6 | 426 | static void |
4a5e902c | 427 | dump_type (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 428 | { |
429 | if (t == NULL_TREE) | |
430 | return; | |
50cd3f45 | 431 | |
7199a4db | 432 | /* Don't print e.g. "struct mytypedef". */ |
433 | if (TYPE_P (t) && typedef_variant_p (t)) | |
434 | { | |
435 | tree decl = TYPE_NAME (t); | |
436 | if ((flags & TFF_CHASE_TYPEDEF) | |
370478b1 | 437 | || DECL_SELF_REFERENCE_P (decl) |
438 | || (!flag_pretty_templates | |
439 | && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) | |
7199a4db | 440 | t = strip_typedefs (t); |
370478b1 | 441 | else if (alias_template_specialization_p (t)) |
442 | { | |
4a5e902c | 443 | dump_alias_template_specialization (pp, t, flags); |
370478b1 | 444 | return; |
445 | } | |
7199a4db | 446 | else if (same_type_p (t, TREE_TYPE (decl))) |
447 | t = decl; | |
448 | else | |
449 | { | |
4a5e902c | 450 | pp_cxx_cv_qualifier_seq (pp, t); |
451 | pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); | |
7199a4db | 452 | return; |
453 | } | |
454 | } | |
455 | ||
471086d6 | 456 | if (TYPE_PTRMEMFUNC_P (t)) |
457 | goto offset_type; | |
458 | ||
459 | switch (TREE_CODE (t)) | |
460 | { | |
4fdaf896 | 461 | case LANG_TYPE: |
f82f1250 | 462 | if (t == init_list_type_node) |
4a5e902c | 463 | pp_string (pp, M_("<brace-enclosed initializer list>")); |
4fdaf896 | 464 | else if (t == unknown_type_node) |
4a5e902c | 465 | pp_string (pp, M_("<unresolved overloaded function type>")); |
4fdaf896 | 466 | else |
c7ca48ea | 467 | { |
4a5e902c | 468 | pp_cxx_cv_qualifier_seq (pp, t); |
469 | pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); | |
c7ca48ea | 470 | } |
471086d6 | 471 | break; |
472 | ||
1717856a | 473 | case TREE_LIST: |
474 | /* A list of function parms. */ | |
4a5e902c | 475 | dump_parameters (pp, t, flags); |
1717856a | 476 | break; |
477 | ||
471086d6 | 478 | case IDENTIFIER_NODE: |
4a5e902c | 479 | pp_cxx_tree_identifier (pp, t); |
471086d6 | 480 | break; |
481 | ||
f7cfa235 | 482 | case TREE_BINFO: |
4a5e902c | 483 | dump_type (pp, BINFO_TYPE (t), flags); |
471086d6 | 484 | break; |
485 | ||
486 | case RECORD_TYPE: | |
487 | case UNION_TYPE: | |
488 | case ENUMERAL_TYPE: | |
4a5e902c | 489 | dump_aggr_type (pp, t, flags); |
471086d6 | 490 | break; |
491 | ||
492 | case TYPE_DECL: | |
682959c4 | 493 | if (flags & TFF_CHASE_TYPEDEF) |
653e5405 | 494 | { |
4a5e902c | 495 | dump_type (pp, DECL_ORIGINAL_TYPE (t) |
653e5405 | 496 | ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); |
497 | break; | |
498 | } | |
e3533433 | 499 | /* Fall through. */ |
50cd3f45 | 500 | |
b1ce805f | 501 | case TEMPLATE_DECL: |
380974a6 | 502 | case NAMESPACE_DECL: |
4a5e902c | 503 | dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS); |
471086d6 | 504 | break; |
50cd3f45 | 505 | |
471086d6 | 506 | case INTEGER_TYPE: |
471086d6 | 507 | case REAL_TYPE: |
508 | case VOID_TYPE: | |
bb0726a1 | 509 | case BOOLEAN_TYPE: |
d7b8e04e | 510 | case COMPLEX_TYPE: |
511 | case VECTOR_TYPE: | |
d62c98bc | 512 | case FIXED_POINT_TYPE: |
4a5e902c | 513 | pp_type_specifier_seq (pp, t); |
471086d6 | 514 | break; |
515 | ||
cd5dd2d8 | 516 | case TEMPLATE_TEMPLATE_PARM: |
47cd6605 | 517 | /* For parameters inside template signature. */ |
1e93ca27 | 518 | if (TYPE_IDENTIFIER (t)) |
4a5e902c | 519 | pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); |
cd5dd2d8 | 520 | else |
4a5e902c | 521 | pp_cxx_canonical_template_parameter (pp, t); |
1e93ca27 | 522 | break; |
523 | ||
524 | case BOUND_TEMPLATE_TEMPLATE_PARM: | |
525 | { | |
526 | tree args = TYPE_TI_ARGS (t); | |
4a5e902c | 527 | pp_cxx_cv_qualifier_seq (pp, t); |
528 | pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); | |
529 | pp_cxx_begin_template_argument_list (pp); | |
530 | dump_template_argument_list (pp, args, flags); | |
531 | pp_cxx_end_template_argument_list (pp); | |
1e93ca27 | 532 | } |
cd5dd2d8 | 533 | break; |
534 | ||
471086d6 | 535 | case TEMPLATE_TYPE_PARM: |
4a5e902c | 536 | pp_cxx_cv_qualifier_seq (pp, t); |
433fc17c | 537 | if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t)) |
538 | pp_cxx_constrained_type_spec (pp, c); | |
539 | else if (TYPE_IDENTIFIER (t)) | |
4a5e902c | 540 | pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); |
dbdf67c6 | 541 | else |
653e5405 | 542 | pp_cxx_canonical_template_parameter |
4a5e902c | 543 | (pp, TEMPLATE_TYPE_PARM_INDEX (t)); |
471086d6 | 544 | break; |
545 | ||
471086d6 | 546 | /* This is not always necessary for pointers and such, but doing this |
547 | reduces code size. */ | |
548 | case ARRAY_TYPE: | |
549 | case POINTER_TYPE: | |
550 | case REFERENCE_TYPE: | |
551 | case OFFSET_TYPE: | |
552 | offset_type: | |
553 | case FUNCTION_TYPE: | |
554 | case METHOD_TYPE: | |
d04f0501 | 555 | { |
4a5e902c | 556 | dump_type_prefix (pp, t, flags); |
557 | dump_type_suffix (pp, t, flags); | |
471086d6 | 558 | break; |
d04f0501 | 559 | } |
e857e9c7 | 560 | case TYPENAME_TYPE: |
a409f927 | 561 | if (! (flags & TFF_CHASE_TYPEDEF) |
562 | && DECL_ORIGINAL_TYPE (TYPE_NAME (t))) | |
563 | { | |
4a5e902c | 564 | dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER); |
a409f927 | 565 | break; |
566 | } | |
4a5e902c | 567 | pp_cxx_cv_qualifier_seq (pp, t); |
568 | pp_cxx_ws_string (pp, | |
9031d10b | 569 | TYPENAME_IS_ENUM_P (t) ? "enum" |
e2ae55f2 | 570 | : TYPENAME_IS_CLASS_P (t) ? "class" |
571 | : "typename"); | |
4a5e902c | 572 | dump_typename (pp, t, flags); |
e857e9c7 | 573 | break; |
574 | ||
47d727d4 | 575 | case UNBOUND_CLASS_TEMPLATE: |
5bd9bf06 | 576 | if (! (flags & TFF_UNQUALIFIED_NAME)) |
577 | { | |
4a5e902c | 578 | dump_type (pp, TYPE_CONTEXT (t), flags); |
579 | pp_cxx_colon_colon (pp); | |
5bd9bf06 | 580 | } |
4a5e902c | 581 | pp_cxx_ws_string (pp, "template"); |
fbbaa325 | 582 | dump_type (pp, TYPE_IDENTIFIER (t), flags); |
47d727d4 | 583 | break; |
584 | ||
63e22e88 | 585 | case TYPEOF_TYPE: |
4a5e902c | 586 | pp_cxx_ws_string (pp, "__typeof__"); |
587 | pp_cxx_whitespace (pp); | |
588 | pp_cxx_left_paren (pp); | |
589 | dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); | |
590 | pp_cxx_right_paren (pp); | |
63e22e88 | 591 | break; |
592 | ||
8de5c43e | 593 | case UNDERLYING_TYPE: |
4a5e902c | 594 | pp_cxx_ws_string (pp, "__underlying_type"); |
595 | pp_cxx_whitespace (pp); | |
596 | pp_cxx_left_paren (pp); | |
597 | dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS); | |
598 | pp_cxx_right_paren (pp); | |
8de5c43e | 599 | break; |
600 | ||
d95d815d | 601 | case TYPE_PACK_EXPANSION: |
4a5e902c | 602 | dump_type (pp, PACK_EXPANSION_PATTERN (t), flags); |
603 | pp_cxx_ws_string (pp, "..."); | |
d95d815d | 604 | break; |
605 | ||
a4f66688 | 606 | case TYPE_ARGUMENT_PACK: |
4a5e902c | 607 | dump_template_argument (pp, t, flags); |
a4f66688 | 608 | break; |
609 | ||
34da8800 | 610 | case DECLTYPE_TYPE: |
4a5e902c | 611 | pp_cxx_ws_string (pp, "decltype"); |
612 | pp_cxx_whitespace (pp); | |
613 | pp_cxx_left_paren (pp); | |
614 | dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); | |
615 | pp_cxx_right_paren (pp); | |
34da8800 | 616 | break; |
617 | ||
fa67d8e8 | 618 | case NULLPTR_TYPE: |
4a5e902c | 619 | pp_string (pp, "std::nullptr_t"); |
fa67d8e8 | 620 | break; |
621 | ||
471086d6 | 622 | default: |
4a5e902c | 623 | pp_unsupported_tree (pp, t); |
c7afb782 | 624 | /* Fall through. */ |
d04f0501 | 625 | |
626 | case ERROR_MARK: | |
4a5e902c | 627 | pp_string (pp, M_("<type error>")); |
d04f0501 | 628 | break; |
471086d6 | 629 | } |
630 | } | |
631 | ||
141fe0b5 | 632 | /* Dump a TYPENAME_TYPE. We need to notice when the context is itself |
633 | a TYPENAME_TYPE. */ | |
634 | ||
635 | static void | |
4a5e902c | 636 | dump_typename (cxx_pretty_printer *pp, tree t, int flags) |
141fe0b5 | 637 | { |
638 | tree ctx = TYPE_CONTEXT (t); | |
50cd3f45 | 639 | |
141fe0b5 | 640 | if (TREE_CODE (ctx) == TYPENAME_TYPE) |
4a5e902c | 641 | dump_typename (pp, ctx, flags); |
141fe0b5 | 642 | else |
4a5e902c | 643 | dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); |
644 | pp_cxx_colon_colon (pp); | |
645 | dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags); | |
141fe0b5 | 646 | } |
647 | ||
d04f0501 | 648 | /* Return the name of the supplied aggregate, or enumeral type. */ |
649 | ||
a32f42ef | 650 | const char * |
651 | class_key_or_enum_as_string (tree t) | |
471086d6 | 652 | { |
3f00a6c0 | 653 | if (TREE_CODE (t) == ENUMERAL_TYPE) |
654 | { | |
655 | if (SCOPED_ENUM_P (t)) | |
656 | return "enum class"; | |
657 | else | |
658 | return "enum"; | |
659 | } | |
471086d6 | 660 | else if (TREE_CODE (t) == UNION_TYPE) |
ac9386a0 | 661 | return "union"; |
471086d6 | 662 | else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) |
ac9386a0 | 663 | return "class"; |
471086d6 | 664 | else |
ac9386a0 | 665 | return "struct"; |
666 | } | |
667 | ||
d04f0501 | 668 | /* Print out a class declaration T under the control of FLAGS, |
669 | in the form `class foo'. */ | |
96624a9e | 670 | |
ac9386a0 | 671 | static void |
4a5e902c | 672 | dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) |
ac9386a0 | 673 | { |
674 | tree name; | |
a32f42ef | 675 | const char *variety = class_key_or_enum_as_string (t); |
d04f0501 | 676 | int typdef = 0; |
677 | int tmplate = 0; | |
471086d6 | 678 | |
4a5e902c | 679 | pp_cxx_cv_qualifier_seq (pp, t); |
471086d6 | 680 | |
682959c4 | 681 | if (flags & TFF_CLASS_KEY_OR_ENUM) |
4a5e902c | 682 | pp_cxx_ws_string (pp, variety); |
50cd3f45 | 683 | |
d04f0501 | 684 | name = TYPE_NAME (t); |
685 | ||
686 | if (name) | |
471086d6 | 687 | { |
370478b1 | 688 | typdef = (!DECL_ARTIFICIAL (name) |
689 | /* An alias specialization is not considered to be a | |
690 | typedef. */ | |
691 | && !alias_template_specialization_p (t)); | |
d0391daf | 692 | |
a70e3c37 | 693 | if ((typdef |
694 | && ((flags & TFF_CHASE_TYPEDEF) | |
695 | || (!flag_pretty_templates && DECL_LANG_SPECIFIC (name) | |
696 | && DECL_TEMPLATE_INFO (name)))) | |
697 | || DECL_SELF_REFERENCE_P (name)) | |
d0391daf | 698 | { |
699 | t = TYPE_MAIN_VARIANT (t); | |
700 | name = TYPE_NAME (t); | |
701 | typdef = 0; | |
702 | } | |
703 | ||
d04f0501 | 704 | tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE |
653e5405 | 705 | && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) |
a761e730 | 706 | && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL |
653e5405 | 707 | || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); |
facb12b2 | 708 | |
709 | if (! (flags & TFF_UNQUALIFIED_NAME)) | |
4a5e902c | 710 | dump_scope (pp, CP_DECL_CONTEXT (name), flags | TFF_SCOPE); |
facb12b2 | 711 | flags &= ~TFF_UNQUALIFIED_NAME; |
d04f0501 | 712 | if (tmplate) |
653e5405 | 713 | { |
714 | /* Because the template names are mangled, we have to locate | |
715 | the most general template, and use that name. */ | |
370478b1 | 716 | tree tpl = TYPE_TI_TEMPLATE (t); |
653e5405 | 717 | |
718 | while (DECL_TEMPLATE_INFO (tpl)) | |
719 | tpl = DECL_TI_TEMPLATE (tpl); | |
720 | name = tpl; | |
721 | } | |
d04f0501 | 722 | name = DECL_NAME (name); |
471086d6 | 723 | } |
724 | ||
29e65f8e | 725 | if (name == 0 || anon_aggrname_p (name)) |
471086d6 | 726 | { |
682959c4 | 727 | if (flags & TFF_CLASS_KEY_OR_ENUM) |
4f86cbb0 | 728 | pp_string (pp, M_("<unnamed>")); |
da901964 | 729 | else |
4f86cbb0 | 730 | pp_printf (pp, M_("<unnamed %s>"), variety); |
471086d6 | 731 | } |
32843f4e | 732 | else if (LAMBDA_TYPE_P (t)) |
a8b75081 | 733 | { |
734 | /* A lambda's "type" is essentially its signature. */ | |
4a5e902c | 735 | pp_string (pp, M_("<lambda")); |
a8b75081 | 736 | if (lambda_function (t)) |
4a5e902c | 737 | dump_parameters (pp, |
738 | FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)), | |
a8b75081 | 739 | flags); |
4a5e902c | 740 | pp_greater (pp); |
a8b75081 | 741 | } |
471086d6 | 742 | else |
4a5e902c | 743 | pp_cxx_tree_identifier (pp, name); |
d04f0501 | 744 | if (tmplate) |
4a5e902c | 745 | dump_template_parms (pp, TYPE_TEMPLATE_INFO (t), |
653e5405 | 746 | !CLASSTYPE_USE_TEMPLATE (t), |
747 | flags & ~TFF_TEMPLATE_HEADER); | |
471086d6 | 748 | } |
749 | ||
750 | /* Dump into the obstack the initial part of the output for a given type. | |
751 | This is necessary when dealing with things like functions returning | |
752 | functions. Examples: | |
753 | ||
754 | return type of `int (* fee ())()': pointer -> function -> int. Both | |
755 | pointer (and reference and offset) and function (and member) types must | |
756 | deal with prefix and suffix. | |
757 | ||
758 | Arrays must also do this for DECL nodes, like int a[], and for things like | |
69cb846f | 759 | int *[]&. */ |
471086d6 | 760 | |
9031d10b | 761 | static void |
4a5e902c | 762 | dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 763 | { |
764 | if (TYPE_PTRMEMFUNC_P (t)) | |
765 | { | |
766 | t = TYPE_PTRMEMFUNC_FN_TYPE (t); | |
767 | goto offset_type; | |
768 | } | |
50cd3f45 | 769 | |
471086d6 | 770 | switch (TREE_CODE (t)) |
771 | { | |
772 | case POINTER_TYPE: | |
3e04bd45 | 773 | case REFERENCE_TYPE: |
471086d6 | 774 | { |
775 | tree sub = TREE_TYPE (t); | |
50cd3f45 | 776 | |
4a5e902c | 777 | dump_type_prefix (pp, sub, flags); |
75eaa947 | 778 | if (TREE_CODE (sub) == ARRAY_TYPE |
779 | || TREE_CODE (sub) == FUNCTION_TYPE) | |
471086d6 | 780 | { |
4a5e902c | 781 | pp_cxx_whitespace (pp); |
782 | pp_cxx_left_paren (pp); | |
783 | pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub)); | |
471086d6 | 784 | } |
c21c015b | 785 | if (TYPE_PTR_P (t)) |
4a5e902c | 786 | pp_star (pp); |
63949b38 | 787 | else if (TREE_CODE (t) == REFERENCE_TYPE) |
788 | { | |
789 | if (TYPE_REF_IS_RVALUE (t)) | |
4a5e902c | 790 | pp_ampersand_ampersand (pp); |
63949b38 | 791 | else |
4a5e902c | 792 | pp_ampersand (pp); |
63949b38 | 793 | } |
4a5e902c | 794 | pp->padding = pp_before; |
795 | pp_cxx_cv_qualifier_seq (pp, t); | |
471086d6 | 796 | } |
471086d6 | 797 | break; |
798 | ||
799 | case OFFSET_TYPE: | |
800 | offset_type: | |
4a5e902c | 801 | dump_type_prefix (pp, TREE_TYPE (t), flags); |
ac9386a0 | 802 | if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ |
803 | { | |
4a5e902c | 804 | pp_maybe_space (pp); |
653e5405 | 805 | if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) |
4a5e902c | 806 | pp_cxx_left_paren (pp); |
807 | dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags); | |
808 | pp_cxx_colon_colon (pp); | |
ac9386a0 | 809 | } |
4a5e902c | 810 | pp_cxx_star (pp); |
811 | pp_cxx_cv_qualifier_seq (pp, t); | |
812 | pp->padding = pp_before; | |
471086d6 | 813 | break; |
814 | ||
75eaa947 | 815 | /* This can be reached without a pointer when dealing with |
816 | templates, e.g. std::is_function. */ | |
471086d6 | 817 | case FUNCTION_TYPE: |
4a5e902c | 818 | dump_type_prefix (pp, TREE_TYPE (t), flags); |
471086d6 | 819 | break; |
820 | ||
821 | case METHOD_TYPE: | |
4a5e902c | 822 | dump_type_prefix (pp, TREE_TYPE (t), flags); |
823 | pp_maybe_space (pp); | |
824 | pp_cxx_left_paren (pp); | |
825 | dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags); | |
826 | pp_cxx_colon_colon (pp); | |
471086d6 | 827 | break; |
828 | ||
829 | case ARRAY_TYPE: | |
4a5e902c | 830 | dump_type_prefix (pp, TREE_TYPE (t), flags); |
471086d6 | 831 | break; |
832 | ||
833 | case ENUMERAL_TYPE: | |
471086d6 | 834 | case IDENTIFIER_NODE: |
835 | case INTEGER_TYPE: | |
bb0726a1 | 836 | case BOOLEAN_TYPE: |
471086d6 | 837 | case REAL_TYPE: |
838 | case RECORD_TYPE: | |
839 | case TEMPLATE_TYPE_PARM: | |
cd5dd2d8 | 840 | case TEMPLATE_TEMPLATE_PARM: |
1e93ca27 | 841 | case BOUND_TEMPLATE_TEMPLATE_PARM: |
471086d6 | 842 | case TREE_LIST: |
843 | case TYPE_DECL: | |
844 | case TREE_VEC: | |
471086d6 | 845 | case UNION_TYPE: |
4fdaf896 | 846 | case LANG_TYPE: |
471086d6 | 847 | case VOID_TYPE: |
e857e9c7 | 848 | case TYPENAME_TYPE: |
c4a8ac95 | 849 | case COMPLEX_TYPE: |
90a83261 | 850 | case VECTOR_TYPE: |
d3b75e30 | 851 | case TYPEOF_TYPE: |
8de5c43e | 852 | case UNDERLYING_TYPE: |
34da8800 | 853 | case DECLTYPE_TYPE: |
e4fbeb04 | 854 | case TYPE_PACK_EXPANSION: |
6ce18e5b | 855 | case FIXED_POINT_TYPE: |
fa67d8e8 | 856 | case NULLPTR_TYPE: |
4a5e902c | 857 | dump_type (pp, t, flags); |
858 | pp->padding = pp_before; | |
471086d6 | 859 | break; |
50cd3f45 | 860 | |
471086d6 | 861 | default: |
4a5e902c | 862 | pp_unsupported_tree (pp, t); |
da901964 | 863 | /* fall through. */ |
d04f0501 | 864 | case ERROR_MARK: |
4a5e902c | 865 | pp_string (pp, M_("<typeprefixerror>")); |
d04f0501 | 866 | break; |
471086d6 | 867 | } |
868 | } | |
869 | ||
d04f0501 | 870 | /* Dump the suffix of type T, under control of FLAGS. This is the part |
871 | which appears after the identifier (or function parms). */ | |
872 | ||
471086d6 | 873 | static void |
4a5e902c | 874 | dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 875 | { |
876 | if (TYPE_PTRMEMFUNC_P (t)) | |
877 | t = TYPE_PTRMEMFUNC_FN_TYPE (t); | |
878 | ||
879 | switch (TREE_CODE (t)) | |
880 | { | |
881 | case POINTER_TYPE: | |
882 | case REFERENCE_TYPE: | |
883 | case OFFSET_TYPE: | |
75eaa947 | 884 | if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE |
885 | || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) | |
4a5e902c | 886 | pp_cxx_right_paren (pp); |
eb2dad34 | 887 | if (TREE_CODE (t) == POINTER_TYPE) |
888 | flags |= TFF_POINTER; | |
4a5e902c | 889 | dump_type_suffix (pp, TREE_TYPE (t), flags); |
471086d6 | 890 | break; |
891 | ||
471086d6 | 892 | case FUNCTION_TYPE: |
893 | case METHOD_TYPE: | |
894 | { | |
895 | tree arg; | |
75eaa947 | 896 | if (TREE_CODE (t) == METHOD_TYPE) |
897 | /* Can only be reached through a pointer. */ | |
4a5e902c | 898 | pp_cxx_right_paren (pp); |
471086d6 | 899 | arg = TYPE_ARG_TYPES (t); |
900 | if (TREE_CODE (t) == METHOD_TYPE) | |
901 | arg = TREE_CHAIN (arg); | |
902 | ||
8998b619 | 903 | /* Function pointers don't have default args. Not in standard C++, |
904 | anyway; they may in g++, but we'll just pretend otherwise. */ | |
4a5e902c | 905 | dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); |
8998b619 | 906 | |
4a5e902c | 907 | pp->padding = pp_before; |
eb2dad34 | 908 | pp_cxx_cv_qualifiers (pp, type_memfn_quals (t), |
909 | TREE_CODE (t) == FUNCTION_TYPE | |
910 | && (flags & TFF_POINTER)); | |
4a5e902c | 911 | dump_ref_qualifier (pp, t, flags); |
6d02e6b2 | 912 | if (tx_safe_fn_type_p (t)) |
913 | pp_cxx_ws_string (pp, "transaction_safe"); | |
4a5e902c | 914 | dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags); |
915 | dump_type_suffix (pp, TREE_TYPE (t), flags); | |
471086d6 | 916 | break; |
917 | } | |
918 | ||
919 | case ARRAY_TYPE: | |
4a5e902c | 920 | pp_maybe_space (pp); |
921 | pp_cxx_left_bracket (pp); | |
6b94e133 | 922 | if (tree dtype = TYPE_DOMAIN (t)) |
3cc0b4b9 | 923 | { |
c47c77bb | 924 | tree max = TYPE_MAX_VALUE (dtype); |
6b94e133 | 925 | /* Zero-length arrays have an upper bound of SIZE_MAX. */ |
e3a4c2db | 926 | if (integer_all_onesp (max)) |
4a5e902c | 927 | pp_character (pp, '0'); |
35ec552a | 928 | else if (tree_fits_shwi_p (max)) |
fcb97e84 | 929 | pp_wide_integer (pp, tree_to_shwi (max) + 1); |
3cc0b4b9 | 930 | else |
a35e091e | 931 | { |
932 | STRIP_NOPS (max); | |
933 | if (TREE_CODE (max) == SAVE_EXPR) | |
934 | max = TREE_OPERAND (max, 0); | |
935 | if (TREE_CODE (max) == MINUS_EXPR | |
936 | || TREE_CODE (max) == PLUS_EXPR) | |
937 | { | |
938 | max = TREE_OPERAND (max, 0); | |
939 | while (CONVERT_EXPR_P (max)) | |
940 | max = TREE_OPERAND (max, 0); | |
941 | } | |
942 | else | |
943 | max = fold_build2_loc (input_location, | |
944 | PLUS_EXPR, dtype, max, | |
945 | build_int_cst (dtype, 1)); | |
4a5e902c | 946 | dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS); |
a35e091e | 947 | } |
3cc0b4b9 | 948 | } |
4a5e902c | 949 | pp_cxx_right_bracket (pp); |
950 | dump_type_suffix (pp, TREE_TYPE (t), flags); | |
471086d6 | 951 | break; |
50cd3f45 | 952 | |
471086d6 | 953 | case ENUMERAL_TYPE: |
471086d6 | 954 | case IDENTIFIER_NODE: |
955 | case INTEGER_TYPE: | |
bb0726a1 | 956 | case BOOLEAN_TYPE: |
471086d6 | 957 | case REAL_TYPE: |
958 | case RECORD_TYPE: | |
959 | case TEMPLATE_TYPE_PARM: | |
cd5dd2d8 | 960 | case TEMPLATE_TEMPLATE_PARM: |
c405dc58 | 961 | case BOUND_TEMPLATE_TEMPLATE_PARM: |
471086d6 | 962 | case TREE_LIST: |
963 | case TYPE_DECL: | |
964 | case TREE_VEC: | |
471086d6 | 965 | case UNION_TYPE: |
4fdaf896 | 966 | case LANG_TYPE: |
471086d6 | 967 | case VOID_TYPE: |
e857e9c7 | 968 | case TYPENAME_TYPE: |
c4a8ac95 | 969 | case COMPLEX_TYPE: |
90a83261 | 970 | case VECTOR_TYPE: |
d3b75e30 | 971 | case TYPEOF_TYPE: |
8de5c43e | 972 | case UNDERLYING_TYPE: |
34da8800 | 973 | case DECLTYPE_TYPE: |
e4fbeb04 | 974 | case TYPE_PACK_EXPANSION: |
6ce18e5b | 975 | case FIXED_POINT_TYPE: |
fa67d8e8 | 976 | case NULLPTR_TYPE: |
471086d6 | 977 | break; |
978 | ||
979 | default: | |
4a5e902c | 980 | pp_unsupported_tree (pp, t); |
d04f0501 | 981 | case ERROR_MARK: |
982 | /* Don't mark it here, we should have already done in | |
653e5405 | 983 | dump_type_prefix. */ |
d04f0501 | 984 | break; |
471086d6 | 985 | } |
986 | } | |
987 | ||
71ccdfff | 988 | static void |
4a5e902c | 989 | dump_global_iord (cxx_pretty_printer *pp, tree t) |
471086d6 | 990 | { |
da901964 | 991 | const char *p = NULL; |
471086d6 | 992 | |
7e64c604 | 993 | if (DECL_GLOBAL_CTOR_P (t)) |
a608187f | 994 | p = M_("(static initializers for %s)"); |
7e64c604 | 995 | else if (DECL_GLOBAL_DTOR_P (t)) |
a608187f | 996 | p = M_("(static destructors for %s)"); |
471086d6 | 997 | else |
092b1d6f | 998 | gcc_unreachable (); |
50cd3f45 | 999 | |
fb79218c | 1000 | pp_printf (pp, p, DECL_SOURCE_FILE (t)); |
471086d6 | 1001 | } |
1002 | ||
3e97700e | 1003 | static void |
4a5e902c | 1004 | dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) |
3e97700e | 1005 | { |
682959c4 | 1006 | if (flags & TFF_DECL_SPECIFIERS) |
3e97700e | 1007 | { |
e6db887a | 1008 | if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t)) |
1009 | { | |
1010 | if (DECL_LANG_SPECIFIC (t) && DECL_DECLARED_CONCEPT_P (t)) | |
1011 | pp_cxx_ws_string (pp, "concept"); | |
1012 | else | |
1013 | pp_cxx_ws_string (pp, "constexpr"); | |
1014 | } | |
4a5e902c | 1015 | dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME); |
1016 | pp_maybe_space (pp); | |
3e97700e | 1017 | } |
facb12b2 | 1018 | if (! (flags & TFF_UNQUALIFIED_NAME) |
6d00b16b | 1019 | && TREE_CODE (t) != PARM_DECL |
facb12b2 | 1020 | && (!DECL_INITIAL (t) |
1021 | || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)) | |
4a5e902c | 1022 | dump_scope (pp, CP_DECL_CONTEXT (t), flags); |
facb12b2 | 1023 | flags &= ~TFF_UNQUALIFIED_NAME; |
7485db95 | 1024 | if ((flags & TFF_DECL_SPECIFIERS) |
1025 | && DECL_TEMPLATE_PARM_P (t) | |
1026 | && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t))) | |
4a5e902c | 1027 | pp_string (pp, "..."); |
3e97700e | 1028 | if (DECL_NAME (t)) |
32843f4e | 1029 | { |
52f020cf | 1030 | if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t)) |
32843f4e | 1031 | { |
4a5e902c | 1032 | pp_less (pp); |
1033 | pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2); | |
1034 | pp_string (pp, " capture>"); | |
32843f4e | 1035 | } |
1036 | else | |
4a5e902c | 1037 | dump_decl (pp, DECL_NAME (t), flags); |
32843f4e | 1038 | } |
a440faa5 | 1039 | else if (DECL_DECOMPOSITION_P (t)) |
1040 | pp_string (pp, M_("<structured bindings>")); | |
3e97700e | 1041 | else |
4a5e902c | 1042 | pp_string (pp, M_("<anonymous>")); |
682959c4 | 1043 | if (flags & TFF_DECL_SPECIFIERS) |
4a5e902c | 1044 | dump_type_suffix (pp, type, flags); |
3e97700e | 1045 | } |
1046 | ||
ac6641ca | 1047 | /* Print an IDENTIFIER_NODE that is the name of a declaration. */ |
1048 | ||
1049 | static void | |
1050 | dump_decl_name (cxx_pretty_printer *pp, tree t, int flags) | |
1051 | { | |
1052 | /* These special cases are duplicated here so that other functions | |
1053 | can feed identifiers to error and get them demangled properly. */ | |
991449b2 | 1054 | if (IDENTIFIER_CONV_OP_P (t)) |
ac6641ca | 1055 | { |
1056 | pp_cxx_ws_string (pp, "operator"); | |
1057 | /* Not exactly IDENTIFIER_TYPE_VALUE. */ | |
1058 | dump_type (pp, TREE_TYPE (t), flags); | |
1059 | return; | |
1060 | } | |
1061 | if (dguide_name_p (t)) | |
1062 | { | |
1063 | dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)), | |
f31d89ff | 1064 | TFF_UNQUALIFIED_NAME); |
ac6641ca | 1065 | return; |
1066 | } | |
1067 | ||
1068 | const char *str = IDENTIFIER_POINTER (t); | |
1069 | if (!strncmp (str, "_ZGR", 3)) | |
1070 | { | |
1071 | pp_cxx_ws_string (pp, "<temporary>"); | |
1072 | return; | |
1073 | } | |
1074 | ||
1075 | pp_cxx_tree_identifier (pp, t); | |
1076 | } | |
1077 | ||
d04f0501 | 1078 | /* Dump a human readable string for the decl T under control of FLAGS. */ |
1079 | ||
471086d6 | 1080 | static void |
4a5e902c | 1081 | dump_decl (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 1082 | { |
1083 | if (t == NULL_TREE) | |
1084 | return; | |
1085 | ||
601154bb | 1086 | /* If doing Objective-C++, give Objective-C a chance to demangle |
1087 | Objective-C method names. */ | |
1088 | if (c_dialect_objc ()) | |
1089 | { | |
1090 | const char *demangled = objc_maybe_printable_name (t, flags); | |
1091 | if (demangled) | |
1092 | { | |
4a5e902c | 1093 | pp_string (pp, demangled); |
601154bb | 1094 | return; |
1095 | } | |
1096 | } | |
1097 | ||
471086d6 | 1098 | switch (TREE_CODE (t)) |
1099 | { | |
b0722fac | 1100 | case TYPE_DECL: |
c0f42aca | 1101 | /* Don't say 'typedef class A' */ |
4ebfe3f3 | 1102 | if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t)) |
c0f42aca | 1103 | { |
1104 | if ((flags & TFF_DECL_SPECIFIERS) | |
1105 | && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) | |
7485db95 | 1106 | { |
1107 | /* Say `class T' not just `T'. */ | |
4a5e902c | 1108 | pp_cxx_ws_string (pp, "class"); |
7485db95 | 1109 | |
1110 | /* Emit the `...' for a parameter pack. */ | |
1111 | if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) | |
4a5e902c | 1112 | pp_cxx_ws_string (pp, "..."); |
7485db95 | 1113 | } |
9031d10b | 1114 | |
4a5e902c | 1115 | dump_type (pp, TREE_TYPE (t), flags); |
c0f42aca | 1116 | break; |
1117 | } | |
370478b1 | 1118 | if (TYPE_DECL_ALIAS_P (t) |
1119 | && (flags & TFF_DECL_SPECIFIERS | |
1120 | || flags & TFF_CLASS_KEY_OR_ENUM)) | |
1121 | { | |
4a5e902c | 1122 | pp_cxx_ws_string (pp, "using"); |
1123 | dump_decl (pp, DECL_NAME (t), flags); | |
1124 | pp_cxx_whitespace (pp); | |
1125 | pp_cxx_ws_string (pp, "="); | |
1126 | pp_cxx_whitespace (pp); | |
8847d9cf | 1127 | dump_type (pp, (DECL_ORIGINAL_TYPE (t) |
1128 | ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)), | |
1129 | flags); | |
370478b1 | 1130 | break; |
1131 | } | |
6dd3a38d | 1132 | if ((flags & TFF_DECL_SPECIFIERS) |
1133 | && !DECL_SELF_REFERENCE_P (t)) | |
4a5e902c | 1134 | pp_cxx_ws_string (pp, "typedef"); |
1135 | dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t) | |
d04f0501 | 1136 | ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), |
653e5405 | 1137 | flags); |
b0722fac | 1138 | break; |
50cd3f45 | 1139 | |
471086d6 | 1140 | case VAR_DECL: |
1e66592c | 1141 | if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) |
471086d6 | 1142 | { |
4a5e902c | 1143 | pp_string (pp, M_("vtable for ")); |
b4df430b | 1144 | gcc_assert (TYPE_P (DECL_CONTEXT (t))); |
4a5e902c | 1145 | dump_type (pp, DECL_CONTEXT (t), flags); |
471086d6 | 1146 | break; |
1147 | } | |
e3533433 | 1148 | /* Fall through. */ |
471086d6 | 1149 | case FIELD_DECL: |
1150 | case PARM_DECL: | |
4a5e902c | 1151 | dump_simple_decl (pp, t, TREE_TYPE (t), flags); |
ac4c2f95 | 1152 | |
1153 | /* Handle variable template specializations. */ | |
f4ae4202 | 1154 | if (VAR_P (t) |
ac4c2f95 | 1155 | && DECL_LANG_SPECIFIC (t) |
1156 | && DECL_TEMPLATE_INFO (t) | |
1157 | && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))) | |
1158 | { | |
1159 | pp_cxx_begin_template_argument_list (pp); | |
1160 | tree args = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t)); | |
1161 | dump_template_argument_list (pp, args, flags); | |
1162 | pp_cxx_end_template_argument_list (pp); | |
1163 | } | |
471086d6 | 1164 | break; |
1165 | ||
21854fc6 | 1166 | case RESULT_DECL: |
4a5e902c | 1167 | pp_string (pp, M_("<return value> ")); |
1168 | dump_simple_decl (pp, t, TREE_TYPE (t), flags); | |
21854fc6 | 1169 | break; |
1170 | ||
d0622bdf | 1171 | case NAMESPACE_DECL: |
2a9d763b | 1172 | if (flags & TFF_DECL_SPECIFIERS) |
36a8d9b9 | 1173 | pp->declaration (t); |
6378afde | 1174 | else |
653e5405 | 1175 | { |
facb12b2 | 1176 | if (! (flags & TFF_UNQUALIFIED_NAME)) |
4a5e902c | 1177 | dump_scope (pp, CP_DECL_CONTEXT (t), flags); |
facb12b2 | 1178 | flags &= ~TFF_UNQUALIFIED_NAME; |
653e5405 | 1179 | if (DECL_NAME (t) == NULL_TREE) |
8a47db47 | 1180 | { |
4a5e902c | 1181 | if (!(pp->flags & pp_c_flag_gnu_v3)) |
1182 | pp_cxx_ws_string (pp, M_("{anonymous}")); | |
8a47db47 | 1183 | else |
4a5e902c | 1184 | pp_cxx_ws_string (pp, M_("(anonymous namespace)")); |
8a47db47 | 1185 | } |
653e5405 | 1186 | else |
4a5e902c | 1187 | pp_cxx_tree_identifier (pp, DECL_NAME (t)); |
653e5405 | 1188 | } |
d0622bdf | 1189 | break; |
1190 | ||
626864c5 | 1191 | case SCOPE_REF: |
4a5e902c | 1192 | dump_type (pp, TREE_OPERAND (t, 0), flags); |
d6cc2ec2 | 1193 | pp_cxx_colon_colon (pp); |
4a5e902c | 1194 | dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME); |
50cd3f45 | 1195 | break; |
626864c5 | 1196 | |
471086d6 | 1197 | case ARRAY_REF: |
4a5e902c | 1198 | dump_decl (pp, TREE_OPERAND (t, 0), flags); |
1199 | pp_cxx_left_bracket (pp); | |
1200 | dump_decl (pp, TREE_OPERAND (t, 1), flags); | |
1201 | pp_cxx_right_bracket (pp); | |
471086d6 | 1202 | break; |
1203 | ||
d04f0501 | 1204 | /* So that we can do dump_decl on an aggr type. */ |
471086d6 | 1205 | case RECORD_TYPE: |
1206 | case UNION_TYPE: | |
1207 | case ENUMERAL_TYPE: | |
4a5e902c | 1208 | dump_type (pp, t, flags); |
471086d6 | 1209 | break; |
1210 | ||
63d857a2 | 1211 | case BIT_NOT_EXPR: |
071d2c90 | 1212 | /* This is a pseudo destructor call which has not been folded into |
653e5405 | 1213 | a PSEUDO_DTOR_EXPR yet. */ |
4a5e902c | 1214 | pp_cxx_complement (pp); |
1215 | dump_type (pp, TREE_OPERAND (t, 0), flags); | |
63d857a2 | 1216 | break; |
1217 | ||
471086d6 | 1218 | case TYPE_EXPR: |
092b1d6f | 1219 | gcc_unreachable (); |
471086d6 | 1220 | break; |
1221 | ||
471086d6 | 1222 | case IDENTIFIER_NODE: |
ac6641ca | 1223 | dump_decl_name (pp, t, flags); |
471086d6 | 1224 | break; |
1225 | ||
1eaf178d | 1226 | case OVERLOAD: |
d14ef710 | 1227 | if (!OVL_SINGLE_P (t)) |
1cfa8cdd | 1228 | { |
d6cc2ec2 | 1229 | tree ctx = ovl_scope (t); |
d14ef710 | 1230 | if (ctx != global_namespace) |
1cfa8cdd | 1231 | { |
d14ef710 | 1232 | if (TYPE_P (ctx)) |
1233 | dump_type (pp, ctx, flags); | |
1234 | else | |
1235 | dump_decl (pp, ctx, flags); | |
4a5e902c | 1236 | pp_cxx_colon_colon (pp); |
1cfa8cdd | 1237 | } |
d6cc2ec2 | 1238 | dump_decl (pp, OVL_NAME (t), flags); |
1cfa8cdd | 1239 | break; |
1240 | } | |
9031d10b | 1241 | |
1cfa8cdd | 1242 | /* If there's only one function, just treat it like an ordinary |
1243 | FUNCTION_DECL. */ | |
6767ca9a | 1244 | t = OVL_FIRST (t); |
1eaf178d | 1245 | /* Fall through. */ |
1246 | ||
471086d6 | 1247 | case FUNCTION_DECL: |
f134e87d | 1248 | if (! DECL_LANG_SPECIFIC (t)) |
a521cfc1 | 1249 | { |
b2620392 | 1250 | if (DECL_ABSTRACT_ORIGIN (t) |
1251 | && DECL_ABSTRACT_ORIGIN (t) != t) | |
a521cfc1 | 1252 | dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags); |
1253 | else | |
b2620392 | 1254 | dump_function_name (pp, t, flags); |
a521cfc1 | 1255 | } |
f134e87d | 1256 | else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) |
4a5e902c | 1257 | dump_global_iord (pp, t); |
471086d6 | 1258 | else |
4a5e902c | 1259 | dump_function_decl (pp, t, flags); |
471086d6 | 1260 | break; |
1261 | ||
1262 | case TEMPLATE_DECL: | |
4a5e902c | 1263 | dump_template_decl (pp, t, flags); |
471086d6 | 1264 | break; |
1265 | ||
aa8ce852 | 1266 | case TEMPLATE_ID_EXPR: |
1267 | { | |
7f634b7a | 1268 | tree name = TREE_OPERAND (t, 0); |
7d96d151 | 1269 | tree args = TREE_OPERAND (t, 1); |
9031d10b | 1270 | |
6767ca9a | 1271 | if (!identifier_p (name)) |
1272 | name = OVL_NAME (name); | |
4a5e902c | 1273 | dump_decl (pp, name, flags); |
1274 | pp_cxx_begin_template_argument_list (pp); | |
7d96d151 | 1275 | if (args == error_mark_node) |
4a5e902c | 1276 | pp_string (pp, M_("<template arguments error>")); |
7d96d151 | 1277 | else if (args) |
2933b804 | 1278 | dump_template_argument_list |
1279 | (pp, args, flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); | |
4a5e902c | 1280 | pp_cxx_end_template_argument_list (pp); |
aa8ce852 | 1281 | } |
1282 | break; | |
1283 | ||
471086d6 | 1284 | case LABEL_DECL: |
4a5e902c | 1285 | pp_cxx_tree_identifier (pp, DECL_NAME (t)); |
471086d6 | 1286 | break; |
1287 | ||
1288 | case CONST_DECL: | |
596c0ae6 | 1289 | if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) |
9c7a56ae | 1290 | || (DECL_INITIAL (t) && |
f3110581 | 1291 | TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) |
4a5e902c | 1292 | dump_simple_decl (pp, t, TREE_TYPE (t), flags); |
c4817b54 | 1293 | else if (DECL_NAME (t)) |
4a5e902c | 1294 | dump_decl (pp, DECL_NAME (t), flags); |
9c7a56ae | 1295 | else if (DECL_INITIAL (t)) |
4a5e902c | 1296 | dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); |
9c7a56ae | 1297 | else |
4a5e902c | 1298 | pp_string (pp, M_("<enumerator>")); |
471086d6 | 1299 | break; |
1300 | ||
fff5e605 | 1301 | case USING_DECL: |
caba101f | 1302 | { |
1303 | pp_cxx_ws_string (pp, "using"); | |
1304 | tree scope = USING_DECL_SCOPE (t); | |
1305 | bool variadic = false; | |
1306 | if (PACK_EXPANSION_P (scope)) | |
1307 | { | |
1308 | scope = PACK_EXPANSION_PATTERN (scope); | |
1309 | variadic = true; | |
1310 | } | |
1311 | dump_type (pp, scope, flags); | |
1312 | pp_cxx_colon_colon (pp); | |
1313 | dump_decl (pp, DECL_NAME (t), flags); | |
1314 | if (variadic) | |
1315 | pp_cxx_ws_string (pp, "..."); | |
1316 | } | |
fff5e605 | 1317 | break; |
1318 | ||
7a05c4b1 | 1319 | case STATIC_ASSERT: |
36a8d9b9 | 1320 | pp->declaration (t); |
7a05c4b1 | 1321 | break; |
1322 | ||
4ac852cb | 1323 | case BASELINK: |
4a5e902c | 1324 | dump_decl (pp, BASELINK_FUNCTIONS (t), flags); |
4ac852cb | 1325 | break; |
1326 | ||
13795292 | 1327 | case NON_DEPENDENT_EXPR: |
4a5e902c | 1328 | dump_expr (pp, t, flags); |
13795292 | 1329 | break; |
1330 | ||
7dddebd7 | 1331 | case TEMPLATE_TYPE_PARM: |
1332 | if (flags & TFF_DECL_SPECIFIERS) | |
36a8d9b9 | 1333 | pp->declaration (t); |
7dddebd7 | 1334 | else |
eaab24b9 | 1335 | pp->type_id (t); |
7dddebd7 | 1336 | break; |
1337 | ||
d676ce6e | 1338 | case UNBOUND_CLASS_TEMPLATE: |
f9550563 | 1339 | case TYPE_PACK_EXPANSION: |
95540e69 | 1340 | case TREE_BINFO: |
4a5e902c | 1341 | dump_type (pp, t, flags); |
d676ce6e | 1342 | break; |
1343 | ||
471086d6 | 1344 | default: |
4a5e902c | 1345 | pp_unsupported_tree (pp, t); |
c7afb782 | 1346 | /* Fall through. */ |
d04f0501 | 1347 | |
1348 | case ERROR_MARK: | |
4a5e902c | 1349 | pp_string (pp, M_("<declaration error>")); |
d04f0501 | 1350 | break; |
1351 | } | |
1352 | } | |
1353 | ||
1354 | /* Dump a template declaration T under control of FLAGS. This means the | |
1355 | 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ | |
1356 | ||
1357 | static void | |
4a5e902c | 1358 | dump_template_decl (cxx_pretty_printer *pp, tree t, int flags) |
d04f0501 | 1359 | { |
a6604172 | 1360 | tree orig_parms = DECL_TEMPLATE_PARMS (t); |
1361 | tree parms; | |
50cd3f45 | 1362 | int i; |
1363 | ||
682959c4 | 1364 | if (flags & TFF_TEMPLATE_HEADER) |
d04f0501 | 1365 | { |
50cd3f45 | 1366 | for (parms = orig_parms = nreverse (orig_parms); |
653e5405 | 1367 | parms; |
1368 | parms = TREE_CHAIN (parms)) | |
1369 | { | |
a6604172 | 1370 | tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); |
653e5405 | 1371 | int len = TREE_VEC_LENGTH (inner_parms); |
50cd3f45 | 1372 | |
68d514c1 | 1373 | if (len == 0) |
1374 | { | |
1375 | /* Skip over the dummy template levels of a template template | |
1376 | parm. */ | |
1377 | gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM); | |
1378 | continue; | |
1379 | } | |
1380 | ||
4a5e902c | 1381 | pp_cxx_ws_string (pp, "template"); |
1382 | pp_cxx_begin_template_argument_list (pp); | |
ed6762c8 | 1383 | |
1384 | /* If we've shown the template prefix, we'd better show the | |
1385 | parameters' and decl's type too. */ | |
1386 | flags |= TFF_DECL_SPECIFIERS; | |
1387 | ||
653e5405 | 1388 | for (i = 0; i < len; i++) |
1389 | { | |
1390 | if (i) | |
4a5e902c | 1391 | pp_separate_with_comma (pp); |
1392 | dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i), | |
1393 | flags); | |
653e5405 | 1394 | } |
4a5e902c | 1395 | pp_cxx_end_template_argument_list (pp); |
1396 | pp_cxx_whitespace (pp); | |
653e5405 | 1397 | } |
a6604172 | 1398 | nreverse(orig_parms); |
ed6762c8 | 1399 | |
1400 | if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) | |
7485db95 | 1401 | { |
1402 | /* Say `template<arg> class TT' not just `template<arg> TT'. */ | |
4a5e902c | 1403 | pp_cxx_ws_string (pp, "class"); |
7485db95 | 1404 | |
1405 | /* If this is a parameter pack, print the ellipsis. */ | |
1406 | if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) | |
4a5e902c | 1407 | pp_cxx_ws_string (pp, "..."); |
7485db95 | 1408 | } |
f59602ad | 1409 | |
1410 | /* Only print the requirements if we're also printing | |
1411 | the template header. */ | |
1412 | if (flag_concepts) | |
1413 | if (tree ci = get_constraints (t)) | |
1414 | if (check_constraint_info (ci)) | |
1415 | if (tree reqs = CI_TEMPLATE_REQS (ci)) | |
1416 | { | |
1417 | pp_cxx_requires_clause (pp, reqs); | |
1418 | pp_cxx_whitespace (pp); | |
1419 | } | |
d04f0501 | 1420 | } |
ed6762c8 | 1421 | |
56c12fd4 | 1422 | |
370478b1 | 1423 | if (DECL_CLASS_TEMPLATE_P (t)) |
4a5e902c | 1424 | dump_type (pp, TREE_TYPE (t), |
653e5405 | 1425 | ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME |
1426 | | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); | |
f25aa85d | 1427 | else if (DECL_TEMPLATE_RESULT (t) |
80a58eb0 | 1428 | && (VAR_P (DECL_TEMPLATE_RESULT (t)) |
370478b1 | 1429 | /* Alias template. */ |
1430 | || DECL_TYPE_TEMPLATE_P (t))) | |
4a5e902c | 1431 | dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); |
d04f0501 | 1432 | else |
d04f0501 | 1433 | { |
092b1d6f | 1434 | gcc_assert (TREE_TYPE (t)); |
1435 | switch (NEXT_CODE (t)) | |
1436 | { | |
1437 | case METHOD_TYPE: | |
1438 | case FUNCTION_TYPE: | |
4a5e902c | 1439 | dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME); |
092b1d6f | 1440 | break; |
1441 | default: | |
1442 | /* This case can occur with some invalid code. */ | |
4a5e902c | 1443 | dump_type (pp, TREE_TYPE (t), |
092b1d6f | 1444 | (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME |
1445 | | (flags & TFF_DECL_SPECIFIERS | |
1446 | ? TFF_CLASS_KEY_OR_ENUM : 0)); | |
1447 | } | |
471086d6 | 1448 | } |
1449 | } | |
1450 | ||
40c700ab | 1451 | /* find_typenames looks through the type of the function template T |
f1f41a6c | 1452 | and returns a vec containing any typedefs, decltypes or TYPENAME_TYPEs |
1c1c1457 | 1453 | it finds. */ |
40c700ab | 1454 | |
1455 | struct find_typenames_t | |
1456 | { | |
431205b7 | 1457 | hash_set<tree> *p_set; |
f1f41a6c | 1458 | vec<tree, va_gc> *typenames; |
40c700ab | 1459 | }; |
1460 | ||
1461 | static tree | |
1ee14739 | 1462 | find_typenames_r (tree *tp, int *walk_subtrees, void *data) |
40c700ab | 1463 | { |
1464 | struct find_typenames_t *d = (struct find_typenames_t *)data; | |
a409f927 | 1465 | tree mv = NULL_TREE; |
1466 | ||
1467 | if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp))) | |
1468 | /* Add the type of the typedef without any additional cv-quals. */ | |
1469 | mv = TREE_TYPE (TYPE_NAME (*tp)); | |
1c1c1457 | 1470 | else if (TREE_CODE (*tp) == TYPENAME_TYPE |
1471 | || TREE_CODE (*tp) == DECLTYPE_TYPE) | |
a409f927 | 1472 | /* Add the typename without any cv-qualifiers. */ |
1473 | mv = TYPE_MAIN_VARIANT (*tp); | |
1474 | ||
1ee14739 | 1475 | if (TREE_CODE (*tp) == TYPE_PACK_EXPANSION) |
1476 | { | |
1477 | /* Don't mess with parameter packs since we don't remember | |
1478 | the pack expansion context for a particular typename. */ | |
1479 | *walk_subtrees = false; | |
1480 | return NULL_TREE; | |
1481 | } | |
1482 | ||
431205b7 | 1483 | if (mv && (mv == *tp || !d->p_set->add (mv))) |
f1f41a6c | 1484 | vec_safe_push (d->typenames, mv); |
40c700ab | 1485 | |
40c700ab | 1486 | /* Search into class template arguments, which cp_walk_subtrees |
1487 | doesn't do. */ | |
a409f927 | 1488 | if (CLASS_TYPE_P (*tp) && CLASSTYPE_TEMPLATE_INFO (*tp)) |
1489 | cp_walk_tree (&CLASSTYPE_TI_ARGS (*tp), find_typenames_r, | |
1490 | data, d->p_set); | |
1491 | ||
40c700ab | 1492 | return NULL_TREE; |
1493 | } | |
1494 | ||
f1f41a6c | 1495 | static vec<tree, va_gc> * |
40c700ab | 1496 | find_typenames (tree t) |
1497 | { | |
1498 | struct find_typenames_t ft; | |
431205b7 | 1499 | ft.p_set = new hash_set<tree>; |
40c700ab | 1500 | ft.typenames = NULL; |
1501 | cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)), | |
1502 | find_typenames_r, &ft, ft.p_set); | |
431205b7 | 1503 | delete ft.p_set; |
40c700ab | 1504 | return ft.typenames; |
1505 | } | |
1506 | ||
a6082de3 | 1507 | /* Output the "[with ...]" clause for a template instantiation T iff |
1508 | TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if | |
1509 | formatting a deduction/substitution diagnostic rather than an | |
1510 | instantiation. */ | |
1511 | ||
1512 | static void | |
1513 | dump_substitution (cxx_pretty_printer *pp, | |
1514 | tree t, tree template_parms, tree template_args, | |
1515 | int flags) | |
1516 | { | |
1517 | if (template_parms != NULL_TREE && template_args != NULL_TREE | |
1518 | && !(flags & TFF_NO_TEMPLATE_BINDINGS)) | |
1519 | { | |
1520 | vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL; | |
1521 | pp_cxx_whitespace (pp); | |
1522 | pp_cxx_left_bracket (pp); | |
1523 | pp->translate_string ("with"); | |
1524 | pp_cxx_whitespace (pp); | |
1525 | dump_template_bindings (pp, template_parms, template_args, typenames); | |
1526 | pp_cxx_right_bracket (pp); | |
1527 | } | |
1528 | } | |
1529 | ||
1530 | /* Dump the lambda function FN including its 'mutable' qualifier and any | |
1531 | template bindings. */ | |
1532 | ||
1533 | static void | |
1534 | dump_lambda_function (cxx_pretty_printer *pp, | |
1535 | tree fn, tree template_parms, tree template_args, | |
1536 | int flags) | |
1537 | { | |
1538 | /* A lambda's signature is essentially its "type". */ | |
1539 | dump_type (pp, DECL_CONTEXT (fn), flags); | |
1540 | if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST)) | |
1541 | { | |
1542 | pp->padding = pp_before; | |
1543 | pp_c_ws_string (pp, "mutable"); | |
1544 | } | |
1545 | dump_substitution (pp, fn, template_parms, template_args, flags); | |
1546 | } | |
1547 | ||
8998b619 | 1548 | /* Pretty print a function decl. There are several ways we want to print a |
682959c4 | 1549 | function declaration. The TFF_ bits in FLAGS tells us how to behave. |
cf103c6c | 1550 | As error can only apply the '#' flag once to give 0 and 1 for V, there |
47cd6605 | 1551 | is %D which doesn't print the throw specs, and %F which does. */ |
471086d6 | 1552 | |
1553 | static void | |
4a5e902c | 1554 | dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 1555 | { |
64b4f183 | 1556 | tree fntype; |
1557 | tree parmtypes; | |
471086d6 | 1558 | tree cname = NULL_TREE; |
a2a627ce | 1559 | tree template_args = NULL_TREE; |
1560 | tree template_parms = NULL_TREE; | |
682959c4 | 1561 | int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; |
facb12b2 | 1562 | int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME); |
35f85a5a | 1563 | tree exceptions; |
98683d85 | 1564 | bool constexpr_p; |
4dfac60f | 1565 | tree ret = NULL_TREE; |
a8b75081 | 1566 | |
a2dc95eb | 1567 | flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME); |
64b4f183 | 1568 | if (TREE_CODE (t) == TEMPLATE_DECL) |
1569 | t = DECL_TEMPLATE_RESULT (t); | |
1570 | ||
35f85a5a | 1571 | /* Save the exceptions, in case t is a specialization and we are |
1572 | emitting an error about incompatible specifications. */ | |
1573 | exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t)); | |
1574 | ||
98683d85 | 1575 | /* Likewise for the constexpr specifier, in case t is a specialization. */ |
1576 | constexpr_p = DECL_DECLARED_CONSTEXPR_P (t); | |
1577 | ||
a2a627ce | 1578 | /* Pretty print template instantiations only. */ |
fc8ee10c | 1579 | if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t) |
33603066 | 1580 | && !(flags & TFF_NO_TEMPLATE_BINDINGS) |
fc8ee10c | 1581 | && flag_pretty_templates) |
a2a627ce | 1582 | { |
a32fe883 | 1583 | tree tmpl; |
1584 | ||
a2a627ce | 1585 | template_args = DECL_TI_ARGS (t); |
a32fe883 | 1586 | tmpl = most_general_template (t); |
1587 | if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL) | |
1588 | { | |
1589 | template_parms = DECL_TEMPLATE_PARMS (tmpl); | |
1590 | t = tmpl; | |
1591 | } | |
a2a627ce | 1592 | } |
1593 | ||
a6082de3 | 1594 | if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t)) |
1595 | return dump_lambda_function (pp, t, template_parms, template_args, flags); | |
1596 | ||
64b4f183 | 1597 | fntype = TREE_TYPE (t); |
dcbeb3ef | 1598 | parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t); |
64b4f183 | 1599 | |
caa99b15 | 1600 | if (DECL_CLASS_SCOPE_P (t)) |
9ba4048d | 1601 | cname = DECL_CONTEXT (t); |
331bc0ad | 1602 | /* This is for partially instantiated template methods. */ |
471086d6 | 1603 | else if (TREE_CODE (fntype) == METHOD_TYPE) |
1604 | cname = TREE_TYPE (TREE_VALUE (parmtypes)); | |
1605 | ||
7f69857d | 1606 | if (flags & TFF_DECL_SPECIFIERS) |
1607 | { | |
1608 | if (DECL_STATIC_FUNCTION_P (t)) | |
4a5e902c | 1609 | pp_cxx_ws_string (pp, "static"); |
7f69857d | 1610 | else if (DECL_VIRTUAL_P (t)) |
4a5e902c | 1611 | pp_cxx_ws_string (pp, "virtual"); |
7f69857d | 1612 | |
98683d85 | 1613 | if (constexpr_p) |
f59602ad | 1614 | { |
1615 | if (DECL_DECLARED_CONCEPT_P (t)) | |
1616 | pp_cxx_ws_string (pp, "concept"); | |
1617 | else | |
1618 | pp_cxx_ws_string (pp, "constexpr"); | |
1619 | } | |
7f69857d | 1620 | } |
50cd3f45 | 1621 | |
d04f0501 | 1622 | /* Print the return type? */ |
1623 | if (show_return) | |
c2ab9194 | 1624 | show_return = (!DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) |
1625 | && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t)); | |
d04f0501 | 1626 | if (show_return) |
2ee8e642 | 1627 | { |
4dfac60f | 1628 | ret = fndecl_declared_return_type (t); |
4a5e902c | 1629 | dump_type_prefix (pp, ret, flags); |
2ee8e642 | 1630 | } |
471086d6 | 1631 | |
477f2174 | 1632 | /* Print the function name. */ |
facb12b2 | 1633 | if (!do_outer_scope) |
1634 | /* Nothing. */; | |
1635 | else if (cname) | |
471086d6 | 1636 | { |
4a5e902c | 1637 | dump_type (pp, cname, flags); |
1638 | pp_cxx_colon_colon (pp); | |
caa99b15 | 1639 | } |
d04f0501 | 1640 | else |
4a5e902c | 1641 | dump_scope (pp, CP_DECL_CONTEXT (t), flags); |
471086d6 | 1642 | |
4a5e902c | 1643 | dump_function_name (pp, t, flags); |
50cd3f45 | 1644 | |
3d2a7578 | 1645 | if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) |
a1abbd01 | 1646 | { |
4a5e902c | 1647 | dump_parameters (pp, parmtypes, flags); |
50cd3f45 | 1648 | |
a1abbd01 | 1649 | if (TREE_CODE (fntype) == METHOD_TYPE) |
653e5405 | 1650 | { |
4a5e902c | 1651 | pp->padding = pp_before; |
1652 | pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype)); | |
1653 | dump_ref_qualifier (pp, fntype, flags); | |
653e5405 | 1654 | } |
50cd3f45 | 1655 | |
6d02e6b2 | 1656 | if (tx_safe_fn_type_p (fntype)) |
1657 | { | |
1658 | pp->padding = pp_before; | |
1659 | pp_cxx_ws_string (pp, "transaction_safe"); | |
1660 | } | |
1661 | ||
682959c4 | 1662 | if (flags & TFF_EXCEPTION_SPECIFICATION) |
653e5405 | 1663 | { |
4a5e902c | 1664 | pp->padding = pp_before; |
1665 | dump_exception_spec (pp, exceptions, flags); | |
653e5405 | 1666 | } |
7f5c5d3e | 1667 | |
1668 | if (show_return) | |
4dfac60f | 1669 | dump_type_suffix (pp, ret, flags); |
c2ab9194 | 1670 | else if (deduction_guide_p (t)) |
1671 | { | |
1672 | pp_cxx_ws_string (pp, "->"); | |
1673 | dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); | |
1674 | } | |
a2a627ce | 1675 | |
56c12fd4 | 1676 | if (flag_concepts) |
1677 | if (tree ci = get_constraints (t)) | |
1678 | if (tree reqs = CI_DECLARATOR_REQS (ci)) | |
1679 | pp_cxx_requires_clause (pp, reqs); | |
1680 | ||
a6082de3 | 1681 | dump_substitution (pp, t, template_parms, template_args, flags); |
7896267d | 1682 | |
1683 | if (tree base = DECL_INHERITED_CTOR_BASE (t)) | |
1684 | { | |
1685 | pp_cxx_ws_string (pp, "[inherited from"); | |
1686 | dump_type (pp, base, TFF_PLAIN_IDENTIFIER); | |
1687 | pp_character (pp, ']'); | |
1688 | } | |
673064cf | 1689 | } |
1690 | else if (template_args) | |
a2a627ce | 1691 | { |
673064cf | 1692 | bool need_comma = false; |
1693 | int i; | |
4a5e902c | 1694 | pp_cxx_begin_template_argument_list (pp); |
673064cf | 1695 | template_args = INNERMOST_TEMPLATE_ARGS (template_args); |
1696 | for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i) | |
1697 | { | |
1698 | tree arg = TREE_VEC_ELT (template_args, i); | |
1699 | if (need_comma) | |
4a5e902c | 1700 | pp_separate_with_comma (pp); |
673064cf | 1701 | if (ARGUMENT_PACK_P (arg)) |
4a5e902c | 1702 | pp_cxx_left_brace (pp); |
1703 | dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER); | |
673064cf | 1704 | if (ARGUMENT_PACK_P (arg)) |
4a5e902c | 1705 | pp_cxx_right_brace (pp); |
673064cf | 1706 | need_comma = true; |
1707 | } | |
4a5e902c | 1708 | pp_cxx_end_template_argument_list (pp); |
a2a627ce | 1709 | } |
8998b619 | 1710 | } |
1711 | ||
d04f0501 | 1712 | /* Print a parameter list. If this is for a member function, the |
1713 | member object ptr (and any other hidden args) should have | |
47cd6605 | 1714 | already been removed. */ |
8998b619 | 1715 | |
1716 | static void | |
4a5e902c | 1717 | dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags) |
8998b619 | 1718 | { |
d95d815d | 1719 | int first = 1; |
6d00b16b | 1720 | flags &= ~TFF_SCOPE; |
4a5e902c | 1721 | pp_cxx_left_paren (pp); |
8998b619 | 1722 | |
1723 | for (first = 1; parmtypes != void_list_node; | |
1724 | parmtypes = TREE_CHAIN (parmtypes)) | |
1725 | { | |
1726 | if (!first) | |
4a5e902c | 1727 | pp_separate_with_comma (pp); |
8998b619 | 1728 | first = 0; |
1729 | if (!parmtypes) | |
653e5405 | 1730 | { |
4a5e902c | 1731 | pp_cxx_ws_string (pp, "..."); |
653e5405 | 1732 | break; |
1733 | } | |
46147ffe | 1734 | |
4a5e902c | 1735 | dump_type (pp, TREE_VALUE (parmtypes), flags); |
50cd3f45 | 1736 | |
682959c4 | 1737 | if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) |
653e5405 | 1738 | { |
4a5e902c | 1739 | pp_cxx_whitespace (pp); |
1740 | pp_equal (pp); | |
1741 | pp_cxx_whitespace (pp); | |
1742 | dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); | |
653e5405 | 1743 | } |
8998b619 | 1744 | } |
1745 | ||
4a5e902c | 1746 | pp_cxx_right_paren (pp); |
8998b619 | 1747 | } |
1748 | ||
e116411c | 1749 | /* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */ |
1750 | ||
1751 | static void | |
4a5e902c | 1752 | dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED) |
e116411c | 1753 | { |
1754 | if (FUNCTION_REF_QUALIFIED (t)) | |
1755 | { | |
4a5e902c | 1756 | pp->padding = pp_before; |
e116411c | 1757 | if (FUNCTION_RVALUE_QUALIFIED (t)) |
4a5e902c | 1758 | pp_cxx_ws_string (pp, "&&"); |
e116411c | 1759 | else |
4a5e902c | 1760 | pp_cxx_ws_string (pp, "&"); |
e116411c | 1761 | } |
1762 | } | |
1763 | ||
47cd6605 | 1764 | /* Print an exception specification. T is the exception specification. */ |
8998b619 | 1765 | |
1766 | static void | |
4a5e902c | 1767 | dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags) |
8998b619 | 1768 | { |
3644efa5 | 1769 | if (t && TREE_PURPOSE (t)) |
1770 | { | |
4a5e902c | 1771 | pp_cxx_ws_string (pp, "noexcept"); |
9a24276f | 1772 | if (!integer_onep (TREE_PURPOSE (t))) |
1773 | { | |
1774 | pp_cxx_whitespace (pp); | |
1775 | pp_cxx_left_paren (pp); | |
1776 | if (DEFERRED_NOEXCEPT_SPEC_P (t)) | |
1777 | pp_cxx_ws_string (pp, "<uninstantiated>"); | |
1778 | else | |
1779 | dump_expr (pp, TREE_PURPOSE (t), flags); | |
1780 | pp_cxx_right_paren (pp); | |
1781 | } | |
3644efa5 | 1782 | } |
1783 | else if (t) | |
8998b619 | 1784 | { |
4a5e902c | 1785 | pp_cxx_ws_string (pp, "throw"); |
1786 | pp_cxx_whitespace (pp); | |
1787 | pp_cxx_left_paren (pp); | |
8998b619 | 1788 | if (TREE_VALUE (t) != NULL_TREE) |
653e5405 | 1789 | while (1) |
1790 | { | |
4a5e902c | 1791 | dump_type (pp, TREE_VALUE (t), flags); |
653e5405 | 1792 | t = TREE_CHAIN (t); |
1793 | if (!t) | |
1794 | break; | |
4a5e902c | 1795 | pp_separate_with_comma (pp); |
653e5405 | 1796 | } |
4a5e902c | 1797 | pp_cxx_right_paren (pp); |
8998b619 | 1798 | } |
471086d6 | 1799 | } |
1800 | ||
1801 | /* Handle the function name for a FUNCTION_DECL node, grokking operators | |
1802 | and destructors properly. */ | |
96624a9e | 1803 | |
471086d6 | 1804 | static void |
4a5e902c | 1805 | dump_function_name (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 1806 | { |
1807 | tree name = DECL_NAME (t); | |
1808 | ||
a5a1f3a2 | 1809 | /* We can get here with a decl that was synthesized by language- |
1810 | independent machinery (e.g. coverage.c) in which case it won't | |
1811 | have a lang_specific structure attached and DECL_CONSTRUCTOR_P | |
1812 | will crash. In this case it is safe just to print out the | |
1813 | literal name. */ | |
1814 | if (!DECL_LANG_SPECIFIC (t)) | |
1815 | { | |
4a5e902c | 1816 | pp_cxx_tree_identifier (pp, name); |
a5a1f3a2 | 1817 | return; |
1818 | } | |
1819 | ||
d5d76adc | 1820 | if (TREE_CODE (t) == TEMPLATE_DECL) |
1821 | t = DECL_TEMPLATE_RESULT (t); | |
1822 | ||
3eb89cd8 | 1823 | /* Don't let the user see __comp_ctor et al. */ |
1824 | if (DECL_CONSTRUCTOR_P (t) | |
1825 | || DECL_DESTRUCTOR_P (t)) | |
a8b75081 | 1826 | { |
1827 | if (LAMBDA_TYPE_P (DECL_CONTEXT (t))) | |
1828 | name = get_identifier ("<lambda>"); | |
4f86cbb0 | 1829 | else if (TYPE_UNNAMED_P (DECL_CONTEXT (t))) |
7b7a44c9 | 1830 | name = get_identifier ("<constructor>"); |
a8b75081 | 1831 | else |
1832 | name = constructor_name (DECL_CONTEXT (t)); | |
1833 | } | |
3eb89cd8 | 1834 | |
ff0e1638 | 1835 | if (DECL_DESTRUCTOR_P (t)) |
471086d6 | 1836 | { |
4a5e902c | 1837 | pp_cxx_complement (pp); |
1838 | dump_decl (pp, name, TFF_PLAIN_IDENTIFIER); | |
471086d6 | 1839 | } |
ff0e1638 | 1840 | else if (DECL_CONV_FN_P (t)) |
471086d6 | 1841 | { |
1842 | /* This cannot use the hack that the operator's return | |
1843 | type is stashed off of its name because it may be | |
1844 | used for error reporting. In the case of conflicting | |
1845 | declarations, both will have the same name, yet | |
1846 | the types will be different, hence the TREE_TYPE field | |
1847 | of the first name will be clobbered by the second. */ | |
4a5e902c | 1848 | pp_cxx_ws_string (pp, "operator"); |
1849 | dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); | |
471086d6 | 1850 | } |
471086d6 | 1851 | else |
4a5e902c | 1852 | dump_decl (pp, name, flags); |
b1cfe2be | 1853 | |
a5a1f3a2 | 1854 | if (DECL_TEMPLATE_INFO (t) |
ea935d05 | 1855 | && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) |
a761e730 | 1856 | && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL |
34197853 | 1857 | || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) |
4a5e902c | 1858 | dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), |
1859 | flags); | |
d04f0501 | 1860 | } |
668ae905 | 1861 | |
d04f0501 | 1862 | /* Dump the template parameters from the template info INFO under control of |
1863 | FLAGS. PRIMARY indicates whether this is a primary template decl, or | |
1864 | specialization (partial or complete). For partial specializations we show | |
1865 | the specialized parameter values. For a primary template we show no | |
1866 | decoration. */ | |
1867 | ||
1868 | static void | |
4a5e902c | 1869 | dump_template_parms (cxx_pretty_printer *pp, tree info, |
1870 | int primary, int flags) | |
d04f0501 | 1871 | { |
1872 | tree args = info ? TI_ARGS (info) : NULL_TREE; | |
50cd3f45 | 1873 | |
682959c4 | 1874 | if (primary && flags & TFF_TEMPLATE_NAME) |
d04f0501 | 1875 | return; |
682959c4 | 1876 | flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); |
4a5e902c | 1877 | pp_cxx_begin_template_argument_list (pp); |
d04f0501 | 1878 | |
1879 | /* Be careful only to print things when we have them, so as not | |
16c89e2f | 1880 | to crash producing error messages. */ |
d04f0501 | 1881 | if (args && !primary) |
1882 | { | |
b5959ba9 | 1883 | int len, ix; |
94c17f03 | 1884 | len = get_non_default_template_args_count (args, flags); |
50cd3f45 | 1885 | |
9e0a6903 | 1886 | args = INNERMOST_TEMPLATE_ARGS (args); |
b5959ba9 | 1887 | for (ix = 0; ix != len; ix++) |
653e5405 | 1888 | { |
1889 | tree arg = TREE_VEC_ELT (args, ix); | |
b5959ba9 | 1890 | |
d95d815d | 1891 | /* Only print a comma if we know there is an argument coming. In |
1892 | the case of an empty template argument pack, no actual | |
1893 | argument will be printed. */ | |
1894 | if (ix | |
1895 | && (!ARGUMENT_PACK_P (arg) | |
1896 | || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) | |
4a5e902c | 1897 | pp_separate_with_comma (pp); |
d95d815d | 1898 | |
1899 | if (!arg) | |
4a5e902c | 1900 | pp_string (pp, M_("<template parameter error>")); |
d95d815d | 1901 | else |
4a5e902c | 1902 | dump_template_argument (pp, arg, flags); |
d95d815d | 1903 | } |
d04f0501 | 1904 | } |
d04f0501 | 1905 | else if (primary) |
1906 | { | |
1907 | tree tpl = TI_TEMPLATE (info); | |
1908 | tree parms = DECL_TEMPLATE_PARMS (tpl); | |
1909 | int len, ix; | |
50cd3f45 | 1910 | |
d04f0501 | 1911 | parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE; |
1912 | len = parms ? TREE_VEC_LENGTH (parms) : 0; | |
50cd3f45 | 1913 | |
d04f0501 | 1914 | for (ix = 0; ix != len; ix++) |
653e5405 | 1915 | { |
6f32df61 | 1916 | tree parm; |
1917 | ||
1918 | if (TREE_VEC_ELT (parms, ix) == error_mark_node) | |
1919 | { | |
4a5e902c | 1920 | pp_string (pp, M_("<template parameter error>")); |
6f32df61 | 1921 | continue; |
1922 | } | |
1923 | ||
1924 | parm = TREE_VALUE (TREE_VEC_ELT (parms, ix)); | |
d04f0501 | 1925 | |
653e5405 | 1926 | if (ix) |
4a5e902c | 1927 | pp_separate_with_comma (pp); |
50cd3f45 | 1928 | |
4a5e902c | 1929 | dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS); |
653e5405 | 1930 | } |
b1cfe2be | 1931 | } |
4a5e902c | 1932 | pp_cxx_end_template_argument_list (pp); |
471086d6 | 1933 | } |
1934 | ||
c2f47e15 | 1935 | /* Print out the arguments of CALL_EXPR T as a parenthesized list using |
1936 | flags FLAGS. Skip over the first argument if SKIPFIRST is true. */ | |
1937 | ||
1938 | static void | |
4a5e902c | 1939 | dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst) |
c2f47e15 | 1940 | { |
1941 | tree arg; | |
1942 | call_expr_arg_iterator iter; | |
1943 | ||
4a5e902c | 1944 | pp_cxx_left_paren (pp); |
c2f47e15 | 1945 | FOR_EACH_CALL_EXPR_ARG (arg, iter, t) |
1946 | { | |
1947 | if (skipfirst) | |
1948 | skipfirst = false; | |
1949 | else | |
1950 | { | |
4a5e902c | 1951 | dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS); |
c2f47e15 | 1952 | if (more_call_expr_args_p (&iter)) |
4a5e902c | 1953 | pp_separate_with_comma (pp); |
c2f47e15 | 1954 | } |
1955 | } | |
4a5e902c | 1956 | pp_cxx_right_paren (pp); |
c2f47e15 | 1957 | } |
1958 | ||
1959 | /* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list | |
1960 | using flags FLAGS. Skip over the first argument if SKIPFIRST is | |
1961 | true. */ | |
1962 | ||
1963 | static void | |
4a5e902c | 1964 | dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags, |
1965 | bool skipfirst) | |
c2f47e15 | 1966 | { |
1967 | tree arg; | |
1968 | aggr_init_expr_arg_iterator iter; | |
1969 | ||
4a5e902c | 1970 | pp_cxx_left_paren (pp); |
c2f47e15 | 1971 | FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t) |
1972 | { | |
1973 | if (skipfirst) | |
1974 | skipfirst = false; | |
1975 | else | |
1976 | { | |
4a5e902c | 1977 | dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS); |
c2f47e15 | 1978 | if (more_aggr_init_expr_args_p (&iter)) |
4a5e902c | 1979 | pp_separate_with_comma (pp); |
c2f47e15 | 1980 | } |
1981 | } | |
4a5e902c | 1982 | pp_cxx_right_paren (pp); |
c2f47e15 | 1983 | } |
1984 | ||
331bc0ad | 1985 | /* Print out a list of initializers (subr of dump_expr). */ |
96624a9e | 1986 | |
471086d6 | 1987 | static void |
4a5e902c | 1988 | dump_expr_list (cxx_pretty_printer *pp, tree l, int flags) |
471086d6 | 1989 | { |
1990 | while (l) | |
1991 | { | |
4a5e902c | 1992 | dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS); |
471086d6 | 1993 | l = TREE_CHAIN (l); |
d04f0501 | 1994 | if (l) |
4a5e902c | 1995 | pp_separate_with_comma (pp); |
471086d6 | 1996 | } |
1997 | } | |
1998 | ||
c75b4594 | 1999 | /* Print out a vector of initializers (subr of dump_expr). */ |
2000 | ||
2001 | static void | |
4a5e902c | 2002 | dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v, |
2003 | int flags) | |
c75b4594 | 2004 | { |
2005 | unsigned HOST_WIDE_INT idx; | |
2006 | tree value; | |
2007 | ||
2008 | FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) | |
2009 | { | |
4a5e902c | 2010 | dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS); |
f1f41a6c | 2011 | if (idx != v->length () - 1) |
4a5e902c | 2012 | pp_separate_with_comma (pp); |
c75b4594 | 2013 | } |
2014 | } | |
2015 | ||
2016 | ||
47ee9a82 | 2017 | /* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual |
2018 | function. Resolve it to a close relative -- in the sense of static | |
2019 | type -- variant being overridden. That is close to what was written in | |
2020 | the source code. Subroutine of dump_expr. */ | |
2021 | ||
2022 | static tree | |
2023 | resolve_virtual_fun_from_obj_type_ref (tree ref) | |
2024 | { | |
2025 | tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref)); | |
6a0712d4 | 2026 | HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref)); |
47ee9a82 | 2027 | tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type))); |
68e4391d | 2028 | while (index) |
2029 | { | |
47ee9a82 | 2030 | fun = TREE_CHAIN (fun); |
68e4391d | 2031 | index -= (TARGET_VTABLE_USES_DESCRIPTORS |
2032 | ? TARGET_VTABLE_USES_DESCRIPTORS : 1); | |
2033 | } | |
47ee9a82 | 2034 | |
2035 | return BV_FN (fun); | |
2036 | } | |
2037 | ||
47cd6605 | 2038 | /* Print out an expression E under control of FLAGS. */ |
96624a9e | 2039 | |
471086d6 | 2040 | static void |
4a5e902c | 2041 | dump_expr (cxx_pretty_printer *pp, tree t, int flags) |
471086d6 | 2042 | { |
d9b14755 | 2043 | tree op; |
2044 | ||
dcc587fc | 2045 | if (t == 0) |
2046 | return; | |
9031d10b | 2047 | |
3fca6807 | 2048 | if (STATEMENT_CLASS_P (t)) |
2049 | { | |
4a5e902c | 2050 | pp_cxx_ws_string (pp, M_("<statement>")); |
3fca6807 | 2051 | return; |
2052 | } | |
2053 | ||
471086d6 | 2054 | switch (TREE_CODE (t)) |
2055 | { | |
2056 | case VAR_DECL: | |
2057 | case PARM_DECL: | |
2058 | case FIELD_DECL: | |
2059 | case CONST_DECL: | |
2060 | case FUNCTION_DECL: | |
dbdf67c6 | 2061 | case TEMPLATE_DECL: |
a8adb76d | 2062 | case NAMESPACE_DECL: |
88529a42 | 2063 | case LABEL_DECL: |
5b592939 | 2064 | case OVERLOAD: |
f91726b4 | 2065 | case TYPE_DECL: |
0a3b29ad | 2066 | case IDENTIFIER_NODE: |
4a5e902c | 2067 | dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE |
2068 | |TFF_TEMPLATE_HEADER)) | |
33603066 | 2069 | | TFF_NO_TEMPLATE_BINDINGS |
4a5e902c | 2070 | | TFF_NO_FUNCTION_ARGUMENTS)); |
471086d6 | 2071 | break; |
2072 | ||
6aa221fa | 2073 | case SSA_NAME: |
ec11736b | 2074 | if (SSA_NAME_VAR (t) |
2075 | && !DECL_ARTIFICIAL (SSA_NAME_VAR (t))) | |
4a5e902c | 2076 | dump_expr (pp, SSA_NAME_VAR (t), flags); |
6aa221fa | 2077 | else |
4a5e902c | 2078 | pp_cxx_ws_string (pp, M_("<unknown>")); |
6aa221fa | 2079 | break; |
2080 | ||
3ab4693e | 2081 | case VOID_CST: |
a9aacc0c | 2082 | case INTEGER_CST: |
471086d6 | 2083 | case REAL_CST: |
bb0c6c22 | 2084 | case STRING_CST: |
3eae2dbf | 2085 | case COMPLEX_CST: |
eaab24b9 | 2086 | pp->constant (t); |
471086d6 | 2087 | break; |
2088 | ||
244db24d | 2089 | case USERDEF_LITERAL: |
4a5e902c | 2090 | pp_cxx_userdef_literal (pp, t); |
244db24d | 2091 | break; |
2092 | ||
891f08be | 2093 | case THROW_EXPR: |
ef8bb1b0 | 2094 | /* While waiting for caret diagnostics, avoid printing |
2095 | __cxa_allocate_exception, __cxa_throw, and the like. */ | |
4a5e902c | 2096 | pp_cxx_ws_string (pp, M_("<throw-expression>")); |
891f08be | 2097 | break; |
2098 | ||
0f2952a1 | 2099 | case PTRMEM_CST: |
4a5e902c | 2100 | pp_ampersand (pp); |
2101 | dump_type (pp, PTRMEM_CST_CLASS (t), flags); | |
2102 | pp_cxx_colon_colon (pp); | |
2103 | pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t))); | |
0f2952a1 | 2104 | break; |
2105 | ||
471086d6 | 2106 | case COMPOUND_EXPR: |
4a5e902c | 2107 | pp_cxx_left_paren (pp); |
2108 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); | |
2109 | pp_separate_with_comma (pp); | |
2110 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); | |
2111 | pp_cxx_right_paren (pp); | |
471086d6 | 2112 | break; |
2113 | ||
2114 | case COND_EXPR: | |
7fcd7802 | 2115 | case VEC_COND_EXPR: |
4a5e902c | 2116 | pp_cxx_left_paren (pp); |
2117 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); | |
2118 | pp_string (pp, " ? "); | |
2119 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); | |
2120 | pp_string (pp, " : "); | |
2121 | dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS); | |
2122 | pp_cxx_right_paren (pp); | |
471086d6 | 2123 | break; |
2124 | ||
2125 | case SAVE_EXPR: | |
2126 | if (TREE_HAS_CONSTRUCTOR (t)) | |
2127 | { | |
4a5e902c | 2128 | pp_cxx_ws_string (pp, "new"); |
2129 | pp_cxx_whitespace (pp); | |
2130 | dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); | |
471086d6 | 2131 | } |
2132 | else | |
4a5e902c | 2133 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
471086d6 | 2134 | break; |
2135 | ||
f64b1d68 | 2136 | case AGGR_INIT_EXPR: |
a3786328 | 2137 | { |
2138 | tree fn = NULL_TREE; | |
50cd3f45 | 2139 | |
c2f47e15 | 2140 | if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR) |
2141 | fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0); | |
a3786328 | 2142 | |
2143 | if (fn && TREE_CODE (fn) == FUNCTION_DECL) | |
2144 | { | |
2145 | if (DECL_CONSTRUCTOR_P (fn)) | |
4a5e902c | 2146 | dump_type (pp, DECL_CONTEXT (fn), flags); |
a3786328 | 2147 | else |
4a5e902c | 2148 | dump_decl (pp, fn, 0); |
a3786328 | 2149 | } |
2150 | else | |
4a5e902c | 2151 | dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0); |
a3786328 | 2152 | } |
4a5e902c | 2153 | dump_aggr_init_expr_args (pp, t, flags, true); |
471086d6 | 2154 | break; |
2155 | ||
2156 | case CALL_EXPR: | |
2157 | { | |
c2f47e15 | 2158 | tree fn = CALL_EXPR_FN (t); |
2159 | bool skipfirst = false; | |
50cd3f45 | 2160 | |
6b71bdb4 | 2161 | /* Deal with internal functions. */ |
2162 | if (fn == NULL_TREE) | |
2163 | { | |
2164 | pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t))); | |
2165 | dump_call_expr_args (pp, t, flags, skipfirst); | |
2166 | break; | |
2167 | } | |
2168 | ||
471086d6 | 2169 | if (TREE_CODE (fn) == ADDR_EXPR) |
2170 | fn = TREE_OPERAND (fn, 0); | |
2171 | ||
074ab442 | 2172 | /* Nobody is interested in seeing the guts of vcalls. */ |
2173 | if (TREE_CODE (fn) == OBJ_TYPE_REF) | |
2174 | fn = resolve_virtual_fun_from_obj_type_ref (fn); | |
47ee9a82 | 2175 | |
27d8c1c6 | 2176 | if (TREE_TYPE (fn) != NULL_TREE |
2177 | && NEXT_CODE (fn) == METHOD_TYPE | |
2178 | && call_expr_nargs (t)) | |
471086d6 | 2179 | { |
c2f47e15 | 2180 | tree ob = CALL_EXPR_ARG (t, 0); |
471086d6 | 2181 | if (TREE_CODE (ob) == ADDR_EXPR) |
2182 | { | |
4a5e902c | 2183 | dump_expr (pp, TREE_OPERAND (ob, 0), |
2184 | flags | TFF_EXPR_IN_PARENS); | |
2185 | pp_cxx_dot (pp); | |
471086d6 | 2186 | } |
e3384c9f | 2187 | else if (!is_this_parameter (ob)) |
471086d6 | 2188 | { |
4a5e902c | 2189 | dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); |
2190 | pp_cxx_arrow (pp); | |
471086d6 | 2191 | } |
c2f47e15 | 2192 | skipfirst = true; |
471086d6 | 2193 | } |
9e46467d | 2194 | if (flag_sanitize & SANITIZE_UNDEFINED |
2195 | && is_ubsan_builtin_p (fn)) | |
2196 | { | |
2197 | pp_string (cxx_pp, M_("<ubsan routine call>")); | |
2198 | break; | |
2199 | } | |
4a5e902c | 2200 | dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS); |
2201 | dump_call_expr_args (pp, t, flags, skipfirst); | |
471086d6 | 2202 | } |
2203 | break; | |
2204 | ||
471086d6 | 2205 | case TARGET_EXPR: |
2206 | /* Note that this only works for G++ target exprs. If somebody | |
2207 | builds a general TARGET_EXPR, there's no way to represent that | |
2208 | it initializes anything other that the parameter slot for the | |
2209 | default argument. Note we may have cleared out the first | |
2210 | operand in expand_expr, so don't go killing ourselves. */ | |
2211 | if (TREE_OPERAND (t, 1)) | |
4a5e902c | 2212 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
471086d6 | 2213 | break; |
2214 | ||
227d73b4 | 2215 | case POINTER_PLUS_EXPR: |
4a5e902c | 2216 | dump_binary_op (pp, "+", t, flags); |
227d73b4 | 2217 | break; |
2218 | ||
57e83b58 | 2219 | case POINTER_DIFF_EXPR: |
2220 | dump_binary_op (pp, "-", t, flags); | |
2221 | break; | |
2222 | ||
054a0626 | 2223 | case INIT_EXPR: |
471086d6 | 2224 | case MODIFY_EXPR: |
ca16a224 | 2225 | dump_binary_op (pp, OVL_OP_INFO (true, NOP_EXPR)->name, t, flags); |
4c969cec | 2226 | break; |
2227 | ||
471086d6 | 2228 | case PLUS_EXPR: |
2229 | case MINUS_EXPR: | |
2230 | case MULT_EXPR: | |
2231 | case TRUNC_DIV_EXPR: | |
2232 | case TRUNC_MOD_EXPR: | |
2233 | case MIN_EXPR: | |
2234 | case MAX_EXPR: | |
2235 | case LSHIFT_EXPR: | |
2236 | case RSHIFT_EXPR: | |
2237 | case BIT_IOR_EXPR: | |
2238 | case BIT_XOR_EXPR: | |
2239 | case BIT_AND_EXPR: | |
471086d6 | 2240 | case TRUTH_ANDIF_EXPR: |
2241 | case TRUTH_ORIF_EXPR: | |
2242 | case LT_EXPR: | |
2243 | case LE_EXPR: | |
2244 | case GT_EXPR: | |
2245 | case GE_EXPR: | |
2246 | case EQ_EXPR: | |
2247 | case NE_EXPR: | |
2d31d4c8 | 2248 | case EXACT_DIV_EXPR: |
ca16a224 | 2249 | dump_binary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags); |
471086d6 | 2250 | break; |
2251 | ||
2252 | case CEIL_DIV_EXPR: | |
2253 | case FLOOR_DIV_EXPR: | |
2254 | case ROUND_DIV_EXPR: | |
7c813b54 | 2255 | case RDIV_EXPR: |
4a5e902c | 2256 | dump_binary_op (pp, "/", t, flags); |
471086d6 | 2257 | break; |
2258 | ||
2259 | case CEIL_MOD_EXPR: | |
2260 | case FLOOR_MOD_EXPR: | |
2261 | case ROUND_MOD_EXPR: | |
4a5e902c | 2262 | dump_binary_op (pp, "%", t, flags); |
471086d6 | 2263 | break; |
2264 | ||
2265 | case COMPONENT_REF: | |
2266 | { | |
2267 | tree ob = TREE_OPERAND (t, 0); | |
86ccc124 | 2268 | if (INDIRECT_REF_P (ob)) |
471086d6 | 2269 | { |
2270 | ob = TREE_OPERAND (ob, 0); | |
e3384c9f | 2271 | if (!is_this_parameter (ob)) |
471086d6 | 2272 | { |
4a5e902c | 2273 | dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); |
97e439ed | 2274 | if (TREE_CODE (TREE_TYPE (ob)) == REFERENCE_TYPE) |
4a5e902c | 2275 | pp_cxx_dot (pp); |
97e439ed | 2276 | else |
4a5e902c | 2277 | pp_cxx_arrow (pp); |
471086d6 | 2278 | } |
2279 | } | |
2280 | else | |
2281 | { | |
4a5e902c | 2282 | dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); |
636eeb71 | 2283 | if (TREE_CODE (ob) != ARROW_EXPR) |
2284 | pp_cxx_dot (pp); | |
471086d6 | 2285 | } |
4a5e902c | 2286 | dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); |
471086d6 | 2287 | } |
2288 | break; | |
2289 | ||
bea7d742 | 2290 | case ARRAY_REF: |
4a5e902c | 2291 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
2292 | pp_cxx_left_bracket (pp); | |
2293 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); | |
2294 | pp_cxx_right_bracket (pp); | |
bea7d742 | 2295 | break; |
2296 | ||
97d541d5 | 2297 | case UNARY_PLUS_EXPR: |
4a5e902c | 2298 | dump_unary_op (pp, "+", t, flags); |
471086d6 | 2299 | break; |
2300 | ||
2301 | case ADDR_EXPR: | |
2302 | if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL | |
bc577f39 | 2303 | || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST |
2304 | /* An ADDR_EXPR can have reference type. In that case, we | |
2305 | shouldn't print the `&' doing so indicates to the user | |
2306 | that the expression has pointer type. */ | |
50cd3f45 | 2307 | || (TREE_TYPE (t) |
bc577f39 | 2308 | && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) |
4a5e902c | 2309 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
88529a42 | 2310 | else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) |
4a5e902c | 2311 | dump_unary_op (pp, "&&", t, flags); |
471086d6 | 2312 | else |
4a5e902c | 2313 | dump_unary_op (pp, "&", t, flags); |
471086d6 | 2314 | break; |
2315 | ||
2316 | case INDIRECT_REF: | |
2317 | if (TREE_HAS_CONSTRUCTOR (t)) | |
2318 | { | |
2319 | t = TREE_OPERAND (t, 0); | |
b4df430b | 2320 | gcc_assert (TREE_CODE (t) == CALL_EXPR); |
4a5e902c | 2321 | dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS); |
2322 | dump_call_expr_args (pp, t, flags, true); | |
471086d6 | 2323 | } |
2324 | else | |
2325 | { | |
596c0ae6 | 2326 | if (TREE_OPERAND (t,0) != NULL_TREE |
072636f3 | 2327 | && TREE_TYPE (TREE_OPERAND (t, 0)) |
596c0ae6 | 2328 | && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) |
4a5e902c | 2329 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
471086d6 | 2330 | else |
4a5e902c | 2331 | dump_unary_op (pp, "*", t, flags); |
471086d6 | 2332 | } |
2333 | break; | |
2334 | ||
b0d55af9 | 2335 | case MEM_REF: |
2336 | if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR | |
2337 | && integer_zerop (TREE_OPERAND (t, 1))) | |
4a5e902c | 2338 | dump_expr (pp, TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags); |
b0d55af9 | 2339 | else |
2340 | { | |
4a5e902c | 2341 | pp_cxx_star (pp); |
b0d55af9 | 2342 | if (!integer_zerop (TREE_OPERAND (t, 1))) |
2343 | { | |
4a5e902c | 2344 | pp_cxx_left_paren (pp); |
b0d55af9 | 2345 | if (!integer_onep (TYPE_SIZE_UNIT |
2346 | (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)))))) | |
2347 | { | |
4a5e902c | 2348 | pp_cxx_left_paren (pp); |
2349 | dump_type (pp, ptr_type_node, flags); | |
2350 | pp_cxx_right_paren (pp); | |
b0d55af9 | 2351 | } |
2352 | } | |
4a5e902c | 2353 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
b0d55af9 | 2354 | if (!integer_zerop (TREE_OPERAND (t, 1))) |
2355 | { | |
4a5e902c | 2356 | pp_cxx_ws_string (pp, "+"); |
2357 | dump_expr (pp, fold_convert (ssizetype, TREE_OPERAND (t, 1)), | |
2358 | flags); | |
2359 | pp_cxx_right_paren (pp); | |
b0d55af9 | 2360 | } |
2361 | } | |
2362 | break; | |
2363 | ||
471086d6 | 2364 | case NEGATE_EXPR: |
2365 | case BIT_NOT_EXPR: | |
2366 | case TRUTH_NOT_EXPR: | |
2367 | case PREDECREMENT_EXPR: | |
2368 | case PREINCREMENT_EXPR: | |
ca16a224 | 2369 | dump_unary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags); |
471086d6 | 2370 | break; |
2371 | ||
2372 | case POSTDECREMENT_EXPR: | |
2373 | case POSTINCREMENT_EXPR: | |
4a5e902c | 2374 | pp_cxx_left_paren (pp); |
2375 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); | |
ca16a224 | 2376 | pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name); |
4a5e902c | 2377 | pp_cxx_right_paren (pp); |
471086d6 | 2378 | break; |
2379 | ||
2380 | case NON_LVALUE_EXPR: | |
2381 | /* FIXME: This is a KLUDGE workaround for a parsing problem. There | |
2382 | should be another level of INDIRECT_REF so that I don't have to do | |
2383 | this. */ | |
596c0ae6 | 2384 | if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) |
471086d6 | 2385 | { |
2386 | tree next = TREE_TYPE (TREE_TYPE (t)); | |
2387 | ||
c21c015b | 2388 | while (TYPE_PTR_P (next)) |
471086d6 | 2389 | next = TREE_TYPE (next); |
50cd3f45 | 2390 | |
471086d6 | 2391 | if (TREE_CODE (next) == FUNCTION_TYPE) |
2392 | { | |
682959c4 | 2393 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2394 | pp_cxx_left_paren (pp); |
2395 | pp_cxx_star (pp); | |
2396 | dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); | |
682959c4 | 2397 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2398 | pp_cxx_right_paren (pp); |
471086d6 | 2399 | break; |
2400 | } | |
331bc0ad | 2401 | /* Else fall through. */ |
471086d6 | 2402 | } |
4a5e902c | 2403 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); |
471086d6 | 2404 | break; |
2405 | ||
e226f39b | 2406 | CASE_CONVERT: |
91c3ace5 | 2407 | case IMPLICIT_CONV_EXPR: |
2d7085a5 | 2408 | case VIEW_CONVERT_EXPR: |
aa616daf | 2409 | { |
2410 | tree op = TREE_OPERAND (t, 0); | |
913dab69 | 2411 | tree ttype = TREE_TYPE (t); |
2412 | tree optype = TREE_TYPE (op); | |
2413 | ||
2414 | if (TREE_CODE (ttype) != TREE_CODE (optype) | |
2415 | && POINTER_TYPE_P (ttype) | |
2416 | && POINTER_TYPE_P (optype) | |
2417 | && same_type_p (TREE_TYPE (optype), | |
2418 | TREE_TYPE (ttype))) | |
2419 | { | |
2420 | if (TREE_CODE (ttype) == REFERENCE_TYPE) | |
8b10f693 | 2421 | { |
2422 | STRIP_NOPS (op); | |
2423 | if (TREE_CODE (op) == ADDR_EXPR) | |
2424 | dump_expr (pp, TREE_OPERAND (op, 0), flags); | |
2425 | else | |
2426 | dump_unary_op (pp, "*", t, flags); | |
2427 | } | |
913dab69 | 2428 | else |
4a5e902c | 2429 | dump_unary_op (pp, "&", t, flags); |
913dab69 | 2430 | } |
2431 | else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t))) | |
aa616daf | 2432 | { |
2433 | /* It is a cast, but we cannot tell whether it is a | |
2434 | reinterpret or static cast. Use the C style notation. */ | |
2435 | if (flags & TFF_EXPR_IN_PARENS) | |
4a5e902c | 2436 | pp_cxx_left_paren (pp); |
2437 | pp_cxx_left_paren (pp); | |
2438 | dump_type (pp, TREE_TYPE (t), flags); | |
2439 | pp_cxx_right_paren (pp); | |
2440 | dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS); | |
aa616daf | 2441 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2442 | pp_cxx_right_paren (pp); |
aa616daf | 2443 | } |
2444 | else | |
4a5e902c | 2445 | dump_expr (pp, op, flags); |
aa616daf | 2446 | break; |
2447 | } | |
9031d10b | 2448 | |
471086d6 | 2449 | case CONSTRUCTOR: |
38281c46 | 2450 | if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) |
2451 | { | |
4ac852cb | 2452 | tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); |
38281c46 | 2453 | |
dc9b5a48 | 2454 | if (integer_zerop (idx)) |
1c16607c | 2455 | { |
2456 | /* A NULL pointer-to-member constant. */ | |
4a5e902c | 2457 | pp_cxx_left_paren (pp); |
2458 | pp_cxx_left_paren (pp); | |
2459 | dump_type (pp, TREE_TYPE (t), flags); | |
2460 | pp_cxx_right_paren (pp); | |
2461 | pp_character (pp, '0'); | |
2462 | pp_cxx_right_paren (pp); | |
1c16607c | 2463 | break; |
2464 | } | |
35ec552a | 2465 | else if (tree_fits_shwi_p (idx)) |
38281c46 | 2466 | { |
2467 | tree virtuals; | |
2468 | unsigned HOST_WIDE_INT n; | |
2469 | ||
2470 | t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); | |
2471 | t = TYPE_METHOD_BASETYPE (t); | |
2cfde4f3 | 2472 | virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); |
50cd3f45 | 2473 | |
fcb97e84 | 2474 | n = tree_to_shwi (idx); |
38281c46 | 2475 | |
2476 | /* Map vtable index back one, to allow for the null pointer to | |
2477 | member. */ | |
2478 | --n; | |
2479 | ||
2480 | while (n > 0 && virtuals) | |
2481 | { | |
2482 | --n; | |
2483 | virtuals = TREE_CHAIN (virtuals); | |
2484 | } | |
2485 | if (virtuals) | |
2486 | { | |
4a5e902c | 2487 | dump_expr (pp, BV_FN (virtuals), |
653e5405 | 2488 | flags | TFF_EXPR_IN_PARENS); |
38281c46 | 2489 | break; |
2490 | } | |
2491 | } | |
2492 | } | |
89b7df3a | 2493 | if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t))) |
4a5e902c | 2494 | pp_string (pp, "<lambda closure object>"); |
c75b4594 | 2495 | if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t)) |
92d62798 | 2496 | { |
4a5e902c | 2497 | dump_type (pp, TREE_TYPE (t), 0); |
2498 | pp_cxx_left_paren (pp); | |
2499 | pp_cxx_right_paren (pp); | |
92d62798 | 2500 | } |
2501 | else | |
2502 | { | |
81d8c61f | 2503 | if (!BRACE_ENCLOSED_INITIALIZER_P (t)) |
4a5e902c | 2504 | dump_type (pp, TREE_TYPE (t), 0); |
2505 | pp_cxx_left_brace (pp); | |
2506 | dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags); | |
2507 | pp_cxx_right_brace (pp); | |
92d62798 | 2508 | } |
9031d10b | 2509 | |
471086d6 | 2510 | break; |
2511 | ||
ac9386a0 | 2512 | case OFFSET_REF: |
2513 | { | |
2514 | tree ob = TREE_OPERAND (t, 0); | |
2917b86f | 2515 | if (is_dummy_object (ob)) |
0f2952a1 | 2516 | { |
42b9ec6a | 2517 | t = TREE_OPERAND (t, 1); |
2518 | if (TREE_CODE (t) == FUNCTION_DECL) | |
0f2952a1 | 2519 | /* A::f */ |
4a5e902c | 2520 | dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS); |
42b9ec6a | 2521 | else if (BASELINK_P (t)) |
6767ca9a | 2522 | dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)), |
8042247d | 2523 | flags | TFF_EXPR_IN_PARENS); |
0f2952a1 | 2524 | else |
4a5e902c | 2525 | dump_decl (pp, t, flags); |
0f2952a1 | 2526 | } |
ac9386a0 | 2527 | else |
2528 | { | |
86ccc124 | 2529 | if (INDIRECT_REF_P (ob)) |
4b5bcd15 | 2530 | { |
4a5e902c | 2531 | dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); |
2532 | pp_cxx_arrow (pp); | |
2533 | pp_cxx_star (pp); | |
4b5bcd15 | 2534 | } |
2535 | else | |
2536 | { | |
4a5e902c | 2537 | dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); |
2538 | pp_cxx_dot (pp); | |
2539 | pp_cxx_star (pp); | |
4b5bcd15 | 2540 | } |
4a5e902c | 2541 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); |
ac9386a0 | 2542 | } |
2543 | break; | |
2544 | } | |
2545 | ||
f3110581 | 2546 | case TEMPLATE_PARM_INDEX: |
4a5e902c | 2547 | dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS); |
1adc02a5 | 2548 | break; |
e857e9c7 | 2549 | |
e857e9c7 | 2550 | case CAST_EXPR: |
1ad432f2 | 2551 | if (TREE_OPERAND (t, 0) == NULL_TREE |
2552 | || TREE_CHAIN (TREE_OPERAND (t, 0))) | |
e4ce2dc4 | 2553 | { |
4a5e902c | 2554 | dump_type (pp, TREE_TYPE (t), flags); |
2555 | pp_cxx_left_paren (pp); | |
2556 | dump_expr_list (pp, TREE_OPERAND (t, 0), flags); | |
2557 | pp_cxx_right_paren (pp); | |
e4ce2dc4 | 2558 | } |
2559 | else | |
2560 | { | |
4a5e902c | 2561 | pp_cxx_left_paren (pp); |
2562 | dump_type (pp, TREE_TYPE (t), flags); | |
2563 | pp_cxx_right_paren (pp); | |
2564 | pp_cxx_left_paren (pp); | |
2565 | dump_expr_list (pp, TREE_OPERAND (t, 0), flags); | |
2566 | pp_cxx_right_paren (pp); | |
e4ce2dc4 | 2567 | } |
2568 | break; | |
2569 | ||
2a88c9e6 | 2570 | case STATIC_CAST_EXPR: |
4a5e902c | 2571 | pp_cxx_ws_string (pp, "static_cast"); |
2a88c9e6 | 2572 | goto cast; |
2573 | case REINTERPRET_CAST_EXPR: | |
4a5e902c | 2574 | pp_cxx_ws_string (pp, "reinterpret_cast"); |
2a88c9e6 | 2575 | goto cast; |
2576 | case CONST_CAST_EXPR: | |
4a5e902c | 2577 | pp_cxx_ws_string (pp, "const_cast"); |
2a88c9e6 | 2578 | goto cast; |
2579 | case DYNAMIC_CAST_EXPR: | |
4a5e902c | 2580 | pp_cxx_ws_string (pp, "dynamic_cast"); |
2a88c9e6 | 2581 | cast: |
4a5e902c | 2582 | pp_cxx_begin_template_argument_list (pp); |
2583 | dump_type (pp, TREE_TYPE (t), flags); | |
2584 | pp_cxx_end_template_argument_list (pp); | |
2585 | pp_cxx_left_paren (pp); | |
2586 | dump_expr (pp, TREE_OPERAND (t, 0), flags); | |
2587 | pp_cxx_right_paren (pp); | |
2a88c9e6 | 2588 | break; |
2589 | ||
c8075df7 | 2590 | case ARROW_EXPR: |
4a5e902c | 2591 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
2592 | pp_cxx_arrow (pp); | |
c8075df7 | 2593 | break; |
2594 | ||
e4ce2dc4 | 2595 | case SIZEOF_EXPR: |
dd53deb4 | 2596 | case ALIGNOF_EXPR: |
2597 | if (TREE_CODE (t) == SIZEOF_EXPR) | |
4a5e902c | 2598 | pp_cxx_ws_string (pp, "sizeof"); |
50cd3f45 | 2599 | else |
dd53deb4 | 2600 | { |
b4df430b | 2601 | gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR); |
4a5e902c | 2602 | pp_cxx_ws_string (pp, "__alignof__"); |
dd53deb4 | 2603 | } |
d9b14755 | 2604 | op = TREE_OPERAND (t, 0); |
2605 | if (PACK_EXPANSION_P (op)) | |
2606 | { | |
4a5e902c | 2607 | pp_string (pp, "..."); |
d9b14755 | 2608 | op = PACK_EXPANSION_PATTERN (op); |
2609 | } | |
4a5e902c | 2610 | pp_cxx_whitespace (pp); |
2611 | pp_cxx_left_paren (pp); | |
121296ee | 2612 | if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) |
4a5e902c | 2613 | dump_type (pp, TREE_TYPE (op), flags); |
121296ee | 2614 | else if (TYPE_P (TREE_OPERAND (t, 0))) |
4a5e902c | 2615 | dump_type (pp, op, flags); |
e4ce2dc4 | 2616 | else |
4a5e902c | 2617 | dump_expr (pp, op, flags); |
2618 | pp_cxx_right_paren (pp); | |
e4ce2dc4 | 2619 | break; |
e857e9c7 | 2620 | |
f4babcfa | 2621 | case AT_ENCODE_EXPR: |
4a5e902c | 2622 | pp_cxx_ws_string (pp, "@encode"); |
2623 | pp_cxx_whitespace (pp); | |
2624 | pp_cxx_left_paren (pp); | |
2625 | dump_type (pp, TREE_OPERAND (t, 0), flags); | |
2626 | pp_cxx_right_paren (pp); | |
f4babcfa | 2627 | break; |
2628 | ||
3644efa5 | 2629 | case NOEXCEPT_EXPR: |
4a5e902c | 2630 | pp_cxx_ws_string (pp, "noexcept"); |
2631 | pp_cxx_whitespace (pp); | |
2632 | pp_cxx_left_paren (pp); | |
2633 | dump_expr (pp, TREE_OPERAND (t, 0), flags); | |
2634 | pp_cxx_right_paren (pp); | |
3644efa5 | 2635 | break; |
2636 | ||
8ae6c136 | 2637 | case REALPART_EXPR: |
2638 | case IMAGPART_EXPR: | |
ca16a224 | 2639 | pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name); |
4a5e902c | 2640 | pp_cxx_whitespace (pp); |
2641 | dump_expr (pp, TREE_OPERAND (t, 0), flags); | |
8ae6c136 | 2642 | break; |
2643 | ||
39c8ac16 | 2644 | case DEFAULT_ARG: |
4a5e902c | 2645 | pp_string (pp, M_("<unparsed>")); |
39c8ac16 | 2646 | break; |
2647 | ||
a3fc4713 | 2648 | case TRY_CATCH_EXPR: |
a3fc4713 | 2649 | case CLEANUP_POINT_EXPR: |
4a5e902c | 2650 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
a3fc4713 | 2651 | break; |
2652 | ||
8318ad7a | 2653 | case PSEUDO_DTOR_EXPR: |
bf810855 | 2654 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
4a5e902c | 2655 | pp_cxx_dot (pp); |
bf810855 | 2656 | if (TREE_OPERAND (t, 1)) |
2657 | { | |
2658 | dump_type (pp, TREE_OPERAND (t, 1), flags); | |
2659 | pp_cxx_colon_colon (pp); | |
2660 | } | |
4a5e902c | 2661 | pp_cxx_complement (pp); |
bf810855 | 2662 | dump_type (pp, TREE_OPERAND (t, 2), flags); |
8318ad7a | 2663 | break; |
2664 | ||
a0412b00 | 2665 | case TEMPLATE_ID_EXPR: |
4a5e902c | 2666 | dump_decl (pp, t, flags); |
a0412b00 | 2667 | break; |
2668 | ||
4cbba981 | 2669 | case BIND_EXPR: |
019cf886 | 2670 | case STMT_EXPR: |
071dd4a7 | 2671 | case EXPR_STMT: |
4cbba981 | 2672 | case STATEMENT_LIST: |
019cf886 | 2673 | /* We don't yet have a way of dumping statements in a |
2674 | human-readable format. */ | |
4a5e902c | 2675 | pp_string (pp, "({...})"); |
019cf886 | 2676 | break; |
2677 | ||
123cc979 | 2678 | case LOOP_EXPR: |
4a5e902c | 2679 | pp_string (pp, "while (1) { "); |
2680 | dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); | |
2681 | pp_cxx_right_brace (pp); | |
123cc979 | 2682 | break; |
2683 | ||
2684 | case EXIT_EXPR: | |
4a5e902c | 2685 | pp_string (pp, "if ("); |
2686 | dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); | |
2687 | pp_string (pp, ") break; "); | |
123cc979 | 2688 | break; |
2689 | ||
0a3b29ad | 2690 | case BASELINK: |
4a5e902c | 2691 | dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS); |
0a3b29ad | 2692 | break; |
2693 | ||
960e38ca | 2694 | case EMPTY_CLASS_EXPR: |
4a5e902c | 2695 | dump_type (pp, TREE_TYPE (t), flags); |
2696 | pp_cxx_left_paren (pp); | |
2697 | pp_cxx_right_paren (pp); | |
960e38ca | 2698 | break; |
2699 | ||
13795292 | 2700 | case NON_DEPENDENT_EXPR: |
4a5e902c | 2701 | dump_expr (pp, TREE_OPERAND (t, 0), flags); |
13795292 | 2702 | break; |
6495357a | 2703 | |
46147ffe | 2704 | case ARGUMENT_PACK_SELECT: |
4a5e902c | 2705 | dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags); |
46147ffe | 2706 | break; |
2707 | ||
d1e981b1 | 2708 | case RECORD_TYPE: |
2709 | case UNION_TYPE: | |
2710 | case ENUMERAL_TYPE: | |
2711 | case REAL_TYPE: | |
2712 | case VOID_TYPE: | |
2713 | case BOOLEAN_TYPE: | |
2714 | case INTEGER_TYPE: | |
2715 | case COMPLEX_TYPE: | |
2716 | case VECTOR_TYPE: | |
4a5e902c | 2717 | pp_type_specifier_seq (pp, t); |
d1e981b1 | 2718 | break; |
2719 | ||
2720 | case TYPENAME_TYPE: | |
2721 | /* We get here when we want to print a dependent type as an | |
2722 | id-expression, without any disambiguator decoration. */ | |
eaab24b9 | 2723 | pp->id_expression (t); |
d1e981b1 | 2724 | break; |
2725 | ||
8d31a12d | 2726 | case TEMPLATE_TYPE_PARM: |
54c12599 | 2727 | case TEMPLATE_TEMPLATE_PARM: |
8d31a12d | 2728 | case BOUND_TEMPLATE_TEMPLATE_PARM: |
4a5e902c | 2729 | dump_type (pp, t, flags); |
8d31a12d | 2730 | break; |
2731 | ||
94c6406e | 2732 | case TRAIT_EXPR: |
4a5e902c | 2733 | pp_cxx_trait_expression (pp, t); |
94c6406e | 2734 | break; |
2735 | ||
6739b437 | 2736 | case VA_ARG_EXPR: |
4a5e902c | 2737 | pp_cxx_va_arg_expression (pp, t); |
6739b437 | 2738 | break; |
2739 | ||
c1d5dc55 | 2740 | case OFFSETOF_EXPR: |
4a5e902c | 2741 | pp_cxx_offsetof_expression (pp, t); |
c1d5dc55 | 2742 | break; |
2743 | ||
cd45162d | 2744 | case ADDRESSOF_EXPR: |
2745 | pp_cxx_addressof_expression (pp, t); | |
2746 | break; | |
2747 | ||
7ec8e6a2 | 2748 | case SCOPE_REF: |
4a5e902c | 2749 | dump_decl (pp, t, flags); |
5bd9bf06 | 2750 | break; |
2751 | ||
7ec8e6a2 | 2752 | case EXPR_PACK_EXPANSION: |
f59602ad | 2753 | case UNARY_LEFT_FOLD_EXPR: |
2754 | case UNARY_RIGHT_FOLD_EXPR: | |
2755 | case BINARY_LEFT_FOLD_EXPR: | |
2756 | case BINARY_RIGHT_FOLD_EXPR: | |
7ec8e6a2 | 2757 | case TYPEID_EXPR: |
1167e60f | 2758 | case MEMBER_REF: |
2759 | case DOTSTAR_EXPR: | |
b350f3fc | 2760 | case NEW_EXPR: |
2761 | case VEC_NEW_EXPR: | |
f9a184db | 2762 | case DELETE_EXPR: |
2763 | case VEC_DELETE_EXPR: | |
7ec8e6a2 | 2764 | case MODOP_EXPR: |
6da504a8 | 2765 | case ABS_EXPR: |
d62c98bc | 2766 | case CONJ_EXPR: |
43fff710 | 2767 | case VECTOR_CST: |
d62c98bc | 2768 | case FIXED_CST: |
cc9a8843 | 2769 | case UNORDERED_EXPR: |
2770 | case ORDERED_EXPR: | |
2771 | case UNLT_EXPR: | |
2772 | case UNLE_EXPR: | |
2773 | case UNGT_EXPR: | |
2774 | case UNGE_EXPR: | |
2775 | case UNEQ_EXPR: | |
2776 | case LTGT_EXPR: | |
7a4209c5 | 2777 | case COMPLEX_EXPR: |
a3efadc7 | 2778 | case BIT_FIELD_REF: |
6ce18e5b | 2779 | case FIX_TRUNC_EXPR: |
2780 | case FLOAT_EXPR: | |
eaab24b9 | 2781 | pp->expression (t); |
f9a184db | 2782 | break; |
2783 | ||
37aea014 | 2784 | case TRUTH_AND_EXPR: |
2785 | case TRUTH_OR_EXPR: | |
2786 | case TRUTH_XOR_EXPR: | |
2787 | if (flags & TFF_EXPR_IN_PARENS) | |
4a5e902c | 2788 | pp_cxx_left_paren (pp); |
eaab24b9 | 2789 | pp->expression (t); |
37aea014 | 2790 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2791 | pp_cxx_right_paren (pp); |
37aea014 | 2792 | break; |
2793 | ||
d5a707b4 | 2794 | case OBJ_TYPE_REF: |
4a5e902c | 2795 | dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags); |
d5a707b4 | 2796 | break; |
2797 | ||
ac92ee1e | 2798 | case LAMBDA_EXPR: |
4a5e902c | 2799 | pp_string (pp, M_("<lambda>")); |
ac92ee1e | 2800 | break; |
2801 | ||
07850d16 | 2802 | case PAREN_EXPR: |
4a5e902c | 2803 | pp_cxx_left_paren (pp); |
2804 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); | |
2805 | pp_cxx_right_paren (pp); | |
07850d16 | 2806 | break; |
2807 | ||
56c12fd4 | 2808 | case REQUIRES_EXPR: |
2809 | pp_cxx_requires_expr (cxx_pp, t); | |
2810 | break; | |
2811 | ||
2812 | case SIMPLE_REQ: | |
2813 | pp_cxx_simple_requirement (cxx_pp, t); | |
2814 | break; | |
2815 | ||
2816 | case TYPE_REQ: | |
2817 | pp_cxx_type_requirement (cxx_pp, t); | |
2818 | break; | |
2819 | ||
2820 | case COMPOUND_REQ: | |
2821 | pp_cxx_compound_requirement (cxx_pp, t); | |
2822 | break; | |
2823 | ||
2824 | case NESTED_REQ: | |
2825 | pp_cxx_nested_requirement (cxx_pp, t); | |
2826 | break; | |
2827 | ||
2828 | case PRED_CONSTR: | |
f59602ad | 2829 | case CHECK_CONSTR: |
56c12fd4 | 2830 | case EXPR_CONSTR: |
2831 | case TYPE_CONSTR: | |
2832 | case ICONV_CONSTR: | |
2833 | case DEDUCT_CONSTR: | |
2834 | case EXCEPT_CONSTR: | |
2835 | case PARM_CONSTR: | |
2836 | case CONJ_CONSTR: | |
2837 | case DISJ_CONSTR: | |
2838 | pp_cxx_constraint (cxx_pp, t); | |
2839 | break; | |
2840 | ||
cf72f34d | 2841 | case PLACEHOLDER_EXPR: |
2842 | pp_string (pp, M_("*this")); | |
2843 | break; | |
2844 | ||
58a20866 | 2845 | case TREE_LIST: |
2846 | dump_expr_list (pp, t, flags); | |
2847 | break; | |
2848 | ||
471086d6 | 2849 | /* This list is incomplete, but should suffice for now. |
2850 | It is very important that `sorry' does not call | |
2851 | `report_error_function'. That could cause an infinite loop. */ | |
2852 | default: | |
4a5e902c | 2853 | pp_unsupported_tree (pp, t); |
c7afb782 | 2854 | /* Fall through. */ |
471086d6 | 2855 | case ERROR_MARK: |
4a5e902c | 2856 | pp_string (pp, M_("<expression error>")); |
471086d6 | 2857 | break; |
2858 | } | |
2859 | } | |
2860 | ||
2861 | static void | |
4a5e902c | 2862 | dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t, |
2863 | int flags) | |
471086d6 | 2864 | { |
4a5e902c | 2865 | pp_cxx_left_paren (pp); |
2866 | dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); | |
2867 | pp_cxx_whitespace (pp); | |
2d31d4c8 | 2868 | if (opstring) |
4a5e902c | 2869 | pp_cxx_ws_string (pp, opstring); |
2d31d4c8 | 2870 | else |
4a5e902c | 2871 | pp_string (pp, M_("<unknown operator>")); |
2872 | pp_cxx_whitespace (pp); | |
2873 | dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); | |
2874 | pp_cxx_right_paren (pp); | |
471086d6 | 2875 | } |
2876 | ||
2877 | static void | |
4a5e902c | 2878 | dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags) |
471086d6 | 2879 | { |
682959c4 | 2880 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2881 | pp_cxx_left_paren (pp); |
2882 | pp_cxx_ws_string (pp, opstring); | |
2883 | dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); | |
682959c4 | 2884 | if (flags & TFF_EXPR_IN_PARENS) |
4a5e902c | 2885 | pp_cxx_right_paren (pp); |
471086d6 | 2886 | } |
2887 | ||
573c13ef | 2888 | static void |
2889 | reinit_cxx_pp (void) | |
2890 | { | |
2891 | pp_clear_output_area (cxx_pp); | |
a94db6b0 | 2892 | cxx_pp->padding = pp_none; |
573c13ef | 2893 | pp_indentation (cxx_pp) = 0; |
2894 | pp_needs_newline (cxx_pp) = false; | |
5b3aad13 | 2895 | cxx_pp->enclosing_scope = current_function_decl; |
573c13ef | 2896 | } |
2897 | ||
53bce36c | 2898 | /* Same as pp_formatted_text, except the return string is a separate |
2899 | copy and has a GGC storage duration, e.g. an indefinite lifetime. */ | |
2900 | ||
2901 | inline const char * | |
2902 | pp_ggc_formatted_text (pretty_printer *pp) | |
2903 | { | |
2904 | return ggc_strdup (pp_formatted_text (pp)); | |
2905 | } | |
573c13ef | 2906 | |
682959c4 | 2907 | /* Exported interface to stringifying types, exprs and decls under TFF_* |
d04f0501 | 2908 | control. */ |
8998b619 | 2909 | |
fe756624 | 2910 | const char * |
f01d4233 | 2911 | type_as_string (tree typ, int flags) |
a608187f | 2912 | { |
2913 | reinit_cxx_pp (); | |
2914 | pp_translate_identifiers (cxx_pp) = false; | |
4a5e902c | 2915 | dump_type (cxx_pp, typ, flags); |
53bce36c | 2916 | return pp_ggc_formatted_text (cxx_pp); |
a608187f | 2917 | } |
2918 | ||
2919 | const char * | |
2920 | type_as_string_translate (tree typ, int flags) | |
471086d6 | 2921 | { |
573c13ef | 2922 | reinit_cxx_pp (); |
4a5e902c | 2923 | dump_type (cxx_pp, typ, flags); |
53bce36c | 2924 | return pp_ggc_formatted_text (cxx_pp); |
471086d6 | 2925 | } |
2926 | ||
fe756624 | 2927 | const char * |
f01d4233 | 2928 | expr_as_string (tree decl, int flags) |
471086d6 | 2929 | { |
573c13ef | 2930 | reinit_cxx_pp (); |
a608187f | 2931 | pp_translate_identifiers (cxx_pp) = false; |
4a5e902c | 2932 | dump_expr (cxx_pp, decl, flags); |
53bce36c | 2933 | return pp_ggc_formatted_text (cxx_pp); |
471086d6 | 2934 | } |
2935 | ||
8a47db47 | 2936 | /* Wrap decl_as_string with options appropriate for dwarf. */ |
2937 | ||
2938 | const char * | |
2939 | decl_as_dwarf_string (tree decl, int flags) | |
2940 | { | |
2941 | const char *name; | |
2942 | /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag | |
67cf9b55 | 2943 | here will be adequate to get the desired behavior. */ |
a94db6b0 | 2944 | cxx_pp->flags |= pp_c_flag_gnu_v3; |
8a47db47 | 2945 | name = decl_as_string (decl, flags); |
2946 | /* Subsequent calls to the pretty printer shouldn't use this style. */ | |
a94db6b0 | 2947 | cxx_pp->flags &= ~pp_c_flag_gnu_v3; |
8a47db47 | 2948 | return name; |
2949 | } | |
2950 | ||
fe756624 | 2951 | const char * |
f01d4233 | 2952 | decl_as_string (tree decl, int flags) |
a608187f | 2953 | { |
2954 | reinit_cxx_pp (); | |
2955 | pp_translate_identifiers (cxx_pp) = false; | |
4a5e902c | 2956 | dump_decl (cxx_pp, decl, flags); |
53bce36c | 2957 | return pp_ggc_formatted_text (cxx_pp); |
a608187f | 2958 | } |
2959 | ||
2960 | const char * | |
2961 | decl_as_string_translate (tree decl, int flags) | |
471086d6 | 2962 | { |
573c13ef | 2963 | reinit_cxx_pp (); |
4a5e902c | 2964 | dump_decl (cxx_pp, decl, flags); |
53bce36c | 2965 | return pp_ggc_formatted_text (cxx_pp); |
471086d6 | 2966 | } |
2967 | ||
8a47db47 | 2968 | /* Wrap lang_decl_name with options appropriate for dwarf. */ |
2969 | ||
2970 | const char * | |
2971 | lang_decl_dwarf_name (tree decl, int v, bool translate) | |
2972 | { | |
2973 | const char *name; | |
2974 | /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag | |
67cf9b55 | 2975 | here will be adequate to get the desired behavior. */ |
a94db6b0 | 2976 | cxx_pp->flags |= pp_c_flag_gnu_v3; |
8a47db47 | 2977 | name = lang_decl_name (decl, v, translate); |
2978 | /* Subsequent calls to the pretty printer shouldn't use this style. */ | |
a94db6b0 | 2979 | cxx_pp->flags &= ~pp_c_flag_gnu_v3; |
8a47db47 | 2980 | return name; |
2981 | } | |
2982 | ||
96554925 | 2983 | /* Generate the three forms of printable names for cxx_printable_name. */ |
11066dd5 | 2984 | |
fe756624 | 2985 | const char * |
a608187f | 2986 | lang_decl_name (tree decl, int v, bool translate) |
11066dd5 | 2987 | { |
2988 | if (v >= 2) | |
a608187f | 2989 | return (translate |
2990 | ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS) | |
2991 | : decl_as_string (decl, TFF_DECL_SPECIFIERS)); | |
11066dd5 | 2992 | |
573c13ef | 2993 | reinit_cxx_pp (); |
a608187f | 2994 | pp_translate_identifiers (cxx_pp) = translate; |
6634b72e | 2995 | if (v == 1 |
2996 | && (DECL_CLASS_SCOPE_P (decl) | |
2997 | || (DECL_NAMESPACE_SCOPE_P (decl) | |
2998 | && CP_DECL_CONTEXT (decl) != global_namespace))) | |
11066dd5 | 2999 | { |
4a5e902c | 3000 | dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); |
573c13ef | 3001 | pp_cxx_colon_colon (cxx_pp); |
11066dd5 | 3002 | } |
3003 | ||
3004 | if (TREE_CODE (decl) == FUNCTION_DECL) | |
4a5e902c | 3005 | dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER); |
8a47db47 | 3006 | else if ((DECL_NAME (decl) == NULL_TREE) |
3007 | && TREE_CODE (decl) == NAMESPACE_DECL) | |
4a5e902c | 3008 | dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME); |
11066dd5 | 3009 | else |
4a5e902c | 3010 | dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); |
11066dd5 | 3011 | |
53bce36c | 3012 | return pp_ggc_formatted_text (cxx_pp); |
11066dd5 | 3013 | } |
11066dd5 | 3014 | |
3cf8b391 | 3015 | /* Return the location of a tree passed to %+ formats. */ |
3016 | ||
f91726b4 | 3017 | location_t |
648a8029 | 3018 | location_of (tree t) |
471086d6 | 3019 | { |
8bed0f72 | 3020 | if (TYPE_P (t)) |
bbd7578e | 3021 | { |
3022 | t = TYPE_MAIN_DECL (t); | |
3023 | if (t == NULL_TREE) | |
3024 | return input_location; | |
3025 | } | |
1eaf178d | 3026 | else if (TREE_CODE (t) == OVERLOAD) |
6767ca9a | 3027 | t = OVL_FIRST (t); |
9031d10b | 3028 | |
a1f05651 | 3029 | if (DECL_P (t)) |
3030 | return DECL_SOURCE_LOCATION (t); | |
b9e17a4a | 3031 | if (TREE_CODE (t) == DEFAULT_ARG) |
3032 | return defarg_location (t); | |
3df42822 | 3033 | return EXPR_LOC_OR_LOC (t, input_location); |
471086d6 | 3034 | } |
3035 | ||
cf103c6c | 3036 | /* Now the interfaces from error et al to dump_type et al. Each takes an |
682959c4 | 3037 | on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_ |
d04f0501 | 3038 | function. */ |
3039 | ||
3040 | static const char * | |
f01d4233 | 3041 | decl_to_string (tree decl, int verbose) |
d04f0501 | 3042 | { |
682959c4 | 3043 | int flags = 0; |
32997f84 | 3044 | |
d04f0501 | 3045 | if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE |
3046 | || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE) | |
682959c4 | 3047 | flags = TFF_CLASS_KEY_OR_ENUM; |
d04f0501 | 3048 | if (verbose) |
a442e18f | 3049 | flags |= TFF_DECL_SPECIFIERS; |
d04f0501 | 3050 | else if (TREE_CODE (decl) == FUNCTION_DECL) |
682959c4 | 3051 | flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE; |
3052 | flags |= TFF_TEMPLATE_HEADER; | |
50cd3f45 | 3053 | |
573c13ef | 3054 | reinit_cxx_pp (); |
4a5e902c | 3055 | dump_decl (cxx_pp, decl, flags); |
53bce36c | 3056 | return pp_ggc_formatted_text (cxx_pp); |
d04f0501 | 3057 | } |
3058 | ||
3059 | static const char * | |
240171a9 | 3060 | expr_to_string (tree decl) |
d04f0501 | 3061 | { |
573c13ef | 3062 | reinit_cxx_pp (); |
4a5e902c | 3063 | dump_expr (cxx_pp, decl, 0); |
53bce36c | 3064 | return pp_ggc_formatted_text (cxx_pp); |
d04f0501 | 3065 | } |
3066 | ||
3067 | static const char * | |
f01d4233 | 3068 | fndecl_to_string (tree fndecl, int verbose) |
d04f0501 | 3069 | { |
682959c4 | 3070 | int flags; |
50cd3f45 | 3071 | |
4f7b3f58 | 3072 | flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS |
3073 | | TFF_TEMPLATE_HEADER; | |
d04f0501 | 3074 | if (verbose) |
682959c4 | 3075 | flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS; |
573c13ef | 3076 | reinit_cxx_pp (); |
4a5e902c | 3077 | dump_decl (cxx_pp, fndecl, flags); |
53bce36c | 3078 | return pp_ggc_formatted_text (cxx_pp); |
d04f0501 | 3079 | } |
3080 | ||
3081 | ||
3082 | static const char * | |
240171a9 | 3083 | code_to_string (enum tree_code c) |
471086d6 | 3084 | { |
f3d35d4d | 3085 | return get_tree_code_name (c); |
471086d6 | 3086 | } |
3087 | ||
f0edcca6 | 3088 | const char * |
240171a9 | 3089 | language_to_string (enum languages c) |
471086d6 | 3090 | { |
3091 | switch (c) | |
3092 | { | |
3093 | case lang_c: | |
3094 | return "C"; | |
3095 | ||
3096 | case lang_cplusplus: | |
3097 | return "C++"; | |
3098 | ||
3099 | default: | |
092b1d6f | 3100 | gcc_unreachable (); |
471086d6 | 3101 | } |
d26312d0 | 3102 | return NULL; |
471086d6 | 3103 | } |
3104 | ||
3105 | /* Return the proper printed version of a parameter to a C++ function. */ | |
96624a9e | 3106 | |
d04f0501 | 3107 | static const char * |
240171a9 | 3108 | parm_to_string (int p) |
471086d6 | 3109 | { |
573c13ef | 3110 | reinit_cxx_pp (); |
471086d6 | 3111 | if (p < 0) |
aa6db498 | 3112 | pp_string (cxx_pp, "'this'"); |
240171a9 | 3113 | else |
aa6db498 | 3114 | pp_decimal_int (cxx_pp, p + 1); |
53bce36c | 3115 | return pp_ggc_formatted_text (cxx_pp); |
471086d6 | 3116 | } |
3117 | ||
d04f0501 | 3118 | static const char * |
ca16a224 | 3119 | op_to_string (bool assop, enum tree_code p) |
471086d6 | 3120 | { |
ca16a224 | 3121 | tree id = ovl_op_identifier (assop, p); |
a608187f | 3122 | return id ? IDENTIFIER_POINTER (id) : M_("<unknown>"); |
471086d6 | 3123 | } |
3124 | ||
8e4391a5 | 3125 | /* Return a GC-allocated representation of type TYP, with verbosity VERBOSE. |
3126 | ||
3127 | If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the | |
3128 | string in appropriate places, and *QUOTE is written to with false | |
3129 | to suppress pp_format's trailing close quote so that e.g. | |
3130 | foo_typedef {aka underlying_foo} {enum} | |
3131 | can be printed by "%qT" as: | |
3132 | `foo_typedef' {aka `underlying_foo'} {enum} | |
3133 | rather than: | |
3134 | `foo_typedef {aka underlying_foo} {enum}' | |
3135 | When adding such quotes, if POSTPROCESSED is true (for handling %H and %I) | |
3136 | then a leading open quote will be added, whereas if POSTPROCESSED is false | |
3137 | (for handling %T) then any leading quote has already been added by | |
3138 | pp_format, or is not needed due to QUOTE being NULL (for template arguments | |
3139 | within %H and %I). | |
3140 | ||
3141 | SHOW_COLOR is used to determine the colorization of any quotes that | |
3142 | are added. */ | |
3143 | ||
d04f0501 | 3144 | static const char * |
8e4391a5 | 3145 | type_to_string (tree typ, int verbose, bool postprocessed, bool *quote, |
3146 | bool show_color) | |
d04f0501 | 3147 | { |
aa6db498 | 3148 | int flags = 0; |
d04f0501 | 3149 | if (verbose) |
682959c4 | 3150 | flags |= TFF_CLASS_KEY_OR_ENUM; |
3151 | flags |= TFF_TEMPLATE_HEADER; | |
50cd3f45 | 3152 | |
573c13ef | 3153 | reinit_cxx_pp (); |
8e4391a5 | 3154 | |
3155 | if (postprocessed && quote && *quote) | |
3156 | pp_begin_quote (cxx_pp, show_color); | |
3157 | ||
3158 | struct obstack *ob = pp_buffer (cxx_pp)->obstack; | |
3159 | int type_start, type_len; | |
3160 | type_start = obstack_object_size (ob); | |
3161 | ||
4a5e902c | 3162 | dump_type (cxx_pp, typ, flags); |
8e4391a5 | 3163 | |
3164 | /* Remember the end of the initial dump. */ | |
3165 | type_len = obstack_object_size (ob) - type_start; | |
3166 | ||
d233cdb5 | 3167 | /* If we're printing a type that involves typedefs, also print the |
3168 | stripped version. But sometimes the stripped version looks | |
3169 | exactly the same, so we don't want it after all. To avoid printing | |
3170 | it in that case, we play ugly obstack games. */ | |
e43fa5a4 | 3171 | if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ) |
3172 | && !uses_template_parms (typ)) | |
3173 | { | |
9c5900d3 | 3174 | int aka_start, aka_len; char *p; |
e43fa5a4 | 3175 | tree aka = strip_typedefs (typ); |
8e4391a5 | 3176 | if (quote && *quote) |
3177 | pp_end_quote (cxx_pp, show_color); | |
e43fa5a4 | 3178 | pp_string (cxx_pp, " {aka"); |
3179 | pp_cxx_whitespace (cxx_pp); | |
8e4391a5 | 3180 | if (quote && *quote) |
3181 | pp_begin_quote (cxx_pp, show_color); | |
d233cdb5 | 3182 | /* And remember the start of the aka dump. */ |
3183 | aka_start = obstack_object_size (ob); | |
4a5e902c | 3184 | dump_type (cxx_pp, aka, flags); |
9c5900d3 | 3185 | aka_len = obstack_object_size (ob) - aka_start; |
8e4391a5 | 3186 | if (quote && *quote) |
3187 | pp_end_quote (cxx_pp, show_color); | |
dda4f0ec | 3188 | pp_right_brace (cxx_pp); |
d233cdb5 | 3189 | p = (char*)obstack_base (ob); |
8e4391a5 | 3190 | /* If they are identical, cut off the aka by unwinding the obstack. */ |
3191 | if (type_len == aka_len | |
3192 | && memcmp (p + type_start, p+aka_start, type_len) == 0) | |
3193 | { | |
3194 | /* We can't add a '\0' here, since we may be adding a closing quote | |
3195 | below, and it would be hidden by the '\0'. | |
3196 | Instead, manually unwind the current object within the obstack | |
3197 | so that the insertion point is at the end of the type, before | |
3198 | the "' {aka". */ | |
3199 | int delta = type_start + type_len - obstack_object_size (ob); | |
3200 | gcc_assert (delta <= 0); | |
3201 | obstack_blank_fast (ob, delta); | |
3202 | } | |
3203 | else | |
3204 | if (quote) | |
3205 | /* No further closing quotes are needed. */ | |
3206 | *quote = false; | |
3207 | } | |
3208 | ||
3209 | if (quote && *quote) | |
3210 | { | |
3211 | pp_end_quote (cxx_pp, show_color); | |
3212 | *quote = false; | |
e43fa5a4 | 3213 | } |
53bce36c | 3214 | return pp_ggc_formatted_text (cxx_pp); |
d04f0501 | 3215 | } |
3216 | ||
d04f0501 | 3217 | static const char * |
f01d4233 | 3218 | args_to_string (tree p, int verbose) |
471086d6 | 3219 | { |
682959c4 | 3220 | int flags = 0; |
d04f0501 | 3221 | if (verbose) |
682959c4 | 3222 | flags |= TFF_CLASS_KEY_OR_ENUM; |
50cd3f45 | 3223 | |
471086d6 | 3224 | if (p == NULL_TREE) |
ec10e4ad | 3225 | return ""; |
471086d6 | 3226 | |
9308e976 | 3227 | if (TYPE_P (TREE_VALUE (p))) |
a608187f | 3228 | return type_as_string_translate (p, flags); |
ec10e4ad | 3229 | |
573c13ef | 3230 | reinit_cxx_pp (); |
ec10e4ad | 3231 | for (; p; p = TREE_CHAIN (p)) |
3232 | { | |
c4d89d79 | 3233 | if (TREE_VALUE (p) == null_node) |
1e00012f | 3234 | pp_cxx_ws_string (cxx_pp, "NULL"); |
c4d89d79 | 3235 | else |
4a5e902c | 3236 | dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags); |
ec10e4ad | 3237 | if (TREE_CHAIN (p)) |
aa6db498 | 3238 | pp_separate_with_comma (cxx_pp); |
ec10e4ad | 3239 | } |
53bce36c | 3240 | return pp_ggc_formatted_text (cxx_pp); |
471086d6 | 3241 | } |
ce28ee2e | 3242 | |
8ce59854 | 3243 | /* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P |
3244 | is a TREE_LIST with purpose the TEMPLATE_DECL, value the template | |
3245 | arguments. */ | |
3246 | ||
3247 | static const char * | |
3248 | subst_to_string (tree p) | |
3249 | { | |
3250 | tree decl = TREE_PURPOSE (p); | |
3251 | tree targs = TREE_VALUE (p); | |
3252 | tree tparms = DECL_TEMPLATE_PARMS (decl); | |
0f38b77f | 3253 | int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER |
3254 | |TFF_NO_TEMPLATE_BINDINGS); | |
8ce59854 | 3255 | |
3256 | if (p == NULL_TREE) | |
3257 | return ""; | |
3258 | ||
3259 | reinit_cxx_pp (); | |
4a5e902c | 3260 | dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags); |
a6082de3 | 3261 | dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0); |
53bce36c | 3262 | return pp_ggc_formatted_text (cxx_pp); |
8ce59854 | 3263 | } |
3264 | ||
d04f0501 | 3265 | static const char * |
f01d4233 | 3266 | cv_to_string (tree p, int v) |
ce28ee2e | 3267 | { |
573c13ef | 3268 | reinit_cxx_pp (); |
a94db6b0 | 3269 | cxx_pp->padding = v ? pp_before : pp_none; |
69cb846f | 3270 | pp_cxx_cv_qualifier_seq (cxx_pp, p); |
53bce36c | 3271 | return pp_ggc_formatted_text (cxx_pp); |
ce28ee2e | 3272 | } |
b97edf7e | 3273 | |
546a04b1 | 3274 | static const char * |
3275 | eh_spec_to_string (tree p, int /*v*/) | |
3276 | { | |
3277 | int flags = 0; | |
3278 | reinit_cxx_pp (); | |
3279 | dump_exception_spec (cxx_pp, p, flags); | |
3280 | return pp_ggc_formatted_text (cxx_pp); | |
3281 | } | |
3282 | ||
6c7ff025 | 3283 | /* Langhook for print_error_function. */ |
3284 | void | |
b8c23db3 | 3285 | cxx_print_error_function (diagnostic_context *context, const char *file, |
3286 | diagnostic_info *diagnostic) | |
68550df5 | 3287 | { |
b8c23db3 | 3288 | lhd_print_error_function (context, file, diagnostic); |
a94db6b0 | 3289 | pp_set_prefix (context->printer, file); |
25e2ffe1 | 3290 | maybe_print_instantiation_context (context); |
68550df5 | 3291 | } |
3292 | ||
b97edf7e | 3293 | static void |
f01d4233 | 3294 | cp_diagnostic_starter (diagnostic_context *context, |
653e5405 | 3295 | diagnostic_info *diagnostic) |
b97edf7e | 3296 | { |
389a9009 | 3297 | diagnostic_report_current_module (context, diagnostic_location (diagnostic)); |
25e2ffe1 | 3298 | cp_print_error_function (context, diagnostic); |
3299 | maybe_print_instantiation_context (context); | |
0a32318d | 3300 | maybe_print_constexpr_context (context); |
a94db6b0 | 3301 | pp_set_prefix (context->printer, diagnostic_build_prefix (context, |
2c2efebb | 3302 | diagnostic)); |
b97edf7e | 3303 | } |
3304 | ||
b97edf7e | 3305 | /* Print current function onto BUFFER, in the process of reporting |
3306 | a diagnostic message. Called from cp_diagnostic_starter. */ | |
3307 | static void | |
f01d4233 | 3308 | cp_print_error_function (diagnostic_context *context, |
653e5405 | 3309 | diagnostic_info *diagnostic) |
b97edf7e | 3310 | { |
5359d2eb | 3311 | /* If we are in an instantiation context, current_function_decl is likely |
3312 | to be wrong, so just rely on print_instantiation_full_context. */ | |
3313 | if (current_instantiation ()) | |
3314 | return; | |
b8c23db3 | 3315 | if (diagnostic_last_function_changed (context, diagnostic)) |
b97edf7e | 3316 | { |
aa6db498 | 3317 | const char *old_prefix = context->printer->prefix; |
389a9009 | 3318 | const char *file = LOCATION_FILE (diagnostic_location (diagnostic)); |
ce084dfc | 3319 | tree abstract_origin = diagnostic_abstract_origin (diagnostic); |
b8c23db3 | 3320 | char *new_prefix = (file && abstract_origin == NULL) |
2cafe211 | 3321 | ? file_name_as_prefix (context, file) : NULL; |
b97edf7e | 3322 | |
a94db6b0 | 3323 | pp_set_prefix (context->printer, new_prefix); |
50cd3f45 | 3324 | |
b97edf7e | 3325 | if (current_function_decl == NULL) |
a94db6b0 | 3326 | pp_string (context->printer, _("At global scope:")); |
b97edf7e | 3327 | else |
b8c23db3 | 3328 | { |
3329 | tree fndecl, ao; | |
3330 | ||
3331 | if (abstract_origin) | |
3332 | { | |
3333 | ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin); | |
c112531f | 3334 | while (TREE_CODE (ao) == BLOCK |
3335 | && BLOCK_ABSTRACT_ORIGIN (ao) | |
3336 | && BLOCK_ABSTRACT_ORIGIN (ao) != ao) | |
b8c23db3 | 3337 | ao = BLOCK_ABSTRACT_ORIGIN (ao); |
3338 | gcc_assert (TREE_CODE (ao) == FUNCTION_DECL); | |
3339 | fndecl = ao; | |
3340 | } | |
3341 | else | |
3342 | fndecl = current_function_decl; | |
3343 | ||
1e00012f | 3344 | pp_printf (context->printer, function_category (fndecl), |
a608187f | 3345 | cxx_printable_name_translate (fndecl, 2)); |
b8c23db3 | 3346 | |
3347 | while (abstract_origin) | |
3348 | { | |
3349 | location_t *locus; | |
3350 | tree block = abstract_origin; | |
3351 | ||
3352 | locus = &BLOCK_SOURCE_LOCATION (block); | |
3353 | fndecl = NULL; | |
3354 | block = BLOCK_SUPERCONTEXT (block); | |
3355 | while (block && TREE_CODE (block) == BLOCK | |
3356 | && BLOCK_ABSTRACT_ORIGIN (block)) | |
3357 | { | |
3358 | ao = BLOCK_ABSTRACT_ORIGIN (block); | |
3359 | ||
c89421d8 | 3360 | while (TREE_CODE (ao) == BLOCK |
3361 | && BLOCK_ABSTRACT_ORIGIN (ao) | |
3362 | && BLOCK_ABSTRACT_ORIGIN (ao) != ao) | |
b8c23db3 | 3363 | ao = BLOCK_ABSTRACT_ORIGIN (ao); |
3364 | ||
3365 | if (TREE_CODE (ao) == FUNCTION_DECL) | |
3366 | { | |
3367 | fndecl = ao; | |
3368 | break; | |
3369 | } | |
3370 | else if (TREE_CODE (ao) != BLOCK) | |
3371 | break; | |
3372 | ||
3373 | block = BLOCK_SUPERCONTEXT (block); | |
3374 | } | |
3375 | if (fndecl) | |
3376 | abstract_origin = block; | |
3377 | else | |
3378 | { | |
3379 | while (block && TREE_CODE (block) == BLOCK) | |
3380 | block = BLOCK_SUPERCONTEXT (block); | |
3381 | ||
abc9203d | 3382 | if (block && TREE_CODE (block) == FUNCTION_DECL) |
b8c23db3 | 3383 | fndecl = block; |
3384 | abstract_origin = NULL; | |
3385 | } | |
3386 | if (fndecl) | |
3387 | { | |
3388 | expanded_location s = expand_location (*locus); | |
a94db6b0 | 3389 | pp_character (context->printer, ','); |
3390 | pp_newline (context->printer); | |
b8c23db3 | 3391 | if (s.file != NULL) |
3392 | { | |
2c2efebb | 3393 | if (context->show_column && s.column != 0) |
b8c23db3 | 3394 | pp_printf (context->printer, |
41609f8b | 3395 | _(" inlined from %qs at %r%s:%d:%d%R"), |
a608187f | 3396 | cxx_printable_name_translate (fndecl, 2), |
41609f8b | 3397 | "locus", s.file, s.line, s.column); |
b8c23db3 | 3398 | else |
b8c23db3 | 3399 | pp_printf (context->printer, |
41609f8b | 3400 | _(" inlined from %qs at %r%s:%d%R"), |
a608187f | 3401 | cxx_printable_name_translate (fndecl, 2), |
41609f8b | 3402 | "locus", s.file, s.line); |
b8c23db3 | 3403 | |
3404 | } | |
3405 | else | |
1e00012f | 3406 | pp_printf (context->printer, _(" inlined from %qs"), |
a608187f | 3407 | cxx_printable_name_translate (fndecl, 2)); |
b8c23db3 | 3408 | } |
3409 | } | |
a94db6b0 | 3410 | pp_character (context->printer, ':'); |
b8c23db3 | 3411 | } |
a94db6b0 | 3412 | pp_newline (context->printer); |
25e2ffe1 | 3413 | |
b8c23db3 | 3414 | diagnostic_set_last_function (context, diagnostic); |
a94db6b0 | 3415 | pp_destroy_prefix (context->printer); |
aa6db498 | 3416 | context->printer->prefix = old_prefix; |
b97edf7e | 3417 | } |
3418 | } | |
3419 | ||
1e00012f | 3420 | /* Returns a description of FUNCTION using standard terminology. The |
3421 | result is a format string of the form "In CATEGORY %qs". */ | |
b97edf7e | 3422 | static const char * |
f01d4233 | 3423 | function_category (tree fn) |
b97edf7e | 3424 | { |
bfec3452 | 3425 | /* We can get called from the middle-end for diagnostics of function |
3426 | clones. Make sure we have language specific information before | |
3427 | dereferencing it. */ | |
3428 | if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn)) | |
3429 | && DECL_FUNCTION_MEMBER_P (fn)) | |
b97edf7e | 3430 | { |
3431 | if (DECL_STATIC_FUNCTION_P (fn)) | |
1e00012f | 3432 | return _("In static member function %qs"); |
b97edf7e | 3433 | else if (DECL_COPY_CONSTRUCTOR_P (fn)) |
1e00012f | 3434 | return _("In copy constructor %qs"); |
b97edf7e | 3435 | else if (DECL_CONSTRUCTOR_P (fn)) |
1e00012f | 3436 | return _("In constructor %qs"); |
b97edf7e | 3437 | else if (DECL_DESTRUCTOR_P (fn)) |
1e00012f | 3438 | return _("In destructor %qs"); |
a8b75081 | 3439 | else if (LAMBDA_FUNCTION_P (fn)) |
3440 | return _("In lambda function"); | |
b97edf7e | 3441 | else |
1e00012f | 3442 | return _("In member function %qs"); |
b97edf7e | 3443 | } |
3444 | else | |
1e00012f | 3445 | return _("In function %qs"); |
b97edf7e | 3446 | } |
3447 | ||
3448 | /* Report the full context of a current template instantiation, | |
3449 | onto BUFFER. */ | |
3450 | static void | |
f01d4233 | 3451 | print_instantiation_full_context (diagnostic_context *context) |
b97edf7e | 3452 | { |
c5dd8e06 | 3453 | struct tinst_level *p = current_instantiation (); |
6a86d77b | 3454 | location_t location = input_location; |
9031d10b | 3455 | |
b97edf7e | 3456 | if (p) |
3457 | { | |
5359d2eb | 3458 | pp_verbatim (context->printer, |
3459 | TREE_CODE (p->decl) == TREE_LIST | |
3460 | ? _("%s: In substitution of %qS:\n") | |
3461 | : _("%s: In instantiation of %q#D:\n"), | |
3462 | LOCATION_FILE (location), | |
3463 | p->decl); | |
3464 | ||
3465 | location = p->locus; | |
3466 | p = p->next; | |
b97edf7e | 3467 | } |
50cd3f45 | 3468 | |
f96e4fb1 | 3469 | print_instantiation_partial_context (context, p, location); |
b97edf7e | 3470 | } |
3471 | ||
24f8939e | 3472 | /* Helper function of print_instantiation_partial_context() that |
3473 | prints a single line of instantiation context. */ | |
3474 | ||
b97edf7e | 3475 | static void |
24f8939e | 3476 | print_instantiation_partial_context_line (diagnostic_context *context, |
fa494501 | 3477 | const struct tinst_level *t, |
3478 | location_t loc, bool recursive_p) | |
b97edf7e | 3479 | { |
fd9fde78 | 3480 | if (loc == UNKNOWN_LOCATION) |
3481 | return; | |
3482 | ||
3483 | expanded_location xloc = expand_location (loc); | |
24f8939e | 3484 | |
8ce59854 | 3485 | if (context->show_column) |
41609f8b | 3486 | pp_verbatim (context->printer, _("%r%s:%d:%d:%R "), |
3487 | "locus", xloc.file, xloc.line, xloc.column); | |
8ce59854 | 3488 | else |
41609f8b | 3489 | pp_verbatim (context->printer, _("%r%s:%d:%R "), |
3490 | "locus", xloc.file, xloc.line); | |
8ce59854 | 3491 | |
3492 | if (t != NULL) | |
fa494501 | 3493 | { |
8ce59854 | 3494 | if (TREE_CODE (t->decl) == TREE_LIST) |
fa494501 | 3495 | pp_verbatim (context->printer, |
3496 | recursive_p | |
8ce59854 | 3497 | ? _("recursively required by substitution of %qS\n") |
3498 | : _("required by substitution of %qS\n"), | |
3499 | t->decl); | |
fa494501 | 3500 | else |
3501 | pp_verbatim (context->printer, | |
3502 | recursive_p | |
8ce59854 | 3503 | ? _("recursively required from %q#D\n") |
3504 | : _("required from %q#D\n"), | |
3505 | t->decl); | |
fa494501 | 3506 | } |
3507 | else | |
3508 | { | |
8ce59854 | 3509 | pp_verbatim (context->printer, |
3510 | recursive_p | |
3752e5b1 | 3511 | ? _("recursively required from here\n") |
3512 | : _("required from here\n")); | |
fa494501 | 3513 | } |
24f8939e | 3514 | } |
3515 | ||
3516 | /* Same as print_instantiation_full_context but less verbose. */ | |
3517 | ||
3518 | static void | |
3519 | print_instantiation_partial_context (diagnostic_context *context, | |
3520 | struct tinst_level *t0, location_t loc) | |
3521 | { | |
3522 | struct tinst_level *t; | |
3523 | int n_total = 0; | |
3524 | int n; | |
fa494501 | 3525 | location_t prev_loc = loc; |
24f8939e | 3526 | |
3527 | for (t = t0; t != NULL; t = t->next) | |
fa494501 | 3528 | if (prev_loc != t->locus) |
3529 | { | |
3530 | prev_loc = t->locus; | |
3531 | n_total++; | |
3532 | } | |
24f8939e | 3533 | |
3534 | t = t0; | |
3535 | ||
249faa35 | 3536 | if (template_backtrace_limit |
3537 | && n_total > template_backtrace_limit) | |
b97edf7e | 3538 | { |
249faa35 | 3539 | int skip = n_total - template_backtrace_limit; |
3540 | int head = template_backtrace_limit / 2; | |
3541 | ||
3542 | /* Avoid skipping just 1. If so, skip 2. */ | |
3543 | if (skip == 1) | |
3544 | { | |
3545 | skip = 2; | |
3546 | head = (template_backtrace_limit - 1) / 2; | |
3547 | } | |
3548 | ||
3549 | for (n = 0; n < head; n++) | |
24f8939e | 3550 | { |
3551 | gcc_assert (t != NULL); | |
fa494501 | 3552 | if (loc != t->locus) |
3553 | print_instantiation_partial_context_line (context, t, loc, | |
3554 | /*recursive_p=*/false); | |
24f8939e | 3555 | loc = t->locus; |
3556 | t = t->next; | |
3557 | } | |
249faa35 | 3558 | if (t != NULL && skip > 0) |
24f8939e | 3559 | { |
3560 | expanded_location xloc; | |
3561 | xloc = expand_location (loc); | |
2c2efebb | 3562 | if (context->show_column) |
24f8939e | 3563 | pp_verbatim (context->printer, |
41609f8b | 3564 | _("%r%s:%d:%d:%R [ skipping %d instantiation " |
3565 | "contexts, use -ftemplate-backtrace-limit=0 to " | |
3566 | "disable ]\n"), | |
3567 | "locus", xloc.file, xloc.line, xloc.column, skip); | |
24f8939e | 3568 | else |
3569 | pp_verbatim (context->printer, | |
41609f8b | 3570 | _("%r%s:%d:%R [ skipping %d instantiation " |
3571 | "contexts, use -ftemplate-backtrace-limit=0 to " | |
3572 | "disable ]\n"), | |
3573 | "locus", xloc.file, xloc.line, skip); | |
24f8939e | 3574 | |
3575 | do { | |
fa494501 | 3576 | loc = t->locus; |
3577 | t = t->next; | |
3578 | } while (t != NULL && --skip > 0); | |
24f8939e | 3579 | } |
3580 | } | |
3581 | ||
fa494501 | 3582 | while (t != NULL) |
24f8939e | 3583 | { |
fa494501 | 3584 | while (t->next != NULL && t->locus == t->next->locus) |
3585 | { | |
3586 | loc = t->locus; | |
3587 | t = t->next; | |
3588 | } | |
3589 | print_instantiation_partial_context_line (context, t, loc, | |
3590 | t->locus == loc); | |
c5dd8e06 | 3591 | loc = t->locus; |
fa494501 | 3592 | t = t->next; |
b97edf7e | 3593 | } |
fa494501 | 3594 | print_instantiation_partial_context_line (context, NULL, loc, |
3595 | /*recursive_p=*/false); | |
b97edf7e | 3596 | } |
3597 | ||
3598 | /* Called from cp_thing to print the template context for an error. */ | |
3599 | static void | |
f01d4233 | 3600 | maybe_print_instantiation_context (diagnostic_context *context) |
b97edf7e | 3601 | { |
3602 | if (!problematic_instantiation_changed () || current_instantiation () == 0) | |
3603 | return; | |
3604 | ||
3605 | record_last_problematic_instantiation (); | |
25e2ffe1 | 3606 | print_instantiation_full_context (context); |
b97edf7e | 3607 | } |
326f388b | 3608 | \f |
0a32318d | 3609 | /* Report what constexpr call(s) we're trying to expand, if any. */ |
3610 | ||
3611 | void | |
3612 | maybe_print_constexpr_context (diagnostic_context *context) | |
3613 | { | |
f1f41a6c | 3614 | vec<tree> call_stack = cx_error_context (); |
0a32318d | 3615 | unsigned ix; |
3616 | tree t; | |
3617 | ||
f1f41a6c | 3618 | FOR_EACH_VEC_ELT (call_stack, ix, t) |
0a32318d | 3619 | { |
3620 | expanded_location xloc = expand_location (EXPR_LOCATION (t)); | |
3621 | const char *s = expr_as_string (t, 0); | |
3622 | if (context->show_column) | |
3623 | pp_verbatim (context->printer, | |
5967b28b | 3624 | _("%r%s:%d:%d:%R in %<constexpr%> expansion of %qs"), |
41609f8b | 3625 | "locus", xloc.file, xloc.line, xloc.column, s); |
0a32318d | 3626 | else |
3627 | pp_verbatim (context->printer, | |
5967b28b | 3628 | _("%r%s:%d:%R in %<constexpr%> expansion of %qs"), |
41609f8b | 3629 | "locus", xloc.file, xloc.line, s); |
a94db6b0 | 3630 | pp_newline (context->printer); |
0a32318d | 3631 | } |
3632 | } | |
3633 | \f | |
4d1eda3a | 3634 | |
3635 | /* Return true iff TYPE_A and TYPE_B are template types that are | |
3636 | meaningful to compare. */ | |
3637 | ||
3638 | static bool | |
3639 | comparable_template_types_p (tree type_a, tree type_b) | |
3640 | { | |
3641 | if (!CLASS_TYPE_P (type_a)) | |
3642 | return false; | |
3643 | if (!CLASS_TYPE_P (type_b)) | |
3644 | return false; | |
3645 | ||
3646 | tree tinfo_a = TYPE_TEMPLATE_INFO (type_a); | |
3647 | tree tinfo_b = TYPE_TEMPLATE_INFO (type_b); | |
3648 | if (!tinfo_a || !tinfo_b) | |
3649 | return false; | |
3650 | ||
3651 | return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b); | |
3652 | } | |
3653 | ||
3654 | /* Start a new line indented by SPC spaces on PP. */ | |
3655 | ||
3656 | static void | |
3657 | newline_and_indent (pretty_printer *pp, int spc) | |
3658 | { | |
3659 | pp_newline (pp); | |
3660 | for (int i = 0; i < spc; i++) | |
3661 | pp_space (pp); | |
3662 | } | |
3663 | ||
3664 | /* Generate a GC-allocated string for ARG, an expression or type. */ | |
3665 | ||
3666 | static const char * | |
3667 | arg_to_string (tree arg, bool verbose) | |
3668 | { | |
3669 | if (TYPE_P (arg)) | |
8e4391a5 | 3670 | return type_to_string (arg, verbose, true, NULL, false); |
4d1eda3a | 3671 | else |
3672 | return expr_to_string (arg); | |
3673 | } | |
3674 | ||
3675 | /* Subroutine to type_to_string_with_compare and | |
3676 | print_template_tree_comparison. | |
3677 | ||
3678 | Print a representation of ARG (an expression or type) to PP, | |
3679 | colorizing it as "type-diff" if PP->show_color. */ | |
3680 | ||
3681 | static void | |
3682 | print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose) | |
3683 | { | |
3684 | pp_printf (pp, "%r%s%R", | |
3685 | "type-diff", | |
3686 | (arg | |
3687 | ? arg_to_string (arg, verbose) | |
3688 | : G_("(no argument)"))); | |
3689 | } | |
3690 | ||
3691 | /* Recursively print template TYPE_A to PP, as compared to template TYPE_B. | |
3692 | ||
3693 | The types must satisfy comparable_template_types_p. | |
3694 | ||
3695 | If INDENT is 0, then this is equivalent to type_to_string (TYPE_A), but | |
3696 | potentially colorizing/eliding in comparison with TYPE_B. | |
3697 | ||
3698 | For example given types: | |
3699 | vector<map<int,double>> | |
3700 | and | |
3701 | vector<map<int,float>> | |
3702 | then the result on PP would be: | |
3703 | vector<map<[...],double>> | |
3704 | with type elision, and: | |
3705 | vector<map<int,double>> | |
3706 | without type elision. | |
3707 | ||
3708 | In both cases the parts of TYPE that differ from PEER will be colorized | |
3709 | if pp_show_color (pp) is true. In the above example, this would be | |
3710 | "double". | |
3711 | ||
3712 | If INDENT is non-zero, then the types are printed in a tree-like form | |
3713 | which shows both types. In the above example, the result on PP would be: | |
3714 | ||
3715 | vector< | |
3716 | map< | |
3717 | [...], | |
3718 | [double != float]>> | |
3719 | ||
3720 | and without type-elision would be: | |
3721 | ||
3722 | vector< | |
3723 | map< | |
3724 | int, | |
3725 | [double != float]>> | |
3726 | ||
3727 | As before, the differing parts of the types are colorized if | |
3728 | pp_show_color (pp) is true ("double" and "float" in this example). | |
3729 | ||
3730 | Template arguments in which both types are using the default arguments | |
3731 | are not printed; if at least one of the two types is using a non-default | |
3732 | argument, then that argument is printed (or both arguments for the | |
3733 | tree-like print format). */ | |
3734 | ||
3735 | static void | |
3736 | print_template_differences (pretty_printer *pp, tree type_a, tree type_b, | |
3737 | bool verbose, int indent) | |
3738 | { | |
3739 | if (indent) | |
3740 | newline_and_indent (pp, indent); | |
3741 | ||
3742 | tree tinfo_a = TYPE_TEMPLATE_INFO (type_a); | |
3743 | tree tinfo_b = TYPE_TEMPLATE_INFO (type_b); | |
3744 | ||
3745 | pp_printf (pp, "%s<", | |
3746 | IDENTIFIER_POINTER (DECL_NAME (TI_TEMPLATE (tinfo_a)))); | |
3747 | ||
3748 | tree args_a = TI_ARGS (tinfo_a); | |
3749 | tree args_b = TI_ARGS (tinfo_b); | |
3750 | gcc_assert (TREE_CODE (args_a) == TREE_VEC); | |
3751 | gcc_assert (TREE_CODE (args_b) == TREE_VEC); | |
3752 | int flags = 0; | |
3753 | int len_a = get_non_default_template_args_count (args_a, flags); | |
3754 | args_a = INNERMOST_TEMPLATE_ARGS (args_a); | |
3755 | int len_b = get_non_default_template_args_count (args_b, flags); | |
3756 | args_b = INNERMOST_TEMPLATE_ARGS (args_b); | |
3757 | /* Determine the maximum range of args for which non-default template args | |
3758 | were used; beyond this, only default args (if any) were used, and so | |
3759 | they will be equal from this point onwards. | |
3760 | One of the two peers might have used default arguments within this | |
3761 | range, but the other will be using non-default arguments, and so | |
3762 | it's more readable to print both within this range, to highlight | |
3763 | the differences. */ | |
3764 | int len_max = MAX (len_a, len_b); | |
3765 | gcc_assert (TREE_CODE (args_a) == TREE_VEC); | |
3766 | gcc_assert (TREE_CODE (args_b) == TREE_VEC); | |
3767 | for (int idx = 0; idx < len_max; idx++) | |
3768 | { | |
3769 | if (idx) | |
3770 | pp_character (pp, ','); | |
3771 | ||
3772 | tree arg_a = TREE_VEC_ELT (args_a, idx); | |
3773 | tree arg_b = TREE_VEC_ELT (args_b, idx); | |
3774 | if (arg_a == arg_b) | |
3775 | { | |
3776 | if (indent) | |
3777 | newline_and_indent (pp, indent + 2); | |
3778 | /* Can do elision here, printing "[...]". */ | |
3779 | if (flag_elide_type) | |
3780 | pp_string (pp, G_("[...]")); | |
3781 | else | |
3782 | pp_string (pp, arg_to_string (arg_a, verbose)); | |
3783 | } | |
3784 | else | |
3785 | { | |
3786 | int new_indent = indent ? indent + 2 : 0; | |
3787 | if (comparable_template_types_p (arg_a, arg_b)) | |
3788 | print_template_differences (pp, arg_a, arg_b, verbose, new_indent); | |
3789 | else | |
3790 | if (indent) | |
3791 | { | |
3792 | newline_and_indent (pp, indent + 2); | |
3793 | pp_character (pp, '['); | |
3794 | print_nonequal_arg (pp, arg_a, verbose); | |
3795 | pp_string (pp, " != "); | |
3796 | print_nonequal_arg (pp, arg_b, verbose); | |
3797 | pp_character (pp, ']'); | |
3798 | } | |
3799 | else | |
3800 | print_nonequal_arg (pp, arg_a, verbose); | |
3801 | } | |
3802 | } | |
3803 | pp_printf (pp, ">"); | |
3804 | } | |
3805 | ||
3806 | /* As type_to_string, but for a template, potentially colorizing/eliding | |
3807 | in comparison with PEER. | |
3808 | For example, if TYPE is map<int,double> and PEER is map<int,int>, | |
3809 | then the resulting string would be: | |
3810 | map<[...],double> | |
3811 | with type elision, and: | |
3812 | map<int,double> | |
3813 | without type elision. | |
3814 | ||
3815 | In both cases the parts of TYPE that differ from PEER will be colorized | |
3816 | if SHOW_COLOR is true. In the above example, this would be "double". | |
3817 | ||
3818 | Template arguments in which both types are using the default arguments | |
3819 | are not printed; if at least one of the two types is using a non-default | |
3820 | argument, then both arguments are printed. | |
3821 | ||
3822 | The resulting string is in a GC-allocated buffer. */ | |
3823 | ||
3824 | static const char * | |
3825 | type_to_string_with_compare (tree type, tree peer, bool verbose, | |
3826 | bool show_color) | |
3827 | { | |
3828 | pretty_printer inner_pp; | |
3829 | pretty_printer *pp = &inner_pp; | |
3830 | pp_show_color (pp) = show_color; | |
3831 | ||
3832 | print_template_differences (pp, type, peer, verbose, 0); | |
3833 | return pp_ggc_formatted_text (pp); | |
3834 | } | |
3835 | ||
3836 | /* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP, | |
3837 | indented by INDENT spaces. | |
3838 | ||
3839 | For example given types: | |
3840 | ||
3841 | vector<map<int,double>> | |
3842 | ||
3843 | and | |
3844 | ||
3845 | vector<map<double,float>> | |
3846 | ||
3847 | the output with type elision would be: | |
3848 | ||
3849 | vector< | |
3850 | map< | |
3851 | [...], | |
3852 | [double != float]>> | |
3853 | ||
3854 | and without type-elision would be: | |
3855 | ||
3856 | vector< | |
3857 | map< | |
3858 | int, | |
3859 | [double != float]>> | |
3860 | ||
3861 | TYPE_A and TYPE_B must both be comparable template types | |
3862 | (as per comparable_template_types_p). | |
3863 | ||
3864 | Template arguments in which both types are using the default arguments | |
3865 | are not printed; if at least one of the two types is using a non-default | |
3866 | argument, then both arguments are printed. */ | |
3867 | ||
3868 | static void | |
3869 | print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b, | |
3870 | bool verbose, int indent) | |
3871 | { | |
3872 | print_template_differences (pp, type_a, type_b, verbose, indent); | |
3873 | } | |
3874 | ||
3875 | /* Subroutine for use in a format_postprocessor::handle | |
3876 | implementation. Adds a chunk to the end of | |
3877 | formatted output, so that it will be printed | |
3878 | by pp_output_formatted_text. */ | |
3879 | ||
3880 | static void | |
3881 | append_formatted_chunk (pretty_printer *pp, const char *content) | |
3882 | { | |
3883 | output_buffer *buffer = pp_buffer (pp); | |
3884 | struct chunk_info *chunk_array = buffer->cur_chunk_array; | |
3885 | const char **args = chunk_array->args; | |
3886 | ||
3887 | unsigned int chunk_idx; | |
3888 | for (chunk_idx = 0; args[chunk_idx]; chunk_idx++) | |
3889 | ; | |
3890 | args[chunk_idx++] = content; | |
3891 | args[chunk_idx] = NULL; | |
3892 | } | |
3893 | ||
3894 | /* Create a copy of CONTENT, with quotes added, and, | |
3895 | potentially, with colorization. | |
3896 | No escaped is performed on CONTENT. | |
3897 | The result is in a GC-allocated buffer. */ | |
3898 | ||
3899 | static const char * | |
3900 | add_quotes (const char *content, bool show_color) | |
3901 | { | |
3902 | pretty_printer tmp_pp; | |
3903 | pp_show_color (&tmp_pp) = show_color; | |
3904 | ||
3905 | /* We have to use "%<%s%>" rather than "%qs" here in order to avoid | |
3906 | quoting colorization bytes within the results. */ | |
3907 | pp_printf (&tmp_pp, "%<%s%>", content); | |
3908 | ||
3909 | return pp_ggc_formatted_text (&tmp_pp); | |
3910 | } | |
3911 | ||
3912 | /* If we had %H and %I, and hence deferred printing them, | |
3913 | print them now, storing the result into the chunk_info | |
3914 | for pp_format. Quote them if 'q' was provided. | |
3915 | Also print the difference in tree form, adding it as | |
3916 | an additional chunk. */ | |
3917 | ||
3918 | void | |
3919 | cxx_format_postprocessor::handle (pretty_printer *pp) | |
3920 | { | |
3921 | /* If we have one of %H and %I, the other should have | |
3922 | been present. */ | |
3923 | if (m_type_a.m_tree || m_type_b.m_tree) | |
3924 | { | |
3925 | /* Avoid reentrancy issues by working with a copy of | |
3926 | m_type_a and m_type_b, resetting them now. */ | |
3927 | deferred_printed_type type_a = m_type_a; | |
3928 | deferred_printed_type type_b = m_type_b; | |
3929 | m_type_a = deferred_printed_type (); | |
3930 | m_type_b = deferred_printed_type (); | |
3931 | ||
3932 | gcc_assert (type_a.m_buffer_ptr); | |
3933 | gcc_assert (type_b.m_buffer_ptr); | |
3934 | ||
3935 | bool show_color = pp_show_color (pp); | |
3936 | ||
3937 | const char *type_a_text; | |
3938 | const char *type_b_text; | |
3939 | ||
3940 | if (comparable_template_types_p (type_a.m_tree, type_b.m_tree)) | |
3941 | { | |
3942 | type_a_text | |
3943 | = type_to_string_with_compare (type_a.m_tree, type_b.m_tree, | |
3944 | type_a.m_verbose, show_color); | |
3945 | type_b_text | |
3946 | = type_to_string_with_compare (type_b.m_tree, type_a.m_tree, | |
3947 | type_b.m_verbose, show_color); | |
3948 | ||
3949 | if (flag_diagnostics_show_template_tree) | |
3950 | { | |
3951 | pretty_printer inner_pp; | |
3952 | pp_show_color (&inner_pp) = pp_show_color (pp); | |
3953 | print_template_tree_comparison | |
3954 | (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2); | |
3955 | append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp)); | |
3956 | } | |
3957 | } | |
3958 | else | |
3959 | { | |
8e4391a5 | 3960 | /* If the types were not comparable (or if only one of %H/%I was |
3961 | provided), they are printed normally, and no difference tree | |
3962 | is printed. */ | |
3963 | type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose, | |
3964 | true, &type_a.m_quote, show_color); | |
3965 | type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose, | |
3966 | true, &type_b.m_quote, show_color); | |
4d1eda3a | 3967 | } |
3968 | ||
3969 | if (type_a.m_quote) | |
3970 | type_a_text = add_quotes (type_a_text, show_color); | |
3971 | *type_a.m_buffer_ptr = type_a_text; | |
3972 | ||
3973 | if (type_b.m_quote) | |
3974 | type_b_text = add_quotes (type_b_text, show_color); | |
3975 | *type_b.m_buffer_ptr = type_b_text; | |
3976 | } | |
3977 | } | |
3978 | ||
3979 | /* Subroutine for handling %H and %I, to support i18n of messages like: | |
3980 | ||
3981 | error_at (loc, "could not convert %qE from %qH to %qI", | |
3982 | expr, type_a, type_b); | |
3983 | ||
3984 | so that we can print things like: | |
3985 | ||
3986 | could not convert 'foo' from 'map<int,double>' to 'map<int,int>' | |
3987 | ||
3988 | and, with type-elision: | |
3989 | ||
3990 | could not convert 'foo' from 'map<[...],double>' to 'map<[...],int>' | |
3991 | ||
3992 | (with color-coding of the differences between the types). | |
3993 | ||
3994 | The %H and %I format codes are peers: both must be present, | |
3995 | and they affect each other. Hence to handle them, we must | |
3996 | delay printing until we have both, deferring the printing to | |
3997 | pretty_printer's m_format_postprocessor hook. | |
3998 | ||
3999 | This is called in phase 2 of pp_format, when it is accumulating | |
4000 | a series of formatted chunks. We stash the location of the chunk | |
4001 | we're meant to have written to, so that we can write to it in the | |
4002 | m_format_postprocessor hook. | |
4003 | ||
4004 | We also need to stash whether a 'q' prefix was provided (the QUOTE | |
4005 | param) so that we can add the quotes when writing out the delayed | |
4006 | chunk. */ | |
4007 | ||
4008 | static void | |
4009 | defer_phase_2_of_type_diff (deferred_printed_type *deferred, | |
4010 | tree type, const char **buffer_ptr, | |
4011 | bool verbose, bool quote) | |
4012 | { | |
4013 | gcc_assert (deferred->m_tree == NULL_TREE); | |
4014 | gcc_assert (deferred->m_buffer_ptr == NULL); | |
4015 | *deferred = deferred_printed_type (type, buffer_ptr, verbose, quote); | |
4016 | } | |
4017 | ||
4018 | ||
326f388b | 4019 | /* Called from output_format -- during diagnostic message processing -- |
4020 | to handle C++ specific format specifier with the following meanings: | |
4021 | %A function argument-list. | |
5124a2c8 | 4022 | %C tree code. |
326f388b | 4023 | %D declaration. |
4024 | %E expression. | |
4025 | %F function declaration. | |
5124a2c8 | 4026 | %L language as used in extern "lang". |
4027 | %O binary operator. | |
326f388b | 4028 | %P function parameter whose position is indicated by an integer. |
5124a2c8 | 4029 | %Q assignment operator. |
546a04b1 | 4030 | %S substitution (template + args) |
326f388b | 4031 | %T type. |
546a04b1 | 4032 | %V cv-qualifier. |
4d1eda3a | 4033 | %X exception-specification. |
4034 | %H type difference (from) | |
4035 | %I type difference (to). */ | |
25e2ffe1 | 4036 | static bool |
c907c5b1 | 4037 | cp_printer (pretty_printer *pp, text_info *text, const char *spec, |
4d1eda3a | 4038 | int precision, bool wide, bool set_locus, bool verbose, |
8e4391a5 | 4039 | bool *quoted, const char **buffer_ptr) |
326f388b | 4040 | { |
4d1eda3a | 4041 | gcc_assert (pp->m_format_postprocessor); |
4042 | cxx_format_postprocessor *postprocessor | |
4043 | = static_cast <cxx_format_postprocessor *> (pp->m_format_postprocessor); | |
4044 | ||
5124a2c8 | 4045 | const char *result; |
c907c5b1 | 4046 | tree t = NULL; |
4047 | #define next_tree (t = va_arg (*text->args_ptr, tree)) | |
d62e827b | 4048 | #define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int)) |
4049 | #define next_lang ((enum languages) va_arg (*text->args_ptr, int)) | |
25e2ffe1 | 4050 | #define next_int va_arg (*text->args_ptr, int) |
4051 | ||
c907c5b1 | 4052 | if (precision != 0 || wide) |
4053 | return false; | |
4054 | ||
c907c5b1 | 4055 | switch (*spec) |
4b63bfb9 | 4056 | { |
5124a2c8 | 4057 | case 'A': result = args_to_string (next_tree, verbose); break; |
653e5405 | 4058 | case 'C': result = code_to_string (next_tcode); break; |
2947608c | 4059 | case 'D': |
4060 | { | |
4061 | tree temp = next_tree; | |
80a58eb0 | 4062 | if (VAR_P (temp) |
8e966116 | 4063 | && DECL_HAS_DEBUG_EXPR_P (temp)) |
2947608c | 4064 | { |
4065 | temp = DECL_DEBUG_EXPR (temp); | |
4066 | if (!DECL_P (temp)) | |
4067 | { | |
4068 | result = expr_to_string (temp); | |
4069 | break; | |
4070 | } | |
4071 | } | |
4072 | result = decl_to_string (temp, verbose); | |
4073 | } | |
4074 | break; | |
653e5405 | 4075 | case 'E': result = expr_to_string (next_tree); break; |
5124a2c8 | 4076 | case 'F': result = fndecl_to_string (next_tree, verbose); break; |
653e5405 | 4077 | case 'L': result = language_to_string (next_lang); break; |
ca16a224 | 4078 | case 'O': result = op_to_string (false, next_tcode); break; |
653e5405 | 4079 | case 'P': result = parm_to_string (next_int); break; |
ca16a224 | 4080 | case 'Q': result = op_to_string (true, next_tcode); break; |
8ce59854 | 4081 | case 'S': result = subst_to_string (next_tree); break; |
8e4391a5 | 4082 | case 'T': |
4083 | { | |
4084 | result = type_to_string (next_tree, verbose, false, quoted, | |
4085 | pp_show_color (pp)); | |
4086 | } | |
4087 | break; | |
5124a2c8 | 4088 | case 'V': result = cv_to_string (next_tree, verbose); break; |
546a04b1 | 4089 | case 'X': result = eh_spec_to_string (next_tree, verbose); break; |
9031d10b | 4090 | |
c8616982 | 4091 | case 'G': |
4092 | percent_G_format (text); | |
4093 | return true; | |
4094 | ||
ce084dfc | 4095 | case 'K': |
c8616982 | 4096 | t = va_arg (*text->args_ptr, tree); |
4097 | percent_K_format (text, t); | |
ce084dfc | 4098 | return true; |
4099 | ||
4d1eda3a | 4100 | case 'H': |
4101 | { | |
4102 | defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree, | |
8e4391a5 | 4103 | buffer_ptr, verbose, *quoted); |
4d1eda3a | 4104 | return true; |
4105 | } | |
4106 | ||
4107 | case 'I': | |
4108 | { | |
4109 | defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree, | |
8e4391a5 | 4110 | buffer_ptr, verbose, *quoted); |
4d1eda3a | 4111 | return true; |
4112 | } | |
4113 | ||
4b63bfb9 | 4114 | default: |
25e2ffe1 | 4115 | return false; |
326f388b | 4116 | } |
50cd3f45 | 4117 | |
a94db6b0 | 4118 | pp_string (pp, result); |
c907c5b1 | 4119 | if (set_locus && t != NULL) |
f0479000 | 4120 | text->set_location (0, location_of (t), true); |
25e2ffe1 | 4121 | return true; |
5124a2c8 | 4122 | #undef next_tree |
4123 | #undef next_tcode | |
4124 | #undef next_lang | |
4125 | #undef next_int | |
326f388b | 4126 | } |
eb0d20b7 | 4127 | \f |
f82f1250 | 4128 | /* Warn about the use of C++0x features when appropriate. */ |
d95d815d | 4129 | void |
bf8d19fe | 4130 | maybe_warn_cpp0x (cpp0x_warn_str str) |
d95d815d | 4131 | { |
3df42822 | 4132 | if ((cxx_dialect == cxx98) && !in_system_header_at (input_location)) |
1034b0d6 | 4133 | /* We really want to suppress this warning in system headers, |
d95d815d | 4134 | because libstdc++ uses variadic templates even when we aren't |
4135 | in C++0x mode. */ | |
bf8d19fe | 4136 | switch (str) |
4137 | { | |
4138 | case CPP0X_INITIALIZER_LISTS: | |
4139 | pedwarn (input_location, 0, | |
4140 | "extended initializer lists " | |
0d84dc2d | 4141 | "only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4142 | break; |
4143 | case CPP0X_EXPLICIT_CONVERSION: | |
4144 | pedwarn (input_location, 0, | |
4145 | "explicit conversion operators " | |
0d84dc2d | 4146 | "only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4147 | break; |
4148 | case CPP0X_VARIADIC_TEMPLATES: | |
4149 | pedwarn (input_location, 0, | |
4150 | "variadic templates " | |
0d84dc2d | 4151 | "only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4152 | break; |
4153 | case CPP0X_LAMBDA_EXPR: | |
4154 | pedwarn (input_location, 0, | |
4155 | "lambda expressions " | |
0d84dc2d | 4156 | "only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4157 | break; |
4158 | case CPP0X_AUTO: | |
4159 | pedwarn (input_location, 0, | |
7821c8c8 | 4160 | "C++11 auto only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4161 | break; |
4162 | case CPP0X_SCOPED_ENUMS: | |
4163 | pedwarn (input_location, 0, | |
0d84dc2d | 4164 | "scoped enums only available with -std=c++11 or -std=gnu++11"); |
bf8d19fe | 4165 | break; |
4166 | case CPP0X_DEFAULTED_DELETED: | |
4167 | pedwarn (input_location, 0, | |
4168 | "defaulted and deleted functions " | |
0d84dc2d | 4169 | "only available with -std=c++11 or -std=gnu++11"); |
af28195d | 4170 | break; |
4171 | case CPP0X_INLINE_NAMESPACES: | |
29438999 | 4172 | pedwarn (input_location, OPT_Wpedantic, |
af28195d | 4173 | "inline namespaces " |
0d84dc2d | 4174 | "only available with -std=c++11 or -std=gnu++11"); |
244db24d | 4175 | break; |
dcdaa0e3 | 4176 | case CPP0X_OVERRIDE_CONTROLS: |
4177 | pedwarn (input_location, 0, | |
4178 | "override controls (override/final) " | |
0d84dc2d | 4179 | "only available with -std=c++11 or -std=gnu++11"); |
dcdaa0e3 | 4180 | break; |
d9c249a4 | 4181 | case CPP0X_NSDMI: |
4182 | pedwarn (input_location, 0, | |
4183 | "non-static data member initializers " | |
0d84dc2d | 4184 | "only available with -std=c++11 or -std=gnu++11"); |
d9c249a4 | 4185 | break; |
244db24d | 4186 | case CPP0X_USER_DEFINED_LITERALS: |
4187 | pedwarn (input_location, 0, | |
4188 | "user-defined literals " | |
0d84dc2d | 4189 | "only available with -std=c++11 or -std=gnu++11"); |
244db24d | 4190 | break; |
90510c63 | 4191 | case CPP0X_DELEGATING_CTORS: |
4192 | pedwarn (input_location, 0, | |
4193 | "delegating constructors " | |
4194 | "only available with -std=c++11 or -std=gnu++11"); | |
fa6e8832 | 4195 | break; |
4196 | case CPP0X_INHERITING_CTORS: | |
4197 | pedwarn (input_location, 0, | |
4198 | "inheriting constructors " | |
4199 | "only available with -std=c++11 or -std=gnu++11"); | |
90510c63 | 4200 | break; |
ffcdbf9c | 4201 | case CPP0X_ATTRIBUTES: |
4202 | pedwarn (input_location, 0, | |
4203 | "c++11 attributes " | |
4204 | "only available with -std=c++11 or -std=gnu++11"); | |
4205 | break; | |
e116411c | 4206 | case CPP0X_REF_QUALIFIER: |
4207 | pedwarn (input_location, 0, | |
4208 | "ref-qualifiers " | |
7821c8c8 | 4209 | "only available with -std=c++11 or -std=gnu++11"); |
e116411c | 4210 | break; |
bf8d19fe | 4211 | default: |
244db24d | 4212 | gcc_unreachable (); |
bf8d19fe | 4213 | } |
f82f1250 | 4214 | } |
4215 | ||
4216 | /* Warn about the use of variadic templates when appropriate. */ | |
4217 | void | |
4218 | maybe_warn_variadic_templates (void) | |
4219 | { | |
bf8d19fe | 4220 | maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES); |
d95d815d | 4221 | } |
9ab71c6b | 4222 | |
4223 | ||
4224 | /* Issue an ISO C++98 pedantic warning at LOCATION, conditional on | |
4225 | option OPT with text GMSGID. Use this function to report | |
4226 | diagnostics for constructs that are invalid C++98, but valid | |
4227 | C++0x. */ | |
4228 | bool | |
4229 | pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) | |
4230 | { | |
4231 | diagnostic_info diagnostic; | |
4232 | va_list ap; | |
b666516d | 4233 | bool ret; |
a96cefb2 | 4234 | rich_location richloc (line_table, location); |
9ab71c6b | 4235 | |
4236 | va_start (ap, gmsgid); | |
f0479000 | 4237 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, |
9ab71c6b | 4238 | (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING); |
4239 | diagnostic.option_index = opt; | |
56b8400f | 4240 | ret = diagnostic_report_diagnostic (global_dc, &diagnostic); |
9ab71c6b | 4241 | va_end (ap); |
b666516d | 4242 | return ret; |
9ab71c6b | 4243 | } |
d3c44c27 | 4244 | |
4245 | /* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what | |
4246 | we found when we tried to do the lookup. LOCATION is the location of | |
4247 | the NAME identifier. */ | |
4248 | ||
4249 | void | |
4250 | qualified_name_lookup_error (tree scope, tree name, | |
4251 | tree decl, location_t location) | |
4252 | { | |
4253 | if (scope == error_mark_node) | |
4254 | ; /* We already complained. */ | |
4255 | else if (TYPE_P (scope)) | |
4256 | { | |
4257 | if (!COMPLETE_TYPE_P (scope)) | |
4258 | error_at (location, "incomplete type %qT used in nested name specifier", | |
4259 | scope); | |
4260 | else if (TREE_CODE (decl) == TREE_LIST) | |
4261 | { | |
4262 | error_at (location, "reference to %<%T::%D%> is ambiguous", | |
4263 | scope, name); | |
4264 | print_candidates (decl); | |
4265 | } | |
4266 | else | |
4267 | error_at (location, "%qD is not a member of %qT", name, scope); | |
4268 | } | |
4269 | else if (scope != global_namespace) | |
4270 | { | |
4271 | error_at (location, "%qD is not a member of %qD", name, scope); | |
f778e503 | 4272 | if (!suggest_alternative_in_explicit_scope (location, name, scope)) |
4273 | suggest_alternatives_for (location, name, false); | |
d3c44c27 | 4274 | } |
4275 | else | |
4276 | { | |
4277 | error_at (location, "%<::%D%> has not been declared", name); | |
f778e503 | 4278 | suggest_alternatives_for (location, name, true); |
d3c44c27 | 4279 | } |
4280 | } |