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