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