]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cp/cxx-pretty-print.c
c-objc-common.c (c_tree_printer): Tidy.
[thirdparty/gcc.git] / gcc / cp / cxx-pretty-print.c
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2013 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 "tm.h"
25 #include "intl.h"
26 #include "cp-tree.h"
27 #include "cxx-pretty-print.h"
28 #include "tree-pretty-print.h"
29
30 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
32 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
33 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
34 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
35 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
36 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
37 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
38 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
40 \f
41
42 static inline void
43 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
44 {
45 const char *p = pp_last_position_in_text (pp);
46
47 if (p != NULL && *p == c)
48 pp_cxx_whitespace (pp);
49 pp_character (pp, c);
50 pp->padding = pp_none;
51 }
52
53 #define pp_cxx_expression_list(PP, T) \
54 pp_c_expression_list (PP, T)
55 #define pp_cxx_space_for_pointer_operator(PP, T) \
56 pp_c_space_for_pointer_operator (PP, T)
57 #define pp_cxx_init_declarator(PP, T) \
58 pp_c_init_declarator (PP, T)
59 #define pp_cxx_call_argument_list(PP, T) \
60 pp_c_call_argument_list (PP, T)
61
62 void
63 pp_cxx_colon_colon (cxx_pretty_printer *pp)
64 {
65 pp_colon_colon (pp);
66 pp->padding = pp_none;
67 }
68
69 void
70 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
71 {
72 pp_cxx_nonconsecutive_character (pp, '<');
73 }
74
75 void
76 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
77 {
78 pp_cxx_nonconsecutive_character (pp, '>');
79 }
80
81 void
82 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
83 {
84 pp_separate_with (pp, c);
85 pp->padding = pp_none;
86 }
87
88 /* Expressions. */
89
90 static inline bool
91 is_destructor_name (tree name)
92 {
93 return name == complete_dtor_identifier
94 || name == base_dtor_identifier
95 || name == deleting_dtor_identifier;
96 }
97
98 /* conversion-function-id:
99 operator conversion-type-id
100
101 conversion-type-id:
102 type-specifier-seq conversion-declarator(opt)
103
104 conversion-declarator:
105 ptr-operator conversion-declarator(opt) */
106
107 static inline void
108 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
109 {
110 pp_cxx_ws_string (pp, "operator");
111 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
112 }
113
114 static inline void
115 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
116 {
117 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
118 pp_cxx_begin_template_argument_list (pp);
119 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
120 pp_cxx_end_template_argument_list (pp);
121 }
122
123 /* Prints the unqualified part of the id-expression T.
124
125 unqualified-id:
126 identifier
127 operator-function-id
128 conversion-function-id
129 ~ class-name
130 template-id */
131
132 static void
133 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
134 {
135 enum tree_code code = TREE_CODE (t);
136 switch (code)
137 {
138 case RESULT_DECL:
139 pp->translate_string ("<return-value>");
140 break;
141
142 case OVERLOAD:
143 t = OVL_CURRENT (t);
144 case VAR_DECL:
145 case PARM_DECL:
146 case CONST_DECL:
147 case TYPE_DECL:
148 case FUNCTION_DECL:
149 case NAMESPACE_DECL:
150 case FIELD_DECL:
151 case LABEL_DECL:
152 case USING_DECL:
153 case TEMPLATE_DECL:
154 t = DECL_NAME (t);
155
156 case IDENTIFIER_NODE:
157 if (t == NULL)
158 pp->translate_string ("<unnamed>");
159 else if (IDENTIFIER_TYPENAME_P (t))
160 pp_cxx_conversion_function_id (pp, t);
161 else
162 {
163 if (is_destructor_name (t))
164 {
165 pp_complement (pp);
166 /* FIXME: Why is this necessary? */
167 if (TREE_TYPE (t))
168 t = constructor_name (TREE_TYPE (t));
169 }
170 pp_cxx_tree_identifier (pp, t);
171 }
172 break;
173
174 case TEMPLATE_ID_EXPR:
175 pp_cxx_template_id (pp, t);
176 break;
177
178 case BASELINK:
179 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
180 break;
181
182 case RECORD_TYPE:
183 case UNION_TYPE:
184 case ENUMERAL_TYPE:
185 case TYPENAME_TYPE:
186 case UNBOUND_CLASS_TEMPLATE:
187 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
188 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
189 {
190 pp_cxx_begin_template_argument_list (pp);
191 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
192 (CLASSTYPE_TI_ARGS (t)));
193 pp_cxx_end_template_argument_list (pp);
194 }
195 break;
196
197 case BIT_NOT_EXPR:
198 pp_cxx_complement (pp);
199 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
200 break;
201
202 case TEMPLATE_TYPE_PARM:
203 case TEMPLATE_TEMPLATE_PARM:
204 if (TYPE_IDENTIFIER (t))
205 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
206 else
207 pp_cxx_canonical_template_parameter (pp, t);
208 break;
209
210 case TEMPLATE_PARM_INDEX:
211 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
212 break;
213
214 case BOUND_TEMPLATE_TEMPLATE_PARM:
215 pp_cxx_cv_qualifier_seq (pp, t);
216 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
217 pp_cxx_begin_template_argument_list (pp);
218 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
219 pp_cxx_end_template_argument_list (pp);
220 break;
221
222 default:
223 pp_unsupported_tree (pp, t);
224 break;
225 }
226 }
227
228 /* Pretty-print out the token sequence ":: template" in template codes
229 where it is needed to "inline declare" the (following) member as
230 a template. This situation arises when SCOPE of T is dependent
231 on template parameters. */
232
233 static inline void
234 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
235 {
236 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
237 && TYPE_P (scope) && dependent_type_p (scope))
238 pp_cxx_ws_string (pp, "template");
239 }
240
241 /* nested-name-specifier:
242 class-or-namespace-name :: nested-name-specifier(opt)
243 class-or-namespace-name :: template nested-name-specifier */
244
245 static void
246 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
247 {
248 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
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_CURRENT (t);
282 case FUNCTION_DECL:
283 if (DECL_FUNCTION_MEMBER_P (t))
284 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
285 pp_cxx_unqualified_id
286 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
287 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
288 break;
289
290 case OFFSET_REF:
291 case SCOPE_REF:
292 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
293 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
294 break;
295
296 default:
297 {
298 tree scope = get_containing_scope (t);
299 if (scope != pp->enclosing_scope)
300 {
301 pp_cxx_nested_name_specifier (pp, scope);
302 pp_cxx_template_keyword_if_needed (pp, scope, t);
303 }
304 pp_cxx_unqualified_id (pp, t);
305 }
306 break;
307 }
308 }
309
310
311 void
312 cxx_pretty_printer::constant (tree t)
313 {
314 switch (TREE_CODE (t))
315 {
316 case STRING_CST:
317 {
318 const bool in_parens = PAREN_STRING_LITERAL_P (t);
319 if (in_parens)
320 pp_cxx_left_paren (this);
321 c_pretty_printer::constant (t);
322 if (in_parens)
323 pp_cxx_right_paren (this);
324 }
325 break;
326
327 case INTEGER_CST:
328 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
329 {
330 pp_string (this, "nullptr");
331 break;
332 }
333 /* else fall through. */
334
335 default:
336 c_pretty_printer::constant (t);
337 break;
338 }
339 }
340
341 /* id-expression:
342 unqualified-id
343 qualified-id */
344
345 void
346 cxx_pretty_printer::id_expression (tree t)
347 {
348 if (TREE_CODE (t) == OVERLOAD)
349 t = OVL_CURRENT (t);
350 if (DECL_P (t) && DECL_CONTEXT (t))
351 pp_cxx_qualified_id (this, t);
352 else
353 pp_cxx_unqualified_id (this, t);
354 }
355
356 /* user-defined literal:
357 literal ud-suffix */
358
359 void
360 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
361 {
362 pp->constant (USERDEF_LITERAL_VALUE (t));
363 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
364 }
365
366
367 /* primary-expression:
368 literal
369 this
370 :: identifier
371 :: operator-function-id
372 :: qualifier-id
373 ( expression )
374 id-expression
375
376 GNU Extensions:
377 __builtin_va_arg ( assignment-expression , type-id )
378 __builtin_offsetof ( type-id, offsetof-expression )
379
380 __has_nothrow_assign ( type-id )
381 __has_nothrow_constructor ( type-id )
382 __has_nothrow_copy ( type-id )
383 __has_trivial_assign ( type-id )
384 __has_trivial_constructor ( type-id )
385 __has_trivial_copy ( type-id )
386 __has_trivial_destructor ( type-id )
387 __has_virtual_destructor ( type-id )
388 __is_abstract ( type-id )
389 __is_base_of ( type-id , type-id )
390 __is_class ( type-id )
391 __is_convertible_to ( type-id , type-id )
392 __is_empty ( type-id )
393 __is_enum ( type-id )
394 __is_literal_type ( type-id )
395 __is_pod ( type-id )
396 __is_polymorphic ( type-id )
397 __is_std_layout ( type-id )
398 __is_trivial ( type-id )
399 __is_union ( type-id ) */
400
401 void
402 cxx_pretty_printer::primary_expression (tree t)
403 {
404 switch (TREE_CODE (t))
405 {
406 case INTEGER_CST:
407 case REAL_CST:
408 case COMPLEX_CST:
409 case STRING_CST:
410 constant (t);
411 break;
412
413 case USERDEF_LITERAL:
414 pp_cxx_userdef_literal (this, t);
415 break;
416
417 case BASELINK:
418 t = BASELINK_FUNCTIONS (t);
419 case VAR_DECL:
420 case PARM_DECL:
421 case FIELD_DECL:
422 case FUNCTION_DECL:
423 case OVERLOAD:
424 case CONST_DECL:
425 case TEMPLATE_DECL:
426 id_expression (t);
427 break;
428
429 case RESULT_DECL:
430 case TEMPLATE_TYPE_PARM:
431 case TEMPLATE_TEMPLATE_PARM:
432 case TEMPLATE_PARM_INDEX:
433 pp_cxx_unqualified_id (this, t);
434 break;
435
436 case STMT_EXPR:
437 pp_cxx_left_paren (this);
438 statement (STMT_EXPR_STMT (t));
439 pp_cxx_right_paren (this);
440 break;
441
442 case TRAIT_EXPR:
443 pp_cxx_trait_expression (this, t);
444 break;
445
446 case VA_ARG_EXPR:
447 pp_cxx_va_arg_expression (this, t);
448 break;
449
450 case OFFSETOF_EXPR:
451 pp_cxx_offsetof_expression (this, t);
452 break;
453
454 default:
455 c_pretty_printer::primary_expression (t);
456 break;
457 }
458 }
459
460 /* postfix-expression:
461 primary-expression
462 postfix-expression [ expression ]
463 postfix-expression ( expression-list(opt) )
464 simple-type-specifier ( expression-list(opt) )
465 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
466 typename ::(opt) nested-name-specifier template(opt)
467 template-id ( expression-list(opt) )
468 postfix-expression . template(opt) ::(opt) id-expression
469 postfix-expression -> template(opt) ::(opt) id-expression
470 postfix-expression . pseudo-destructor-name
471 postfix-expression -> pseudo-destructor-name
472 postfix-expression ++
473 postfix-expression --
474 dynamic_cast < type-id > ( expression )
475 static_cast < type-id > ( expression )
476 reinterpret_cast < type-id > ( expression )
477 const_cast < type-id > ( expression )
478 typeid ( expression )
479 typeid ( type-id ) */
480
481 void
482 cxx_pretty_printer::postfix_expression (tree t)
483 {
484 enum tree_code code = TREE_CODE (t);
485
486 switch (code)
487 {
488 case AGGR_INIT_EXPR:
489 case CALL_EXPR:
490 {
491 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
492 : CALL_EXPR_FN (t));
493 tree saved_scope = enclosing_scope;
494 bool skipfirst = false;
495 tree arg;
496
497 if (TREE_CODE (fun) == ADDR_EXPR)
498 fun = TREE_OPERAND (fun, 0);
499
500 /* In templates, where there is no way to tell whether a given
501 call uses an actual member function. So the parser builds
502 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
503 instantiation time. */
504 if (TREE_CODE (fun) != FUNCTION_DECL)
505 ;
506 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
507 {
508 tree object = (code == AGGR_INIT_EXPR
509 ? (AGGR_INIT_VIA_CTOR_P (t)
510 ? AGGR_INIT_EXPR_SLOT (t)
511 : AGGR_INIT_EXPR_ARG (t, 0))
512 : CALL_EXPR_ARG (t, 0));
513
514 while (TREE_CODE (object) == NOP_EXPR)
515 object = TREE_OPERAND (object, 0);
516
517 if (TREE_CODE (object) == ADDR_EXPR)
518 object = TREE_OPERAND (object, 0);
519
520 if (!TYPE_PTR_P (TREE_TYPE (object)))
521 {
522 postfix_expression (object);
523 pp_cxx_dot (this);
524 }
525 else
526 {
527 postfix_expression (object);
528 pp_cxx_arrow (this);
529 }
530 skipfirst = true;
531 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
532 }
533
534 postfix_expression (fun);
535 enclosing_scope = saved_scope;
536 pp_cxx_left_paren (this);
537 if (code == AGGR_INIT_EXPR)
538 {
539 aggr_init_expr_arg_iterator iter;
540 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
541 {
542 if (skipfirst)
543 skipfirst = false;
544 else
545 {
546 expression (arg);
547 if (more_aggr_init_expr_args_p (&iter))
548 pp_cxx_separate_with (this, ',');
549 }
550 }
551 }
552 else
553 {
554 call_expr_arg_iterator iter;
555 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
556 {
557 if (skipfirst)
558 skipfirst = false;
559 else
560 {
561 expression (arg);
562 if (more_call_expr_args_p (&iter))
563 pp_cxx_separate_with (this, ',');
564 }
565 }
566 }
567 pp_cxx_right_paren (this);
568 }
569 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
570 {
571 pp_cxx_separate_with (this, ',');
572 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
573 }
574 break;
575
576 case BASELINK:
577 case VAR_DECL:
578 case PARM_DECL:
579 case FIELD_DECL:
580 case FUNCTION_DECL:
581 case OVERLOAD:
582 case CONST_DECL:
583 case TEMPLATE_DECL:
584 case RESULT_DECL:
585 primary_expression (t);
586 break;
587
588 case DYNAMIC_CAST_EXPR:
589 case STATIC_CAST_EXPR:
590 case REINTERPRET_CAST_EXPR:
591 case CONST_CAST_EXPR:
592 if (code == DYNAMIC_CAST_EXPR)
593 pp_cxx_ws_string (this, "dynamic_cast");
594 else if (code == STATIC_CAST_EXPR)
595 pp_cxx_ws_string (this, "static_cast");
596 else if (code == REINTERPRET_CAST_EXPR)
597 pp_cxx_ws_string (this, "reinterpret_cast");
598 else
599 pp_cxx_ws_string (this, "const_cast");
600 pp_cxx_begin_template_argument_list (this);
601 type_id (TREE_TYPE (t));
602 pp_cxx_end_template_argument_list (this);
603 pp_left_paren (this);
604 expression (TREE_OPERAND (t, 0));
605 pp_right_paren (this);
606 break;
607
608 case EMPTY_CLASS_EXPR:
609 type_id (TREE_TYPE (t));
610 pp_left_paren (this);
611 pp_right_paren (this);
612 break;
613
614 case TYPEID_EXPR:
615 pp_cxx_typeid_expression (this, t);
616 break;
617
618 case PSEUDO_DTOR_EXPR:
619 postfix_expression (TREE_OPERAND (t, 0));
620 pp_cxx_dot (this);
621 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
622 pp_cxx_colon_colon (this);
623 pp_complement (this);
624 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
625 break;
626
627 case ARROW_EXPR:
628 postfix_expression (TREE_OPERAND (t, 0));
629 pp_cxx_arrow (this);
630 break;
631
632 default:
633 c_pretty_printer::postfix_expression (t);
634 break;
635 }
636 }
637
638 /* new-expression:
639 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
640 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
641
642 new-placement:
643 ( expression-list )
644
645 new-type-id:
646 type-specifier-seq new-declarator(opt)
647
648 new-declarator:
649 ptr-operator new-declarator(opt)
650 direct-new-declarator
651
652 direct-new-declarator
653 [ expression ]
654 direct-new-declarator [ constant-expression ]
655
656 new-initializer:
657 ( expression-list(opt) ) */
658
659 static void
660 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
661 {
662 enum tree_code code = TREE_CODE (t);
663 tree type = TREE_OPERAND (t, 1);
664 tree init = TREE_OPERAND (t, 2);
665 switch (code)
666 {
667 case NEW_EXPR:
668 case VEC_NEW_EXPR:
669 if (NEW_EXPR_USE_GLOBAL (t))
670 pp_cxx_colon_colon (pp);
671 pp_cxx_ws_string (pp, "new");
672 if (TREE_OPERAND (t, 0))
673 {
674 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
675 pp_space (pp);
676 }
677 if (TREE_CODE (type) == ARRAY_REF)
678 type = build_cplus_array_type
679 (TREE_OPERAND (type, 0),
680 build_index_type (fold_build2_loc (input_location,
681 MINUS_EXPR, integer_type_node,
682 TREE_OPERAND (type, 1),
683 integer_one_node)));
684 pp->type_id (type);
685 if (init)
686 {
687 pp_left_paren (pp);
688 if (TREE_CODE (init) == TREE_LIST)
689 pp_c_expression_list (pp, init);
690 else if (init == void_zero_node)
691 ; /* OK, empty initializer list. */
692 else
693 pp->expression (init);
694 pp_right_paren (pp);
695 }
696 break;
697
698 default:
699 pp_unsupported_tree (pp, t);
700 }
701 }
702
703 /* delete-expression:
704 ::(opt) delete cast-expression
705 ::(opt) delete [ ] cast-expression */
706
707 static void
708 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
709 {
710 enum tree_code code = TREE_CODE (t);
711 switch (code)
712 {
713 case DELETE_EXPR:
714 case VEC_DELETE_EXPR:
715 if (DELETE_EXPR_USE_GLOBAL (t))
716 pp_cxx_colon_colon (pp);
717 pp_cxx_ws_string (pp, "delete");
718 pp_space (pp);
719 if (code == VEC_DELETE_EXPR
720 || DELETE_EXPR_USE_VEC (t))
721 {
722 pp_left_bracket (pp);
723 pp_right_bracket (pp);
724 pp_space (pp);
725 }
726 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
727 break;
728
729 default:
730 pp_unsupported_tree (pp, t);
731 }
732 }
733
734 /* unary-expression:
735 postfix-expression
736 ++ cast-expression
737 -- cast-expression
738 unary-operator cast-expression
739 sizeof unary-expression
740 sizeof ( type-id )
741 sizeof ... ( identifier )
742 new-expression
743 delete-expression
744
745 unary-operator: one of
746 * & + - !
747
748 GNU extensions:
749 __alignof__ unary-expression
750 __alignof__ ( type-id ) */
751
752 void
753 cxx_pretty_printer::unary_expression (tree t)
754 {
755 enum tree_code code = TREE_CODE (t);
756 switch (code)
757 {
758 case NEW_EXPR:
759 case VEC_NEW_EXPR:
760 pp_cxx_new_expression (this, t);
761 break;
762
763 case DELETE_EXPR:
764 case VEC_DELETE_EXPR:
765 pp_cxx_delete_expression (this, t);
766 break;
767
768 case SIZEOF_EXPR:
769 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
770 {
771 pp_cxx_ws_string (this, "sizeof");
772 pp_cxx_ws_string (this, "...");
773 pp_cxx_whitespace (this);
774 pp_cxx_left_paren (this);
775 if (TYPE_P (TREE_OPERAND (t, 0)))
776 type_id (TREE_OPERAND (t, 0));
777 else
778 unary_expression (TREE_OPERAND (t, 0));
779 pp_cxx_right_paren (this);
780 break;
781 }
782 /* Fall through */
783
784 case ALIGNOF_EXPR:
785 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
786 pp_cxx_whitespace (this);
787 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
788 {
789 pp_cxx_left_paren (this);
790 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
791 pp_cxx_right_paren (this);
792 }
793 else if (TYPE_P (TREE_OPERAND (t, 0)))
794 {
795 pp_cxx_left_paren (this);
796 type_id (TREE_OPERAND (t, 0));
797 pp_cxx_right_paren (this);
798 }
799 else
800 unary_expression (TREE_OPERAND (t, 0));
801 break;
802
803 case AT_ENCODE_EXPR:
804 pp_cxx_ws_string (this, "@encode");
805 pp_cxx_whitespace (this);
806 pp_cxx_left_paren (this);
807 type_id (TREE_OPERAND (t, 0));
808 pp_cxx_right_paren (this);
809 break;
810
811 case NOEXCEPT_EXPR:
812 pp_cxx_ws_string (this, "noexcept");
813 pp_cxx_whitespace (this);
814 pp_cxx_left_paren (this);
815 expression (TREE_OPERAND (t, 0));
816 pp_cxx_right_paren (this);
817 break;
818
819 case UNARY_PLUS_EXPR:
820 pp_plus (this);
821 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
822 break;
823
824 default:
825 c_pretty_printer::unary_expression (t);
826 break;
827 }
828 }
829
830 /* cast-expression:
831 unary-expression
832 ( type-id ) cast-expression */
833
834 static void
835 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
836 {
837 switch (TREE_CODE (t))
838 {
839 case CAST_EXPR:
840 case IMPLICIT_CONV_EXPR:
841 pp->type_id (TREE_TYPE (t));
842 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
843 break;
844
845 default:
846 pp_c_cast_expression (pp, t);
847 break;
848 }
849 }
850
851 /* pm-expression:
852 cast-expression
853 pm-expression .* cast-expression
854 pm-expression ->* cast-expression */
855
856 static void
857 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
858 {
859 switch (TREE_CODE (t))
860 {
861 /* Handle unfortunate OFFSET_REF overloading here. */
862 case OFFSET_REF:
863 if (TYPE_P (TREE_OPERAND (t, 0)))
864 {
865 pp_cxx_qualified_id (pp, t);
866 break;
867 }
868 /* Else fall through. */
869 case MEMBER_REF:
870 case DOTSTAR_EXPR:
871 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
872 if (TREE_CODE (t) == MEMBER_REF)
873 pp_cxx_arrow (pp);
874 else
875 pp_cxx_dot (pp);
876 pp_star(pp);
877 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
878 break;
879
880
881 default:
882 pp_cxx_cast_expression (pp, t);
883 break;
884 }
885 }
886
887 /* multiplicative-expression:
888 pm-expression
889 multiplicative-expression * pm-expression
890 multiplicative-expression / pm-expression
891 multiplicative-expression % pm-expression */
892
893 void
894 cxx_pretty_printer::multiplicative_expression (tree e)
895 {
896 enum tree_code code = TREE_CODE (e);
897 switch (code)
898 {
899 case MULT_EXPR:
900 case TRUNC_DIV_EXPR:
901 case TRUNC_MOD_EXPR:
902 multiplicative_expression (TREE_OPERAND (e, 0));
903 pp_space (this);
904 if (code == MULT_EXPR)
905 pp_star (this);
906 else if (code == TRUNC_DIV_EXPR)
907 pp_slash (this);
908 else
909 pp_modulo (this);
910 pp_space (this);
911 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
912 break;
913
914 default:
915 pp_cxx_pm_expression (this, e);
916 break;
917 }
918 }
919
920 /* conditional-expression:
921 logical-or-expression
922 logical-or-expression ? expression : assignment-expression */
923
924 void
925 cxx_pretty_printer::conditional_expression (tree e)
926 {
927 if (TREE_CODE (e) == COND_EXPR)
928 {
929 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
930 pp_space (this);
931 pp_question (this);
932 pp_space (this);
933 expression (TREE_OPERAND (e, 1));
934 pp_space (this);
935 assignment_expression (TREE_OPERAND (e, 2));
936 }
937 else
938 pp_c_logical_or_expression (this, e);
939 }
940
941 /* Pretty-print a compound assignment operator token as indicated by T. */
942
943 static void
944 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
945 {
946 const char *op;
947
948 switch (TREE_CODE (t))
949 {
950 case NOP_EXPR:
951 op = "=";
952 break;
953
954 case PLUS_EXPR:
955 op = "+=";
956 break;
957
958 case MINUS_EXPR:
959 op = "-=";
960 break;
961
962 case TRUNC_DIV_EXPR:
963 op = "/=";
964 break;
965
966 case TRUNC_MOD_EXPR:
967 op = "%=";
968 break;
969
970 default:
971 op = tree_code_name[TREE_CODE (t)];
972 break;
973 }
974
975 pp_cxx_ws_string (pp, op);
976 }
977
978
979 /* assignment-expression:
980 conditional-expression
981 logical-or-expression assignment-operator assignment-expression
982 throw-expression
983
984 throw-expression:
985 throw assignment-expression(opt)
986
987 assignment-operator: one of
988 = *= /= %= += -= >>= <<= &= ^= |= */
989
990 void
991 cxx_pretty_printer::assignment_expression (tree e)
992 {
993 switch (TREE_CODE (e))
994 {
995 case MODIFY_EXPR:
996 case INIT_EXPR:
997 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
998 pp_space (this);
999 pp_equal (this);
1000 pp_space (this);
1001 assignment_expression (TREE_OPERAND (e, 1));
1002 break;
1003
1004 case THROW_EXPR:
1005 pp_cxx_ws_string (this, "throw");
1006 if (TREE_OPERAND (e, 0))
1007 assignment_expression (TREE_OPERAND (e, 0));
1008 break;
1009
1010 case MODOP_EXPR:
1011 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1012 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1013 assignment_expression (TREE_OPERAND (e, 2));
1014 break;
1015
1016 default:
1017 conditional_expression (e);
1018 break;
1019 }
1020 }
1021
1022 void
1023 cxx_pretty_printer::expression (tree t)
1024 {
1025 switch (TREE_CODE (t))
1026 {
1027 case STRING_CST:
1028 case INTEGER_CST:
1029 case REAL_CST:
1030 case COMPLEX_CST:
1031 constant (t);
1032 break;
1033
1034 case USERDEF_LITERAL:
1035 pp_cxx_userdef_literal (this, t);
1036 break;
1037
1038 case RESULT_DECL:
1039 pp_cxx_unqualified_id (this, t);
1040 break;
1041
1042 #if 0
1043 case OFFSET_REF:
1044 #endif
1045 case SCOPE_REF:
1046 case PTRMEM_CST:
1047 pp_cxx_qualified_id (this, t);
1048 break;
1049
1050 case OVERLOAD:
1051 t = OVL_CURRENT (t);
1052 case VAR_DECL:
1053 case PARM_DECL:
1054 case FIELD_DECL:
1055 case CONST_DECL:
1056 case FUNCTION_DECL:
1057 case BASELINK:
1058 case TEMPLATE_DECL:
1059 case TEMPLATE_TYPE_PARM:
1060 case TEMPLATE_PARM_INDEX:
1061 case TEMPLATE_TEMPLATE_PARM:
1062 case STMT_EXPR:
1063 primary_expression (t);
1064 break;
1065
1066 case CALL_EXPR:
1067 case DYNAMIC_CAST_EXPR:
1068 case STATIC_CAST_EXPR:
1069 case REINTERPRET_CAST_EXPR:
1070 case CONST_CAST_EXPR:
1071 #if 0
1072 case MEMBER_REF:
1073 #endif
1074 case EMPTY_CLASS_EXPR:
1075 case TYPEID_EXPR:
1076 case PSEUDO_DTOR_EXPR:
1077 case AGGR_INIT_EXPR:
1078 case ARROW_EXPR:
1079 postfix_expression (t);
1080 break;
1081
1082 case NEW_EXPR:
1083 case VEC_NEW_EXPR:
1084 pp_cxx_new_expression (this, t);
1085 break;
1086
1087 case DELETE_EXPR:
1088 case VEC_DELETE_EXPR:
1089 pp_cxx_delete_expression (this, t);
1090 break;
1091
1092 case SIZEOF_EXPR:
1093 case ALIGNOF_EXPR:
1094 case NOEXCEPT_EXPR:
1095 unary_expression (t);
1096 break;
1097
1098 case CAST_EXPR:
1099 case IMPLICIT_CONV_EXPR:
1100 pp_cxx_cast_expression (this, t);
1101 break;
1102
1103 case OFFSET_REF:
1104 case MEMBER_REF:
1105 case DOTSTAR_EXPR:
1106 pp_cxx_pm_expression (this, t);
1107 break;
1108
1109 case MULT_EXPR:
1110 case TRUNC_DIV_EXPR:
1111 case TRUNC_MOD_EXPR:
1112 multiplicative_expression (t);
1113 break;
1114
1115 case COND_EXPR:
1116 conditional_expression (t);
1117 break;
1118
1119 case MODIFY_EXPR:
1120 case INIT_EXPR:
1121 case THROW_EXPR:
1122 case MODOP_EXPR:
1123 assignment_expression (t);
1124 break;
1125
1126 case NON_DEPENDENT_EXPR:
1127 case MUST_NOT_THROW_EXPR:
1128 expression (TREE_OPERAND (t, 0));
1129 break;
1130
1131 case EXPR_PACK_EXPANSION:
1132 expression (PACK_EXPANSION_PATTERN (t));
1133 pp_cxx_ws_string (this, "...");
1134 break;
1135
1136 case TEMPLATE_ID_EXPR:
1137 pp_cxx_template_id (this, t);
1138 break;
1139
1140 case NONTYPE_ARGUMENT_PACK:
1141 {
1142 tree args = ARGUMENT_PACK_ARGS (t);
1143 int i, len = TREE_VEC_LENGTH (args);
1144 for (i = 0; i < len; ++i)
1145 {
1146 if (i > 0)
1147 pp_cxx_separate_with (this, ',');
1148 expression (TREE_VEC_ELT (args, i));
1149 }
1150 }
1151 break;
1152
1153 case LAMBDA_EXPR:
1154 pp_cxx_ws_string (this, "<lambda>");
1155 break;
1156
1157 case PAREN_EXPR:
1158 pp_cxx_left_paren (this);
1159 expression (TREE_OPERAND (t, 0));
1160 pp_cxx_right_paren (this);
1161 break;
1162
1163 default:
1164 c_pretty_printer::expression (t);
1165 break;
1166 }
1167 }
1168
1169
1170 /* Declarations. */
1171
1172 /* function-specifier:
1173 inline
1174 virtual
1175 explicit */
1176
1177 void
1178 cxx_pretty_printer::function_specifier (tree t)
1179 {
1180 switch (TREE_CODE (t))
1181 {
1182 case FUNCTION_DECL:
1183 if (DECL_VIRTUAL_P (t))
1184 pp_cxx_ws_string (this, "virtual");
1185 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1186 pp_cxx_ws_string (this, "explicit");
1187 else
1188 c_pretty_printer::function_specifier (t);
1189
1190 default:
1191 break;
1192 }
1193 }
1194
1195 /* decl-specifier-seq:
1196 decl-specifier-seq(opt) decl-specifier
1197
1198 decl-specifier:
1199 storage-class-specifier
1200 type-specifier
1201 function-specifier
1202 friend
1203 typedef */
1204
1205 void
1206 cxx_pretty_printer::declaration_specifiers (tree t)
1207 {
1208 switch (TREE_CODE (t))
1209 {
1210 case VAR_DECL:
1211 case PARM_DECL:
1212 case CONST_DECL:
1213 case FIELD_DECL:
1214 storage_class_specifier (t);
1215 declaration_specifiers (TREE_TYPE (t));
1216 break;
1217
1218 case TYPE_DECL:
1219 pp_cxx_ws_string (this, "typedef");
1220 declaration_specifiers (TREE_TYPE (t));
1221 break;
1222
1223 case FUNCTION_DECL:
1224 /* Constructors don't have return types. And conversion functions
1225 do not have a type-specifier in their return types. */
1226 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1227 function_specifier (t);
1228 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1229 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1230 else
1231 default:
1232 c_pretty_printer::declaration_specifiers (t);
1233 break;
1234 }
1235 }
1236
1237 /* simple-type-specifier:
1238 ::(opt) nested-name-specifier(opt) type-name
1239 ::(opt) nested-name-specifier(opt) template(opt) template-id
1240 char
1241 wchar_t
1242 bool
1243 short
1244 int
1245 long
1246 signed
1247 unsigned
1248 float
1249 double
1250 void */
1251
1252 static void
1253 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1254 {
1255 switch (TREE_CODE (t))
1256 {
1257 case RECORD_TYPE:
1258 case UNION_TYPE:
1259 case ENUMERAL_TYPE:
1260 pp_cxx_qualified_id (pp, t);
1261 break;
1262
1263 case TEMPLATE_TYPE_PARM:
1264 case TEMPLATE_TEMPLATE_PARM:
1265 case TEMPLATE_PARM_INDEX:
1266 case BOUND_TEMPLATE_TEMPLATE_PARM:
1267 pp_cxx_unqualified_id (pp, t);
1268 break;
1269
1270 case TYPENAME_TYPE:
1271 pp_cxx_ws_string (pp, "typename");
1272 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1273 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1274 break;
1275
1276 default:
1277 pp_c_type_specifier (pp, t);
1278 break;
1279 }
1280 }
1281
1282 /* type-specifier-seq:
1283 type-specifier type-specifier-seq(opt)
1284
1285 type-specifier:
1286 simple-type-specifier
1287 class-specifier
1288 enum-specifier
1289 elaborated-type-specifier
1290 cv-qualifier */
1291
1292 static void
1293 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1294 {
1295 switch (TREE_CODE (t))
1296 {
1297 case TEMPLATE_DECL:
1298 case TEMPLATE_TYPE_PARM:
1299 case TEMPLATE_TEMPLATE_PARM:
1300 case TYPE_DECL:
1301 case BOUND_TEMPLATE_TEMPLATE_PARM:
1302 pp_cxx_cv_qualifier_seq (pp, t);
1303 pp_cxx_simple_type_specifier (pp, t);
1304 break;
1305
1306 case METHOD_TYPE:
1307 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1308 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1309 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1310 break;
1311
1312 case DECLTYPE_TYPE:
1313 pp_cxx_ws_string (pp, "decltype");
1314 pp_cxx_left_paren (pp);
1315 pp->expression (DECLTYPE_TYPE_EXPR (t));
1316 pp_cxx_right_paren (pp);
1317 break;
1318
1319 case RECORD_TYPE:
1320 if (TYPE_PTRMEMFUNC_P (t))
1321 {
1322 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1323 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1324 pp_cxx_whitespace (pp);
1325 pp_cxx_ptr_operator (pp, t);
1326 break;
1327 }
1328 /* else fall through */
1329
1330 default:
1331 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1332 pp_c_specifier_qualifier_list (pp, t);
1333 }
1334 }
1335
1336 /* ptr-operator:
1337 * cv-qualifier-seq(opt)
1338 &
1339 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1340
1341 static void
1342 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1343 {
1344 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1345 t = TREE_TYPE (t);
1346 switch (TREE_CODE (t))
1347 {
1348 case REFERENCE_TYPE:
1349 case POINTER_TYPE:
1350 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1351 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1352 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1353 if (TYPE_PTR_P (t))
1354 {
1355 pp_star (pp);
1356 pp_cxx_cv_qualifier_seq (pp, t);
1357 }
1358 else
1359 pp_ampersand (pp);
1360 break;
1361
1362 case RECORD_TYPE:
1363 if (TYPE_PTRMEMFUNC_P (t))
1364 {
1365 pp_cxx_left_paren (pp);
1366 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1367 pp_star (pp);
1368 break;
1369 }
1370 case OFFSET_TYPE:
1371 if (TYPE_PTRMEM_P (t))
1372 {
1373 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1374 pp_cxx_left_paren (pp);
1375 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1376 pp_star (pp);
1377 pp_cxx_cv_qualifier_seq (pp, t);
1378 break;
1379 }
1380 /* else fall through. */
1381
1382 default:
1383 pp_unsupported_tree (pp, t);
1384 break;
1385 }
1386 }
1387
1388 static inline tree
1389 pp_cxx_implicit_parameter_type (tree mf)
1390 {
1391 return class_of_this_parm (TREE_TYPE (mf));
1392 }
1393
1394 /*
1395 parameter-declaration:
1396 decl-specifier-seq declarator
1397 decl-specifier-seq declarator = assignment-expression
1398 decl-specifier-seq abstract-declarator(opt)
1399 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1400
1401 static inline void
1402 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1403 {
1404 pp->declaration_specifiers (t);
1405 if (TYPE_P (t))
1406 pp->abstract_declarator (t);
1407 else
1408 pp->declarator (t);
1409 }
1410
1411 /* parameter-declaration-clause:
1412 parameter-declaration-list(opt) ...(opt)
1413 parameter-declaration-list , ...
1414
1415 parameter-declaration-list:
1416 parameter-declaration
1417 parameter-declaration-list , parameter-declaration */
1418
1419 static void
1420 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1421 {
1422 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1423 tree types =
1424 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1425 const bool abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1426 bool first = true;
1427
1428 /* Skip artificial parameter for nonstatic member functions. */
1429 if (TREE_CODE (t) == METHOD_TYPE)
1430 types = TREE_CHAIN (types);
1431
1432 pp_cxx_left_paren (pp);
1433 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1434 {
1435 if (!first)
1436 pp_cxx_separate_with (pp, ',');
1437 first = false;
1438 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1439 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1440 {
1441 pp_cxx_whitespace (pp);
1442 pp_equal (pp);
1443 pp_cxx_whitespace (pp);
1444 pp->assignment_expression (TREE_PURPOSE (types));
1445 }
1446 }
1447 pp_cxx_right_paren (pp);
1448 }
1449
1450 /* exception-specification:
1451 throw ( type-id-list(opt) )
1452
1453 type-id-list
1454 type-id
1455 type-id-list , type-id */
1456
1457 static void
1458 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1459 {
1460 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1461 bool need_comma = false;
1462
1463 if (ex_spec == NULL)
1464 return;
1465 if (TREE_PURPOSE (ex_spec))
1466 {
1467 pp_cxx_ws_string (pp, "noexcept");
1468 pp_cxx_whitespace (pp);
1469 pp_cxx_left_paren (pp);
1470 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1471 pp_cxx_ws_string (pp, "<uninstantiated>");
1472 else
1473 pp->expression (TREE_PURPOSE (ex_spec));
1474 pp_cxx_right_paren (pp);
1475 return;
1476 }
1477 pp_cxx_ws_string (pp, "throw");
1478 pp_cxx_left_paren (pp);
1479 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1480 {
1481 tree type = TREE_VALUE (ex_spec);
1482 tree argpack = NULL_TREE;
1483 int i, len = 1;
1484
1485 if (ARGUMENT_PACK_P (type))
1486 {
1487 argpack = ARGUMENT_PACK_ARGS (type);
1488 len = TREE_VEC_LENGTH (argpack);
1489 }
1490
1491 for (i = 0; i < len; ++i)
1492 {
1493 if (argpack)
1494 type = TREE_VEC_ELT (argpack, i);
1495
1496 if (need_comma)
1497 pp_cxx_separate_with (pp, ',');
1498 else
1499 need_comma = true;
1500
1501 pp->type_id (type);
1502 }
1503 }
1504 pp_cxx_right_paren (pp);
1505 }
1506
1507 /* direct-declarator:
1508 declarator-id
1509 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1510 exception-specification(opt)
1511 direct-declaration [ constant-expression(opt) ]
1512 ( declarator ) */
1513
1514 void
1515 cxx_pretty_printer::direct_declarator (tree t)
1516 {
1517 switch (TREE_CODE (t))
1518 {
1519 case VAR_DECL:
1520 case PARM_DECL:
1521 case CONST_DECL:
1522 case FIELD_DECL:
1523 if (DECL_NAME (t))
1524 {
1525 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1526
1527 if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1528 || template_parameter_pack_p (t))
1529 /* A function parameter pack or non-type template
1530 parameter pack. */
1531 pp_cxx_ws_string (this, "...");
1532
1533 id_expression (DECL_NAME (t));
1534 }
1535 abstract_declarator (TREE_TYPE (t));
1536 break;
1537
1538 case FUNCTION_DECL:
1539 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1540 expression (t);
1541 pp_cxx_parameter_declaration_clause (this, t);
1542
1543 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1544 {
1545 padding = pp_before;
1546 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1547 }
1548
1549 pp_cxx_exception_specification (this, TREE_TYPE (t));
1550 break;
1551
1552 case TYPENAME_TYPE:
1553 case TEMPLATE_DECL:
1554 case TEMPLATE_TYPE_PARM:
1555 case TEMPLATE_PARM_INDEX:
1556 case TEMPLATE_TEMPLATE_PARM:
1557 break;
1558
1559 default:
1560 c_pretty_printer::direct_declarator (t);
1561 break;
1562 }
1563 }
1564
1565 /* declarator:
1566 direct-declarator
1567 ptr-operator declarator */
1568
1569 void
1570 cxx_pretty_printer::declarator (tree t)
1571 {
1572 direct_declarator (t);
1573 }
1574
1575 /* ctor-initializer:
1576 : mem-initializer-list
1577
1578 mem-initializer-list:
1579 mem-initializer
1580 mem-initializer , mem-initializer-list
1581
1582 mem-initializer:
1583 mem-initializer-id ( expression-list(opt) )
1584
1585 mem-initializer-id:
1586 ::(opt) nested-name-specifier(opt) class-name
1587 identifier */
1588
1589 static void
1590 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1591 {
1592 t = TREE_OPERAND (t, 0);
1593 pp_cxx_whitespace (pp);
1594 pp_colon (pp);
1595 pp_cxx_whitespace (pp);
1596 for (; t; t = TREE_CHAIN (t))
1597 {
1598 tree purpose = TREE_PURPOSE (t);
1599 bool is_pack = PACK_EXPANSION_P (purpose);
1600
1601 if (is_pack)
1602 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1603 else
1604 pp->primary_expression (purpose);
1605 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1606 if (is_pack)
1607 pp_cxx_ws_string (pp, "...");
1608 if (TREE_CHAIN (t))
1609 pp_cxx_separate_with (pp, ',');
1610 }
1611 }
1612
1613 /* function-definition:
1614 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1615 decl-specifier-seq(opt) declarator function-try-block */
1616
1617 static void
1618 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1619 {
1620 tree saved_scope = pp->enclosing_scope;
1621 pp->declaration_specifiers (t);
1622 pp->declarator (t);
1623 pp_needs_newline (pp) = true;
1624 pp->enclosing_scope = DECL_CONTEXT (t);
1625 if (DECL_SAVED_TREE (t))
1626 pp->statement (DECL_SAVED_TREE (t));
1627 else
1628 pp_cxx_semicolon (pp);
1629 pp_newline_and_flush (pp);
1630 pp->enclosing_scope = saved_scope;
1631 }
1632
1633 /* abstract-declarator:
1634 ptr-operator abstract-declarator(opt)
1635 direct-abstract-declarator */
1636
1637 void
1638 cxx_pretty_printer::abstract_declarator (tree t)
1639 {
1640 if (TYPE_PTRMEM_P (t))
1641 pp_cxx_right_paren (this);
1642 else if (POINTER_TYPE_P (t))
1643 {
1644 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1645 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1646 pp_cxx_right_paren (this);
1647 t = TREE_TYPE (t);
1648 }
1649 direct_abstract_declarator (t);
1650 }
1651
1652 /* direct-abstract-declarator:
1653 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1654 cv-qualifier-seq(opt) exception-specification(opt)
1655 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1656 ( abstract-declarator ) */
1657
1658 void
1659 cxx_pretty_printer::direct_abstract_declarator (tree t)
1660 {
1661 switch (TREE_CODE (t))
1662 {
1663 case REFERENCE_TYPE:
1664 abstract_declarator (t);
1665 break;
1666
1667 case RECORD_TYPE:
1668 if (TYPE_PTRMEMFUNC_P (t))
1669 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1670 break;
1671
1672 case METHOD_TYPE:
1673 case FUNCTION_TYPE:
1674 pp_cxx_parameter_declaration_clause (this, t);
1675 direct_abstract_declarator (TREE_TYPE (t));
1676 if (TREE_CODE (t) == METHOD_TYPE)
1677 {
1678 padding = pp_before;
1679 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1680 }
1681 pp_cxx_exception_specification (this, t);
1682 break;
1683
1684 case TYPENAME_TYPE:
1685 case TEMPLATE_TYPE_PARM:
1686 case TEMPLATE_TEMPLATE_PARM:
1687 case BOUND_TEMPLATE_TEMPLATE_PARM:
1688 case UNBOUND_CLASS_TEMPLATE:
1689 break;
1690
1691 default:
1692 c_pretty_printer::direct_abstract_declarator (t);
1693 break;
1694 }
1695 }
1696
1697 /* type-id:
1698 type-specifier-seq abstract-declarator(opt) */
1699
1700 void
1701 cxx_pretty_printer::type_id (tree t)
1702 {
1703 pp_flags saved_flags = flags;
1704 flags |= pp_c_flag_abstract;
1705
1706 switch (TREE_CODE (t))
1707 {
1708 case TYPE_DECL:
1709 case UNION_TYPE:
1710 case RECORD_TYPE:
1711 case ENUMERAL_TYPE:
1712 case TYPENAME_TYPE:
1713 case BOUND_TEMPLATE_TEMPLATE_PARM:
1714 case UNBOUND_CLASS_TEMPLATE:
1715 case TEMPLATE_TEMPLATE_PARM:
1716 case TEMPLATE_TYPE_PARM:
1717 case TEMPLATE_PARM_INDEX:
1718 case TEMPLATE_DECL:
1719 case TYPEOF_TYPE:
1720 case UNDERLYING_TYPE:
1721 case DECLTYPE_TYPE:
1722 case TEMPLATE_ID_EXPR:
1723 pp_cxx_type_specifier_seq (this, t);
1724 break;
1725
1726 case TYPE_PACK_EXPANSION:
1727 type_id (PACK_EXPANSION_PATTERN (t));
1728 pp_cxx_ws_string (this, "...");
1729 break;
1730
1731 default:
1732 c_pretty_printer::type_id (t);
1733 break;
1734 }
1735
1736 flags = saved_flags;
1737 }
1738
1739 /* template-argument-list:
1740 template-argument ...(opt)
1741 template-argument-list, template-argument ...(opt)
1742
1743 template-argument:
1744 assignment-expression
1745 type-id
1746 template-name */
1747
1748 static void
1749 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1750 {
1751 int i;
1752 bool need_comma = false;
1753
1754 if (t == NULL)
1755 return;
1756 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1757 {
1758 tree arg = TREE_VEC_ELT (t, i);
1759 tree argpack = NULL_TREE;
1760 int idx, len = 1;
1761
1762 if (ARGUMENT_PACK_P (arg))
1763 {
1764 argpack = ARGUMENT_PACK_ARGS (arg);
1765 len = TREE_VEC_LENGTH (argpack);
1766 }
1767
1768 for (idx = 0; idx < len; idx++)
1769 {
1770 if (argpack)
1771 arg = TREE_VEC_ELT (argpack, idx);
1772
1773 if (need_comma)
1774 pp_cxx_separate_with (pp, ',');
1775 else
1776 need_comma = true;
1777
1778 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1779 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1780 pp->type_id (arg);
1781 else
1782 pp->expression (arg);
1783 }
1784 }
1785 }
1786
1787
1788 static void
1789 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1790 {
1791 t = DECL_EXPR_DECL (t);
1792 pp_cxx_type_specifier_seq (pp, t);
1793 if (TYPE_P (t))
1794 pp->abstract_declarator (t);
1795 else
1796 pp->declarator (t);
1797 }
1798
1799 /* Statements. */
1800
1801 void
1802 cxx_pretty_printer::statement (tree t)
1803 {
1804 switch (TREE_CODE (t))
1805 {
1806 case CTOR_INITIALIZER:
1807 pp_cxx_ctor_initializer (this, t);
1808 break;
1809
1810 case USING_STMT:
1811 pp_cxx_ws_string (this, "using");
1812 pp_cxx_ws_string (this, "namespace");
1813 if (DECL_CONTEXT (t))
1814 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1815 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1816 break;
1817
1818 case USING_DECL:
1819 pp_cxx_ws_string (this, "using");
1820 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1821 pp_cxx_unqualified_id (this, DECL_NAME (t));
1822 break;
1823
1824 case EH_SPEC_BLOCK:
1825 break;
1826
1827 /* try-block:
1828 try compound-statement handler-seq */
1829 case TRY_BLOCK:
1830 pp_maybe_newline_and_indent (this, 0);
1831 pp_cxx_ws_string (this, "try");
1832 pp_newline_and_indent (this, 3);
1833 statement (TRY_STMTS (t));
1834 pp_newline_and_indent (this, -3);
1835 if (CLEANUP_P (t))
1836 ;
1837 else
1838 statement (TRY_HANDLERS (t));
1839 break;
1840
1841 /*
1842 handler-seq:
1843 handler handler-seq(opt)
1844
1845 handler:
1846 catch ( exception-declaration ) compound-statement
1847
1848 exception-declaration:
1849 type-specifier-seq declarator
1850 type-specifier-seq abstract-declarator
1851 ... */
1852 case HANDLER:
1853 pp_cxx_ws_string (this, "catch");
1854 pp_cxx_left_paren (this);
1855 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1856 pp_cxx_right_paren (this);
1857 pp_indentation (this) += 3;
1858 pp_needs_newline (this) = true;
1859 statement (HANDLER_BODY (t));
1860 pp_indentation (this) -= 3;
1861 pp_needs_newline (this) = true;
1862 break;
1863
1864 /* selection-statement:
1865 if ( expression ) statement
1866 if ( expression ) statement else statement */
1867 case IF_STMT:
1868 pp_cxx_ws_string (this, "if");
1869 pp_cxx_whitespace (this);
1870 pp_cxx_left_paren (this);
1871 expression (IF_COND (t));
1872 pp_cxx_right_paren (this);
1873 pp_newline_and_indent (this, 2);
1874 statement (THEN_CLAUSE (t));
1875 pp_newline_and_indent (this, -2);
1876 if (ELSE_CLAUSE (t))
1877 {
1878 tree else_clause = ELSE_CLAUSE (t);
1879 pp_cxx_ws_string (this, "else");
1880 if (TREE_CODE (else_clause) == IF_STMT)
1881 pp_cxx_whitespace (this);
1882 else
1883 pp_newline_and_indent (this, 2);
1884 statement (else_clause);
1885 if (TREE_CODE (else_clause) != IF_STMT)
1886 pp_newline_and_indent (this, -2);
1887 }
1888 break;
1889
1890 case SWITCH_STMT:
1891 pp_cxx_ws_string (this, "switch");
1892 pp_space (this);
1893 pp_cxx_left_paren (this);
1894 expression (SWITCH_STMT_COND (t));
1895 pp_cxx_right_paren (this);
1896 pp_indentation (this) += 3;
1897 pp_needs_newline (this) = true;
1898 statement (SWITCH_STMT_BODY (t));
1899 pp_newline_and_indent (this, -3);
1900 break;
1901
1902 /* iteration-statement:
1903 while ( expression ) statement
1904 do statement while ( expression ) ;
1905 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1906 for ( declaration expression(opt) ; expression(opt) ) statement */
1907 case WHILE_STMT:
1908 pp_cxx_ws_string (this, "while");
1909 pp_space (this);
1910 pp_cxx_left_paren (this);
1911 expression (WHILE_COND (t));
1912 pp_cxx_right_paren (this);
1913 pp_newline_and_indent (this, 3);
1914 statement (WHILE_BODY (t));
1915 pp_indentation (this) -= 3;
1916 pp_needs_newline (this) = true;
1917 break;
1918
1919 case DO_STMT:
1920 pp_cxx_ws_string (this, "do");
1921 pp_newline_and_indent (this, 3);
1922 statement (DO_BODY (t));
1923 pp_newline_and_indent (this, -3);
1924 pp_cxx_ws_string (this, "while");
1925 pp_space (this);
1926 pp_cxx_left_paren (this);
1927 expression (DO_COND (t));
1928 pp_cxx_right_paren (this);
1929 pp_cxx_semicolon (this);
1930 pp_needs_newline (this) = true;
1931 break;
1932
1933 case FOR_STMT:
1934 pp_cxx_ws_string (this, "for");
1935 pp_space (this);
1936 pp_cxx_left_paren (this);
1937 if (FOR_INIT_STMT (t))
1938 statement (FOR_INIT_STMT (t));
1939 else
1940 pp_cxx_semicolon (this);
1941 pp_needs_newline (this) = false;
1942 pp_cxx_whitespace (this);
1943 if (FOR_COND (t))
1944 expression (FOR_COND (t));
1945 pp_cxx_semicolon (this);
1946 pp_needs_newline (this) = false;
1947 pp_cxx_whitespace (this);
1948 if (FOR_EXPR (t))
1949 expression (FOR_EXPR (t));
1950 pp_cxx_right_paren (this);
1951 pp_newline_and_indent (this, 3);
1952 statement (FOR_BODY (t));
1953 pp_indentation (this) -= 3;
1954 pp_needs_newline (this) = true;
1955 break;
1956
1957 case RANGE_FOR_STMT:
1958 pp_cxx_ws_string (this, "for");
1959 pp_space (this);
1960 pp_cxx_left_paren (this);
1961 statement (RANGE_FOR_DECL (t));
1962 pp_space (this);
1963 pp_needs_newline (this) = false;
1964 pp_colon (this);
1965 pp_space (this);
1966 statement (RANGE_FOR_EXPR (t));
1967 pp_cxx_right_paren (this);
1968 pp_newline_and_indent (this, 3);
1969 statement (FOR_BODY (t));
1970 pp_indentation (this) -= 3;
1971 pp_needs_newline (this) = true;
1972 break;
1973
1974 /* jump-statement:
1975 goto identifier;
1976 continue ;
1977 return expression(opt) ; */
1978 case BREAK_STMT:
1979 case CONTINUE_STMT:
1980 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1981 pp_cxx_semicolon (this);
1982 pp_needs_newline (this) = true;
1983 break;
1984
1985 /* expression-statement:
1986 expression(opt) ; */
1987 case EXPR_STMT:
1988 expression (EXPR_STMT_EXPR (t));
1989 pp_cxx_semicolon (this);
1990 pp_needs_newline (this) = true;
1991 break;
1992
1993 case CLEANUP_STMT:
1994 pp_cxx_ws_string (this, "try");
1995 pp_newline_and_indent (this, 2);
1996 statement (CLEANUP_BODY (t));
1997 pp_newline_and_indent (this, -2);
1998 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1999 pp_newline_and_indent (this, 2);
2000 statement (CLEANUP_EXPR (t));
2001 pp_newline_and_indent (this, -2);
2002 break;
2003
2004 case STATIC_ASSERT:
2005 declaration (t);
2006 break;
2007
2008 default:
2009 c_pretty_printer::statement (t);
2010 break;
2011 }
2012 }
2013
2014 /* original-namespace-definition:
2015 namespace identifier { namespace-body }
2016
2017 As an edge case, we also handle unnamed namespace definition here. */
2018
2019 static void
2020 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2021 {
2022 pp_cxx_ws_string (pp, "namespace");
2023 if (DECL_CONTEXT (t))
2024 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2025 if (DECL_NAME (t))
2026 pp_cxx_unqualified_id (pp, t);
2027 pp_cxx_whitespace (pp);
2028 pp_cxx_left_brace (pp);
2029 /* We do not print the namespace-body. */
2030 pp_cxx_whitespace (pp);
2031 pp_cxx_right_brace (pp);
2032 }
2033
2034 /* namespace-alias:
2035 identifier
2036
2037 namespace-alias-definition:
2038 namespace identifier = qualified-namespace-specifier ;
2039
2040 qualified-namespace-specifier:
2041 ::(opt) nested-name-specifier(opt) namespace-name */
2042
2043 static void
2044 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2045 {
2046 pp_cxx_ws_string (pp, "namespace");
2047 if (DECL_CONTEXT (t))
2048 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2049 pp_cxx_unqualified_id (pp, t);
2050 pp_cxx_whitespace (pp);
2051 pp_equal (pp);
2052 pp_cxx_whitespace (pp);
2053 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2054 pp_cxx_nested_name_specifier (pp,
2055 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2056 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2057 pp_cxx_semicolon (pp);
2058 }
2059
2060 /* simple-declaration:
2061 decl-specifier-seq(opt) init-declarator-list(opt) */
2062
2063 static void
2064 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2065 {
2066 pp->declaration_specifiers (t);
2067 pp_cxx_init_declarator (pp, t);
2068 pp_cxx_semicolon (pp);
2069 pp_needs_newline (pp) = true;
2070 }
2071
2072 /*
2073 template-parameter-list:
2074 template-parameter
2075 template-parameter-list , template-parameter */
2076
2077 static inline void
2078 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2079 {
2080 const int n = TREE_VEC_LENGTH (t);
2081 int i;
2082 for (i = 0; i < n; ++i)
2083 {
2084 if (i)
2085 pp_cxx_separate_with (pp, ',');
2086 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2087 }
2088 }
2089
2090 /* template-parameter:
2091 type-parameter
2092 parameter-declaration
2093
2094 type-parameter:
2095 class ...(opt) identifier(opt)
2096 class identifier(opt) = type-id
2097 typename identifier(opt)
2098 typename ...(opt) identifier(opt) = type-id
2099 template < template-parameter-list > class ...(opt) identifier(opt)
2100 template < template-parameter-list > class identifier(opt) = template-name */
2101
2102 static void
2103 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2104 {
2105 tree parameter = TREE_VALUE (t);
2106 switch (TREE_CODE (parameter))
2107 {
2108 case TYPE_DECL:
2109 pp_cxx_ws_string (pp, "class");
2110 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2111 pp_cxx_ws_string (pp, "...");
2112 if (DECL_NAME (parameter))
2113 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2114 /* FIXME: Check if we should print also default argument. */
2115 break;
2116
2117 case PARM_DECL:
2118 pp_cxx_parameter_declaration (pp, parameter);
2119 break;
2120
2121 case TEMPLATE_DECL:
2122 break;
2123
2124 default:
2125 pp_unsupported_tree (pp, t);
2126 break;
2127 }
2128 }
2129
2130 /* Pretty-print a template parameter in the canonical form
2131 "template-parameter-<level>-<position in parameter list>". */
2132
2133 void
2134 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2135 {
2136 const enum tree_code code = TREE_CODE (parm);
2137
2138 /* Brings type template parameters to the canonical forms. */
2139 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2140 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2141 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2142
2143 pp_cxx_begin_template_argument_list (pp);
2144 pp->translate_string ("template-parameter-");
2145 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2146 pp_minus (pp);
2147 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2148 pp_cxx_end_template_argument_list (pp);
2149 }
2150
2151 /*
2152 template-declaration:
2153 export(opt) template < template-parameter-list > declaration */
2154
2155 static void
2156 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2157 {
2158 tree tmpl = most_general_template (t);
2159 tree level;
2160
2161 pp_maybe_newline_and_indent (pp, 0);
2162 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2163 {
2164 pp_cxx_ws_string (pp, "template");
2165 pp_cxx_begin_template_argument_list (pp);
2166 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2167 pp_cxx_end_template_argument_list (pp);
2168 pp_newline_and_indent (pp, 3);
2169 }
2170 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2171 pp_cxx_function_definition (pp, t);
2172 else
2173 pp_cxx_simple_declaration (pp, t);
2174 }
2175
2176 static void
2177 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2178 {
2179 pp_unsupported_tree (pp, t);
2180 }
2181
2182 static void
2183 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2184 {
2185 pp_unsupported_tree (pp, t);
2186 }
2187
2188 /*
2189 declaration:
2190 block-declaration
2191 function-definition
2192 template-declaration
2193 explicit-instantiation
2194 explicit-specialization
2195 linkage-specification
2196 namespace-definition
2197
2198 block-declaration:
2199 simple-declaration
2200 asm-definition
2201 namespace-alias-definition
2202 using-declaration
2203 using-directive
2204 static_assert-declaration */
2205 void
2206 cxx_pretty_printer::declaration (tree t)
2207 {
2208 if (TREE_CODE (t) == STATIC_ASSERT)
2209 {
2210 pp_cxx_ws_string (this, "static_assert");
2211 pp_cxx_left_paren (this);
2212 expression (STATIC_ASSERT_CONDITION (t));
2213 pp_cxx_separate_with (this, ',');
2214 expression (STATIC_ASSERT_MESSAGE (t));
2215 pp_cxx_right_paren (this);
2216 }
2217 else if (!DECL_LANG_SPECIFIC (t))
2218 pp_cxx_simple_declaration (this, t);
2219 else if (DECL_USE_TEMPLATE (t))
2220 switch (DECL_USE_TEMPLATE (t))
2221 {
2222 case 1:
2223 pp_cxx_template_declaration (this, t);
2224 break;
2225
2226 case 2:
2227 pp_cxx_explicit_specialization (this, t);
2228 break;
2229
2230 case 3:
2231 pp_cxx_explicit_instantiation (this, t);
2232 break;
2233
2234 default:
2235 break;
2236 }
2237 else switch (TREE_CODE (t))
2238 {
2239 case VAR_DECL:
2240 case TYPE_DECL:
2241 pp_cxx_simple_declaration (this, t);
2242 break;
2243
2244 case FUNCTION_DECL:
2245 if (DECL_SAVED_TREE (t))
2246 pp_cxx_function_definition (this, t);
2247 else
2248 pp_cxx_simple_declaration (this, t);
2249 break;
2250
2251 case NAMESPACE_DECL:
2252 if (DECL_NAMESPACE_ALIAS (t))
2253 pp_cxx_namespace_alias_definition (this, t);
2254 else
2255 pp_cxx_original_namespace_definition (this, t);
2256 break;
2257
2258 default:
2259 pp_unsupported_tree (this, t);
2260 break;
2261 }
2262 }
2263
2264 static void
2265 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2266 {
2267 t = TREE_OPERAND (t, 0);
2268 pp_cxx_ws_string (pp, "typeid");
2269 pp_cxx_left_paren (pp);
2270 if (TYPE_P (t))
2271 pp->type_id (t);
2272 else
2273 pp->expression (t);
2274 pp_cxx_right_paren (pp);
2275 }
2276
2277 void
2278 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2279 {
2280 pp_cxx_ws_string (pp, "va_arg");
2281 pp_cxx_left_paren (pp);
2282 pp->assignment_expression (TREE_OPERAND (t, 0));
2283 pp_cxx_separate_with (pp, ',');
2284 pp->type_id (TREE_TYPE (t));
2285 pp_cxx_right_paren (pp);
2286 }
2287
2288 static bool
2289 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2290 {
2291 switch (TREE_CODE (t))
2292 {
2293 case ARROW_EXPR:
2294 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2295 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2296 {
2297 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2298 pp_cxx_separate_with (pp, ',');
2299 return true;
2300 }
2301 return false;
2302 case COMPONENT_REF:
2303 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2304 return false;
2305 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2306 pp_cxx_dot (pp);
2307 pp->expression (TREE_OPERAND (t, 1));
2308 return true;
2309 case ARRAY_REF:
2310 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2311 return false;
2312 pp_left_bracket (pp);
2313 pp->expression (TREE_OPERAND (t, 1));
2314 pp_right_bracket (pp);
2315 return true;
2316 default:
2317 return false;
2318 }
2319 }
2320
2321 void
2322 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2323 {
2324 pp_cxx_ws_string (pp, "offsetof");
2325 pp_cxx_left_paren (pp);
2326 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2327 pp->expression (TREE_OPERAND (t, 0));
2328 pp_cxx_right_paren (pp);
2329 }
2330
2331 void
2332 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2333 {
2334 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2335
2336 switch (kind)
2337 {
2338 case CPTK_HAS_NOTHROW_ASSIGN:
2339 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2340 break;
2341 case CPTK_HAS_TRIVIAL_ASSIGN:
2342 pp_cxx_ws_string (pp, "__has_trivial_assign");
2343 break;
2344 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2345 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2346 break;
2347 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2348 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2349 break;
2350 case CPTK_HAS_NOTHROW_COPY:
2351 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2352 break;
2353 case CPTK_HAS_TRIVIAL_COPY:
2354 pp_cxx_ws_string (pp, "__has_trivial_copy");
2355 break;
2356 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2357 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2358 break;
2359 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2360 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2361 break;
2362 case CPTK_IS_ABSTRACT:
2363 pp_cxx_ws_string (pp, "__is_abstract");
2364 break;
2365 case CPTK_IS_BASE_OF:
2366 pp_cxx_ws_string (pp, "__is_base_of");
2367 break;
2368 case CPTK_IS_CLASS:
2369 pp_cxx_ws_string (pp, "__is_class");
2370 break;
2371 case CPTK_IS_CONVERTIBLE_TO:
2372 pp_cxx_ws_string (pp, "__is_convertible_to");
2373 break;
2374 case CPTK_IS_EMPTY:
2375 pp_cxx_ws_string (pp, "__is_empty");
2376 break;
2377 case CPTK_IS_ENUM:
2378 pp_cxx_ws_string (pp, "__is_enum");
2379 break;
2380 case CPTK_IS_FINAL:
2381 pp_cxx_ws_string (pp, "__is_final");
2382 break;
2383 case CPTK_IS_POD:
2384 pp_cxx_ws_string (pp, "__is_pod");
2385 break;
2386 case CPTK_IS_POLYMORPHIC:
2387 pp_cxx_ws_string (pp, "__is_polymorphic");
2388 break;
2389 case CPTK_IS_STD_LAYOUT:
2390 pp_cxx_ws_string (pp, "__is_std_layout");
2391 break;
2392 case CPTK_IS_TRIVIAL:
2393 pp_cxx_ws_string (pp, "__is_trivial");
2394 break;
2395 case CPTK_IS_UNION:
2396 pp_cxx_ws_string (pp, "__is_union");
2397 break;
2398 case CPTK_IS_LITERAL_TYPE:
2399 pp_cxx_ws_string (pp, "__is_literal_type");
2400 break;
2401
2402 default:
2403 gcc_unreachable ();
2404 }
2405
2406 pp_cxx_left_paren (pp);
2407 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2408
2409 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2410 {
2411 pp_cxx_separate_with (pp, ',');
2412 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2413 }
2414
2415 pp_cxx_right_paren (pp);
2416 }
2417 \f
2418 typedef c_pretty_print_fn pp_fun;
2419
2420 /* Initialization of a C++ pretty-printer object. */
2421
2422 cxx_pretty_printer::cxx_pretty_printer ()
2423 : c_pretty_printer (),
2424 enclosing_scope (global_namespace)
2425 {
2426 pp_set_line_maximum_length (this, 0);
2427
2428 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2429 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2430 simple_type_specifier = (pp_fun) pp_cxx_simple_type_specifier;
2431 }