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