138fd1498Szrj /* Call-backs for C++ error reporting.
238fd1498Szrj This code is non-reentrant.
338fd1498Szrj Copyright (C) 1993-2018 Free Software Foundation, Inc.
438fd1498Szrj This file is part of GCC.
538fd1498Szrj
638fd1498Szrj GCC is free software; you can redistribute it and/or modify
738fd1498Szrj it under the terms of the GNU General Public License as published by
838fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj any later version.
1038fd1498Szrj
1138fd1498Szrj GCC is distributed in the hope that it will be useful,
1238fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1438fd1498Szrj GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj You should have received a copy of the GNU General Public License
1738fd1498Szrj along with GCC; see the file COPYING3. If not see
1838fd1498Szrj <http://www.gnu.org/licenses/>. */
1938fd1498Szrj
2038fd1498Szrj #include "config.h"
2138fd1498Szrj #include "system.h"
2238fd1498Szrj #include "coretypes.h"
2338fd1498Szrj #include "cp-tree.h"
2438fd1498Szrj #include "stringpool.h"
2538fd1498Szrj #include "tree-diagnostic.h"
2638fd1498Szrj #include "langhooks-def.h"
2738fd1498Szrj #include "intl.h"
2838fd1498Szrj #include "cxx-pretty-print.h"
2938fd1498Szrj #include "tree-pretty-print.h"
3038fd1498Szrj #include "gimple-pretty-print.h"
3138fd1498Szrj #include "c-family/c-objc.h"
3238fd1498Szrj #include "ubsan.h"
3338fd1498Szrj #include "internal-fn.h"
3438fd1498Szrj
3538fd1498Szrj #define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
3638fd1498Szrj #define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';')
3738fd1498Szrj
3838fd1498Szrj /* cxx_pp is a C++ front-end-specific pretty printer: this is where we
3938fd1498Szrj dump C++ ASTs as strings. It is mostly used only by the various
4038fd1498Szrj tree -> string functions that are occasionally called from the
4138fd1498Szrj debugger or by the front-end for things like
4238fd1498Szrj __PRETTY_FUNCTION__. */
4338fd1498Szrj static cxx_pretty_printer actual_pretty_printer;
4438fd1498Szrj static cxx_pretty_printer * const cxx_pp = &actual_pretty_printer;
4538fd1498Szrj
4638fd1498Szrj /* Translate if being used for diagnostics, but not for dump files or
4738fd1498Szrj __PRETTY_FUNCTION. */
4838fd1498Szrj #define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid))
4938fd1498Szrj
5038fd1498Szrj # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
5138fd1498Szrj
5238fd1498Szrj static const char *args_to_string (tree, int);
5338fd1498Szrj static const char *code_to_string (enum tree_code);
5438fd1498Szrj static const char *cv_to_string (tree, int);
5538fd1498Szrj static const char *decl_to_string (tree, int);
5638fd1498Szrj static const char *expr_to_string (tree);
5738fd1498Szrj static const char *fndecl_to_string (tree, int);
5838fd1498Szrj static const char *op_to_string (bool, enum tree_code);
5938fd1498Szrj static const char *parm_to_string (int);
6038fd1498Szrj static const char *type_to_string (tree, int, bool, bool *, bool);
6138fd1498Szrj
6238fd1498Szrj static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
6338fd1498Szrj static void dump_type (cxx_pretty_printer *, tree, int);
6438fd1498Szrj static void dump_typename (cxx_pretty_printer *, tree, int);
6538fd1498Szrj static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int);
6638fd1498Szrj static void dump_decl (cxx_pretty_printer *, tree, int);
6738fd1498Szrj static void dump_template_decl (cxx_pretty_printer *, tree, int);
6838fd1498Szrj static void dump_function_decl (cxx_pretty_printer *, tree, int);
6938fd1498Szrj static void dump_expr (cxx_pretty_printer *, tree, int);
7038fd1498Szrj static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int);
7138fd1498Szrj static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int);
7238fd1498Szrj static void dump_aggr_type (cxx_pretty_printer *, tree, int);
7338fd1498Szrj static void dump_type_prefix (cxx_pretty_printer *, tree, int);
7438fd1498Szrj static void dump_type_suffix (cxx_pretty_printer *, tree, int);
7538fd1498Szrj static void dump_function_name (cxx_pretty_printer *, tree, int);
7638fd1498Szrj static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool);
7738fd1498Szrj static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool);
7838fd1498Szrj static void dump_expr_list (cxx_pretty_printer *, tree, int);
7938fd1498Szrj static void dump_global_iord (cxx_pretty_printer *, tree);
8038fd1498Szrj static void dump_parameters (cxx_pretty_printer *, tree, int);
8138fd1498Szrj static void dump_ref_qualifier (cxx_pretty_printer *, tree, int);
8238fd1498Szrj static void dump_exception_spec (cxx_pretty_printer *, tree, int);
8338fd1498Szrj static void dump_template_argument (cxx_pretty_printer *, tree, int);
8438fd1498Szrj static void dump_template_argument_list (cxx_pretty_printer *, tree, int);
8538fd1498Szrj static void dump_template_parameter (cxx_pretty_printer *, tree, int);
8638fd1498Szrj static void dump_template_bindings (cxx_pretty_printer *, tree, tree,
8738fd1498Szrj vec<tree, va_gc> *);
8838fd1498Szrj static void dump_scope (cxx_pretty_printer *, tree, int);
8938fd1498Szrj static void dump_template_parms (cxx_pretty_printer *, tree, int, int);
9038fd1498Szrj static int get_non_default_template_args_count (tree, int);
9138fd1498Szrj static const char *function_category (tree);
9238fd1498Szrj static void maybe_print_constexpr_context (diagnostic_context *);
9338fd1498Szrj static void maybe_print_instantiation_context (diagnostic_context *);
9438fd1498Szrj static void print_instantiation_full_context (diagnostic_context *);
9538fd1498Szrj static void print_instantiation_partial_context (diagnostic_context *,
9638fd1498Szrj struct tinst_level *,
9738fd1498Szrj location_t);
9838fd1498Szrj static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
9938fd1498Szrj static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
10038fd1498Szrj
10138fd1498Szrj static bool cp_printer (pretty_printer *, text_info *, const char *,
10238fd1498Szrj int, bool, bool, bool, bool *, const char **);
10338fd1498Szrj
10438fd1498Szrj /* Struct for handling %H or %I, which require delaying printing the
10538fd1498Szrj type until a postprocessing stage. */
10638fd1498Szrj
10738fd1498Szrj struct deferred_printed_type
10838fd1498Szrj {
deferred_printed_typedeferred_printed_type10938fd1498Szrj deferred_printed_type ()
11038fd1498Szrj : m_tree (NULL_TREE), m_buffer_ptr (NULL), m_verbose (false), m_quote (false)
11138fd1498Szrj {}
11238fd1498Szrj
deferred_printed_typedeferred_printed_type11338fd1498Szrj deferred_printed_type (tree type, const char **buffer_ptr, bool verbose,
11438fd1498Szrj bool quote)
11538fd1498Szrj : m_tree (type), m_buffer_ptr (buffer_ptr), m_verbose (verbose),
11638fd1498Szrj m_quote (quote)
11738fd1498Szrj {
11838fd1498Szrj gcc_assert (type);
11938fd1498Szrj gcc_assert (buffer_ptr);
12038fd1498Szrj }
12138fd1498Szrj
12238fd1498Szrj /* The tree is not GTY-marked: they are only non-NULL within a
12338fd1498Szrj call to pp_format. */
12438fd1498Szrj tree m_tree;
12538fd1498Szrj const char **m_buffer_ptr;
12638fd1498Szrj bool m_verbose;
12738fd1498Szrj bool m_quote;
12838fd1498Szrj };
12938fd1498Szrj
13038fd1498Szrj /* Subclass of format_postprocessor for the C++ frontend.
13138fd1498Szrj This handles the %H and %I formatting codes, printing them
13238fd1498Szrj in a postprocessing phase (since they affect each other). */
13338fd1498Szrj
13438fd1498Szrj class cxx_format_postprocessor : public format_postprocessor
13538fd1498Szrj {
13638fd1498Szrj public:
cxx_format_postprocessor()13738fd1498Szrj cxx_format_postprocessor ()
13838fd1498Szrj : m_type_a (), m_type_b ()
13938fd1498Szrj {}
14038fd1498Szrj
14138fd1498Szrj void handle (pretty_printer *pp) FINAL OVERRIDE;
14238fd1498Szrj
14338fd1498Szrj deferred_printed_type m_type_a;
14438fd1498Szrj deferred_printed_type m_type_b;
14538fd1498Szrj };
14638fd1498Szrj
14738fd1498Szrj /* CONTEXT->printer is a basic pretty printer that was constructed
14838fd1498Szrj presumably by diagnostic_initialize(), called early in the
14938fd1498Szrj compiler's initialization process (in general_init) Before the FE
15038fd1498Szrj is initialized. This (C++) FE-specific diagnostic initializer is
15138fd1498Szrj thus replacing the basic pretty printer with one that has C++-aware
15238fd1498Szrj capacities. */
15338fd1498Szrj
15438fd1498Szrj void
cxx_initialize_diagnostics(diagnostic_context * context)15538fd1498Szrj cxx_initialize_diagnostics (diagnostic_context *context)
15638fd1498Szrj {
15738fd1498Szrj pretty_printer *base = context->printer;
15838fd1498Szrj cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
15938fd1498Szrj context->printer = new (pp) cxx_pretty_printer ();
16038fd1498Szrj
16138fd1498Szrj /* It is safe to free this object because it was previously XNEW()'d. */
16238fd1498Szrj base->~pretty_printer ();
16338fd1498Szrj XDELETE (base);
16438fd1498Szrj
16538fd1498Szrj c_common_diagnostics_set_defaults (context);
16638fd1498Szrj diagnostic_starter (context) = cp_diagnostic_starter;
16738fd1498Szrj /* diagnostic_finalizer is already c_diagnostic_finalizer. */
16838fd1498Szrj diagnostic_format_decoder (context) = cp_printer;
16938fd1498Szrj pp->m_format_postprocessor = new cxx_format_postprocessor ();
17038fd1498Szrj }
17138fd1498Szrj
17238fd1498Szrj /* Dump a scope, if deemed necessary. */
17338fd1498Szrj
17438fd1498Szrj static void
dump_scope(cxx_pretty_printer * pp,tree scope,int flags)17538fd1498Szrj dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
17638fd1498Szrj {
17738fd1498Szrj int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
17838fd1498Szrj
17938fd1498Szrj if (scope == NULL_TREE)
18038fd1498Szrj return;
18138fd1498Szrj
18238fd1498Szrj if (TREE_CODE (scope) == NAMESPACE_DECL)
18338fd1498Szrj {
18438fd1498Szrj if (scope != global_namespace)
18538fd1498Szrj {
18638fd1498Szrj dump_decl (pp, scope, f);
18738fd1498Szrj pp_cxx_colon_colon (pp);
18838fd1498Szrj }
18938fd1498Szrj }
19038fd1498Szrj else if (AGGREGATE_TYPE_P (scope))
19138fd1498Szrj {
19238fd1498Szrj dump_type (pp, scope, f);
19338fd1498Szrj pp_cxx_colon_colon (pp);
19438fd1498Szrj }
19538fd1498Szrj else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
19638fd1498Szrj {
19738fd1498Szrj dump_function_decl (pp, scope, f);
19838fd1498Szrj pp_cxx_colon_colon (pp);
19938fd1498Szrj }
20038fd1498Szrj }
20138fd1498Szrj
20238fd1498Szrj /* Dump the template ARGument under control of FLAGS. */
20338fd1498Szrj
20438fd1498Szrj static void
dump_template_argument(cxx_pretty_printer * pp,tree arg,int flags)20538fd1498Szrj dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags)
20638fd1498Szrj {
20738fd1498Szrj if (ARGUMENT_PACK_P (arg))
20838fd1498Szrj dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg),
20938fd1498Szrj /* No default args in argument packs. */
21038fd1498Szrj flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
21138fd1498Szrj else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
21238fd1498Szrj dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
21338fd1498Szrj else
21438fd1498Szrj {
21538fd1498Szrj if (TREE_CODE (arg) == TREE_LIST)
21638fd1498Szrj arg = TREE_VALUE (arg);
21738fd1498Szrj
21838fd1498Szrj /* Strip implicit conversions. */
21938fd1498Szrj while (CONVERT_EXPR_P (arg))
22038fd1498Szrj arg = TREE_OPERAND (arg, 0);
22138fd1498Szrj
22238fd1498Szrj dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
22338fd1498Szrj }
22438fd1498Szrj }
22538fd1498Szrj
22638fd1498Szrj /* Count the number of template arguments ARGS whose value does not
22738fd1498Szrj match the (optional) default template parameter in PARAMS */
22838fd1498Szrj
22938fd1498Szrj static int
get_non_default_template_args_count(tree args,int flags)23038fd1498Szrj get_non_default_template_args_count (tree args, int flags)
23138fd1498Szrj {
23238fd1498Szrj int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
23338fd1498Szrj
23438fd1498Szrj if (/* We use this flag when generating debug information. We don't
23538fd1498Szrj want to expand templates at this point, for this may generate
23638fd1498Szrj new decls, which gets decl counts out of sync, which may in
23738fd1498Szrj turn cause codegen differences between compilations with and
23838fd1498Szrj without -g. */
23938fd1498Szrj (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0
24038fd1498Szrj || !flag_pretty_templates)
24138fd1498Szrj return n;
24238fd1498Szrj
24338fd1498Szrj return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args));
24438fd1498Szrj }
24538fd1498Szrj
24638fd1498Szrj /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
24738fd1498Szrj of FLAGS. */
24838fd1498Szrj
24938fd1498Szrj static void
dump_template_argument_list(cxx_pretty_printer * pp,tree args,int flags)25038fd1498Szrj dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags)
25138fd1498Szrj {
25238fd1498Szrj int n = get_non_default_template_args_count (args, flags);
25338fd1498Szrj int need_comma = 0;
25438fd1498Szrj int i;
25538fd1498Szrj
25638fd1498Szrj for (i = 0; i < n; ++i)
25738fd1498Szrj {
25838fd1498Szrj tree arg = TREE_VEC_ELT (args, i);
25938fd1498Szrj
26038fd1498Szrj /* Only print a comma if we know there is an argument coming. In
26138fd1498Szrj the case of an empty template argument pack, no actual
26238fd1498Szrj argument will be printed. */
26338fd1498Szrj if (need_comma
26438fd1498Szrj && (!ARGUMENT_PACK_P (arg)
26538fd1498Szrj || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
26638fd1498Szrj pp_separate_with_comma (pp);
26738fd1498Szrj
26838fd1498Szrj dump_template_argument (pp, arg, flags);
26938fd1498Szrj need_comma = 1;
27038fd1498Szrj }
27138fd1498Szrj }
27238fd1498Szrj
27338fd1498Szrj /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */
27438fd1498Szrj
27538fd1498Szrj static void
dump_template_parameter(cxx_pretty_printer * pp,tree parm,int flags)27638fd1498Szrj dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
27738fd1498Szrj {
27838fd1498Szrj tree p;
27938fd1498Szrj tree a;
28038fd1498Szrj
28138fd1498Szrj if (parm == error_mark_node)
28238fd1498Szrj return;
28338fd1498Szrj
28438fd1498Szrj p = TREE_VALUE (parm);
28538fd1498Szrj a = TREE_PURPOSE (parm);
28638fd1498Szrj
28738fd1498Szrj if (TREE_CODE (p) == TYPE_DECL)
28838fd1498Szrj {
28938fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
29038fd1498Szrj {
29138fd1498Szrj pp_cxx_ws_string (pp, "class");
29238fd1498Szrj if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
29338fd1498Szrj pp_cxx_ws_string (pp, "...");
29438fd1498Szrj if (DECL_NAME (p))
29538fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (p));
29638fd1498Szrj }
29738fd1498Szrj else if (DECL_NAME (p))
29838fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (p));
29938fd1498Szrj else
30038fd1498Szrj pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p));
30138fd1498Szrj }
30238fd1498Szrj else
30338fd1498Szrj dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS);
30438fd1498Szrj
30538fd1498Szrj if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
30638fd1498Szrj {
30738fd1498Szrj pp_cxx_whitespace (pp);
30838fd1498Szrj pp_equal (pp);
30938fd1498Szrj pp_cxx_whitespace (pp);
31038fd1498Szrj if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
31138fd1498Szrj dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF);
31238fd1498Szrj else
31338fd1498Szrj dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS);
31438fd1498Szrj }
31538fd1498Szrj }
31638fd1498Szrj
31738fd1498Szrj /* Dump, under control of FLAGS, a template-parameter-list binding.
31838fd1498Szrj PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
31938fd1498Szrj TREE_VEC. */
32038fd1498Szrj
32138fd1498Szrj static void
dump_template_bindings(cxx_pretty_printer * pp,tree parms,tree args,vec<tree,va_gc> * typenames)32238fd1498Szrj dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
32338fd1498Szrj vec<tree, va_gc> *typenames)
32438fd1498Szrj {
32538fd1498Szrj bool need_semicolon = false;
32638fd1498Szrj int i;
32738fd1498Szrj tree t;
32838fd1498Szrj
32938fd1498Szrj while (parms)
33038fd1498Szrj {
33138fd1498Szrj tree p = TREE_VALUE (parms);
33238fd1498Szrj int lvl = TMPL_PARMS_DEPTH (parms);
33338fd1498Szrj int arg_idx = 0;
33438fd1498Szrj int i;
33538fd1498Szrj tree lvl_args = NULL_TREE;
33638fd1498Szrj
33738fd1498Szrj /* Don't crash if we had an invalid argument list. */
33838fd1498Szrj if (TMPL_ARGS_DEPTH (args) >= lvl)
33938fd1498Szrj lvl_args = TMPL_ARGS_LEVEL (args, lvl);
34038fd1498Szrj
34138fd1498Szrj for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
34238fd1498Szrj {
34338fd1498Szrj tree arg = NULL_TREE;
34438fd1498Szrj
34538fd1498Szrj /* Don't crash if we had an invalid argument list. */
34638fd1498Szrj if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
34738fd1498Szrj arg = TREE_VEC_ELT (lvl_args, arg_idx);
34838fd1498Szrj
34938fd1498Szrj if (need_semicolon)
35038fd1498Szrj pp_separate_with_semicolon (pp);
35138fd1498Szrj dump_template_parameter (pp, TREE_VEC_ELT (p, i),
35238fd1498Szrj TFF_PLAIN_IDENTIFIER);
35338fd1498Szrj pp_cxx_whitespace (pp);
35438fd1498Szrj pp_equal (pp);
35538fd1498Szrj pp_cxx_whitespace (pp);
35638fd1498Szrj if (arg)
35738fd1498Szrj {
35838fd1498Szrj if (ARGUMENT_PACK_P (arg))
35938fd1498Szrj pp_cxx_left_brace (pp);
36038fd1498Szrj dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
36138fd1498Szrj if (ARGUMENT_PACK_P (arg))
36238fd1498Szrj pp_cxx_right_brace (pp);
36338fd1498Szrj }
36438fd1498Szrj else
36538fd1498Szrj pp_string (pp, M_("<missing>"));
36638fd1498Szrj
36738fd1498Szrj ++arg_idx;
36838fd1498Szrj need_semicolon = true;
36938fd1498Szrj }
37038fd1498Szrj
37138fd1498Szrj parms = TREE_CHAIN (parms);
37238fd1498Szrj }
37338fd1498Szrj
37438fd1498Szrj /* Don't bother with typenames for a partial instantiation. */
37538fd1498Szrj if (vec_safe_is_empty (typenames) || uses_template_parms (args))
37638fd1498Szrj return;
37738fd1498Szrj
37838fd1498Szrj /* Don't try to print typenames when we're processing a clone. */
37938fd1498Szrj if (current_function_decl
38038fd1498Szrj && !DECL_LANG_SPECIFIC (current_function_decl))
38138fd1498Szrj return;
38238fd1498Szrj
38338fd1498Szrj /* Don't try to do this once cgraph starts throwing away front-end
38438fd1498Szrj information. */
38538fd1498Szrj if (at_eof >= 2)
38638fd1498Szrj return;
38738fd1498Szrj
38838fd1498Szrj FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
38938fd1498Szrj {
39038fd1498Szrj if (need_semicolon)
39138fd1498Szrj pp_separate_with_semicolon (pp);
39238fd1498Szrj dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
39338fd1498Szrj pp_cxx_whitespace (pp);
39438fd1498Szrj pp_equal (pp);
39538fd1498Szrj pp_cxx_whitespace (pp);
39638fd1498Szrj push_deferring_access_checks (dk_no_check);
39738fd1498Szrj t = tsubst (t, args, tf_none, NULL_TREE);
39838fd1498Szrj pop_deferring_access_checks ();
39938fd1498Szrj /* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
40038fd1498Szrj pp_simple_type_specifier doesn't know about it. */
40138fd1498Szrj t = strip_typedefs (t);
40238fd1498Szrj dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
40338fd1498Szrj }
40438fd1498Szrj }
40538fd1498Szrj
40638fd1498Szrj /* Dump a human-readable equivalent of the alias template
40738fd1498Szrj specialization of T. */
40838fd1498Szrj
40938fd1498Szrj static void
dump_alias_template_specialization(cxx_pretty_printer * pp,tree t,int flags)41038fd1498Szrj dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
41138fd1498Szrj {
41238fd1498Szrj gcc_assert (alias_template_specialization_p (t));
41338fd1498Szrj
41438fd1498Szrj tree decl = TYPE_NAME (t);
41538fd1498Szrj if (!(flags & TFF_UNQUALIFIED_NAME))
41638fd1498Szrj dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
41738fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (decl));
41838fd1498Szrj dump_template_parms (pp, DECL_TEMPLATE_INFO (decl),
41938fd1498Szrj /*primary=*/false,
42038fd1498Szrj flags & ~TFF_TEMPLATE_HEADER);
42138fd1498Szrj }
42238fd1498Szrj
42338fd1498Szrj /* Dump a human-readable equivalent of TYPE. FLAGS controls the
42438fd1498Szrj format. */
42538fd1498Szrj
42638fd1498Szrj static void
dump_type(cxx_pretty_printer * pp,tree t,int flags)42738fd1498Szrj dump_type (cxx_pretty_printer *pp, tree t, int flags)
42838fd1498Szrj {
42938fd1498Szrj if (t == NULL_TREE)
43038fd1498Szrj return;
43138fd1498Szrj
43238fd1498Szrj /* Don't print e.g. "struct mytypedef". */
43338fd1498Szrj if (TYPE_P (t) && typedef_variant_p (t))
43438fd1498Szrj {
43538fd1498Szrj tree decl = TYPE_NAME (t);
43638fd1498Szrj if ((flags & TFF_CHASE_TYPEDEF)
43738fd1498Szrj || DECL_SELF_REFERENCE_P (decl)
43838fd1498Szrj || (!flag_pretty_templates
43938fd1498Szrj && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)))
44038fd1498Szrj t = strip_typedefs (t);
44138fd1498Szrj else if (alias_template_specialization_p (t))
44238fd1498Szrj {
44338fd1498Szrj dump_alias_template_specialization (pp, t, flags);
44438fd1498Szrj return;
44538fd1498Szrj }
44638fd1498Szrj else if (same_type_p (t, TREE_TYPE (decl)))
44738fd1498Szrj t = decl;
44838fd1498Szrj else
44938fd1498Szrj {
45038fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
45138fd1498Szrj pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
45238fd1498Szrj return;
45338fd1498Szrj }
45438fd1498Szrj }
45538fd1498Szrj
45638fd1498Szrj if (TYPE_PTRMEMFUNC_P (t))
45738fd1498Szrj goto offset_type;
45838fd1498Szrj
45938fd1498Szrj switch (TREE_CODE (t))
46038fd1498Szrj {
46138fd1498Szrj case LANG_TYPE:
46238fd1498Szrj if (t == init_list_type_node)
46338fd1498Szrj pp_string (pp, M_("<brace-enclosed initializer list>"));
46438fd1498Szrj else if (t == unknown_type_node)
46538fd1498Szrj pp_string (pp, M_("<unresolved overloaded function type>"));
46638fd1498Szrj else
46738fd1498Szrj {
46838fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
46938fd1498Szrj pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
47038fd1498Szrj }
47138fd1498Szrj break;
47238fd1498Szrj
47338fd1498Szrj case TREE_LIST:
47438fd1498Szrj /* A list of function parms. */
47538fd1498Szrj dump_parameters (pp, t, flags);
47638fd1498Szrj break;
47738fd1498Szrj
47838fd1498Szrj case IDENTIFIER_NODE:
47938fd1498Szrj pp_cxx_tree_identifier (pp, t);
48038fd1498Szrj break;
48138fd1498Szrj
48238fd1498Szrj case TREE_BINFO:
48338fd1498Szrj dump_type (pp, BINFO_TYPE (t), flags);
48438fd1498Szrj break;
48538fd1498Szrj
48638fd1498Szrj case RECORD_TYPE:
48738fd1498Szrj case UNION_TYPE:
48838fd1498Szrj case ENUMERAL_TYPE:
48938fd1498Szrj dump_aggr_type (pp, t, flags);
49038fd1498Szrj break;
49138fd1498Szrj
49238fd1498Szrj case TYPE_DECL:
49338fd1498Szrj if (flags & TFF_CHASE_TYPEDEF)
49438fd1498Szrj {
49538fd1498Szrj dump_type (pp, DECL_ORIGINAL_TYPE (t)
49638fd1498Szrj ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
49738fd1498Szrj break;
49838fd1498Szrj }
49938fd1498Szrj /* Fall through. */
50038fd1498Szrj
50138fd1498Szrj case TEMPLATE_DECL:
50238fd1498Szrj case NAMESPACE_DECL:
50338fd1498Szrj dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS);
50438fd1498Szrj break;
50538fd1498Szrj
50638fd1498Szrj case INTEGER_TYPE:
50738fd1498Szrj case REAL_TYPE:
50838fd1498Szrj case VOID_TYPE:
50938fd1498Szrj case BOOLEAN_TYPE:
51038fd1498Szrj case COMPLEX_TYPE:
51138fd1498Szrj case VECTOR_TYPE:
51238fd1498Szrj case FIXED_POINT_TYPE:
51338fd1498Szrj pp_type_specifier_seq (pp, t);
51438fd1498Szrj break;
51538fd1498Szrj
51638fd1498Szrj case TEMPLATE_TEMPLATE_PARM:
51738fd1498Szrj /* For parameters inside template signature. */
51838fd1498Szrj if (TYPE_IDENTIFIER (t))
51938fd1498Szrj pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
52038fd1498Szrj else
52138fd1498Szrj pp_cxx_canonical_template_parameter (pp, t);
52238fd1498Szrj break;
52338fd1498Szrj
52438fd1498Szrj case BOUND_TEMPLATE_TEMPLATE_PARM:
52538fd1498Szrj {
52638fd1498Szrj tree args = TYPE_TI_ARGS (t);
52738fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
52838fd1498Szrj pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
52938fd1498Szrj pp_cxx_begin_template_argument_list (pp);
53038fd1498Szrj dump_template_argument_list (pp, args, flags);
53138fd1498Szrj pp_cxx_end_template_argument_list (pp);
53238fd1498Szrj }
53338fd1498Szrj break;
53438fd1498Szrj
53538fd1498Szrj case TEMPLATE_TYPE_PARM:
53638fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
53738fd1498Szrj if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
53838fd1498Szrj pp_cxx_constrained_type_spec (pp, c);
53938fd1498Szrj else if (TYPE_IDENTIFIER (t))
54038fd1498Szrj pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
54138fd1498Szrj else
54238fd1498Szrj pp_cxx_canonical_template_parameter
54338fd1498Szrj (pp, TEMPLATE_TYPE_PARM_INDEX (t));
54438fd1498Szrj break;
54538fd1498Szrj
54638fd1498Szrj /* This is not always necessary for pointers and such, but doing this
54738fd1498Szrj reduces code size. */
54838fd1498Szrj case ARRAY_TYPE:
54938fd1498Szrj case POINTER_TYPE:
55038fd1498Szrj case REFERENCE_TYPE:
55138fd1498Szrj case OFFSET_TYPE:
55238fd1498Szrj offset_type:
55338fd1498Szrj case FUNCTION_TYPE:
55438fd1498Szrj case METHOD_TYPE:
55538fd1498Szrj {
55638fd1498Szrj dump_type_prefix (pp, t, flags);
55738fd1498Szrj dump_type_suffix (pp, t, flags);
55838fd1498Szrj break;
55938fd1498Szrj }
56038fd1498Szrj case TYPENAME_TYPE:
56138fd1498Szrj if (! (flags & TFF_CHASE_TYPEDEF)
56238fd1498Szrj && DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
56338fd1498Szrj {
56438fd1498Szrj dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
56538fd1498Szrj break;
56638fd1498Szrj }
56738fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
56838fd1498Szrj pp_cxx_ws_string (pp,
56938fd1498Szrj TYPENAME_IS_ENUM_P (t) ? "enum"
57038fd1498Szrj : TYPENAME_IS_CLASS_P (t) ? "class"
57138fd1498Szrj : "typename");
57238fd1498Szrj dump_typename (pp, t, flags);
57338fd1498Szrj break;
57438fd1498Szrj
57538fd1498Szrj case UNBOUND_CLASS_TEMPLATE:
57638fd1498Szrj if (! (flags & TFF_UNQUALIFIED_NAME))
57738fd1498Szrj {
57838fd1498Szrj dump_type (pp, TYPE_CONTEXT (t), flags);
57938fd1498Szrj pp_cxx_colon_colon (pp);
58038fd1498Szrj }
58138fd1498Szrj pp_cxx_ws_string (pp, "template");
58238fd1498Szrj dump_type (pp, TYPE_IDENTIFIER (t), flags);
58338fd1498Szrj break;
58438fd1498Szrj
58538fd1498Szrj case TYPEOF_TYPE:
58638fd1498Szrj pp_cxx_ws_string (pp, "__typeof__");
58738fd1498Szrj pp_cxx_whitespace (pp);
58838fd1498Szrj pp_cxx_left_paren (pp);
58938fd1498Szrj dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
59038fd1498Szrj pp_cxx_right_paren (pp);
59138fd1498Szrj break;
59238fd1498Szrj
59338fd1498Szrj case UNDERLYING_TYPE:
59438fd1498Szrj pp_cxx_ws_string (pp, "__underlying_type");
59538fd1498Szrj pp_cxx_whitespace (pp);
59638fd1498Szrj pp_cxx_left_paren (pp);
59738fd1498Szrj dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS);
59838fd1498Szrj pp_cxx_right_paren (pp);
59938fd1498Szrj break;
60038fd1498Szrj
60138fd1498Szrj case TYPE_PACK_EXPANSION:
60238fd1498Szrj dump_type (pp, PACK_EXPANSION_PATTERN (t), flags);
60338fd1498Szrj pp_cxx_ws_string (pp, "...");
60438fd1498Szrj break;
60538fd1498Szrj
60638fd1498Szrj case TYPE_ARGUMENT_PACK:
60738fd1498Szrj dump_template_argument (pp, t, flags);
60838fd1498Szrj break;
60938fd1498Szrj
61038fd1498Szrj case DECLTYPE_TYPE:
61138fd1498Szrj pp_cxx_ws_string (pp, "decltype");
61238fd1498Szrj pp_cxx_whitespace (pp);
61338fd1498Szrj pp_cxx_left_paren (pp);
61438fd1498Szrj dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
61538fd1498Szrj pp_cxx_right_paren (pp);
61638fd1498Szrj break;
61738fd1498Szrj
61838fd1498Szrj case NULLPTR_TYPE:
61938fd1498Szrj pp_string (pp, "std::nullptr_t");
62038fd1498Szrj break;
62138fd1498Szrj
62238fd1498Szrj default:
62338fd1498Szrj pp_unsupported_tree (pp, t);
62438fd1498Szrj /* Fall through. */
62538fd1498Szrj
62638fd1498Szrj case ERROR_MARK:
62738fd1498Szrj pp_string (pp, M_("<type error>"));
62838fd1498Szrj break;
62938fd1498Szrj }
63038fd1498Szrj }
63138fd1498Szrj
63238fd1498Szrj /* Dump a TYPENAME_TYPE. We need to notice when the context is itself
63338fd1498Szrj a TYPENAME_TYPE. */
63438fd1498Szrj
63538fd1498Szrj static void
dump_typename(cxx_pretty_printer * pp,tree t,int flags)63638fd1498Szrj dump_typename (cxx_pretty_printer *pp, tree t, int flags)
63738fd1498Szrj {
63838fd1498Szrj tree ctx = TYPE_CONTEXT (t);
63938fd1498Szrj
64038fd1498Szrj if (TREE_CODE (ctx) == TYPENAME_TYPE)
64138fd1498Szrj dump_typename (pp, ctx, flags);
64238fd1498Szrj else
64338fd1498Szrj dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
64438fd1498Szrj pp_cxx_colon_colon (pp);
64538fd1498Szrj dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags);
64638fd1498Szrj }
64738fd1498Szrj
64838fd1498Szrj /* Return the name of the supplied aggregate, or enumeral type. */
64938fd1498Szrj
65038fd1498Szrj const char *
class_key_or_enum_as_string(tree t)65138fd1498Szrj class_key_or_enum_as_string (tree t)
65238fd1498Szrj {
65338fd1498Szrj if (TREE_CODE (t) == ENUMERAL_TYPE)
65438fd1498Szrj {
65538fd1498Szrj if (SCOPED_ENUM_P (t))
65638fd1498Szrj return "enum class";
65738fd1498Szrj else
65838fd1498Szrj return "enum";
65938fd1498Szrj }
66038fd1498Szrj else if (TREE_CODE (t) == UNION_TYPE)
66138fd1498Szrj return "union";
66238fd1498Szrj else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
66338fd1498Szrj return "class";
66438fd1498Szrj else
66538fd1498Szrj return "struct";
66638fd1498Szrj }
66738fd1498Szrj
66838fd1498Szrj /* Print out a class declaration T under the control of FLAGS,
66938fd1498Szrj in the form `class foo'. */
67038fd1498Szrj
67138fd1498Szrj static void
dump_aggr_type(cxx_pretty_printer * pp,tree t,int flags)67238fd1498Szrj dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
67338fd1498Szrj {
67438fd1498Szrj tree name;
67538fd1498Szrj const char *variety = class_key_or_enum_as_string (t);
67638fd1498Szrj int typdef = 0;
67738fd1498Szrj int tmplate = 0;
67838fd1498Szrj
67938fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
68038fd1498Szrj
68138fd1498Szrj if (flags & TFF_CLASS_KEY_OR_ENUM)
68238fd1498Szrj pp_cxx_ws_string (pp, variety);
68338fd1498Szrj
68438fd1498Szrj name = TYPE_NAME (t);
68538fd1498Szrj
68638fd1498Szrj if (name)
68738fd1498Szrj {
68838fd1498Szrj typdef = (!DECL_ARTIFICIAL (name)
68938fd1498Szrj /* An alias specialization is not considered to be a
69038fd1498Szrj typedef. */
69138fd1498Szrj && !alias_template_specialization_p (t));
69238fd1498Szrj
69338fd1498Szrj if ((typdef
69438fd1498Szrj && ((flags & TFF_CHASE_TYPEDEF)
69538fd1498Szrj || (!flag_pretty_templates && DECL_LANG_SPECIFIC (name)
69638fd1498Szrj && DECL_TEMPLATE_INFO (name))))
69738fd1498Szrj || DECL_SELF_REFERENCE_P (name))
69838fd1498Szrj {
69938fd1498Szrj t = TYPE_MAIN_VARIANT (t);
70038fd1498Szrj name = TYPE_NAME (t);
70138fd1498Szrj typdef = 0;
70238fd1498Szrj }
70338fd1498Szrj
70438fd1498Szrj tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
70538fd1498Szrj && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
70638fd1498Szrj && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
70738fd1498Szrj || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
70838fd1498Szrj
70938fd1498Szrj if (! (flags & TFF_UNQUALIFIED_NAME))
71038fd1498Szrj dump_scope (pp, CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
71138fd1498Szrj flags &= ~TFF_UNQUALIFIED_NAME;
71238fd1498Szrj if (tmplate)
71338fd1498Szrj {
71438fd1498Szrj /* Because the template names are mangled, we have to locate
71538fd1498Szrj the most general template, and use that name. */
71638fd1498Szrj tree tpl = TYPE_TI_TEMPLATE (t);
71738fd1498Szrj
71838fd1498Szrj while (DECL_TEMPLATE_INFO (tpl))
71938fd1498Szrj tpl = DECL_TI_TEMPLATE (tpl);
72038fd1498Szrj name = tpl;
72138fd1498Szrj }
72238fd1498Szrj name = DECL_NAME (name);
72338fd1498Szrj }
72438fd1498Szrj
72538fd1498Szrj if (name == 0 || anon_aggrname_p (name))
72638fd1498Szrj {
72738fd1498Szrj if (flags & TFF_CLASS_KEY_OR_ENUM)
72838fd1498Szrj pp_string (pp, M_("<unnamed>"));
72938fd1498Szrj else
73038fd1498Szrj pp_printf (pp, M_("<unnamed %s>"), variety);
73138fd1498Szrj }
73238fd1498Szrj else if (LAMBDA_TYPE_P (t))
73338fd1498Szrj {
73438fd1498Szrj /* A lambda's "type" is essentially its signature. */
73538fd1498Szrj pp_string (pp, M_("<lambda"));
73638fd1498Szrj if (lambda_function (t))
73738fd1498Szrj dump_parameters (pp,
73838fd1498Szrj FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)),
73938fd1498Szrj flags);
74038fd1498Szrj pp_greater (pp);
74138fd1498Szrj }
74238fd1498Szrj else
74338fd1498Szrj pp_cxx_tree_identifier (pp, name);
74438fd1498Szrj if (tmplate)
74538fd1498Szrj dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
74638fd1498Szrj !CLASSTYPE_USE_TEMPLATE (t),
74738fd1498Szrj flags & ~TFF_TEMPLATE_HEADER);
74838fd1498Szrj }
74938fd1498Szrj
75038fd1498Szrj /* Dump into the obstack the initial part of the output for a given type.
75138fd1498Szrj This is necessary when dealing with things like functions returning
75238fd1498Szrj functions. Examples:
75338fd1498Szrj
75438fd1498Szrj return type of `int (* fee ())()': pointer -> function -> int. Both
75538fd1498Szrj pointer (and reference and offset) and function (and member) types must
75638fd1498Szrj deal with prefix and suffix.
75738fd1498Szrj
75838fd1498Szrj Arrays must also do this for DECL nodes, like int a[], and for things like
75938fd1498Szrj int *[]&. */
76038fd1498Szrj
76138fd1498Szrj static void
dump_type_prefix(cxx_pretty_printer * pp,tree t,int flags)76238fd1498Szrj dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
76338fd1498Szrj {
76438fd1498Szrj if (TYPE_PTRMEMFUNC_P (t))
76538fd1498Szrj {
76638fd1498Szrj t = TYPE_PTRMEMFUNC_FN_TYPE (t);
76738fd1498Szrj goto offset_type;
76838fd1498Szrj }
76938fd1498Szrj
77038fd1498Szrj switch (TREE_CODE (t))
77138fd1498Szrj {
77238fd1498Szrj case POINTER_TYPE:
77338fd1498Szrj case REFERENCE_TYPE:
77438fd1498Szrj {
77538fd1498Szrj tree sub = TREE_TYPE (t);
77638fd1498Szrj
77738fd1498Szrj dump_type_prefix (pp, sub, flags);
77838fd1498Szrj if (TREE_CODE (sub) == ARRAY_TYPE
77938fd1498Szrj || TREE_CODE (sub) == FUNCTION_TYPE)
78038fd1498Szrj {
78138fd1498Szrj pp_cxx_whitespace (pp);
78238fd1498Szrj pp_cxx_left_paren (pp);
78338fd1498Szrj pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub));
78438fd1498Szrj }
78538fd1498Szrj if (TYPE_PTR_P (t))
78638fd1498Szrj pp_star (pp);
78738fd1498Szrj else if (TREE_CODE (t) == REFERENCE_TYPE)
78838fd1498Szrj {
78938fd1498Szrj if (TYPE_REF_IS_RVALUE (t))
79038fd1498Szrj pp_ampersand_ampersand (pp);
79138fd1498Szrj else
79238fd1498Szrj pp_ampersand (pp);
79338fd1498Szrj }
79438fd1498Szrj pp->padding = pp_before;
79538fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
79638fd1498Szrj }
79738fd1498Szrj break;
79838fd1498Szrj
79938fd1498Szrj case OFFSET_TYPE:
80038fd1498Szrj offset_type:
80138fd1498Szrj dump_type_prefix (pp, TREE_TYPE (t), flags);
80238fd1498Szrj if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
80338fd1498Szrj {
80438fd1498Szrj pp_maybe_space (pp);
80538fd1498Szrj if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
80638fd1498Szrj pp_cxx_left_paren (pp);
80738fd1498Szrj dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags);
80838fd1498Szrj pp_cxx_colon_colon (pp);
80938fd1498Szrj }
81038fd1498Szrj pp_cxx_star (pp);
81138fd1498Szrj pp_cxx_cv_qualifier_seq (pp, t);
81238fd1498Szrj pp->padding = pp_before;
81338fd1498Szrj break;
81438fd1498Szrj
81538fd1498Szrj /* This can be reached without a pointer when dealing with
81638fd1498Szrj templates, e.g. std::is_function. */
81738fd1498Szrj case FUNCTION_TYPE:
81838fd1498Szrj dump_type_prefix (pp, TREE_TYPE (t), flags);
81938fd1498Szrj break;
82038fd1498Szrj
82138fd1498Szrj case METHOD_TYPE:
82238fd1498Szrj dump_type_prefix (pp, TREE_TYPE (t), flags);
82338fd1498Szrj pp_maybe_space (pp);
82438fd1498Szrj pp_cxx_left_paren (pp);
82538fd1498Szrj dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags);
82638fd1498Szrj pp_cxx_colon_colon (pp);
82738fd1498Szrj break;
82838fd1498Szrj
82938fd1498Szrj case ARRAY_TYPE:
83038fd1498Szrj dump_type_prefix (pp, TREE_TYPE (t), flags);
83138fd1498Szrj break;
83238fd1498Szrj
83338fd1498Szrj case ENUMERAL_TYPE:
83438fd1498Szrj case IDENTIFIER_NODE:
83538fd1498Szrj case INTEGER_TYPE:
83638fd1498Szrj case BOOLEAN_TYPE:
83738fd1498Szrj case REAL_TYPE:
83838fd1498Szrj case RECORD_TYPE:
83938fd1498Szrj case TEMPLATE_TYPE_PARM:
84038fd1498Szrj case TEMPLATE_TEMPLATE_PARM:
84138fd1498Szrj case BOUND_TEMPLATE_TEMPLATE_PARM:
84238fd1498Szrj case TREE_LIST:
84338fd1498Szrj case TYPE_DECL:
84438fd1498Szrj case TREE_VEC:
84538fd1498Szrj case UNION_TYPE:
84638fd1498Szrj case LANG_TYPE:
84738fd1498Szrj case VOID_TYPE:
84838fd1498Szrj case TYPENAME_TYPE:
84938fd1498Szrj case COMPLEX_TYPE:
85038fd1498Szrj case VECTOR_TYPE:
85138fd1498Szrj case TYPEOF_TYPE:
85238fd1498Szrj case UNDERLYING_TYPE:
85338fd1498Szrj case DECLTYPE_TYPE:
85438fd1498Szrj case TYPE_PACK_EXPANSION:
85538fd1498Szrj case FIXED_POINT_TYPE:
85638fd1498Szrj case NULLPTR_TYPE:
85738fd1498Szrj dump_type (pp, t, flags);
85838fd1498Szrj pp->padding = pp_before;
85938fd1498Szrj break;
86038fd1498Szrj
86138fd1498Szrj default:
86238fd1498Szrj pp_unsupported_tree (pp, t);
86338fd1498Szrj /* fall through. */
86438fd1498Szrj case ERROR_MARK:
86538fd1498Szrj pp_string (pp, M_("<typeprefixerror>"));
86638fd1498Szrj break;
86738fd1498Szrj }
86838fd1498Szrj }
86938fd1498Szrj
87038fd1498Szrj /* Dump the suffix of type T, under control of FLAGS. This is the part
87138fd1498Szrj which appears after the identifier (or function parms). */
87238fd1498Szrj
87338fd1498Szrj static void
dump_type_suffix(cxx_pretty_printer * pp,tree t,int flags)87438fd1498Szrj dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
87538fd1498Szrj {
87638fd1498Szrj if (TYPE_PTRMEMFUNC_P (t))
87738fd1498Szrj t = TYPE_PTRMEMFUNC_FN_TYPE (t);
87838fd1498Szrj
87938fd1498Szrj switch (TREE_CODE (t))
88038fd1498Szrj {
88138fd1498Szrj case POINTER_TYPE:
88238fd1498Szrj case REFERENCE_TYPE:
88338fd1498Szrj case OFFSET_TYPE:
88438fd1498Szrj if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
88538fd1498Szrj || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
88638fd1498Szrj pp_cxx_right_paren (pp);
88738fd1498Szrj if (TREE_CODE (t) == POINTER_TYPE)
88838fd1498Szrj flags |= TFF_POINTER;
88938fd1498Szrj dump_type_suffix (pp, TREE_TYPE (t), flags);
89038fd1498Szrj break;
89138fd1498Szrj
89238fd1498Szrj case FUNCTION_TYPE:
89338fd1498Szrj case METHOD_TYPE:
89438fd1498Szrj {
89538fd1498Szrj tree arg;
89638fd1498Szrj if (TREE_CODE (t) == METHOD_TYPE)
89738fd1498Szrj /* Can only be reached through a pointer. */
89838fd1498Szrj pp_cxx_right_paren (pp);
89938fd1498Szrj arg = TYPE_ARG_TYPES (t);
90038fd1498Szrj if (TREE_CODE (t) == METHOD_TYPE)
90138fd1498Szrj arg = TREE_CHAIN (arg);
90238fd1498Szrj
90338fd1498Szrj /* Function pointers don't have default args. Not in standard C++,
90438fd1498Szrj anyway; they may in g++, but we'll just pretend otherwise. */
90538fd1498Szrj dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
90638fd1498Szrj
90738fd1498Szrj pp->padding = pp_before;
90838fd1498Szrj pp_cxx_cv_qualifiers (pp, type_memfn_quals (t),
90938fd1498Szrj TREE_CODE (t) == FUNCTION_TYPE
91038fd1498Szrj && (flags & TFF_POINTER));
91138fd1498Szrj dump_ref_qualifier (pp, t, flags);
91238fd1498Szrj if (tx_safe_fn_type_p (t))
91338fd1498Szrj pp_cxx_ws_string (pp, "transaction_safe");
91438fd1498Szrj dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags);
91538fd1498Szrj dump_type_suffix (pp, TREE_TYPE (t), flags);
91638fd1498Szrj break;
91738fd1498Szrj }
91838fd1498Szrj
91938fd1498Szrj case ARRAY_TYPE:
92038fd1498Szrj pp_maybe_space (pp);
92138fd1498Szrj pp_cxx_left_bracket (pp);
92238fd1498Szrj if (tree dtype = TYPE_DOMAIN (t))
92338fd1498Szrj {
92438fd1498Szrj tree max = TYPE_MAX_VALUE (dtype);
92538fd1498Szrj /* Zero-length arrays have an upper bound of SIZE_MAX. */
92638fd1498Szrj if (integer_all_onesp (max))
92738fd1498Szrj pp_character (pp, '0');
92838fd1498Szrj else if (tree_fits_shwi_p (max))
92938fd1498Szrj pp_wide_integer (pp, tree_to_shwi (max) + 1);
93038fd1498Szrj else
93138fd1498Szrj {
93238fd1498Szrj STRIP_NOPS (max);
93338fd1498Szrj if (TREE_CODE (max) == SAVE_EXPR)
93438fd1498Szrj max = TREE_OPERAND (max, 0);
93538fd1498Szrj if (TREE_CODE (max) == MINUS_EXPR
93638fd1498Szrj || TREE_CODE (max) == PLUS_EXPR)
93738fd1498Szrj {
93838fd1498Szrj max = TREE_OPERAND (max, 0);
93938fd1498Szrj while (CONVERT_EXPR_P (max))
94038fd1498Szrj max = TREE_OPERAND (max, 0);
94138fd1498Szrj }
94238fd1498Szrj else
94338fd1498Szrj max = fold_build2_loc (input_location,
94438fd1498Szrj PLUS_EXPR, dtype, max,
94538fd1498Szrj build_int_cst (dtype, 1));
94638fd1498Szrj dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS);
94738fd1498Szrj }
94838fd1498Szrj }
94938fd1498Szrj pp_cxx_right_bracket (pp);
95038fd1498Szrj dump_type_suffix (pp, TREE_TYPE (t), flags);
95138fd1498Szrj break;
95238fd1498Szrj
95338fd1498Szrj case ENUMERAL_TYPE:
95438fd1498Szrj case IDENTIFIER_NODE:
95538fd1498Szrj case INTEGER_TYPE:
95638fd1498Szrj case BOOLEAN_TYPE:
95738fd1498Szrj case REAL_TYPE:
95838fd1498Szrj case RECORD_TYPE:
95938fd1498Szrj case TEMPLATE_TYPE_PARM:
96038fd1498Szrj case TEMPLATE_TEMPLATE_PARM:
96138fd1498Szrj case BOUND_TEMPLATE_TEMPLATE_PARM:
96238fd1498Szrj case TREE_LIST:
96338fd1498Szrj case TYPE_DECL:
96438fd1498Szrj case TREE_VEC:
96538fd1498Szrj case UNION_TYPE:
96638fd1498Szrj case LANG_TYPE:
96738fd1498Szrj case VOID_TYPE:
96838fd1498Szrj case TYPENAME_TYPE:
96938fd1498Szrj case COMPLEX_TYPE:
97038fd1498Szrj case VECTOR_TYPE:
97138fd1498Szrj case TYPEOF_TYPE:
97238fd1498Szrj case UNDERLYING_TYPE:
97338fd1498Szrj case DECLTYPE_TYPE:
97438fd1498Szrj case TYPE_PACK_EXPANSION:
97538fd1498Szrj case FIXED_POINT_TYPE:
97638fd1498Szrj case NULLPTR_TYPE:
97738fd1498Szrj break;
97838fd1498Szrj
97938fd1498Szrj default:
98038fd1498Szrj pp_unsupported_tree (pp, t);
98138fd1498Szrj case ERROR_MARK:
98238fd1498Szrj /* Don't mark it here, we should have already done in
98338fd1498Szrj dump_type_prefix. */
98438fd1498Szrj break;
98538fd1498Szrj }
98638fd1498Szrj }
98738fd1498Szrj
98838fd1498Szrj static void
dump_global_iord(cxx_pretty_printer * pp,tree t)98938fd1498Szrj dump_global_iord (cxx_pretty_printer *pp, tree t)
99038fd1498Szrj {
99138fd1498Szrj const char *p = NULL;
99238fd1498Szrj
99338fd1498Szrj if (DECL_GLOBAL_CTOR_P (t))
99438fd1498Szrj p = M_("(static initializers for %s)");
99538fd1498Szrj else if (DECL_GLOBAL_DTOR_P (t))
99638fd1498Szrj p = M_("(static destructors for %s)");
99738fd1498Szrj else
99838fd1498Szrj gcc_unreachable ();
99938fd1498Szrj
100038fd1498Szrj pp_printf (pp, p, DECL_SOURCE_FILE (t));
100138fd1498Szrj }
100238fd1498Szrj
100338fd1498Szrj static void
dump_simple_decl(cxx_pretty_printer * pp,tree t,tree type,int flags)100438fd1498Szrj dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
100538fd1498Szrj {
100638fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
100738fd1498Szrj {
100838fd1498Szrj if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t))
100938fd1498Szrj {
101038fd1498Szrj if (DECL_LANG_SPECIFIC (t) && DECL_DECLARED_CONCEPT_P (t))
101138fd1498Szrj pp_cxx_ws_string (pp, "concept");
101238fd1498Szrj else
101338fd1498Szrj pp_cxx_ws_string (pp, "constexpr");
101438fd1498Szrj }
101538fd1498Szrj dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
101638fd1498Szrj pp_maybe_space (pp);
101738fd1498Szrj }
101838fd1498Szrj if (! (flags & TFF_UNQUALIFIED_NAME)
101938fd1498Szrj && TREE_CODE (t) != PARM_DECL
102038fd1498Szrj && (!DECL_INITIAL (t)
102138fd1498Szrj || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
102238fd1498Szrj dump_scope (pp, CP_DECL_CONTEXT (t), flags);
102338fd1498Szrj flags &= ~TFF_UNQUALIFIED_NAME;
102438fd1498Szrj if ((flags & TFF_DECL_SPECIFIERS)
102538fd1498Szrj && DECL_TEMPLATE_PARM_P (t)
102638fd1498Szrj && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
102738fd1498Szrj pp_string (pp, "...");
102838fd1498Szrj if (DECL_NAME (t))
102938fd1498Szrj {
103038fd1498Szrj if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t))
103138fd1498Szrj {
103238fd1498Szrj pp_less (pp);
103338fd1498Szrj pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
103438fd1498Szrj pp_string (pp, " capture>");
103538fd1498Szrj }
103638fd1498Szrj else
103738fd1498Szrj dump_decl (pp, DECL_NAME (t), flags);
103838fd1498Szrj }
103938fd1498Szrj else if (DECL_DECOMPOSITION_P (t))
104038fd1498Szrj pp_string (pp, M_("<structured bindings>"));
104138fd1498Szrj else
104238fd1498Szrj pp_string (pp, M_("<anonymous>"));
104338fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
104438fd1498Szrj dump_type_suffix (pp, type, flags);
104538fd1498Szrj }
104638fd1498Szrj
104738fd1498Szrj /* Print an IDENTIFIER_NODE that is the name of a declaration. */
104838fd1498Szrj
104938fd1498Szrj static void
dump_decl_name(cxx_pretty_printer * pp,tree t,int flags)105038fd1498Szrj dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
105138fd1498Szrj {
105238fd1498Szrj /* These special cases are duplicated here so that other functions
105338fd1498Szrj can feed identifiers to error and get them demangled properly. */
105438fd1498Szrj if (IDENTIFIER_CONV_OP_P (t))
105538fd1498Szrj {
105638fd1498Szrj pp_cxx_ws_string (pp, "operator");
105738fd1498Szrj /* Not exactly IDENTIFIER_TYPE_VALUE. */
105838fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
105938fd1498Szrj return;
106038fd1498Szrj }
106138fd1498Szrj if (dguide_name_p (t))
106238fd1498Szrj {
106338fd1498Szrj dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)),
106438fd1498Szrj TFF_UNQUALIFIED_NAME);
106538fd1498Szrj return;
106638fd1498Szrj }
106738fd1498Szrj
106838fd1498Szrj const char *str = IDENTIFIER_POINTER (t);
106938fd1498Szrj if (!strncmp (str, "_ZGR", 3))
107038fd1498Szrj {
107138fd1498Szrj pp_cxx_ws_string (pp, "<temporary>");
107238fd1498Szrj return;
107338fd1498Szrj }
107438fd1498Szrj
107538fd1498Szrj pp_cxx_tree_identifier (pp, t);
107638fd1498Szrj }
107738fd1498Szrj
107838fd1498Szrj /* Dump a human readable string for the decl T under control of FLAGS. */
107938fd1498Szrj
108038fd1498Szrj static void
dump_decl(cxx_pretty_printer * pp,tree t,int flags)108138fd1498Szrj dump_decl (cxx_pretty_printer *pp, tree t, int flags)
108238fd1498Szrj {
108338fd1498Szrj if (t == NULL_TREE)
108438fd1498Szrj return;
108538fd1498Szrj
108638fd1498Szrj /* If doing Objective-C++, give Objective-C a chance to demangle
108738fd1498Szrj Objective-C method names. */
108838fd1498Szrj if (c_dialect_objc ())
108938fd1498Szrj {
109038fd1498Szrj const char *demangled = objc_maybe_printable_name (t, flags);
109138fd1498Szrj if (demangled)
109238fd1498Szrj {
109338fd1498Szrj pp_string (pp, demangled);
109438fd1498Szrj return;
109538fd1498Szrj }
109638fd1498Szrj }
109738fd1498Szrj
109838fd1498Szrj switch (TREE_CODE (t))
109938fd1498Szrj {
110038fd1498Szrj case TYPE_DECL:
110138fd1498Szrj /* Don't say 'typedef class A' */
110238fd1498Szrj if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t))
110338fd1498Szrj {
110438fd1498Szrj if ((flags & TFF_DECL_SPECIFIERS)
110538fd1498Szrj && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
110638fd1498Szrj {
110738fd1498Szrj /* Say `class T' not just `T'. */
110838fd1498Szrj pp_cxx_ws_string (pp, "class");
110938fd1498Szrj
111038fd1498Szrj /* Emit the `...' for a parameter pack. */
111138fd1498Szrj if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
111238fd1498Szrj pp_cxx_ws_string (pp, "...");
111338fd1498Szrj }
111438fd1498Szrj
111538fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
111638fd1498Szrj break;
111738fd1498Szrj }
111838fd1498Szrj if (TYPE_DECL_ALIAS_P (t)
111938fd1498Szrj && (flags & TFF_DECL_SPECIFIERS
112038fd1498Szrj || flags & TFF_CLASS_KEY_OR_ENUM))
112138fd1498Szrj {
112238fd1498Szrj pp_cxx_ws_string (pp, "using");
112338fd1498Szrj dump_decl (pp, DECL_NAME (t), flags);
112438fd1498Szrj pp_cxx_whitespace (pp);
112538fd1498Szrj pp_cxx_ws_string (pp, "=");
112638fd1498Szrj pp_cxx_whitespace (pp);
112738fd1498Szrj dump_type (pp, (DECL_ORIGINAL_TYPE (t)
112838fd1498Szrj ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)),
112938fd1498Szrj flags);
113038fd1498Szrj break;
113138fd1498Szrj }
113238fd1498Szrj if ((flags & TFF_DECL_SPECIFIERS)
113338fd1498Szrj && !DECL_SELF_REFERENCE_P (t))
113438fd1498Szrj pp_cxx_ws_string (pp, "typedef");
113538fd1498Szrj dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t)
113638fd1498Szrj ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
113738fd1498Szrj flags);
113838fd1498Szrj break;
113938fd1498Szrj
114038fd1498Szrj case VAR_DECL:
114138fd1498Szrj if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
114238fd1498Szrj {
114338fd1498Szrj pp_string (pp, M_("vtable for "));
114438fd1498Szrj gcc_assert (TYPE_P (DECL_CONTEXT (t)));
114538fd1498Szrj dump_type (pp, DECL_CONTEXT (t), flags);
114638fd1498Szrj break;
114738fd1498Szrj }
114838fd1498Szrj /* Fall through. */
114938fd1498Szrj case FIELD_DECL:
115038fd1498Szrj case PARM_DECL:
115138fd1498Szrj dump_simple_decl (pp, t, TREE_TYPE (t), flags);
115238fd1498Szrj
115338fd1498Szrj /* Handle variable template specializations. */
115438fd1498Szrj if (VAR_P (t)
115538fd1498Szrj && DECL_LANG_SPECIFIC (t)
115638fd1498Szrj && DECL_TEMPLATE_INFO (t)
115738fd1498Szrj && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
115838fd1498Szrj {
115938fd1498Szrj pp_cxx_begin_template_argument_list (pp);
116038fd1498Szrj tree args = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
116138fd1498Szrj dump_template_argument_list (pp, args, flags);
116238fd1498Szrj pp_cxx_end_template_argument_list (pp);
116338fd1498Szrj }
116438fd1498Szrj break;
116538fd1498Szrj
116638fd1498Szrj case RESULT_DECL:
116738fd1498Szrj pp_string (pp, M_("<return value> "));
116838fd1498Szrj dump_simple_decl (pp, t, TREE_TYPE (t), flags);
116938fd1498Szrj break;
117038fd1498Szrj
117138fd1498Szrj case NAMESPACE_DECL:
117238fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
117338fd1498Szrj pp->declaration (t);
117438fd1498Szrj else
117538fd1498Szrj {
117638fd1498Szrj if (! (flags & TFF_UNQUALIFIED_NAME))
117738fd1498Szrj dump_scope (pp, CP_DECL_CONTEXT (t), flags);
117838fd1498Szrj flags &= ~TFF_UNQUALIFIED_NAME;
117938fd1498Szrj if (DECL_NAME (t) == NULL_TREE)
118038fd1498Szrj {
118138fd1498Szrj if (!(pp->flags & pp_c_flag_gnu_v3))
118238fd1498Szrj pp_cxx_ws_string (pp, M_("{anonymous}"));
118338fd1498Szrj else
118438fd1498Szrj pp_cxx_ws_string (pp, M_("(anonymous namespace)"));
118538fd1498Szrj }
118638fd1498Szrj else
118738fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (t));
118838fd1498Szrj }
118938fd1498Szrj break;
119038fd1498Szrj
119138fd1498Szrj case SCOPE_REF:
119238fd1498Szrj dump_type (pp, TREE_OPERAND (t, 0), flags);
119338fd1498Szrj pp_cxx_colon_colon (pp);
119438fd1498Szrj dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
119538fd1498Szrj break;
119638fd1498Szrj
119738fd1498Szrj case ARRAY_REF:
119838fd1498Szrj dump_decl (pp, TREE_OPERAND (t, 0), flags);
119938fd1498Szrj pp_cxx_left_bracket (pp);
120038fd1498Szrj dump_decl (pp, TREE_OPERAND (t, 1), flags);
120138fd1498Szrj pp_cxx_right_bracket (pp);
120238fd1498Szrj break;
120338fd1498Szrj
120438fd1498Szrj /* So that we can do dump_decl on an aggr type. */
120538fd1498Szrj case RECORD_TYPE:
120638fd1498Szrj case UNION_TYPE:
120738fd1498Szrj case ENUMERAL_TYPE:
120838fd1498Szrj dump_type (pp, t, flags);
120938fd1498Szrj break;
121038fd1498Szrj
121138fd1498Szrj case BIT_NOT_EXPR:
121238fd1498Szrj /* This is a pseudo destructor call which has not been folded into
121338fd1498Szrj a PSEUDO_DTOR_EXPR yet. */
121438fd1498Szrj pp_cxx_complement (pp);
121538fd1498Szrj dump_type (pp, TREE_OPERAND (t, 0), flags);
121638fd1498Szrj break;
121738fd1498Szrj
121838fd1498Szrj case TYPE_EXPR:
121938fd1498Szrj gcc_unreachable ();
122038fd1498Szrj break;
122138fd1498Szrj
122238fd1498Szrj case IDENTIFIER_NODE:
122338fd1498Szrj dump_decl_name (pp, t, flags);
122438fd1498Szrj break;
122538fd1498Szrj
122638fd1498Szrj case OVERLOAD:
122738fd1498Szrj if (!OVL_SINGLE_P (t))
122838fd1498Szrj {
122938fd1498Szrj tree ctx = ovl_scope (t);
123038fd1498Szrj if (ctx != global_namespace)
123138fd1498Szrj {
123238fd1498Szrj if (TYPE_P (ctx))
123338fd1498Szrj dump_type (pp, ctx, flags);
123438fd1498Szrj else
123538fd1498Szrj dump_decl (pp, ctx, flags);
123638fd1498Szrj pp_cxx_colon_colon (pp);
123738fd1498Szrj }
123838fd1498Szrj dump_decl (pp, OVL_NAME (t), flags);
123938fd1498Szrj break;
124038fd1498Szrj }
124138fd1498Szrj
124238fd1498Szrj /* If there's only one function, just treat it like an ordinary
124338fd1498Szrj FUNCTION_DECL. */
124438fd1498Szrj t = OVL_FIRST (t);
124538fd1498Szrj /* Fall through. */
124638fd1498Szrj
124738fd1498Szrj case FUNCTION_DECL:
124838fd1498Szrj if (! DECL_LANG_SPECIFIC (t))
124938fd1498Szrj {
125038fd1498Szrj if (DECL_ABSTRACT_ORIGIN (t)
125138fd1498Szrj && DECL_ABSTRACT_ORIGIN (t) != t)
125238fd1498Szrj dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags);
125338fd1498Szrj else
125438fd1498Szrj dump_function_name (pp, t, flags);
125538fd1498Szrj }
125638fd1498Szrj else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
125738fd1498Szrj dump_global_iord (pp, t);
125838fd1498Szrj else
125938fd1498Szrj dump_function_decl (pp, t, flags);
126038fd1498Szrj break;
126138fd1498Szrj
126238fd1498Szrj case TEMPLATE_DECL:
126338fd1498Szrj dump_template_decl (pp, t, flags);
126438fd1498Szrj break;
126538fd1498Szrj
126638fd1498Szrj case TEMPLATE_ID_EXPR:
126738fd1498Szrj {
126838fd1498Szrj tree name = TREE_OPERAND (t, 0);
126938fd1498Szrj tree args = TREE_OPERAND (t, 1);
127038fd1498Szrj
127138fd1498Szrj if (!identifier_p (name))
127238fd1498Szrj name = OVL_NAME (name);
127338fd1498Szrj dump_decl (pp, name, flags);
127438fd1498Szrj pp_cxx_begin_template_argument_list (pp);
127538fd1498Szrj if (args == error_mark_node)
127638fd1498Szrj pp_string (pp, M_("<template arguments error>"));
127738fd1498Szrj else if (args)
127838fd1498Szrj dump_template_argument_list
127938fd1498Szrj (pp, args, flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
128038fd1498Szrj pp_cxx_end_template_argument_list (pp);
128138fd1498Szrj }
128238fd1498Szrj break;
128338fd1498Szrj
128438fd1498Szrj case LABEL_DECL:
128538fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (t));
128638fd1498Szrj break;
128738fd1498Szrj
128838fd1498Szrj case CONST_DECL:
128938fd1498Szrj if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
129038fd1498Szrj || (DECL_INITIAL (t) &&
129138fd1498Szrj TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
129238fd1498Szrj dump_simple_decl (pp, t, TREE_TYPE (t), flags);
129338fd1498Szrj else if (DECL_NAME (t))
129438fd1498Szrj dump_decl (pp, DECL_NAME (t), flags);
129538fd1498Szrj else if (DECL_INITIAL (t))
129638fd1498Szrj dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
129738fd1498Szrj else
129838fd1498Szrj pp_string (pp, M_("<enumerator>"));
129938fd1498Szrj break;
130038fd1498Szrj
130138fd1498Szrj case USING_DECL:
130238fd1498Szrj {
130338fd1498Szrj pp_cxx_ws_string (pp, "using");
130438fd1498Szrj tree scope = USING_DECL_SCOPE (t);
130538fd1498Szrj bool variadic = false;
130638fd1498Szrj if (PACK_EXPANSION_P (scope))
130738fd1498Szrj {
130838fd1498Szrj scope = PACK_EXPANSION_PATTERN (scope);
130938fd1498Szrj variadic = true;
131038fd1498Szrj }
131138fd1498Szrj dump_type (pp, scope, flags);
131238fd1498Szrj pp_cxx_colon_colon (pp);
131338fd1498Szrj dump_decl (pp, DECL_NAME (t), flags);
131438fd1498Szrj if (variadic)
131538fd1498Szrj pp_cxx_ws_string (pp, "...");
131638fd1498Szrj }
131738fd1498Szrj break;
131838fd1498Szrj
131938fd1498Szrj case STATIC_ASSERT:
132038fd1498Szrj pp->declaration (t);
132138fd1498Szrj break;
132238fd1498Szrj
132338fd1498Szrj case BASELINK:
132438fd1498Szrj dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
132538fd1498Szrj break;
132638fd1498Szrj
132738fd1498Szrj case NON_DEPENDENT_EXPR:
132838fd1498Szrj dump_expr (pp, t, flags);
132938fd1498Szrj break;
133038fd1498Szrj
133138fd1498Szrj case TEMPLATE_TYPE_PARM:
133238fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
133338fd1498Szrj pp->declaration (t);
133438fd1498Szrj else
133538fd1498Szrj pp->type_id (t);
133638fd1498Szrj break;
133738fd1498Szrj
133838fd1498Szrj case UNBOUND_CLASS_TEMPLATE:
133938fd1498Szrj case TYPE_PACK_EXPANSION:
134038fd1498Szrj case TREE_BINFO:
134138fd1498Szrj dump_type (pp, t, flags);
134238fd1498Szrj break;
134338fd1498Szrj
134438fd1498Szrj default:
134538fd1498Szrj pp_unsupported_tree (pp, t);
134638fd1498Szrj /* Fall through. */
134738fd1498Szrj
134838fd1498Szrj case ERROR_MARK:
134938fd1498Szrj pp_string (pp, M_("<declaration error>"));
135038fd1498Szrj break;
135138fd1498Szrj }
135238fd1498Szrj }
135338fd1498Szrj
135438fd1498Szrj /* Dump a template declaration T under control of FLAGS. This means the
135538fd1498Szrj 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */
135638fd1498Szrj
135738fd1498Szrj static void
dump_template_decl(cxx_pretty_printer * pp,tree t,int flags)135838fd1498Szrj dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
135938fd1498Szrj {
136038fd1498Szrj tree orig_parms = DECL_TEMPLATE_PARMS (t);
136138fd1498Szrj tree parms;
136238fd1498Szrj int i;
136338fd1498Szrj
136438fd1498Szrj if (flags & TFF_TEMPLATE_HEADER)
136538fd1498Szrj {
136638fd1498Szrj for (parms = orig_parms = nreverse (orig_parms);
136738fd1498Szrj parms;
136838fd1498Szrj parms = TREE_CHAIN (parms))
136938fd1498Szrj {
137038fd1498Szrj tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
137138fd1498Szrj int len = TREE_VEC_LENGTH (inner_parms);
137238fd1498Szrj
137338fd1498Szrj if (len == 0)
137438fd1498Szrj {
137538fd1498Szrj /* Skip over the dummy template levels of a template template
137638fd1498Szrj parm. */
137738fd1498Szrj gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM);
137838fd1498Szrj continue;
137938fd1498Szrj }
138038fd1498Szrj
138138fd1498Szrj pp_cxx_ws_string (pp, "template");
138238fd1498Szrj pp_cxx_begin_template_argument_list (pp);
138338fd1498Szrj
138438fd1498Szrj /* If we've shown the template prefix, we'd better show the
138538fd1498Szrj parameters' and decl's type too. */
138638fd1498Szrj flags |= TFF_DECL_SPECIFIERS;
138738fd1498Szrj
138838fd1498Szrj for (i = 0; i < len; i++)
138938fd1498Szrj {
139038fd1498Szrj if (i)
139138fd1498Szrj pp_separate_with_comma (pp);
139238fd1498Szrj dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i),
139338fd1498Szrj flags);
139438fd1498Szrj }
139538fd1498Szrj pp_cxx_end_template_argument_list (pp);
139638fd1498Szrj pp_cxx_whitespace (pp);
139738fd1498Szrj }
139838fd1498Szrj nreverse(orig_parms);
139938fd1498Szrj
140038fd1498Szrj if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
140138fd1498Szrj {
140238fd1498Szrj /* Say `template<arg> class TT' not just `template<arg> TT'. */
140338fd1498Szrj pp_cxx_ws_string (pp, "class");
140438fd1498Szrj
140538fd1498Szrj /* If this is a parameter pack, print the ellipsis. */
140638fd1498Szrj if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
140738fd1498Szrj pp_cxx_ws_string (pp, "...");
140838fd1498Szrj }
140938fd1498Szrj
141038fd1498Szrj /* Only print the requirements if we're also printing
141138fd1498Szrj the template header. */
141238fd1498Szrj if (flag_concepts)
141338fd1498Szrj if (tree ci = get_constraints (t))
141438fd1498Szrj if (check_constraint_info (ci))
141538fd1498Szrj if (tree reqs = CI_TEMPLATE_REQS (ci))
141638fd1498Szrj {
141738fd1498Szrj pp_cxx_requires_clause (pp, reqs);
141838fd1498Szrj pp_cxx_whitespace (pp);
141938fd1498Szrj }
142038fd1498Szrj }
142138fd1498Szrj
142238fd1498Szrj
142338fd1498Szrj if (DECL_CLASS_TEMPLATE_P (t))
142438fd1498Szrj dump_type (pp, TREE_TYPE (t),
142538fd1498Szrj ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
142638fd1498Szrj | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
142738fd1498Szrj else if (DECL_TEMPLATE_RESULT (t)
142838fd1498Szrj && (VAR_P (DECL_TEMPLATE_RESULT (t))
142938fd1498Szrj /* Alias template. */
143038fd1498Szrj || DECL_TYPE_TEMPLATE_P (t)))
143138fd1498Szrj dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
143238fd1498Szrj else
143338fd1498Szrj {
143438fd1498Szrj gcc_assert (TREE_TYPE (t));
143538fd1498Szrj switch (NEXT_CODE (t))
143638fd1498Szrj {
143738fd1498Szrj case METHOD_TYPE:
143838fd1498Szrj case FUNCTION_TYPE:
143938fd1498Szrj dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME);
144038fd1498Szrj break;
144138fd1498Szrj default:
144238fd1498Szrj /* This case can occur with some invalid code. */
144338fd1498Szrj dump_type (pp, TREE_TYPE (t),
144438fd1498Szrj (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
144538fd1498Szrj | (flags & TFF_DECL_SPECIFIERS
144638fd1498Szrj ? TFF_CLASS_KEY_OR_ENUM : 0));
144738fd1498Szrj }
144838fd1498Szrj }
144938fd1498Szrj }
145038fd1498Szrj
145138fd1498Szrj /* find_typenames looks through the type of the function template T
145238fd1498Szrj and returns a vec containing any typedefs, decltypes or TYPENAME_TYPEs
145338fd1498Szrj it finds. */
145438fd1498Szrj
145538fd1498Szrj struct find_typenames_t
145638fd1498Szrj {
145738fd1498Szrj hash_set<tree> *p_set;
145838fd1498Szrj vec<tree, va_gc> *typenames;
145938fd1498Szrj };
146038fd1498Szrj
146138fd1498Szrj static tree
find_typenames_r(tree * tp,int * walk_subtrees,void * data)146238fd1498Szrj find_typenames_r (tree *tp, int *walk_subtrees, void *data)
146338fd1498Szrj {
146438fd1498Szrj struct find_typenames_t *d = (struct find_typenames_t *)data;
146538fd1498Szrj tree mv = NULL_TREE;
146638fd1498Szrj
146738fd1498Szrj if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
146838fd1498Szrj /* Add the type of the typedef without any additional cv-quals. */
146938fd1498Szrj mv = TREE_TYPE (TYPE_NAME (*tp));
147038fd1498Szrj else if (TREE_CODE (*tp) == TYPENAME_TYPE
147138fd1498Szrj || TREE_CODE (*tp) == DECLTYPE_TYPE)
147238fd1498Szrj /* Add the typename without any cv-qualifiers. */
147338fd1498Szrj mv = TYPE_MAIN_VARIANT (*tp);
147438fd1498Szrj
147538fd1498Szrj if (PACK_EXPANSION_P (*tp))
147638fd1498Szrj {
147738fd1498Szrj /* Don't mess with parameter packs since we don't remember
147838fd1498Szrj the pack expansion context for a particular typename. */
147938fd1498Szrj *walk_subtrees = false;
148038fd1498Szrj return NULL_TREE;
148138fd1498Szrj }
148238fd1498Szrj
148338fd1498Szrj if (mv && (mv == *tp || !d->p_set->add (mv)))
148438fd1498Szrj vec_safe_push (d->typenames, mv);
148538fd1498Szrj
148638fd1498Szrj /* Search into class template arguments, which cp_walk_subtrees
148738fd1498Szrj doesn't do. */
148838fd1498Szrj if (CLASS_TYPE_P (*tp) && CLASSTYPE_TEMPLATE_INFO (*tp))
148938fd1498Szrj cp_walk_tree (&CLASSTYPE_TI_ARGS (*tp), find_typenames_r,
149038fd1498Szrj data, d->p_set);
149138fd1498Szrj
149238fd1498Szrj return NULL_TREE;
149338fd1498Szrj }
149438fd1498Szrj
149538fd1498Szrj static vec<tree, va_gc> *
find_typenames(tree t)149638fd1498Szrj find_typenames (tree t)
149738fd1498Szrj {
149838fd1498Szrj struct find_typenames_t ft;
149938fd1498Szrj ft.p_set = new hash_set<tree>;
150038fd1498Szrj ft.typenames = NULL;
150138fd1498Szrj cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
150238fd1498Szrj find_typenames_r, &ft, ft.p_set);
150338fd1498Szrj delete ft.p_set;
150438fd1498Szrj return ft.typenames;
150538fd1498Szrj }
150638fd1498Szrj
150738fd1498Szrj /* Output the "[with ...]" clause for a template instantiation T iff
150838fd1498Szrj TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if
150938fd1498Szrj formatting a deduction/substitution diagnostic rather than an
151038fd1498Szrj instantiation. */
151138fd1498Szrj
151238fd1498Szrj static void
dump_substitution(cxx_pretty_printer * pp,tree t,tree template_parms,tree template_args,int flags)151338fd1498Szrj dump_substitution (cxx_pretty_printer *pp,
151438fd1498Szrj tree t, tree template_parms, tree template_args,
151538fd1498Szrj int flags)
151638fd1498Szrj {
151738fd1498Szrj if (template_parms != NULL_TREE && template_args != NULL_TREE
151838fd1498Szrj && !(flags & TFF_NO_TEMPLATE_BINDINGS))
151938fd1498Szrj {
152038fd1498Szrj vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
152138fd1498Szrj pp_cxx_whitespace (pp);
152238fd1498Szrj pp_cxx_left_bracket (pp);
152338fd1498Szrj pp->translate_string ("with");
152438fd1498Szrj pp_cxx_whitespace (pp);
152538fd1498Szrj dump_template_bindings (pp, template_parms, template_args, typenames);
152638fd1498Szrj pp_cxx_right_bracket (pp);
152738fd1498Szrj }
152838fd1498Szrj }
152938fd1498Szrj
153038fd1498Szrj /* Dump the lambda function FN including its 'mutable' qualifier and any
153138fd1498Szrj template bindings. */
153238fd1498Szrj
153338fd1498Szrj static void
dump_lambda_function(cxx_pretty_printer * pp,tree fn,tree template_parms,tree template_args,int flags)153438fd1498Szrj dump_lambda_function (cxx_pretty_printer *pp,
153538fd1498Szrj tree fn, tree template_parms, tree template_args,
153638fd1498Szrj int flags)
153738fd1498Szrj {
153838fd1498Szrj /* A lambda's signature is essentially its "type". */
153938fd1498Szrj dump_type (pp, DECL_CONTEXT (fn), flags);
154038fd1498Szrj if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST))
154138fd1498Szrj {
154238fd1498Szrj pp->padding = pp_before;
154338fd1498Szrj pp_c_ws_string (pp, "mutable");
154438fd1498Szrj }
154538fd1498Szrj dump_substitution (pp, fn, template_parms, template_args, flags);
154638fd1498Szrj }
154738fd1498Szrj
154838fd1498Szrj /* Pretty print a function decl. There are several ways we want to print a
154938fd1498Szrj function declaration. The TFF_ bits in FLAGS tells us how to behave.
155038fd1498Szrj As error can only apply the '#' flag once to give 0 and 1 for V, there
155138fd1498Szrj is %D which doesn't print the throw specs, and %F which does. */
155238fd1498Szrj
155338fd1498Szrj static void
dump_function_decl(cxx_pretty_printer * pp,tree t,int flags)155438fd1498Szrj dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
155538fd1498Szrj {
155638fd1498Szrj tree fntype;
155738fd1498Szrj tree parmtypes;
155838fd1498Szrj tree cname = NULL_TREE;
155938fd1498Szrj tree template_args = NULL_TREE;
156038fd1498Szrj tree template_parms = NULL_TREE;
156138fd1498Szrj int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
156238fd1498Szrj int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
156338fd1498Szrj tree exceptions;
156438fd1498Szrj bool constexpr_p;
156538fd1498Szrj tree ret = NULL_TREE;
156638fd1498Szrj
156738fd1498Szrj flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
156838fd1498Szrj if (TREE_CODE (t) == TEMPLATE_DECL)
156938fd1498Szrj t = DECL_TEMPLATE_RESULT (t);
157038fd1498Szrj
157138fd1498Szrj /* Save the exceptions, in case t is a specialization and we are
157238fd1498Szrj emitting an error about incompatible specifications. */
157338fd1498Szrj exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
157438fd1498Szrj
157538fd1498Szrj /* Likewise for the constexpr specifier, in case t is a specialization. */
157638fd1498Szrj constexpr_p = DECL_DECLARED_CONSTEXPR_P (t);
157738fd1498Szrj
157838fd1498Szrj /* Pretty print template instantiations only. */
157938fd1498Szrj if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
158038fd1498Szrj && !(flags & TFF_NO_TEMPLATE_BINDINGS)
158138fd1498Szrj && flag_pretty_templates)
158238fd1498Szrj {
158338fd1498Szrj tree tmpl;
158438fd1498Szrj
158538fd1498Szrj template_args = DECL_TI_ARGS (t);
158638fd1498Szrj tmpl = most_general_template (t);
158738fd1498Szrj if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
158838fd1498Szrj {
158938fd1498Szrj template_parms = DECL_TEMPLATE_PARMS (tmpl);
159038fd1498Szrj t = tmpl;
159138fd1498Szrj }
159238fd1498Szrj }
159338fd1498Szrj
159438fd1498Szrj if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
159538fd1498Szrj return dump_lambda_function (pp, t, template_parms, template_args, flags);
159638fd1498Szrj
159738fd1498Szrj fntype = TREE_TYPE (t);
159838fd1498Szrj parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
159938fd1498Szrj
160038fd1498Szrj if (DECL_CLASS_SCOPE_P (t))
160138fd1498Szrj cname = DECL_CONTEXT (t);
160238fd1498Szrj /* This is for partially instantiated template methods. */
160338fd1498Szrj else if (TREE_CODE (fntype) == METHOD_TYPE)
160438fd1498Szrj cname = TREE_TYPE (TREE_VALUE (parmtypes));
160538fd1498Szrj
160638fd1498Szrj if (flags & TFF_DECL_SPECIFIERS)
160738fd1498Szrj {
160838fd1498Szrj if (DECL_STATIC_FUNCTION_P (t))
160938fd1498Szrj pp_cxx_ws_string (pp, "static");
161038fd1498Szrj else if (DECL_VIRTUAL_P (t))
161138fd1498Szrj pp_cxx_ws_string (pp, "virtual");
161238fd1498Szrj
161338fd1498Szrj if (constexpr_p)
161438fd1498Szrj {
161538fd1498Szrj if (DECL_DECLARED_CONCEPT_P (t))
161638fd1498Szrj pp_cxx_ws_string (pp, "concept");
161738fd1498Szrj else
161838fd1498Szrj pp_cxx_ws_string (pp, "constexpr");
161938fd1498Szrj }
162038fd1498Szrj }
162138fd1498Szrj
162238fd1498Szrj /* Print the return type? */
162338fd1498Szrj if (show_return)
162438fd1498Szrj show_return = (!DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t)
162538fd1498Szrj && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t));
162638fd1498Szrj if (show_return)
162738fd1498Szrj {
162838fd1498Szrj ret = fndecl_declared_return_type (t);
162938fd1498Szrj dump_type_prefix (pp, ret, flags);
163038fd1498Szrj }
163138fd1498Szrj
163238fd1498Szrj /* Print the function name. */
163338fd1498Szrj if (!do_outer_scope)
163438fd1498Szrj /* Nothing. */;
163538fd1498Szrj else if (cname)
163638fd1498Szrj {
163738fd1498Szrj dump_type (pp, cname, flags);
163838fd1498Szrj pp_cxx_colon_colon (pp);
163938fd1498Szrj }
164038fd1498Szrj else
164138fd1498Szrj dump_scope (pp, CP_DECL_CONTEXT (t), flags);
164238fd1498Szrj
164338fd1498Szrj dump_function_name (pp, t, flags);
164438fd1498Szrj
164538fd1498Szrj if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
164638fd1498Szrj {
164738fd1498Szrj dump_parameters (pp, parmtypes, flags);
164838fd1498Szrj
164938fd1498Szrj if (TREE_CODE (fntype) == METHOD_TYPE)
165038fd1498Szrj {
165138fd1498Szrj pp->padding = pp_before;
165238fd1498Szrj pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
165338fd1498Szrj dump_ref_qualifier (pp, fntype, flags);
165438fd1498Szrj }
165538fd1498Szrj
165638fd1498Szrj if (tx_safe_fn_type_p (fntype))
165738fd1498Szrj {
165838fd1498Szrj pp->padding = pp_before;
165938fd1498Szrj pp_cxx_ws_string (pp, "transaction_safe");
166038fd1498Szrj }
166138fd1498Szrj
166238fd1498Szrj if (flags & TFF_EXCEPTION_SPECIFICATION)
166338fd1498Szrj {
166438fd1498Szrj pp->padding = pp_before;
166538fd1498Szrj dump_exception_spec (pp, exceptions, flags);
166638fd1498Szrj }
166738fd1498Szrj
166838fd1498Szrj if (show_return)
166938fd1498Szrj dump_type_suffix (pp, ret, flags);
167038fd1498Szrj else if (deduction_guide_p (t))
167138fd1498Szrj {
167238fd1498Szrj pp_cxx_ws_string (pp, "->");
167338fd1498Szrj dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
167438fd1498Szrj }
167538fd1498Szrj
167638fd1498Szrj if (flag_concepts)
167738fd1498Szrj if (tree ci = get_constraints (t))
167838fd1498Szrj if (tree reqs = CI_DECLARATOR_REQS (ci))
167938fd1498Szrj pp_cxx_requires_clause (pp, reqs);
168038fd1498Szrj
168138fd1498Szrj dump_substitution (pp, t, template_parms, template_args, flags);
168238fd1498Szrj
168338fd1498Szrj if (tree base = DECL_INHERITED_CTOR_BASE (t))
168438fd1498Szrj {
168538fd1498Szrj pp_cxx_ws_string (pp, "[inherited from");
168638fd1498Szrj dump_type (pp, base, TFF_PLAIN_IDENTIFIER);
168738fd1498Szrj pp_character (pp, ']');
168838fd1498Szrj }
168938fd1498Szrj }
169038fd1498Szrj else if (template_args)
169138fd1498Szrj {
169238fd1498Szrj bool need_comma = false;
169338fd1498Szrj int i;
169438fd1498Szrj pp_cxx_begin_template_argument_list (pp);
169538fd1498Szrj template_args = INNERMOST_TEMPLATE_ARGS (template_args);
169638fd1498Szrj for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i)
169738fd1498Szrj {
169838fd1498Szrj tree arg = TREE_VEC_ELT (template_args, i);
169938fd1498Szrj if (need_comma)
170038fd1498Szrj pp_separate_with_comma (pp);
170138fd1498Szrj if (ARGUMENT_PACK_P (arg))
170238fd1498Szrj pp_cxx_left_brace (pp);
170338fd1498Szrj dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
170438fd1498Szrj if (ARGUMENT_PACK_P (arg))
170538fd1498Szrj pp_cxx_right_brace (pp);
170638fd1498Szrj need_comma = true;
170738fd1498Szrj }
170838fd1498Szrj pp_cxx_end_template_argument_list (pp);
170938fd1498Szrj }
171038fd1498Szrj }
171138fd1498Szrj
171238fd1498Szrj /* Print a parameter list. If this is for a member function, the
171338fd1498Szrj member object ptr (and any other hidden args) should have
171438fd1498Szrj already been removed. */
171538fd1498Szrj
171638fd1498Szrj static void
dump_parameters(cxx_pretty_printer * pp,tree parmtypes,int flags)171738fd1498Szrj dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags)
171838fd1498Szrj {
171938fd1498Szrj int first = 1;
172038fd1498Szrj flags &= ~TFF_SCOPE;
172138fd1498Szrj pp_cxx_left_paren (pp);
172238fd1498Szrj
172338fd1498Szrj for (first = 1; parmtypes != void_list_node;
172438fd1498Szrj parmtypes = TREE_CHAIN (parmtypes))
172538fd1498Szrj {
172638fd1498Szrj if (!first)
172738fd1498Szrj pp_separate_with_comma (pp);
172838fd1498Szrj first = 0;
172938fd1498Szrj if (!parmtypes)
173038fd1498Szrj {
173138fd1498Szrj pp_cxx_ws_string (pp, "...");
173238fd1498Szrj break;
173338fd1498Szrj }
173438fd1498Szrj
173538fd1498Szrj dump_type (pp, TREE_VALUE (parmtypes), flags);
173638fd1498Szrj
173738fd1498Szrj if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
173838fd1498Szrj {
173938fd1498Szrj pp_cxx_whitespace (pp);
174038fd1498Szrj pp_equal (pp);
174138fd1498Szrj pp_cxx_whitespace (pp);
174238fd1498Szrj dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
174338fd1498Szrj }
174438fd1498Szrj }
174538fd1498Szrj
174638fd1498Szrj pp_cxx_right_paren (pp);
174738fd1498Szrj }
174838fd1498Szrj
174938fd1498Szrj /* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
175038fd1498Szrj
175138fd1498Szrj static void
dump_ref_qualifier(cxx_pretty_printer * pp,tree t,int flags ATTRIBUTE_UNUSED)175238fd1498Szrj dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED)
175338fd1498Szrj {
175438fd1498Szrj if (FUNCTION_REF_QUALIFIED (t))
175538fd1498Szrj {
175638fd1498Szrj pp->padding = pp_before;
175738fd1498Szrj if (FUNCTION_RVALUE_QUALIFIED (t))
175838fd1498Szrj pp_cxx_ws_string (pp, "&&");
175938fd1498Szrj else
176038fd1498Szrj pp_cxx_ws_string (pp, "&");
176138fd1498Szrj }
176238fd1498Szrj }
176338fd1498Szrj
176438fd1498Szrj /* Print an exception specification. T is the exception specification. */
176538fd1498Szrj
176638fd1498Szrj static void
dump_exception_spec(cxx_pretty_printer * pp,tree t,int flags)176738fd1498Szrj dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
176838fd1498Szrj {
176938fd1498Szrj if (t && TREE_PURPOSE (t))
177038fd1498Szrj {
177138fd1498Szrj pp_cxx_ws_string (pp, "noexcept");
177238fd1498Szrj if (!integer_onep (TREE_PURPOSE (t)))
177338fd1498Szrj {
177438fd1498Szrj pp_cxx_whitespace (pp);
177538fd1498Szrj pp_cxx_left_paren (pp);
177638fd1498Szrj if (DEFERRED_NOEXCEPT_SPEC_P (t))
177738fd1498Szrj pp_cxx_ws_string (pp, "<uninstantiated>");
177838fd1498Szrj else
177938fd1498Szrj dump_expr (pp, TREE_PURPOSE (t), flags);
178038fd1498Szrj pp_cxx_right_paren (pp);
178138fd1498Szrj }
178238fd1498Szrj }
178338fd1498Szrj else if (t)
178438fd1498Szrj {
178538fd1498Szrj pp_cxx_ws_string (pp, "throw");
178638fd1498Szrj pp_cxx_whitespace (pp);
178738fd1498Szrj pp_cxx_left_paren (pp);
178838fd1498Szrj if (TREE_VALUE (t) != NULL_TREE)
178938fd1498Szrj while (1)
179038fd1498Szrj {
179138fd1498Szrj dump_type (pp, TREE_VALUE (t), flags);
179238fd1498Szrj t = TREE_CHAIN (t);
179338fd1498Szrj if (!t)
179438fd1498Szrj break;
179538fd1498Szrj pp_separate_with_comma (pp);
179638fd1498Szrj }
179738fd1498Szrj pp_cxx_right_paren (pp);
179838fd1498Szrj }
179938fd1498Szrj }
180038fd1498Szrj
180138fd1498Szrj /* Handle the function name for a FUNCTION_DECL node, grokking operators
180238fd1498Szrj and destructors properly. */
180338fd1498Szrj
180438fd1498Szrj static void
dump_function_name(cxx_pretty_printer * pp,tree t,int flags)180538fd1498Szrj dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
180638fd1498Szrj {
180738fd1498Szrj tree name = DECL_NAME (t);
180838fd1498Szrj
180938fd1498Szrj /* We can get here with a decl that was synthesized by language-
181038fd1498Szrj independent machinery (e.g. coverage.c) in which case it won't
181138fd1498Szrj have a lang_specific structure attached and DECL_CONSTRUCTOR_P
181238fd1498Szrj will crash. In this case it is safe just to print out the
181338fd1498Szrj literal name. */
181438fd1498Szrj if (!DECL_LANG_SPECIFIC (t))
181538fd1498Szrj {
181638fd1498Szrj pp_cxx_tree_identifier (pp, name);
181738fd1498Szrj return;
181838fd1498Szrj }
181938fd1498Szrj
182038fd1498Szrj if (TREE_CODE (t) == TEMPLATE_DECL)
182138fd1498Szrj t = DECL_TEMPLATE_RESULT (t);
182238fd1498Szrj
182338fd1498Szrj /* Don't let the user see __comp_ctor et al. */
182438fd1498Szrj if (DECL_CONSTRUCTOR_P (t)
182538fd1498Szrj || DECL_DESTRUCTOR_P (t))
182638fd1498Szrj {
182738fd1498Szrj if (LAMBDA_TYPE_P (DECL_CONTEXT (t)))
182838fd1498Szrj name = get_identifier ("<lambda>");
182938fd1498Szrj else if (TYPE_UNNAMED_P (DECL_CONTEXT (t)))
183038fd1498Szrj name = get_identifier ("<constructor>");
183138fd1498Szrj else
183238fd1498Szrj name = constructor_name (DECL_CONTEXT (t));
183338fd1498Szrj }
183438fd1498Szrj
183538fd1498Szrj if (DECL_DESTRUCTOR_P (t))
183638fd1498Szrj {
183738fd1498Szrj pp_cxx_complement (pp);
183838fd1498Szrj dump_decl (pp, name, TFF_PLAIN_IDENTIFIER);
183938fd1498Szrj }
184038fd1498Szrj else if (DECL_CONV_FN_P (t))
184138fd1498Szrj {
184238fd1498Szrj /* This cannot use the hack that the operator's return
184338fd1498Szrj type is stashed off of its name because it may be
184438fd1498Szrj used for error reporting. In the case of conflicting
184538fd1498Szrj declarations, both will have the same name, yet
184638fd1498Szrj the types will be different, hence the TREE_TYPE field
184738fd1498Szrj of the first name will be clobbered by the second. */
184838fd1498Szrj pp_cxx_ws_string (pp, "operator");
184938fd1498Szrj dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
185038fd1498Szrj }
185138fd1498Szrj else
185238fd1498Szrj dump_decl (pp, name, flags);
185338fd1498Szrj
185438fd1498Szrj if (DECL_TEMPLATE_INFO (t)
185538fd1498Szrj && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
185638fd1498Szrj && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
185738fd1498Szrj || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
185838fd1498Szrj dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t),
185938fd1498Szrj flags);
186038fd1498Szrj }
186138fd1498Szrj
186238fd1498Szrj /* Dump the template parameters from the template info INFO under control of
186338fd1498Szrj FLAGS. PRIMARY indicates whether this is a primary template decl, or
186438fd1498Szrj specialization (partial or complete). For partial specializations we show
186538fd1498Szrj the specialized parameter values. For a primary template we show no
186638fd1498Szrj decoration. */
186738fd1498Szrj
186838fd1498Szrj static void
dump_template_parms(cxx_pretty_printer * pp,tree info,int primary,int flags)186938fd1498Szrj dump_template_parms (cxx_pretty_printer *pp, tree info,
187038fd1498Szrj int primary, int flags)
187138fd1498Szrj {
187238fd1498Szrj tree args = info ? TI_ARGS (info) : NULL_TREE;
187338fd1498Szrj
187438fd1498Szrj if (primary && flags & TFF_TEMPLATE_NAME)
187538fd1498Szrj return;
187638fd1498Szrj flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
187738fd1498Szrj pp_cxx_begin_template_argument_list (pp);
187838fd1498Szrj
187938fd1498Szrj /* Be careful only to print things when we have them, so as not
188038fd1498Szrj to crash producing error messages. */
188138fd1498Szrj if (args && !primary)
188238fd1498Szrj {
188338fd1498Szrj int len, ix;
188438fd1498Szrj len = get_non_default_template_args_count (args, flags);
188538fd1498Szrj
188638fd1498Szrj args = INNERMOST_TEMPLATE_ARGS (args);
188738fd1498Szrj for (ix = 0; ix != len; ix++)
188838fd1498Szrj {
188938fd1498Szrj tree arg = TREE_VEC_ELT (args, ix);
189038fd1498Szrj
189138fd1498Szrj /* Only print a comma if we know there is an argument coming. In
189238fd1498Szrj the case of an empty template argument pack, no actual
189338fd1498Szrj argument will be printed. */
189438fd1498Szrj if (ix
189538fd1498Szrj && (!ARGUMENT_PACK_P (arg)
189638fd1498Szrj || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
189738fd1498Szrj pp_separate_with_comma (pp);
189838fd1498Szrj
189938fd1498Szrj if (!arg)
190038fd1498Szrj pp_string (pp, M_("<template parameter error>"));
190138fd1498Szrj else
190238fd1498Szrj dump_template_argument (pp, arg, flags);
190338fd1498Szrj }
190438fd1498Szrj }
190538fd1498Szrj else if (primary)
190638fd1498Szrj {
190738fd1498Szrj tree tpl = TI_TEMPLATE (info);
190838fd1498Szrj tree parms = DECL_TEMPLATE_PARMS (tpl);
190938fd1498Szrj int len, ix;
191038fd1498Szrj
191138fd1498Szrj parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
191238fd1498Szrj len = parms ? TREE_VEC_LENGTH (parms) : 0;
191338fd1498Szrj
191438fd1498Szrj for (ix = 0; ix != len; ix++)
191538fd1498Szrj {
191638fd1498Szrj tree parm;
191738fd1498Szrj
191838fd1498Szrj if (TREE_VEC_ELT (parms, ix) == error_mark_node)
191938fd1498Szrj {
192038fd1498Szrj pp_string (pp, M_("<template parameter error>"));
192138fd1498Szrj continue;
192238fd1498Szrj }
192338fd1498Szrj
192438fd1498Szrj parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
192538fd1498Szrj
192638fd1498Szrj if (ix)
192738fd1498Szrj pp_separate_with_comma (pp);
192838fd1498Szrj
192938fd1498Szrj dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS);
193038fd1498Szrj }
193138fd1498Szrj }
193238fd1498Szrj pp_cxx_end_template_argument_list (pp);
193338fd1498Szrj }
193438fd1498Szrj
193538fd1498Szrj /* Print out the arguments of CALL_EXPR T as a parenthesized list using
193638fd1498Szrj flags FLAGS. Skip over the first argument if SKIPFIRST is true. */
193738fd1498Szrj
193838fd1498Szrj static void
dump_call_expr_args(cxx_pretty_printer * pp,tree t,int flags,bool skipfirst)193938fd1498Szrj dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
194038fd1498Szrj {
194138fd1498Szrj tree arg;
194238fd1498Szrj call_expr_arg_iterator iter;
194338fd1498Szrj
194438fd1498Szrj pp_cxx_left_paren (pp);
194538fd1498Szrj FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
194638fd1498Szrj {
194738fd1498Szrj if (skipfirst)
194838fd1498Szrj skipfirst = false;
194938fd1498Szrj else
195038fd1498Szrj {
195138fd1498Szrj dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
195238fd1498Szrj if (more_call_expr_args_p (&iter))
195338fd1498Szrj pp_separate_with_comma (pp);
195438fd1498Szrj }
195538fd1498Szrj }
195638fd1498Szrj pp_cxx_right_paren (pp);
195738fd1498Szrj }
195838fd1498Szrj
195938fd1498Szrj /* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
196038fd1498Szrj using flags FLAGS. Skip over the first argument if SKIPFIRST is
196138fd1498Szrj true. */
196238fd1498Szrj
196338fd1498Szrj static void
dump_aggr_init_expr_args(cxx_pretty_printer * pp,tree t,int flags,bool skipfirst)196438fd1498Szrj dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags,
196538fd1498Szrj bool skipfirst)
196638fd1498Szrj {
196738fd1498Szrj tree arg;
196838fd1498Szrj aggr_init_expr_arg_iterator iter;
196938fd1498Szrj
197038fd1498Szrj pp_cxx_left_paren (pp);
197138fd1498Szrj FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
197238fd1498Szrj {
197338fd1498Szrj if (skipfirst)
197438fd1498Szrj skipfirst = false;
197538fd1498Szrj else
197638fd1498Szrj {
197738fd1498Szrj dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
197838fd1498Szrj if (more_aggr_init_expr_args_p (&iter))
197938fd1498Szrj pp_separate_with_comma (pp);
198038fd1498Szrj }
198138fd1498Szrj }
198238fd1498Szrj pp_cxx_right_paren (pp);
198338fd1498Szrj }
198438fd1498Szrj
198538fd1498Szrj /* Print out a list of initializers (subr of dump_expr). */
198638fd1498Szrj
198738fd1498Szrj static void
dump_expr_list(cxx_pretty_printer * pp,tree l,int flags)198838fd1498Szrj dump_expr_list (cxx_pretty_printer *pp, tree l, int flags)
198938fd1498Szrj {
199038fd1498Szrj while (l)
199138fd1498Szrj {
199238fd1498Szrj dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
199338fd1498Szrj l = TREE_CHAIN (l);
199438fd1498Szrj if (l)
199538fd1498Szrj pp_separate_with_comma (pp);
199638fd1498Szrj }
199738fd1498Szrj }
199838fd1498Szrj
199938fd1498Szrj /* Print out a vector of initializers (subr of dump_expr). */
200038fd1498Szrj
200138fd1498Szrj static void
dump_expr_init_vec(cxx_pretty_printer * pp,vec<constructor_elt,va_gc> * v,int flags)200238fd1498Szrj dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v,
200338fd1498Szrj int flags)
200438fd1498Szrj {
200538fd1498Szrj unsigned HOST_WIDE_INT idx;
200638fd1498Szrj tree value;
200738fd1498Szrj
200838fd1498Szrj FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
200938fd1498Szrj {
201038fd1498Szrj dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
201138fd1498Szrj if (idx != v->length () - 1)
201238fd1498Szrj pp_separate_with_comma (pp);
201338fd1498Szrj }
201438fd1498Szrj }
201538fd1498Szrj
201638fd1498Szrj
201738fd1498Szrj /* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual
201838fd1498Szrj function. Resolve it to a close relative -- in the sense of static
201938fd1498Szrj type -- variant being overridden. That is close to what was written in
202038fd1498Szrj the source code. Subroutine of dump_expr. */
202138fd1498Szrj
202238fd1498Szrj static tree
resolve_virtual_fun_from_obj_type_ref(tree ref)202338fd1498Szrj resolve_virtual_fun_from_obj_type_ref (tree ref)
202438fd1498Szrj {
202538fd1498Szrj tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref));
202638fd1498Szrj HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
202738fd1498Szrj tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
202838fd1498Szrj while (index)
202938fd1498Szrj {
203038fd1498Szrj fun = TREE_CHAIN (fun);
203138fd1498Szrj index -= (TARGET_VTABLE_USES_DESCRIPTORS
203238fd1498Szrj ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
203338fd1498Szrj }
203438fd1498Szrj
203538fd1498Szrj return BV_FN (fun);
203638fd1498Szrj }
203738fd1498Szrj
203838fd1498Szrj /* Print out an expression E under control of FLAGS. */
203938fd1498Szrj
204038fd1498Szrj static void
dump_expr(cxx_pretty_printer * pp,tree t,int flags)204138fd1498Szrj dump_expr (cxx_pretty_printer *pp, tree t, int flags)
204238fd1498Szrj {
204338fd1498Szrj tree op;
204438fd1498Szrj
204538fd1498Szrj if (t == 0)
204638fd1498Szrj return;
204738fd1498Szrj
204838fd1498Szrj if (STATEMENT_CLASS_P (t))
204938fd1498Szrj {
205038fd1498Szrj pp_cxx_ws_string (pp, M_("<statement>"));
205138fd1498Szrj return;
205238fd1498Szrj }
205338fd1498Szrj
205438fd1498Szrj switch (TREE_CODE (t))
205538fd1498Szrj {
205638fd1498Szrj case VAR_DECL:
205738fd1498Szrj case PARM_DECL:
205838fd1498Szrj case FIELD_DECL:
205938fd1498Szrj case CONST_DECL:
206038fd1498Szrj case FUNCTION_DECL:
206138fd1498Szrj case TEMPLATE_DECL:
206238fd1498Szrj case NAMESPACE_DECL:
206338fd1498Szrj case LABEL_DECL:
206438fd1498Szrj case OVERLOAD:
206538fd1498Szrj case TYPE_DECL:
206638fd1498Szrj case IDENTIFIER_NODE:
206738fd1498Szrj dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
206838fd1498Szrj |TFF_TEMPLATE_HEADER))
206938fd1498Szrj | TFF_NO_TEMPLATE_BINDINGS
207038fd1498Szrj | TFF_NO_FUNCTION_ARGUMENTS));
207138fd1498Szrj break;
207238fd1498Szrj
207338fd1498Szrj case SSA_NAME:
207438fd1498Szrj if (SSA_NAME_VAR (t)
207538fd1498Szrj && !DECL_ARTIFICIAL (SSA_NAME_VAR (t)))
207638fd1498Szrj dump_expr (pp, SSA_NAME_VAR (t), flags);
207738fd1498Szrj else
207838fd1498Szrj pp_cxx_ws_string (pp, M_("<unknown>"));
207938fd1498Szrj break;
208038fd1498Szrj
208138fd1498Szrj case VOID_CST:
208238fd1498Szrj case INTEGER_CST:
208338fd1498Szrj case REAL_CST:
208438fd1498Szrj case STRING_CST:
208538fd1498Szrj case COMPLEX_CST:
208638fd1498Szrj pp->constant (t);
208738fd1498Szrj break;
208838fd1498Szrj
208938fd1498Szrj case USERDEF_LITERAL:
209038fd1498Szrj pp_cxx_userdef_literal (pp, t);
209138fd1498Szrj break;
209238fd1498Szrj
209338fd1498Szrj case THROW_EXPR:
209438fd1498Szrj /* While waiting for caret diagnostics, avoid printing
209538fd1498Szrj __cxa_allocate_exception, __cxa_throw, and the like. */
209638fd1498Szrj pp_cxx_ws_string (pp, M_("<throw-expression>"));
209738fd1498Szrj break;
209838fd1498Szrj
209938fd1498Szrj case PTRMEM_CST:
210038fd1498Szrj pp_ampersand (pp);
210138fd1498Szrj dump_type (pp, PTRMEM_CST_CLASS (t), flags);
210238fd1498Szrj pp_cxx_colon_colon (pp);
210338fd1498Szrj pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
210438fd1498Szrj break;
210538fd1498Szrj
210638fd1498Szrj case COMPOUND_EXPR:
210738fd1498Szrj pp_cxx_left_paren (pp);
210838fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
210938fd1498Szrj pp_separate_with_comma (pp);
211038fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
211138fd1498Szrj pp_cxx_right_paren (pp);
211238fd1498Szrj break;
211338fd1498Szrj
211438fd1498Szrj case COND_EXPR:
211538fd1498Szrj case VEC_COND_EXPR:
211638fd1498Szrj pp_cxx_left_paren (pp);
211738fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
211838fd1498Szrj pp_string (pp, " ? ");
211938fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
212038fd1498Szrj pp_string (pp, " : ");
212138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
212238fd1498Szrj pp_cxx_right_paren (pp);
212338fd1498Szrj break;
212438fd1498Szrj
212538fd1498Szrj case SAVE_EXPR:
212638fd1498Szrj if (TREE_HAS_CONSTRUCTOR (t))
212738fd1498Szrj {
212838fd1498Szrj pp_cxx_ws_string (pp, "new");
212938fd1498Szrj pp_cxx_whitespace (pp);
213038fd1498Szrj dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
213138fd1498Szrj }
213238fd1498Szrj else
213338fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
213438fd1498Szrj break;
213538fd1498Szrj
213638fd1498Szrj case AGGR_INIT_EXPR:
213738fd1498Szrj {
213838fd1498Szrj tree fn = NULL_TREE;
213938fd1498Szrj
214038fd1498Szrj if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR)
214138fd1498Szrj fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0);
214238fd1498Szrj
214338fd1498Szrj if (fn && TREE_CODE (fn) == FUNCTION_DECL)
214438fd1498Szrj {
214538fd1498Szrj if (DECL_CONSTRUCTOR_P (fn))
214638fd1498Szrj dump_type (pp, DECL_CONTEXT (fn), flags);
214738fd1498Szrj else
214838fd1498Szrj dump_decl (pp, fn, 0);
214938fd1498Szrj }
215038fd1498Szrj else
215138fd1498Szrj dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0);
215238fd1498Szrj }
215338fd1498Szrj dump_aggr_init_expr_args (pp, t, flags, true);
215438fd1498Szrj break;
215538fd1498Szrj
215638fd1498Szrj case CALL_EXPR:
215738fd1498Szrj {
215838fd1498Szrj tree fn = CALL_EXPR_FN (t);
215938fd1498Szrj bool skipfirst = false;
216038fd1498Szrj
216138fd1498Szrj /* Deal with internal functions. */
216238fd1498Szrj if (fn == NULL_TREE)
216338fd1498Szrj {
216438fd1498Szrj pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
216538fd1498Szrj dump_call_expr_args (pp, t, flags, skipfirst);
216638fd1498Szrj break;
216738fd1498Szrj }
216838fd1498Szrj
216938fd1498Szrj if (TREE_CODE (fn) == ADDR_EXPR)
217038fd1498Szrj fn = TREE_OPERAND (fn, 0);
217138fd1498Szrj
217238fd1498Szrj /* Nobody is interested in seeing the guts of vcalls. */
217338fd1498Szrj if (TREE_CODE (fn) == OBJ_TYPE_REF)
217438fd1498Szrj fn = resolve_virtual_fun_from_obj_type_ref (fn);
217538fd1498Szrj
217638fd1498Szrj if (TREE_TYPE (fn) != NULL_TREE
217738fd1498Szrj && NEXT_CODE (fn) == METHOD_TYPE
217838fd1498Szrj && call_expr_nargs (t))
217938fd1498Szrj {
218038fd1498Szrj tree ob = CALL_EXPR_ARG (t, 0);
218138fd1498Szrj if (TREE_CODE (ob) == ADDR_EXPR)
218238fd1498Szrj {
218338fd1498Szrj dump_expr (pp, TREE_OPERAND (ob, 0),
218438fd1498Szrj flags | TFF_EXPR_IN_PARENS);
218538fd1498Szrj pp_cxx_dot (pp);
218638fd1498Szrj }
218738fd1498Szrj else if (!is_this_parameter (ob))
218838fd1498Szrj {
218938fd1498Szrj dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
219038fd1498Szrj pp_cxx_arrow (pp);
219138fd1498Szrj }
219238fd1498Szrj skipfirst = true;
219338fd1498Szrj }
219438fd1498Szrj if (flag_sanitize & SANITIZE_UNDEFINED
219538fd1498Szrj && is_ubsan_builtin_p (fn))
219638fd1498Szrj {
219738fd1498Szrj pp_string (cxx_pp, M_("<ubsan routine call>"));
219838fd1498Szrj break;
219938fd1498Szrj }
220038fd1498Szrj dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
220138fd1498Szrj dump_call_expr_args (pp, t, flags, skipfirst);
220238fd1498Szrj }
220338fd1498Szrj break;
220438fd1498Szrj
220538fd1498Szrj case TARGET_EXPR:
220638fd1498Szrj /* Note that this only works for G++ target exprs. If somebody
220738fd1498Szrj builds a general TARGET_EXPR, there's no way to represent that
220838fd1498Szrj it initializes anything other that the parameter slot for the
220938fd1498Szrj default argument. Note we may have cleared out the first
221038fd1498Szrj operand in expand_expr, so don't go killing ourselves. */
221138fd1498Szrj if (TREE_OPERAND (t, 1))
221238fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
221338fd1498Szrj break;
221438fd1498Szrj
221538fd1498Szrj case POINTER_PLUS_EXPR:
221638fd1498Szrj dump_binary_op (pp, "+", t, flags);
221738fd1498Szrj break;
221838fd1498Szrj
221938fd1498Szrj case POINTER_DIFF_EXPR:
222038fd1498Szrj dump_binary_op (pp, "-", t, flags);
222138fd1498Szrj break;
222238fd1498Szrj
222338fd1498Szrj case INIT_EXPR:
222438fd1498Szrj case MODIFY_EXPR:
222538fd1498Szrj dump_binary_op (pp, OVL_OP_INFO (true, NOP_EXPR)->name, t, flags);
222638fd1498Szrj break;
222738fd1498Szrj
222838fd1498Szrj case PLUS_EXPR:
222938fd1498Szrj case MINUS_EXPR:
223038fd1498Szrj case MULT_EXPR:
223138fd1498Szrj case TRUNC_DIV_EXPR:
223238fd1498Szrj case TRUNC_MOD_EXPR:
223338fd1498Szrj case MIN_EXPR:
223438fd1498Szrj case MAX_EXPR:
223538fd1498Szrj case LSHIFT_EXPR:
223638fd1498Szrj case RSHIFT_EXPR:
223738fd1498Szrj case BIT_IOR_EXPR:
223838fd1498Szrj case BIT_XOR_EXPR:
223938fd1498Szrj case BIT_AND_EXPR:
224038fd1498Szrj case TRUTH_ANDIF_EXPR:
224138fd1498Szrj case TRUTH_ORIF_EXPR:
224238fd1498Szrj case LT_EXPR:
224338fd1498Szrj case LE_EXPR:
224438fd1498Szrj case GT_EXPR:
224538fd1498Szrj case GE_EXPR:
224638fd1498Szrj case EQ_EXPR:
224738fd1498Szrj case NE_EXPR:
224838fd1498Szrj case EXACT_DIV_EXPR:
224938fd1498Szrj dump_binary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
225038fd1498Szrj break;
225138fd1498Szrj
225238fd1498Szrj case CEIL_DIV_EXPR:
225338fd1498Szrj case FLOOR_DIV_EXPR:
225438fd1498Szrj case ROUND_DIV_EXPR:
225538fd1498Szrj case RDIV_EXPR:
225638fd1498Szrj dump_binary_op (pp, "/", t, flags);
225738fd1498Szrj break;
225838fd1498Szrj
225938fd1498Szrj case CEIL_MOD_EXPR:
226038fd1498Szrj case FLOOR_MOD_EXPR:
226138fd1498Szrj case ROUND_MOD_EXPR:
226238fd1498Szrj dump_binary_op (pp, "%", t, flags);
226338fd1498Szrj break;
226438fd1498Szrj
226538fd1498Szrj case COMPONENT_REF:
226638fd1498Szrj {
226738fd1498Szrj tree ob = TREE_OPERAND (t, 0);
226838fd1498Szrj if (INDIRECT_REF_P (ob))
226938fd1498Szrj {
227038fd1498Szrj ob = TREE_OPERAND (ob, 0);
227138fd1498Szrj if (!is_this_parameter (ob))
227238fd1498Szrj {
227338fd1498Szrj dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
227438fd1498Szrj if (TREE_CODE (TREE_TYPE (ob)) == REFERENCE_TYPE)
227538fd1498Szrj pp_cxx_dot (pp);
227638fd1498Szrj else
227738fd1498Szrj pp_cxx_arrow (pp);
227838fd1498Szrj }
227938fd1498Szrj }
228038fd1498Szrj else
228138fd1498Szrj {
228238fd1498Szrj dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
228338fd1498Szrj if (TREE_CODE (ob) != ARROW_EXPR)
228438fd1498Szrj pp_cxx_dot (pp);
228538fd1498Szrj }
228638fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
228738fd1498Szrj }
228838fd1498Szrj break;
228938fd1498Szrj
229038fd1498Szrj case ARRAY_REF:
229138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
229238fd1498Szrj pp_cxx_left_bracket (pp);
229338fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
229438fd1498Szrj pp_cxx_right_bracket (pp);
229538fd1498Szrj break;
229638fd1498Szrj
229738fd1498Szrj case UNARY_PLUS_EXPR:
229838fd1498Szrj dump_unary_op (pp, "+", t, flags);
229938fd1498Szrj break;
230038fd1498Szrj
230138fd1498Szrj case ADDR_EXPR:
230238fd1498Szrj if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
230338fd1498Szrj || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
230438fd1498Szrj /* An ADDR_EXPR can have reference type. In that case, we
230538fd1498Szrj shouldn't print the `&' doing so indicates to the user
230638fd1498Szrj that the expression has pointer type. */
230738fd1498Szrj || (TREE_TYPE (t)
230838fd1498Szrj && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
230938fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
231038fd1498Szrj else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
231138fd1498Szrj dump_unary_op (pp, "&&", t, flags);
231238fd1498Szrj else
231338fd1498Szrj dump_unary_op (pp, "&", t, flags);
231438fd1498Szrj break;
231538fd1498Szrj
231638fd1498Szrj case INDIRECT_REF:
231738fd1498Szrj if (TREE_HAS_CONSTRUCTOR (t))
231838fd1498Szrj {
231938fd1498Szrj t = TREE_OPERAND (t, 0);
232038fd1498Szrj gcc_assert (TREE_CODE (t) == CALL_EXPR);
232138fd1498Szrj dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
232238fd1498Szrj dump_call_expr_args (pp, t, flags, true);
232338fd1498Szrj }
232438fd1498Szrj else
232538fd1498Szrj {
232638fd1498Szrj if (TREE_OPERAND (t,0) != NULL_TREE
232738fd1498Szrj && TREE_TYPE (TREE_OPERAND (t, 0))
232838fd1498Szrj && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
232938fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
233038fd1498Szrj else
233138fd1498Szrj dump_unary_op (pp, "*", t, flags);
233238fd1498Szrj }
233338fd1498Szrj break;
233438fd1498Szrj
233538fd1498Szrj case MEM_REF:
233638fd1498Szrj if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
233738fd1498Szrj && integer_zerop (TREE_OPERAND (t, 1)))
233838fd1498Szrj dump_expr (pp, TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags);
233938fd1498Szrj else
234038fd1498Szrj {
234138fd1498Szrj pp_cxx_star (pp);
234238fd1498Szrj if (!integer_zerop (TREE_OPERAND (t, 1)))
234338fd1498Szrj {
234438fd1498Szrj pp_cxx_left_paren (pp);
234538fd1498Szrj if (!integer_onep (TYPE_SIZE_UNIT
234638fd1498Szrj (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))))))
234738fd1498Szrj {
234838fd1498Szrj pp_cxx_left_paren (pp);
234938fd1498Szrj dump_type (pp, ptr_type_node, flags);
235038fd1498Szrj pp_cxx_right_paren (pp);
235138fd1498Szrj }
235238fd1498Szrj }
235338fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
235438fd1498Szrj if (!integer_zerop (TREE_OPERAND (t, 1)))
235538fd1498Szrj {
235638fd1498Szrj pp_cxx_ws_string (pp, "+");
235738fd1498Szrj dump_expr (pp, fold_convert (ssizetype, TREE_OPERAND (t, 1)),
235838fd1498Szrj flags);
235938fd1498Szrj pp_cxx_right_paren (pp);
236038fd1498Szrj }
236138fd1498Szrj }
236238fd1498Szrj break;
236338fd1498Szrj
236438fd1498Szrj case NEGATE_EXPR:
236538fd1498Szrj case BIT_NOT_EXPR:
236638fd1498Szrj case TRUTH_NOT_EXPR:
236738fd1498Szrj case PREDECREMENT_EXPR:
236838fd1498Szrj case PREINCREMENT_EXPR:
236938fd1498Szrj dump_unary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
237038fd1498Szrj break;
237138fd1498Szrj
237238fd1498Szrj case POSTDECREMENT_EXPR:
237338fd1498Szrj case POSTINCREMENT_EXPR:
237438fd1498Szrj pp_cxx_left_paren (pp);
237538fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
237638fd1498Szrj pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
237738fd1498Szrj pp_cxx_right_paren (pp);
237838fd1498Szrj break;
237938fd1498Szrj
238038fd1498Szrj case NON_LVALUE_EXPR:
238138fd1498Szrj /* FIXME: This is a KLUDGE workaround for a parsing problem. There
238238fd1498Szrj should be another level of INDIRECT_REF so that I don't have to do
238338fd1498Szrj this. */
238438fd1498Szrj if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
238538fd1498Szrj {
238638fd1498Szrj tree next = TREE_TYPE (TREE_TYPE (t));
238738fd1498Szrj
238838fd1498Szrj while (TYPE_PTR_P (next))
238938fd1498Szrj next = TREE_TYPE (next);
239038fd1498Szrj
239138fd1498Szrj if (TREE_CODE (next) == FUNCTION_TYPE)
239238fd1498Szrj {
239338fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
239438fd1498Szrj pp_cxx_left_paren (pp);
239538fd1498Szrj pp_cxx_star (pp);
239638fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
239738fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
239838fd1498Szrj pp_cxx_right_paren (pp);
239938fd1498Szrj break;
240038fd1498Szrj }
240138fd1498Szrj /* Else fall through. */
240238fd1498Szrj }
240338fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
240438fd1498Szrj break;
240538fd1498Szrj
240638fd1498Szrj CASE_CONVERT:
240738fd1498Szrj case IMPLICIT_CONV_EXPR:
240838fd1498Szrj case VIEW_CONVERT_EXPR:
240938fd1498Szrj {
241038fd1498Szrj tree op = TREE_OPERAND (t, 0);
241138fd1498Szrj tree ttype = TREE_TYPE (t);
241238fd1498Szrj tree optype = TREE_TYPE (op);
241338fd1498Szrj
241438fd1498Szrj if (TREE_CODE (ttype) != TREE_CODE (optype)
241538fd1498Szrj && POINTER_TYPE_P (ttype)
241638fd1498Szrj && POINTER_TYPE_P (optype)
241738fd1498Szrj && same_type_p (TREE_TYPE (optype),
241838fd1498Szrj TREE_TYPE (ttype)))
241938fd1498Szrj {
242038fd1498Szrj if (TREE_CODE (ttype) == REFERENCE_TYPE)
242138fd1498Szrj {
242238fd1498Szrj STRIP_NOPS (op);
242338fd1498Szrj if (TREE_CODE (op) == ADDR_EXPR)
242438fd1498Szrj dump_expr (pp, TREE_OPERAND (op, 0), flags);
242538fd1498Szrj else
242638fd1498Szrj dump_unary_op (pp, "*", t, flags);
242738fd1498Szrj }
242838fd1498Szrj else
242938fd1498Szrj dump_unary_op (pp, "&", t, flags);
243038fd1498Szrj }
243138fd1498Szrj else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
243238fd1498Szrj {
243338fd1498Szrj /* It is a cast, but we cannot tell whether it is a
243438fd1498Szrj reinterpret or static cast. Use the C style notation. */
243538fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
243638fd1498Szrj pp_cxx_left_paren (pp);
243738fd1498Szrj pp_cxx_left_paren (pp);
243838fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
243938fd1498Szrj pp_cxx_right_paren (pp);
244038fd1498Szrj dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS);
244138fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
244238fd1498Szrj pp_cxx_right_paren (pp);
244338fd1498Szrj }
244438fd1498Szrj else
244538fd1498Szrj dump_expr (pp, op, flags);
244638fd1498Szrj break;
244738fd1498Szrj }
244838fd1498Szrj
244938fd1498Szrj case CONSTRUCTOR:
245038fd1498Szrj if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
245138fd1498Szrj {
245238fd1498Szrj tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
245338fd1498Szrj
245438fd1498Szrj if (integer_zerop (idx))
245538fd1498Szrj {
245638fd1498Szrj /* A NULL pointer-to-member constant. */
245738fd1498Szrj pp_cxx_left_paren (pp);
245838fd1498Szrj pp_cxx_left_paren (pp);
245938fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
246038fd1498Szrj pp_cxx_right_paren (pp);
246138fd1498Szrj pp_character (pp, '0');
246238fd1498Szrj pp_cxx_right_paren (pp);
246338fd1498Szrj break;
246438fd1498Szrj }
246538fd1498Szrj else if (tree_fits_shwi_p (idx))
246638fd1498Szrj {
246738fd1498Szrj tree virtuals;
246838fd1498Szrj unsigned HOST_WIDE_INT n;
246938fd1498Szrj
247038fd1498Szrj t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
247138fd1498Szrj t = TYPE_METHOD_BASETYPE (t);
247238fd1498Szrj virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
247338fd1498Szrj
247438fd1498Szrj n = tree_to_shwi (idx);
247538fd1498Szrj
247638fd1498Szrj /* Map vtable index back one, to allow for the null pointer to
247738fd1498Szrj member. */
247838fd1498Szrj --n;
247938fd1498Szrj
248038fd1498Szrj while (n > 0 && virtuals)
248138fd1498Szrj {
248238fd1498Szrj --n;
248338fd1498Szrj virtuals = TREE_CHAIN (virtuals);
248438fd1498Szrj }
248538fd1498Szrj if (virtuals)
248638fd1498Szrj {
248738fd1498Szrj dump_expr (pp, BV_FN (virtuals),
248838fd1498Szrj flags | TFF_EXPR_IN_PARENS);
248938fd1498Szrj break;
249038fd1498Szrj }
249138fd1498Szrj }
249238fd1498Szrj }
249338fd1498Szrj if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
249438fd1498Szrj pp_string (pp, "<lambda closure object>");
249538fd1498Szrj if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
249638fd1498Szrj {
249738fd1498Szrj dump_type (pp, TREE_TYPE (t), 0);
249838fd1498Szrj pp_cxx_left_paren (pp);
249938fd1498Szrj pp_cxx_right_paren (pp);
250038fd1498Szrj }
250138fd1498Szrj else
250238fd1498Szrj {
250338fd1498Szrj if (!BRACE_ENCLOSED_INITIALIZER_P (t))
250438fd1498Szrj dump_type (pp, TREE_TYPE (t), 0);
250538fd1498Szrj pp_cxx_left_brace (pp);
250638fd1498Szrj dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags);
250738fd1498Szrj pp_cxx_right_brace (pp);
250838fd1498Szrj }
250938fd1498Szrj
251038fd1498Szrj break;
251138fd1498Szrj
251238fd1498Szrj case OFFSET_REF:
251338fd1498Szrj {
251438fd1498Szrj tree ob = TREE_OPERAND (t, 0);
251538fd1498Szrj if (is_dummy_object (ob))
251638fd1498Szrj {
251738fd1498Szrj t = TREE_OPERAND (t, 1);
251838fd1498Szrj if (TREE_CODE (t) == FUNCTION_DECL)
251938fd1498Szrj /* A::f */
252038fd1498Szrj dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS);
252138fd1498Szrj else if (BASELINK_P (t))
252238fd1498Szrj dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)),
252338fd1498Szrj flags | TFF_EXPR_IN_PARENS);
252438fd1498Szrj else
252538fd1498Szrj dump_decl (pp, t, flags);
252638fd1498Szrj }
252738fd1498Szrj else
252838fd1498Szrj {
252938fd1498Szrj if (INDIRECT_REF_P (ob))
253038fd1498Szrj {
253138fd1498Szrj dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
253238fd1498Szrj pp_cxx_arrow (pp);
253338fd1498Szrj pp_cxx_star (pp);
253438fd1498Szrj }
253538fd1498Szrj else
253638fd1498Szrj {
253738fd1498Szrj dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
253838fd1498Szrj pp_cxx_dot (pp);
253938fd1498Szrj pp_cxx_star (pp);
254038fd1498Szrj }
254138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
254238fd1498Szrj }
254338fd1498Szrj break;
254438fd1498Szrj }
254538fd1498Szrj
254638fd1498Szrj case TEMPLATE_PARM_INDEX:
254738fd1498Szrj dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
254838fd1498Szrj break;
254938fd1498Szrj
255038fd1498Szrj case CAST_EXPR:
255138fd1498Szrj if (TREE_OPERAND (t, 0) == NULL_TREE
255238fd1498Szrj || TREE_CHAIN (TREE_OPERAND (t, 0)))
255338fd1498Szrj {
255438fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
255538fd1498Szrj pp_cxx_left_paren (pp);
255638fd1498Szrj dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
255738fd1498Szrj pp_cxx_right_paren (pp);
255838fd1498Szrj }
255938fd1498Szrj else
256038fd1498Szrj {
256138fd1498Szrj pp_cxx_left_paren (pp);
256238fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
256338fd1498Szrj pp_cxx_right_paren (pp);
256438fd1498Szrj pp_cxx_left_paren (pp);
256538fd1498Szrj dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
256638fd1498Szrj pp_cxx_right_paren (pp);
256738fd1498Szrj }
256838fd1498Szrj break;
256938fd1498Szrj
257038fd1498Szrj case STATIC_CAST_EXPR:
257138fd1498Szrj pp_cxx_ws_string (pp, "static_cast");
257238fd1498Szrj goto cast;
257338fd1498Szrj case REINTERPRET_CAST_EXPR:
257438fd1498Szrj pp_cxx_ws_string (pp, "reinterpret_cast");
257538fd1498Szrj goto cast;
257638fd1498Szrj case CONST_CAST_EXPR:
257738fd1498Szrj pp_cxx_ws_string (pp, "const_cast");
257838fd1498Szrj goto cast;
257938fd1498Szrj case DYNAMIC_CAST_EXPR:
258038fd1498Szrj pp_cxx_ws_string (pp, "dynamic_cast");
258138fd1498Szrj cast:
258238fd1498Szrj pp_cxx_begin_template_argument_list (pp);
258338fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
258438fd1498Szrj pp_cxx_end_template_argument_list (pp);
258538fd1498Szrj pp_cxx_left_paren (pp);
258638fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
258738fd1498Szrj pp_cxx_right_paren (pp);
258838fd1498Szrj break;
258938fd1498Szrj
259038fd1498Szrj case ARROW_EXPR:
259138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
259238fd1498Szrj pp_cxx_arrow (pp);
259338fd1498Szrj break;
259438fd1498Szrj
259538fd1498Szrj case SIZEOF_EXPR:
259638fd1498Szrj case ALIGNOF_EXPR:
259738fd1498Szrj if (TREE_CODE (t) == SIZEOF_EXPR)
259838fd1498Szrj pp_cxx_ws_string (pp, "sizeof");
259938fd1498Szrj else
260038fd1498Szrj {
260138fd1498Szrj gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR);
260238fd1498Szrj pp_cxx_ws_string (pp, "__alignof__");
260338fd1498Szrj }
260438fd1498Szrj op = TREE_OPERAND (t, 0);
260538fd1498Szrj if (PACK_EXPANSION_P (op))
260638fd1498Szrj {
260738fd1498Szrj pp_string (pp, "...");
260838fd1498Szrj op = PACK_EXPANSION_PATTERN (op);
260938fd1498Szrj }
261038fd1498Szrj pp_cxx_whitespace (pp);
261138fd1498Szrj pp_cxx_left_paren (pp);
261238fd1498Szrj if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
261338fd1498Szrj dump_type (pp, TREE_TYPE (op), flags);
261438fd1498Szrj else if (TYPE_P (TREE_OPERAND (t, 0)))
261538fd1498Szrj dump_type (pp, op, flags);
261638fd1498Szrj else
261738fd1498Szrj dump_expr (pp, op, flags);
261838fd1498Szrj pp_cxx_right_paren (pp);
261938fd1498Szrj break;
262038fd1498Szrj
262138fd1498Szrj case AT_ENCODE_EXPR:
262238fd1498Szrj pp_cxx_ws_string (pp, "@encode");
262338fd1498Szrj pp_cxx_whitespace (pp);
262438fd1498Szrj pp_cxx_left_paren (pp);
262538fd1498Szrj dump_type (pp, TREE_OPERAND (t, 0), flags);
262638fd1498Szrj pp_cxx_right_paren (pp);
262738fd1498Szrj break;
262838fd1498Szrj
262938fd1498Szrj case NOEXCEPT_EXPR:
263038fd1498Szrj pp_cxx_ws_string (pp, "noexcept");
263138fd1498Szrj pp_cxx_whitespace (pp);
263238fd1498Szrj pp_cxx_left_paren (pp);
263338fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
263438fd1498Szrj pp_cxx_right_paren (pp);
263538fd1498Szrj break;
263638fd1498Szrj
263738fd1498Szrj case REALPART_EXPR:
263838fd1498Szrj case IMAGPART_EXPR:
263938fd1498Szrj pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
264038fd1498Szrj pp_cxx_whitespace (pp);
264138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
264238fd1498Szrj break;
264338fd1498Szrj
264438fd1498Szrj case DEFAULT_ARG:
264538fd1498Szrj pp_string (pp, M_("<unparsed>"));
264638fd1498Szrj break;
264738fd1498Szrj
264838fd1498Szrj case TRY_CATCH_EXPR:
264938fd1498Szrj case CLEANUP_POINT_EXPR:
265038fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
265138fd1498Szrj break;
265238fd1498Szrj
265338fd1498Szrj case PSEUDO_DTOR_EXPR:
265438fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
265538fd1498Szrj pp_cxx_dot (pp);
265638fd1498Szrj if (TREE_OPERAND (t, 1))
265738fd1498Szrj {
265838fd1498Szrj dump_type (pp, TREE_OPERAND (t, 1), flags);
265938fd1498Szrj pp_cxx_colon_colon (pp);
266038fd1498Szrj }
266138fd1498Szrj pp_cxx_complement (pp);
266238fd1498Szrj dump_type (pp, TREE_OPERAND (t, 2), flags);
266338fd1498Szrj break;
266438fd1498Szrj
266538fd1498Szrj case TEMPLATE_ID_EXPR:
266638fd1498Szrj dump_decl (pp, t, flags);
266738fd1498Szrj break;
266838fd1498Szrj
266938fd1498Szrj case BIND_EXPR:
267038fd1498Szrj case STMT_EXPR:
267138fd1498Szrj case EXPR_STMT:
267238fd1498Szrj case STATEMENT_LIST:
267338fd1498Szrj /* We don't yet have a way of dumping statements in a
267438fd1498Szrj human-readable format. */
267538fd1498Szrj pp_string (pp, "({...})");
267638fd1498Szrj break;
267738fd1498Szrj
267838fd1498Szrj case LOOP_EXPR:
267938fd1498Szrj pp_string (pp, "while (1) { ");
268038fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
268138fd1498Szrj pp_cxx_right_brace (pp);
268238fd1498Szrj break;
268338fd1498Szrj
268438fd1498Szrj case EXIT_EXPR:
268538fd1498Szrj pp_string (pp, "if (");
268638fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
268738fd1498Szrj pp_string (pp, ") break; ");
268838fd1498Szrj break;
268938fd1498Szrj
269038fd1498Szrj case BASELINK:
269138fd1498Szrj dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
269238fd1498Szrj break;
269338fd1498Szrj
269438fd1498Szrj case EMPTY_CLASS_EXPR:
269538fd1498Szrj dump_type (pp, TREE_TYPE (t), flags);
269638fd1498Szrj pp_cxx_left_paren (pp);
269738fd1498Szrj pp_cxx_right_paren (pp);
269838fd1498Szrj break;
269938fd1498Szrj
270038fd1498Szrj case NON_DEPENDENT_EXPR:
270138fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags);
270238fd1498Szrj break;
270338fd1498Szrj
270438fd1498Szrj case ARGUMENT_PACK_SELECT:
270538fd1498Szrj dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
270638fd1498Szrj break;
270738fd1498Szrj
270838fd1498Szrj case RECORD_TYPE:
270938fd1498Szrj case UNION_TYPE:
271038fd1498Szrj case ENUMERAL_TYPE:
271138fd1498Szrj case REAL_TYPE:
271238fd1498Szrj case VOID_TYPE:
271338fd1498Szrj case BOOLEAN_TYPE:
271438fd1498Szrj case INTEGER_TYPE:
271538fd1498Szrj case COMPLEX_TYPE:
271638fd1498Szrj case VECTOR_TYPE:
271738fd1498Szrj case DECLTYPE_TYPE:
271838fd1498Szrj pp_type_specifier_seq (pp, t);
271938fd1498Szrj break;
272038fd1498Szrj
272138fd1498Szrj case TYPENAME_TYPE:
272238fd1498Szrj /* We get here when we want to print a dependent type as an
272338fd1498Szrj id-expression, without any disambiguator decoration. */
272438fd1498Szrj pp->id_expression (t);
272538fd1498Szrj break;
272638fd1498Szrj
272738fd1498Szrj case TEMPLATE_TYPE_PARM:
272838fd1498Szrj case TEMPLATE_TEMPLATE_PARM:
272938fd1498Szrj case BOUND_TEMPLATE_TEMPLATE_PARM:
273038fd1498Szrj dump_type (pp, t, flags);
273138fd1498Szrj break;
273238fd1498Szrj
273338fd1498Szrj case TRAIT_EXPR:
273438fd1498Szrj pp_cxx_trait_expression (pp, t);
273538fd1498Szrj break;
273638fd1498Szrj
273738fd1498Szrj case VA_ARG_EXPR:
273838fd1498Szrj pp_cxx_va_arg_expression (pp, t);
273938fd1498Szrj break;
274038fd1498Szrj
274138fd1498Szrj case OFFSETOF_EXPR:
274238fd1498Szrj pp_cxx_offsetof_expression (pp, t);
274338fd1498Szrj break;
274438fd1498Szrj
274538fd1498Szrj case ADDRESSOF_EXPR:
274638fd1498Szrj pp_cxx_addressof_expression (pp, t);
274738fd1498Szrj break;
274838fd1498Szrj
274938fd1498Szrj case SCOPE_REF:
275038fd1498Szrj dump_decl (pp, t, flags);
275138fd1498Szrj break;
275238fd1498Szrj
275338fd1498Szrj case EXPR_PACK_EXPANSION:
275438fd1498Szrj case UNARY_LEFT_FOLD_EXPR:
275538fd1498Szrj case UNARY_RIGHT_FOLD_EXPR:
275638fd1498Szrj case BINARY_LEFT_FOLD_EXPR:
275738fd1498Szrj case BINARY_RIGHT_FOLD_EXPR:
275838fd1498Szrj case TYPEID_EXPR:
275938fd1498Szrj case MEMBER_REF:
276038fd1498Szrj case DOTSTAR_EXPR:
276138fd1498Szrj case NEW_EXPR:
276238fd1498Szrj case VEC_NEW_EXPR:
276338fd1498Szrj case DELETE_EXPR:
276438fd1498Szrj case VEC_DELETE_EXPR:
276538fd1498Szrj case MODOP_EXPR:
276638fd1498Szrj case ABS_EXPR:
276738fd1498Szrj case CONJ_EXPR:
276838fd1498Szrj case VECTOR_CST:
276938fd1498Szrj case FIXED_CST:
277038fd1498Szrj case UNORDERED_EXPR:
277138fd1498Szrj case ORDERED_EXPR:
277238fd1498Szrj case UNLT_EXPR:
277338fd1498Szrj case UNLE_EXPR:
277438fd1498Szrj case UNGT_EXPR:
277538fd1498Szrj case UNGE_EXPR:
277638fd1498Szrj case UNEQ_EXPR:
277738fd1498Szrj case LTGT_EXPR:
277838fd1498Szrj case COMPLEX_EXPR:
277938fd1498Szrj case BIT_FIELD_REF:
278038fd1498Szrj case FIX_TRUNC_EXPR:
278138fd1498Szrj case FLOAT_EXPR:
278238fd1498Szrj pp->expression (t);
278338fd1498Szrj break;
278438fd1498Szrj
278538fd1498Szrj case TRUTH_AND_EXPR:
278638fd1498Szrj case TRUTH_OR_EXPR:
278738fd1498Szrj case TRUTH_XOR_EXPR:
278838fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
278938fd1498Szrj pp_cxx_left_paren (pp);
279038fd1498Szrj pp->expression (t);
279138fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
279238fd1498Szrj pp_cxx_right_paren (pp);
279338fd1498Szrj break;
279438fd1498Szrj
279538fd1498Szrj case OBJ_TYPE_REF:
279638fd1498Szrj dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags);
279738fd1498Szrj break;
279838fd1498Szrj
279938fd1498Szrj case LAMBDA_EXPR:
280038fd1498Szrj pp_string (pp, M_("<lambda>"));
280138fd1498Szrj break;
280238fd1498Szrj
280338fd1498Szrj case PAREN_EXPR:
280438fd1498Szrj pp_cxx_left_paren (pp);
280538fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
280638fd1498Szrj pp_cxx_right_paren (pp);
280738fd1498Szrj break;
280838fd1498Szrj
280938fd1498Szrj case REQUIRES_EXPR:
281038fd1498Szrj pp_cxx_requires_expr (cxx_pp, t);
281138fd1498Szrj break;
281238fd1498Szrj
281338fd1498Szrj case SIMPLE_REQ:
281438fd1498Szrj pp_cxx_simple_requirement (cxx_pp, t);
281538fd1498Szrj break;
281638fd1498Szrj
281738fd1498Szrj case TYPE_REQ:
281838fd1498Szrj pp_cxx_type_requirement (cxx_pp, t);
281938fd1498Szrj break;
282038fd1498Szrj
282138fd1498Szrj case COMPOUND_REQ:
282238fd1498Szrj pp_cxx_compound_requirement (cxx_pp, t);
282338fd1498Szrj break;
282438fd1498Szrj
282538fd1498Szrj case NESTED_REQ:
282638fd1498Szrj pp_cxx_nested_requirement (cxx_pp, t);
282738fd1498Szrj break;
282838fd1498Szrj
282938fd1498Szrj case PRED_CONSTR:
283038fd1498Szrj case CHECK_CONSTR:
283138fd1498Szrj case EXPR_CONSTR:
283238fd1498Szrj case TYPE_CONSTR:
283338fd1498Szrj case ICONV_CONSTR:
283438fd1498Szrj case DEDUCT_CONSTR:
283538fd1498Szrj case EXCEPT_CONSTR:
283638fd1498Szrj case PARM_CONSTR:
283738fd1498Szrj case CONJ_CONSTR:
283838fd1498Szrj case DISJ_CONSTR:
283938fd1498Szrj pp_cxx_constraint (cxx_pp, t);
284038fd1498Szrj break;
284138fd1498Szrj
284238fd1498Szrj case PLACEHOLDER_EXPR:
284338fd1498Szrj pp_string (pp, M_("*this"));
284438fd1498Szrj break;
284538fd1498Szrj
284638fd1498Szrj case TREE_LIST:
284738fd1498Szrj dump_expr_list (pp, t, flags);
284838fd1498Szrj break;
284938fd1498Szrj
285038fd1498Szrj /* This list is incomplete, but should suffice for now.
285138fd1498Szrj It is very important that `sorry' does not call
285238fd1498Szrj `report_error_function'. That could cause an infinite loop. */
285338fd1498Szrj default:
285438fd1498Szrj pp_unsupported_tree (pp, t);
285538fd1498Szrj /* Fall through. */
285638fd1498Szrj case ERROR_MARK:
285738fd1498Szrj pp_string (pp, M_("<expression error>"));
285838fd1498Szrj break;
285938fd1498Szrj }
286038fd1498Szrj }
286138fd1498Szrj
286238fd1498Szrj static void
dump_binary_op(cxx_pretty_printer * pp,const char * opstring,tree t,int flags)286338fd1498Szrj dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
286438fd1498Szrj int flags)
286538fd1498Szrj {
286638fd1498Szrj pp_cxx_left_paren (pp);
286738fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
286838fd1498Szrj pp_cxx_whitespace (pp);
286938fd1498Szrj if (opstring)
287038fd1498Szrj pp_cxx_ws_string (pp, opstring);
287138fd1498Szrj else
287238fd1498Szrj pp_string (pp, M_("<unknown operator>"));
287338fd1498Szrj pp_cxx_whitespace (pp);
287438fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
287538fd1498Szrj pp_cxx_right_paren (pp);
287638fd1498Szrj }
287738fd1498Szrj
287838fd1498Szrj static void
dump_unary_op(cxx_pretty_printer * pp,const char * opstring,tree t,int flags)287938fd1498Szrj dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags)
288038fd1498Szrj {
288138fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
288238fd1498Szrj pp_cxx_left_paren (pp);
288338fd1498Szrj pp_cxx_ws_string (pp, opstring);
288438fd1498Szrj dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
288538fd1498Szrj if (flags & TFF_EXPR_IN_PARENS)
288638fd1498Szrj pp_cxx_right_paren (pp);
288738fd1498Szrj }
288838fd1498Szrj
288938fd1498Szrj static void
reinit_cxx_pp(void)289038fd1498Szrj reinit_cxx_pp (void)
289138fd1498Szrj {
289238fd1498Szrj pp_clear_output_area (cxx_pp);
289338fd1498Szrj cxx_pp->padding = pp_none;
289438fd1498Szrj pp_indentation (cxx_pp) = 0;
289538fd1498Szrj pp_needs_newline (cxx_pp) = false;
289638fd1498Szrj cxx_pp->enclosing_scope = current_function_decl;
289738fd1498Szrj }
289838fd1498Szrj
289938fd1498Szrj /* Same as pp_formatted_text, except the return string is a separate
290038fd1498Szrj copy and has a GGC storage duration, e.g. an indefinite lifetime. */
290138fd1498Szrj
290238fd1498Szrj inline const char *
pp_ggc_formatted_text(pretty_printer * pp)290338fd1498Szrj pp_ggc_formatted_text (pretty_printer *pp)
290438fd1498Szrj {
290538fd1498Szrj return ggc_strdup (pp_formatted_text (pp));
290638fd1498Szrj }
290738fd1498Szrj
290838fd1498Szrj /* Exported interface to stringifying types, exprs and decls under TFF_*
290938fd1498Szrj control. */
291038fd1498Szrj
291138fd1498Szrj const char *
type_as_string(tree typ,int flags)291238fd1498Szrj type_as_string (tree typ, int flags)
291338fd1498Szrj {
291438fd1498Szrj reinit_cxx_pp ();
291538fd1498Szrj pp_translate_identifiers (cxx_pp) = false;
291638fd1498Szrj dump_type (cxx_pp, typ, flags);
291738fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
291838fd1498Szrj }
291938fd1498Szrj
292038fd1498Szrj const char *
type_as_string_translate(tree typ,int flags)292138fd1498Szrj type_as_string_translate (tree typ, int flags)
292238fd1498Szrj {
292338fd1498Szrj reinit_cxx_pp ();
292438fd1498Szrj dump_type (cxx_pp, typ, flags);
292538fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
292638fd1498Szrj }
292738fd1498Szrj
292838fd1498Szrj const char *
expr_as_string(tree decl,int flags)292938fd1498Szrj expr_as_string (tree decl, int flags)
293038fd1498Szrj {
293138fd1498Szrj reinit_cxx_pp ();
293238fd1498Szrj pp_translate_identifiers (cxx_pp) = false;
293338fd1498Szrj dump_expr (cxx_pp, decl, flags);
293438fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
293538fd1498Szrj }
293638fd1498Szrj
293738fd1498Szrj /* Wrap decl_as_string with options appropriate for dwarf. */
293838fd1498Szrj
293938fd1498Szrj const char *
decl_as_dwarf_string(tree decl,int flags)294038fd1498Szrj decl_as_dwarf_string (tree decl, int flags)
294138fd1498Szrj {
294238fd1498Szrj const char *name;
294338fd1498Szrj /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
294438fd1498Szrj here will be adequate to get the desired behavior. */
294538fd1498Szrj cxx_pp->flags |= pp_c_flag_gnu_v3;
294638fd1498Szrj name = decl_as_string (decl, flags);
294738fd1498Szrj /* Subsequent calls to the pretty printer shouldn't use this style. */
294838fd1498Szrj cxx_pp->flags &= ~pp_c_flag_gnu_v3;
294938fd1498Szrj return name;
295038fd1498Szrj }
295138fd1498Szrj
295238fd1498Szrj const char *
decl_as_string(tree decl,int flags)295338fd1498Szrj decl_as_string (tree decl, int flags)
295438fd1498Szrj {
295538fd1498Szrj reinit_cxx_pp ();
295638fd1498Szrj pp_translate_identifiers (cxx_pp) = false;
295738fd1498Szrj dump_decl (cxx_pp, decl, flags);
295838fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
295938fd1498Szrj }
296038fd1498Szrj
296138fd1498Szrj const char *
decl_as_string_translate(tree decl,int flags)296238fd1498Szrj decl_as_string_translate (tree decl, int flags)
296338fd1498Szrj {
296438fd1498Szrj reinit_cxx_pp ();
296538fd1498Szrj dump_decl (cxx_pp, decl, flags);
296638fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
296738fd1498Szrj }
296838fd1498Szrj
296938fd1498Szrj /* Wrap lang_decl_name with options appropriate for dwarf. */
297038fd1498Szrj
297138fd1498Szrj const char *
lang_decl_dwarf_name(tree decl,int v,bool translate)297238fd1498Szrj lang_decl_dwarf_name (tree decl, int v, bool translate)
297338fd1498Szrj {
297438fd1498Szrj const char *name;
297538fd1498Szrj /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
297638fd1498Szrj here will be adequate to get the desired behavior. */
297738fd1498Szrj cxx_pp->flags |= pp_c_flag_gnu_v3;
297838fd1498Szrj name = lang_decl_name (decl, v, translate);
297938fd1498Szrj /* Subsequent calls to the pretty printer shouldn't use this style. */
298038fd1498Szrj cxx_pp->flags &= ~pp_c_flag_gnu_v3;
298138fd1498Szrj return name;
298238fd1498Szrj }
298338fd1498Szrj
298438fd1498Szrj /* Generate the three forms of printable names for cxx_printable_name. */
298538fd1498Szrj
298638fd1498Szrj const char *
lang_decl_name(tree decl,int v,bool translate)298738fd1498Szrj lang_decl_name (tree decl, int v, bool translate)
298838fd1498Szrj {
298938fd1498Szrj if (v >= 2)
299038fd1498Szrj return (translate
299138fd1498Szrj ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS)
299238fd1498Szrj : decl_as_string (decl, TFF_DECL_SPECIFIERS));
299338fd1498Szrj
299438fd1498Szrj reinit_cxx_pp ();
299538fd1498Szrj pp_translate_identifiers (cxx_pp) = translate;
299638fd1498Szrj if (v == 1
299738fd1498Szrj && (DECL_CLASS_SCOPE_P (decl)
299838fd1498Szrj || (DECL_NAMESPACE_SCOPE_P (decl)
299938fd1498Szrj && CP_DECL_CONTEXT (decl) != global_namespace)))
300038fd1498Szrj {
300138fd1498Szrj dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
300238fd1498Szrj pp_cxx_colon_colon (cxx_pp);
300338fd1498Szrj }
300438fd1498Szrj
300538fd1498Szrj if (TREE_CODE (decl) == FUNCTION_DECL)
300638fd1498Szrj dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
300738fd1498Szrj else if ((DECL_NAME (decl) == NULL_TREE)
300838fd1498Szrj && TREE_CODE (decl) == NAMESPACE_DECL)
300938fd1498Szrj dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
301038fd1498Szrj else
301138fd1498Szrj dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
301238fd1498Szrj
301338fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
301438fd1498Szrj }
301538fd1498Szrj
301638fd1498Szrj /* Return the location of a tree passed to %+ formats. */
301738fd1498Szrj
301838fd1498Szrj location_t
location_of(tree t)301938fd1498Szrj location_of (tree t)
302038fd1498Szrj {
302138fd1498Szrj if (TYPE_P (t))
302238fd1498Szrj {
302338fd1498Szrj t = TYPE_MAIN_DECL (t);
302438fd1498Szrj if (t == NULL_TREE)
302538fd1498Szrj return input_location;
302638fd1498Szrj }
302738fd1498Szrj else if (TREE_CODE (t) == OVERLOAD)
302838fd1498Szrj t = OVL_FIRST (t);
302938fd1498Szrj
303038fd1498Szrj if (DECL_P (t))
303138fd1498Szrj return DECL_SOURCE_LOCATION (t);
303238fd1498Szrj if (TREE_CODE (t) == DEFAULT_ARG)
303338fd1498Szrj return defarg_location (t);
303438fd1498Szrj return EXPR_LOC_OR_LOC (t, input_location);
303538fd1498Szrj }
303638fd1498Szrj
303738fd1498Szrj /* Now the interfaces from error et al to dump_type et al. Each takes an
303838fd1498Szrj on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
303938fd1498Szrj function. */
304038fd1498Szrj
304138fd1498Szrj static const char *
decl_to_string(tree decl,int verbose)304238fd1498Szrj decl_to_string (tree decl, int verbose)
304338fd1498Szrj {
304438fd1498Szrj int flags = 0;
304538fd1498Szrj
304638fd1498Szrj if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
304738fd1498Szrj || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
304838fd1498Szrj flags = TFF_CLASS_KEY_OR_ENUM;
304938fd1498Szrj if (verbose)
305038fd1498Szrj flags |= TFF_DECL_SPECIFIERS;
305138fd1498Szrj else if (TREE_CODE (decl) == FUNCTION_DECL)
305238fd1498Szrj flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
305338fd1498Szrj flags |= TFF_TEMPLATE_HEADER;
305438fd1498Szrj
305538fd1498Szrj reinit_cxx_pp ();
305638fd1498Szrj dump_decl (cxx_pp, decl, flags);
305738fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
305838fd1498Szrj }
305938fd1498Szrj
306038fd1498Szrj static const char *
expr_to_string(tree decl)306138fd1498Szrj expr_to_string (tree decl)
306238fd1498Szrj {
306338fd1498Szrj reinit_cxx_pp ();
306438fd1498Szrj dump_expr (cxx_pp, decl, 0);
306538fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
306638fd1498Szrj }
306738fd1498Szrj
306838fd1498Szrj static const char *
fndecl_to_string(tree fndecl,int verbose)306938fd1498Szrj fndecl_to_string (tree fndecl, int verbose)
307038fd1498Szrj {
307138fd1498Szrj int flags;
307238fd1498Szrj
307338fd1498Szrj flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS
307438fd1498Szrj | TFF_TEMPLATE_HEADER;
307538fd1498Szrj if (verbose)
307638fd1498Szrj flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
307738fd1498Szrj reinit_cxx_pp ();
307838fd1498Szrj dump_decl (cxx_pp, fndecl, flags);
307938fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
308038fd1498Szrj }
308138fd1498Szrj
308238fd1498Szrj
308338fd1498Szrj static const char *
code_to_string(enum tree_code c)308438fd1498Szrj code_to_string (enum tree_code c)
308538fd1498Szrj {
308638fd1498Szrj return get_tree_code_name (c);
308738fd1498Szrj }
308838fd1498Szrj
308938fd1498Szrj const char *
language_to_string(enum languages c)309038fd1498Szrj language_to_string (enum languages c)
309138fd1498Szrj {
309238fd1498Szrj switch (c)
309338fd1498Szrj {
309438fd1498Szrj case lang_c:
309538fd1498Szrj return "C";
309638fd1498Szrj
309738fd1498Szrj case lang_cplusplus:
309838fd1498Szrj return "C++";
309938fd1498Szrj
310038fd1498Szrj default:
310138fd1498Szrj gcc_unreachable ();
310238fd1498Szrj }
310338fd1498Szrj return NULL;
310438fd1498Szrj }
310538fd1498Szrj
310638fd1498Szrj /* Return the proper printed version of a parameter to a C++ function. */
310738fd1498Szrj
310838fd1498Szrj static const char *
parm_to_string(int p)310938fd1498Szrj parm_to_string (int p)
311038fd1498Szrj {
311138fd1498Szrj reinit_cxx_pp ();
311238fd1498Szrj if (p < 0)
311338fd1498Szrj pp_string (cxx_pp, "'this'");
311438fd1498Szrj else
311538fd1498Szrj pp_decimal_int (cxx_pp, p + 1);
311638fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
311738fd1498Szrj }
311838fd1498Szrj
311938fd1498Szrj static const char *
op_to_string(bool assop,enum tree_code p)312038fd1498Szrj op_to_string (bool assop, enum tree_code p)
312138fd1498Szrj {
312238fd1498Szrj tree id = ovl_op_identifier (assop, p);
312338fd1498Szrj return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
312438fd1498Szrj }
312538fd1498Szrj
312638fd1498Szrj /* Return a GC-allocated representation of type TYP, with verbosity VERBOSE.
312738fd1498Szrj
312838fd1498Szrj If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the
312938fd1498Szrj string in appropriate places, and *QUOTE is written to with false
313038fd1498Szrj to suppress pp_format's trailing close quote so that e.g.
313138fd1498Szrj foo_typedef {aka underlying_foo} {enum}
313238fd1498Szrj can be printed by "%qT" as:
313338fd1498Szrj `foo_typedef' {aka `underlying_foo'} {enum}
313438fd1498Szrj rather than:
313538fd1498Szrj `foo_typedef {aka underlying_foo} {enum}'
313638fd1498Szrj When adding such quotes, if POSTPROCESSED is true (for handling %H and %I)
313738fd1498Szrj then a leading open quote will be added, whereas if POSTPROCESSED is false
313838fd1498Szrj (for handling %T) then any leading quote has already been added by
313938fd1498Szrj pp_format, or is not needed due to QUOTE being NULL (for template arguments
314038fd1498Szrj within %H and %I).
314138fd1498Szrj
314238fd1498Szrj SHOW_COLOR is used to determine the colorization of any quotes that
314338fd1498Szrj are added. */
314438fd1498Szrj
314538fd1498Szrj static const char *
type_to_string(tree typ,int verbose,bool postprocessed,bool * quote,bool show_color)314638fd1498Szrj type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
314738fd1498Szrj bool show_color)
314838fd1498Szrj {
314938fd1498Szrj int flags = 0;
315038fd1498Szrj if (verbose)
315138fd1498Szrj flags |= TFF_CLASS_KEY_OR_ENUM;
315238fd1498Szrj flags |= TFF_TEMPLATE_HEADER;
315338fd1498Szrj
315438fd1498Szrj reinit_cxx_pp ();
315538fd1498Szrj
315638fd1498Szrj if (postprocessed && quote && *quote)
315738fd1498Szrj pp_begin_quote (cxx_pp, show_color);
315838fd1498Szrj
315938fd1498Szrj struct obstack *ob = pp_buffer (cxx_pp)->obstack;
316038fd1498Szrj int type_start, type_len;
316138fd1498Szrj type_start = obstack_object_size (ob);
316238fd1498Szrj
316338fd1498Szrj dump_type (cxx_pp, typ, flags);
316438fd1498Szrj
316538fd1498Szrj /* Remember the end of the initial dump. */
316638fd1498Szrj type_len = obstack_object_size (ob) - type_start;
316738fd1498Szrj
316838fd1498Szrj /* If we're printing a type that involves typedefs, also print the
316938fd1498Szrj stripped version. But sometimes the stripped version looks
317038fd1498Szrj exactly the same, so we don't want it after all. To avoid printing
317138fd1498Szrj it in that case, we play ugly obstack games. */
317238fd1498Szrj if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ)
317338fd1498Szrj && !uses_template_parms (typ))
317438fd1498Szrj {
317538fd1498Szrj int aka_start, aka_len; char *p;
317638fd1498Szrj tree aka = strip_typedefs (typ);
317738fd1498Szrj if (quote && *quote)
317838fd1498Szrj pp_end_quote (cxx_pp, show_color);
317938fd1498Szrj pp_string (cxx_pp, " {aka");
318038fd1498Szrj pp_cxx_whitespace (cxx_pp);
318138fd1498Szrj if (quote && *quote)
318238fd1498Szrj pp_begin_quote (cxx_pp, show_color);
318338fd1498Szrj /* And remember the start of the aka dump. */
318438fd1498Szrj aka_start = obstack_object_size (ob);
318538fd1498Szrj dump_type (cxx_pp, aka, flags);
318638fd1498Szrj aka_len = obstack_object_size (ob) - aka_start;
318738fd1498Szrj if (quote && *quote)
318838fd1498Szrj pp_end_quote (cxx_pp, show_color);
318938fd1498Szrj pp_right_brace (cxx_pp);
319038fd1498Szrj p = (char*)obstack_base (ob);
319138fd1498Szrj /* If they are identical, cut off the aka by unwinding the obstack. */
319238fd1498Szrj if (type_len == aka_len
319338fd1498Szrj && memcmp (p + type_start, p+aka_start, type_len) == 0)
319438fd1498Szrj {
319538fd1498Szrj /* We can't add a '\0' here, since we may be adding a closing quote
319638fd1498Szrj below, and it would be hidden by the '\0'.
319738fd1498Szrj Instead, manually unwind the current object within the obstack
319838fd1498Szrj so that the insertion point is at the end of the type, before
319938fd1498Szrj the "' {aka". */
320038fd1498Szrj int delta = type_start + type_len - obstack_object_size (ob);
320138fd1498Szrj gcc_assert (delta <= 0);
320238fd1498Szrj obstack_blank_fast (ob, delta);
320338fd1498Szrj }
320438fd1498Szrj else
320538fd1498Szrj if (quote)
320638fd1498Szrj /* No further closing quotes are needed. */
320738fd1498Szrj *quote = false;
320838fd1498Szrj }
320938fd1498Szrj
321038fd1498Szrj if (quote && *quote)
321138fd1498Szrj {
321238fd1498Szrj pp_end_quote (cxx_pp, show_color);
321338fd1498Szrj *quote = false;
321438fd1498Szrj }
321538fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
321638fd1498Szrj }
321738fd1498Szrj
321838fd1498Szrj static const char *
args_to_string(tree p,int verbose)321938fd1498Szrj args_to_string (tree p, int verbose)
322038fd1498Szrj {
322138fd1498Szrj int flags = 0;
322238fd1498Szrj if (verbose)
322338fd1498Szrj flags |= TFF_CLASS_KEY_OR_ENUM;
322438fd1498Szrj
322538fd1498Szrj if (p == NULL_TREE)
322638fd1498Szrj return "";
322738fd1498Szrj
322838fd1498Szrj if (TYPE_P (TREE_VALUE (p)))
322938fd1498Szrj return type_as_string_translate (p, flags);
323038fd1498Szrj
323138fd1498Szrj reinit_cxx_pp ();
323238fd1498Szrj for (; p; p = TREE_CHAIN (p))
323338fd1498Szrj {
323438fd1498Szrj if (null_node_p (TREE_VALUE (p)))
323538fd1498Szrj pp_cxx_ws_string (cxx_pp, "NULL");
323638fd1498Szrj else
323738fd1498Szrj dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags);
323838fd1498Szrj if (TREE_CHAIN (p))
323938fd1498Szrj pp_separate_with_comma (cxx_pp);
324038fd1498Szrj }
324138fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
324238fd1498Szrj }
324338fd1498Szrj
324438fd1498Szrj /* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P
324538fd1498Szrj is a TREE_LIST with purpose the TEMPLATE_DECL, value the template
324638fd1498Szrj arguments. */
324738fd1498Szrj
324838fd1498Szrj static const char *
subst_to_string(tree p)324938fd1498Szrj subst_to_string (tree p)
325038fd1498Szrj {
325138fd1498Szrj tree decl = TREE_PURPOSE (p);
325238fd1498Szrj tree targs = TREE_VALUE (p);
325338fd1498Szrj tree tparms = DECL_TEMPLATE_PARMS (decl);
325438fd1498Szrj int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER
325538fd1498Szrj |TFF_NO_TEMPLATE_BINDINGS);
325638fd1498Szrj
325738fd1498Szrj if (p == NULL_TREE)
325838fd1498Szrj return "";
325938fd1498Szrj
326038fd1498Szrj reinit_cxx_pp ();
326138fd1498Szrj dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
326238fd1498Szrj dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
326338fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
326438fd1498Szrj }
326538fd1498Szrj
326638fd1498Szrj static const char *
cv_to_string(tree p,int v)326738fd1498Szrj cv_to_string (tree p, int v)
326838fd1498Szrj {
326938fd1498Szrj reinit_cxx_pp ();
327038fd1498Szrj cxx_pp->padding = v ? pp_before : pp_none;
327138fd1498Szrj pp_cxx_cv_qualifier_seq (cxx_pp, p);
327238fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
327338fd1498Szrj }
327438fd1498Szrj
327538fd1498Szrj static const char *
eh_spec_to_string(tree p,int)327638fd1498Szrj eh_spec_to_string (tree p, int /*v*/)
327738fd1498Szrj {
327838fd1498Szrj int flags = 0;
327938fd1498Szrj reinit_cxx_pp ();
328038fd1498Szrj dump_exception_spec (cxx_pp, p, flags);
328138fd1498Szrj return pp_ggc_formatted_text (cxx_pp);
328238fd1498Szrj }
328338fd1498Szrj
328438fd1498Szrj /* Langhook for print_error_function. */
328538fd1498Szrj void
cxx_print_error_function(diagnostic_context * context,const char * file,diagnostic_info * diagnostic)328638fd1498Szrj cxx_print_error_function (diagnostic_context *context, const char *file,
328738fd1498Szrj diagnostic_info *diagnostic)
328838fd1498Szrj {
3289*58e805e6Szrj char *prefix;
3290*58e805e6Szrj if (file)
3291*58e805e6Szrj prefix = xstrdup (file);
3292*58e805e6Szrj else
3293*58e805e6Szrj prefix = NULL;
329438fd1498Szrj lhd_print_error_function (context, file, diagnostic);
3295*58e805e6Szrj pp_set_prefix (context->printer, prefix);
329638fd1498Szrj maybe_print_instantiation_context (context);
329738fd1498Szrj }
329838fd1498Szrj
329938fd1498Szrj static void
cp_diagnostic_starter(diagnostic_context * context,diagnostic_info * diagnostic)330038fd1498Szrj cp_diagnostic_starter (diagnostic_context *context,
330138fd1498Szrj diagnostic_info *diagnostic)
330238fd1498Szrj {
330338fd1498Szrj diagnostic_report_current_module (context, diagnostic_location (diagnostic));
330438fd1498Szrj cp_print_error_function (context, diagnostic);
330538fd1498Szrj maybe_print_instantiation_context (context);
330638fd1498Szrj maybe_print_constexpr_context (context);
330738fd1498Szrj pp_set_prefix (context->printer, diagnostic_build_prefix (context,
330838fd1498Szrj diagnostic));
330938fd1498Szrj }
331038fd1498Szrj
331138fd1498Szrj /* Print current function onto BUFFER, in the process of reporting
331238fd1498Szrj a diagnostic message. Called from cp_diagnostic_starter. */
331338fd1498Szrj static void
cp_print_error_function(diagnostic_context * context,diagnostic_info * diagnostic)331438fd1498Szrj cp_print_error_function (diagnostic_context *context,
331538fd1498Szrj diagnostic_info *diagnostic)
331638fd1498Szrj {
331738fd1498Szrj /* If we are in an instantiation context, current_function_decl is likely
331838fd1498Szrj to be wrong, so just rely on print_instantiation_full_context. */
331938fd1498Szrj if (current_instantiation ())
332038fd1498Szrj return;
332138fd1498Szrj if (diagnostic_last_function_changed (context, diagnostic))
332238fd1498Szrj {
3323*58e805e6Szrj char *old_prefix = pp_take_prefix (context->printer);
332438fd1498Szrj const char *file = LOCATION_FILE (diagnostic_location (diagnostic));
332538fd1498Szrj tree abstract_origin = diagnostic_abstract_origin (diagnostic);
332638fd1498Szrj char *new_prefix = (file && abstract_origin == NULL)
332738fd1498Szrj ? file_name_as_prefix (context, file) : NULL;
332838fd1498Szrj
332938fd1498Szrj pp_set_prefix (context->printer, new_prefix);
333038fd1498Szrj
333138fd1498Szrj if (current_function_decl == NULL)
333238fd1498Szrj pp_string (context->printer, _("At global scope:"));
333338fd1498Szrj else
333438fd1498Szrj {
333538fd1498Szrj tree fndecl, ao;
333638fd1498Szrj
333738fd1498Szrj if (abstract_origin)
333838fd1498Szrj {
333938fd1498Szrj ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
334038fd1498Szrj while (TREE_CODE (ao) == BLOCK
334138fd1498Szrj && BLOCK_ABSTRACT_ORIGIN (ao)
334238fd1498Szrj && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
334338fd1498Szrj ao = BLOCK_ABSTRACT_ORIGIN (ao);
334438fd1498Szrj gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
334538fd1498Szrj fndecl = ao;
334638fd1498Szrj }
334738fd1498Szrj else
334838fd1498Szrj fndecl = current_function_decl;
334938fd1498Szrj
335038fd1498Szrj pp_printf (context->printer, function_category (fndecl),
335138fd1498Szrj cxx_printable_name_translate (fndecl, 2));
335238fd1498Szrj
335338fd1498Szrj while (abstract_origin)
335438fd1498Szrj {
335538fd1498Szrj location_t *locus;
335638fd1498Szrj tree block = abstract_origin;
335738fd1498Szrj
335838fd1498Szrj locus = &BLOCK_SOURCE_LOCATION (block);
335938fd1498Szrj fndecl = NULL;
336038fd1498Szrj block = BLOCK_SUPERCONTEXT (block);
336138fd1498Szrj while (block && TREE_CODE (block) == BLOCK
336238fd1498Szrj && BLOCK_ABSTRACT_ORIGIN (block))
336338fd1498Szrj {
336438fd1498Szrj ao = BLOCK_ABSTRACT_ORIGIN (block);
336538fd1498Szrj
336638fd1498Szrj while (TREE_CODE (ao) == BLOCK
336738fd1498Szrj && BLOCK_ABSTRACT_ORIGIN (ao)
336838fd1498Szrj && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
336938fd1498Szrj ao = BLOCK_ABSTRACT_ORIGIN (ao);
337038fd1498Szrj
337138fd1498Szrj if (TREE_CODE (ao) == FUNCTION_DECL)
337238fd1498Szrj {
337338fd1498Szrj fndecl = ao;
337438fd1498Szrj break;
337538fd1498Szrj }
337638fd1498Szrj else if (TREE_CODE (ao) != BLOCK)
337738fd1498Szrj break;
337838fd1498Szrj
337938fd1498Szrj block = BLOCK_SUPERCONTEXT (block);
338038fd1498Szrj }
338138fd1498Szrj if (fndecl)
338238fd1498Szrj abstract_origin = block;
338338fd1498Szrj else
338438fd1498Szrj {
338538fd1498Szrj while (block && TREE_CODE (block) == BLOCK)
338638fd1498Szrj block = BLOCK_SUPERCONTEXT (block);
338738fd1498Szrj
338838fd1498Szrj if (block && TREE_CODE (block) == FUNCTION_DECL)
338938fd1498Szrj fndecl = block;
339038fd1498Szrj abstract_origin = NULL;
339138fd1498Szrj }
339238fd1498Szrj if (fndecl)
339338fd1498Szrj {
339438fd1498Szrj expanded_location s = expand_location (*locus);
339538fd1498Szrj pp_character (context->printer, ',');
339638fd1498Szrj pp_newline (context->printer);
339738fd1498Szrj if (s.file != NULL)
339838fd1498Szrj {
339938fd1498Szrj if (context->show_column && s.column != 0)
340038fd1498Szrj pp_printf (context->printer,
340138fd1498Szrj _(" inlined from %qs at %r%s:%d:%d%R"),
340238fd1498Szrj cxx_printable_name_translate (fndecl, 2),
340338fd1498Szrj "locus", s.file, s.line, s.column);
340438fd1498Szrj else
340538fd1498Szrj pp_printf (context->printer,
340638fd1498Szrj _(" inlined from %qs at %r%s:%d%R"),
340738fd1498Szrj cxx_printable_name_translate (fndecl, 2),
340838fd1498Szrj "locus", s.file, s.line);
340938fd1498Szrj
341038fd1498Szrj }
341138fd1498Szrj else
341238fd1498Szrj pp_printf (context->printer, _(" inlined from %qs"),
341338fd1498Szrj cxx_printable_name_translate (fndecl, 2));
341438fd1498Szrj }
341538fd1498Szrj }
341638fd1498Szrj pp_character (context->printer, ':');
341738fd1498Szrj }
341838fd1498Szrj pp_newline (context->printer);
341938fd1498Szrj
342038fd1498Szrj diagnostic_set_last_function (context, diagnostic);
342138fd1498Szrj pp_destroy_prefix (context->printer);
342238fd1498Szrj context->printer->prefix = old_prefix;
342338fd1498Szrj }
342438fd1498Szrj }
342538fd1498Szrj
342638fd1498Szrj /* Returns a description of FUNCTION using standard terminology. The
342738fd1498Szrj result is a format string of the form "In CATEGORY %qs". */
342838fd1498Szrj static const char *
function_category(tree fn)342938fd1498Szrj function_category (tree fn)
343038fd1498Szrj {
343138fd1498Szrj /* We can get called from the middle-end for diagnostics of function
343238fd1498Szrj clones. Make sure we have language specific information before
343338fd1498Szrj dereferencing it. */
343438fd1498Szrj if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
343538fd1498Szrj && DECL_FUNCTION_MEMBER_P (fn))
343638fd1498Szrj {
343738fd1498Szrj if (DECL_STATIC_FUNCTION_P (fn))
343838fd1498Szrj return _("In static member function %qs");
343938fd1498Szrj else if (DECL_COPY_CONSTRUCTOR_P (fn))
344038fd1498Szrj return _("In copy constructor %qs");
344138fd1498Szrj else if (DECL_CONSTRUCTOR_P (fn))
344238fd1498Szrj return _("In constructor %qs");
344338fd1498Szrj else if (DECL_DESTRUCTOR_P (fn))
344438fd1498Szrj return _("In destructor %qs");
344538fd1498Szrj else if (LAMBDA_FUNCTION_P (fn))
344638fd1498Szrj return _("In lambda function");
344738fd1498Szrj else
344838fd1498Szrj return _("In member function %qs");
344938fd1498Szrj }
345038fd1498Szrj else
345138fd1498Szrj return _("In function %qs");
345238fd1498Szrj }
345338fd1498Szrj
345438fd1498Szrj /* Report the full context of a current template instantiation,
345538fd1498Szrj onto BUFFER. */
345638fd1498Szrj static void
print_instantiation_full_context(diagnostic_context * context)345738fd1498Szrj print_instantiation_full_context (diagnostic_context *context)
345838fd1498Szrj {
345938fd1498Szrj struct tinst_level *p = current_instantiation ();
346038fd1498Szrj location_t location = input_location;
346138fd1498Szrj
346238fd1498Szrj if (p)
346338fd1498Szrj {
346438fd1498Szrj pp_verbatim (context->printer,
346538fd1498Szrj p->list_p ()
346638fd1498Szrj ? _("%s: In substitution of %qS:\n")
346738fd1498Szrj : _("%s: In instantiation of %q#D:\n"),
346838fd1498Szrj LOCATION_FILE (location),
346938fd1498Szrj p->get_node ());
347038fd1498Szrj
347138fd1498Szrj location = p->locus;
347238fd1498Szrj p = p->next;
347338fd1498Szrj }
347438fd1498Szrj
347538fd1498Szrj print_instantiation_partial_context (context, p, location);
347638fd1498Szrj }
347738fd1498Szrj
347838fd1498Szrj /* Helper function of print_instantiation_partial_context() that
347938fd1498Szrj prints a single line of instantiation context. */
348038fd1498Szrj
348138fd1498Szrj static void
print_instantiation_partial_context_line(diagnostic_context * context,struct tinst_level * t,location_t loc,bool recursive_p)348238fd1498Szrj print_instantiation_partial_context_line (diagnostic_context *context,
348338fd1498Szrj struct tinst_level *t,
348438fd1498Szrj location_t loc, bool recursive_p)
348538fd1498Szrj {
348638fd1498Szrj if (loc == UNKNOWN_LOCATION)
348738fd1498Szrj return;
348838fd1498Szrj
348938fd1498Szrj expanded_location xloc = expand_location (loc);
349038fd1498Szrj
349138fd1498Szrj if (context->show_column)
349238fd1498Szrj pp_verbatim (context->printer, _("%r%s:%d:%d:%R "),
349338fd1498Szrj "locus", xloc.file, xloc.line, xloc.column);
349438fd1498Szrj else
349538fd1498Szrj pp_verbatim (context->printer, _("%r%s:%d:%R "),
349638fd1498Szrj "locus", xloc.file, xloc.line);
349738fd1498Szrj
349838fd1498Szrj if (t != NULL)
349938fd1498Szrj {
350038fd1498Szrj if (t->list_p ())
350138fd1498Szrj pp_verbatim (context->printer,
350238fd1498Szrj recursive_p
350338fd1498Szrj ? _("recursively required by substitution of %qS\n")
350438fd1498Szrj : _("required by substitution of %qS\n"),
350538fd1498Szrj t->get_node ());
350638fd1498Szrj else
350738fd1498Szrj pp_verbatim (context->printer,
350838fd1498Szrj recursive_p
350938fd1498Szrj ? _("recursively required from %q#D\n")
351038fd1498Szrj : _("required from %q#D\n"),
351138fd1498Szrj t->get_node ());
351238fd1498Szrj }
351338fd1498Szrj else
351438fd1498Szrj {
351538fd1498Szrj pp_verbatim (context->printer,
351638fd1498Szrj recursive_p
351738fd1498Szrj ? _("recursively required from here\n")
351838fd1498Szrj : _("required from here\n"));
351938fd1498Szrj }
352038fd1498Szrj }
352138fd1498Szrj
352238fd1498Szrj /* Same as print_instantiation_full_context but less verbose. */
352338fd1498Szrj
352438fd1498Szrj static void
print_instantiation_partial_context(diagnostic_context * context,struct tinst_level * t0,location_t loc)352538fd1498Szrj print_instantiation_partial_context (diagnostic_context *context,
352638fd1498Szrj struct tinst_level *t0, location_t loc)
352738fd1498Szrj {
352838fd1498Szrj struct tinst_level *t;
352938fd1498Szrj int n_total = 0;
353038fd1498Szrj int n;
353138fd1498Szrj location_t prev_loc = loc;
353238fd1498Szrj
353338fd1498Szrj for (t = t0; t != NULL; t = t->next)
353438fd1498Szrj if (prev_loc != t->locus)
353538fd1498Szrj {
353638fd1498Szrj prev_loc = t->locus;
353738fd1498Szrj n_total++;
353838fd1498Szrj }
353938fd1498Szrj
354038fd1498Szrj t = t0;
354138fd1498Szrj
354238fd1498Szrj if (template_backtrace_limit
354338fd1498Szrj && n_total > template_backtrace_limit)
354438fd1498Szrj {
354538fd1498Szrj int skip = n_total - template_backtrace_limit;
354638fd1498Szrj int head = template_backtrace_limit / 2;
354738fd1498Szrj
354838fd1498Szrj /* Avoid skipping just 1. If so, skip 2. */
354938fd1498Szrj if (skip == 1)
355038fd1498Szrj {
355138fd1498Szrj skip = 2;
355238fd1498Szrj head = (template_backtrace_limit - 1) / 2;
355338fd1498Szrj }
355438fd1498Szrj
355538fd1498Szrj for (n = 0; n < head; n++)
355638fd1498Szrj {
355738fd1498Szrj gcc_assert (t != NULL);
355838fd1498Szrj if (loc != t->locus)
355938fd1498Szrj print_instantiation_partial_context_line (context, t, loc,
356038fd1498Szrj /*recursive_p=*/false);
356138fd1498Szrj loc = t->locus;
356238fd1498Szrj t = t->next;
356338fd1498Szrj }
356438fd1498Szrj if (t != NULL && skip > 0)
356538fd1498Szrj {
356638fd1498Szrj expanded_location xloc;
356738fd1498Szrj xloc = expand_location (loc);
356838fd1498Szrj if (context->show_column)
356938fd1498Szrj pp_verbatim (context->printer,
357038fd1498Szrj _("%r%s:%d:%d:%R [ skipping %d instantiation "
357138fd1498Szrj "contexts, use -ftemplate-backtrace-limit=0 to "
357238fd1498Szrj "disable ]\n"),
357338fd1498Szrj "locus", xloc.file, xloc.line, xloc.column, skip);
357438fd1498Szrj else
357538fd1498Szrj pp_verbatim (context->printer,
357638fd1498Szrj _("%r%s:%d:%R [ skipping %d instantiation "
357738fd1498Szrj "contexts, use -ftemplate-backtrace-limit=0 to "
357838fd1498Szrj "disable ]\n"),
357938fd1498Szrj "locus", xloc.file, xloc.line, skip);
358038fd1498Szrj
358138fd1498Szrj do {
358238fd1498Szrj loc = t->locus;
358338fd1498Szrj t = t->next;
358438fd1498Szrj } while (t != NULL && --skip > 0);
358538fd1498Szrj }
358638fd1498Szrj }
358738fd1498Szrj
358838fd1498Szrj while (t != NULL)
358938fd1498Szrj {
359038fd1498Szrj while (t->next != NULL && t->locus == t->next->locus)
359138fd1498Szrj {
359238fd1498Szrj loc = t->locus;
359338fd1498Szrj t = t->next;
359438fd1498Szrj }
359538fd1498Szrj print_instantiation_partial_context_line (context, t, loc,
359638fd1498Szrj t->locus == loc);
359738fd1498Szrj loc = t->locus;
359838fd1498Szrj t = t->next;
359938fd1498Szrj }
360038fd1498Szrj print_instantiation_partial_context_line (context, NULL, loc,
360138fd1498Szrj /*recursive_p=*/false);
360238fd1498Szrj }
360338fd1498Szrj
360438fd1498Szrj /* Called from cp_thing to print the template context for an error. */
360538fd1498Szrj static void
maybe_print_instantiation_context(diagnostic_context * context)360638fd1498Szrj maybe_print_instantiation_context (diagnostic_context *context)
360738fd1498Szrj {
360838fd1498Szrj if (!problematic_instantiation_changed () || current_instantiation () == 0)
360938fd1498Szrj return;
361038fd1498Szrj
361138fd1498Szrj record_last_problematic_instantiation ();
361238fd1498Szrj print_instantiation_full_context (context);
361338fd1498Szrj }
361438fd1498Szrj
361538fd1498Szrj /* Report what constexpr call(s) we're trying to expand, if any. */
361638fd1498Szrj
361738fd1498Szrj void
maybe_print_constexpr_context(diagnostic_context * context)361838fd1498Szrj maybe_print_constexpr_context (diagnostic_context *context)
361938fd1498Szrj {
362038fd1498Szrj vec<tree> call_stack = cx_error_context ();
362138fd1498Szrj unsigned ix;
362238fd1498Szrj tree t;
362338fd1498Szrj
362438fd1498Szrj FOR_EACH_VEC_ELT (call_stack, ix, t)
362538fd1498Szrj {
362638fd1498Szrj expanded_location xloc = expand_location (EXPR_LOCATION (t));
362738fd1498Szrj const char *s = expr_as_string (t, 0);
362838fd1498Szrj if (context->show_column)
362938fd1498Szrj pp_verbatim (context->printer,
363038fd1498Szrj _("%r%s:%d:%d:%R in %<constexpr%> expansion of %qs"),
363138fd1498Szrj "locus", xloc.file, xloc.line, xloc.column, s);
363238fd1498Szrj else
363338fd1498Szrj pp_verbatim (context->printer,
363438fd1498Szrj _("%r%s:%d:%R in %<constexpr%> expansion of %qs"),
363538fd1498Szrj "locus", xloc.file, xloc.line, s);
363638fd1498Szrj pp_newline (context->printer);
363738fd1498Szrj }
363838fd1498Szrj }
363938fd1498Szrj
364038fd1498Szrj
364138fd1498Szrj /* Return true iff TYPE_A and TYPE_B are template types that are
364238fd1498Szrj meaningful to compare. */
364338fd1498Szrj
364438fd1498Szrj static bool
comparable_template_types_p(tree type_a,tree type_b)364538fd1498Szrj comparable_template_types_p (tree type_a, tree type_b)
364638fd1498Szrj {
364738fd1498Szrj if (!CLASS_TYPE_P (type_a))
364838fd1498Szrj return false;
364938fd1498Szrj if (!CLASS_TYPE_P (type_b))
365038fd1498Szrj return false;
365138fd1498Szrj
365238fd1498Szrj tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
365338fd1498Szrj tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
365438fd1498Szrj if (!tinfo_a || !tinfo_b)
365538fd1498Szrj return false;
365638fd1498Szrj
365738fd1498Szrj return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b);
365838fd1498Szrj }
365938fd1498Szrj
366038fd1498Szrj /* Start a new line indented by SPC spaces on PP. */
366138fd1498Szrj
366238fd1498Szrj static void
newline_and_indent(pretty_printer * pp,int spc)366338fd1498Szrj newline_and_indent (pretty_printer *pp, int spc)
366438fd1498Szrj {
366538fd1498Szrj pp_newline (pp);
366638fd1498Szrj for (int i = 0; i < spc; i++)
366738fd1498Szrj pp_space (pp);
366838fd1498Szrj }
366938fd1498Szrj
367038fd1498Szrj /* Generate a GC-allocated string for ARG, an expression or type. */
367138fd1498Szrj
367238fd1498Szrj static const char *
arg_to_string(tree arg,bool verbose)367338fd1498Szrj arg_to_string (tree arg, bool verbose)
367438fd1498Szrj {
367538fd1498Szrj if (TYPE_P (arg))
367638fd1498Szrj return type_to_string (arg, verbose, true, NULL, false);
367738fd1498Szrj else
367838fd1498Szrj return expr_to_string (arg);
367938fd1498Szrj }
368038fd1498Szrj
368138fd1498Szrj /* Subroutine to type_to_string_with_compare and
368238fd1498Szrj print_template_tree_comparison.
368338fd1498Szrj
368438fd1498Szrj Print a representation of ARG (an expression or type) to PP,
368538fd1498Szrj colorizing it as "type-diff" if PP->show_color. */
368638fd1498Szrj
368738fd1498Szrj static void
print_nonequal_arg(pretty_printer * pp,tree arg,bool verbose)368838fd1498Szrj print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose)
368938fd1498Szrj {
369038fd1498Szrj pp_printf (pp, "%r%s%R",
369138fd1498Szrj "type-diff",
369238fd1498Szrj (arg
369338fd1498Szrj ? arg_to_string (arg, verbose)
369438fd1498Szrj : G_("(no argument)")));
369538fd1498Szrj }
369638fd1498Szrj
369738fd1498Szrj /* Recursively print template TYPE_A to PP, as compared to template TYPE_B.
369838fd1498Szrj
369938fd1498Szrj The types must satisfy comparable_template_types_p.
370038fd1498Szrj
370138fd1498Szrj If INDENT is 0, then this is equivalent to type_to_string (TYPE_A), but
370238fd1498Szrj potentially colorizing/eliding in comparison with TYPE_B.
370338fd1498Szrj
370438fd1498Szrj For example given types:
370538fd1498Szrj vector<map<int,double>>
370638fd1498Szrj and
370738fd1498Szrj vector<map<int,float>>
370838fd1498Szrj then the result on PP would be:
370938fd1498Szrj vector<map<[...],double>>
371038fd1498Szrj with type elision, and:
371138fd1498Szrj vector<map<int,double>>
371238fd1498Szrj without type elision.
371338fd1498Szrj
371438fd1498Szrj In both cases the parts of TYPE that differ from PEER will be colorized
371538fd1498Szrj if pp_show_color (pp) is true. In the above example, this would be
371638fd1498Szrj "double".
371738fd1498Szrj
371838fd1498Szrj If INDENT is non-zero, then the types are printed in a tree-like form
371938fd1498Szrj which shows both types. In the above example, the result on PP would be:
372038fd1498Szrj
372138fd1498Szrj vector<
372238fd1498Szrj map<
372338fd1498Szrj [...],
372438fd1498Szrj [double != float]>>
372538fd1498Szrj
372638fd1498Szrj and without type-elision would be:
372738fd1498Szrj
372838fd1498Szrj vector<
372938fd1498Szrj map<
373038fd1498Szrj int,
373138fd1498Szrj [double != float]>>
373238fd1498Szrj
373338fd1498Szrj As before, the differing parts of the types are colorized if
373438fd1498Szrj pp_show_color (pp) is true ("double" and "float" in this example).
373538fd1498Szrj
373638fd1498Szrj Template arguments in which both types are using the default arguments
373738fd1498Szrj are not printed; if at least one of the two types is using a non-default
373838fd1498Szrj argument, then that argument is printed (or both arguments for the
373938fd1498Szrj tree-like print format). */
374038fd1498Szrj
374138fd1498Szrj static void
print_template_differences(pretty_printer * pp,tree type_a,tree type_b,bool verbose,int indent)374238fd1498Szrj print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
374338fd1498Szrj bool verbose, int indent)
374438fd1498Szrj {
374538fd1498Szrj if (indent)
374638fd1498Szrj newline_and_indent (pp, indent);
374738fd1498Szrj
374838fd1498Szrj tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
374938fd1498Szrj tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
375038fd1498Szrj
375138fd1498Szrj pp_printf (pp, "%s<",
375238fd1498Szrj IDENTIFIER_POINTER (DECL_NAME (TI_TEMPLATE (tinfo_a))));
375338fd1498Szrj
375438fd1498Szrj tree args_a = TI_ARGS (tinfo_a);
375538fd1498Szrj tree args_b = TI_ARGS (tinfo_b);
375638fd1498Szrj gcc_assert (TREE_CODE (args_a) == TREE_VEC);
375738fd1498Szrj gcc_assert (TREE_CODE (args_b) == TREE_VEC);
375838fd1498Szrj int flags = 0;
375938fd1498Szrj int len_a = get_non_default_template_args_count (args_a, flags);
376038fd1498Szrj args_a = INNERMOST_TEMPLATE_ARGS (args_a);
376138fd1498Szrj int len_b = get_non_default_template_args_count (args_b, flags);
376238fd1498Szrj args_b = INNERMOST_TEMPLATE_ARGS (args_b);
376338fd1498Szrj /* Determine the maximum range of args for which non-default template args
376438fd1498Szrj were used; beyond this, only default args (if any) were used, and so
376538fd1498Szrj they will be equal from this point onwards.
376638fd1498Szrj One of the two peers might have used default arguments within this
376738fd1498Szrj range, but the other will be using non-default arguments, and so
376838fd1498Szrj it's more readable to print both within this range, to highlight
376938fd1498Szrj the differences. */
377038fd1498Szrj int len_max = MAX (len_a, len_b);
377138fd1498Szrj gcc_assert (TREE_CODE (args_a) == TREE_VEC);
377238fd1498Szrj gcc_assert (TREE_CODE (args_b) == TREE_VEC);
377338fd1498Szrj for (int idx = 0; idx < len_max; idx++)
377438fd1498Szrj {
377538fd1498Szrj if (idx)
377638fd1498Szrj pp_character (pp, ',');
377738fd1498Szrj
377838fd1498Szrj tree arg_a = TREE_VEC_ELT (args_a, idx);
377938fd1498Szrj tree arg_b = TREE_VEC_ELT (args_b, idx);
378038fd1498Szrj if (arg_a == arg_b)
378138fd1498Szrj {
378238fd1498Szrj if (indent)
378338fd1498Szrj newline_and_indent (pp, indent + 2);
378438fd1498Szrj /* Can do elision here, printing "[...]". */
378538fd1498Szrj if (flag_elide_type)
378638fd1498Szrj pp_string (pp, G_("[...]"));
378738fd1498Szrj else
378838fd1498Szrj pp_string (pp, arg_to_string (arg_a, verbose));
378938fd1498Szrj }
379038fd1498Szrj else
379138fd1498Szrj {
379238fd1498Szrj int new_indent = indent ? indent + 2 : 0;
379338fd1498Szrj if (comparable_template_types_p (arg_a, arg_b))
379438fd1498Szrj print_template_differences (pp, arg_a, arg_b, verbose, new_indent);
379538fd1498Szrj else
379638fd1498Szrj if (indent)
379738fd1498Szrj {
379838fd1498Szrj newline_and_indent (pp, indent + 2);
379938fd1498Szrj pp_character (pp, '[');
380038fd1498Szrj print_nonequal_arg (pp, arg_a, verbose);
380138fd1498Szrj pp_string (pp, " != ");
380238fd1498Szrj print_nonequal_arg (pp, arg_b, verbose);
380338fd1498Szrj pp_character (pp, ']');
380438fd1498Szrj }
380538fd1498Szrj else
380638fd1498Szrj print_nonequal_arg (pp, arg_a, verbose);
380738fd1498Szrj }
380838fd1498Szrj }
380938fd1498Szrj pp_printf (pp, ">");
381038fd1498Szrj }
381138fd1498Szrj
381238fd1498Szrj /* As type_to_string, but for a template, potentially colorizing/eliding
381338fd1498Szrj in comparison with PEER.
381438fd1498Szrj For example, if TYPE is map<int,double> and PEER is map<int,int>,
381538fd1498Szrj then the resulting string would be:
381638fd1498Szrj map<[...],double>
381738fd1498Szrj with type elision, and:
381838fd1498Szrj map<int,double>
381938fd1498Szrj without type elision.
382038fd1498Szrj
382138fd1498Szrj In both cases the parts of TYPE that differ from PEER will be colorized
382238fd1498Szrj if SHOW_COLOR is true. In the above example, this would be "double".
382338fd1498Szrj
382438fd1498Szrj Template arguments in which both types are using the default arguments
382538fd1498Szrj are not printed; if at least one of the two types is using a non-default
382638fd1498Szrj argument, then both arguments are printed.
382738fd1498Szrj
382838fd1498Szrj The resulting string is in a GC-allocated buffer. */
382938fd1498Szrj
383038fd1498Szrj static const char *
type_to_string_with_compare(tree type,tree peer,bool verbose,bool show_color)383138fd1498Szrj type_to_string_with_compare (tree type, tree peer, bool verbose,
383238fd1498Szrj bool show_color)
383338fd1498Szrj {
383438fd1498Szrj pretty_printer inner_pp;
383538fd1498Szrj pretty_printer *pp = &inner_pp;
383638fd1498Szrj pp_show_color (pp) = show_color;
383738fd1498Szrj
383838fd1498Szrj print_template_differences (pp, type, peer, verbose, 0);
383938fd1498Szrj return pp_ggc_formatted_text (pp);
384038fd1498Szrj }
384138fd1498Szrj
384238fd1498Szrj /* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP,
384338fd1498Szrj indented by INDENT spaces.
384438fd1498Szrj
384538fd1498Szrj For example given types:
384638fd1498Szrj
384738fd1498Szrj vector<map<int,double>>
384838fd1498Szrj
384938fd1498Szrj and
385038fd1498Szrj
385138fd1498Szrj vector<map<double,float>>
385238fd1498Szrj
385338fd1498Szrj the output with type elision would be:
385438fd1498Szrj
385538fd1498Szrj vector<
385638fd1498Szrj map<
385738fd1498Szrj [...],
385838fd1498Szrj [double != float]>>
385938fd1498Szrj
386038fd1498Szrj and without type-elision would be:
386138fd1498Szrj
386238fd1498Szrj vector<
386338fd1498Szrj map<
386438fd1498Szrj int,
386538fd1498Szrj [double != float]>>
386638fd1498Szrj
386738fd1498Szrj TYPE_A and TYPE_B must both be comparable template types
386838fd1498Szrj (as per comparable_template_types_p).
386938fd1498Szrj
387038fd1498Szrj Template arguments in which both types are using the default arguments
387138fd1498Szrj are not printed; if at least one of the two types is using a non-default
387238fd1498Szrj argument, then both arguments are printed. */
387338fd1498Szrj
387438fd1498Szrj static void
print_template_tree_comparison(pretty_printer * pp,tree type_a,tree type_b,bool verbose,int indent)387538fd1498Szrj print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b,
387638fd1498Szrj bool verbose, int indent)
387738fd1498Szrj {
387838fd1498Szrj print_template_differences (pp, type_a, type_b, verbose, indent);
387938fd1498Szrj }
388038fd1498Szrj
388138fd1498Szrj /* Subroutine for use in a format_postprocessor::handle
388238fd1498Szrj implementation. Adds a chunk to the end of
388338fd1498Szrj formatted output, so that it will be printed
388438fd1498Szrj by pp_output_formatted_text. */
388538fd1498Szrj
388638fd1498Szrj static void
append_formatted_chunk(pretty_printer * pp,const char * content)388738fd1498Szrj append_formatted_chunk (pretty_printer *pp, const char *content)
388838fd1498Szrj {
388938fd1498Szrj output_buffer *buffer = pp_buffer (pp);
389038fd1498Szrj struct chunk_info *chunk_array = buffer->cur_chunk_array;
389138fd1498Szrj const char **args = chunk_array->args;
389238fd1498Szrj
389338fd1498Szrj unsigned int chunk_idx;
389438fd1498Szrj for (chunk_idx = 0; args[chunk_idx]; chunk_idx++)
389538fd1498Szrj ;
389638fd1498Szrj args[chunk_idx++] = content;
389738fd1498Szrj args[chunk_idx] = NULL;
389838fd1498Szrj }
389938fd1498Szrj
390038fd1498Szrj /* Create a copy of CONTENT, with quotes added, and,
390138fd1498Szrj potentially, with colorization.
390238fd1498Szrj No escaped is performed on CONTENT.
390338fd1498Szrj The result is in a GC-allocated buffer. */
390438fd1498Szrj
390538fd1498Szrj static const char *
add_quotes(const char * content,bool show_color)390638fd1498Szrj add_quotes (const char *content, bool show_color)
390738fd1498Szrj {
390838fd1498Szrj pretty_printer tmp_pp;
390938fd1498Szrj pp_show_color (&tmp_pp) = show_color;
391038fd1498Szrj
391138fd1498Szrj /* We have to use "%<%s%>" rather than "%qs" here in order to avoid
391238fd1498Szrj quoting colorization bytes within the results. */
391338fd1498Szrj pp_printf (&tmp_pp, "%<%s%>", content);
391438fd1498Szrj
391538fd1498Szrj return pp_ggc_formatted_text (&tmp_pp);
391638fd1498Szrj }
391738fd1498Szrj
391838fd1498Szrj /* If we had %H and %I, and hence deferred printing them,
391938fd1498Szrj print them now, storing the result into the chunk_info
392038fd1498Szrj for pp_format. Quote them if 'q' was provided.
392138fd1498Szrj Also print the difference in tree form, adding it as
392238fd1498Szrj an additional chunk. */
392338fd1498Szrj
392438fd1498Szrj void
handle(pretty_printer * pp)392538fd1498Szrj cxx_format_postprocessor::handle (pretty_printer *pp)
392638fd1498Szrj {
392738fd1498Szrj /* If we have one of %H and %I, the other should have
392838fd1498Szrj been present. */
392938fd1498Szrj if (m_type_a.m_tree || m_type_b.m_tree)
393038fd1498Szrj {
393138fd1498Szrj /* Avoid reentrancy issues by working with a copy of
393238fd1498Szrj m_type_a and m_type_b, resetting them now. */
393338fd1498Szrj deferred_printed_type type_a = m_type_a;
393438fd1498Szrj deferred_printed_type type_b = m_type_b;
393538fd1498Szrj m_type_a = deferred_printed_type ();
393638fd1498Szrj m_type_b = deferred_printed_type ();
393738fd1498Szrj
393838fd1498Szrj gcc_assert (type_a.m_buffer_ptr);
393938fd1498Szrj gcc_assert (type_b.m_buffer_ptr);
394038fd1498Szrj
394138fd1498Szrj bool show_color = pp_show_color (pp);
394238fd1498Szrj
394338fd1498Szrj const char *type_a_text;
394438fd1498Szrj const char *type_b_text;
394538fd1498Szrj
394638fd1498Szrj if (comparable_template_types_p (type_a.m_tree, type_b.m_tree))
394738fd1498Szrj {
394838fd1498Szrj type_a_text
394938fd1498Szrj = type_to_string_with_compare (type_a.m_tree, type_b.m_tree,
395038fd1498Szrj type_a.m_verbose, show_color);
395138fd1498Szrj type_b_text
395238fd1498Szrj = type_to_string_with_compare (type_b.m_tree, type_a.m_tree,
395338fd1498Szrj type_b.m_verbose, show_color);
395438fd1498Szrj
395538fd1498Szrj if (flag_diagnostics_show_template_tree)
395638fd1498Szrj {
395738fd1498Szrj pretty_printer inner_pp;
395838fd1498Szrj pp_show_color (&inner_pp) = pp_show_color (pp);
395938fd1498Szrj print_template_tree_comparison
396038fd1498Szrj (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2);
396138fd1498Szrj append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp));
396238fd1498Szrj }
396338fd1498Szrj }
396438fd1498Szrj else
396538fd1498Szrj {
396638fd1498Szrj /* If the types were not comparable (or if only one of %H/%I was
396738fd1498Szrj provided), they are printed normally, and no difference tree
396838fd1498Szrj is printed. */
396938fd1498Szrj type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose,
397038fd1498Szrj true, &type_a.m_quote, show_color);
397138fd1498Szrj type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose,
397238fd1498Szrj true, &type_b.m_quote, show_color);
397338fd1498Szrj }
397438fd1498Szrj
397538fd1498Szrj if (type_a.m_quote)
397638fd1498Szrj type_a_text = add_quotes (type_a_text, show_color);
397738fd1498Szrj *type_a.m_buffer_ptr = type_a_text;
397838fd1498Szrj
397938fd1498Szrj if (type_b.m_quote)
398038fd1498Szrj type_b_text = add_quotes (type_b_text, show_color);
398138fd1498Szrj *type_b.m_buffer_ptr = type_b_text;
398238fd1498Szrj }
398338fd1498Szrj }
398438fd1498Szrj
398538fd1498Szrj /* Subroutine for handling %H and %I, to support i18n of messages like:
398638fd1498Szrj
398738fd1498Szrj error_at (loc, "could not convert %qE from %qH to %qI",
398838fd1498Szrj expr, type_a, type_b);
398938fd1498Szrj
399038fd1498Szrj so that we can print things like:
399138fd1498Szrj
399238fd1498Szrj could not convert 'foo' from 'map<int,double>' to 'map<int,int>'
399338fd1498Szrj
399438fd1498Szrj and, with type-elision:
399538fd1498Szrj
399638fd1498Szrj could not convert 'foo' from 'map<[...],double>' to 'map<[...],int>'
399738fd1498Szrj
399838fd1498Szrj (with color-coding of the differences between the types).
399938fd1498Szrj
400038fd1498Szrj The %H and %I format codes are peers: both must be present,
400138fd1498Szrj and they affect each other. Hence to handle them, we must
400238fd1498Szrj delay printing until we have both, deferring the printing to
400338fd1498Szrj pretty_printer's m_format_postprocessor hook.
400438fd1498Szrj
400538fd1498Szrj This is called in phase 2 of pp_format, when it is accumulating
400638fd1498Szrj a series of formatted chunks. We stash the location of the chunk
400738fd1498Szrj we're meant to have written to, so that we can write to it in the
400838fd1498Szrj m_format_postprocessor hook.
400938fd1498Szrj
401038fd1498Szrj We also need to stash whether a 'q' prefix was provided (the QUOTE
401138fd1498Szrj param) so that we can add the quotes when writing out the delayed
401238fd1498Szrj chunk. */
401338fd1498Szrj
401438fd1498Szrj static void
defer_phase_2_of_type_diff(deferred_printed_type * deferred,tree type,const char ** buffer_ptr,bool verbose,bool quote)401538fd1498Szrj defer_phase_2_of_type_diff (deferred_printed_type *deferred,
401638fd1498Szrj tree type, const char **buffer_ptr,
401738fd1498Szrj bool verbose, bool quote)
401838fd1498Szrj {
401938fd1498Szrj gcc_assert (deferred->m_tree == NULL_TREE);
402038fd1498Szrj gcc_assert (deferred->m_buffer_ptr == NULL);
402138fd1498Szrj *deferred = deferred_printed_type (type, buffer_ptr, verbose, quote);
402238fd1498Szrj }
402338fd1498Szrj
402438fd1498Szrj
402538fd1498Szrj /* Called from output_format -- during diagnostic message processing --
402638fd1498Szrj to handle C++ specific format specifier with the following meanings:
402738fd1498Szrj %A function argument-list.
402838fd1498Szrj %C tree code.
402938fd1498Szrj %D declaration.
403038fd1498Szrj %E expression.
403138fd1498Szrj %F function declaration.
403238fd1498Szrj %L language as used in extern "lang".
403338fd1498Szrj %O binary operator.
403438fd1498Szrj %P function parameter whose position is indicated by an integer.
403538fd1498Szrj %Q assignment operator.
403638fd1498Szrj %S substitution (template + args)
403738fd1498Szrj %T type.
403838fd1498Szrj %V cv-qualifier.
403938fd1498Szrj %X exception-specification.
404038fd1498Szrj %H type difference (from)
404138fd1498Szrj %I type difference (to). */
404238fd1498Szrj static bool
cp_printer(pretty_printer * pp,text_info * text,const char * spec,int precision,bool wide,bool set_locus,bool verbose,bool * quoted,const char ** buffer_ptr)404338fd1498Szrj cp_printer (pretty_printer *pp, text_info *text, const char *spec,
404438fd1498Szrj int precision, bool wide, bool set_locus, bool verbose,
404538fd1498Szrj bool *quoted, const char **buffer_ptr)
404638fd1498Szrj {
404738fd1498Szrj gcc_assert (pp->m_format_postprocessor);
404838fd1498Szrj cxx_format_postprocessor *postprocessor
404938fd1498Szrj = static_cast <cxx_format_postprocessor *> (pp->m_format_postprocessor);
405038fd1498Szrj
405138fd1498Szrj const char *result;
405238fd1498Szrj tree t = NULL;
405338fd1498Szrj #define next_tree (t = va_arg (*text->args_ptr, tree))
405438fd1498Szrj #define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int))
405538fd1498Szrj #define next_lang ((enum languages) va_arg (*text->args_ptr, int))
405638fd1498Szrj #define next_int va_arg (*text->args_ptr, int)
405738fd1498Szrj
405838fd1498Szrj if (precision != 0 || wide)
405938fd1498Szrj return false;
406038fd1498Szrj
406138fd1498Szrj switch (*spec)
406238fd1498Szrj {
406338fd1498Szrj case 'A': result = args_to_string (next_tree, verbose); break;
406438fd1498Szrj case 'C': result = code_to_string (next_tcode); break;
406538fd1498Szrj case 'D':
406638fd1498Szrj {
406738fd1498Szrj tree temp = next_tree;
406838fd1498Szrj if (VAR_P (temp)
406938fd1498Szrj && DECL_HAS_DEBUG_EXPR_P (temp))
407038fd1498Szrj {
407138fd1498Szrj temp = DECL_DEBUG_EXPR (temp);
407238fd1498Szrj if (!DECL_P (temp))
407338fd1498Szrj {
407438fd1498Szrj result = expr_to_string (temp);
407538fd1498Szrj break;
407638fd1498Szrj }
407738fd1498Szrj }
407838fd1498Szrj result = decl_to_string (temp, verbose);
407938fd1498Szrj }
408038fd1498Szrj break;
408138fd1498Szrj case 'E': result = expr_to_string (next_tree); break;
408238fd1498Szrj case 'F': result = fndecl_to_string (next_tree, verbose); break;
408338fd1498Szrj case 'L': result = language_to_string (next_lang); break;
408438fd1498Szrj case 'O': result = op_to_string (false, next_tcode); break;
408538fd1498Szrj case 'P': result = parm_to_string (next_int); break;
408638fd1498Szrj case 'Q': result = op_to_string (true, next_tcode); break;
408738fd1498Szrj case 'S': result = subst_to_string (next_tree); break;
408838fd1498Szrj case 'T':
408938fd1498Szrj {
409038fd1498Szrj result = type_to_string (next_tree, verbose, false, quoted,
409138fd1498Szrj pp_show_color (pp));
409238fd1498Szrj }
409338fd1498Szrj break;
409438fd1498Szrj case 'V': result = cv_to_string (next_tree, verbose); break;
409538fd1498Szrj case 'X': result = eh_spec_to_string (next_tree, verbose); break;
409638fd1498Szrj
409738fd1498Szrj case 'G':
409838fd1498Szrj percent_G_format (text);
409938fd1498Szrj return true;
410038fd1498Szrj
410138fd1498Szrj case 'K':
410238fd1498Szrj t = va_arg (*text->args_ptr, tree);
410338fd1498Szrj percent_K_format (text, t);
410438fd1498Szrj return true;
410538fd1498Szrj
410638fd1498Szrj case 'H':
410738fd1498Szrj {
410838fd1498Szrj defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree,
410938fd1498Szrj buffer_ptr, verbose, *quoted);
411038fd1498Szrj return true;
411138fd1498Szrj }
411238fd1498Szrj
411338fd1498Szrj case 'I':
411438fd1498Szrj {
411538fd1498Szrj defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree,
411638fd1498Szrj buffer_ptr, verbose, *quoted);
411738fd1498Szrj return true;
411838fd1498Szrj }
411938fd1498Szrj
412038fd1498Szrj default:
412138fd1498Szrj return false;
412238fd1498Szrj }
412338fd1498Szrj
412438fd1498Szrj pp_string (pp, result);
412538fd1498Szrj if (set_locus && t != NULL)
412638fd1498Szrj text->set_location (0, location_of (t), true);
412738fd1498Szrj return true;
412838fd1498Szrj #undef next_tree
412938fd1498Szrj #undef next_tcode
413038fd1498Szrj #undef next_lang
413138fd1498Szrj #undef next_int
413238fd1498Szrj }
413338fd1498Szrj
413438fd1498Szrj /* Warn about the use of C++0x features when appropriate. */
413538fd1498Szrj void
maybe_warn_cpp0x(cpp0x_warn_str str)413638fd1498Szrj maybe_warn_cpp0x (cpp0x_warn_str str)
413738fd1498Szrj {
413838fd1498Szrj if ((cxx_dialect == cxx98) && !in_system_header_at (input_location))
413938fd1498Szrj /* We really want to suppress this warning in system headers,
414038fd1498Szrj because libstdc++ uses variadic templates even when we aren't
414138fd1498Szrj in C++0x mode. */
414238fd1498Szrj switch (str)
414338fd1498Szrj {
414438fd1498Szrj case CPP0X_INITIALIZER_LISTS:
414538fd1498Szrj pedwarn (input_location, 0,
414638fd1498Szrj "extended initializer lists "
414738fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
414838fd1498Szrj break;
414938fd1498Szrj case CPP0X_EXPLICIT_CONVERSION:
415038fd1498Szrj pedwarn (input_location, 0,
415138fd1498Szrj "explicit conversion operators "
415238fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
415338fd1498Szrj break;
415438fd1498Szrj case CPP0X_VARIADIC_TEMPLATES:
415538fd1498Szrj pedwarn (input_location, 0,
415638fd1498Szrj "variadic templates "
415738fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
415838fd1498Szrj break;
415938fd1498Szrj case CPP0X_LAMBDA_EXPR:
416038fd1498Szrj pedwarn (input_location, 0,
416138fd1498Szrj "lambda expressions "
416238fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
416338fd1498Szrj break;
416438fd1498Szrj case CPP0X_AUTO:
416538fd1498Szrj pedwarn (input_location, 0,
416638fd1498Szrj "C++11 auto only available with -std=c++11 or -std=gnu++11");
416738fd1498Szrj break;
416838fd1498Szrj case CPP0X_SCOPED_ENUMS:
416938fd1498Szrj pedwarn (input_location, 0,
417038fd1498Szrj "scoped enums only available with -std=c++11 or -std=gnu++11");
417138fd1498Szrj break;
417238fd1498Szrj case CPP0X_DEFAULTED_DELETED:
417338fd1498Szrj pedwarn (input_location, 0,
417438fd1498Szrj "defaulted and deleted functions "
417538fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
417638fd1498Szrj break;
417738fd1498Szrj case CPP0X_INLINE_NAMESPACES:
417838fd1498Szrj pedwarn (input_location, OPT_Wpedantic,
417938fd1498Szrj "inline namespaces "
418038fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
418138fd1498Szrj break;
418238fd1498Szrj case CPP0X_OVERRIDE_CONTROLS:
418338fd1498Szrj pedwarn (input_location, 0,
418438fd1498Szrj "override controls (override/final) "
418538fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
418638fd1498Szrj break;
418738fd1498Szrj case CPP0X_NSDMI:
418838fd1498Szrj pedwarn (input_location, 0,
418938fd1498Szrj "non-static data member initializers "
419038fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
419138fd1498Szrj break;
419238fd1498Szrj case CPP0X_USER_DEFINED_LITERALS:
419338fd1498Szrj pedwarn (input_location, 0,
419438fd1498Szrj "user-defined literals "
419538fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
419638fd1498Szrj break;
419738fd1498Szrj case CPP0X_DELEGATING_CTORS:
419838fd1498Szrj pedwarn (input_location, 0,
419938fd1498Szrj "delegating constructors "
420038fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
420138fd1498Szrj break;
420238fd1498Szrj case CPP0X_INHERITING_CTORS:
420338fd1498Szrj pedwarn (input_location, 0,
420438fd1498Szrj "inheriting constructors "
420538fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
420638fd1498Szrj break;
420738fd1498Szrj case CPP0X_ATTRIBUTES:
420838fd1498Szrj pedwarn (input_location, 0,
420938fd1498Szrj "c++11 attributes "
421038fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
421138fd1498Szrj break;
421238fd1498Szrj case CPP0X_REF_QUALIFIER:
421338fd1498Szrj pedwarn (input_location, 0,
421438fd1498Szrj "ref-qualifiers "
421538fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
421638fd1498Szrj break;
421738fd1498Szrj default:
421838fd1498Szrj gcc_unreachable ();
421938fd1498Szrj }
422038fd1498Szrj }
422138fd1498Szrj
422238fd1498Szrj /* Warn about the use of variadic templates when appropriate. */
422338fd1498Szrj void
maybe_warn_variadic_templates(void)422438fd1498Szrj maybe_warn_variadic_templates (void)
422538fd1498Szrj {
422638fd1498Szrj maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
422738fd1498Szrj }
422838fd1498Szrj
422938fd1498Szrj
423038fd1498Szrj /* Issue an ISO C++98 pedantic warning at LOCATION, conditional on
423138fd1498Szrj option OPT with text GMSGID. Use this function to report
423238fd1498Szrj diagnostics for constructs that are invalid C++98, but valid
423338fd1498Szrj C++0x. */
423438fd1498Szrj bool
pedwarn_cxx98(location_t location,int opt,const char * gmsgid,...)423538fd1498Szrj pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
423638fd1498Szrj {
423738fd1498Szrj diagnostic_info diagnostic;
423838fd1498Szrj va_list ap;
423938fd1498Szrj bool ret;
424038fd1498Szrj rich_location richloc (line_table, location);
424138fd1498Szrj
424238fd1498Szrj va_start (ap, gmsgid);
424338fd1498Szrj diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
424438fd1498Szrj (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING);
424538fd1498Szrj diagnostic.option_index = opt;
424638fd1498Szrj ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
424738fd1498Szrj va_end (ap);
424838fd1498Szrj return ret;
424938fd1498Szrj }
425038fd1498Szrj
425138fd1498Szrj /* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what
425238fd1498Szrj we found when we tried to do the lookup. LOCATION is the location of
425338fd1498Szrj the NAME identifier. */
425438fd1498Szrj
425538fd1498Szrj void
qualified_name_lookup_error(tree scope,tree name,tree decl,location_t location)425638fd1498Szrj qualified_name_lookup_error (tree scope, tree name,
425738fd1498Szrj tree decl, location_t location)
425838fd1498Szrj {
425938fd1498Szrj if (scope == error_mark_node)
426038fd1498Szrj ; /* We already complained. */
426138fd1498Szrj else if (TYPE_P (scope))
426238fd1498Szrj {
426338fd1498Szrj if (!COMPLETE_TYPE_P (scope))
426438fd1498Szrj error_at (location, "incomplete type %qT used in nested name specifier",
426538fd1498Szrj scope);
426638fd1498Szrj else if (TREE_CODE (decl) == TREE_LIST)
426738fd1498Szrj {
426838fd1498Szrj error_at (location, "reference to %<%T::%D%> is ambiguous",
426938fd1498Szrj scope, name);
427038fd1498Szrj print_candidates (decl);
427138fd1498Szrj }
427238fd1498Szrj else
427338fd1498Szrj error_at (location, "%qD is not a member of %qT", name, scope);
427438fd1498Szrj }
427538fd1498Szrj else if (scope != global_namespace)
427638fd1498Szrj {
427738fd1498Szrj error_at (location, "%qD is not a member of %qD", name, scope);
427838fd1498Szrj if (!suggest_alternative_in_explicit_scope (location, name, scope))
427938fd1498Szrj suggest_alternatives_for (location, name, false);
428038fd1498Szrj }
428138fd1498Szrj else
428238fd1498Szrj {
428338fd1498Szrj error_at (location, "%<::%D%> has not been declared", name);
428438fd1498Szrj suggest_alternatives_for (location, name, true);
428538fd1498Szrj }
428638fd1498Szrj }
4287