LCOV - code coverage report
Current view: top level - gcc/c-family - c-pretty-print.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 77.5 % 1681 1302
Test Date: 2026-02-28 14:20:25 Functions: 88.4 % 86 76
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Subroutines common to both C and C++ pretty-printers.
       2              :    Copyright (C) 2002-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 "c-pretty-print.h"
      25              : #include "gimple-pretty-print.h"
      26              : #include "diagnostic.h"
      27              : #include "stor-layout.h"
      28              : #include "stringpool.h"
      29              : #include "attribs.h"
      30              : #include "intl.h"
      31              : #include "tree-pretty-print.h"
      32              : #include "selftest.h"
      33              : #include "langhooks.h"
      34              : #include "options.h"
      35              : #include "internal-fn.h"
      36              : #include "function.h"
      37              : #include "basic-block.h"
      38              : #include "gimple.h"
      39              : #include "tm.h"
      40              : 
      41              : /* The pretty-printer code is primarily designed to closely follow
      42              :    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
      43              :    codes we used to have in the past.  Following a structured
      44              :    approach (preferably the official grammars) is believed to make it
      45              :    much easier to add extensions and nifty pretty-printing effects that
      46              :    takes expression or declaration contexts into account.  */
      47              : 
      48              : 
      49              : /* literal  */
      50              : static void pp_c_char (c_pretty_printer *, int);
      51              : 
      52              : /* postfix-expression  */
      53              : static void pp_c_initializer_list (c_pretty_printer *, tree);
      54              : static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
      55              : 
      56              : static void pp_c_additive_expression (c_pretty_printer *, tree);
      57              : static void pp_c_shift_expression (c_pretty_printer *, tree);
      58              : static void pp_c_relational_expression (c_pretty_printer *, tree);
      59              : static void pp_c_equality_expression (c_pretty_printer *, tree);
      60              : static void pp_c_and_expression (c_pretty_printer *, tree);
      61              : static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
      62              : static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
      63              : static void pp_c_logical_and_expression (c_pretty_printer *, tree);
      64              : 
      65              : /* declarations.  */
      66              : 
      67              : 
      68              : /* Helper functions.  */
      69              : 
      70              : void
      71     62527866 : pp_c_whitespace (c_pretty_printer *pp)
      72              : {
      73     62527866 :   pp_space (pp);
      74     62527866 :   pp->set_padding (pp_none);
      75     62527866 : }
      76              : 
      77              : void
      78      3254511 : pp_c_left_paren (c_pretty_printer *pp)
      79              : {
      80      3254511 :   pp_left_paren (pp);
      81      3254511 :   pp->set_padding (pp_none);
      82      3254511 : }
      83              : 
      84              : void
      85      3254511 : pp_c_right_paren (c_pretty_printer *pp)
      86              : {
      87      3254511 :   pp_right_paren (pp);
      88      3254511 :   pp->set_padding (pp_none);
      89      3254511 : }
      90              : 
      91              : void
      92        15327 : pp_c_left_brace (c_pretty_printer *pp)
      93              : {
      94        15327 :   pp_left_brace (pp);
      95        15327 :   pp->set_padding (pp_none);
      96        15327 : }
      97              : 
      98              : void
      99        15327 : pp_c_right_brace (c_pretty_printer *pp)
     100              : {
     101        15327 :   pp_right_brace (pp);
     102        15327 :   pp->set_padding (pp_none);
     103        15327 : }
     104              : 
     105              : void
     106       886306 : pp_c_left_bracket (c_pretty_printer *pp)
     107              : {
     108       886306 :   pp_left_bracket (pp);
     109       886306 :   pp->set_padding (pp_none);
     110       886306 : }
     111              : 
     112              : void
     113       886306 : pp_c_right_bracket (c_pretty_printer *pp)
     114              : {
     115       886306 :   pp_right_bracket (pp);
     116       886306 :   pp->set_padding (pp_none);
     117       886306 : }
     118              : 
     119              : void
     120         2920 : pp_c_dot (c_pretty_printer *pp)
     121              : {
     122         2920 :   pp_dot (pp);
     123         2920 :   pp->set_padding (pp_none);
     124         2920 : }
     125              : 
     126              : void
     127         4203 : pp_c_ampersand (c_pretty_printer *pp)
     128              : {
     129         4203 :   pp_ampersand (pp);
     130         4203 :   pp->set_padding (pp_none);
     131         4203 : }
     132              : 
     133              : void
     134       189776 : pp_c_star (c_pretty_printer *pp)
     135              : {
     136       189776 :   pp_star (pp);
     137       189776 :   pp->set_padding (pp_none);
     138       189776 : }
     139              : 
     140              : void
     141         1305 : pp_c_arrow (c_pretty_printer *pp)
     142              : {
     143         1305 :   pp_arrow (pp);
     144         1305 :   pp->set_padding (pp_none);
     145         1305 : }
     146              : 
     147              : void
     148          328 : pp_c_semicolon (c_pretty_printer *pp)
     149              : {
     150          328 :   pp_semicolon (pp);
     151          328 :   pp->set_padding (pp_none);
     152          328 : }
     153              : 
     154              : void
     155      2502616 : pp_c_complement (c_pretty_printer *pp)
     156              : {
     157      2502616 :   pp_complement (pp);
     158      2502616 :   pp->set_padding (pp_none);
     159      2502616 : }
     160              : 
     161              : void
     162            0 : pp_c_exclamation (c_pretty_printer *pp)
     163              : {
     164            0 :   pp_exclamation (pp);
     165            0 :   pp->set_padding (pp_none);
     166            0 : }
     167              : 
     168              : /* Print out the external representation of QUALIFIERS.  */
     169              : 
     170              : void
     171    264519157 : pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
     172              : {
     173    264519157 :   const char *p = pp_last_position_in_text (pp);
     174              : 
     175    264519157 :   if (!qualifiers)
     176              :     return;
     177              : 
     178              :   /* The C programming language does not have references, but it is much
     179              :      simpler to handle those here rather than going through the same
     180              :      logic in the C++ pretty-printer.  */
     181     27832672 :   if (p != NULL && (*p == '*' || *p == '&'))
     182      2689411 :     pp_c_whitespace (pp);
     183              : 
     184     27832672 :   if (qualifiers & TYPE_QUAL_ATOMIC)
     185          134 :     pp_c_ws_string (pp, "_Atomic");
     186     27832672 :   if (qualifiers & TYPE_QUAL_CONST)
     187     55603780 :     pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
     188     27832672 :   if (qualifiers & TYPE_QUAL_VOLATILE)
     189       247355 :     pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
     190     27832672 :   if (qualifiers & TYPE_QUAL_RESTRICT)
     191          997 :     pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
     192              :                          ? "restrict" : "__restrict__"));
     193              : }
     194              : 
     195              : /* Pretty-print T using the type-cast notation '( type-name )'.  */
     196              : 
     197              : void
     198       891351 : pp_c_type_cast (c_pretty_printer *pp, tree t)
     199              : {
     200       891351 :   pp_c_left_paren (pp);
     201       891351 :   pp->type_id (t);
     202       891351 :   pp_c_right_paren (pp);
     203       891351 : }
     204              : 
     205              : /* We're about to pretty-print a pointer type as indicated by T.
     206              :    Output a whitespace, if needed, preparing for subsequent output.  */
     207              : 
     208              : void
     209          155 : pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
     210              : {
     211          155 :   if (POINTER_TYPE_P (t))
     212              :     {
     213           77 :       tree pointee = strip_pointer_operator (TREE_TYPE (t));
     214           77 :       if (TREE_CODE (pointee) != ARRAY_TYPE
     215           77 :           && TREE_CODE (pointee) != FUNCTION_TYPE)
     216           77 :         pp_c_whitespace (pp);
     217              :     }
     218          155 : }
     219              : 
     220              : 
     221              : /* Declarations.  */
     222              : 
     223              : /* C++ cv-qualifiers are called type-qualifiers in C.  Print out the
     224              :    cv-qualifiers of T.  If T is a declaration then it is the cv-qualifier
     225              :    of its type.  Take care of possible extensions.
     226              : 
     227              :    type-qualifier-list:
     228              :        type-qualifier
     229              :        type-qualifier-list type-qualifier
     230              : 
     231              :    type-qualifier:
     232              :        const
     233              :        restrict                              -- C99
     234              :        __restrict__                          -- GNU C
     235              :        address-space-qualifier               -- GNU C
     236              :        volatile
     237              :        _Atomic                               -- C11
     238              : 
     239              :    address-space-qualifier:
     240              :        identifier                            -- GNU C  */
     241              : 
     242              : void
     243    263896130 : pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
     244              : {
     245    263896130 :   int qualifiers;
     246              : 
     247    263896130 :   if (!t || t == error_mark_node)
     248              :     return;
     249              : 
     250    263896115 :   if (!TYPE_P (t))
     251            0 :     t = TREE_TYPE (t);
     252              : 
     253    263896115 :   if (TREE_CODE (t) != ARRAY_TYPE)
     254              :     {
     255    263859895 :       qualifiers = TYPE_QUALS (t);
     256    263859895 :       pp_c_cv_qualifiers (pp, qualifiers,
     257              :                           TREE_CODE (t) == FUNCTION_TYPE);
     258              :     }
     259              : 
     260    263896115 :   if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t)))
     261              :     {
     262            3 :       const char *as = c_addr_space_name (TYPE_ADDR_SPACE (t));
     263            3 :       pp_c_identifier (pp, as);
     264              :     }
     265              : }
     266              : 
     267              : /* pointer:
     268              :       * type-qualifier-list(opt)
     269              :       * type-qualifier-list(opt) pointer  */
     270              : 
     271              : static void
     272        12614 : pp_c_pointer (c_pretty_printer *pp, tree t)
     273              : {
     274        12614 :   if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
     275            0 :     t = TREE_TYPE (t);
     276        12614 :   switch (TREE_CODE (t))
     277              :     {
     278        12614 :     case POINTER_TYPE:
     279              :       /* It is easier to handle C++ reference types here.  */
     280        12614 :     case REFERENCE_TYPE:
     281        12614 :       if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
     282          363 :         pp_c_pointer (pp, TREE_TYPE (t));
     283        12614 :       if (TREE_CODE (t) == POINTER_TYPE)
     284         8499 :         pp_c_star (pp);
     285              :       else
     286              :         {
     287         4115 :           pp_c_ampersand (pp);
     288         4115 :           if (TYPE_REF_IS_RVALUE (t))
     289           76 :             pp_c_ampersand (pp);
     290              :         }
     291        12614 :       pp_c_type_qualifier_list (pp, t);
     292        12614 :       break;
     293              : 
     294              :       /* ??? This node is now in GENERIC and so shouldn't be here.  But
     295              :          we'll fix that later.  */
     296            0 :     case DECL_EXPR:
     297            0 :       pp->declaration (DECL_EXPR_DECL (t));
     298            0 :       pp_needs_newline (pp) = true;
     299            0 :       break;
     300              : 
     301            0 :     default:
     302            0 :       pp_unsupported_tree (pp, t);
     303              :     }
     304        12614 : }
     305              : 
     306              : /* simple-type-specifier:
     307              :      type-specifier
     308              : 
     309              :    type-specifier:
     310              :       void
     311              :       char
     312              :       short
     313              :       int
     314              :       long
     315              :       float
     316              :       double
     317              :       signed
     318              :       unsigned
     319              :       _Bool                          -- C99
     320              :       _Complex                       -- C99
     321              :       _Imaginary                     -- C99
     322              :       nullptr_t                      -- C23
     323              :       struct-or-union-specifier
     324              :       enum-specifier
     325              :       typedef-name.
     326              : 
     327              :   GNU extensions.
     328              :   simple-type-specifier:
     329              :       __complex__
     330              :       __vector__   */
     331              : 
     332              : void
     333    142797710 : c_pretty_printer::simple_type_specifier (tree t)
     334              : {
     335    142797710 :   const enum tree_code code = TREE_CODE (t);
     336    142797710 :   switch (code)
     337              :     {
     338           15 :     case ERROR_MARK:
     339           15 :       translate_string ("<type-error>");
     340           15 :       break;
     341              : 
     342          117 :     case IDENTIFIER_NODE:
     343          117 :       pp_c_identifier (this, IDENTIFIER_POINTER (t));
     344          117 :       break;
     345              : 
     346     71397443 :     case VOID_TYPE:
     347     71397443 :     case OPAQUE_TYPE:
     348     71397443 :     case BOOLEAN_TYPE:
     349     71397443 :     case INTEGER_TYPE:
     350     71397443 :     case REAL_TYPE:
     351     71397443 :     case FIXED_POINT_TYPE:
     352     71397443 :       if (TYPE_NAME (t))
     353              :         {
     354     71397143 :           t = TYPE_NAME (t);
     355     71397143 :           simple_type_specifier (t);
     356              :         }
     357              :       else
     358              :         {
     359          300 :           int prec = TYPE_PRECISION (t);
     360          300 :           tree common_t;
     361          300 :           if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t)))
     362            0 :             common_t = c_common_type_for_mode (TYPE_MODE (t),
     363            0 :                                                TYPE_SATURATING (t));
     364              :           else
     365          300 :             common_t = c_common_type_for_mode (TYPE_MODE (t),
     366          300 :                                                TYPE_UNSIGNED (t));
     367          300 :           if (common_t && TYPE_NAME (common_t))
     368              :             {
     369          264 :               simple_type_specifier (common_t);
     370          264 :               if (TYPE_PRECISION (common_t) != prec)
     371              :                 {
     372          151 :                   pp_colon (this);
     373          151 :                   pp_decimal_int (this, prec);
     374              :                 }
     375              :             }
     376              :           else
     377              :             {
     378           36 :               switch (code)
     379              :                 {
     380            0 :                 case INTEGER_TYPE:
     381            0 :                   translate_string (TYPE_UNSIGNED (t)
     382              :                                     ? "<unnamed-unsigned:"
     383              :                                     : "<unnamed-signed:");
     384            0 :                   break;
     385           36 :                 case REAL_TYPE:
     386           36 :                   translate_string ("<unnamed-float:");
     387           36 :                   break;
     388            0 :                 case FIXED_POINT_TYPE:
     389            0 :                   translate_string ("<unnamed-fixed:");
     390            0 :                   break;
     391            0 :                 default:
     392            0 :                   gcc_unreachable ();
     393              :                 }
     394           36 :               pp_decimal_int (this, prec);
     395           36 :               pp_greater (this);
     396              :             }
     397              :         }
     398              :       break;
     399              : 
     400           43 :     case BITINT_TYPE:
     401           43 :       if (TYPE_NAME (t))
     402              :         {
     403            0 :           t = TYPE_NAME (t);
     404            0 :           simple_type_specifier (t);
     405              :         }
     406              :       else
     407              :         {
     408           43 :           int prec = TYPE_PRECISION (t);
     409           43 :           if (TYPE_UNSIGNED (t))
     410           13 :             pp_c_ws_string (this, "unsigned");
     411           43 :           pp_c_ws_string (this, "_BitInt(");;
     412           43 :           pp_decimal_int (this, prec);
     413           43 :           pp_right_paren (this);
     414              :         }
     415              :       break;
     416              : 
     417     71397026 :     case TYPE_DECL:
     418     71397026 :       if (DECL_NAME (t))
     419     71397026 :         id_expression (t);
     420              :       else
     421            0 :         translate_string ("<typedef-error>");
     422              :       break;
     423              : 
     424         3059 :     case UNION_TYPE:
     425         3059 :     case RECORD_TYPE:
     426         3059 :     case ENUMERAL_TYPE:
     427         3059 :       if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
     428              :         /* Don't decorate the type if this is a typedef name.  */;
     429         2177 :       else if (code == UNION_TYPE)
     430          169 :         pp_c_ws_string (this, "union");
     431         2008 :       else if (code == RECORD_TYPE)
     432         1679 :         pp_c_ws_string (this, "struct");
     433          329 :       else if (code == ENUMERAL_TYPE)
     434          329 :         pp_c_ws_string (this, "enum");
     435              :       else
     436              :         translate_string ("<tag-error>");
     437              : 
     438         3059 :       if (TYPE_NAME (t))
     439         3015 :         id_expression (TYPE_NAME (t));
     440              :       else
     441           44 :         translate_string ("<anonymous>");
     442              :       break;
     443            7 :     case NULLPTR_TYPE:
     444            7 :       pp_c_ws_string (this, "nullptr_t");
     445            7 :       break;
     446              : 
     447            0 :     default:
     448            0 :       pp_unsupported_tree (this, t);
     449            0 :       break;
     450              :     }
     451    142797710 : }
     452              : 
     453              : /* specifier-qualifier-list:
     454              :       type-specifier specifier-qualifier-list-opt
     455              :       type-qualifier specifier-qualifier-list-opt
     456              : 
     457              : 
     458              :   Implementation note:  Because of the non-linearities in array or
     459              :   function declarations, this routine prints not just the
     460              :   specifier-qualifier-list of such entities or types of such entities,
     461              :   but also the 'pointer' production part of their declarators.  The
     462              :   remaining part is done by declarator() or abstract_declarator().  */
     463              : 
     464              : void
     465     72352254 : pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
     466              : {
     467     72352254 :   const enum tree_code code = TREE_CODE (t);
     468              : 
     469     72352254 :   if (!(pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
     470       415817 :     pp_c_type_qualifier_list (pp, t);
     471     72344118 :   switch (code)
     472              :     {
     473        12251 :     case REFERENCE_TYPE:
     474        12251 :     case POINTER_TYPE:
     475        12251 :       {
     476              :         /* Get the types-specifier of this type.  */
     477        12251 :         tree pointee = strip_pointer_operator (TREE_TYPE (t));
     478        12251 :         pp_c_specifier_qualifier_list (pp, pointee);
     479        12251 :         if (TREE_CODE (pointee) == ARRAY_TYPE
     480        11778 :             || TREE_CODE (pointee) == FUNCTION_TYPE)
     481              :           {
     482         2361 :             pp_c_whitespace (pp);
     483         2361 :             pp_c_left_paren (pp);
     484              :             /* If we're dealing with the GNU form of attributes, print this:
     485              :                  void (__attribute__((noreturn)) *f) ();
     486              :                If it is the standard [[]] attribute, we'll print the attribute
     487              :                in c_pretty_printer::direct_abstract_declarator/FUNCTION_TYPE.  */
     488         2361 :             if (!cxx11_attribute_p (TYPE_ATTRIBUTES (pointee)))
     489         2357 :               pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee));
     490              :           }
     491         9890 :         else if (!c_dialect_cxx ())
     492         5442 :           pp_c_whitespace (pp);
     493        12251 :         pp_ptr_operator (pp, t);
     494              :       }
     495        12251 :       break;
     496              : 
     497        38836 :     case FUNCTION_TYPE:
     498        38836 :     case ARRAY_TYPE:
     499        38836 :       pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
     500        38836 :       break;
     501              : 
     502         3466 :     case VECTOR_TYPE:
     503         3466 :     case COMPLEX_TYPE:
     504         3466 :       if (code == COMPLEX_TYPE)
     505          589 :         pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
     506              :                              ? "_Complex" : "__complex__"));
     507         3119 :       else if (code == VECTOR_TYPE)
     508              :         {
     509              :           /* The syntax we print for vector types isn't real C or C++ syntax,
     510              :              so it's better to print the type name if we have one.  */
     511         3119 :           tree name = TYPE_NAME (t);
     512         3119 :           if (!(pp->flags & pp_c_flag_gnu_v3)
     513         1262 :               && name
     514           23 :               && TREE_CODE (name) == TYPE_DECL)
     515              :             {
     516           23 :               pp->id_expression (name);
     517           23 :               break;
     518              :             }
     519         3096 :           pp_c_ws_string (pp, "__vector");
     520         3096 :           pp_c_left_paren (pp);
     521         3096 :           pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (t));
     522         3096 :           pp_c_right_paren (pp);
     523         3096 :           pp_c_whitespace (pp);
     524              :         }
     525         3443 :       pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
     526         3443 :       break;
     527              : 
     528     72297701 :     default:
     529     72297701 :       pp->simple_type_specifier (t);
     530     72297701 :       break;
     531              :     }
     532     72352254 :   if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
     533     71928301 :     pp_c_type_qualifier_list (pp, t);
     534     72352254 : }
     535              : 
     536              : /* parameter-type-list:
     537              :       parameter-list
     538              :       parameter-list , ...
     539              : 
     540              :    parameter-list:
     541              :       parameter-declaration
     542              :       parameter-list , parameter-declaration
     543              : 
     544              :    parameter-declaration:
     545              :       declaration-specifiers declarator
     546              :       declaration-specifiers abstract-declarator(opt)   */
     547              : 
     548              : void
     549         2597 : pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
     550              : {
     551         2597 :   bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
     552         2597 :   tree parms = want_parm_decl ? DECL_ARGUMENTS (t) :  TYPE_ARG_TYPES (t);
     553         2597 :   pp_c_left_paren (pp);
     554         2597 :   if (parms == void_list_node)
     555          891 :     pp_c_ws_string (pp, "void");
     556              :   else
     557              :     {
     558              :       bool first = true;
     559         4348 :       for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
     560              :         {
     561         2642 :           if (!first)
     562         1065 :             pp_separate_with (pp, ',');
     563         2642 :           first = false;
     564         2642 :           pp->declaration_specifiers
     565         5284 :             (want_parm_decl ? parms : TREE_VALUE (parms));
     566         2642 :           if (want_parm_decl)
     567            0 :             pp->declarator (parms);
     568              :           else
     569         2642 :             pp->abstract_declarator (TREE_VALUE (parms));
     570              :         }
     571         1706 :       if (!first && !parms)
     572              :         {
     573           68 :           pp_separate_with (pp, ',');
     574           68 :           pp_string (pp, "...");
     575              :         }
     576              :     }
     577         2597 :   pp_c_right_paren (pp);
     578         2597 : }
     579              : 
     580              : /* abstract-declarator:
     581              :       pointer
     582              :       pointer(opt) direct-abstract-declarator  */
     583              : 
     584              : void
     585        32424 : c_pretty_printer::abstract_declarator (tree t)
     586              : {
     587        32424 :   if (TREE_CODE (t) == POINTER_TYPE)
     588              :     {
     589         8082 :       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
     590         8082 :           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
     591         2286 :         pp_c_right_paren (this);
     592         8082 :       t = TREE_TYPE (t);
     593              :     }
     594              : 
     595        32424 :   direct_abstract_declarator (t);
     596        32424 : }
     597              : 
     598              : /* direct-abstract-declarator:
     599              :       ( abstract-declarator )
     600              :       direct-abstract-declarator(opt) [ assignment-expression(opt) ]
     601              :       direct-abstract-declarator(opt) [ * ]
     602              :       direct-abstract-declarator(opt) ( parameter-type-list(opt) )  */
     603              : 
     604              : void
     605        74033 : c_pretty_printer::direct_abstract_declarator (tree t)
     606              : {
     607        74033 :   bool add_space = false;
     608              : 
     609        74033 :   switch (TREE_CODE (t))
     610              :     {
     611         1077 :     case POINTER_TYPE:
     612         1077 :       abstract_declarator (t);
     613         1077 :       break;
     614              : 
     615         2597 :     case FUNCTION_TYPE:
     616         2597 :       pp_c_parameter_type_list (this, t);
     617         2597 :       direct_abstract_declarator (TREE_TYPE (t));
     618              :       /* If this is the standard [[]] attribute, print
     619              :          void (*)() [[noreturn]];  */
     620         2597 :       if (cxx11_attribute_p (TYPE_ATTRIBUTES (t)))
     621              :         {
     622            4 :           pp_space (this);
     623            4 :           pp_c_attributes_display (this, TYPE_ATTRIBUTES (t));
     624              :         }
     625              :       break;
     626              : 
     627        36218 :     case ARRAY_TYPE:
     628        36218 :       pp_c_left_bracket (this);
     629              : 
     630        36218 :       if (int quals = TYPE_QUALS (t))
     631              :         {
     632              :           /* Print the array qualifiers such as in "T[const restrict 3]".  */
     633           40 :           pp_c_cv_qualifiers (this, quals, false);
     634           40 :           add_space = true;
     635              :         }
     636              : 
     637        36218 :       if (tree arr = lookup_attribute ("array ", TYPE_ATTRIBUTES (t)))
     638              :         {
     639          812 :           if (TREE_VALUE (arr))
     640              :             {
     641              :               /* Print the specifier as in "T[static 3]" that's not actually
     642              :                  part of the type but may be added by the front end.  */
     643           48 :               pp_c_ws_string (this, "static");
     644           48 :               add_space = true;
     645              :             }
     646          764 :           else if (!TYPE_DOMAIN (t))
     647              :             /* For arrays of unspecified bound using the [*] notation. */
     648           78 :             pp_character (this, '*');
     649              :         }
     650              : 
     651        36218 :       if (tree dom = TYPE_DOMAIN (t))
     652              :         {
     653        34984 :           if (tree maxval = TYPE_MAX_VALUE (dom))
     654              :             {
     655        34604 :               if (add_space)
     656           67 :                 pp_space (this);
     657              : 
     658        34604 :               tree type = TREE_TYPE (maxval);
     659              : 
     660        34604 :               if (tree_fits_shwi_p (maxval))
     661        25291 :                 pp_wide_integer (this, tree_to_shwi (maxval) + 1);
     662         9313 :               else if (TREE_CODE (maxval) == INTEGER_CST)
     663            0 :                 expression (fold_build2 (PLUS_EXPR, type, maxval,
     664              :                                          build_int_cst (type, 1)));
     665              :               else
     666              :                 {
     667              :                   /* Strip the expressions from around a VLA bound added
     668              :                      internally to make it fit the domain mold, including
     669              :                      any casts.  */
     670         9313 :                   if (TREE_CODE (maxval) == NOP_EXPR)
     671         9197 :                     maxval = TREE_OPERAND (maxval, 0);
     672         9313 :                   if (TREE_CODE (maxval) == PLUS_EXPR
     673         9313 :                       && integer_all_onesp (TREE_OPERAND (maxval, 1)))
     674              :                     {
     675         8505 :                       maxval = TREE_OPERAND (maxval, 0);
     676         8505 :                       if (TREE_CODE (maxval) == NOP_EXPR)
     677         8505 :                         maxval = TREE_OPERAND (maxval, 0);
     678              :                     }
     679         9313 :                   if (TREE_CODE (maxval) == SAVE_EXPR)
     680              :                     {
     681         8505 :                       maxval = TREE_OPERAND (maxval, 0);
     682         8505 :                       if (TREE_CODE (maxval) == NOP_EXPR)
     683            0 :                         maxval = TREE_OPERAND (maxval, 0);
     684              :                     }
     685              : 
     686              :                   /* This covers unspecified bounds.  */
     687         9313 :                   if (TREE_CODE (maxval) == COMPOUND_EXPR)
     688           43 :                     pp_string (this, "*");
     689              :                   else
     690         9270 :                     expression (maxval);
     691              :                 }
     692              :             }
     693          380 :           else if (TYPE_SIZE (t))
     694              :             /* Print zero for zero-length arrays but not for flexible
     695              :                array members whose TYPE_SIZE is null.  */
     696          244 :             pp_string (this, "0");
     697              :         }
     698        36218 :       pp_c_right_bracket (this);
     699        36218 :       direct_abstract_declarator (TREE_TYPE (t));
     700        36218 :       break;
     701              : 
     702              :     case IDENTIFIER_NODE:
     703              :     case VOID_TYPE:
     704              :     case OPAQUE_TYPE:
     705              :     case BOOLEAN_TYPE:
     706              :     case INTEGER_TYPE:
     707              :     case REAL_TYPE:
     708              :     case FIXED_POINT_TYPE:
     709              :     case ENUMERAL_TYPE:
     710              :     case BITINT_TYPE:
     711              :     case RECORD_TYPE:
     712              :     case UNION_TYPE:
     713              :     case VECTOR_TYPE:
     714              :     case COMPLEX_TYPE:
     715              :     case TYPE_DECL:
     716              :     case ERROR_MARK:
     717              :     case NULLPTR_TYPE:
     718              :       break;
     719              : 
     720            0 :     default:
     721            0 :       pp_unsupported_tree (this, t);
     722            0 :       break;
     723              :     }
     724        74033 : }
     725              : 
     726              : /* type-name:
     727              :       specifier-qualifier-list  abstract-declarator(opt)  */
     728              : 
     729              : void
     730        35576 : c_pretty_printer::type_id (tree t)
     731              : {
     732        35576 :   pp_c_specifier_qualifier_list (this, t);
     733        35576 :   abstract_declarator (t);
     734        35576 : }
     735              : 
     736              : /* storage-class-specifier:
     737              :       typedef
     738              :       extern
     739              :       static
     740              :       auto
     741              :       register  */
     742              : 
     743              : void
     744         2985 : c_pretty_printer::storage_class_specifier (tree t)
     745              : {
     746         2985 :   if (TREE_CODE (t) == TYPE_DECL)
     747            0 :     pp_c_ws_string (this, "typedef");
     748         2985 :   else if (DECL_P (t))
     749              :     {
     750          155 :       if ((TREE_CODE (t) == PARM_DECL || VAR_P (t))
     751          155 :           && DECL_REGISTER (t))
     752            0 :         pp_c_ws_string (this, "register");
     753          155 :       else if (TREE_STATIC (t) && VAR_P (t))
     754            0 :         pp_c_ws_string (this, "static");
     755              :     }
     756         2985 : }
     757              : 
     758              : /* function-specifier:
     759              :       inline   */
     760              : 
     761              : void
     762         2642 : c_pretty_printer::function_specifier (tree t)
     763              : {
     764         2642 :   if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
     765            0 :     pp_c_ws_string (this, "inline");
     766         2642 : }
     767              : 
     768              : /* declaration-specifiers:
     769              :       storage-class-specifier declaration-specifiers(opt)
     770              :       type-specifier declaration-specifiers(opt)
     771              :       type-qualifier declaration-specifiers(opt)
     772              :       function-specifier declaration-specifiers(opt)  */
     773              : 
     774              : void
     775         2830 : c_pretty_printer::declaration_specifiers (tree t)
     776              : {
     777         2830 :   storage_class_specifier (t);
     778         2830 :   function_specifier (t);
     779         2830 :   pp_c_specifier_qualifier_list (this, DECL_P (t) ?  TREE_TYPE (t) : t);
     780         2830 : }
     781              : 
     782              : /* direct-declarator
     783              :       identifier
     784              :       ( declarator )
     785              :       direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
     786              :       direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
     787              :       direct-declarator [ type-qualifier-list static assignment-expression ]
     788              :       direct-declarator [ type-qualifier-list * ]
     789              :       direct-declarator ( parameter-type-list )
     790              :       direct-declarator ( identifier-list(opt) )  */
     791              : 
     792              : void
     793            0 : c_pretty_printer::direct_declarator (tree t)
     794              : {
     795            0 :   switch (TREE_CODE (t))
     796              :     {
     797            0 :     case VAR_DECL:
     798            0 :     case PARM_DECL:
     799            0 :     case TYPE_DECL:
     800            0 :     case FIELD_DECL:
     801            0 :     case LABEL_DECL:
     802            0 :       pp_c_space_for_pointer_operator (this, TREE_TYPE (t));
     803            0 :       pp_c_tree_decl_identifier (this, t);
     804            0 :       break;
     805              : 
     806            0 :     case ARRAY_TYPE:
     807            0 :     case POINTER_TYPE:
     808            0 :       abstract_declarator (TREE_TYPE (t));
     809            0 :       break;
     810              : 
     811            0 :     case FUNCTION_TYPE:
     812            0 :       pp_parameter_list (this, t);
     813            0 :       abstract_declarator (TREE_TYPE (t));
     814            0 :       break;
     815              : 
     816            0 :     case FUNCTION_DECL:
     817            0 :       pp_c_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
     818            0 :       pp_c_tree_decl_identifier (this, t);
     819            0 :       if (flags & pp_c_flag_abstract)
     820            0 :         abstract_declarator (TREE_TYPE (t));
     821              :       else
     822              :         {
     823            0 :           pp_parameter_list (this, t);
     824            0 :           abstract_declarator (TREE_TYPE (TREE_TYPE (t)));
     825              :         }
     826              :       break;
     827              : 
     828              :     case INTEGER_TYPE:
     829              :     case REAL_TYPE:
     830              :     case FIXED_POINT_TYPE:
     831              :     case ENUMERAL_TYPE:
     832              :     case BITINT_TYPE:
     833              :     case UNION_TYPE:
     834              :     case RECORD_TYPE:
     835              :       break;
     836              : 
     837            0 :     default:
     838            0 :       pp_unsupported_tree (this, t);
     839            0 :       break;
     840              :     }
     841            0 : }
     842              : 
     843              : 
     844              : /* declarator:
     845              :       pointer(opt)  direct-declarator   */
     846              : 
     847              : void
     848            0 : c_pretty_printer::declarator (tree t)
     849              : {
     850            0 :   switch (TREE_CODE (t))
     851              :     {
     852              :     case INTEGER_TYPE:
     853              :     case REAL_TYPE:
     854              :     case FIXED_POINT_TYPE:
     855              :     case ENUMERAL_TYPE:
     856              :     case BITINT_TYPE:
     857              :     case UNION_TYPE:
     858              :     case RECORD_TYPE:
     859              :       break;
     860              : 
     861            0 :     case VAR_DECL:
     862            0 :     case PARM_DECL:
     863            0 :     case FIELD_DECL:
     864            0 :     case ARRAY_TYPE:
     865            0 :     case FUNCTION_TYPE:
     866            0 :     case FUNCTION_DECL:
     867            0 :     case TYPE_DECL:
     868            0 :       direct_declarator (t);
     869            0 :     break;
     870              : 
     871              : 
     872            0 :     default:
     873            0 :       pp_unsupported_tree (this, t);
     874            0 :       break;
     875              :     }
     876            0 : }
     877              : 
     878              : /* declaration:
     879              :       declaration-specifiers init-declarator-list(opt) ;  */
     880              : 
     881              : void
     882            0 : c_pretty_printer::declaration (tree t)
     883              : {
     884            0 :   declaration_specifiers (t);
     885            0 :   pp_c_init_declarator (this, t);
     886            0 : }
     887              : 
     888              : /* Pretty-print ATTRIBUTES marked to be displayed on diagnostic.  */
     889              : 
     890              : void
     891       488553 : pp_c_attributes_display (c_pretty_printer *pp, tree a)
     892              : {
     893       488553 :   bool is_first = true;
     894              : 
     895       488553 :   if (a == NULL_TREE)
     896              :     return;
     897              : 
     898          991 :   const bool std_p = cxx11_attribute_p (a);
     899              : 
     900         2235 :   for (; a != NULL_TREE; a = TREE_CHAIN (a))
     901              :     {
     902         1244 :       const struct attribute_spec *as
     903         1244 :         = lookup_attribute_spec (get_attribute_name (a));
     904         1244 :       if (!as || as->affects_type_identity == false)
     905          489 :         continue;
     906          755 :       if (c_dialect_cxx ()
     907          486 :           && !strcmp ("transaction_safe", as->name))
     908              :         /* In C++ transaction_safe is printed at the end of the declarator.  */
     909           19 :         continue;
     910          736 :       if (is_first)
     911              :         {
     912          736 :           if (std_p)
     913              :             {
     914            6 :               pp_c_left_bracket (pp);
     915            6 :               pp_c_left_bracket (pp);
     916              :             }
     917              :           else
     918              :             {
     919          730 :               pp_c_ws_string (pp, "__attribute__");
     920          730 :               pp_c_left_paren (pp);
     921          730 :               pp_c_left_paren (pp);
     922              :             }
     923              :           is_first = false;
     924              :         }
     925              :       else
     926            0 :         pp_separate_with (pp, ',');
     927          736 :       tree ns;
     928          736 :       if (std_p && (ns = get_attribute_namespace (a)))
     929              :         {
     930            6 :           pp_tree_identifier (pp, ns);
     931            6 :           pp_colon (pp);
     932            6 :           pp_colon (pp);
     933              :         }
     934          736 :       pp_tree_identifier (pp, get_attribute_name (a));
     935          736 :       if (TREE_VALUE (a))
     936          546 :         pp_c_call_argument_list (pp, TREE_VALUE (a));
     937              :     }
     938              : 
     939          991 :   if (!is_first)
     940              :     {
     941          736 :       if (std_p)
     942              :         {
     943            6 :           pp_c_right_bracket (pp);
     944            6 :           pp_c_right_bracket (pp);
     945              :         }
     946              :       else
     947              :         {
     948          730 :           pp_c_right_paren (pp);
     949          730 :           pp_c_right_paren (pp);
     950          730 :           pp_c_whitespace (pp);
     951              :         }
     952              :     }
     953              : }
     954              : 
     955              : /* function-definition:
     956              :       declaration-specifiers declarator compound-statement  */
     957              : 
     958              : void
     959            0 : pp_c_function_definition (c_pretty_printer *pp, tree t)
     960              : {
     961            0 :   pp->declaration_specifiers (t);
     962            0 :   pp->declarator (t);
     963            0 :   pp_needs_newline (pp) = true;
     964            0 :   pp->statement (DECL_SAVED_TREE (t));
     965            0 :   pp_newline_and_flush (pp);
     966            0 : }
     967              : 
     968              : 
     969              : /* Expressions.  */
     970              : 
     971              : /* Print out a c-char.  This is called solely for characters which are
     972              :    in the *target* execution character set.  We ought to convert them
     973              :    back to the *host* execution character set before printing, but we
     974              :    have no way to do this at present.  A decent compromise is to print
     975              :    all characters as if they were in the host execution character set,
     976              :    and not attempt to recover any named escape characters, but render
     977              :    all unprintables as octal escapes.  If the host and target character
     978              :    sets are the same, this produces relatively readable output.  If they
     979              :    are not the same, strings may appear as gibberish, but that's okay
     980              :    (in fact, it may well be what the reader wants, e.g. if they are looking
     981              :    to see if conversion to the target character set happened correctly).
     982              : 
     983              :    A special case: we need to prefix \, ", and ' with backslashes.  It is
     984              :    correct to do so for the *host*'s \, ", and ', because the rest of the
     985              :    file appears in the host character set.  */
     986              : 
     987              : static void
     988      1703236 : pp_c_char (c_pretty_printer *pp, int c)
     989              : {
     990      1703236 :   if (ISPRINT (c))
     991              :     {
     992      1701045 :       switch (c)
     993              :         {
     994            0 :         case '\\': pp_string (pp, "\\\\"); break;
     995          180 :         case '\'': pp_string (pp, "\\\'"); break;
     996            0 :         case '\"': pp_string (pp, "\\\""); break;
     997      1700865 :         default:   pp_character (pp, c);
     998              :         }
     999              :     }
    1000              :   else
    1001         2191 :     pp_scalar (pp, "\\%03o", (unsigned) c);
    1002      1703236 : }
    1003              : 
    1004              : /* Print out a STRING literal.  */
    1005              : 
    1006              : void
    1007         1175 : pp_c_string_literal (c_pretty_printer *pp, tree s)
    1008              : {
    1009         1175 :   const char *p = TREE_STRING_POINTER (s);
    1010         1175 :   int n = TREE_STRING_LENGTH (s) - 1;
    1011         1175 :   int i;
    1012         1175 :   pp_doublequote (pp);
    1013        12700 :   for (i = 0; i < n; ++i)
    1014        10350 :     pp_c_char (pp, p[i]);
    1015         1175 :   pp_doublequote (pp);
    1016         1175 : }
    1017              : 
    1018              : /* Pretty-print a VOID_CST (void_node).  */
    1019              : 
    1020              : static void
    1021           27 : pp_c_void_constant (c_pretty_printer *pp)
    1022              : {
    1023           27 :   pp_c_type_cast (pp, void_type_node);
    1024           27 :   pp_string (pp, "0");
    1025           27 : }
    1026              : 
    1027              : /* Pretty-print an INTEGER literal.  */
    1028              : 
    1029              : void
    1030     14797474 : pp_c_integer_constant (c_pretty_printer *pp, tree i)
    1031              : {
    1032     14797474 :   if (tree_fits_shwi_p (i))
    1033     13207811 :     pp_wide_integer (pp, tree_to_shwi (i));
    1034      1589663 :   else if (tree_fits_uhwi_p (i))
    1035      1589641 :     pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
    1036              :   else
    1037              :     {
    1038           22 :       wide_int wi = wi::to_wide (i);
    1039              : 
    1040           22 :       if (wi::lt_p (wi::to_wide (i), 0, TYPE_SIGN (TREE_TYPE (i))))
    1041              :         {
    1042            5 :           pp_minus (pp);
    1043            5 :           wi = -wi;
    1044              :         }
    1045           22 :       unsigned int prec = wi.get_precision ();
    1046           22 :       if ((prec + 3) / 4 > sizeof (pp_buffer (pp)->m_digit_buffer) - 3)
    1047              :         {
    1048            1 :           char *buf = XALLOCAVEC (char, (prec + 3) / 4 + 3);
    1049            1 :           print_hex (wi, buf);
    1050            1 :           pp_string (pp, buf);
    1051              :         }
    1052              :       else
    1053              :         {
    1054           21 :           print_hex (wi, pp_buffer (pp)->m_digit_buffer);
    1055           21 :           pp_string (pp, pp_buffer (pp)->m_digit_buffer);
    1056              :         }
    1057           22 :     }
    1058     14797474 : }
    1059              : 
    1060              : /* Print out a CHARACTER literal.  */
    1061              : 
    1062              : static void
    1063      1692886 : pp_c_character_constant (c_pretty_printer *pp, tree c)
    1064              : {
    1065      1692886 :   pp_quote (pp);
    1066      1692886 :   pp_c_char (pp, (unsigned) TREE_INT_CST_LOW (c));
    1067      1692886 :   pp_quote (pp);
    1068      1692886 : }
    1069              : 
    1070              : /* Print out a BOOLEAN literal.  */
    1071              : 
    1072              : static void
    1073      8551803 : pp_c_bool_constant (c_pretty_printer *pp, tree b)
    1074              : {
    1075      8551803 :   if (b == boolean_false_node)
    1076              :     {
    1077      4913391 :       if (c_dialect_cxx ())
    1078      4913391 :         pp_c_ws_string (pp, "false");
    1079            0 :       else if (flag_isoc99)
    1080            0 :         pp_c_ws_string (pp, "_False");
    1081              :       else
    1082            0 :         pp_unsupported_tree (pp, b);
    1083              :     }
    1084      3638412 :   else if (b == boolean_true_node)
    1085              :     {
    1086      3638412 :       if (c_dialect_cxx ())
    1087      3638412 :         pp_c_ws_string (pp, "true");
    1088            0 :       else if (flag_isoc99)
    1089            0 :         pp_c_ws_string (pp, "_True");
    1090              :       else
    1091            0 :         pp_unsupported_tree (pp, b);
    1092              :     }
    1093            0 :   else if (TREE_CODE (b) == INTEGER_CST)
    1094            0 :     pp_c_integer_constant (pp, b);
    1095              :   else
    1096            0 :     pp_unsupported_tree (pp, b);
    1097      8551803 : }
    1098              : 
    1099              : /* Given a value e of ENUMERAL_TYPE:
    1100              :    Print out the first ENUMERATOR id with value e, if one is found,
    1101              :    else print out the value as a C-style cast (type-id)value.  */
    1102              : 
    1103              : static void
    1104            0 : pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
    1105              : {
    1106            0 :   tree type = TREE_TYPE (e);
    1107            0 :   tree value = NULL_TREE;
    1108              : 
    1109              :   /* Find the name of this constant.  */
    1110            0 :   if ((pp->flags & pp_c_flag_gnu_v3) == 0)
    1111            0 :     for (value = TYPE_VALUES (type); value != NULL_TREE;
    1112            0 :          value = TREE_CHAIN (value))
    1113            0 :       if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e))
    1114              :         break;
    1115              : 
    1116            0 :   if (value != NULL_TREE)
    1117            0 :     pp->id_expression (TREE_PURPOSE (value));
    1118              :   else
    1119              :     {
    1120              :       /* Value must have been cast.  */
    1121            0 :       pp_c_type_cast (pp, type);
    1122            0 :       pp_c_integer_constant (pp, e);
    1123              :     }
    1124            0 : }
    1125              : 
    1126              : /* Print out a REAL value as a decimal-floating-constant.  */
    1127              : 
    1128              : static void
    1129          866 : pp_c_floating_constant (c_pretty_printer *pp, tree r)
    1130              : {
    1131          866 :   const struct real_format *fmt
    1132          866 :     = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (r)));
    1133              : 
    1134          866 :   REAL_VALUE_TYPE floating_cst = TREE_REAL_CST (r);
    1135          866 :   bool is_decimal = floating_cst.decimal;
    1136              : 
    1137              :   /* See ISO C++ WG N1822.  Note: The fraction 643/2136 approximates
    1138              :      log10(2) to 7 significant digits.  */
    1139          866 :   int max_digits10 = 2 + (is_decimal ? fmt->p : fmt->p * 643L / 2136);
    1140              : 
    1141          866 :   real_to_decimal (pp_buffer (pp)->m_digit_buffer, &TREE_REAL_CST (r),
    1142              :                    sizeof (pp_buffer (pp)->m_digit_buffer),
    1143              :                    max_digits10, 1);
    1144              : 
    1145          866 :   pp_string (pp, pp_buffer(pp)->m_digit_buffer);
    1146          866 :   if (TREE_TYPE (r) == float_type_node)
    1147          249 :     pp_character (pp, 'f');
    1148          617 :   else if (TREE_TYPE (r) == long_double_type_node)
    1149           32 :     pp_character (pp, 'l');
    1150          585 :   else if (TREE_TYPE (r) == dfloat128_type_node)
    1151           12 :     pp_string (pp, "dl");
    1152          573 :   else if (TREE_TYPE (r) == dfloat64_type_node)
    1153           12 :     pp_string (pp, "dd");
    1154          561 :   else if (TREE_TYPE (r) == dfloat32_type_node)
    1155           12 :     pp_string (pp, "df");
    1156          549 :   else if (TREE_TYPE (r) == dfloat64x_type_node)
    1157            0 :     pp_string (pp, "d64x");
    1158          549 :   else if (TREE_TYPE (r) != double_type_node)
    1159            4 :     for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
    1160            4 :       if (TREE_TYPE (r) == FLOATN_NX_TYPE_NODE (i))
    1161              :         {
    1162            2 :           pp_character (pp, 'f');
    1163            2 :           pp_decimal_int (pp, floatn_nx_types[i].n);
    1164            2 :           if (floatn_nx_types[i].extended)
    1165            0 :             pp_character (pp, 'x');
    1166              :           break;
    1167              :         }
    1168          866 : }
    1169              : 
    1170              : /* Print out a FIXED value as a decimal-floating-constant.  */
    1171              : 
    1172              : static void
    1173            0 : pp_c_fixed_constant (c_pretty_printer *pp, tree r)
    1174              : {
    1175            0 :   fixed_to_decimal (pp_buffer (pp)->m_digit_buffer, &TREE_FIXED_CST (r),
    1176              :                    sizeof (pp_buffer (pp)->m_digit_buffer));
    1177            0 :   pp_string (pp, pp_buffer(pp)->m_digit_buffer);
    1178            0 : }
    1179              : 
    1180              : /* Pretty-print a compound literal expression.  GNU extensions include
    1181              :    vector constants.  */
    1182              : 
    1183              : static void
    1184           66 : pp_c_compound_literal (c_pretty_printer *pp, tree e)
    1185              : {
    1186           66 :   tree type = TREE_TYPE (e);
    1187           66 :   pp_c_type_cast (pp, type);
    1188              : 
    1189           66 :   switch (TREE_CODE (type))
    1190              :     {
    1191           66 :     case RECORD_TYPE:
    1192           66 :     case UNION_TYPE:
    1193           66 :     case ARRAY_TYPE:
    1194           66 :     case VECTOR_TYPE:
    1195           66 :     case COMPLEX_TYPE:
    1196           66 :       pp_c_brace_enclosed_initializer_list (pp, e);
    1197           66 :       break;
    1198              : 
    1199            0 :     default:
    1200            0 :       pp_unsupported_tree (pp, e);
    1201            0 :       break;
    1202              :     }
    1203           66 : }
    1204              : 
    1205              : /* Pretty-print a COMPLEX_EXPR expression.  */
    1206              : 
    1207              : static void
    1208           24 : pp_c_complex_expr (c_pretty_printer *pp, tree e)
    1209              : {
    1210              :   /* Handle a few common special cases, otherwise fallback
    1211              :      to printing it as compound literal.  */
    1212           24 :   tree type = TREE_TYPE (e);
    1213           24 :   tree realexpr = TREE_OPERAND (e, 0);
    1214           24 :   tree imagexpr = TREE_OPERAND (e, 1);
    1215              : 
    1216              :   /* Cast of an COMPLEX_TYPE expression to a different COMPLEX_TYPE.  */
    1217           24 :   if (TREE_CODE (realexpr) == NOP_EXPR
    1218           20 :       && TREE_CODE (imagexpr) == NOP_EXPR
    1219            8 :       && TREE_TYPE (realexpr) == TREE_TYPE (type)
    1220            8 :       && TREE_TYPE (imagexpr) == TREE_TYPE (type)
    1221            8 :       && TREE_CODE (TREE_OPERAND (realexpr, 0)) == REALPART_EXPR
    1222            8 :       && TREE_CODE (TREE_OPERAND (imagexpr, 0)) == IMAGPART_EXPR
    1223           32 :       && TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0)
    1224            8 :          == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0))
    1225              :     {
    1226            8 :       pp_c_type_cast (pp, type);
    1227            8 :       pp->expression (TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
    1228            8 :       return;
    1229              :     }
    1230              : 
    1231              :   /* Cast of an scalar expression to COMPLEX_TYPE.  */
    1232           24 :   if ((integer_zerop (imagexpr) || real_zerop (imagexpr))
    1233           18 :       && TREE_TYPE (realexpr) == TREE_TYPE (type))
    1234              :     {
    1235           10 :       pp_c_type_cast (pp, type);
    1236           10 :       if (TREE_CODE (realexpr) == NOP_EXPR)
    1237            6 :         realexpr = TREE_OPERAND (realexpr, 0);
    1238           10 :       pp->expression (realexpr);
    1239           10 :       return;
    1240              :     }
    1241              : 
    1242            6 :   pp_c_compound_literal (pp, e);
    1243              : }
    1244              : 
    1245              : /* constant:
    1246              :       integer-constant
    1247              :       floating-constant
    1248              :       fixed-point-constant
    1249              :       enumeration-constant
    1250              :       character-constant   */
    1251              : 
    1252              : void
    1253     24145207 : c_pretty_printer::constant (tree e)
    1254              : {
    1255     24145207 :   const enum tree_code code = TREE_CODE (e);
    1256              : 
    1257     24145207 :   switch (code)
    1258              :     {
    1259           27 :     case VOID_CST:
    1260           27 :       pp_c_void_constant (this);
    1261           27 :       break;
    1262              : 
    1263     24143590 :     case INTEGER_CST:
    1264     24143590 :       {
    1265     24143590 :         tree type = TREE_TYPE (e);
    1266     24143590 :         if (type == boolean_type_node)
    1267      8551803 :           pp_c_bool_constant (this, e);
    1268     15591787 :         else if (type == char_type_node)
    1269      1692886 :           pp_c_character_constant (this, e);
    1270     13898901 :         else if (TREE_CODE (type) == ENUMERAL_TYPE)
    1271            0 :           pp_c_enumeration_constant (this, e);
    1272     13898901 :         else if (NULLPTR_TYPE_P (type))
    1273            0 :           pp_string (this, "nullptr");
    1274              :         else
    1275     13898901 :           pp_c_integer_constant (this, e);
    1276              :       }
    1277              :       break;
    1278              : 
    1279          695 :     case REAL_CST:
    1280          695 :       pp_c_floating_constant (this, e);
    1281          695 :       break;
    1282              : 
    1283            0 :     case FIXED_CST:
    1284            0 :       pp_c_fixed_constant (this, e);
    1285            0 :       break;
    1286              : 
    1287          895 :     case STRING_CST:
    1288          895 :       pp_c_string_literal (this, e);
    1289          895 :       break;
    1290              : 
    1291            0 :     case COMPLEX_CST:
    1292              :       /* Sometimes, we are confused and we think a complex literal
    1293              :          is a constant.  Such thing is a compound literal which
    1294              :          grammatically belongs to postfix-expr production.  */
    1295            0 :       pp_c_compound_literal (this, e);
    1296            0 :       break;
    1297              : 
    1298            0 :     default:
    1299            0 :       pp_unsupported_tree (this, e);
    1300            0 :       break;
    1301              :     }
    1302     24145207 : }
    1303              : 
    1304              : /* Pretty-print a string such as an identifier, without changing its
    1305              :    encoding, preceded by whitespace is necessary.  */
    1306              : 
    1307              : void
    1308     38358672 : pp_c_ws_string (c_pretty_printer *pp, const char *str)
    1309              : {
    1310     38358672 :   pp_c_maybe_whitespace (pp);
    1311     38358672 :   pp_string (pp, str);
    1312     38358672 :   pp->set_padding (pp_before);
    1313     38358672 : }
    1314              : 
    1315              : void
    1316        42279 : c_pretty_printer::translate_string (const char *gmsgid)
    1317              : {
    1318        42279 :   if (pp_translate_identifiers (this))
    1319         9474 :     pp_c_ws_string (this, _(gmsgid));
    1320              :   else
    1321        32805 :     pp_c_ws_string (this, gmsgid);
    1322        42279 : }
    1323              : 
    1324              : /* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences
    1325              :    that need converting to the locale encoding, preceded by whitespace
    1326              :    is necessary.  */
    1327              : 
    1328              : void
    1329    533398141 : pp_c_identifier (c_pretty_printer *pp, const char *id)
    1330              : {
    1331    533398141 :   pp_c_maybe_whitespace (pp);
    1332    533398141 :   pp_identifier (pp, id);
    1333    533398141 :   pp->set_padding (pp_before);
    1334    533398141 : }
    1335              : 
    1336              : /* Pretty-print a C primary-expression.
    1337              :    primary-expression:
    1338              :       identifier
    1339              :       constant
    1340              :       string-literal
    1341              :       ( expression )   */
    1342              : 
    1343              : void
    1344        35710 : c_pretty_printer::primary_expression (tree e)
    1345              : {
    1346        35710 :   switch (TREE_CODE (e))
    1347              :     {
    1348        28196 :     case VAR_DECL:
    1349        28196 :     case PARM_DECL:
    1350        28196 :     case FIELD_DECL:
    1351        28196 :     case CONST_DECL:
    1352        28196 :     case FUNCTION_DECL:
    1353        28196 :     case LABEL_DECL:
    1354        28196 :       pp_c_tree_decl_identifier (this, e);
    1355        28196 :       break;
    1356              : 
    1357          196 :     case IDENTIFIER_NODE:
    1358          196 :       pp_c_tree_identifier (this, e);
    1359          196 :       break;
    1360              : 
    1361           22 :     case ERROR_MARK:
    1362           22 :       translate_string ("<erroneous-expression>");
    1363           22 :       break;
    1364              : 
    1365           33 :     case RESULT_DECL:
    1366           33 :       translate_string ("<return-value>");
    1367           33 :       break;
    1368              : 
    1369         1128 :     case VOID_CST:
    1370         1128 :     case INTEGER_CST:
    1371         1128 :     case REAL_CST:
    1372         1128 :     case FIXED_CST:
    1373         1128 :     case STRING_CST:
    1374         1128 :       constant (e);
    1375         1128 :       break;
    1376              : 
    1377            2 :     case TARGET_EXPR:
    1378            2 :       pp_c_ws_string (this, "__builtin_memcpy");
    1379            2 :       pp_c_left_paren (this);
    1380            2 :       pp_ampersand (this);
    1381            2 :       primary_expression (TARGET_EXPR_SLOT (e));
    1382            2 :       pp_separate_with (this, ',');
    1383            2 :       pp_ampersand (this);
    1384            2 :       initializer (TARGET_EXPR_INITIAL (e));
    1385            2 :       if (TARGET_EXPR_CLEANUP (e))
    1386              :         {
    1387            0 :           pp_separate_with (this, ',');
    1388            0 :           expression (TARGET_EXPR_CLEANUP (e));
    1389              :         }
    1390            2 :       pp_c_right_paren (this);
    1391            2 :       break;
    1392              : 
    1393          799 :     case SSA_NAME:
    1394          799 :       if (SSA_NAME_VAR (e))
    1395          750 :         primary_expression (SSA_NAME_VAR (e));
    1396           49 :       else if (gimple_assign_single_p (SSA_NAME_DEF_STMT (e)))
    1397              :         {
    1398              :           /* Print only the right side of the GIMPLE assignment.  */
    1399            6 :           gimple *def_stmt = SSA_NAME_DEF_STMT (e);
    1400            6 :           pp_gimple_stmt_1 (this, def_stmt, 0, TDF_RHS_ONLY);
    1401              :         }
    1402              :       else
    1403           43 :         expression (e);
    1404              :       break;
    1405              : 
    1406         5334 :     default:
    1407              :       /* FIXME:  Make sure we won't get into an infinite loop.  */
    1408         5334 :       if (location_wrapper_p (e))
    1409          340 :         expression (e);
    1410              :       else
    1411              :         {
    1412         4994 :           pp_c_left_paren (this);
    1413         4994 :           expression (e);
    1414         4994 :           pp_c_right_paren (this);
    1415              :         }
    1416              :       break;
    1417              :     }
    1418        35710 : }
    1419              : 
    1420              : /* Print out a C initializer -- also support C compound-literals.
    1421              :    initializer:
    1422              :       assignment-expression:
    1423              :       { initializer-list }
    1424              :       { initializer-list , }   */
    1425              : 
    1426              : void
    1427           28 : c_pretty_printer::initializer (tree e)
    1428              : {
    1429           28 :   if (TREE_CODE (e) == CONSTRUCTOR)
    1430           26 :     pp_c_brace_enclosed_initializer_list (this, e);
    1431              :   else
    1432            2 :     expression (e);
    1433           28 : }
    1434              : 
    1435              : /* init-declarator:
    1436              :       declarator:
    1437              :       declarator = initializer   */
    1438              : 
    1439              : void
    1440            0 : pp_c_init_declarator (c_pretty_printer *pp, tree t)
    1441              : {
    1442            0 :   pp->declarator (t);
    1443              :   /* We don't want to output function definitions here.  There are handled
    1444              :      elsewhere (and the syntactic form is bogus anyway).  */
    1445            0 :   if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
    1446              :     {
    1447            0 :       tree init = DECL_INITIAL (t);
    1448              :       /* This C++ bit is handled here because it is easier to do so.
    1449              :          In templates, the C++ parser builds a TREE_LIST for a
    1450              :          direct-initialization; the TREE_PURPOSE is the variable to
    1451              :          initialize and the TREE_VALUE is the initializer.  */
    1452            0 :       if (TREE_CODE (init) == TREE_LIST)
    1453              :         {
    1454            0 :           pp_c_left_paren (pp);
    1455            0 :           pp->expression (TREE_VALUE (init));
    1456            0 :           pp_right_paren (pp);
    1457              :         }
    1458              :       else
    1459              :         {
    1460            0 :           pp_space (pp);
    1461            0 :           pp_equal (pp);
    1462            0 :           pp_space (pp);
    1463            0 :           pp->initializer (init);
    1464              :         }
    1465              :     }
    1466            0 : }
    1467              : 
    1468              : /* initializer-list:
    1469              :       designation(opt) initializer
    1470              :       initializer-list , designation(opt) initializer
    1471              : 
    1472              :    designation:
    1473              :       designator-list =
    1474              : 
    1475              :    designator-list:
    1476              :       designator
    1477              :       designator-list designator
    1478              : 
    1479              :    designator:
    1480              :       [ constant-expression ]
    1481              :       identifier   */
    1482              : 
    1483              : static void
    1484           92 : pp_c_initializer_list (c_pretty_printer *pp, tree e)
    1485              : {
    1486           92 :   tree type = TREE_TYPE (e);
    1487           92 :   const enum tree_code code = TREE_CODE (type);
    1488              : 
    1489           92 :   if (TREE_CODE (e) == CONSTRUCTOR)
    1490              :     {
    1491           26 :       pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
    1492           26 :       return;
    1493              :     }
    1494              : 
    1495           66 :   switch (code)
    1496              :     {
    1497            0 :     case RECORD_TYPE:
    1498            0 :     case UNION_TYPE:
    1499            0 :     case ARRAY_TYPE:
    1500            0 :       {
    1501            0 :         tree init = TREE_OPERAND (e, 0);
    1502            0 :         for (; init != NULL_TREE; init = TREE_CHAIN (init))
    1503              :           {
    1504            0 :             if (code == RECORD_TYPE || code == UNION_TYPE)
    1505              :               {
    1506            0 :                 pp_c_dot (pp);
    1507            0 :                 pp->primary_expression (TREE_PURPOSE (init));
    1508              :               }
    1509              :             else
    1510              :               {
    1511            0 :                 pp_c_left_bracket (pp);
    1512            0 :                 if (TREE_PURPOSE (init))
    1513            0 :                   pp->constant (TREE_PURPOSE (init));
    1514            0 :                 pp_c_right_bracket (pp);
    1515              :               }
    1516            0 :             pp_c_whitespace (pp);
    1517            0 :             pp_equal (pp);
    1518            0 :             pp_c_whitespace (pp);
    1519            0 :             pp->initializer (TREE_VALUE (init));
    1520            0 :             if (TREE_CHAIN (init))
    1521            0 :               pp_separate_with (pp, ',');
    1522              :           }
    1523              :       }
    1524              :       return;
    1525              : 
    1526            6 :     case VECTOR_TYPE:
    1527            6 :       if (TREE_CODE (e) == VECTOR_CST)
    1528              :         {
    1529              :           /* We don't create variable-length VECTOR_CSTs.  */
    1530            6 :           unsigned int nunits = VECTOR_CST_NELTS (e).to_constant ();
    1531           30 :           for (unsigned int i = 0; i < nunits; ++i)
    1532              :             {
    1533           24 :               if (i > 0)
    1534           18 :                 pp_separate_with (pp, ',');
    1535           24 :               pp->expression (VECTOR_CST_ELT (e, i));
    1536              :             }
    1537              :         }
    1538              :       else
    1539              :         break;
    1540              :       return;
    1541              : 
    1542           60 :     case COMPLEX_TYPE:
    1543           60 :       if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
    1544              :         {
    1545           60 :           const bool cst = TREE_CODE (e) == COMPLEX_CST;
    1546           60 :           pp->expression (cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
    1547           60 :           pp_separate_with (pp, ',');
    1548          114 :           pp->expression (cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
    1549              :         }
    1550              :       else
    1551              :         break;
    1552           60 :       return;
    1553              : 
    1554              :     default:
    1555              :       break;
    1556              :     }
    1557              : 
    1558            0 :   pp_unsupported_tree (pp, type);
    1559              : }
    1560              : 
    1561              : /* Pretty-print a brace-enclosed initializer-list.  */
    1562              : 
    1563              : static void
    1564           92 : pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
    1565              : {
    1566           92 :   pp_c_left_brace (pp);
    1567           92 :   pp_c_initializer_list (pp, l);
    1568           92 :   pp_c_right_brace (pp);
    1569           92 : }
    1570              : 
    1571              : 
    1572              : /*  This is a convenient function, used to bridge gap between C and C++
    1573              :     grammars.
    1574              : 
    1575              :     id-expression:
    1576              :        identifier  */
    1577              : 
    1578              : void
    1579        31361 : c_pretty_printer::id_expression (tree t)
    1580              : {
    1581        31361 :   switch (TREE_CODE (t))
    1582              :     {
    1583        29228 :     case VAR_DECL:
    1584        29228 :     case PARM_DECL:
    1585        29228 :     case CONST_DECL:
    1586        29228 :     case TYPE_DECL:
    1587        29228 :     case FUNCTION_DECL:
    1588        29228 :     case FIELD_DECL:
    1589        29228 :     case LABEL_DECL:
    1590        29228 :       pp_c_tree_decl_identifier (this, t);
    1591        29228 :       break;
    1592              : 
    1593         2133 :     case IDENTIFIER_NODE:
    1594         2133 :       pp_c_tree_identifier (this, t);
    1595         2133 :       break;
    1596              : 
    1597            0 :     default:
    1598            0 :       pp_unsupported_tree (this, t);
    1599            0 :       break;
    1600              :     }
    1601        31361 : }
    1602              : 
    1603              : /* postfix-expression:
    1604              :       primary-expression
    1605              :       postfix-expression [ expression ]
    1606              :       postfix-expression ( argument-expression-list(opt) )
    1607              :       postfix-expression . identifier
    1608              :       postfix-expression -> identifier
    1609              :       postfix-expression ++
    1610              :       postfix-expression --
    1611              :       ( type-name ) { initializer-list }
    1612              :       ( type-name ) { initializer-list , }  */
    1613              : 
    1614              : void
    1615        11933 : c_pretty_printer::postfix_expression (tree e)
    1616              : {
    1617        11933 :   enum tree_code code = TREE_CODE (e);
    1618        11933 :   switch (code)
    1619              :     {
    1620            0 :     case POSTINCREMENT_EXPR:
    1621            0 :     case POSTDECREMENT_EXPR:
    1622            0 :       postfix_expression (TREE_OPERAND (e, 0));
    1623            0 :       pp_string (this, code == POSTINCREMENT_EXPR ? "++" : "--");
    1624            0 :       break;
    1625              : 
    1626          547 :     case ARRAY_REF:
    1627          547 :       postfix_expression (TREE_OPERAND (e, 0));
    1628          547 :       pp_c_left_bracket (this);
    1629          547 :       expression (TREE_OPERAND (e, 1));
    1630          547 :       pp_c_right_bracket (this);
    1631          547 :       break;
    1632              : 
    1633            6 :     case OMP_ARRAY_SECTION:
    1634            6 :       postfix_expression (TREE_OPERAND (e, 0));
    1635            6 :       pp_c_left_bracket (this);
    1636            6 :       if (TREE_OPERAND (e, 1))
    1637            4 :         expression (TREE_OPERAND (e, 1));
    1638            6 :       pp_colon (this);
    1639            6 :       if (TREE_OPERAND (e, 2))
    1640            6 :         expression (TREE_OPERAND (e, 2));
    1641            6 :       pp_c_right_bracket (this);
    1642            6 :       break;
    1643              : 
    1644          146 :     case CALL_EXPR:
    1645          146 :       {
    1646          146 :         call_expr_arg_iterator iter;
    1647          146 :         tree arg;
    1648          146 :         if (CALL_EXPR_FN (e) != NULL_TREE)
    1649          145 :           postfix_expression (CALL_EXPR_FN (e));
    1650              :         else
    1651            1 :           pp_string (this, internal_fn_name (CALL_EXPR_IFN (e)));
    1652          146 :         pp_c_left_paren (this);
    1653          413 :         FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
    1654              :           {
    1655          121 :             expression (arg);
    1656          121 :             if (more_call_expr_args_p (&iter))
    1657            0 :               pp_separate_with (this, ',');
    1658              :           }
    1659          146 :         pp_c_right_paren (this);
    1660          146 :         break;
    1661              :       }
    1662              : 
    1663            0 :     case UNORDERED_EXPR:
    1664            0 :       pp_c_ws_string (this, flag_isoc99
    1665              :                            ? "isunordered"
    1666              :                            : "__builtin_isunordered");
    1667            0 :       goto two_args_fun;
    1668              : 
    1669            0 :     case ORDERED_EXPR:
    1670            0 :       pp_c_ws_string (this, flag_isoc99
    1671              :                            ? "!isunordered"
    1672              :                            : "!__builtin_isunordered");
    1673            0 :       goto two_args_fun;
    1674              : 
    1675            0 :     case UNLT_EXPR:
    1676            0 :       pp_c_ws_string (this, flag_isoc99
    1677              :                            ? "!isgreaterequal"
    1678              :                            : "!__builtin_isgreaterequal");
    1679            0 :       goto two_args_fun;
    1680              : 
    1681            0 :     case UNLE_EXPR:
    1682            0 :       pp_c_ws_string (this, flag_isoc99
    1683              :                            ? "!isgreater"
    1684              :                            : "!__builtin_isgreater");
    1685            0 :       goto two_args_fun;
    1686              : 
    1687            0 :     case UNGT_EXPR:
    1688            0 :       pp_c_ws_string (this, flag_isoc99
    1689              :                            ? "!islessequal"
    1690              :                            : "!__builtin_islessequal");
    1691            0 :       goto two_args_fun;
    1692              : 
    1693            0 :     case UNGE_EXPR:
    1694            0 :       pp_c_ws_string (this, flag_isoc99
    1695              :                            ? "!isless"
    1696              :                            : "!__builtin_isless");
    1697            0 :       goto two_args_fun;
    1698              : 
    1699            0 :     case UNEQ_EXPR:
    1700            0 :       pp_c_ws_string (this, flag_isoc99
    1701              :                            ? "!islessgreater"
    1702              :                            : "!__builtin_islessgreater");
    1703            0 :       goto two_args_fun;
    1704              : 
    1705            0 :     case LTGT_EXPR:
    1706            0 :       pp_c_ws_string (this, flag_isoc99
    1707              :                            ? "islessgreater"
    1708              :                            : "__builtin_islessgreater");
    1709            0 :       goto two_args_fun;
    1710              : 
    1711            1 :     case MAX_EXPR:
    1712            1 :       pp_c_ws_string (this, "max");
    1713            1 :       goto two_args_fun;
    1714              : 
    1715            1 :     case MIN_EXPR:
    1716            1 :       pp_c_ws_string (this, "min");
    1717            1 :       goto two_args_fun;
    1718              : 
    1719            2 :     two_args_fun:
    1720            2 :       pp_c_left_paren (this);
    1721            2 :       expression (TREE_OPERAND (e, 0));
    1722            2 :       pp_separate_with (this, ',');
    1723            2 :       expression (TREE_OPERAND (e, 1));
    1724            2 :       pp_c_right_paren (this);
    1725            2 :       break;
    1726              : 
    1727            0 :     case ABS_EXPR:
    1728            0 :       pp_c_ws_string (this, "__builtin_abs");
    1729            0 :       pp_c_left_paren (this);
    1730            0 :       expression (TREE_OPERAND (e, 0));
    1731            0 :       pp_c_right_paren (this);
    1732            0 :       break;
    1733              : 
    1734          879 :     case COMPONENT_REF:
    1735          879 :       {
    1736          879 :         tree object = TREE_OPERAND (e, 0);
    1737          879 :         if (INDIRECT_REF_P (object))
    1738              :           {
    1739          157 :             postfix_expression (TREE_OPERAND (object, 0));
    1740          157 :             pp_c_arrow (this);
    1741              :           }
    1742              :         else
    1743              :           {
    1744          722 :             postfix_expression (object);
    1745          722 :             pp_c_dot (this);
    1746              :           }
    1747          879 :         expression (TREE_OPERAND (e, 1));
    1748              :       }
    1749          879 :       break;
    1750              : 
    1751           12 :     case BIT_FIELD_REF:
    1752           12 :       {
    1753           12 :         tree type = TREE_TYPE (e);
    1754              : 
    1755           12 :         type = signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type);
    1756           12 :         if (type
    1757           12 :             && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1)))
    1758              :           {
    1759           12 :             HOST_WIDE_INT bitpos = tree_to_shwi (TREE_OPERAND (e, 2));
    1760           12 :             HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (type));
    1761           12 :             if ((bitpos % size) == 0)
    1762              :               {
    1763           12 :                 pp_c_left_paren (this);
    1764           12 :                 pp_c_left_paren (this);
    1765           12 :                 type_id (type);
    1766           12 :                 pp_c_star (this);
    1767           12 :                 pp_c_right_paren (this);
    1768           12 :                 pp_c_ampersand (this);
    1769           12 :                 expression (TREE_OPERAND (e, 0));
    1770           12 :                 pp_c_right_paren (this);
    1771           12 :                 pp_c_left_bracket (this);
    1772           12 :                 pp_wide_integer (this, bitpos / size);
    1773           12 :                 pp_c_right_bracket (this);
    1774           12 :                 break;
    1775              :               }
    1776              :           }
    1777            0 :         pp_unsupported_tree (this, e);
    1778              :       }
    1779            0 :       break;
    1780              : 
    1781          111 :     case MEM_REF:
    1782          111 :     case TARGET_MEM_REF:
    1783          111 :       expression (e);
    1784          111 :       break;
    1785              : 
    1786           60 :     case COMPLEX_CST:
    1787           60 :     case VECTOR_CST:
    1788           60 :       pp_c_compound_literal (this, e);
    1789           60 :       break;
    1790              : 
    1791           24 :     case COMPLEX_EXPR:
    1792           24 :       pp_c_complex_expr (this, e);
    1793           24 :       break;
    1794              : 
    1795            4 :     case COMPOUND_LITERAL_EXPR:
    1796            4 :       e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
    1797              :       /* Fall through.  */
    1798           26 :     case CONSTRUCTOR:
    1799           26 :       initializer (e);
    1800           26 :       break;
    1801              : 
    1802            0 :     case VA_ARG_EXPR:
    1803            0 :       pp_c_ws_string (this, "__builtin_va_arg");
    1804            0 :       pp_c_left_paren (this);
    1805            0 :       assignment_expression (TREE_OPERAND (e, 0));
    1806            0 :       pp_separate_with (this, ',');
    1807            0 :       type_id (TREE_TYPE (e));
    1808            0 :       pp_c_right_paren (this);
    1809            0 :       break;
    1810              : 
    1811          139 :     case ADDR_EXPR:
    1812          139 :       if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
    1813              :         {
    1814          139 :           id_expression (TREE_OPERAND (e, 0));
    1815          139 :           break;
    1816              :         }
    1817              :       /* fall through.  */
    1818              : 
    1819         9981 :     default:
    1820         9981 :       primary_expression (e);
    1821         9981 :       break;
    1822              :     }
    1823        11933 : }
    1824              : 
    1825              : /* Print out an expression-list; E is expected to be a TREE_LIST.  */
    1826              : 
    1827              : void
    1828          667 : pp_c_expression_list (c_pretty_printer *pp, tree e)
    1829              : {
    1830         1334 :   for (; e != NULL_TREE; e = TREE_CHAIN (e))
    1831              :     {
    1832          667 :       pp->expression (TREE_VALUE (e));
    1833          667 :       if (TREE_CHAIN (e))
    1834            0 :         pp_separate_with (pp, ',');
    1835              :     }
    1836          667 : }
    1837              : 
    1838              : /* Print out V, which contains the elements of a constructor.  */
    1839              : 
    1840              : void
    1841           26 : pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
    1842              : {
    1843           26 :   unsigned HOST_WIDE_INT ix;
    1844           26 :   tree value;
    1845              : 
    1846           37 :   FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
    1847              :     {
    1848           11 :       pp->expression (value);
    1849           11 :       if (ix != vec_safe_length (v) - 1)
    1850            1 :         pp_separate_with (pp, ',');
    1851              :     }
    1852           26 : }
    1853              : 
    1854              : /* Print out an expression-list in parens, as if it were the argument
    1855              :    list to a function.  */
    1856              : 
    1857              : void
    1858          694 : pp_c_call_argument_list (c_pretty_printer *pp, tree t)
    1859              : {
    1860          694 :   pp_c_left_paren (pp);
    1861          694 :   if (t && TREE_CODE (t) == TREE_LIST)
    1862          667 :     pp_c_expression_list (pp, t);
    1863          694 :   pp_c_right_paren (pp);
    1864          694 : }
    1865              : 
    1866              : /* Try to fold *(type *)&op into op.fld.fld2[1] if possible.
    1867              :    Only used for printing expressions.  Should punt if ambiguous
    1868              :    (e.g. in unions).  */
    1869              : 
    1870              : static tree
    1871          723 : c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
    1872              :                               offset_int &off)
    1873              : {
    1874          723 :   tree optype = TREE_TYPE (op);
    1875          723 :   if (off == 0)
    1876              :     {
    1877          651 :       if (lang_hooks.types_compatible_p (optype, type))
    1878              :         return op;
    1879              :       /* *(foo *)&complexfoo => __real__ complexfoo */
    1880          365 :       else if (TREE_CODE (optype) == COMPLEX_TYPE
    1881          365 :                && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
    1882            0 :         return build1_loc (loc, REALPART_EXPR, type, op);
    1883              :     }
    1884              :   /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
    1885           72 :   else if (TREE_CODE (optype) == COMPLEX_TYPE
    1886            0 :            && lang_hooks.types_compatible_p (type, TREE_TYPE (optype))
    1887           72 :            && tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
    1888              :     {
    1889            0 :       off = 0;
    1890            0 :       return build1_loc (loc, IMAGPART_EXPR, type, op);
    1891              :     }
    1892              :   /* ((foo *)&fooarray)[x] => fooarray[x] */
    1893          437 :   if (TREE_CODE (optype) == ARRAY_TYPE
    1894          300 :       && TYPE_SIZE_UNIT (TREE_TYPE (optype))
    1895          300 :       && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
    1896          737 :       && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
    1897              :     {
    1898          300 :       tree type_domain = TYPE_DOMAIN (optype);
    1899          300 :       tree min_val = size_zero_node;
    1900          300 :       if (type_domain && TYPE_MIN_VALUE (type_domain))
    1901          300 :         min_val = TYPE_MIN_VALUE (type_domain);
    1902          300 :       offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
    1903          300 :       offset_int idx = off / el_sz;
    1904          300 :       offset_int rem = off % el_sz;
    1905          300 :       if (TREE_CODE (min_val) == INTEGER_CST)
    1906              :         {
    1907          300 :           tree index
    1908          300 :             = wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));
    1909          300 :           op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
    1910              :                            NULL_TREE, NULL_TREE);
    1911          300 :           off = rem;
    1912          300 :           if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
    1913          300 :             return ret;
    1914           22 :           return op;
    1915              :         }
    1916              :     }
    1917              :   /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
    1918          137 :   else if (TREE_CODE (optype) == RECORD_TYPE)
    1919              :     {
    1920           79 :       for (tree field = TYPE_FIELDS (optype);
    1921          413 :            field; field = DECL_CHAIN (field))
    1922          413 :         if (TREE_CODE (field) == FIELD_DECL
    1923          143 :             && TREE_TYPE (field) != error_mark_node
    1924          143 :             && TYPE_SIZE_UNIT (TREE_TYPE (field))
    1925          556 :             && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (field))) == INTEGER_CST)
    1926              :           {
    1927          143 :             tree pos = byte_position (field);
    1928          143 :             if (TREE_CODE (pos) != INTEGER_CST)
    1929            0 :               continue;
    1930          143 :             offset_int upos = wi::to_offset (pos);
    1931          143 :             offset_int el_sz
    1932          143 :               = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (field)));
    1933          286 :             if (upos <= off && off < upos + el_sz)
    1934              :               {
    1935              :                 /* The C++ pretty printers print scope of the FIELD_DECLs,
    1936              :                    so punt if it is something that can't be printed.  */
    1937           79 :                 if (c_dialect_cxx ())
    1938           49 :                   if (tree scope = get_containing_scope (field))
    1939           49 :                     if (TYPE_P (scope) && TYPE_NAME (scope) == NULL_TREE)
    1940              :                       break;
    1941           75 :                 tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE (field),
    1942              :                                        op, field, NULL_TREE);
    1943           75 :                 off = off - upos;
    1944           75 :                 if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
    1945              :                                                              off))
    1946           75 :                   return ret;
    1947           13 :                 return cop;
    1948              :               }
    1949              :           }
    1950              :     }
    1951              :   /* Similarly for unions, but in this case try to be very conservative,
    1952              :      only match if some field has type compatible with type and it is the
    1953              :      only such field.  */
    1954           58 :   else if (TREE_CODE (optype) == UNION_TYPE)
    1955              :     {
    1956            8 :       tree fld = NULL_TREE;
    1957            8 :       for (tree field = TYPE_FIELDS (optype);
    1958          152 :            field; field = DECL_CHAIN (field))
    1959          144 :         if (TREE_CODE (field) == FIELD_DECL
    1960           18 :             && TREE_TYPE (field) != error_mark_node
    1961          162 :             && lang_hooks.types_compatible_p (TREE_TYPE (field), type))
    1962              :           {
    1963            2 :             if (fld)
    1964              :               return NULL_TREE;
    1965              :             else
    1966              :               fld = field;
    1967              :           }
    1968            8 :       if (fld)
    1969              :         {
    1970            2 :           off = 0;
    1971            2 :           return build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), op, fld,
    1972            2 :                              NULL_TREE);
    1973              :         }
    1974              :     }
    1975              : 
    1976              :   return NULL_TREE;
    1977              : }
    1978              : 
    1979              : /* Print the MEM_REF expression REF, including its type and offset.
    1980              :    Apply casts as necessary if the type of the access is different
    1981              :    from the type of the accessed object.  Produce compact output
    1982              :    designed to include both the element index as well as any
    1983              :    misalignment by preferring
    1984              :      ((int*)((char*)p + 1))[2]
    1985              :    over
    1986              :      *(int*)((char*)p + 9)
    1987              :    The former is more verbose but makes it clearer that the access
    1988              :    to the third element of the array is misaligned by one byte.  */
    1989              : 
    1990              : static void
    1991          934 : print_mem_ref (c_pretty_printer *pp, tree e)
    1992              : {
    1993          934 :   tree arg = TREE_OPERAND (e, 0);
    1994              : 
    1995              :   /* The byte offset.  Initially equal to the MEM_REF offset, then
    1996              :      adjusted to the remainder of the division by the byte size of
    1997              :      the access.  */
    1998          934 :   offset_int byte_off = wi::to_offset (TREE_OPERAND (e, 1));
    1999              :   /* The result of dividing BYTE_OFF by the size of the access.  */
    2000          934 :   offset_int elt_idx = 0;
    2001              :   /* True to include a cast to char* (for a nonzero final BYTE_OFF).  */
    2002          934 :   bool char_cast = false;
    2003          934 :   tree op = NULL_TREE;
    2004          934 :   bool array_ref_only = false;
    2005          934 :   if (TREE_CODE (arg) == ADDR_EXPR)
    2006              :     {
    2007          348 :       op = c_fold_indirect_ref_for_warn (EXPR_LOCATION (e), TREE_TYPE (e),
    2008          348 :                                          TREE_OPERAND (arg, 0), byte_off);
    2009              :       /* Try to fold it back to component, array ref or their combination,
    2010              :          but print it only if the types and TBAA types are compatible.  */
    2011          348 :       if (op
    2012          323 :           && byte_off == 0
    2013          323 :           && lang_hooks.types_compatible_p (TREE_TYPE (e), TREE_TYPE (op))
    2014          636 :           && (!flag_strict_aliasing
    2015           28 :               || (get_deref_alias_set (TREE_OPERAND (e, 1))
    2016           14 :                   == get_alias_set (op))))
    2017              :         {
    2018          286 :           pp->expression (op);
    2019          286 :           return;
    2020              :         }
    2021           62 :       if (op == NULL_TREE)
    2022           25 :         op = TREE_OPERAND (arg, 0);
    2023              :       /* If the types or TBAA types are incompatible, undo the
    2024              :          UNION_TYPE handling from c_fold_indirect_ref_for_warn, and similarly
    2025              :          undo __real__/__imag__ the code below doesn't try to handle.  */
    2026           62 :       if (op != TREE_OPERAND (arg, 0)
    2027           62 :           && ((TREE_CODE (op) == COMPONENT_REF
    2028           15 :                && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == UNION_TYPE)
    2029           35 :               || TREE_CODE (op) == REALPART_EXPR
    2030           35 :               || TREE_CODE (op) == IMAGPART_EXPR))
    2031            2 :         op = TREE_OPERAND (op, 0);
    2032           62 :       if (op != TREE_OPERAND (arg, 0))
    2033              :         {
    2034           61 :           array_ref_only = true;
    2035           61 :           for (tree ref = op; ref != TREE_OPERAND (arg, 0);
    2036           24 :                ref = TREE_OPERAND (ref, 0))
    2037           41 :             if (TREE_CODE (ref) != ARRAY_REF)
    2038              :               {
    2039              :                 array_ref_only = false;
    2040              :                 break;
    2041              :               }
    2042              :         }
    2043              :     }
    2044              : 
    2045          648 :   tree access_type = TREE_TYPE (e);
    2046          648 :   tree arg_type = TREE_TYPE (TREE_TYPE (arg));
    2047          648 :   if (tree access_size = TYPE_SIZE_UNIT (access_type))
    2048         1223 :     if (byte_off != 0
    2049           68 :         && TREE_CODE (access_size) == INTEGER_CST
    2050          712 :         && !integer_zerop (access_size))
    2051              :       {
    2052           67 :         offset_int asize = wi::to_offset (access_size);
    2053           67 :         elt_idx = byte_off / asize;
    2054           67 :         byte_off = byte_off % asize;
    2055              :       }
    2056              : 
    2057              :   /* True to include a cast to the accessed type.  */
    2058          648 :   const bool access_cast
    2059           62 :     = ((op && op != TREE_OPERAND (arg, 0))
    2060          611 :        || VOID_TYPE_P (arg_type)
    2061         1219 :        || !lang_hooks.types_compatible_p (access_type, arg_type));
    2062          648 :   const bool has_off = byte_off != 0 || (op && op != TREE_OPERAND (arg, 0));
    2063              : 
    2064          648 :   if (has_off && (byte_off != 0 || !array_ref_only))
    2065              :     {
    2066              :       /* When printing the byte offset for a pointer to a type of
    2067              :          a different size than char, include a cast to char* first,
    2068              :          before printing the cast to a pointer to the accessed type.  */
    2069           48 :       tree size = TYPE_SIZE (arg_type);
    2070           48 :       if (size == NULL_TREE
    2071           48 :           || TREE_CODE (size) != INTEGER_CST
    2072           79 :           || wi::to_wide (size) != BITS_PER_UNIT)
    2073           42 :         char_cast = true;
    2074              :     }
    2075              : 
    2076          648 :   if (elt_idx == 0)
    2077          593 :     pp_c_star (pp);
    2078           55 :   else if (access_cast || char_cast)
    2079           33 :     pp_c_left_paren (pp);
    2080              : 
    2081          626 :   if (access_cast)
    2082              :     {
    2083              :       /* Include a cast to the accessed type if it isn't compatible
    2084              :          with the type of the referenced object (or if the object
    2085              :          is typeless).  */
    2086          135 :       pp_c_left_paren (pp);
    2087          135 :       pp->type_id (build_pointer_type (access_type));
    2088          135 :       pp_c_right_paren (pp);
    2089              :     }
    2090              : 
    2091          648 :   if (has_off)
    2092           68 :     pp_c_left_paren (pp);
    2093              : 
    2094          648 :   if (char_cast)
    2095              :     {
    2096              :       /* Include a cast to char *.  */
    2097           42 :       pp_c_left_paren (pp);
    2098           42 :       pp->type_id (string_type_node);
    2099           42 :       pp_c_right_paren (pp);
    2100              :     }
    2101              : 
    2102          648 :   pp->unary_expression (arg);
    2103              : 
    2104          648 :   if (op && op != TREE_OPERAND (arg, 0))
    2105              :     {
    2106           37 :       auto_vec<tree, 16> refs;
    2107           37 :       tree ref;
    2108           37 :       unsigned i;
    2109           37 :       bool array_refs = true;
    2110          126 :       for (ref = op; ref != TREE_OPERAND (arg, 0); ref = TREE_OPERAND (ref, 0))
    2111           89 :         refs.safe_push (ref);
    2112          163 :       FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
    2113           89 :         if (array_refs && TREE_CODE (ref) == ARRAY_REF)
    2114              :           {
    2115           26 :             pp_c_left_bracket (pp);
    2116           26 :             pp->expression (TREE_OPERAND (ref, 1));
    2117           26 :             pp_c_right_bracket (pp);
    2118              :           }
    2119              :         else
    2120              :           {
    2121           17 :             if (array_refs)
    2122              :               {
    2123           17 :                 array_refs = false;
    2124           17 :                 pp_string (pp, " + offsetof");
    2125           17 :                 pp_c_left_paren (pp);
    2126           17 :                 pp->type_id (TREE_TYPE (TREE_OPERAND (ref, 0)));
    2127           17 :                 pp_comma (pp);
    2128              :               }
    2129           46 :             else if (TREE_CODE (ref) == COMPONENT_REF)
    2130           44 :               pp_c_dot (pp);
    2131           63 :             if (TREE_CODE (ref) == COMPONENT_REF)
    2132           61 :               pp->expression (TREE_OPERAND (ref, 1));
    2133              :             else
    2134              :               {
    2135            2 :                 pp_c_left_bracket (pp);
    2136            2 :                 pp->expression (TREE_OPERAND (ref, 1));
    2137            2 :                 pp_c_right_bracket (pp);
    2138              :               }
    2139              :           }
    2140           37 :       if (!array_refs)
    2141           17 :         pp_c_right_paren (pp);
    2142           37 :     }
    2143              : 
    2144          648 :   if (byte_off != 0)
    2145              :     {
    2146           31 :       pp_space (pp);
    2147           31 :       pp_plus (pp);
    2148           31 :       pp_space (pp);
    2149           31 :       tree off = wide_int_to_tree (ssizetype, byte_off);
    2150           31 :       pp->constant (off);
    2151              :     }
    2152              : 
    2153          648 :   if (has_off)
    2154           68 :     pp_c_right_paren (pp);
    2155              : 
    2156          648 :   if (elt_idx != 0)
    2157              :     {
    2158           55 :       if (access_cast || char_cast)
    2159           33 :         pp_c_right_paren (pp);
    2160              : 
    2161           55 :       pp_c_left_bracket (pp);
    2162           55 :       tree idx = wide_int_to_tree (ssizetype, elt_idx);
    2163           55 :       pp->constant (idx);
    2164           55 :       pp_c_right_bracket (pp);
    2165              :     }
    2166              : }
    2167              : 
    2168              : /* unary-expression:
    2169              :       postfix-expression
    2170              :       ++ cast-expression
    2171              :       -- cast-expression
    2172              :       unary-operator cast-expression
    2173              :       sizeof unary-expression
    2174              :       sizeof ( type-id )
    2175              : 
    2176              :   unary-operator: one of
    2177              :       * &  + - ! ~
    2178              : 
    2179              :    GNU extensions.
    2180              :    unary-expression:
    2181              :       __alignof__ unary-expression
    2182              :       __alignof__ ( type-id )
    2183              :       __real__ unary-expression
    2184              :       __imag__ unary-expression  */
    2185              : 
    2186              : void
    2187         8690 : c_pretty_printer::unary_expression (tree e)
    2188              : {
    2189         8690 :   enum tree_code code = TREE_CODE (e);
    2190         8690 :   switch (code)
    2191              :     {
    2192            1 :     case PREINCREMENT_EXPR:
    2193            1 :     case PREDECREMENT_EXPR:
    2194            1 :       pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
    2195            1 :       unary_expression (TREE_OPERAND (e, 0));
    2196            1 :       break;
    2197              : 
    2198         1615 :     case ADDR_EXPR:
    2199         1615 :     case INDIRECT_REF:
    2200         1615 :     case NEGATE_EXPR:
    2201         1615 :     case BIT_NOT_EXPR:
    2202         1615 :     case TRUTH_NOT_EXPR:
    2203         1615 :     case CONJ_EXPR:
    2204              :       /* String literal are used by address.  */
    2205         1615 :       if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
    2206          291 :         pp_ampersand (this);
    2207         1324 :       else if (code == INDIRECT_REF)
    2208              :         {
    2209          353 :           tree type = TREE_TYPE (TREE_OPERAND (e, 0));
    2210          353 :           if (type && TREE_CODE (type) == REFERENCE_TYPE)
    2211              :             /* Reference decay is implicit, don't print anything.  */;
    2212              :           else
    2213          255 :             pp_c_star (this);
    2214              :         }
    2215          971 :       else if (code == NEGATE_EXPR)
    2216           26 :         pp_minus (this);
    2217          945 :       else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
    2218            6 :         pp_complement (this);
    2219          939 :       else if (code == TRUTH_NOT_EXPR)
    2220          939 :         pp_exclamation (this);
    2221         1615 :       pp_c_cast_expression (this, TREE_OPERAND (e, 0));
    2222         1615 :       break;
    2223              : 
    2224          934 :     case MEM_REF:
    2225          934 :       print_mem_ref (this, e);
    2226          934 :       break;
    2227              : 
    2228            0 :     case TARGET_MEM_REF:
    2229              :       /* TARGET_MEM_REF can't appear directly from source, but can appear
    2230              :          during late GIMPLE optimizations and through late diagnostic we might
    2231              :          need to support it.  Print it as dereferencing of a pointer after
    2232              :          cast to the TARGET_MEM_REF type, with pointer arithmetics on some
    2233              :          pointer to single byte types, so
    2234              :          *(type *)((char *) ptr + step * index + index2) if all the operands
    2235              :          are present and the casts are needed.  */
    2236            0 :       pp_c_star (this);
    2237            0 :       if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))) == NULL_TREE
    2238            0 :           || !integer_onep (TYPE_SIZE_UNIT
    2239              :                                 (TREE_TYPE (TREE_TYPE (TMR_BASE (e))))))
    2240              :         {
    2241            0 :           if (TYPE_SIZE_UNIT (TREE_TYPE (e))
    2242            0 :               && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (e))))
    2243              :             {
    2244            0 :               pp_c_left_paren (this);
    2245            0 :               pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
    2246              :             }
    2247              :           else
    2248              :             {
    2249            0 :               pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
    2250            0 :               pp_c_left_paren (this);
    2251            0 :               pp_c_type_cast (this, build_pointer_type (char_type_node));
    2252              :             }
    2253              :         }
    2254            0 :       else if (!lang_hooks.types_compatible_p
    2255            0 :                   (TREE_TYPE (e), TREE_TYPE (TREE_TYPE (TMR_BASE (e)))))
    2256              :         {
    2257            0 :           pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
    2258            0 :           pp_c_left_paren (this);
    2259              :         }
    2260              :       else
    2261            0 :         pp_c_left_paren (this);
    2262            0 :       pp_c_cast_expression (this, TMR_BASE (e));
    2263            0 :       if (TMR_STEP (e) && TMR_INDEX (e))
    2264              :         {
    2265            0 :           pp_plus (this);
    2266            0 :           pp_c_cast_expression (this, TMR_INDEX (e));
    2267            0 :           pp_c_star (this);
    2268            0 :           pp_c_cast_expression (this, TMR_STEP (e));
    2269              :         }
    2270            0 :       if (TMR_INDEX2 (e))
    2271              :         {
    2272            0 :           pp_plus (this);
    2273            0 :           pp_c_cast_expression (this, TMR_INDEX2 (e));
    2274              :         }
    2275            0 :       if (!integer_zerop (TMR_OFFSET (e)))
    2276              :         {
    2277            0 :           pp_plus (this);
    2278            0 :           pp_c_integer_constant (this,
    2279            0 :                                  fold_convert (ssizetype, TMR_OFFSET (e)));
    2280              :         }
    2281            0 :       pp_c_right_paren (this);
    2282            0 :       break;
    2283              : 
    2284           14 :     case REALPART_EXPR:
    2285           14 :     case IMAGPART_EXPR:
    2286           21 :       pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
    2287           14 :       pp_c_whitespace (this);
    2288           14 :       unary_expression (TREE_OPERAND (e, 0));
    2289           14 :       break;
    2290              : 
    2291         6126 :     default:
    2292         6126 :       postfix_expression (e);
    2293         6126 :       break;
    2294              :     }
    2295         8690 : }
    2296              : 
    2297              : /* cast-expression:
    2298              :       unary-expression
    2299              :       ( type-name ) cast-expression  */
    2300              : 
    2301              : void
    2302         5976 : pp_c_cast_expression (c_pretty_printer *pp, tree e)
    2303              : {
    2304         6517 :   switch (TREE_CODE (e))
    2305              :     {
    2306          541 :     case FLOAT_EXPR:
    2307          541 :     case FIX_TRUNC_EXPR:
    2308          541 :     CASE_CONVERT:
    2309          541 :     case VIEW_CONVERT_EXPR:
    2310          541 :     case EXCESS_PRECISION_EXPR:
    2311          541 :       if (!location_wrapper_p (e))
    2312          270 :         pp_c_type_cast (pp, TREE_TYPE (e));
    2313          541 :       pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
    2314          541 :       break;
    2315              : 
    2316         5976 :     default:
    2317         5976 :       pp->unary_expression (e);
    2318              :     }
    2319         5976 : }
    2320              : 
    2321              : /* multiplicative-expression:
    2322              :       cast-expression
    2323              :       multiplicative-expression * cast-expression
    2324              :       multiplicative-expression / cast-expression
    2325              :       multiplicative-expression % cast-expression   */
    2326              : 
    2327              : void
    2328         2183 : c_pretty_printer::multiplicative_expression (tree e)
    2329              : {
    2330         2183 :   enum tree_code code = TREE_CODE (e);
    2331         2183 :   switch (code)
    2332              :     {
    2333          133 :     case MULT_EXPR:
    2334          133 :     case TRUNC_DIV_EXPR:
    2335          133 :     case TRUNC_MOD_EXPR:
    2336          133 :     case EXACT_DIV_EXPR:
    2337          133 :     case RDIV_EXPR:
    2338          133 :       multiplicative_expression (TREE_OPERAND (e, 0));
    2339          133 :       pp_c_whitespace (this);
    2340          133 :       if (code == MULT_EXPR)
    2341          128 :         pp_c_star (this);
    2342            5 :       else if (code != TRUNC_MOD_EXPR)
    2343            4 :         pp_slash (this);
    2344              :       else
    2345            1 :         pp_modulo (this);
    2346          133 :       pp_c_whitespace (this);
    2347          133 :       pp_c_cast_expression (this, TREE_OPERAND (e, 1));
    2348          133 :       break;
    2349              : 
    2350         2050 :     default:
    2351         2050 :       pp_c_cast_expression (this, e);
    2352         2050 :       break;
    2353              :     }
    2354         2183 : }
    2355              : 
    2356              : /* additive-expression:
    2357              :       multiplicative-expression
    2358              :       additive-expression + multiplicative-expression
    2359              :       additive-expression - multiplicative-expression   */
    2360              : 
    2361              : static void
    2362         3843 : pp_c_additive_expression (c_pretty_printer *pp, tree e)
    2363              : {
    2364         3843 :   enum tree_code code = TREE_CODE (e);
    2365         3843 :   switch (code)
    2366              :     {
    2367          855 :     case POINTER_PLUS_EXPR:
    2368          855 :     case PLUS_EXPR:
    2369          855 :     case POINTER_DIFF_EXPR:
    2370          855 :     case MINUS_EXPR:
    2371          855 :       pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
    2372          855 :       pp_c_whitespace (pp);
    2373          855 :       if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
    2374          844 :         pp_plus (pp);
    2375              :       else
    2376           11 :         pp_minus (pp);
    2377          855 :       pp_c_whitespace (pp);
    2378          855 :       {
    2379          855 :         tree op1 = TREE_OPERAND (e, 1);
    2380          855 :         if (code == POINTER_PLUS_EXPR
    2381           65 :             && TREE_CODE (op1) == INTEGER_CST
    2382          876 :             && tree_int_cst_sign_bit (op1))
    2383              :           /* A pointer minus an integer is represented internally as plus a very
    2384              :              large number, don't expose that to users.  */
    2385            7 :           op1 = convert (ssizetype, op1);
    2386          855 :         pp->multiplicative_expression (op1);
    2387              :       }
    2388          855 :       break;
    2389              : 
    2390         2988 :     default:
    2391         2988 :       pp->multiplicative_expression (e);
    2392         2988 :       break;
    2393              :     }
    2394         3843 : }
    2395              : 
    2396              : /* additive-expression:
    2397              :       additive-expression
    2398              :       shift-expression << additive-expression
    2399              :       shift-expression >> additive-expression   */
    2400              : 
    2401              : static void
    2402         2134 : pp_c_shift_expression (c_pretty_printer *pp, tree e)
    2403              : {
    2404         2134 :   enum tree_code code = TREE_CODE (e);
    2405         2134 :   switch (code)
    2406              :     {
    2407          105 :     case LSHIFT_EXPR:
    2408          105 :     case RSHIFT_EXPR:
    2409          105 :     case LROTATE_EXPR:
    2410          105 :     case RROTATE_EXPR:
    2411          105 :       pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
    2412          105 :       pp_c_whitespace (pp);
    2413          209 :       pp_string (pp, code == LSHIFT_EXPR ? "<<" :
    2414              :                      code == RSHIFT_EXPR ? ">>" :
    2415              :                      code == LROTATE_EXPR ? "<<<" : ">>>");
    2416          105 :       pp_c_whitespace (pp);
    2417          105 :       pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
    2418          105 :       break;
    2419              : 
    2420         2029 :     default:
    2421         2029 :       pp_c_additive_expression (pp, e);
    2422              :     }
    2423         2134 : }
    2424              : 
    2425              : /* relational-expression:
    2426              :       shift-expression
    2427              :       relational-expression < shift-expression
    2428              :       relational-expression > shift-expression
    2429              :       relational-expression <= shift-expression
    2430              :       relational-expression >= shift-expression   */
    2431              : 
    2432              : static void
    2433         1924 : pp_c_relational_expression (c_pretty_printer *pp, tree e)
    2434              : {
    2435         1924 :   enum tree_code code = TREE_CODE (e);
    2436         1924 :   switch (code)
    2437              :     {
    2438           40 :     case LT_EXPR:
    2439           40 :     case GT_EXPR:
    2440           40 :     case LE_EXPR:
    2441           40 :     case GE_EXPR:
    2442           40 :       pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
    2443           40 :       pp_c_whitespace (pp);
    2444           40 :       if (code == LT_EXPR)
    2445            7 :         pp_less (pp);
    2446           33 :       else if (code == GT_EXPR)
    2447           27 :         pp_greater (pp);
    2448            6 :       else if (code == LE_EXPR)
    2449            0 :         pp_less_equal (pp);
    2450            6 :       else if (code == GE_EXPR)
    2451            6 :         pp_greater_equal (pp);
    2452           40 :       pp_c_whitespace (pp);
    2453           40 :       pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
    2454           40 :       break;
    2455              : 
    2456         1884 :     default:
    2457         1884 :       pp_c_shift_expression (pp, e);
    2458         1884 :       break;
    2459              :     }
    2460         1924 : }
    2461              : 
    2462              : /* equality-expression:
    2463              :       relational-expression
    2464              :       equality-expression == relational-expression
    2465              :       equality-equality != relational-expression  */
    2466              : 
    2467              : static void
    2468         1844 : pp_c_equality_expression (c_pretty_printer *pp, tree e)
    2469              : {
    2470         1844 :   enum tree_code code = TREE_CODE (e);
    2471         1844 :   switch (code)
    2472              :     {
    2473          350 :     case EQ_EXPR:
    2474          350 :     case NE_EXPR:
    2475          350 :       pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
    2476          350 :       pp_c_whitespace (pp);
    2477          413 :       pp_string (pp, code == EQ_EXPR ? "==" : "!=");
    2478          350 :       pp_c_whitespace (pp);
    2479          350 :       pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
    2480          350 :       break;
    2481              : 
    2482         1494 :     default:
    2483         1494 :       pp_c_relational_expression (pp, e);
    2484         1494 :       break;
    2485              :     }
    2486         1844 : }
    2487              : 
    2488              : /* AND-expression:
    2489              :       equality-expression
    2490              :       AND-expression & equality-equality   */
    2491              : 
    2492              : static void
    2493         1198 : pp_c_and_expression (c_pretty_printer *pp, tree e)
    2494              : {
    2495         1198 :   if (TREE_CODE (e) == BIT_AND_EXPR)
    2496              :     {
    2497            4 :       pp_c_and_expression (pp, TREE_OPERAND (e, 0));
    2498            4 :       pp_c_whitespace (pp);
    2499            4 :       pp_ampersand (pp);
    2500            4 :       pp_c_whitespace (pp);
    2501            4 :       pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
    2502              :     }
    2503              :   else
    2504         1194 :     pp_c_equality_expression (pp, e);
    2505         1198 : }
    2506              : 
    2507              : /* exclusive-OR-expression:
    2508              :      AND-expression
    2509              :      exclusive-OR-expression ^ AND-expression  */
    2510              : 
    2511              : static void
    2512         1190 : pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
    2513              : {
    2514         1190 :   if (TREE_CODE (e) == BIT_XOR_EXPR
    2515         1190 :       || TREE_CODE (e) == TRUTH_XOR_EXPR)
    2516              :     {
    2517            1 :       pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
    2518            1 :       if (TREE_CODE (e) == BIT_XOR_EXPR)
    2519            0 :         pp_c_maybe_whitespace (pp);
    2520              :       else
    2521            1 :         pp_c_whitespace (pp);
    2522            1 :       pp_carret (pp);
    2523            1 :       pp_c_whitespace (pp);
    2524            1 :       pp_c_and_expression (pp, TREE_OPERAND (e, 1));
    2525              :     }
    2526              :   else
    2527         1189 :     pp_c_and_expression (pp, e);
    2528         1190 : }
    2529              : 
    2530              : /* inclusive-OR-expression:
    2531              :      exclusive-OR-expression
    2532              :      inclusive-OR-expression | exclusive-OR-expression  */
    2533              : 
    2534              : static void
    2535         1176 : pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
    2536              : {
    2537         1176 :   if (TREE_CODE (e) == BIT_IOR_EXPR)
    2538              :     {
    2539           12 :       pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
    2540           12 :       pp_c_whitespace (pp);
    2541           12 :       pp_bar (pp);
    2542           12 :       pp_c_whitespace (pp);
    2543           12 :       pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
    2544              :     }
    2545              :   else
    2546         1164 :     pp_c_exclusive_or_expression (pp, e);
    2547         1176 : }
    2548              : 
    2549              : /* logical-AND-expression:
    2550              :       inclusive-OR-expression
    2551              :       logical-AND-expression && inclusive-OR-expression  */
    2552              : 
    2553              : static void
    2554         1164 : pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
    2555              : {
    2556         1164 :   if (TREE_CODE (e) == TRUTH_ANDIF_EXPR
    2557          651 :       || TREE_CODE (e) == TRUTH_AND_EXPR)
    2558              :     {
    2559          514 :       pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
    2560          514 :       pp_c_whitespace (pp);
    2561          514 :       pp_ampersand_ampersand (pp);
    2562          514 :       pp_c_whitespace (pp);
    2563          514 :       pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
    2564              :     }
    2565              :   else
    2566          650 :     pp_c_inclusive_or_expression (pp, e);
    2567         1164 : }
    2568              : 
    2569              : /* logical-OR-expression:
    2570              :       logical-AND-expression
    2571              :       logical-OR-expression || logical-AND-expression  */
    2572              : 
    2573              : void
    2574          243 : pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
    2575              : {
    2576          243 :   if (TREE_CODE (e) == TRUTH_ORIF_EXPR
    2577          145 :       || TREE_CODE (e) == TRUTH_OR_EXPR)
    2578              :     {
    2579           99 :       pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
    2580           99 :       pp_c_whitespace (pp);
    2581           99 :       pp_bar_bar (pp);
    2582           99 :       pp_c_whitespace (pp);
    2583           99 :       pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
    2584              :     }
    2585              :   else
    2586          144 :     pp_c_logical_and_expression (pp, e);
    2587          243 : }
    2588              : 
    2589              : /* conditional-expression:
    2590              :       logical-OR-expression
    2591              :       logical-OR-expression ? expression : conditional-expression  */
    2592              : 
    2593              : void
    2594           42 : c_pretty_printer::conditional_expression (tree e)
    2595              : {
    2596           42 :   if (TREE_CODE (e) == COND_EXPR)
    2597              :     {
    2598           21 :       pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
    2599           21 :       pp_c_whitespace (this);
    2600           21 :       pp_question (this);
    2601           21 :       pp_c_whitespace (this);
    2602           21 :       expression (TREE_OPERAND (e, 1));
    2603           21 :       pp_c_whitespace (this);
    2604           21 :       pp_colon (this);
    2605           21 :       pp_c_whitespace (this);
    2606           21 :       conditional_expression (TREE_OPERAND (e, 2));
    2607              :     }
    2608              :   else
    2609           21 :     pp_c_logical_or_expression (this, e);
    2610           42 : }
    2611              : 
    2612              : 
    2613              : /* assignment-expression:
    2614              :       conditional-expression
    2615              :       unary-expression assignment-operator  assignment-expression
    2616              : 
    2617              :    assignment-expression: one of
    2618              :       =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
    2619              : 
    2620              : void
    2621            0 : c_pretty_printer::assignment_expression (tree e)
    2622              : {
    2623            0 :   if (TREE_CODE (e) == MODIFY_EXPR
    2624            0 :       || TREE_CODE (e) == INIT_EXPR)
    2625              :     {
    2626            0 :       unary_expression (TREE_OPERAND (e, 0));
    2627            0 :       pp_c_whitespace (this);
    2628            0 :       pp_equal (this);
    2629            0 :       pp_space (this);
    2630            0 :       expression (TREE_OPERAND (e, 1));
    2631              :     }
    2632              :   else
    2633            0 :     conditional_expression (e);
    2634            0 : }
    2635              : 
    2636              : /* expression:
    2637              :        assignment-expression
    2638              :        expression , assignment-expression
    2639              : 
    2640              :   Implementation note:  instead of going through the usual recursion
    2641              :   chain, I take the liberty of dispatching nodes to the appropriate
    2642              :   functions.  This makes some redundancy, but it worths it. That also
    2643              :   prevents a possible infinite recursion between primary_expression ()
    2644              :   and expression ().  */
    2645              : 
    2646              : void
    2647        44135 : c_pretty_printer::expression (tree e)
    2648              : {
    2649        44135 :   switch (TREE_CODE (e))
    2650              :     {
    2651            0 :     case VOID_CST:
    2652            0 :       pp_c_void_constant (this);
    2653            0 :       break;
    2654              : 
    2655         7603 :     case INTEGER_CST:
    2656         7603 :       pp_c_integer_constant (this, e);
    2657         7603 :       break;
    2658              : 
    2659          171 :     case REAL_CST:
    2660          171 :       pp_c_floating_constant (this, e);
    2661          171 :       break;
    2662              : 
    2663            0 :     case FIXED_CST:
    2664            0 :       pp_c_fixed_constant (this, e);
    2665            0 :       break;
    2666              : 
    2667          280 :     case STRING_CST:
    2668          280 :       pp_c_string_literal (this, e);
    2669          280 :       break;
    2670              : 
    2671        26224 :     case IDENTIFIER_NODE:
    2672        26224 :     case FUNCTION_DECL:
    2673        26224 :     case VAR_DECL:
    2674        26224 :     case CONST_DECL:
    2675        26224 :     case PARM_DECL:
    2676        26224 :     case RESULT_DECL:
    2677        26224 :     case FIELD_DECL:
    2678        26224 :     case LABEL_DECL:
    2679        26224 :     case ERROR_MARK:
    2680        26224 :       primary_expression (e);
    2681        26224 :       break;
    2682              : 
    2683         4104 :     case SSA_NAME:
    2684         4104 :       if (SSA_NAME_VAR (e)
    2685         4026 :           && !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
    2686         4014 :         expression (SSA_NAME_VAR (e));
    2687              :       else
    2688           90 :         translate_string ("<unknown>");
    2689              :       break;
    2690              : 
    2691         1318 :     case POSTINCREMENT_EXPR:
    2692         1318 :     case POSTDECREMENT_EXPR:
    2693         1318 :     case ARRAY_REF:
    2694         1318 :     case OMP_ARRAY_SECTION:
    2695         1318 :     case CALL_EXPR:
    2696         1318 :     case COMPONENT_REF:
    2697         1318 :     case BIT_FIELD_REF:
    2698         1318 :     case COMPLEX_CST:
    2699         1318 :     case COMPLEX_EXPR:
    2700         1318 :     case VECTOR_CST:
    2701         1318 :     case ORDERED_EXPR:
    2702         1318 :     case UNORDERED_EXPR:
    2703         1318 :     case LTGT_EXPR:
    2704         1318 :     case UNEQ_EXPR:
    2705         1318 :     case UNLE_EXPR:
    2706         1318 :     case UNLT_EXPR:
    2707         1318 :     case UNGE_EXPR:
    2708         1318 :     case UNGT_EXPR:
    2709         1318 :     case MAX_EXPR:
    2710         1318 :     case MIN_EXPR:
    2711         1318 :     case ABS_EXPR:
    2712         1318 :     case CONSTRUCTOR:
    2713         1318 :     case COMPOUND_LITERAL_EXPR:
    2714         1318 :     case VA_ARG_EXPR:
    2715         1318 :       postfix_expression (e);
    2716         1318 :       break;
    2717              : 
    2718         1637 :     case CONJ_EXPR:
    2719         1637 :     case ADDR_EXPR:
    2720         1637 :     case INDIRECT_REF:
    2721         1637 :     case MEM_REF:
    2722         1637 :     case TARGET_MEM_REF:
    2723         1637 :     case NEGATE_EXPR:
    2724         1637 :     case BIT_NOT_EXPR:
    2725         1637 :     case TRUTH_NOT_EXPR:
    2726         1637 :     case PREINCREMENT_EXPR:
    2727         1637 :     case PREDECREMENT_EXPR:
    2728         1637 :     case REALPART_EXPR:
    2729         1637 :     case IMAGPART_EXPR:
    2730         1637 :       unary_expression (e);
    2731         1637 :       break;
    2732              : 
    2733          253 :     case FLOAT_EXPR:
    2734          253 :     case FIX_TRUNC_EXPR:
    2735          253 :     CASE_CONVERT:
    2736          253 :     case VIEW_CONVERT_EXPR:
    2737          253 :     case EXCESS_PRECISION_EXPR:
    2738          253 :       pp_c_cast_expression (this, e);
    2739          253 :       break;
    2740              : 
    2741           90 :     case MULT_EXPR:
    2742           90 :     case TRUNC_MOD_EXPR:
    2743           90 :     case TRUNC_DIV_EXPR:
    2744           90 :     case EXACT_DIV_EXPR:
    2745           90 :     case RDIV_EXPR:
    2746           90 :       multiplicative_expression (e);
    2747           90 :       break;
    2748              : 
    2749          105 :     case LSHIFT_EXPR:
    2750          105 :     case RSHIFT_EXPR:
    2751          105 :     case LROTATE_EXPR:
    2752          105 :     case RROTATE_EXPR:
    2753          105 :       pp_c_shift_expression (this, e);
    2754          105 :       break;
    2755              : 
    2756           40 :     case LT_EXPR:
    2757           40 :     case GT_EXPR:
    2758           40 :     case LE_EXPR:
    2759           40 :     case GE_EXPR:
    2760           40 :       pp_c_relational_expression (this, e);
    2761           40 :       break;
    2762              : 
    2763            4 :     case BIT_AND_EXPR:
    2764            4 :       pp_c_and_expression (this, e);
    2765            4 :       break;
    2766              : 
    2767            1 :     case BIT_XOR_EXPR:
    2768            1 :     case TRUTH_XOR_EXPR:
    2769            1 :       pp_c_exclusive_or_expression (this, e);
    2770            1 :       break;
    2771              : 
    2772           12 :     case BIT_IOR_EXPR:
    2773           12 :       pp_c_inclusive_or_expression (this, e);
    2774           12 :       break;
    2775              : 
    2776          407 :     case TRUTH_ANDIF_EXPR:
    2777          407 :     case TRUTH_AND_EXPR:
    2778          407 :       pp_c_logical_and_expression (this, e);
    2779          407 :       break;
    2780              : 
    2781           75 :     case TRUTH_ORIF_EXPR:
    2782           75 :     case TRUTH_OR_EXPR:
    2783           75 :       pp_c_logical_or_expression (this, e);
    2784           75 :       break;
    2785              : 
    2786          296 :     case EQ_EXPR:
    2787          296 :     case NE_EXPR:
    2788          296 :       pp_c_equality_expression (this, e);
    2789          296 :       break;
    2790              : 
    2791           21 :     case COND_EXPR:
    2792           21 :       conditional_expression (e);
    2793           21 :       break;
    2794              : 
    2795          854 :     case POINTER_PLUS_EXPR:
    2796          854 :     case PLUS_EXPR:
    2797          854 :     case POINTER_DIFF_EXPR:
    2798          854 :     case MINUS_EXPR:
    2799          854 :       pp_c_additive_expression (this, e);
    2800          854 :       break;
    2801              : 
    2802            0 :     case MODIFY_EXPR:
    2803            0 :     case INIT_EXPR:
    2804            0 :       assignment_expression (e);
    2805            0 :       break;
    2806              : 
    2807            0 :     case COMPOUND_EXPR:
    2808            0 :       pp_c_left_paren (this);
    2809            0 :       expression (TREE_OPERAND (e, 0));
    2810            0 :       pp_separate_with (this, ',');
    2811            0 :       assignment_expression (TREE_OPERAND (e, 1));
    2812            0 :       pp_c_right_paren (this);
    2813            0 :       break;
    2814              : 
    2815          630 :     case NON_LVALUE_EXPR:
    2816          630 :     case SAVE_EXPR:
    2817          630 :       expression (TREE_OPERAND (e, 0));
    2818          630 :       break;
    2819              : 
    2820            2 :     case TARGET_EXPR:
    2821            2 :       postfix_expression (TARGET_EXPR_INITIAL (e));
    2822            2 :       break;
    2823              : 
    2824            2 :     case BIND_EXPR:
    2825            2 :     case GOTO_EXPR:
    2826              :       /* We don't yet have a way of dumping statements in a
    2827              :          human-readable format.  */
    2828            2 :       pp_string (this, "({...})");
    2829            2 :       break;
    2830              : 
    2831            6 :     case C_MAYBE_CONST_EXPR:
    2832            6 :       expression (C_MAYBE_CONST_EXPR_EXPR (e));
    2833            6 :       break;
    2834              : 
    2835            0 :     default:
    2836            0 :       pp_unsupported_tree (this, e);
    2837            0 :       break;
    2838              :     }
    2839        44135 : }
    2840              : 
    2841              : 
    2842              : 
    2843              : /* Statements.  */
    2844              : 
    2845              : void
    2846         7418 : c_pretty_printer::statement (tree t)
    2847              : {
    2848         7418 :   if (t == NULL)
    2849              :     return;
    2850              : 
    2851         7418 :   switch (TREE_CODE (t))
    2852              :     {
    2853              : 
    2854            0 :     case SWITCH_STMT:
    2855            0 :       if (dump_flags != TDF_NONE)
    2856            0 :         internal_error ("dump flags not handled here");
    2857              : 
    2858            0 :       pp_c_ws_string (this, "switch");
    2859            0 :       pp_space (this);
    2860            0 :       pp_c_left_paren (this);
    2861            0 :       expression (SWITCH_STMT_COND (t));
    2862            0 :       pp_c_right_paren (this);
    2863            0 :       pp_indentation (this) += 3;
    2864            0 :       pp_needs_newline (this) = true;
    2865            0 :       statement (SWITCH_STMT_BODY (t));
    2866            0 :       pp_newline_and_indent (this, -3);
    2867            0 :       break;
    2868              : 
    2869              :       /* iteration-statement:
    2870              :             while ( expression ) statement
    2871              :             do statement while ( expression ) ;
    2872              :             for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
    2873              :             for ( declaration expression(opt) ; expression(opt) ) statement  */
    2874            0 :     case WHILE_STMT:
    2875            0 :       if (dump_flags != TDF_NONE)
    2876            0 :         internal_error ("dump flags not handled here");
    2877              : 
    2878            0 :       pp_c_ws_string (this, "while");
    2879            0 :       pp_space (this);
    2880            0 :       pp_c_left_paren (this);
    2881            0 :       expression (WHILE_COND (t));
    2882            0 :       pp_c_right_paren (this);
    2883            0 :       pp_newline_and_indent (this, 3);
    2884            0 :       statement (WHILE_BODY (t));
    2885            0 :       pp_indentation (this) -= 3;
    2886            0 :       pp_needs_newline (this) = true;
    2887            0 :       break;
    2888              : 
    2889            0 :     case DO_STMT:
    2890            0 :       if (dump_flags != TDF_NONE)
    2891            0 :         internal_error ("dump flags not handled here");
    2892              : 
    2893            0 :       pp_c_ws_string (this, "do");
    2894            0 :       pp_newline_and_indent (this, 3);
    2895            0 :       statement (DO_BODY (t));
    2896            0 :       pp_newline_and_indent (this, -3);
    2897            0 :       pp_c_ws_string (this, "while");
    2898            0 :       pp_space (this);
    2899            0 :       pp_c_left_paren (this);
    2900            0 :       expression (DO_COND (t));
    2901            0 :       pp_c_right_paren (this);
    2902            0 :       pp_c_semicolon (this);
    2903            0 :       pp_needs_newline (this) = true;
    2904            0 :       break;
    2905              : 
    2906            0 :     case FOR_STMT:
    2907            0 :       if (dump_flags != TDF_NONE)
    2908            0 :         internal_error ("dump flags not handled here");
    2909              : 
    2910            0 :       pp_c_ws_string (this, "for");
    2911            0 :       pp_space (this);
    2912            0 :       pp_c_left_paren (this);
    2913            0 :       if (FOR_INIT_STMT (t))
    2914            0 :         statement (FOR_INIT_STMT (t));
    2915              :       else
    2916            0 :         pp_c_semicolon (this);
    2917            0 :       pp_needs_newline (this) = false;
    2918            0 :       pp_c_whitespace (this);
    2919            0 :       if (FOR_COND (t))
    2920            0 :         expression (FOR_COND (t));
    2921            0 :       pp_c_semicolon (this);
    2922            0 :       pp_needs_newline (this) = false;
    2923            0 :       pp_c_whitespace (this);
    2924            0 :       if (FOR_EXPR (t))
    2925            0 :         expression (FOR_EXPR (t));
    2926            0 :       pp_c_right_paren (this);
    2927            0 :       pp_newline_and_indent (this, 3);
    2928            0 :       statement (FOR_BODY (t));
    2929            0 :       pp_indentation (this) -= 3;
    2930            0 :       pp_needs_newline (this) = true;
    2931            0 :       break;
    2932              : 
    2933              :       /* jump-statement:
    2934              :             goto identifier;
    2935              :             continue ;
    2936              :             return expression(opt) ;  */
    2937            0 :     case BREAK_STMT:
    2938            0 :       if (dump_flags != TDF_NONE)
    2939            0 :         internal_error ("dump flags not handled here");
    2940              : 
    2941            0 :       pp_string (this, "break");
    2942            0 :       if (BREAK_NAME (t))
    2943              :         {
    2944            0 :           pp_space (this);
    2945            0 :           pp_c_tree_decl_identifier (this, BREAK_NAME (t));
    2946              :         }
    2947            0 :       pp_c_semicolon (this);
    2948            0 :       pp_needs_newline (this) = true;
    2949            0 :       break;
    2950              : 
    2951            0 :     case CONTINUE_STMT:
    2952            0 :       if (dump_flags != TDF_NONE)
    2953            0 :         internal_error ("dump flags not handled here");
    2954              : 
    2955            0 :       pp_string (this, "continue");
    2956            0 :       if (CONTINUE_NAME (t))
    2957              :         {
    2958            0 :           pp_space (this);
    2959            0 :           pp_c_tree_decl_identifier (this, CONTINUE_NAME (t));
    2960              :         }
    2961            0 :       pp_c_semicolon (this);
    2962            0 :       pp_needs_newline (this) = true;
    2963            0 :       break;
    2964              : 
    2965         7418 :     default:
    2966         7418 :       if (pp_needs_newline (this))
    2967         7418 :         pp_newline_and_indent (this, 0);
    2968         7418 :       dump_generic_node (this, t, pp_indentation (this), dump_flags, true);
    2969              :     }
    2970              : }
    2971              : 
    2972              : 
    2973              : /* Initialize the PRETTY-PRINTER for handling C codes.  */
    2974              : 
    2975       319868 : c_pretty_printer::c_pretty_printer (dump_flags_t dump_flags)
    2976              :   : pretty_printer (),
    2977       319868 :     dump_flags (dump_flags),
    2978       319868 :     offset_list (),
    2979       319868 :     flags ()
    2980              : {
    2981       319868 :   type_specifier_seq        = pp_c_specifier_qualifier_list;
    2982       319868 :   ptr_operator              = pp_c_pointer;
    2983       319868 :   parameter_list            = pp_c_parameter_type_list;
    2984       319868 : }
    2985              : 
    2986              : /* c_pretty_printer's implementation of pretty_printer::clone vfunc.  */
    2987              : 
    2988              : std::unique_ptr<pretty_printer>
    2989       253294 : c_pretty_printer::clone () const
    2990              : {
    2991       253294 :   return std::make_unique<c_pretty_printer> (*this);
    2992              : }
    2993              : 
    2994              : /* Print the tree T in full, on file FILE.  */
    2995              : 
    2996              : void
    2997         7418 : print_c_tree (FILE *file, tree t, dump_flags_t dump_flags)
    2998              : {
    2999         7418 :   c_pretty_printer pp (dump_flags);
    3000              : 
    3001         7418 :   pp_needs_newline (&pp) = true;
    3002         7418 :   pp.set_output_stream (file);
    3003         7418 :   pp.statement (t);
    3004         7418 :   pp_newline_and_flush (&pp);
    3005         7418 : }
    3006              : 
    3007              : /* Print the tree T in full, on stderr.  */
    3008              : 
    3009              : DEBUG_FUNCTION void
    3010            0 : debug_c_tree (tree t)
    3011              : {
    3012            0 :   print_c_tree (stderr, t, TDF_NONE);
    3013            0 :   fputc ('\n', stderr);
    3014            0 : }
    3015              : 
    3016              : /* Output the DECL_NAME of T.  If T has no DECL_NAME, output a string made
    3017              :    up of T's memory address.  */
    3018              : 
    3019              : void
    3020        57424 : pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
    3021              : {
    3022        57424 :   const char *name;
    3023              : 
    3024        57424 :   gcc_assert (DECL_P (t));
    3025              : 
    3026        57424 :   if (DECL_NAME (t))
    3027              :     {
    3028        57320 :       const char *dot;
    3029        57320 :       name = IDENTIFIER_POINTER (DECL_NAME (t));
    3030        57320 :       if (DECL_ARTIFICIAL (t) && (dot = strchr (name, '.')))
    3031              :         {
    3032              :           /* Print the name without the . suffix (such as in VLAs and
    3033              :              callee-copied parameters).  */
    3034           63 :           size_t size = dot - name;
    3035           63 :           char *ident = XALLOCAVEC (char, size + 1);
    3036           63 :           memcpy (ident, name, size);
    3037           63 :           ident[size] = '\0';
    3038           63 :           name = ident;
    3039              :         }
    3040              :     }
    3041              :   else
    3042              :     {
    3043          104 :       static char xname[8];
    3044          104 :       sprintf (xname, "<U%4hx>", ((unsigned short) ((uintptr_t) (t)
    3045              :                                                     & 0xffff)));
    3046          104 :       name = xname;
    3047              :     }
    3048              : 
    3049        57424 :   pp_c_identifier (pp, name);
    3050        57424 : }
    3051              : 
    3052              : /* Prints "[version: VERSION]" for a versioned function decl.
    3053              :    This will only print for targets with target_version semantics.  */
    3054              : void
    3055       627420 : pp_c_function_target_version (c_pretty_printer *pp, tree t)
    3056              : {
    3057       627420 :   if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
    3058       627420 :     return;
    3059              : 
    3060              :   string_slice version = get_target_version (t);
    3061              :   if (!version.is_valid ())
    3062              :     return;
    3063              : 
    3064              :   pp_c_whitespace (pp);
    3065              : 
    3066              :   pp_c_left_bracket (pp);
    3067              :   pp_c_left_bracket (pp);
    3068              :   pp_string (pp, "target_version");
    3069              :   pp_c_left_paren (pp);
    3070              :   pp_doublequote (pp);
    3071              :   pp_string_n (pp, version.begin (), version.size ());
    3072              :   pp_doublequote (pp);
    3073              :   pp_c_right_paren (pp);
    3074              :   pp_c_right_bracket (pp);
    3075              :   pp_c_right_bracket (pp);
    3076              : 
    3077              :   pp->set_padding (pp_before);
    3078              : }
    3079              : 
    3080              : /* Prints "[clones: VERSION, +]" for a versioned function decl.
    3081              :    This only works for targets with target_version semantics.  */
    3082              : void
    3083       627420 : pp_c_function_target_clones (c_pretty_printer *pp, tree t)
    3084              : {
    3085              :   /* Only print for target_version semantics.
    3086              :      This is because for target FMV semantics a target_clone always defines
    3087              :      the entire FMV set.  target_version semantics can mix target_clone and
    3088              :      target_version decls in the definition of a FMV set and so the
    3089              :      target_clone becomes a part of the identity of the declaration.  */
    3090       627420 :   if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
    3091       627420 :     return;
    3092              : 
    3093              :   auto_vec<string_slice> versions = get_clone_versions (t, NULL, false);
    3094              :   if (versions.is_empty ())
    3095              :     return;
    3096              : 
    3097              :   pp_c_whitespace (pp);
    3098              : 
    3099              :   string_slice final_version = versions.pop ();
    3100              :   pp_c_left_bracket (pp);
    3101              :   pp_c_left_bracket (pp);
    3102              :   pp_string (pp, "target_clones");
    3103              :   pp_c_left_paren (pp);
    3104              :   for (string_slice version : versions)
    3105              :     {
    3106              :       pp_doublequote (pp);
    3107              :       pp_string_n (pp, version.begin (), version.size ());
    3108              :       pp_doublequote (pp);
    3109              :       pp_string (pp, ",");
    3110              :       pp_c_whitespace (pp);
    3111              :     }
    3112              :   pp_doublequote (pp);
    3113              :   pp_string_n (pp, final_version.begin (), final_version.size ());
    3114              :   pp_doublequote (pp);
    3115              :   pp_c_right_paren (pp);
    3116              :   pp_c_right_bracket (pp);
    3117              :   pp_c_right_bracket (pp);
    3118              : 
    3119              :   pp->set_padding (pp_before);
    3120              : }
    3121              : 
    3122              : #if CHECKING_P
    3123              : 
    3124              : namespace selftest {
    3125              : 
    3126              : /* Selftests for pretty-printing trees.  */
    3127              : 
    3128              : /* Verify that EXPR printed by c_pretty_printer is EXPECTED, using
    3129              :    LOC as the effective location for any failures.  */
    3130              : 
    3131              : static void
    3132           12 : assert_c_pretty_printer_output (const location &loc, const char *expected,
    3133              :                                 tree expr)
    3134              : {
    3135           12 :   c_pretty_printer pp;
    3136           12 :   pp.expression (expr);
    3137           12 :   ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
    3138           12 : }
    3139              : 
    3140              : /* Helper function for calling assert_c_pretty_printer_output.
    3141              :    This is to avoid having to write SELFTEST_LOCATION.  */
    3142              : 
    3143              : #define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \
    3144              :   SELFTEST_BEGIN_STMT                                           \
    3145              :     assert_c_pretty_printer_output ((SELFTEST_LOCATION),        \
    3146              :                                     (EXPECTED),         \
    3147              :                                     (EXPR));                    \
    3148              :   SELFTEST_END_STMT
    3149              : 
    3150              : /* Verify that location wrappers don't show up in pretty-printed output.  */
    3151              : 
    3152              : static void
    3153            3 : test_location_wrappers ()
    3154              : {
    3155              :   /* VAR_DECL.  */
    3156            3 :   tree id = get_identifier ("foo");
    3157            3 :   tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
    3158              :                           integer_type_node);
    3159            3 :   tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION);
    3160            3 :   ASSERT_NE (wrapped_decl, decl);
    3161            3 :   ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl);
    3162            3 :   ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl);
    3163              : 
    3164              :   /* INTEGER_CST.  */
    3165            3 :   tree int_cst = build_int_cst (integer_type_node, 42);
    3166            3 :   tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION);
    3167            3 :   ASSERT_NE (wrapped_cst, int_cst);
    3168            3 :   ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst);
    3169            3 :   ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst);
    3170            3 : }
    3171              : 
    3172              : /* Run all of the selftests within this file.  */
    3173              : 
    3174              : void
    3175            3 : c_pretty_print_cc_tests ()
    3176              : {
    3177            3 :   test_location_wrappers ();
    3178            3 : }
    3179              : 
    3180              : } // namespace selftest
    3181              : 
    3182              : #endif /* CHECKING_P */
        

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.