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