xref: /netbsd-src/external/gpl3/gcc/dist/gcc/cp/cxx-pretty-print.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2    Copyright (C) 2003-2022 Free Software Foundation, Inc.
3    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cp-tree.h"
25 #include "cxx-pretty-print.h"
26 #include "tree-pretty-print.h"
27 
28 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
29 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
30 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
32 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
33 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
34 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
35 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
36 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
37 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
38 static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree);
40 static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree);
41 static void pp_cxx_concept_definition (cxx_pretty_printer *, tree);
42 
43 
44 static inline void
pp_cxx_nonconsecutive_character(cxx_pretty_printer * pp,int c)45 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
46 {
47   const char *p = pp_last_position_in_text (pp);
48 
49   if (p != NULL && *p == c)
50     pp_cxx_whitespace (pp);
51   pp_character (pp, c);
52   pp->padding = pp_none;
53 }
54 
55 #define pp_cxx_expression_list(PP, T)    \
56    pp_c_expression_list (PP, T)
57 #define pp_cxx_space_for_pointer_operator(PP, T)  \
58    pp_c_space_for_pointer_operator (PP, T)
59 #define pp_cxx_init_declarator(PP, T)    \
60    pp_c_init_declarator (PP, T)
61 #define pp_cxx_call_argument_list(PP, T) \
62    pp_c_call_argument_list (PP, T)
63 
64 void
pp_cxx_colon_colon(cxx_pretty_printer * pp)65 pp_cxx_colon_colon (cxx_pretty_printer *pp)
66 {
67   pp_colon_colon (pp);
68   pp->padding = pp_none;
69 }
70 
71 void
pp_cxx_begin_template_argument_list(cxx_pretty_printer * pp)72 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
73 {
74   pp_cxx_nonconsecutive_character (pp, '<');
75 }
76 
77 void
pp_cxx_end_template_argument_list(cxx_pretty_printer * pp)78 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
79 {
80   pp_cxx_nonconsecutive_character (pp, '>');
81 }
82 
83 void
pp_cxx_separate_with(cxx_pretty_printer * pp,int c)84 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
85 {
86   pp_separate_with (pp, c);
87   pp->padding = pp_none;
88 }
89 
90 /* Expressions.  */
91 
92 /* conversion-function-id:
93       operator conversion-type-id
94 
95    conversion-type-id:
96       type-specifier-seq conversion-declarator(opt)
97 
98    conversion-declarator:
99       ptr-operator conversion-declarator(opt)  */
100 
101 static inline void
pp_cxx_conversion_function_id(cxx_pretty_printer * pp,tree t)102 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
103 {
104   pp_cxx_ws_string (pp, "operator");
105   pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
106 }
107 
108 static inline void
pp_cxx_template_id(cxx_pretty_printer * pp,tree t)109 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
110 {
111   pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
112   pp_cxx_begin_template_argument_list (pp);
113   pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
114   pp_cxx_end_template_argument_list (pp);
115 }
116 
117 /* Prints the unqualified part of the id-expression T.
118 
119    unqualified-id:
120      identifier
121      operator-function-id
122      conversion-function-id
123      ~ class-name
124      template-id  */
125 
126 static void
pp_cxx_unqualified_id(cxx_pretty_printer * pp,tree t)127 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
128 {
129   enum tree_code code = TREE_CODE (t);
130   switch (code)
131     {
132     case RESULT_DECL:
133       pp->translate_string ("<return-value>");
134       break;
135 
136     case OVERLOAD:
137       t = OVL_FIRST (t);
138       /* FALLTHRU */
139     case VAR_DECL:
140     case PARM_DECL:
141     case CONST_DECL:
142     case TYPE_DECL:
143     case FUNCTION_DECL:
144     case NAMESPACE_DECL:
145     case FIELD_DECL:
146     case LABEL_DECL:
147     case USING_DECL:
148     case TEMPLATE_DECL:
149       t = DECL_NAME (t);
150       /* FALLTHRU */
151 
152     case IDENTIFIER_NODE:
153       if (t == NULL)
154 	pp->translate_string ("<unnamed>");
155       else if (IDENTIFIER_CONV_OP_P (t))
156 	pp_cxx_conversion_function_id (pp, t);
157       else
158 	pp_cxx_tree_identifier (pp, t);
159       break;
160 
161     case TEMPLATE_ID_EXPR:
162       pp_cxx_template_id (pp, t);
163       break;
164 
165     case BASELINK:
166       pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
167       break;
168 
169     case RECORD_TYPE:
170     case UNION_TYPE:
171     case ENUMERAL_TYPE:
172     case TYPENAME_TYPE:
173     case UNBOUND_CLASS_TEMPLATE:
174       pp_cxx_unqualified_id (pp, TYPE_NAME (t));
175       if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (t))
176 	if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)))
177 	  {
178 	    pp_cxx_begin_template_argument_list (pp);
179 	    tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti));
180 	    pp_cxx_template_argument_list (pp, args);
181 	    pp_cxx_end_template_argument_list (pp);
182 	  }
183       break;
184 
185     case BIT_NOT_EXPR:
186       pp_cxx_complement (pp);
187       pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
188       break;
189 
190     case TEMPLATE_TYPE_PARM:
191     case TEMPLATE_TEMPLATE_PARM:
192       if (template_placeholder_p (t))
193 	{
194 	  t = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t));
195 	  pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
196 	  pp_string (pp, "<...auto...>");
197 	}
198       else if (TYPE_IDENTIFIER (t))
199 	pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
200       else
201 	pp_cxx_canonical_template_parameter (pp, t);
202       break;
203 
204     case TEMPLATE_PARM_INDEX:
205       pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
206       break;
207 
208     case BOUND_TEMPLATE_TEMPLATE_PARM:
209       pp_cxx_cv_qualifier_seq (pp, t);
210       pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
211       pp_cxx_begin_template_argument_list (pp);
212       pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
213       pp_cxx_end_template_argument_list (pp);
214       break;
215 
216     default:
217       pp_unsupported_tree (pp, t);
218       break;
219     }
220 }
221 
222 /* Pretty-print out the token sequence ":: template" in template codes
223    where it is needed to "inline declare" the (following) member as
224    a template.  This situation arises when SCOPE of T is dependent
225    on template parameters.  */
226 
227 static inline void
pp_cxx_template_keyword_if_needed(cxx_pretty_printer * pp,tree scope,tree t)228 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
229 {
230   if (TREE_CODE (t) == TEMPLATE_ID_EXPR
231       && TYPE_P (scope) && dependent_type_p (scope))
232     pp_cxx_ws_string (pp, "template");
233 }
234 
235 /* nested-name-specifier:
236       class-or-namespace-name :: nested-name-specifier(opt)
237       class-or-namespace-name :: template nested-name-specifier   */
238 
239 static void
pp_cxx_nested_name_specifier(cxx_pretty_printer * pp,tree t)240 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
241 {
242   /* FIXME: When diagnosing references to concepts (especially as types?)
243      we end up adding too many '::' to the name. This is partially due
244      to the fact that pp->enclosing_namespace is null.  */
245   if (t == global_namespace)
246     {
247       pp_cxx_colon_colon (pp);
248     }
249   else if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
250     {
251       tree scope = get_containing_scope (t);
252       pp_cxx_nested_name_specifier (pp, scope);
253       pp_cxx_template_keyword_if_needed (pp, scope, t);
254       pp_cxx_unqualified_id (pp, t);
255       pp_cxx_colon_colon (pp);
256     }
257 }
258 
259 /* qualified-id:
260       nested-name-specifier template(opt) unqualified-id  */
261 
262 static void
pp_cxx_qualified_id(cxx_pretty_printer * pp,tree t)263 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
264 {
265   switch (TREE_CODE (t))
266     {
267       /* A pointer-to-member is always qualified.  */
268     case PTRMEM_CST:
269       pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
270       pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
271       break;
272 
273       /* In Standard C++, functions cannot possibly be used as
274 	 nested-name-specifiers.  However, there are situations where
275 	 is "makes sense" to output the surrounding function name for the
276 	 purpose of emphasizing on the scope kind.  Just printing the
277 	 function name might not be sufficient as it may be overloaded; so,
278 	 we decorate the function with its signature too.
279 	 FIXME:  This is probably the wrong pretty-printing for conversion
280 	 functions and some function templates.  */
281     case OVERLOAD:
282       t = OVL_FIRST (t);
283       /* FALLTHRU */
284     case FUNCTION_DECL:
285       if (DECL_FUNCTION_MEMBER_P (t))
286 	pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
287       pp_cxx_unqualified_id
288 	(pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
289       pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
290       break;
291 
292     case OFFSET_REF:
293     case SCOPE_REF:
294       pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
295       pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
296       break;
297 
298     default:
299       {
300 	tree scope = get_containing_scope (t);
301 	if (scope != pp->enclosing_scope)
302 	  {
303 	    pp_cxx_nested_name_specifier (pp, scope);
304 	    pp_cxx_template_keyword_if_needed (pp, scope, t);
305 	  }
306 	pp_cxx_unqualified_id (pp, t);
307       }
308       break;
309     }
310 }
311 
312 /* Given a value e of ENUMERAL_TYPE:
313    Print out the first ENUMERATOR id with value e, if one is found,
314    (including nested names but excluding the enum name if unscoped)
315    else print out the value as a C-style cast (type-id)value.  */
316 
317 static void
pp_cxx_enumeration_constant(cxx_pretty_printer * pp,tree e)318 pp_cxx_enumeration_constant (cxx_pretty_printer *pp, tree e)
319 {
320   tree type = TREE_TYPE (e);
321   tree value = NULL_TREE;
322 
323   /* Find the name of this constant.  */
324   if ((pp->flags & pp_c_flag_gnu_v3) == 0)
325     for (value = TYPE_VALUES (type); value != NULL_TREE;
326 	 value = TREE_CHAIN (value))
327       if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e))
328 	break;
329 
330   if (value != NULL_TREE)
331     {
332       if (!ENUM_IS_SCOPED (type))
333 	type = get_containing_scope (type);
334       pp_cxx_nested_name_specifier (pp, type);
335       pp->id_expression (TREE_PURPOSE (value));
336     }
337   else
338     {
339       /* Value must have been cast.  */
340        pp_c_type_cast (pp, type);
341        pp_c_integer_constant (pp, e);
342     }
343 }
344 
345 
346 void
constant(tree t)347 cxx_pretty_printer::constant (tree t)
348 {
349   switch (TREE_CODE (t))
350     {
351     case STRING_CST:
352       {
353 	const bool in_parens = PAREN_STRING_LITERAL_P (t);
354 	if (in_parens)
355 	  pp_cxx_left_paren (this);
356 	c_pretty_printer::constant (t);
357 	if (in_parens)
358 	  pp_cxx_right_paren (this);
359       }
360       break;
361 
362     case INTEGER_CST:
363       if (NULLPTR_TYPE_P (TREE_TYPE (t)))
364 	{
365 	  pp_string (this, "nullptr");
366 	  break;
367 	}
368       else if (TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
369 	{
370 	  pp_cxx_enumeration_constant (this, t);
371 	  break;
372 	}
373       /* fall through.  */
374 
375     default:
376       c_pretty_printer::constant (t);
377       break;
378     }
379 }
380 
381 /* id-expression:
382       unqualified-id
383       qualified-id   */
384 
385 void
id_expression(tree t)386 cxx_pretty_printer::id_expression (tree t)
387 {
388   if (TREE_CODE (t) == OVERLOAD)
389     t = OVL_FIRST (t);
390   if (DECL_P (t) && DECL_CONTEXT (t))
391     pp_cxx_qualified_id (this, t);
392   else
393     pp_cxx_unqualified_id (this, t);
394 }
395 
396 /* user-defined literal:
397       literal ud-suffix  */
398 
399 void
pp_cxx_userdef_literal(cxx_pretty_printer * pp,tree t)400 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
401 {
402   pp->constant (USERDEF_LITERAL_VALUE (t));
403   pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
404 }
405 
406 
407 /* primary-expression:
408      literal
409      this
410      :: identifier
411      :: operator-function-id
412      :: qualifier-id
413      ( expression )
414      id-expression
415 
416    GNU Extensions:
417      __builtin_va_arg ( assignment-expression , type-id )
418      __builtin_offsetof ( type-id, offsetof-expression )
419      __builtin_addressof ( expression )
420 
421      __has_nothrow_assign ( type-id )
422      __has_nothrow_constructor ( type-id )
423      __has_nothrow_copy ( type-id )
424      __has_trivial_assign ( type-id )
425      __has_trivial_constructor ( type-id )
426      __has_trivial_copy ( type-id )
427      __has_unique_object_representations ( type-id )
428      __has_trivial_destructor ( type-id )
429      __has_virtual_destructor ( type-id )
430      __is_abstract ( type-id )
431      __is_base_of ( type-id , type-id )
432      __is_class ( type-id )
433      __is_empty ( type-id )
434      __is_enum ( type-id )
435      __is_literal_type ( type-id )
436      __is_pod ( type-id )
437      __is_polymorphic ( type-id )
438      __is_std_layout ( type-id )
439      __is_trivial ( type-id )
440      __is_union ( type-id )  */
441 
442 void
primary_expression(tree t)443 cxx_pretty_printer::primary_expression (tree t)
444 {
445   switch (TREE_CODE (t))
446     {
447     case VOID_CST:
448     case INTEGER_CST:
449     case REAL_CST:
450     case COMPLEX_CST:
451     case STRING_CST:
452       constant (t);
453       break;
454 
455     case USERDEF_LITERAL:
456       pp_cxx_userdef_literal (this, t);
457       break;
458 
459     case BASELINK:
460       t = BASELINK_FUNCTIONS (t);
461       /* FALLTHRU */
462     case VAR_DECL:
463     case PARM_DECL:
464     case FIELD_DECL:
465     case FUNCTION_DECL:
466     case OVERLOAD:
467     case CONST_DECL:
468     case TEMPLATE_DECL:
469       id_expression (t);
470       break;
471 
472     case RESULT_DECL:
473     case TEMPLATE_TYPE_PARM:
474     case TEMPLATE_TEMPLATE_PARM:
475     case TEMPLATE_PARM_INDEX:
476       pp_cxx_unqualified_id (this, t);
477       break;
478 
479     case STMT_EXPR:
480       pp_cxx_left_paren (this);
481       statement (STMT_EXPR_STMT (t));
482       pp_cxx_right_paren (this);
483       break;
484 
485     case TRAIT_EXPR:
486       pp_cxx_trait_expression (this, t);
487       break;
488 
489     case VA_ARG_EXPR:
490       pp_cxx_va_arg_expression (this, t);
491       break;
492 
493     case OFFSETOF_EXPR:
494       pp_cxx_offsetof_expression (this, t);
495       break;
496 
497     case ADDRESSOF_EXPR:
498       pp_cxx_addressof_expression (this, t);
499       break;
500 
501     case REQUIRES_EXPR:
502       pp_cxx_requires_expr (this, t);
503       break;
504 
505     default:
506       c_pretty_printer::primary_expression (t);
507       break;
508     }
509 }
510 
511 /* postfix-expression:
512      primary-expression
513      postfix-expression [ expression ]
514      postfix-expression ( expression-list(opt) )
515      simple-type-specifier ( expression-list(opt) )
516      typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
517      typename ::(opt) nested-name-specifier template(opt)
518 				       template-id ( expression-list(opt) )
519      postfix-expression . template(opt) ::(opt) id-expression
520      postfix-expression -> template(opt) ::(opt) id-expression
521      postfix-expression . pseudo-destructor-name
522      postfix-expression -> pseudo-destructor-name
523      postfix-expression ++
524      postfix-expression --
525      dynamic_cast < type-id > ( expression )
526      static_cast < type-id > ( expression )
527      reinterpret_cast < type-id > ( expression )
528      const_cast < type-id > ( expression )
529      typeid ( expression )
530      typeid ( type-id )  */
531 
532 void
postfix_expression(tree t)533 cxx_pretty_printer::postfix_expression (tree t)
534 {
535   enum tree_code code = TREE_CODE (t);
536 
537   switch (code)
538     {
539     case AGGR_INIT_EXPR:
540     case CALL_EXPR:
541       {
542 	tree fun = cp_get_callee (t);
543 	tree saved_scope = enclosing_scope;
544 	bool skipfirst = false;
545 	tree arg;
546 
547 	if (TREE_CODE (fun) == ADDR_EXPR)
548 	  fun = TREE_OPERAND (fun, 0);
549 
550 	/* In templates, where there is no way to tell whether a given
551 	   call uses an actual member function.  So the parser builds
552 	   FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
553 	   instantiation time.  */
554 	if (TREE_CODE (fun) != FUNCTION_DECL)
555 	  ;
556 	else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
557 	  {
558 	    tree object = (code == AGGR_INIT_EXPR
559 			   ? (AGGR_INIT_VIA_CTOR_P (t)
560 			      ? AGGR_INIT_EXPR_SLOT (t)
561 			      : AGGR_INIT_EXPR_ARG (t, 0))
562 			   : CALL_EXPR_ARG (t, 0));
563 
564 	    while (TREE_CODE (object) == NOP_EXPR)
565 	      object = TREE_OPERAND (object, 0);
566 
567 	    if (TREE_CODE (object) == ADDR_EXPR)
568 	      object = TREE_OPERAND (object, 0);
569 
570 	    if (!TYPE_PTR_P (TREE_TYPE (object)))
571 	      {
572 		postfix_expression (object);
573 		pp_cxx_dot (this);
574 	      }
575 	    else
576 	      {
577 		postfix_expression (object);
578 		pp_cxx_arrow (this);
579 	      }
580 	    skipfirst = true;
581 	    enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
582 	  }
583 
584 	postfix_expression (fun);
585 	enclosing_scope = saved_scope;
586 	pp_cxx_left_paren (this);
587 	if (code == AGGR_INIT_EXPR)
588 	  {
589 	    aggr_init_expr_arg_iterator iter;
590 	    FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
591 	      {
592 		if (skipfirst)
593 		  skipfirst = false;
594 		else
595 		  {
596 		    expression (arg);
597 		    if (more_aggr_init_expr_args_p (&iter))
598 		      pp_cxx_separate_with (this, ',');
599 		  }
600 	      }
601 	  }
602 	else
603 	  {
604 	    call_expr_arg_iterator iter;
605 	    FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
606 	      {
607 		if (skipfirst)
608 		  skipfirst = false;
609 		else
610 		  {
611 		    expression (arg);
612 		    if (more_call_expr_args_p (&iter))
613 		      pp_cxx_separate_with (this, ',');
614 		  }
615 	      }
616 	  }
617 	pp_cxx_right_paren (this);
618       }
619       if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
620 	{
621 	  pp_cxx_separate_with (this, ',');
622 	  postfix_expression (AGGR_INIT_EXPR_SLOT (t));
623 	}
624       break;
625 
626     case BASELINK:
627     case VAR_DECL:
628     case PARM_DECL:
629     case FIELD_DECL:
630     case FUNCTION_DECL:
631     case OVERLOAD:
632     case CONST_DECL:
633     case TEMPLATE_DECL:
634     case RESULT_DECL:
635       primary_expression (t);
636       break;
637 
638     case DYNAMIC_CAST_EXPR:
639     case STATIC_CAST_EXPR:
640     case REINTERPRET_CAST_EXPR:
641     case CONST_CAST_EXPR:
642       if (code == DYNAMIC_CAST_EXPR)
643 	pp_cxx_ws_string (this, "dynamic_cast");
644       else if (code == STATIC_CAST_EXPR)
645 	pp_cxx_ws_string (this, "static_cast");
646       else if (code == REINTERPRET_CAST_EXPR)
647 	pp_cxx_ws_string (this, "reinterpret_cast");
648       else
649 	pp_cxx_ws_string (this, "const_cast");
650       pp_cxx_begin_template_argument_list (this);
651       type_id (TREE_TYPE (t));
652       pp_cxx_end_template_argument_list (this);
653       pp_left_paren (this);
654       expression (TREE_OPERAND (t, 0));
655       pp_right_paren (this);
656       break;
657 
658     case BIT_CAST_EXPR:
659       pp_cxx_ws_string (this, "__builtin_bit_cast");
660       pp_left_paren (this);
661       type_id (TREE_TYPE (t));
662       pp_comma (this);
663       expression (TREE_OPERAND (t, 0));
664       pp_right_paren (this);
665       break;
666 
667     case EMPTY_CLASS_EXPR:
668       type_id (TREE_TYPE (t));
669       pp_left_paren (this);
670       pp_right_paren (this);
671       break;
672 
673     case TYPEID_EXPR:
674       pp_cxx_typeid_expression (this, t);
675       break;
676 
677     case PSEUDO_DTOR_EXPR:
678       postfix_expression (TREE_OPERAND (t, 0));
679       pp_cxx_dot (this);
680       if (TREE_OPERAND (t, 1))
681 	{
682 	  pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
683 	  pp_cxx_colon_colon (this);
684 	}
685       pp_complement (this);
686       pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
687       break;
688 
689     case ARROW_EXPR:
690       postfix_expression (TREE_OPERAND (t, 0));
691       pp_cxx_arrow (this);
692       break;
693 
694     default:
695       c_pretty_printer::postfix_expression (t);
696       break;
697     }
698 }
699 
700 /* new-expression:
701       ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
702       ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
703 
704    new-placement:
705       ( expression-list )
706 
707    new-type-id:
708       type-specifier-seq new-declarator(opt)
709 
710    new-declarator:
711       ptr-operator new-declarator(opt)
712       direct-new-declarator
713 
714    direct-new-declarator
715       [ expression ]
716       direct-new-declarator [ constant-expression ]
717 
718    new-initializer:
719       ( expression-list(opt) )  */
720 
721 static void
pp_cxx_new_expression(cxx_pretty_printer * pp,tree t)722 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
723 {
724   enum tree_code code = TREE_CODE (t);
725   tree type = TREE_OPERAND (t, 1);
726   tree init = TREE_OPERAND (t, 2);
727   switch (code)
728     {
729     case NEW_EXPR:
730     case VEC_NEW_EXPR:
731       if (NEW_EXPR_USE_GLOBAL (t))
732 	pp_cxx_colon_colon (pp);
733       pp_cxx_ws_string (pp, "new");
734       if (TREE_OPERAND (t, 0))
735 	{
736 	  pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
737 	  pp_space (pp);
738 	}
739       if (TREE_CODE (type) == ARRAY_REF)
740 	type = build_cplus_array_type
741 	  (TREE_OPERAND (type, 0),
742 	   build_index_type (fold_build2_loc (input_location,
743 					  MINUS_EXPR, integer_type_node,
744 					  TREE_OPERAND (type, 1),
745 					  integer_one_node)));
746       pp->type_id (type);
747       if (init)
748 	{
749 	  pp_left_paren (pp);
750 	  if (TREE_CODE (init) == TREE_LIST)
751 	    pp_c_expression_list (pp, init);
752 	  else if (init == void_node)
753 	    ;			/* OK, empty initializer list.  */
754 	  else
755 	    pp->expression (init);
756 	  pp_right_paren (pp);
757 	}
758       break;
759 
760     default:
761       pp_unsupported_tree (pp, t);
762     }
763 }
764 
765 /* delete-expression:
766       ::(opt) delete cast-expression
767       ::(opt) delete [ ] cast-expression   */
768 
769 static void
pp_cxx_delete_expression(cxx_pretty_printer * pp,tree t)770 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
771 {
772   enum tree_code code = TREE_CODE (t);
773   switch (code)
774     {
775     case DELETE_EXPR:
776     case VEC_DELETE_EXPR:
777       if (DELETE_EXPR_USE_GLOBAL (t))
778 	pp_cxx_colon_colon (pp);
779       pp_cxx_ws_string (pp, "delete");
780       pp_space (pp);
781       if (code == VEC_DELETE_EXPR
782 	  || DELETE_EXPR_USE_VEC (t))
783 	{
784 	  pp_left_bracket (pp);
785 	  pp_right_bracket (pp);
786 	  pp_space (pp);
787 	}
788       pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
789       break;
790 
791     default:
792       pp_unsupported_tree (pp, t);
793     }
794 }
795 
796 /* unary-expression:
797       postfix-expression
798       ++ cast-expression
799       -- cast-expression
800       unary-operator cast-expression
801       sizeof unary-expression
802       sizeof ( type-id )
803       sizeof ... ( identifier )
804       new-expression
805       delete-expression
806 
807    unary-operator: one of
808       *   &   +   -  !
809 
810    GNU extensions:
811       __alignof__ unary-expression
812       __alignof__ ( type-id )  */
813 
814 void
unary_expression(tree t)815 cxx_pretty_printer::unary_expression (tree t)
816 {
817   enum tree_code code = TREE_CODE (t);
818   switch (code)
819     {
820     case NEW_EXPR:
821     case VEC_NEW_EXPR:
822       pp_cxx_new_expression (this, t);
823       break;
824 
825     case DELETE_EXPR:
826     case VEC_DELETE_EXPR:
827       pp_cxx_delete_expression (this, t);
828       break;
829 
830     case SIZEOF_EXPR:
831       if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
832 	{
833 	  pp_cxx_ws_string (this, "sizeof");
834 	  pp_cxx_ws_string (this, "...");
835 	  pp_cxx_whitespace (this);
836 	  pp_cxx_left_paren (this);
837 	  if (TYPE_P (TREE_OPERAND (t, 0)))
838 	    type_id (TREE_OPERAND (t, 0));
839 	  else
840 	    unary_expression (TREE_OPERAND (t, 0));
841 	  pp_cxx_right_paren (this);
842 	  break;
843 	}
844       /* Fall through  */
845 
846     case ALIGNOF_EXPR:
847       pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
848       pp_cxx_whitespace (this);
849       if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
850 	{
851 	  pp_cxx_left_paren (this);
852 	  type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
853 	  pp_cxx_right_paren (this);
854 	}
855       else if (TYPE_P (TREE_OPERAND (t, 0)))
856 	{
857 	  pp_cxx_left_paren (this);
858 	  type_id (TREE_OPERAND (t, 0));
859 	  pp_cxx_right_paren (this);
860 	}
861       else
862 	unary_expression (TREE_OPERAND (t, 0));
863       break;
864 
865     case AT_ENCODE_EXPR:
866       pp_cxx_ws_string (this, "@encode");
867       pp_cxx_whitespace (this);
868       pp_cxx_left_paren (this);
869       type_id (TREE_OPERAND (t, 0));
870       pp_cxx_right_paren (this);
871       break;
872 
873     case NOEXCEPT_EXPR:
874       pp_cxx_ws_string (this, "noexcept");
875       pp_cxx_whitespace (this);
876       pp_cxx_left_paren (this);
877       expression (TREE_OPERAND (t, 0));
878       pp_cxx_right_paren (this);
879       break;
880 
881     case UNARY_PLUS_EXPR:
882       pp_plus (this);
883       pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
884       break;
885 
886     default:
887       c_pretty_printer::unary_expression (t);
888       break;
889     }
890 }
891 
892 /* cast-expression:
893       unary-expression
894       ( type-id ) cast-expression  */
895 
896 static void
pp_cxx_cast_expression(cxx_pretty_printer * pp,tree t)897 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
898 {
899   switch (TREE_CODE (t))
900     {
901     case CAST_EXPR:
902     case IMPLICIT_CONV_EXPR:
903       pp->type_id (TREE_TYPE (t));
904       pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
905       break;
906 
907     default:
908       pp_c_cast_expression (pp, t);
909       break;
910     }
911 }
912 
913 /* pm-expression:
914       cast-expression
915       pm-expression .* cast-expression
916       pm-expression ->* cast-expression  */
917 
918 static void
pp_cxx_pm_expression(cxx_pretty_printer * pp,tree t)919 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
920 {
921   switch (TREE_CODE (t))
922     {
923       /* Handle unfortunate OFFSET_REF overloading here.  */
924     case OFFSET_REF:
925       if (TYPE_P (TREE_OPERAND (t, 0)))
926 	{
927 	  pp_cxx_qualified_id (pp, t);
928 	  break;
929 	}
930       /* Fall through.  */
931     case MEMBER_REF:
932     case DOTSTAR_EXPR:
933       pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
934       if (TREE_CODE (t) == MEMBER_REF)
935 	pp_cxx_arrow (pp);
936       else
937 	pp_cxx_dot (pp);
938       pp_star(pp);
939       pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
940       break;
941 
942 
943     default:
944       pp_cxx_cast_expression (pp, t);
945       break;
946     }
947 }
948 
949 /* multiplicative-expression:
950       pm-expression
951       multiplicative-expression * pm-expression
952       multiplicative-expression / pm-expression
953       multiplicative-expression % pm-expression  */
954 
955 void
multiplicative_expression(tree e)956 cxx_pretty_printer::multiplicative_expression (tree e)
957 {
958   enum tree_code code = TREE_CODE (e);
959   switch (code)
960     {
961     case MULT_EXPR:
962     case TRUNC_DIV_EXPR:
963     case TRUNC_MOD_EXPR:
964     case EXACT_DIV_EXPR:
965     case RDIV_EXPR:
966       multiplicative_expression (TREE_OPERAND (e, 0));
967       pp_space (this);
968       if (code == MULT_EXPR)
969 	pp_star (this);
970       else if (code != TRUNC_MOD_EXPR)
971 	pp_slash (this);
972       else
973 	pp_modulo (this);
974       pp_space (this);
975       pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
976       break;
977 
978     default:
979       pp_cxx_pm_expression (this, e);
980       break;
981     }
982 }
983 
984 /* conditional-expression:
985       logical-or-expression
986       logical-or-expression ?  expression  : assignment-expression  */
987 
988 void
conditional_expression(tree e)989 cxx_pretty_printer::conditional_expression (tree e)
990 {
991   if (TREE_CODE (e) == COND_EXPR)
992     {
993       pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
994       pp_space (this);
995       pp_question (this);
996       pp_space (this);
997       expression (TREE_OPERAND (e, 1));
998       pp_space (this);
999       assignment_expression (TREE_OPERAND (e, 2));
1000     }
1001   else
1002     pp_c_logical_or_expression (this, e);
1003 }
1004 
1005 /* Pretty-print a compound assignment operator token as indicated by T.  */
1006 
1007 static void
pp_cxx_assignment_operator(cxx_pretty_printer * pp,tree t)1008 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1009 {
1010   const char *op;
1011 
1012   switch (TREE_CODE (t))
1013     {
1014     case NOP_EXPR:
1015       op = "=";
1016       break;
1017 
1018     case PLUS_EXPR:
1019       op = "+=";
1020       break;
1021 
1022     case MINUS_EXPR:
1023       op = "-=";
1024       break;
1025 
1026     case TRUNC_DIV_EXPR:
1027       op = "/=";
1028       break;
1029 
1030     case TRUNC_MOD_EXPR:
1031       op = "%=";
1032       break;
1033 
1034     default:
1035       op = get_tree_code_name (TREE_CODE (t));
1036       break;
1037     }
1038 
1039   pp_cxx_ws_string (pp, op);
1040 }
1041 
1042 
1043 /* assignment-expression:
1044       conditional-expression
1045       logical-or-expression assignment-operator assignment-expression
1046       throw-expression
1047 
1048    throw-expression:
1049        throw assignment-expression(opt)
1050 
1051    assignment-operator: one of
1052       =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
1053 
1054 void
assignment_expression(tree e)1055 cxx_pretty_printer::assignment_expression (tree e)
1056 {
1057   switch (TREE_CODE (e))
1058     {
1059     case MODIFY_EXPR:
1060     case INIT_EXPR:
1061       pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1062       pp_space (this);
1063       pp_equal (this);
1064       pp_space (this);
1065       assignment_expression (TREE_OPERAND (e, 1));
1066       break;
1067 
1068     case THROW_EXPR:
1069       pp_cxx_ws_string (this, "throw");
1070       if (TREE_OPERAND (e, 0))
1071 	assignment_expression (TREE_OPERAND (e, 0));
1072       break;
1073 
1074     case MODOP_EXPR:
1075       pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1076       pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1077       assignment_expression (TREE_OPERAND (e, 2));
1078       break;
1079 
1080     default:
1081       conditional_expression (e);
1082       break;
1083     }
1084 }
1085 
1086 void
expression(tree t)1087 cxx_pretty_printer::expression (tree t)
1088 {
1089   switch (TREE_CODE (t))
1090     {
1091     case STRING_CST:
1092     case VOID_CST:
1093     case INTEGER_CST:
1094     case REAL_CST:
1095     case COMPLEX_CST:
1096       constant (t);
1097       break;
1098 
1099     case USERDEF_LITERAL:
1100       pp_cxx_userdef_literal (this, t);
1101       break;
1102 
1103     case RESULT_DECL:
1104       pp_cxx_unqualified_id (this, t);
1105       break;
1106 
1107 #if 0
1108     case OFFSET_REF:
1109 #endif
1110     case SCOPE_REF:
1111     case PTRMEM_CST:
1112       pp_cxx_qualified_id (this, t);
1113       break;
1114 
1115     case OVERLOAD:
1116       t = OVL_FIRST (t);
1117       /* FALLTHRU */
1118     case VAR_DECL:
1119     case PARM_DECL:
1120     case FIELD_DECL:
1121     case CONST_DECL:
1122     case FUNCTION_DECL:
1123     case BASELINK:
1124     case TEMPLATE_DECL:
1125     case TEMPLATE_TYPE_PARM:
1126     case TEMPLATE_PARM_INDEX:
1127     case TEMPLATE_TEMPLATE_PARM:
1128     case STMT_EXPR:
1129     case REQUIRES_EXPR:
1130       primary_expression (t);
1131       break;
1132 
1133     case CALL_EXPR:
1134     case DYNAMIC_CAST_EXPR:
1135     case STATIC_CAST_EXPR:
1136     case REINTERPRET_CAST_EXPR:
1137     case CONST_CAST_EXPR:
1138 #if 0
1139     case MEMBER_REF:
1140 #endif
1141     case EMPTY_CLASS_EXPR:
1142     case TYPEID_EXPR:
1143     case PSEUDO_DTOR_EXPR:
1144     case AGGR_INIT_EXPR:
1145     case ARROW_EXPR:
1146       postfix_expression (t);
1147       break;
1148 
1149     case NEW_EXPR:
1150     case VEC_NEW_EXPR:
1151       pp_cxx_new_expression (this, t);
1152       break;
1153 
1154     case DELETE_EXPR:
1155     case VEC_DELETE_EXPR:
1156       pp_cxx_delete_expression (this, t);
1157       break;
1158 
1159     case SIZEOF_EXPR:
1160     case ALIGNOF_EXPR:
1161     case NOEXCEPT_EXPR:
1162     case UNARY_PLUS_EXPR:
1163       unary_expression (t);
1164       break;
1165 
1166     case CAST_EXPR:
1167     case IMPLICIT_CONV_EXPR:
1168       pp_cxx_cast_expression (this, t);
1169       break;
1170 
1171     case OFFSET_REF:
1172     case MEMBER_REF:
1173     case DOTSTAR_EXPR:
1174       pp_cxx_pm_expression (this, t);
1175       break;
1176 
1177     case MULT_EXPR:
1178     case TRUNC_DIV_EXPR:
1179     case TRUNC_MOD_EXPR:
1180     case EXACT_DIV_EXPR:
1181     case RDIV_EXPR:
1182       multiplicative_expression (t);
1183       break;
1184 
1185     case COND_EXPR:
1186       conditional_expression (t);
1187       break;
1188 
1189     case MODIFY_EXPR:
1190     case INIT_EXPR:
1191     case THROW_EXPR:
1192     case MODOP_EXPR:
1193       assignment_expression (t);
1194       break;
1195 
1196     case NON_DEPENDENT_EXPR:
1197     case MUST_NOT_THROW_EXPR:
1198       expression (TREE_OPERAND (t, 0));
1199       break;
1200 
1201     case EXPR_PACK_EXPANSION:
1202       expression (PACK_EXPANSION_PATTERN (t));
1203       pp_cxx_ws_string (this, "...");
1204       break;
1205 
1206     case UNARY_LEFT_FOLD_EXPR:
1207       pp_cxx_unary_left_fold_expression (this, t);
1208       break;
1209 
1210     case UNARY_RIGHT_FOLD_EXPR:
1211       pp_cxx_unary_right_fold_expression (this, t);
1212     break;
1213 
1214     case BINARY_LEFT_FOLD_EXPR:
1215     case BINARY_RIGHT_FOLD_EXPR:
1216       pp_cxx_binary_fold_expression (this, t);
1217       break;
1218 
1219     case TEMPLATE_ID_EXPR:
1220       pp_cxx_template_id (this, t);
1221       break;
1222 
1223     case NONTYPE_ARGUMENT_PACK:
1224       {
1225 	tree args = ARGUMENT_PACK_ARGS (t);
1226 	int i, len = TREE_VEC_LENGTH (args);
1227 	pp_cxx_left_brace (this);
1228 	for (i = 0; i < len; ++i)
1229 	  {
1230 	    if (i > 0)
1231 	      pp_cxx_separate_with (this, ',');
1232 	    expression (TREE_VEC_ELT (args, i));
1233 	  }
1234 	pp_cxx_right_brace (this);
1235       }
1236       break;
1237 
1238     case LAMBDA_EXPR:
1239       pp_cxx_ws_string (this, "<lambda>");
1240       break;
1241 
1242     case TRAIT_EXPR:
1243       pp_cxx_trait_expression (this, t);
1244       break;
1245 
1246     case ATOMIC_CONSTR:
1247     case CHECK_CONSTR:
1248     case CONJ_CONSTR:
1249     case DISJ_CONSTR:
1250       pp_cxx_constraint (this, t);
1251       break;
1252 
1253     case PAREN_EXPR:
1254       pp_cxx_left_paren (this);
1255       expression (TREE_OPERAND (t, 0));
1256       pp_cxx_right_paren (this);
1257       break;
1258 
1259     default:
1260       c_pretty_printer::expression (t);
1261       break;
1262     }
1263 }
1264 
1265 
1266 /* Declarations.  */
1267 
1268 /* function-specifier:
1269       inline
1270       virtual
1271       explicit   */
1272 
1273 void
function_specifier(tree t)1274 cxx_pretty_printer::function_specifier (tree t)
1275 {
1276   switch (TREE_CODE (t))
1277     {
1278     case FUNCTION_DECL:
1279       if (DECL_VIRTUAL_P (t))
1280 	pp_cxx_ws_string (this, "virtual");
1281       else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1282 	pp_cxx_ws_string (this, "explicit");
1283       else
1284         c_pretty_printer::function_specifier (t);
1285 
1286     default:
1287       break;
1288     }
1289 }
1290 
1291 /* decl-specifier-seq:
1292       decl-specifier-seq(opt) decl-specifier
1293 
1294    decl-specifier:
1295       storage-class-specifier
1296       type-specifier
1297       function-specifier
1298       friend
1299       typedef  */
1300 
1301 void
declaration_specifiers(tree t)1302 cxx_pretty_printer::declaration_specifiers (tree t)
1303 {
1304   switch (TREE_CODE (t))
1305     {
1306     case VAR_DECL:
1307     case PARM_DECL:
1308     case CONST_DECL:
1309     case FIELD_DECL:
1310       storage_class_specifier (t);
1311       declaration_specifiers (TREE_TYPE (t));
1312       break;
1313 
1314     case TYPE_DECL:
1315       pp_cxx_ws_string (this, "typedef");
1316       declaration_specifiers (TREE_TYPE (t));
1317       break;
1318 
1319     case FUNCTION_DECL:
1320       /* Constructors don't have return types.  And conversion functions
1321 	 do not have a type-specifier in their return types.  */
1322       if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1323 	function_specifier (t);
1324       else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1325 	declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1326       else
1327         c_pretty_printer::declaration_specifiers (t);
1328       break;
1329     default:
1330         c_pretty_printer::declaration_specifiers (t);
1331       break;
1332     }
1333 }
1334 
1335 /* simple-type-specifier:
1336       ::(opt) nested-name-specifier(opt) type-name
1337       ::(opt) nested-name-specifier(opt) template(opt) template-id
1338       decltype-specifier
1339       char
1340       wchar_t
1341       bool
1342       short
1343       int
1344       long
1345       signed
1346       unsigned
1347       float
1348       double
1349       void  */
1350 
1351 void
simple_type_specifier(tree t)1352 cxx_pretty_printer::simple_type_specifier (tree t)
1353 {
1354   switch (TREE_CODE (t))
1355     {
1356     case RECORD_TYPE:
1357     case UNION_TYPE:
1358     case ENUMERAL_TYPE:
1359       pp_cxx_qualified_id (this, t);
1360       break;
1361 
1362     case TEMPLATE_TYPE_PARM:
1363     case TEMPLATE_TEMPLATE_PARM:
1364     case TEMPLATE_PARM_INDEX:
1365     case BOUND_TEMPLATE_TEMPLATE_PARM:
1366       pp_cxx_unqualified_id (this, t);
1367       if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1368         pp_cxx_constrained_type_spec (this, c);
1369       break;
1370 
1371     case TYPENAME_TYPE:
1372       pp_cxx_ws_string (this, "typename");
1373       pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1374       pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1375       break;
1376 
1377     case DECLTYPE_TYPE:
1378       pp_cxx_ws_string (this, "decltype");
1379       pp_cxx_left_paren (this);
1380       this->expression (DECLTYPE_TYPE_EXPR (t));
1381       pp_cxx_right_paren (this);
1382       break;
1383 
1384     case NULLPTR_TYPE:
1385       pp_cxx_ws_string (this, "std::nullptr_t");
1386       break;
1387 
1388     default:
1389       c_pretty_printer::simple_type_specifier (t);
1390       break;
1391     }
1392 }
1393 
1394 /* type-specifier-seq:
1395       type-specifier type-specifier-seq(opt)
1396 
1397    type-specifier:
1398       simple-type-specifier
1399       class-specifier
1400       enum-specifier
1401       elaborated-type-specifier
1402       cv-qualifier   */
1403 
1404 static void
pp_cxx_type_specifier_seq(cxx_pretty_printer * pp,tree t)1405 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1406 {
1407   switch (TREE_CODE (t))
1408     {
1409     case TEMPLATE_DECL:
1410     case TEMPLATE_TYPE_PARM:
1411     case TEMPLATE_TEMPLATE_PARM:
1412     case TYPE_DECL:
1413     case BOUND_TEMPLATE_TEMPLATE_PARM:
1414     case DECLTYPE_TYPE:
1415     case NULLPTR_TYPE:
1416       pp_cxx_cv_qualifier_seq (pp, t);
1417       pp->simple_type_specifier (t);
1418       break;
1419 
1420     case METHOD_TYPE:
1421       pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1422       pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1423       pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1424       break;
1425 
1426     case RECORD_TYPE:
1427       if (TYPE_PTRMEMFUNC_P (t))
1428 	{
1429 	  tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1430 	  pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1431 	  pp_cxx_whitespace (pp);
1432 	  pp_cxx_ptr_operator (pp, t);
1433 	  break;
1434 	}
1435       /* fall through */
1436 
1437     case OFFSET_TYPE:
1438       if (TYPE_PTRDATAMEM_P (t))
1439 	{
1440 	  pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1441 	  pp_cxx_whitespace (pp);
1442 	  pp_cxx_ptr_operator (pp, t);
1443 	  break;
1444 	}
1445       /* fall through */
1446 
1447     default:
1448       if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1449 	pp_c_specifier_qualifier_list (pp, t);
1450     }
1451 }
1452 
1453 /* ptr-operator:
1454       * cv-qualifier-seq(opt)
1455       &
1456       ::(opt) nested-name-specifier * cv-qualifier-seq(opt)  */
1457 
1458 static void
pp_cxx_ptr_operator(cxx_pretty_printer * pp,tree t)1459 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1460 {
1461   if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1462     t = TREE_TYPE (t);
1463   switch (TREE_CODE (t))
1464     {
1465     case REFERENCE_TYPE:
1466     case POINTER_TYPE:
1467       if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1468 	pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1469       pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1470       if (TYPE_PTR_P (t))
1471 	{
1472 	  pp_star (pp);
1473 	  pp_cxx_cv_qualifier_seq (pp, t);
1474 	}
1475       else
1476 	pp_ampersand (pp);
1477       break;
1478 
1479     case RECORD_TYPE:
1480       if (TYPE_PTRMEMFUNC_P (t))
1481 	{
1482 	  pp_cxx_left_paren (pp);
1483 	  pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1484 	  pp_star (pp);
1485 	  break;
1486 	}
1487       /* FALLTHRU */
1488     case OFFSET_TYPE:
1489       if (TYPE_PTRMEM_P (t))
1490 	{
1491 	  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1492 	    pp_cxx_left_paren (pp);
1493 	  pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1494 	  pp_star (pp);
1495 	  pp_cxx_cv_qualifier_seq (pp, t);
1496 	  break;
1497 	}
1498       /* fall through.  */
1499 
1500     default:
1501       pp_unsupported_tree (pp, t);
1502       break;
1503     }
1504 }
1505 
1506 static inline tree
pp_cxx_implicit_parameter_type(tree mf)1507 pp_cxx_implicit_parameter_type (tree mf)
1508 {
1509   return class_of_this_parm (TREE_TYPE (mf));
1510 }
1511 
1512 /*
1513    parameter-declaration:
1514       decl-specifier-seq declarator
1515       decl-specifier-seq declarator = assignment-expression
1516       decl-specifier-seq abstract-declarator(opt)
1517       decl-specifier-seq abstract-declarator(opt) assignment-expression  */
1518 
1519 static inline void
pp_cxx_parameter_declaration(cxx_pretty_printer * pp,tree t)1520 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1521 {
1522   pp->declaration_specifiers (t);
1523   if (TYPE_P (t))
1524     pp->abstract_declarator (t);
1525   else
1526     pp->declarator (t);
1527 }
1528 
1529 /* parameter-declaration-clause:
1530       parameter-declaration-list(opt) ...(opt)
1531       parameter-declaration-list , ...
1532 
1533    parameter-declaration-list:
1534       parameter-declaration
1535       parameter-declaration-list , parameter-declaration  */
1536 
1537 static void
pp_cxx_parameter_declaration_clause(cxx_pretty_printer * pp,tree t)1538 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1539 {
1540   gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1541   tree types, args;
1542   if (TYPE_P (t))
1543     {
1544       types = TYPE_ARG_TYPES (t);
1545       args = NULL_TREE;
1546     }
1547   else
1548     {
1549       types = FUNCTION_FIRST_USER_PARMTYPE (t);
1550       args = FUNCTION_FIRST_USER_PARM (t);
1551     }
1552   bool abstract = !args || (pp->flags & pp_c_flag_abstract);
1553 
1554   /* Skip artificial parameter for non-static member functions.  */
1555   if (TREE_CODE (t) == METHOD_TYPE)
1556     types = TREE_CHAIN (types);
1557 
1558   bool first = true;
1559   pp_cxx_left_paren (pp);
1560   for (; types != void_list_node; types = TREE_CHAIN (types))
1561     {
1562       if (!first)
1563 	pp_cxx_separate_with (pp, ',');
1564       first = false;
1565       if (!types)
1566 	{
1567 	  pp_cxx_ws_string (pp, "...");
1568 	  break;
1569 	}
1570       pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1571       if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1572 	{
1573 	  pp_cxx_whitespace (pp);
1574 	  pp_equal (pp);
1575 	  pp_cxx_whitespace (pp);
1576 	  pp->assignment_expression (TREE_PURPOSE (types));
1577 	}
1578       if (!abstract)
1579 	args = TREE_CHAIN (args);
1580     }
1581   pp_cxx_right_paren (pp);
1582 }
1583 
1584 /* exception-specification:
1585       throw ( type-id-list(opt) )
1586 
1587    type-id-list
1588       type-id
1589       type-id-list , type-id   */
1590 
1591 static void
pp_cxx_exception_specification(cxx_pretty_printer * pp,tree t)1592 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1593 {
1594   tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1595   bool need_comma = false;
1596 
1597   if (ex_spec == NULL)
1598     return;
1599   if (TREE_PURPOSE (ex_spec))
1600     {
1601       pp_cxx_ws_string (pp, "noexcept");
1602       pp_cxx_whitespace (pp);
1603       pp_cxx_left_paren (pp);
1604       if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1605 	pp_cxx_ws_string (pp, "<uninstantiated>");
1606       else
1607 	pp->expression (TREE_PURPOSE (ex_spec));
1608       pp_cxx_right_paren (pp);
1609       return;
1610     }
1611   pp_cxx_ws_string (pp, "throw");
1612   pp_cxx_left_paren (pp);
1613   for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1614     {
1615       tree type = TREE_VALUE (ex_spec);
1616       tree argpack = NULL_TREE;
1617       int i, len = 1;
1618 
1619       if (ARGUMENT_PACK_P (type))
1620 	{
1621 	  argpack = ARGUMENT_PACK_ARGS (type);
1622 	  len = TREE_VEC_LENGTH (argpack);
1623 	}
1624 
1625       for (i = 0; i < len; ++i)
1626 	{
1627 	  if (argpack)
1628 	    type = TREE_VEC_ELT (argpack, i);
1629 
1630 	  if (need_comma)
1631 	    pp_cxx_separate_with (pp, ',');
1632 	  else
1633 	    need_comma = true;
1634 
1635 	  pp->type_id (type);
1636 	}
1637     }
1638   pp_cxx_right_paren (pp);
1639 }
1640 
1641 /* direct-declarator:
1642       declarator-id
1643       direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1644 					    exception-specification(opt)
1645       direct-declaration [ constant-expression(opt) ]
1646       ( declarator )  */
1647 
1648 void
direct_declarator(tree t)1649 cxx_pretty_printer::direct_declarator (tree t)
1650 {
1651   switch (TREE_CODE (t))
1652     {
1653     case VAR_DECL:
1654     case PARM_DECL:
1655     case CONST_DECL:
1656     case FIELD_DECL:
1657       if (DECL_NAME (t))
1658 	{
1659 	  pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1660 
1661 	  if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1662 	      || template_parameter_pack_p (t))
1663 	    /* A function parameter pack or non-type template
1664 	       parameter pack.  */
1665 	    pp_cxx_ws_string (this, "...");
1666 
1667 	  id_expression (DECL_NAME (t));
1668 	}
1669       abstract_declarator (TREE_TYPE (t));
1670       break;
1671 
1672     case FUNCTION_DECL:
1673       pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1674       expression (t);
1675       pp_cxx_parameter_declaration_clause (this, t);
1676 
1677       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1678 	{
1679 	  padding = pp_before;
1680 	  pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1681 	}
1682 
1683       pp_cxx_exception_specification (this, TREE_TYPE (t));
1684       break;
1685 
1686     case TYPENAME_TYPE:
1687     case TEMPLATE_DECL:
1688     case TEMPLATE_TYPE_PARM:
1689     case TEMPLATE_PARM_INDEX:
1690     case TEMPLATE_TEMPLATE_PARM:
1691       break;
1692 
1693     default:
1694       c_pretty_printer::direct_declarator (t);
1695       break;
1696     }
1697 }
1698 
1699 /* declarator:
1700    direct-declarator
1701    ptr-operator declarator  */
1702 
1703 void
declarator(tree t)1704 cxx_pretty_printer::declarator (tree t)
1705 {
1706   direct_declarator (t);
1707 
1708   // Print a requires clause.
1709   if (flag_concepts)
1710     if (tree ci = get_constraints (t))
1711       if (tree reqs = CI_DECLARATOR_REQS (ci))
1712         pp_cxx_requires_clause (this, reqs);
1713 }
1714 
1715 /* ctor-initializer:
1716       : mem-initializer-list
1717 
1718    mem-initializer-list:
1719       mem-initializer
1720       mem-initializer , mem-initializer-list
1721 
1722    mem-initializer:
1723       mem-initializer-id ( expression-list(opt) )
1724 
1725    mem-initializer-id:
1726       ::(opt) nested-name-specifier(opt) class-name
1727       identifier   */
1728 
1729 static void
pp_cxx_ctor_initializer(cxx_pretty_printer * pp,tree t)1730 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1731 {
1732   t = TREE_OPERAND (t, 0);
1733   pp_cxx_whitespace (pp);
1734   pp_colon (pp);
1735   pp_cxx_whitespace (pp);
1736   for (; t; t = TREE_CHAIN (t))
1737     {
1738       tree purpose = TREE_PURPOSE (t);
1739       bool is_pack = PACK_EXPANSION_P (purpose);
1740 
1741       if (is_pack)
1742 	pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1743       else
1744 	pp->primary_expression (purpose);
1745       pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1746       if (is_pack)
1747 	pp_cxx_ws_string (pp, "...");
1748       if (TREE_CHAIN (t))
1749 	pp_cxx_separate_with (pp, ',');
1750     }
1751 }
1752 
1753 /* function-definition:
1754       decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1755       decl-specifier-seq(opt) declarator function-try-block  */
1756 
1757 static void
pp_cxx_function_definition(cxx_pretty_printer * pp,tree t)1758 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1759 {
1760   tree saved_scope = pp->enclosing_scope;
1761   pp->declaration_specifiers (t);
1762   pp->declarator (t);
1763   pp_needs_newline (pp) = true;
1764   pp->enclosing_scope = DECL_CONTEXT (t);
1765   if (DECL_SAVED_TREE (t))
1766     pp->statement (DECL_SAVED_TREE (t));
1767   else
1768     pp_cxx_semicolon (pp);
1769   pp_newline_and_flush (pp);
1770   pp->enclosing_scope = saved_scope;
1771 }
1772 
1773 /* abstract-declarator:
1774       ptr-operator abstract-declarator(opt)
1775       direct-abstract-declarator  */
1776 
1777 void
abstract_declarator(tree t)1778 cxx_pretty_printer::abstract_declarator (tree t)
1779 {
1780   /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1781      or a pointer-to-data-member of array type:
1782 
1783        void (X::*)()
1784        int (X::*)[5]
1785 
1786      but not for a pointer-to-data-member of non-array type:
1787 
1788        int X::*
1789 
1790      so be mindful of that.  */
1791   if (TYPE_PTRMEMFUNC_P (t)
1792       || (TYPE_PTRDATAMEM_P (t)
1793 	  && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
1794     pp_cxx_right_paren (this);
1795   else if (INDIRECT_TYPE_P (t))
1796     {
1797       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1798 	  || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1799 	pp_cxx_right_paren (this);
1800       t = TREE_TYPE (t);
1801     }
1802   direct_abstract_declarator (t);
1803 }
1804 
1805 /* direct-abstract-declarator:
1806       direct-abstract-declarator(opt) ( parameter-declaration-clause )
1807 			   cv-qualifier-seq(opt) exception-specification(opt)
1808       direct-abstract-declarator(opt) [ constant-expression(opt) ]
1809       ( abstract-declarator )  */
1810 
1811 void
direct_abstract_declarator(tree t)1812 cxx_pretty_printer::direct_abstract_declarator (tree t)
1813 {
1814   switch (TREE_CODE (t))
1815     {
1816     case REFERENCE_TYPE:
1817       abstract_declarator (t);
1818       break;
1819 
1820     case RECORD_TYPE:
1821       if (TYPE_PTRMEMFUNC_P (t))
1822 	direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1823       break;
1824 
1825     case OFFSET_TYPE:
1826       if (TYPE_PTRDATAMEM_P (t))
1827 	direct_abstract_declarator (TREE_TYPE (t));
1828       break;
1829 
1830     case METHOD_TYPE:
1831     case FUNCTION_TYPE:
1832       pp_cxx_parameter_declaration_clause (this, t);
1833       direct_abstract_declarator (TREE_TYPE (t));
1834       if (TREE_CODE (t) == METHOD_TYPE)
1835 	{
1836 	  padding = pp_before;
1837 	  pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1838 	}
1839       pp_cxx_exception_specification (this, t);
1840       break;
1841 
1842     case TYPENAME_TYPE:
1843     case TEMPLATE_TYPE_PARM:
1844     case TEMPLATE_TEMPLATE_PARM:
1845     case BOUND_TEMPLATE_TEMPLATE_PARM:
1846     case UNBOUND_CLASS_TEMPLATE:
1847     case DECLTYPE_TYPE:
1848       break;
1849 
1850     default:
1851       c_pretty_printer::direct_abstract_declarator (t);
1852       break;
1853     }
1854 }
1855 
1856 /* type-id:
1857      type-specifier-seq abstract-declarator(opt) */
1858 
1859 void
type_id(tree t)1860 cxx_pretty_printer::type_id (tree t)
1861 {
1862   pp_flags saved_flags = flags;
1863   flags |= pp_c_flag_abstract;
1864 
1865   switch (TREE_CODE (t))
1866     {
1867     case TYPE_DECL:
1868     case UNION_TYPE:
1869     case RECORD_TYPE:
1870     case ENUMERAL_TYPE:
1871     case TYPENAME_TYPE:
1872     case BOUND_TEMPLATE_TEMPLATE_PARM:
1873     case UNBOUND_CLASS_TEMPLATE:
1874     case TEMPLATE_TEMPLATE_PARM:
1875     case TEMPLATE_TYPE_PARM:
1876     case TEMPLATE_PARM_INDEX:
1877     case TEMPLATE_DECL:
1878     case TYPEOF_TYPE:
1879     case UNDERLYING_TYPE:
1880     case DECLTYPE_TYPE:
1881     case NULLPTR_TYPE:
1882     case TEMPLATE_ID_EXPR:
1883     case OFFSET_TYPE:
1884       pp_cxx_type_specifier_seq (this, t);
1885       if (TYPE_PTRMEM_P (t))
1886 	abstract_declarator (t);
1887       break;
1888 
1889     case TYPE_PACK_EXPANSION:
1890       type_id (PACK_EXPANSION_PATTERN (t));
1891       pp_cxx_ws_string (this, "...");
1892       break;
1893 
1894     case TYPE_ARGUMENT_PACK:
1895       {
1896 	tree args = ARGUMENT_PACK_ARGS (t);
1897 	int len = TREE_VEC_LENGTH (args);
1898 	pp_cxx_left_brace (this);
1899 	for (int i = 0; i < len; ++i)
1900 	  {
1901 	    if (i > 0)
1902 	      pp_cxx_separate_with (this, ',');
1903 	    type_id (TREE_VEC_ELT (args, i));
1904 	  }
1905 	pp_cxx_right_brace (this);
1906       }
1907       break;
1908 
1909     default:
1910       c_pretty_printer::type_id (t);
1911       break;
1912     }
1913 
1914   flags = saved_flags;
1915 }
1916 
1917 /* template-argument-list:
1918       template-argument ...(opt)
1919       template-argument-list, template-argument ...(opt)
1920 
1921    template-argument:
1922       assignment-expression
1923       type-id
1924       template-name  */
1925 
1926 static void
pp_cxx_template_argument_list(cxx_pretty_printer * pp,tree t)1927 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1928 {
1929   int i;
1930   bool need_comma = false;
1931 
1932   if (t == NULL)
1933     return;
1934   for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1935     {
1936       tree arg = TREE_VEC_ELT (t, i);
1937       tree argpack = NULL_TREE;
1938       int idx, len = 1;
1939 
1940       if (ARGUMENT_PACK_P (arg))
1941 	{
1942 	  argpack = ARGUMENT_PACK_ARGS (arg);
1943 	  len = TREE_VEC_LENGTH (argpack);
1944 	}
1945 
1946       for (idx = 0; idx < len; idx++)
1947 	{
1948 	  if (argpack)
1949 	    arg = TREE_VEC_ELT (argpack, idx);
1950 
1951 	  if (need_comma)
1952 	    pp_cxx_separate_with (pp, ',');
1953 	  else
1954 	    need_comma = true;
1955 
1956 	  if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1957 			       && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1958 	    pp->type_id (arg);
1959 	  else if (template_parm_object_p (arg))
1960 	    pp->expression (DECL_INITIAL (arg));
1961 	  else
1962 	    pp->expression (arg);
1963 	}
1964     }
1965 }
1966 
1967 
1968 static void
pp_cxx_exception_declaration(cxx_pretty_printer * pp,tree t)1969 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1970 {
1971   t = DECL_EXPR_DECL (t);
1972   pp_cxx_type_specifier_seq (pp, t);
1973   if (TYPE_P (t))
1974     pp->abstract_declarator (t);
1975   else
1976     pp->declarator (t);
1977 }
1978 
1979 /* Statements.  */
1980 
1981 void
statement(tree t)1982 cxx_pretty_printer::statement (tree t)
1983 {
1984   switch (TREE_CODE (t))
1985     {
1986     case CTOR_INITIALIZER:
1987       pp_cxx_ctor_initializer (this, t);
1988       break;
1989 
1990     case USING_STMT:
1991       pp_cxx_ws_string (this, "using");
1992       pp_cxx_ws_string (this, "namespace");
1993       if (DECL_CONTEXT (t))
1994 	pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1995       pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1996       break;
1997 
1998     case USING_DECL:
1999       pp_cxx_ws_string (this, "using");
2000       pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2001       pp_cxx_unqualified_id (this, DECL_NAME (t));
2002       break;
2003 
2004     case EH_SPEC_BLOCK:
2005       break;
2006 
2007       /* try-block:
2008 	    try compound-statement handler-seq  */
2009     case TRY_BLOCK:
2010       pp_maybe_newline_and_indent (this, 0);
2011       pp_cxx_ws_string (this, "try");
2012       pp_newline_and_indent (this, 3);
2013       statement (TRY_STMTS (t));
2014       pp_newline_and_indent (this, -3);
2015       if (CLEANUP_P (t))
2016 	;
2017       else
2018 	statement (TRY_HANDLERS (t));
2019       break;
2020 
2021       /*
2022 	 handler-seq:
2023 	    handler handler-seq(opt)
2024 
2025 	 handler:
2026 	 catch ( exception-declaration ) compound-statement
2027 
2028 	 exception-declaration:
2029 	    type-specifier-seq declarator
2030 	    type-specifier-seq abstract-declarator
2031 	    ...   */
2032     case HANDLER:
2033       pp_cxx_ws_string (this, "catch");
2034       pp_cxx_left_paren (this);
2035       pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2036       pp_cxx_right_paren (this);
2037       pp_indentation (this) += 3;
2038       pp_needs_newline (this) = true;
2039       statement (HANDLER_BODY (t));
2040       pp_indentation (this) -= 3;
2041       pp_needs_newline (this) = true;
2042       break;
2043 
2044       /* selection-statement:
2045 	    if ( expression ) statement
2046 	    if ( expression ) statement else statement  */
2047     case IF_STMT:
2048       pp_cxx_ws_string (this, "if");
2049       pp_cxx_whitespace (this);
2050       pp_cxx_left_paren (this);
2051       expression (IF_COND (t));
2052       pp_cxx_right_paren (this);
2053       pp_newline_and_indent (this, 2);
2054       statement (THEN_CLAUSE (t));
2055       pp_newline_and_indent (this, -2);
2056       if (ELSE_CLAUSE (t))
2057 	{
2058 	  tree else_clause = ELSE_CLAUSE (t);
2059 	  pp_cxx_ws_string (this, "else");
2060 	  if (TREE_CODE (else_clause) == IF_STMT)
2061 	    pp_cxx_whitespace (this);
2062 	  else
2063 	    pp_newline_and_indent (this, 2);
2064 	  statement (else_clause);
2065 	  if (TREE_CODE (else_clause) != IF_STMT)
2066 	    pp_newline_and_indent (this, -2);
2067 	}
2068       break;
2069 
2070     case RANGE_FOR_STMT:
2071       pp_cxx_ws_string (this, "for");
2072       pp_space (this);
2073       pp_cxx_left_paren (this);
2074       if (RANGE_FOR_INIT_STMT (t))
2075 	{
2076 	  statement (RANGE_FOR_INIT_STMT (t));
2077 	  pp_needs_newline (this) = false;
2078 	  pp_cxx_whitespace (this);
2079 	}
2080       statement (RANGE_FOR_DECL (t));
2081       pp_space (this);
2082       pp_needs_newline (this) = false;
2083       pp_colon (this);
2084       pp_space (this);
2085       statement (RANGE_FOR_EXPR (t));
2086       pp_cxx_right_paren (this);
2087       pp_newline_and_indent (this, 3);
2088       statement (FOR_BODY (t));
2089       pp_indentation (this) -= 3;
2090       pp_needs_newline (this) = true;
2091       break;
2092 
2093       /* expression-statement:
2094 	    expression(opt) ;  */
2095     case EXPR_STMT:
2096       expression (EXPR_STMT_EXPR (t));
2097       pp_cxx_semicolon (this);
2098       pp_needs_newline (this) = true;
2099       break;
2100 
2101     case CLEANUP_STMT:
2102       pp_cxx_ws_string (this, "try");
2103       pp_newline_and_indent (this, 2);
2104       statement (CLEANUP_BODY (t));
2105       pp_newline_and_indent (this, -2);
2106       pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2107       pp_newline_and_indent (this, 2);
2108       statement (CLEANUP_EXPR (t));
2109       pp_newline_and_indent (this, -2);
2110       break;
2111 
2112     case STATIC_ASSERT:
2113       declaration (t);
2114       break;
2115 
2116     case OMP_DEPOBJ:
2117       pp_cxx_ws_string (this, "#pragma omp depobj");
2118       pp_space (this);
2119       pp_cxx_left_paren (this);
2120       expression (OMP_DEPOBJ_DEPOBJ (t));
2121       pp_cxx_right_paren (this);
2122       if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2123 	{
2124 	  if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2125 	    dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2126 			      pp_indentation (this), TDF_NONE);
2127 	  else
2128 	    switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2129 	      {
2130 	      case OMP_CLAUSE_DEPEND_IN:
2131 		pp_cxx_ws_string (this, " update(in)");
2132 		break;
2133 	      case OMP_CLAUSE_DEPEND_INOUT:
2134 		pp_cxx_ws_string (this, " update(inout)");
2135 		break;
2136 	      case OMP_CLAUSE_DEPEND_OUT:
2137 		pp_cxx_ws_string (this, " update(out)");
2138 		break;
2139 	      case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2140 		pp_cxx_ws_string (this, " update(mutexinoutset)");
2141 		break;
2142 	      case OMP_CLAUSE_DEPEND_LAST:
2143 		pp_cxx_ws_string (this, " destroy");
2144 		break;
2145 	      default:
2146 		break;
2147 	      }
2148 	}
2149       pp_needs_newline (this) = true;
2150       break;
2151 
2152     default:
2153       c_pretty_printer::statement (t);
2154       break;
2155     }
2156 }
2157 
2158 /* original-namespace-definition:
2159       namespace identifier { namespace-body }
2160 
2161   As an edge case, we also handle unnamed namespace definition here.  */
2162 
2163 static void
pp_cxx_original_namespace_definition(cxx_pretty_printer * pp,tree t)2164 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2165 {
2166   pp_cxx_ws_string (pp, "namespace");
2167   if (DECL_CONTEXT (t))
2168     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2169   if (DECL_NAME (t))
2170     pp_cxx_unqualified_id (pp, t);
2171   pp_cxx_whitespace (pp);
2172   pp_cxx_left_brace (pp);
2173   /* We do not print the namespace-body.  */
2174   pp_cxx_whitespace (pp);
2175   pp_cxx_right_brace (pp);
2176 }
2177 
2178 /* namespace-alias:
2179       identifier
2180 
2181    namespace-alias-definition:
2182       namespace identifier = qualified-namespace-specifier ;
2183 
2184    qualified-namespace-specifier:
2185       ::(opt) nested-name-specifier(opt) namespace-name   */
2186 
2187 static void
pp_cxx_namespace_alias_definition(cxx_pretty_printer * pp,tree t)2188 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2189 {
2190   pp_cxx_ws_string (pp, "namespace");
2191   if (DECL_CONTEXT (t))
2192     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2193   pp_cxx_unqualified_id (pp, t);
2194   pp_cxx_whitespace (pp);
2195   pp_equal (pp);
2196   pp_cxx_whitespace (pp);
2197   if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2198     pp_cxx_nested_name_specifier (pp,
2199 				  DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2200   pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2201   pp_cxx_semicolon (pp);
2202 }
2203 
2204 /* simple-declaration:
2205       decl-specifier-seq(opt) init-declarator-list(opt)  */
2206 
2207 static void
pp_cxx_simple_declaration(cxx_pretty_printer * pp,tree t)2208 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2209 {
2210   pp->declaration_specifiers (t);
2211   pp_cxx_init_declarator (pp, t);
2212   pp_cxx_semicolon (pp);
2213   pp_needs_newline (pp) = true;
2214 }
2215 
2216 /*
2217   template-parameter-list:
2218      template-parameter
2219      template-parameter-list , template-parameter  */
2220 
2221 static inline void
pp_cxx_template_parameter_list(cxx_pretty_printer * pp,tree t)2222 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2223 {
2224   const int n = TREE_VEC_LENGTH (t);
2225   int i;
2226   for (i = 0; i < n; ++i)
2227     {
2228       if (i)
2229 	pp_cxx_separate_with (pp, ',');
2230       pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2231     }
2232 }
2233 
2234 /* template-parameter:
2235       type-parameter
2236       parameter-declaration
2237 
2238    type-parameter:
2239      class ...(opt) identifier(opt)
2240      class identifier(opt) = type-id
2241      typename identifier(opt)
2242      typename ...(opt) identifier(opt) = type-id
2243      template < template-parameter-list > class ...(opt) identifier(opt)
2244      template < template-parameter-list > class identifier(opt) = template-name  */
2245 
2246 static void
pp_cxx_template_parameter(cxx_pretty_printer * pp,tree t)2247 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2248 {
2249   tree parameter =  TREE_VALUE (t);
2250   switch (TREE_CODE (parameter))
2251     {
2252     case TYPE_DECL:
2253       pp_cxx_ws_string (pp, "class");
2254       if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2255 	pp_cxx_ws_string (pp, "...");
2256       if (DECL_NAME (parameter))
2257 	pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2258       /* FIXME: Check if we should print also default argument.  */
2259       break;
2260 
2261     case PARM_DECL:
2262       pp_cxx_parameter_declaration (pp, parameter);
2263       break;
2264 
2265     case TEMPLATE_DECL:
2266       break;
2267 
2268     default:
2269       pp_unsupported_tree (pp, t);
2270       break;
2271     }
2272 }
2273 
2274 /* Pretty-print a template parameter in the canonical form
2275    "template-parameter-<level>-<position in parameter list>".  */
2276 
2277 void
pp_cxx_canonical_template_parameter(cxx_pretty_printer * pp,tree parm)2278 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2279 {
2280   const enum tree_code code = TREE_CODE (parm);
2281 
2282   /* Brings type template parameters to the canonical forms.  */
2283   if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2284       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2285     parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2286 
2287   pp_cxx_begin_template_argument_list (pp);
2288   pp->translate_string ("template-parameter-");
2289   pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2290   pp_minus (pp);
2291   pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2292   pp_cxx_end_template_argument_list (pp);
2293 }
2294 
2295 /* Print a constrained-type-specifier.  */
2296 
2297 void
pp_cxx_constrained_type_spec(cxx_pretty_printer * pp,tree c)2298 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2299 {
2300   pp_cxx_whitespace (pp);
2301   pp_cxx_left_bracket (pp);
2302   pp->translate_string ("requires");
2303   pp_cxx_whitespace (pp);
2304   if (c == error_mark_node)
2305     {
2306       pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2307       return;
2308     }
2309   tree t, a;
2310   placeholder_extract_concept_and_args (c, t, a);
2311   pp->id_expression (t);
2312   pp_cxx_begin_template_argument_list (pp);
2313   pp_cxx_ws_string (pp, "<placeholder>");
2314   pp_cxx_separate_with (pp, ',');
2315   tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2316   for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2317     TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2318   pp_cxx_template_argument_list (pp, args);
2319   ggc_free (args);
2320   pp_cxx_end_template_argument_list (pp);
2321   pp_cxx_right_bracket (pp);
2322 }
2323 
2324 /*
2325   template-declaration:
2326      export(opt) template < template-parameter-list > declaration
2327 
2328   Concept extensions:
2329 
2330   template-declaration:
2331      export(opt) template < template-parameter-list >
2332        requires-clause(opt) declaration */
2333 
2334 static void
pp_cxx_template_declaration(cxx_pretty_printer * pp,tree t)2335 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2336 {
2337   tree tmpl = most_general_template (t);
2338   tree level;
2339 
2340   pp_maybe_newline_and_indent (pp, 0);
2341   for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2342     {
2343       pp_cxx_ws_string (pp, "template");
2344       pp_cxx_begin_template_argument_list (pp);
2345       pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2346       pp_cxx_end_template_argument_list (pp);
2347       pp_newline_and_indent (pp, 3);
2348     }
2349 
2350   if (flag_concepts)
2351     if (tree ci = get_constraints (t))
2352       if (tree reqs = CI_TEMPLATE_REQS (ci))
2353          {
2354             pp_cxx_requires_clause (pp, reqs);
2355             pp_newline_and_indent (pp, 6);
2356          }
2357 
2358   if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2359     pp_cxx_function_definition (pp, t);
2360   else if (TREE_CODE (t) == CONCEPT_DECL)
2361     pp_cxx_concept_definition (pp, t);
2362   else
2363     pp_cxx_simple_declaration (pp, t);
2364 }
2365 
2366 static void
pp_cxx_explicit_specialization(cxx_pretty_printer * pp,tree t)2367 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2368 {
2369   pp_unsupported_tree (pp, t);
2370 }
2371 
2372 static void
pp_cxx_explicit_instantiation(cxx_pretty_printer * pp,tree t)2373 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2374 {
2375   pp_unsupported_tree (pp, t);
2376 }
2377 
2378 static void
pp_cxx_concept_definition(cxx_pretty_printer * pp,tree t)2379 pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2380 {
2381   pp_cxx_unqualified_id (pp, DECL_NAME (t));
2382   pp_cxx_whitespace (pp);
2383   pp_cxx_ws_string (pp, "=");
2384   pp_cxx_whitespace (pp);
2385   pp->expression (DECL_INITIAL (t));
2386   pp_cxx_semicolon (pp);
2387 }
2388 
2389 /*
2390     declaration:
2391        block-declaration
2392        function-definition
2393        template-declaration
2394        explicit-instantiation
2395        explicit-specialization
2396        linkage-specification
2397        namespace-definition
2398 
2399     block-declaration:
2400        simple-declaration
2401        asm-definition
2402        namespace-alias-definition
2403        using-declaration
2404        using-directive
2405        static_assert-declaration */
2406 void
declaration(tree t)2407 cxx_pretty_printer::declaration (tree t)
2408 {
2409   if (TREE_CODE (t) == STATIC_ASSERT)
2410     {
2411       pp_cxx_ws_string (this, "static_assert");
2412       pp_cxx_left_paren (this);
2413       expression (STATIC_ASSERT_CONDITION (t));
2414       pp_cxx_separate_with (this, ',');
2415       expression (STATIC_ASSERT_MESSAGE (t));
2416       pp_cxx_right_paren (this);
2417     }
2418   else if (!DECL_LANG_SPECIFIC (t))
2419     pp_cxx_simple_declaration (this, t);
2420   else if (DECL_USE_TEMPLATE (t))
2421     switch (DECL_USE_TEMPLATE (t))
2422       {
2423       case 1:
2424 	pp_cxx_template_declaration (this, t);
2425 	break;
2426 
2427       case 2:
2428 	pp_cxx_explicit_specialization (this, t);
2429 	break;
2430 
2431       case 3:
2432 	pp_cxx_explicit_instantiation (this, t);
2433 	break;
2434 
2435       default:
2436 	break;
2437       }
2438   else switch (TREE_CODE (t))
2439     {
2440     case VAR_DECL:
2441     case TYPE_DECL:
2442       pp_cxx_simple_declaration (this, t);
2443       break;
2444 
2445     case FUNCTION_DECL:
2446       if (DECL_SAVED_TREE (t))
2447 	pp_cxx_function_definition (this, t);
2448       else
2449 	pp_cxx_simple_declaration (this, t);
2450       break;
2451 
2452     case NAMESPACE_DECL:
2453       if (DECL_NAMESPACE_ALIAS (t))
2454 	pp_cxx_namespace_alias_definition (this, t);
2455       else
2456 	pp_cxx_original_namespace_definition (this, t);
2457       break;
2458 
2459     default:
2460       pp_unsupported_tree (this, t);
2461       break;
2462     }
2463 }
2464 
2465 static void
pp_cxx_typeid_expression(cxx_pretty_printer * pp,tree t)2466 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2467 {
2468   t = TREE_OPERAND (t, 0);
2469   pp_cxx_ws_string (pp, "typeid");
2470   pp_cxx_left_paren (pp);
2471   if (TYPE_P (t))
2472     pp->type_id (t);
2473   else
2474     pp->expression (t);
2475   pp_cxx_right_paren (pp);
2476 }
2477 
2478 void
pp_cxx_va_arg_expression(cxx_pretty_printer * pp,tree t)2479 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2480 {
2481   pp_cxx_ws_string (pp, "va_arg");
2482   pp_cxx_left_paren (pp);
2483   pp->assignment_expression (TREE_OPERAND (t, 0));
2484   pp_cxx_separate_with (pp, ',');
2485   pp->type_id (TREE_TYPE (t));
2486   pp_cxx_right_paren (pp);
2487 }
2488 
2489 static bool
pp_cxx_offsetof_expression_1(cxx_pretty_printer * pp,tree t)2490 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2491 {
2492   switch (TREE_CODE (t))
2493     {
2494     case ARROW_EXPR:
2495       if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2496 	  && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2497 	{
2498 	  pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2499 	  pp_cxx_separate_with (pp, ',');
2500 	  return true;
2501 	}
2502       return false;
2503     case COMPONENT_REF:
2504       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2505 	return false;
2506       if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2507 	pp_cxx_dot (pp);
2508       pp->expression (TREE_OPERAND (t, 1));
2509       return true;
2510     case ARRAY_REF:
2511       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2512 	return false;
2513       pp_left_bracket (pp);
2514       pp->expression (TREE_OPERAND (t, 1));
2515       pp_right_bracket (pp);
2516       return true;
2517     default:
2518       return false;
2519     }
2520 }
2521 
2522 void
pp_cxx_offsetof_expression(cxx_pretty_printer * pp,tree t)2523 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2524 {
2525   pp_cxx_ws_string (pp, "offsetof");
2526   pp_cxx_left_paren (pp);
2527   if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2528     pp->expression (TREE_OPERAND (t, 0));
2529   pp_cxx_right_paren (pp);
2530 }
2531 
2532 void
pp_cxx_addressof_expression(cxx_pretty_printer * pp,tree t)2533 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2534 {
2535   pp_cxx_ws_string (pp, "__builtin_addressof");
2536   pp_cxx_left_paren (pp);
2537   pp->expression (TREE_OPERAND (t, 0));
2538   pp_cxx_right_paren (pp);
2539 }
2540 
2541 static char const*
get_fold_operator(tree t)2542 get_fold_operator (tree t)
2543 {
2544   ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2545 				     FOLD_EXPR_OP (t));
2546   return info->name;
2547 }
2548 
2549 void
pp_cxx_unary_left_fold_expression(cxx_pretty_printer * pp,tree t)2550 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2551 {
2552   char const* op = get_fold_operator (t);
2553   tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2554   pp_cxx_left_paren (pp);
2555   pp_cxx_ws_string (pp, "...");
2556   pp_cxx_ws_string (pp, op);
2557   pp->expression (expr);
2558   pp_cxx_right_paren (pp);
2559 }
2560 
2561 void
pp_cxx_unary_right_fold_expression(cxx_pretty_printer * pp,tree t)2562 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2563 {
2564   char const* op = get_fold_operator (t);
2565   tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2566   pp_cxx_left_paren (pp);
2567   pp->expression (expr);
2568   pp_space (pp);
2569   pp_cxx_ws_string (pp, op);
2570   pp_cxx_ws_string (pp, "...");
2571   pp_cxx_right_paren (pp);
2572 }
2573 
2574 void
pp_cxx_binary_fold_expression(cxx_pretty_printer * pp,tree t)2575 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2576 {
2577   char const* op = get_fold_operator (t);
2578   tree t1 = TREE_OPERAND (t, 1);
2579   tree t2 = TREE_OPERAND (t, 2);
2580   if (t1 == FOLD_EXPR_PACK (t))
2581     t1 = PACK_EXPANSION_PATTERN (t1);
2582   else
2583     t2 = PACK_EXPANSION_PATTERN (t2);
2584   pp_cxx_left_paren (pp);
2585   pp->expression (t1);
2586   pp_cxx_ws_string (pp, op);
2587   pp_cxx_ws_string (pp, "...");
2588   pp_cxx_ws_string (pp, op);
2589   pp->expression (t2);
2590   pp_cxx_right_paren (pp);
2591 }
2592 
2593 void
pp_cxx_trait_expression(cxx_pretty_printer * pp,tree t)2594 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2595 {
2596   cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2597 
2598   switch (kind)
2599     {
2600     case CPTK_HAS_NOTHROW_ASSIGN:
2601       pp_cxx_ws_string (pp, "__has_nothrow_assign");
2602       break;
2603     case CPTK_HAS_TRIVIAL_ASSIGN:
2604       pp_cxx_ws_string (pp, "__has_trivial_assign");
2605       break;
2606     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2607       pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2608       break;
2609     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2610       pp_cxx_ws_string (pp, "__has_trivial_constructor");
2611       break;
2612     case CPTK_HAS_NOTHROW_COPY:
2613       pp_cxx_ws_string (pp, "__has_nothrow_copy");
2614       break;
2615     case CPTK_HAS_TRIVIAL_COPY:
2616       pp_cxx_ws_string (pp, "__has_trivial_copy");
2617       break;
2618     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2619       pp_cxx_ws_string (pp, "__has_trivial_destructor");
2620       break;
2621     case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2622       pp_cxx_ws_string (pp, "__has_unique_object_representations");
2623       break;
2624     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2625       pp_cxx_ws_string (pp, "__has_virtual_destructor");
2626       break;
2627     case CPTK_IS_ABSTRACT:
2628       pp_cxx_ws_string (pp, "__is_abstract");
2629       break;
2630     case CPTK_IS_AGGREGATE:
2631       pp_cxx_ws_string (pp, "__is_aggregate");
2632       break;
2633     case CPTK_IS_BASE_OF:
2634       pp_cxx_ws_string (pp, "__is_base_of");
2635       break;
2636     case CPTK_IS_CLASS:
2637       pp_cxx_ws_string (pp, "__is_class");
2638       break;
2639     case CPTK_IS_EMPTY:
2640       pp_cxx_ws_string (pp, "__is_empty");
2641       break;
2642     case CPTK_IS_ENUM:
2643       pp_cxx_ws_string (pp, "__is_enum");
2644       break;
2645     case CPTK_IS_FINAL:
2646       pp_cxx_ws_string (pp, "__is_final");
2647       break;
2648     case CPTK_IS_LAYOUT_COMPATIBLE:
2649       pp_cxx_ws_string (pp, "__is_layout_compatible");
2650       break;
2651     case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
2652       pp_cxx_ws_string (pp, "__is_pointer_interconvertible_base_of");
2653       break;
2654     case CPTK_IS_POD:
2655       pp_cxx_ws_string (pp, "__is_pod");
2656       break;
2657     case CPTK_IS_POLYMORPHIC:
2658       pp_cxx_ws_string (pp, "__is_polymorphic");
2659       break;
2660     case CPTK_IS_SAME_AS:
2661       pp_cxx_ws_string (pp, "__is_same");
2662       break;
2663     case CPTK_IS_STD_LAYOUT:
2664       pp_cxx_ws_string (pp, "__is_std_layout");
2665       break;
2666     case CPTK_IS_TRIVIAL:
2667       pp_cxx_ws_string (pp, "__is_trivial");
2668       break;
2669     case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2670       pp_cxx_ws_string (pp, "__is_trivially_assignable");
2671       break;
2672     case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2673       pp_cxx_ws_string (pp, "__is_trivially_constructible");
2674       break;
2675     case CPTK_IS_TRIVIALLY_COPYABLE:
2676       pp_cxx_ws_string (pp, "__is_trivially_copyable");
2677       break;
2678     case CPTK_IS_UNION:
2679       pp_cxx_ws_string (pp, "__is_union");
2680       break;
2681     case CPTK_IS_LITERAL_TYPE:
2682       pp_cxx_ws_string (pp, "__is_literal_type");
2683       break;
2684     case CPTK_IS_ASSIGNABLE:
2685       pp_cxx_ws_string (pp, "__is_assignable");
2686       break;
2687     case CPTK_IS_CONSTRUCTIBLE:
2688       pp_cxx_ws_string (pp, "__is_constructible");
2689       break;
2690     case CPTK_IS_NOTHROW_ASSIGNABLE:
2691       pp_cxx_ws_string (pp, "__is_nothrow_assignable");
2692       break;
2693     case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
2694       pp_cxx_ws_string (pp, "__is_nothrow_constructible");
2695       break;
2696 
2697     default:
2698       gcc_unreachable ();
2699     }
2700 
2701   pp_cxx_left_paren (pp);
2702   pp->type_id (TRAIT_EXPR_TYPE1 (t));
2703 
2704   if (kind == CPTK_IS_BASE_OF
2705       || kind == CPTK_IS_SAME_AS
2706       || kind == CPTK_IS_LAYOUT_COMPATIBLE
2707       || kind == CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF)
2708     {
2709       pp_cxx_separate_with (pp, ',');
2710       pp->type_id (TRAIT_EXPR_TYPE2 (t));
2711     }
2712 
2713   pp_cxx_right_paren (pp);
2714 }
2715 
2716 // requires-clause:
2717 //    'requires' logical-or-expression
2718 void
pp_cxx_requires_clause(cxx_pretty_printer * pp,tree t)2719 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2720 {
2721   if (!t)
2722     return;
2723   pp->padding = pp_before;
2724   pp_cxx_ws_string (pp, "requires");
2725   pp_space (pp);
2726   pp->expression (t);
2727 }
2728 
2729 /* requirement:
2730      simple-requirement
2731      compound-requirement
2732      type-requirement
2733      nested-requirement */
2734 static void
pp_cxx_requirement(cxx_pretty_printer * pp,tree t)2735 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2736 {
2737   switch (TREE_CODE (t))
2738     {
2739     case SIMPLE_REQ:
2740       pp_cxx_simple_requirement (pp, t);
2741       break;
2742 
2743     case TYPE_REQ:
2744       pp_cxx_type_requirement (pp, t);
2745       break;
2746 
2747     case COMPOUND_REQ:
2748       pp_cxx_compound_requirement (pp, t);
2749       break;
2750 
2751     case NESTED_REQ:
2752       pp_cxx_nested_requirement (pp, t);
2753       break;
2754 
2755     default:
2756       gcc_unreachable ();
2757     }
2758 }
2759 
2760 // requirement-list:
2761 //    requirement
2762 //    requirement-list ';' requirement[opt]
2763 //
2764 static void
pp_cxx_requirement_list(cxx_pretty_printer * pp,tree t)2765 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2766 {
2767   for (; t; t = TREE_CHAIN (t))
2768     pp_cxx_requirement (pp, TREE_VALUE (t));
2769 }
2770 
2771 // requirement-body:
2772 //    '{' requirement-list '}'
2773 static void
pp_cxx_requirement_body(cxx_pretty_printer * pp,tree t)2774 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2775 {
2776   pp_cxx_left_brace (pp);
2777   pp_cxx_requirement_list (pp, t);
2778   pp_cxx_right_brace (pp);
2779 }
2780 
2781 // requires-expression:
2782 //    'requires' requirement-parameter-list requirement-body
2783 void
pp_cxx_requires_expr(cxx_pretty_printer * pp,tree t)2784 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2785 {
2786   pp_string (pp, "requires");
2787   if (tree parms = REQUIRES_EXPR_PARMS (t))
2788     {
2789       bool first = true;
2790       pp_cxx_left_paren (pp);
2791       for (; parms; parms = TREE_CHAIN (parms))
2792 	{
2793 	  if (!first)
2794 	    pp_cxx_separate_with (pp, ',' );
2795 	  first = false;
2796 	  pp_cxx_parameter_declaration (pp, parms);
2797 	}
2798       pp_cxx_right_paren (pp);
2799       pp_cxx_whitespace (pp);
2800     }
2801   pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2802 }
2803 
2804 /* simple-requirement:
2805      expression ';' */
2806 void
pp_cxx_simple_requirement(cxx_pretty_printer * pp,tree t)2807 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2808 {
2809   pp->expression (TREE_OPERAND (t, 0));
2810   pp_cxx_semicolon (pp);
2811 }
2812 
2813 /* type-requirement:
2814      typename type-name ';' */
2815 void
pp_cxx_type_requirement(cxx_pretty_printer * pp,tree t)2816 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2817 {
2818   pp->type_id (TREE_OPERAND (t, 0));
2819   pp_cxx_semicolon (pp);
2820 }
2821 
2822 /* compound-requirement:
2823      '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2824 void
pp_cxx_compound_requirement(cxx_pretty_printer * pp,tree t)2825 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2826 {
2827   pp_cxx_left_brace (pp);
2828   pp->expression (TREE_OPERAND (t, 0));
2829   pp_cxx_right_brace (pp);
2830 
2831   if (COMPOUND_REQ_NOEXCEPT_P (t))
2832     pp_cxx_ws_string (pp, "noexcept");
2833 
2834   if (tree type = TREE_OPERAND (t, 1))
2835     {
2836       pp_cxx_whitespace (pp);
2837       pp_cxx_ws_string (pp, "->");
2838       pp->type_id (type);
2839     }
2840   pp_cxx_semicolon (pp);
2841 }
2842 
2843 /* nested requirement:
2844      'requires' constraint-expression */
2845 void
pp_cxx_nested_requirement(cxx_pretty_printer * pp,tree t)2846 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2847 {
2848   pp_cxx_ws_string (pp, "requires");
2849   pp->expression (TREE_OPERAND (t, 0));
2850   pp_cxx_semicolon (pp);
2851 }
2852 
2853 void
pp_cxx_check_constraint(cxx_pretty_printer * pp,tree t)2854 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2855 {
2856   tree decl = CHECK_CONSTR_CONCEPT (t);
2857   tree tmpl = DECL_TI_TEMPLATE (decl);
2858   tree args = CHECK_CONSTR_ARGS (t);
2859   tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2860 
2861   if (TREE_CODE (decl) == CONCEPT_DECL)
2862     pp->expression (id);
2863   else if (VAR_P (decl))
2864     pp->expression (id);
2865   else if (TREE_CODE (decl) == FUNCTION_DECL)
2866     {
2867       tree call = build_vl_exp (CALL_EXPR, 2);
2868       TREE_OPERAND (call, 0) = integer_two_node;
2869       TREE_OPERAND (call, 1) = id;
2870       pp->expression (call);
2871     }
2872   else
2873     gcc_unreachable ();
2874 }
2875 
2876 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2877    constraint.   */
2878 
2879 void
pp_cxx_parameter_mapping(cxx_pretty_printer * pp,tree map)2880 pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2881 {
2882   pp_cxx_whitespace (pp);
2883   pp_cxx_left_bracket (pp);
2884   pp->translate_string ("with");
2885   pp_cxx_whitespace (pp);
2886 
2887   for (tree p = map; p; p = TREE_CHAIN (p))
2888     {
2889       tree parm = TREE_VALUE (p);
2890       tree arg = TREE_PURPOSE (p);
2891 
2892       if (TYPE_P (parm))
2893 	pp->type_id (parm);
2894       else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2895 	pp_cxx_tree_identifier (pp, name);
2896       else
2897 	pp->translate_string ("<unnamed>");
2898 
2899       pp_cxx_whitespace (pp);
2900       pp_equal (pp);
2901       pp_cxx_whitespace (pp);
2902 
2903       if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2904 	pp->type_id (arg);
2905       else
2906 	pp->expression (arg);
2907 
2908       if (TREE_CHAIN (p) != NULL_TREE)
2909 	pp_cxx_separate_with (pp, ';');
2910     }
2911 
2912   pp_cxx_right_bracket (pp);
2913 }
2914 
2915 void
pp_cxx_atomic_constraint(cxx_pretty_printer * pp,tree t)2916 pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2917 {
2918   /* Emit the expression.  */
2919   pp->expression (ATOMIC_CONSTR_EXPR (t));
2920 
2921   /* Emit the parameter mapping.  */
2922   tree map = ATOMIC_CONSTR_MAP (t);
2923   if (map && map != error_mark_node)
2924     pp_cxx_parameter_mapping (pp, map);
2925 }
2926 
2927 void
pp_cxx_conjunction(cxx_pretty_printer * pp,tree t)2928 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2929 {
2930   pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2931   pp_string (pp, " /\\ ");
2932   pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2933 }
2934 
2935 void
pp_cxx_disjunction(cxx_pretty_printer * pp,tree t)2936 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2937 {
2938   pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2939   pp_string (pp, " \\/ ");
2940   pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2941 }
2942 
2943 void
pp_cxx_constraint(cxx_pretty_printer * pp,tree t)2944 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2945 {
2946   if (t == error_mark_node)
2947     return pp->expression (t);
2948 
2949   switch (TREE_CODE (t))
2950     {
2951     case ATOMIC_CONSTR:
2952       pp_cxx_atomic_constraint (pp, t);
2953       break;
2954 
2955     case CHECK_CONSTR:
2956       pp_cxx_check_constraint (pp, t);
2957       break;
2958 
2959     case CONJ_CONSTR:
2960       pp_cxx_conjunction (pp, t);
2961       break;
2962 
2963     case DISJ_CONSTR:
2964       pp_cxx_disjunction (pp, t);
2965       break;
2966 
2967     case EXPR_PACK_EXPANSION:
2968       pp->expression (TREE_OPERAND (t, 0));
2969       break;
2970 
2971     default:
2972       gcc_unreachable ();
2973     }
2974 }
2975 
2976 
2977 typedef c_pretty_print_fn pp_fun;
2978 
2979 /* Initialization of a C++ pretty-printer object.  */
2980 
cxx_pretty_printer()2981 cxx_pretty_printer::cxx_pretty_printer ()
2982   : c_pretty_printer (),
2983     enclosing_scope (global_namespace)
2984 {
2985   type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2986   parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2987 }
2988 
2989 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc.  */
2990 
2991 pretty_printer *
clone() const2992 cxx_pretty_printer::clone () const
2993 {
2994   return new cxx_pretty_printer (*this);
2995 }
2996