LCOV - code coverage report
Current view: top level - gcc/cp - cxx-pretty-print.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 61.9 % 1672 1035
Test Date: 2026-02-28 14:20:25 Functions: 78.6 % 84 66
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.