1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
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 2, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
27 #include "cxx-pretty-print.h"
31 static void pp_cxx_unqualified_id (cxx_pretty_printer
*, tree
);
32 static void pp_cxx_nested_name_specifier (cxx_pretty_printer
*, tree
);
33 static void pp_cxx_qualified_id (cxx_pretty_printer
*, tree
);
34 static void pp_cxx_assignment_expression (cxx_pretty_printer
*, tree
);
35 static void pp_cxx_expression (cxx_pretty_printer
*, tree
);
36 static void pp_cxx_template_argument_list (cxx_pretty_printer
*, tree
);
37 static void pp_cxx_type_specifier_seq (cxx_pretty_printer
*, tree
);
38 static void pp_cxx_ptr_operator (cxx_pretty_printer
*, tree
);
39 static void pp_cxx_type_id (cxx_pretty_printer
*, tree
);
40 static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer
*, tree
);
41 static void pp_cxx_declarator (cxx_pretty_printer
*, tree
);
42 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*, tree
);
43 static void pp_cxx_abstract_declarator (cxx_pretty_printer
*, tree
);
44 static void pp_cxx_template_parameter (cxx_pretty_printer
*, tree
);
46 #define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
47 #define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
48 #define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
49 #define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
50 #define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
51 #define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
52 #define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
53 #define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
56 pp_cxx_nonconsecutive_character (cxx_pretty_printer
*pp
, int c
)
58 const char *p
= pp_last_position_in_text (pp
);
60 if (p
!= NULL
&& *p
== c
)
61 pp_cxx_whitespace (pp
);
63 pp_base (pp
)->padding
= pp_none
;
66 #define pp_cxx_begin_template_argument_list(PP) \
67 pp_cxx_nonconsecutive_character (PP, '<')
68 #define pp_cxx_end_template_argument_list(PP) \
69 pp_cxx_nonconsecutive_character (PP, '>')
71 #define pp_cxx_identifier(PP, ID) pp_c_identifier (pp_c_base (PP), ID)
72 #define pp_cxx_tree_identifier(PP, T) pp_c_tree_identifier (pp_c_base (PP), T)
74 #define pp_cxx_storage_class_specifier(PP, T) \
75 pp_c_storage_class_specifier (pp_c_base (PP), T)
76 #define pp_cxx_expression_list(PP, T) \
77 pp_c_expression_list (pp_c_base (PP), T)
78 #define pp_cxx_space_for_pointer_operator(PP, T) \
79 pp_c_space_for_pointer_operator (pp_c_base (PP), T)
80 #define pp_cxx_init_declarator(PP, T) \
81 pp_c_init_declarator (pp_c_base (PP), T)
82 #define pp_cxx_call_argument_list(PP, T) \
83 pp_c_call_argument_list (pp_c_base (PP), T)
86 pp_cxx_colon_colon (cxx_pretty_printer
*pp
)
89 pp_base (pp
)->padding
= pp_none
;
96 is_destructor_name (tree name
)
98 return name
== complete_dtor_identifier
99 || name
== base_dtor_identifier
100 || name
== deleting_dtor_identifier
;
103 /* conversion-function-id:
104 operator conversion-type-id
107 type-specifier-seq conversion-declarator(opt)
109 conversion-declarator:
110 ptr-operator conversion-declarator(opt) */
113 pp_cxx_conversion_function_id (cxx_pretty_printer
*pp
, tree t
)
115 pp_cxx_identifier (pp
, "operator");
116 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
120 pp_cxx_template_id (cxx_pretty_printer
*pp
, tree t
)
122 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 0));
123 pp_cxx_begin_template_argument_list (pp
);
124 pp_cxx_template_argument_list (pp
, TREE_OPERAND (t
, 1));
125 pp_cxx_end_template_argument_list (pp
);
131 conversion-function-id
136 pp_cxx_unqualified_id (cxx_pretty_printer
*pp
, tree t
)
138 enum tree_code code
= TREE_CODE (t
);
142 pp_cxx_identifier (pp
, "<return-value>");
159 case IDENTIFIER_NODE
:
161 pp_cxx_identifier (pp
, "<anonymous>");
162 else if (IDENTIFIER_TYPENAME_P (t
))
163 pp_cxx_conversion_function_id (pp
, t
);
166 if (is_destructor_name (t
))
169 /* FIXME: Why is this necessary? */
171 t
= constructor_name (TREE_TYPE (t
));
173 pp_cxx_tree_identifier (pp
, t
);
177 case TEMPLATE_ID_EXPR
:
178 pp_cxx_template_id (pp
, t
);
184 pp_cxx_unqualified_id (pp
, TYPE_NAME (t
));
187 case TEMPLATE_TYPE_PARM
:
188 t
= TEMPLATE_TYPE_PARM_INDEX (t
);
189 case TEMPLATE_PARM_INDEX
:
190 pp_cxx_unqualified_id (pp
, TEMPLATE_PARM_DECL (t
));
194 pp_unsupported_tree (pp
, t
);
199 /* Pretty-print out the token sequence ":: template" in template codes
200 where it is needed to "inline declare" the (following) member as
201 a template. This situation arises when SCOPE of T is dependent
202 on template parameters. */
205 pp_cxx_template_keyword_if_needed (cxx_pretty_printer
*pp
, tree scope
, tree t
)
207 if (TREE_CODE (t
) == TEMPLATE_ID_EXPR
208 && TYPE_P (scope
) && dependent_type_p (scope
))
209 pp_cxx_identifier (pp
, "template");
212 /* nested-name-specifier:
213 class-or-namespace-name :: nested-name-specifier(opt)
214 class-or-namespace-name :: template nested-name-specifier */
217 pp_cxx_nested_name_specifier (cxx_pretty_printer
*pp
, tree t
)
219 if (t
!= NULL
&& t
!= pp
->enclosing_scope
)
221 tree scope
= TYPE_P (t
) ? TYPE_CONTEXT (t
) : DECL_CONTEXT (t
);
222 pp_cxx_nested_name_specifier (pp
, scope
);
223 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
224 pp_cxx_unqualified_id (pp
, t
);
225 pp_cxx_colon_colon (pp
);
230 nested-name-specifier template(opt) unqualified-id */
233 pp_cxx_qualified_id (cxx_pretty_printer
*pp
, tree t
)
235 switch (TREE_CODE (t
))
237 /* A pointer-to-member is always qualified. */
239 pp_cxx_nested_name_specifier (pp
, PTRMEM_CST_CLASS (t
));
240 pp_cxx_unqualified_id (pp
, PTRMEM_CST_MEMBER (t
));
243 /* In Standard C++, functions cannot possibly be used as
244 nested-name-specifiers. However, there are situations where
245 is "makes sense" to output the surrounding function name for the
246 purpose of emphasizing on the scope kind. Just printing the
247 function name might not be sufficient as it may be overloaded; so,
248 we decorate the function with its signature too.
249 FIXME: This is probably the wrong pretty-printing for conversion
250 functions and some function templates. */
254 if (DECL_FUNCTION_MEMBER_P (t
))
255 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
256 pp_cxx_unqualified_id
257 (pp
, DECL_CONSTRUCTOR_P (t
) ? DECL_CONTEXT (t
) : t
);
258 pp_cxx_parameter_declaration_clause (pp
, TREE_TYPE (t
));
263 pp_cxx_nested_name_specifier (pp
, TREE_OPERAND (t
, 0));
264 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 1));
269 tree scope
= TYPE_P (t
) ? TYPE_CONTEXT (t
) : DECL_CONTEXT (t
);
270 if (scope
!= pp
->enclosing_scope
)
272 pp_cxx_nested_name_specifier (pp
, scope
);
273 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
275 pp_cxx_unqualified_id (pp
, t
);
286 pp_cxx_id_expression (cxx_pretty_printer
*pp
, tree t
)
288 if (TREE_CODE (t
) == OVERLOAD
)
290 if (DECL_P (t
) && DECL_CONTEXT (t
))
291 pp_cxx_qualified_id (pp
, t
);
293 pp_cxx_unqualified_id (pp
, t
);
296 /* primary-expression:
300 :: operator-function-id
306 pp_cxx_primary_expression (cxx_pretty_printer
*pp
, tree t
)
308 switch (TREE_CODE (t
))
313 pp_c_constant (pp_c_base (pp
), t
);
317 t
= BASELINK_FUNCTIONS (t
);
325 pp_cxx_id_expression (pp
, t
);
329 case TEMPLATE_TYPE_PARM
:
330 case TEMPLATE_PARM_INDEX
:
331 pp_cxx_unqualified_id (pp
, t
);
335 pp_c_primary_expression (pp_c_base (pp
), t
);
340 /* postfix-expression:
342 postfix-expression [ expression ]
343 postfix-expression ( expression-list(opt) )
344 simple-type-specifier ( expression-list(opt) )
345 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
346 typename ::(opt) nested-name-specifier template(opt)
347 template-id ( expression-list(opt) )
348 postfix-expression . template(opt) ::(opt) id-expression
349 postfix-expression -> template(opt) ::(opt) id-expression
350 postfix-expression . pseudo-destructor-name
351 postfix-expression -> pseudo-destructor-name
352 postfix-expression ++
353 postfix-expression --
354 dynamic_cast < type-id > ( expression )
355 static_cast < type-id > ( expression )
356 reinterpret_cast < type-id > ( expression )
357 const_cast < type-id > ( expression )
358 typeid ( expression )
359 typeif ( type-id ) */
362 pp_cxx_postfix_expression (cxx_pretty_printer
*pp
, tree t
)
364 enum tree_code code
= TREE_CODE (t
);
371 tree fun
= TREE_OPERAND (t
, 0);
372 tree args
= TREE_OPERAND (t
, 1);
373 tree saved_scope
= pp
->enclosing_scope
;
375 if (TREE_CODE (fun
) == ADDR_EXPR
)
376 fun
= TREE_OPERAND (fun
, 0);
378 /* In templates, where there is no way to tell whether a given
379 call uses an actual member function. So the parser builds
380 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
381 instantiation time. */
382 if (TREE_CODE (fun
) != FUNCTION_DECL
)
384 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun
))
386 tree object
= code
== AGGR_INIT_EXPR
&& AGGR_INIT_VIA_CTOR_P (t
)
387 ? TREE_OPERAND (t
, 2)
390 while (TREE_CODE (object
) == NOP_EXPR
)
391 object
= TREE_OPERAND (object
, 0);
393 if (TREE_CODE (object
) == ADDR_EXPR
)
394 object
= TREE_OPERAND (object
, 0);
396 if (TREE_CODE (TREE_TYPE (object
)) != POINTER_TYPE
)
398 pp_cxx_postfix_expression (pp
, object
);
403 pp_cxx_postfix_expression (pp
, object
);
406 args
= TREE_CHAIN (args
);
407 pp
->enclosing_scope
= strip_pointer_operator (TREE_TYPE (object
));
410 pp_cxx_postfix_expression (pp
, fun
);
411 pp
->enclosing_scope
= saved_scope
;
412 pp_cxx_call_argument_list (pp
, args
);
414 if (code
== AGGR_INIT_EXPR
&& AGGR_INIT_VIA_CTOR_P (t
))
416 pp_separate_with (pp
, ',');
417 pp_cxx_postfix_expression (pp
, TREE_OPERAND (t
, 2));
430 pp_cxx_primary_expression (pp
, t
);
433 case DYNAMIC_CAST_EXPR
:
434 case STATIC_CAST_EXPR
:
435 case REINTERPRET_CAST_EXPR
:
436 case CONST_CAST_EXPR
:
437 if (code
== DYNAMIC_CAST_EXPR
)
438 pp_identifier (pp
, "dynamic_cast");
439 else if (code
== STATIC_CAST_EXPR
)
440 pp_identifier (pp
, "static_cast");
441 else if (code
== REINTERPRET_CAST_EXPR
)
442 pp_identifier (pp
, "reinterpret_cast");
444 pp_identifier (pp
, "const_cast");
445 pp_cxx_begin_template_argument_list (pp
);
446 pp_cxx_type_id (pp
, TREE_TYPE (t
));
447 pp_cxx_end_template_argument_list (pp
);
449 pp_cxx_expression (pp
, TREE_OPERAND (t
, 0));
453 case EMPTY_CLASS_EXPR
:
454 pp_cxx_type_id (pp
, TREE_TYPE (t
));
460 t
= TREE_OPERAND (t
, 0);
461 pp_cxx_identifier (pp
, "typeid");
464 pp_cxx_type_id (pp
, t
);
466 pp_cxx_expression (pp
, t
);
470 case PSEUDO_DTOR_EXPR
:
471 pp_cxx_postfix_expression (pp
, TREE_OPERAND (t
, 0));
473 pp_cxx_qualified_id (pp
, TREE_OPERAND (t
, 1));
474 pp_cxx_colon_colon (pp
);
476 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 2));
480 pp_c_postfix_expression (pp_c_base (pp
), t
);
486 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
487 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
493 type-specifier-seq new-declarator(opt)
496 ptr-operator new-declarator(opt)
497 direct-new-declarator
499 direct-new-declarator
501 direct-new-declarator [ constant-expression ]
504 ( expression-list(opt) ) */
507 pp_cxx_new_expression (cxx_pretty_printer
*pp
, tree t
)
509 enum tree_code code
= TREE_CODE (t
);
514 if (NEW_EXPR_USE_GLOBAL (t
))
515 pp_cxx_colon_colon (pp
);
516 pp_cxx_identifier (pp
, "new");
517 if (TREE_OPERAND (t
, 0))
519 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
522 /* FIXME: array-types are built with one more element. */
523 pp_cxx_type_id (pp
, TREE_OPERAND (t
, 1));
524 if (TREE_OPERAND (t
, 2))
527 t
= TREE_OPERAND (t
, 2);
528 if (TREE_CODE (t
) == TREE_LIST
)
529 pp_c_expression_list (pp_c_base (pp
), t
);
530 else if (t
== void_zero_node
)
531 ; /* OK, empty initializer list. */
533 pp_cxx_expression (pp
, t
);
539 pp_unsupported_tree (pp
, t
);
543 /* delete-expression:
544 ::(opt) delete cast-expression
545 ::(opt) delete [ ] cast-expression */
548 pp_cxx_delete_expression (cxx_pretty_printer
*pp
, tree t
)
550 enum tree_code code
= TREE_CODE (t
);
554 case VEC_DELETE_EXPR
:
555 if (DELETE_EXPR_USE_GLOBAL (t
))
556 pp_cxx_colon_colon (pp
);
557 pp_cxx_identifier (pp
, "delete");
558 if (code
== VEC_DELETE_EXPR
)
560 pp_left_bracket (pp
);
561 pp_right_bracket (pp
);
563 pp_c_cast_expression (pp_c_base (pp
), TREE_OPERAND (t
, 0));
567 pp_unsupported_tree (pp
, t
);
575 unary-operator cast-expression
576 sizeof unary-expression
581 unary-operator: one of
585 __alignof__ unary-expression
586 __alignof__ ( type-id ) */
589 pp_cxx_unary_expression (cxx_pretty_printer
*pp
, tree t
)
591 enum tree_code code
= TREE_CODE (t
);
596 pp_cxx_new_expression (pp
, t
);
600 case VEC_DELETE_EXPR
:
601 pp_cxx_delete_expression (pp
, t
);
605 pp_c_unary_expression (pp_c_base (pp
), t
);
612 ( type-id ) cast-expression */
615 pp_cxx_cast_expression (cxx_pretty_printer
*pp
, tree t
)
617 switch (TREE_CODE (t
))
620 pp_cxx_type_id (pp
, TREE_TYPE (t
));
621 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
625 pp_c_cast_expression (pp_c_base (pp
), t
);
632 pm-expression .* cast-expression
633 pm-expression ->* cast-expression */
636 pp_cxx_pm_expression (cxx_pretty_printer
*pp
, tree t
)
638 switch (TREE_CODE (t
))
640 /* Handle unfortunate OFFESET_REF overloading here. */
642 if (TYPE_P (TREE_OPERAND (t
, 0)))
644 pp_cxx_qualified_id (pp
, t
);
647 /* Else fall through. */
650 pp_cxx_pm_expression (pp
, TREE_OPERAND (t
, 0));
653 pp_cxx_cast_expression (pp
, TREE_OPERAND (t
, 1));
658 pp_cxx_cast_expression (pp
, t
);
663 /* multiplicative-expression:
665 multiplicative-expression * pm-expression
666 multiplicative-expression / pm-expression
667 multiplicative-expression % pm-expression */
670 pp_cxx_multiplicative_expression (cxx_pretty_printer
*pp
, tree e
)
672 enum tree_code code
= TREE_CODE (e
);
678 pp_cxx_multiplicative_expression (pp
, TREE_OPERAND (e
, 0));
680 if (code
== MULT_EXPR
)
682 else if (code
== TRUNC_DIV_EXPR
)
687 pp_cxx_pm_expression (pp
, TREE_OPERAND (e
, 1));
691 pp_cxx_pm_expression (pp
, e
);
696 /* conditional-expression:
697 logical-or-expression
698 logical-or-expression ? expression : assignment-expression */
701 pp_cxx_conditional_expression (cxx_pretty_printer
*pp
, tree e
)
703 if (TREE_CODE (e
) == COND_EXPR
)
705 pp_c_logical_or_expression (pp_c_base (pp
), TREE_OPERAND (e
, 0));
709 pp_cxx_expression (pp
, TREE_OPERAND (e
, 1));
711 pp_cxx_assignment_expression (pp
, TREE_OPERAND (e
, 2));
714 pp_c_logical_or_expression (pp_c_base (pp
), e
);
717 /* Pretty-print a compound assignment operator token as indicated by T. */
720 pp_cxx_assignment_operator (cxx_pretty_printer
*pp
, tree t
)
724 switch (TREE_CODE (t
))
747 op
= tree_code_name
[TREE_CODE (t
)];
751 pp_cxx_identifier (pp
, op
);
755 /* assignment-expression:
756 conditional-expression
757 logical-or-expression assignment-operator assignment-expression
761 throw assignment-expression(opt)
763 assignment-operator: one of
764 = *= /= %= += -= >>= <<= &= ^= |= */
767 pp_cxx_assignment_expression (cxx_pretty_printer
*pp
, tree e
)
769 switch (TREE_CODE (e
))
773 pp_c_logical_or_expression (pp_c_base (pp
), TREE_OPERAND (e
, 0));
777 pp_cxx_assignment_expression (pp
, TREE_OPERAND (e
, 1));
781 pp_cxx_identifier (pp
, "throw");
782 if (TREE_OPERAND (e
, 0))
783 pp_cxx_assignment_expression (pp
, TREE_OPERAND (e
, 0));
787 pp_c_logical_or_expression (pp_c_base (pp
), TREE_OPERAND (e
, 0));
788 pp_cxx_assignment_operator (pp
, TREE_OPERAND (e
, 1));
789 pp_cxx_assignment_expression (pp
, TREE_OPERAND (e
, 2));
793 pp_cxx_conditional_expression (pp
, e
);
799 pp_cxx_expression (cxx_pretty_printer
*pp
, tree t
)
801 switch (TREE_CODE (t
))
806 pp_c_constant (pp_c_base (pp
), t
);
810 pp_cxx_unqualified_id (pp
, t
);
818 pp_cxx_qualified_id (pp
, t
);
830 case TEMPLATE_TYPE_PARM
:
831 case TEMPLATE_PARM_INDEX
:
832 pp_cxx_primary_expression (pp
, t
);
836 case DYNAMIC_CAST_EXPR
:
837 case STATIC_CAST_EXPR
:
838 case REINTERPRET_CAST_EXPR
:
839 case CONST_CAST_EXPR
:
843 case EMPTY_CLASS_EXPR
:
845 case PSEUDO_DTOR_EXPR
:
847 pp_cxx_postfix_expression (pp
, t
);
852 pp_cxx_new_expression (pp
, t
);
856 case VEC_DELETE_EXPR
:
857 pp_cxx_delete_expression (pp
, t
);
861 pp_cxx_cast_expression (pp
, t
);
867 pp_cxx_pm_expression (pp
, t
);
873 pp_cxx_multiplicative_expression (pp
, t
);
877 pp_cxx_conditional_expression (pp
, t
);
884 pp_cxx_assignment_expression (pp
, t
);
887 case NON_DEPENDENT_EXPR
:
888 case MUST_NOT_THROW_EXPR
:
889 pp_cxx_expression (pp
, t
);
893 pp_c_expression (pp_c_base (pp
), t
);
901 /* function-specifier:
907 pp_cxx_function_specifier (cxx_pretty_printer
*pp
, tree t
)
909 switch (TREE_CODE (t
))
912 if (DECL_VIRTUAL_P (t
))
913 pp_cxx_identifier (pp
, "virtual");
914 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
915 pp_cxx_identifier (pp
, "explicit");
917 pp_c_function_specifier (pp_c_base (pp
), t
);
924 /* decl-specifier-seq:
925 decl-specifier-seq(opt) decl-specifier
928 storage-class-specifier
935 pp_cxx_decl_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
937 switch (TREE_CODE (t
))
943 pp_cxx_storage_class_specifier (pp
, t
);
944 pp_cxx_decl_specifier_seq (pp
, TREE_TYPE (t
));
948 pp_cxx_identifier (pp
, "typedef");
949 pp_cxx_decl_specifier_seq (pp
, TREE_TYPE (t
));
953 if (TYPE_PTRMEMFUNC_P (t
))
955 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
956 pp_cxx_decl_specifier_seq (pp
, TREE_TYPE (TREE_TYPE (pfm
)));
957 pp_cxx_whitespace (pp
);
958 pp_cxx_ptr_operator (pp
, t
);
963 /* Constructors don't have return types. And conversion functions
964 do not have a type-specifier in their return types. */
965 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
966 pp_cxx_function_specifier (pp
, t
);
967 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
968 pp_cxx_decl_specifier_seq (pp
, TREE_TYPE (TREE_TYPE (t
)));
971 pp_c_declaration_specifiers (pp_c_base (pp
), t
);
976 /* simple-type-specifier:
977 ::(opt) nested-name-specifier(opt) type-name
978 ::(opt) nested-name-specifier(opt) template(opt) template-id
992 pp_cxx_simple_type_specifier (cxx_pretty_printer
*pp
, tree t
)
994 switch (TREE_CODE (t
))
999 pp_cxx_qualified_id (pp
, t
);
1002 case TEMPLATE_TYPE_PARM
:
1003 case TEMPLATE_PARM_INDEX
:
1004 pp_cxx_unqualified_id (pp
, t
);
1008 pp_cxx_identifier (pp
, "typename");
1009 pp_cxx_nested_name_specifier (pp
, TYPE_CONTEXT (t
));
1010 pp_cxx_unqualified_id (pp
, TYPE_NAME (t
));
1014 pp_c_type_specifier (pp_c_base (pp
), t
);
1019 /* type-specifier-seq:
1020 type-specifier type-specifier-seq(opt)
1023 simple-type-specifier
1026 elaborated-type-specifier
1030 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1032 switch (TREE_CODE (t
))
1035 case TEMPLATE_TYPE_PARM
:
1037 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1038 pp_c_type_qualifier_list (pp_c_base (pp
), t
);
1039 pp_cxx_simple_type_specifier (pp
, t
);
1043 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1044 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1045 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1049 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1050 pp_c_specifier_qualifier_list (pp_c_base (pp
), t
);
1055 * cv-qualifier-seq(opt)
1057 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1060 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1062 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1064 switch (TREE_CODE (t
))
1066 case REFERENCE_TYPE
:
1068 if (TREE_CODE (TREE_TYPE (t
)) == POINTER_TYPE
1069 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t
)))
1070 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1071 if (TREE_CODE (t
) == POINTER_TYPE
)
1074 pp_cxx_cv_qualifier_seq (pp
, t
);
1081 if (TYPE_PTRMEMFUNC_P (t
))
1083 pp_cxx_left_paren (pp
);
1084 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1089 if (TYPE_PTR_TO_MEMBER_P (t
))
1091 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1093 pp_cxx_cv_qualifier_seq (pp
, t
);
1096 /* else fall through. */
1099 pp_unsupported_tree (pp
, t
);
1105 pp_cxx_implicit_parameter_type (tree mf
)
1107 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf
))));
1111 parameter-declaration:
1112 decl-specifier-seq declarator
1113 decl-specifier-seq declarator = assignment-expression
1114 decl-specifier-seq abstract-declarator(opt)
1115 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1118 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1120 pp_cxx_decl_specifier_seq (pp
, t
);
1122 pp_cxx_abstract_declarator (pp
, t
);
1124 pp_cxx_declarator (pp
, t
);
1127 /* parameter-declaration-clause:
1128 parameter-declaration-list(opt) ...(opt)
1129 parameter-declaration-list , ...
1131 parameter-declaration-list:
1132 parameter-declaration
1133 parameter-declaration-list , parameter-declaration */
1136 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1138 tree args
= TYPE_P (t
) ? NULL
: FUNCTION_FIRST_USER_PARM (t
);
1139 tree types
= TYPE_P (t
) ? TYPE_ARG_TYPES (t
) : FUNCTION_FIRST_USER_PARMTYPE (t
);
1140 const bool abstract
= args
== NULL
1141 || pp_c_base (pp
)->flags
& pp_c_flag_abstract
;
1144 /* Skip artificial parameter for nonstatic member functions. */
1145 if (TREE_CODE (t
) == METHOD_TYPE
)
1146 types
= TREE_CHAIN (types
);
1148 pp_cxx_left_paren (pp
);
1149 for (; args
; args
= TREE_CHAIN (args
), types
= TREE_CHAIN (types
))
1152 pp_separate_with (pp
, ',');
1154 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1155 if (!abstract
&& pp_c_base (pp
)->flags
& pp_cxx_flag_default_argument
)
1157 pp_cxx_whitespace (pp
);
1159 pp_cxx_whitespace (pp
);
1160 pp_cxx_assignment_expression (pp
, TREE_PURPOSE (types
));
1163 pp_cxx_right_paren (pp
);
1166 /* exception-specification:
1167 throw ( type-id-list(opt) )
1171 type-id-list , type-id */
1174 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1176 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1178 if (!TYPE_NOTHROW_P (t
) && ex_spec
== NULL
)
1180 pp_cxx_identifier (pp
, "throw");
1181 pp_cxx_left_paren (pp
);
1182 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1184 pp_cxx_type_id (pp
, TREE_VALUE (ex_spec
));
1185 if (TREE_CHAIN (ex_spec
))
1186 pp_separate_with (pp
, ',');
1188 pp_cxx_right_paren (pp
);
1191 /* direct-declarator:
1193 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1194 exception-specification(opt)
1195 direct-declaration [ constant-expression(opt) ]
1199 pp_cxx_direct_declarator (cxx_pretty_printer
*pp
, tree t
)
1201 switch (TREE_CODE (t
))
1209 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1210 pp_cxx_id_expression (pp
, DECL_NAME (t
));
1212 pp_cxx_abstract_declarator (pp
, TREE_TYPE (t
));
1216 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (TREE_TYPE (t
)));
1217 pp_cxx_id_expression (pp
, t
);
1218 pp_cxx_parameter_declaration_clause (pp
, t
);
1220 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1222 pp_base (pp
)->padding
= pp_before
;
1223 pp_cxx_cv_qualifier_seq (pp
, pp_cxx_implicit_parameter_type (t
));
1226 pp_cxx_exception_specification (pp
, TREE_TYPE (t
));
1231 case TEMPLATE_TYPE_PARM
:
1232 case TEMPLATE_PARM_INDEX
:
1236 pp_c_direct_declarator (pp_c_base (pp
), t
);
1243 ptr-operator declarator */
1246 pp_cxx_declarator (cxx_pretty_printer
*pp
, tree t
)
1248 pp_cxx_direct_declarator (pp
, t
);
1251 /* ctor-initializer:
1252 : mem-initializer-list
1254 mem-initializer-list:
1256 mem-initializer , mem-initializer-list
1259 mem-initializer-id ( expression-list(opt) )
1262 ::(opt) nested-name-specifier(opt) class-name
1266 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1268 t
= TREE_OPERAND (t
, 0);
1269 pp_cxx_whitespace (pp
);
1271 pp_cxx_whitespace (pp
);
1272 for (; t
; t
= TREE_CHAIN (t
))
1274 pp_cxx_primary_expression (pp
, TREE_PURPOSE (t
));
1275 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1277 pp_separate_with (pp
, ',');
1281 /* function-definition:
1282 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1283 decl-specifier-seq(opt) declarator function-try-block */
1286 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1288 tree saved_scope
= pp
->enclosing_scope
;
1289 pp_cxx_decl_specifier_seq (pp
, t
);
1290 pp_cxx_declarator (pp
, t
);
1291 pp_needs_newline (pp
) = true;
1292 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1293 if (DECL_SAVED_TREE (t
))
1295 tree body
= DECL_SAVED_TREE (t
);
1296 if (TREE_CODE (body
) == COMPOUND_STMT
1297 && TREE_CODE (COMPOUND_BODY (body
)) == CTOR_INITIALIZER
)
1299 body
= COMPOUND_BODY (body
);
1300 pp_cxx_ctor_initializer (pp
, body
);
1301 body
= TREE_CHAIN (body
);
1303 pp_cxx_statement (pp
, body
);
1307 pp_cxx_semicolon (pp
);
1308 pp_needs_newline (pp
) = true;
1311 pp
->enclosing_scope
= saved_scope
;
1314 /* abstract-declarator:
1315 ptr-operator abstract-declarator(opt)
1316 direct-abstract-declarator */
1319 pp_cxx_abstract_declarator (cxx_pretty_printer
*pp
, tree t
)
1321 if (TYPE_PTRMEM_P (t
) || TYPE_PTRMEMFUNC_P (t
))
1322 pp_cxx_right_paren (pp
);
1323 else if (POINTER_TYPE_P (t
))
1325 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1326 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1327 pp_cxx_right_paren (pp
);
1330 pp_cxx_direct_abstract_declarator (pp
, t
);
1333 /* direct-abstract-declarator:
1334 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1335 cv-qualifier-seq(opt) exception-specification(opt)
1336 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1337 ( abstract-declarator ) */
1340 pp_cxx_direct_abstract_declarator (cxx_pretty_printer
*pp
, tree t
)
1342 switch (TREE_CODE (t
))
1344 case REFERENCE_TYPE
:
1345 pp_cxx_abstract_declarator (pp
, t
);
1349 if (TYPE_PTRMEMFUNC_P (t
))
1350 pp_cxx_direct_abstract_declarator (pp
, TYPE_PTRMEMFUNC_FN_TYPE (t
));
1355 pp_cxx_parameter_declaration_clause (pp
, t
);
1356 pp_cxx_direct_abstract_declarator (pp
, TREE_TYPE (t
));
1357 if (TREE_CODE (t
) == METHOD_TYPE
)
1359 pp_base (pp
)->padding
= pp_before
;
1360 pp_cxx_cv_qualifier_seq
1361 (pp
, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t
))));
1363 pp_cxx_exception_specification (pp
, t
);
1367 case TEMPLATE_TYPE_PARM
:
1368 case TEMPLATE_TEMPLATE_PARM
:
1369 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1370 case UNBOUND_CLASS_TEMPLATE
:
1374 pp_c_direct_abstract_declarator (pp_c_base (pp
), t
);
1380 type-specifier-seq abstract-declarator(opt) */
1383 pp_cxx_type_id (cxx_pretty_printer
*pp
, tree t
)
1385 pp_flags saved_flags
= pp_c_base (pp
)->flags
;
1386 pp_c_base (pp
)->flags
|= pp_c_flag_abstract
;
1388 switch (TREE_CODE (t
))
1395 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1396 case UNBOUND_CLASS_TEMPLATE
:
1397 case TEMPLATE_TEMPLATE_PARM
:
1398 case TEMPLATE_TYPE_PARM
:
1399 case TEMPLATE_PARM_INDEX
:
1402 case TEMPLATE_ID_EXPR
:
1403 /* FIXME: Should be pp_cxx_type_specifier_seq. */
1404 pp_cxx_type_specifier_seq (pp
, t
);
1405 pp_cxx_declarator (pp
, t
);
1409 pp_c_type_id (pp_c_base (pp
), t
);
1413 pp_c_base (pp
)->flags
= saved_flags
;
1416 /* template-argument-list:
1418 template-argument-list, template-argument
1421 assignment-expression
1426 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1431 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1433 tree arg
= TREE_VEC_ELT (t
, i
);
1435 pp_separate_with (pp
, ',');
1436 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1437 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1438 pp_cxx_type_id (pp
, arg
);
1440 pp_cxx_expression (pp
, arg
);
1446 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1448 t
= DECL_STMT_DECL (t
);
1449 pp_cxx_type_specifier_seq (pp
, t
);
1451 pp_cxx_abstract_declarator (pp
, t
);
1453 pp_cxx_declarator (pp
, t
);
1459 pp_cxx_statement (cxx_pretty_printer
*pp
, tree t
)
1461 switch (TREE_CODE (t
))
1464 pp_cxx_identifier (pp
, "using");
1465 pp_cxx_identifier (pp
, "namespace");
1466 pp_cxx_qualified_id (pp
, USING_STMT_NAMESPACE (t
));
1470 pp_cxx_identifier (pp
, "using");
1471 pp_cxx_nested_name_specifier (pp
, DECL_INITIAL (t
));
1472 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
1479 try compound-statement handler-seq */
1481 pp_maybe_newline_and_indent (pp
, 0);
1482 pp_cxx_identifier (pp
, "try");
1483 pp_newline_and_indent (pp
, 3);
1484 pp_cxx_statement (pp
, TRY_STMTS (t
));
1485 pp_newline_and_indent (pp
, -3);
1489 pp_cxx_statement (pp
, TRY_HANDLERS (t
));
1494 handler handler-seq(opt)
1497 catch ( exception-declaration ) compound-statement
1499 exception-declaration:
1500 type-specifier-seq declarator
1501 type-specifier-seq abstract-declarator
1504 pp_cxx_identifier (pp
, "catch");
1505 pp_cxx_left_paren (pp
);
1506 pp_cxx_exception_declaration (pp
, HANDLER_PARMS (t
));
1507 pp_cxx_right_paren (pp
);
1508 pp_indentation (pp
) += 3;
1509 pp_needs_newline (pp
) = true;
1510 pp_cxx_statement (pp
, HANDLER_BODY (t
));
1511 pp_indentation (pp
) -= 3;
1512 pp_needs_newline (pp
) = true;
1516 pp_c_statement (pp_c_base (pp
), t
);
1521 /* original-namespace-definition:
1522 namespace identifier { namespace-body }
1524 As an edge case, we also handle unnamed namespace definition here. */
1527 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
1529 pp_cxx_identifier (pp
, "namespace");
1531 pp_cxx_unqualified_id (pp
, t
);
1532 pp_cxx_whitespace (pp
);
1533 pp_cxx_left_brace (pp
);
1534 /* We do not print the namespace-body. */
1535 pp_cxx_whitespace (pp
);
1536 pp_cxx_right_brace (pp
);
1542 namespace-alias-definition:
1543 namespace identifier = qualified-namespace-specifier ;
1545 qualified-namespace-specifier:
1546 ::(opt) nested-name-specifier(opt) namespace-name */
1549 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
1551 pp_cxx_identifier (pp
, "namespace");
1552 pp_cxx_unqualified_id (pp
, t
);
1553 pp_cxx_whitespace (pp
);
1555 pp_cxx_whitespace (pp
);
1556 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
1557 pp_cxx_semicolon (pp
);
1560 /* simple-declaration:
1561 decl-specifier-seq(opt) init-declarator-list(opt) */
1564 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
1566 pp_cxx_decl_specifier_seq (pp
, t
);
1567 pp_cxx_init_declarator (pp
, t
);
1568 pp_cxx_semicolon (pp
);
1569 pp_needs_newline (pp
) = true;
1573 template-parameter-list:
1575 template-parameter-list , template-parameter */
1578 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
1580 const int n
= TREE_VEC_LENGTH (t
);
1582 for (i
= 0; i
< n
; ++i
)
1585 pp_separate_with (pp
, ',');
1586 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
1590 /* template-parameter:
1592 parameter-declaration
1595 class identifier(opt)
1596 class identifier(op) = type-id
1597 typename identifier(opt)
1598 typename identifier(opt) = type-id
1599 template < template-parameter-list > class identifier(opt)
1600 template < template-parameter-list > class identifier(opt) = template-name
1604 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
1606 tree parameter
= TREE_VALUE (t
);
1607 switch (TREE_CODE (parameter
))
1610 pp_cxx_identifier (pp
, "class");
1611 if (DECL_NAME (parameter
))
1612 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
1613 /* FIXME: Chech if we should print also default argument. */
1617 pp_cxx_parameter_declaration (pp
, parameter
);
1624 pp_unsupported_tree (pp
, t
);
1629 /* Pretty-print a template parameter in the canonical form
1630 "template-parameter-<level>-<position in parameter list>". */
1633 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
1635 const enum tree_code code
= TREE_CODE (parm
);
1637 /* Brings type template parameters to the canonical forms. */
1638 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
1639 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
1640 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
1642 pp_cxx_begin_template_argument_list (pp
);
1643 pp_cxx_identifier (pp
, "template-parameter-");
1644 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
1646 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
1647 pp_cxx_end_template_argument_list (pp
);
1651 template-declaration:
1652 export(opt) template < template-parameter-list > declaration */
1655 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
1657 tree tmpl
= most_general_template (t
);
1661 pp_maybe_newline_and_indent (pp
, 0);
1662 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
1664 pp_cxx_identifier (pp
, "template");
1665 pp_cxx_begin_template_argument_list (pp
);
1666 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
1667 pp_cxx_end_template_argument_list (pp
);
1668 pp_newline_and_indent (pp
, 3);
1671 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
1672 pp_cxx_function_definition (pp
, t
);
1674 pp_cxx_simple_declaration (pp
, t
);
1678 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
1680 pp_unsupported_tree (pp
, t
);
1684 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
1686 pp_unsupported_tree (pp
, t
);
1693 template-declaration
1694 explicit-instantiation
1695 explicit-specialization
1696 linkage-specification
1697 namespace-definition
1702 namespace-alias-definition
1706 pp_cxx_declaration (cxx_pretty_printer
*pp
, tree t
)
1708 if (!DECL_LANG_SPECIFIC (t
))
1709 pp_cxx_simple_declaration (pp
, t
);
1710 else if (DECL_USE_TEMPLATE (t
))
1711 switch (DECL_USE_TEMPLATE (t
))
1714 pp_cxx_template_declaration (pp
, t
);
1718 pp_cxx_explicit_specialization (pp
, t
);
1722 pp_cxx_explicit_instantiation (pp
, t
);
1728 else switch (TREE_CODE (t
))
1732 pp_cxx_simple_declaration (pp
, t
);
1736 if (DECL_SAVED_TREE (t
))
1737 pp_cxx_function_definition (pp
, t
);
1739 pp_cxx_simple_declaration (pp
, t
);
1742 case NAMESPACE_DECL
:
1743 if (DECL_NAMESPACE_ALIAS (t
))
1744 pp_cxx_namespace_alias_definition (pp
, t
);
1746 pp_cxx_original_namespace_definition (pp
, t
);
1750 pp_unsupported_tree (pp
, t
);
1756 typedef c_pretty_print_fn pp_fun
;
1758 /* Initialization of a C++ pretty-printer object. */
1761 pp_cxx_pretty_printer_init (cxx_pretty_printer
*pp
)
1763 pp_c_pretty_printer_init (pp_c_base (pp
));
1764 pp_set_line_maximum_length (pp
, 0);
1766 pp
->c_base
.declaration
= (pp_fun
) pp_cxx_declaration
;
1767 pp
->c_base
.declaration_specifiers
= (pp_fun
) pp_cxx_decl_specifier_seq
;
1768 pp
->c_base
.function_specifier
= (pp_fun
) pp_cxx_function_specifier
;
1769 pp
->c_base
.type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
1770 pp
->c_base
.declarator
= (pp_fun
) pp_cxx_declarator
;
1771 pp
->c_base
.direct_declarator
= (pp_fun
) pp_cxx_direct_declarator
;
1772 pp
->c_base
.parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
1773 pp
->c_base
.type_id
= (pp_fun
) pp_cxx_type_id
;
1774 pp
->c_base
.abstract_declarator
= (pp_fun
) pp_cxx_abstract_declarator
;
1775 pp
->c_base
.direct_abstract_declarator
=
1776 (pp_fun
) pp_cxx_direct_abstract_declarator
;
1777 pp
->c_base
.simple_type_specifier
= (pp_fun
)pp_cxx_simple_type_specifier
;
1779 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
1781 pp
->c_base
.id_expression
= (pp_fun
) pp_cxx_id_expression
;
1782 pp
->c_base
.primary_expression
= (pp_fun
) pp_cxx_primary_expression
;
1783 pp
->c_base
.postfix_expression
= (pp_fun
) pp_cxx_postfix_expression
;
1784 pp
->c_base
.unary_expression
= (pp_fun
) pp_cxx_unary_expression
;
1785 pp
->c_base
.multiplicative_expression
= (pp_fun
) pp_cxx_multiplicative_expression
;
1786 pp
->c_base
.conditional_expression
= (pp_fun
) pp_cxx_conditional_expression
;
1787 pp
->c_base
.assignment_expression
= (pp_fun
) pp_cxx_assignment_expression
;
1788 pp
->c_base
.expression
= (pp_fun
) pp_cxx_expression
;
1789 pp
->enclosing_scope
= global_namespace
;