1117395Skan/* Subroutines common to both C and C++ pretty-printers.
2169689Skan   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3117395Skan   Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4117395Skan
5117395SkanThis file is part of GCC.
6117395Skan
7117395SkanGCC is free software; you can redistribute it and/or modify it under
8117395Skanthe terms of the GNU General Public License as published by the Free
9117395SkanSoftware Foundation; either version 2, or (at your option) any later
10117395Skanversion.
11117395Skan
12117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
14117395SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15117395Skanfor more details.
16117395Skan
17117395SkanYou should have received a copy of the GNU General Public License
18117395Skanalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
21117395Skan
22117395Skan#include "config.h"
23117395Skan#include "system.h"
24132718Skan#include "coretypes.h"
25132718Skan#include "tm.h"
26117395Skan#include "real.h"
27117395Skan#include "c-pretty-print.h"
28117395Skan#include "c-tree.h"
29169689Skan#include "tree-iterator.h"
30169689Skan#include "diagnostic.h"
31117395Skan
32132718Skan/* The pretty-printer code is primarily designed to closely follow
33132718Skan   (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
34132718Skan   codes we used to have in the past.  Following a structured
35132718Skan   approach (preferably the official grammars) is believed to make it
36132718Skan   much easier to add extensions and nifty pretty-printing effects that
37132718Skan   takes expression or declaration contexts into account.  */
38132718Skan
39132718Skan
40132718Skan#define pp_c_maybe_whitespace(PP)            \
41132718Skan   do {                                      \
42132718Skan     if (pp_base (PP)->padding == pp_before) \
43132718Skan       pp_c_whitespace (PP);                 \
44132718Skan   } while (0)
45132718Skan
46117395Skan/* literal  */
47132718Skanstatic void pp_c_char (c_pretty_printer *, int);
48117395Skan
49117395Skan/* postfix-expression  */
50132718Skanstatic void pp_c_initializer_list (c_pretty_printer *, tree);
51132718Skanstatic void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
52117395Skan
53132718Skanstatic void pp_c_multiplicative_expression (c_pretty_printer *, tree);
54132718Skanstatic void pp_c_additive_expression (c_pretty_printer *, tree);
55132718Skanstatic void pp_c_shift_expression (c_pretty_printer *, tree);
56132718Skanstatic void pp_c_relational_expression (c_pretty_printer *, tree);
57132718Skanstatic void pp_c_equality_expression (c_pretty_printer *, tree);
58132718Skanstatic void pp_c_and_expression (c_pretty_printer *, tree);
59132718Skanstatic void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
60132718Skanstatic void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
61132718Skanstatic void pp_c_logical_and_expression (c_pretty_printer *, tree);
62132718Skanstatic void pp_c_conditional_expression (c_pretty_printer *, tree);
63132718Skanstatic void pp_c_assignment_expression (c_pretty_printer *, tree);
64117395Skan
65117395Skan/* declarations.  */
66117395Skan
67117395Skan
68132718Skan/* Helper functions.  */
69132718Skan
70132718Skanvoid
71132718Skanpp_c_whitespace (c_pretty_printer *pp)
72132718Skan{
73132718Skan  pp_space (pp);
74132718Skan  pp_base (pp)->padding = pp_none;
75132718Skan}
76132718Skan
77132718Skanvoid
78132718Skanpp_c_left_paren (c_pretty_printer *pp)
79132718Skan{
80132718Skan  pp_left_paren (pp);
81132718Skan  pp_base (pp)->padding = pp_none;
82132718Skan}
83132718Skan
84132718Skanvoid
85132718Skanpp_c_right_paren (c_pretty_printer *pp)
86132718Skan{
87132718Skan  pp_right_paren (pp);
88132718Skan  pp_base (pp)->padding = pp_none;
89132718Skan}
90132718Skan
91132718Skanvoid
92132718Skanpp_c_left_brace (c_pretty_printer *pp)
93132718Skan{
94132718Skan  pp_left_brace (pp);
95132718Skan  pp_base (pp)->padding = pp_none;
96132718Skan}
97132718Skan
98132718Skanvoid
99132718Skanpp_c_right_brace (c_pretty_printer *pp)
100132718Skan{
101132718Skan  pp_right_brace (pp);
102132718Skan  pp_base (pp)->padding = pp_none;
103132718Skan}
104132718Skan
105132718Skanvoid
106169689Skanpp_c_left_bracket (c_pretty_printer *pp)
107169689Skan{
108169689Skan  pp_left_bracket (pp);
109169689Skan  pp_base (pp)->padding = pp_none;
110169689Skan}
111169689Skan
112169689Skanvoid
113169689Skanpp_c_right_bracket (c_pretty_printer *pp)
114169689Skan{
115169689Skan  pp_right_bracket (pp);
116169689Skan  pp_base (pp)->padding = pp_none;
117169689Skan}
118169689Skan
119169689Skanvoid
120132718Skanpp_c_dot (c_pretty_printer *pp)
121132718Skan{
122132718Skan  pp_dot (pp);
123132718Skan  pp_base (pp)->padding = pp_none;
124132718Skan}
125132718Skan
126132718Skanvoid
127132718Skanpp_c_ampersand (c_pretty_printer *pp)
128132718Skan{
129132718Skan  pp_ampersand (pp);
130132718Skan  pp_base (pp)->padding = pp_none;
131132718Skan}
132132718Skan
133132718Skanvoid
134169689Skanpp_c_star (c_pretty_printer *pp)
135169689Skan{
136169689Skan  pp_star (pp);
137169689Skan  pp_base (pp)->padding = pp_none;
138169689Skan}
139169689Skan
140261188Spfg/* APPLE LOCAL begin blocks */
141169689Skanvoid
142261188Spfgpp_c_caret (c_pretty_printer *pp)
143261188Spfg{
144261188Spfg  pp_carret (pp);
145261188Spfg  pp_base (pp)->padding = pp_none;
146261188Spfg}
147261188Spfg/* APPLE LOCAL end blocks */
148261188Spfg
149261188Spfgvoid
150132718Skanpp_c_arrow (c_pretty_printer *pp)
151132718Skan{
152132718Skan  pp_arrow (pp);
153132718Skan  pp_base (pp)->padding = pp_none;
154132718Skan}
155132718Skan
156132718Skanvoid
157169689Skanpp_c_semicolon (c_pretty_printer *pp)
158132718Skan{
159132718Skan  pp_semicolon (pp);
160132718Skan  pp_base (pp)->padding = pp_none;
161132718Skan}
162132718Skan
163169689Skanvoid
164169689Skanpp_c_complement (c_pretty_printer *pp)
165169689Skan{
166169689Skan  pp_complement (pp);
167169689Skan  pp_base (pp)->padding = pp_none;
168169689Skan}
169169689Skan
170169689Skanvoid
171169689Skanpp_c_exclamation (c_pretty_printer *pp)
172169689Skan{
173169689Skan  pp_exclamation (pp);
174169689Skan  pp_base (pp)->padding = pp_none;
175169689Skan}
176169689Skan
177169689Skan/* Print out the external representation of CV-QUALIFIER.  */
178169689Skan
179132718Skanstatic void
180132718Skanpp_c_cv_qualifier (c_pretty_printer *pp, const char *cv)
181132718Skan{
182132718Skan  const char *p = pp_last_position_in_text (pp);
183169689Skan  /* The C programming language does not have references, but it is much
184169689Skan     simpler to handle those here rather than going through the same
185169689Skan     logic in the C++ pretty-printer.  */
186169689Skan  if (p != NULL && (*p == '*' || *p == '&'))
187132718Skan    pp_c_whitespace (pp);
188132718Skan  pp_c_identifier (pp, cv);
189132718Skan}
190132718Skan
191132718Skan/* Pretty-print T using the type-cast notation '( type-name )'.  */
192132718Skan
193132718Skanstatic void
194132718Skanpp_c_type_cast (c_pretty_printer *pp, tree t)
195132718Skan{
196132718Skan  pp_c_left_paren (pp);
197132718Skan  pp_type_id (pp, t);
198132718Skan  pp_c_right_paren (pp);
199132718Skan}
200132718Skan
201169689Skan/* We're about to pretty-print a pointer type as indicated by T.
202169689Skan   Output a whitespace, if needed, preparing for subsequent output.  */
203169689Skan
204132718Skanvoid
205132718Skanpp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
206132718Skan{
207132718Skan  if (POINTER_TYPE_P (t))
208132718Skan    {
209132718Skan      tree pointee = strip_pointer_operator (TREE_TYPE (t));
210132718Skan      if (TREE_CODE (pointee) != ARRAY_TYPE
211169689Skan	  && TREE_CODE (pointee) != FUNCTION_TYPE)
212169689Skan	pp_c_whitespace (pp);
213132718Skan    }
214132718Skan}
215132718Skan
216132718Skan
217117395Skan/* Declarations.  */
218117395Skan
219132718Skan/* C++ cv-qualifiers are called type-qualifiers in C.  Print out the
220132718Skan   cv-qualifiers of T.  If T is a declaration then it is the cv-qualifier
221132718Skan   of its type.  Take care of possible extensions.
222132718Skan
223132718Skan   type-qualifier-list:
224132718Skan       type-qualifier
225132718Skan       type-qualifier-list type-qualifier
226132718Skan
227132718Skan   type-qualifier:
228132718Skan       const
229132718Skan       restrict                              -- C99
230132718Skan       __restrict__                          -- GNU C
231132718Skan       volatile    */
232132718Skan
233117395Skanvoid
234132718Skanpp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
235117395Skan{
236132718Skan   int qualifiers;
237169689Skan
238132718Skan  if (!TYPE_P (t))
239132718Skan    t = TREE_TYPE (t);
240132718Skan
241132718Skan  qualifiers = TYPE_QUALS (t);
242132718Skan  if (qualifiers & TYPE_QUAL_CONST)
243132718Skan    pp_c_cv_qualifier (pp, "const");
244132718Skan  if (qualifiers & TYPE_QUAL_VOLATILE)
245132718Skan    pp_c_cv_qualifier (pp, "volatile");
246132718Skan  if (qualifiers & TYPE_QUAL_RESTRICT)
247132718Skan    pp_c_cv_qualifier (pp, flag_isoc99 ? "restrict" : "__restrict__");
248117395Skan}
249117395Skan
250132718Skan/* pointer:
251132718Skan      * type-qualifier-list(opt)
252132718Skan      * type-qualifier-list(opt) pointer  */
253132718Skan
254117395Skanstatic void
255132718Skanpp_c_pointer (c_pretty_printer *pp, tree t)
256117395Skan{
257132718Skan  if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
258132718Skan    t = TREE_TYPE (t);
259132718Skan  switch (TREE_CODE (t))
260132718Skan    {
261132718Skan    case POINTER_TYPE:
262132718Skan      /* It is easier to handle C++ reference types here.  */
263132718Skan    case REFERENCE_TYPE:
264132718Skan      if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
265169689Skan	pp_c_pointer (pp, TREE_TYPE (t));
266132718Skan      if (TREE_CODE (t) == POINTER_TYPE)
267169689Skan	pp_c_star (pp);
268132718Skan      else
269169689Skan	pp_c_ampersand (pp);
270132718Skan      pp_c_type_qualifier_list (pp, t);
271132718Skan      break;
272261188Spfg    /* APPLE LOCAL begin blocks */
273261188Spfg    case BLOCK_POINTER_TYPE:
274261188Spfg      pp_c_caret (pp);
275261188Spfg      pp_c_type_qualifier_list (pp, t);
276261188Spfg      break;
277261188Spfg    /* APPLE LOCAL end blocks */
278132718Skan
279169689Skan      /* ??? This node is now in GENERIC and so shouldn't be here.  But
280169689Skan	 we'll fix that later.  */
281169689Skan    case DECL_EXPR:
282169689Skan      pp_declaration (pp, DECL_EXPR_DECL (t));
283169689Skan      pp_needs_newline (pp) = true;
284169689Skan      break;
285169689Skan
286132718Skan    default:
287132718Skan      pp_unsupported_tree (pp, t);
288132718Skan    }
289132718Skan}
290132718Skan
291132718Skan/* type-specifier:
292132718Skan      void
293132718Skan      char
294132718Skan      short
295132718Skan      int
296132718Skan      long
297132718Skan      float
298132718Skan      double
299132718Skan      signed
300132718Skan      unsigned
301132718Skan      _Bool                          -- C99
302132718Skan      _Complex                       -- C99
303132718Skan      _Imaginary                     -- C99
304132718Skan      struct-or-union-specifier
305132718Skan      enum-specifier
306132718Skan      typedef-name.
307132718Skan
308132718Skan  GNU extensions.
309132718Skan  simple-type-specifier:
310132718Skan      __complex__
311132718Skan      __vector__   */
312132718Skan
313132718Skanvoid
314132718Skanpp_c_type_specifier (c_pretty_printer *pp, tree t)
315132718Skan{
316117395Skan  const enum tree_code code = TREE_CODE (t);
317117395Skan  switch (code)
318117395Skan    {
319117395Skan    case ERROR_MARK:
320132718Skan      pp_c_identifier (pp, "<type-error>");
321117395Skan      break;
322117395Skan
323132718Skan    case IDENTIFIER_NODE:
324169689Skan      pp_c_tree_decl_identifier (pp, t);
325117395Skan      break;
326117395Skan
327117395Skan    case VOID_TYPE:
328117395Skan    case BOOLEAN_TYPE:
329117395Skan    case INTEGER_TYPE:
330117395Skan    case REAL_TYPE:
331132718Skan      if (TYPE_NAME (t))
332169689Skan	{
333169689Skan	  t = TYPE_NAME (t);
334169689Skan	  pp_c_type_specifier (pp, t);
335169689Skan	}
336132718Skan      else
337169689Skan	{
338169689Skan	  int prec = TYPE_PRECISION (t);
339169689Skan	  t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
340169689Skan	  if (TYPE_NAME (t))
341169689Skan	    {
342169689Skan	      pp_c_type_specifier (pp, t);
343169689Skan	      if (TYPE_PRECISION (t) != prec)
344169689Skan		{
345169689Skan		  pp_string (pp, ":");
346169689Skan		  pp_decimal_int (pp, prec);
347169689Skan		}
348169689Skan	    }
349169689Skan	  else
350169689Skan	    {
351169689Skan	      switch (code)
352169689Skan		{
353169689Skan		case INTEGER_TYPE:
354169689Skan		  pp_string (pp, (TYPE_UNSIGNED (t)
355169689Skan				  ? "<unnamed-unsigned:"
356169689Skan				  : "<unnamed-signed:"));
357169689Skan		  break;
358169689Skan		case REAL_TYPE:
359169689Skan		  pp_string (pp, "<unnamed-float:");
360169689Skan		  break;
361169689Skan		default:
362169689Skan		  gcc_unreachable ();
363169689Skan		}
364169689Skan	      pp_decimal_int (pp, prec);
365169689Skan	      pp_string (pp, ">");
366169689Skan	    }
367169689Skan	}
368117395Skan      break;
369117395Skan
370117395Skan    case TYPE_DECL:
371117395Skan      if (DECL_NAME (t))
372132718Skan	pp_id_expression (pp, t);
373117395Skan      else
374132718Skan	pp_c_identifier (pp, "<typedef-error>");
375117395Skan      break;
376117395Skan
377117395Skan    case UNION_TYPE:
378117395Skan    case RECORD_TYPE:
379117395Skan    case ENUMERAL_TYPE:
380117395Skan      if (code == UNION_TYPE)
381132718Skan	pp_c_identifier (pp, "union");
382117395Skan      else if (code == RECORD_TYPE)
383132718Skan	pp_c_identifier (pp, "struct");
384117395Skan      else if (code == ENUMERAL_TYPE)
385132718Skan	pp_c_identifier (pp, "enum");
386117395Skan      else
387132718Skan	pp_c_identifier (pp, "<tag-error>");
388132718Skan
389117395Skan      if (TYPE_NAME (t))
390132718Skan	pp_id_expression (pp, TYPE_NAME (t));
391117395Skan      else
392132718Skan	pp_c_identifier (pp, "<anonymous>");
393117395Skan      break;
394117395Skan
395117395Skan    default:
396132718Skan      pp_unsupported_tree (pp, t);
397132718Skan      break;
398117395Skan    }
399117395Skan}
400117395Skan
401132718Skan/* specifier-qualifier-list:
402132718Skan      type-specifier specifier-qualifier-list-opt
403132718Skan      type-qualifier specifier-qualifier-list-opt
404132718Skan
405132718Skan
406132718Skan  Implementation note:  Because of the non-linearities in array or
407132718Skan  function declarations, this routine prints not just the
408132718Skan  specifier-qualifier-list of such entities or types of such entities,
409132718Skan  but also the 'pointer' production part of their declarators.  The
410132718Skan  remaining part is done by pp_declarator or pp_c_abstract_declarator.  */
411132718Skan
412132718Skanvoid
413132718Skanpp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
414117395Skan{
415132718Skan  const enum tree_code code = TREE_CODE (t);
416132718Skan
417132718Skan  if (TREE_CODE (t) != POINTER_TYPE)
418132718Skan    pp_c_type_qualifier_list (pp, t);
419132718Skan  switch (code)
420132718Skan    {
421132718Skan    case REFERENCE_TYPE:
422132718Skan    case POINTER_TYPE:
423261188Spfg    /* APPLE LOCAL blocks */
424261188Spfg    case BLOCK_POINTER_TYPE:
425132718Skan      {
426169689Skan	/* Get the types-specifier of this type.  */
427169689Skan	tree pointee = strip_pointer_operator (TREE_TYPE (t));
428169689Skan	pp_c_specifier_qualifier_list (pp, pointee);
429169689Skan	if (TREE_CODE (pointee) == ARRAY_TYPE
430169689Skan	    || TREE_CODE (pointee) == FUNCTION_TYPE)
431169689Skan	  {
432169689Skan	    pp_c_whitespace (pp);
433169689Skan	    pp_c_left_paren (pp);
434169689Skan	  }
435169689Skan	else if (!c_dialect_cxx ())
436169689Skan	  pp_c_whitespace (pp);
437169689Skan	pp_ptr_operator (pp, t);
438132718Skan      }
439132718Skan      break;
440132718Skan
441132718Skan    case FUNCTION_TYPE:
442132718Skan    case ARRAY_TYPE:
443132718Skan      pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
444132718Skan      break;
445132718Skan
446132718Skan    case VECTOR_TYPE:
447132718Skan    case COMPLEX_TYPE:
448132718Skan      pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
449132718Skan      if (code == COMPLEX_TYPE)
450169689Skan	pp_c_identifier (pp, flag_isoc99 ? "_Complex" : "__complex__");
451132718Skan      else if (code == VECTOR_TYPE)
452169689Skan	pp_c_identifier (pp, "__vector__");
453132718Skan      break;
454132718Skan
455132718Skan    default:
456132718Skan      pp_simple_type_specifier (pp, t);
457132718Skan      break;
458132718Skan    }
459117395Skan}
460117395Skan
461132718Skan/* parameter-type-list:
462132718Skan      parameter-list
463132718Skan      parameter-list , ...
464132718Skan
465132718Skan   parameter-list:
466132718Skan      parameter-declaration
467132718Skan      parameter-list , parameter-declaration
468132718Skan
469132718Skan   parameter-declaration:
470132718Skan      declaration-specifiers declarator
471132718Skan      declaration-specifiers abstract-declarator(opt)   */
472132718Skan
473132718Skanvoid
474132718Skanpp_c_parameter_type_list (c_pretty_printer *pp, tree t)
475132718Skan{
476132718Skan  bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
477132718Skan  tree parms = want_parm_decl ? DECL_ARGUMENTS (t) :  TYPE_ARG_TYPES (t);
478132718Skan  pp_c_left_paren (pp);
479132718Skan  if (parms == void_list_node)
480132718Skan    pp_c_identifier (pp, "void");
481132718Skan  else
482132718Skan    {
483132718Skan      bool first = true;
484132718Skan      for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
485169689Skan	{
486169689Skan	  if (!first)
487169689Skan	    pp_separate_with (pp, ',');
488169689Skan	  first = false;
489169689Skan	  pp_declaration_specifiers
490169689Skan	    (pp, want_parm_decl ? parms : TREE_VALUE (parms));
491169689Skan	  if (want_parm_decl)
492169689Skan	    pp_declarator (pp, parms);
493169689Skan	  else
494169689Skan	    pp_abstract_declarator (pp, TREE_VALUE (parms));
495169689Skan	}
496132718Skan    }
497132718Skan  pp_c_right_paren (pp);
498132718Skan}
499132718Skan
500132718Skan/* abstract-declarator:
501132718Skan      pointer
502132718Skan      pointer(opt) direct-abstract-declarator  */
503132718Skan
504117395Skanstatic void
505132718Skanpp_c_abstract_declarator (c_pretty_printer *pp, tree t)
506117395Skan{
507261188Spfg  /* APPLE LOCAL begin blocks */
508261188Spfg  if (TREE_CODE (t) == POINTER_TYPE ||
509261188Spfg      TREE_CODE (t) == BLOCK_POINTER_TYPE)
510261188Spfg   /* APPLE LOCAL end blocks */
511132718Skan    {
512132718Skan      if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
513169689Skan	  || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
514169689Skan	pp_c_right_paren (pp);
515132718Skan      t = TREE_TYPE (t);
516132718Skan    }
517132718Skan
518132718Skan  pp_direct_abstract_declarator (pp, t);
519117395Skan}
520117395Skan
521132718Skan/* direct-abstract-declarator:
522132718Skan      ( abstract-declarator )
523132718Skan      direct-abstract-declarator(opt) [ assignment-expression(opt) ]
524132718Skan      direct-abstract-declarator(opt) [ * ]
525132718Skan      direct-abstract-declarator(opt) ( parameter-type-list(opt) )  */
526117395Skan
527132718Skanvoid
528132718Skanpp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
529117395Skan{
530132718Skan  switch (TREE_CODE (t))
531132718Skan    {
532132718Skan    case POINTER_TYPE:
533261188Spfg    /* APPLE LOCAL blocks */
534261188Spfg    case BLOCK_POINTER_TYPE:
535132718Skan      pp_abstract_declarator (pp, t);
536132718Skan      break;
537169689Skan
538132718Skan    case FUNCTION_TYPE:
539132718Skan      pp_c_parameter_type_list (pp, t);
540132718Skan      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
541132718Skan      break;
542132718Skan
543132718Skan    case ARRAY_TYPE:
544132718Skan      pp_c_left_bracket (pp);
545169689Skan      if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
546169689Skan	{
547169689Skan	  tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t));
548169689Skan	  tree type = TREE_TYPE (maxval);
549169689Skan
550169689Skan	  if (host_integerp (maxval, 0))
551169689Skan	    pp_wide_integer (pp, tree_low_cst (maxval, 0) + 1);
552169689Skan	  else
553169689Skan	    pp_expression (pp, fold (build2 (PLUS_EXPR, type, maxval,
554169689Skan					     build_int_cst (type, 1))));
555169689Skan	}
556132718Skan      pp_c_right_bracket (pp);
557132718Skan      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
558132718Skan      break;
559132718Skan
560132718Skan    case IDENTIFIER_NODE:
561132718Skan    case VOID_TYPE:
562132718Skan    case BOOLEAN_TYPE:
563132718Skan    case INTEGER_TYPE:
564132718Skan    case REAL_TYPE:
565132718Skan    case ENUMERAL_TYPE:
566132718Skan    case RECORD_TYPE:
567132718Skan    case UNION_TYPE:
568132718Skan    case VECTOR_TYPE:
569132718Skan    case COMPLEX_TYPE:
570132718Skan    case TYPE_DECL:
571132718Skan      break;
572169689Skan
573132718Skan    default:
574132718Skan      pp_unsupported_tree (pp, t);
575132718Skan      break;
576132718Skan    }
577117395Skan}
578117395Skan
579132718Skan/* type-name:
580132718Skan      specifier-qualifier-list  abstract-declarator(opt)  */
581132718Skan
582132718Skanvoid
583132718Skanpp_c_type_id (c_pretty_printer *pp, tree t)
584117395Skan{
585132718Skan  pp_c_specifier_qualifier_list (pp, t);
586132718Skan  pp_abstract_declarator (pp, t);
587132718Skan}
588132718Skan
589132718Skan/* storage-class-specifier:
590132718Skan      typedef
591132718Skan      extern
592132718Skan      static
593132718Skan      auto
594132718Skan      register  */
595132718Skan
596132718Skanvoid
597132718Skanpp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
598132718Skan{
599117395Skan  if (TREE_CODE (t) == TYPE_DECL)
600117395Skan    pp_c_identifier (pp, "typedef");
601132718Skan  else if (DECL_P (t))
602132718Skan    {
603132718Skan      if (DECL_REGISTER (t))
604169689Skan	pp_c_identifier (pp, "register");
605132718Skan      else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
606169689Skan	pp_c_identifier (pp, "static");
607132718Skan    }
608117395Skan}
609117395Skan
610132718Skan/* function-specifier:
611132718Skan      inline   */
612132718Skan
613132718Skanvoid
614132718Skanpp_c_function_specifier (c_pretty_printer *pp, tree t)
615117395Skan{
616117395Skan  if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
617117395Skan    pp_c_identifier (pp, "inline");
618117395Skan}
619117395Skan
620132718Skan/* declaration-specifiers:
621132718Skan      storage-class-specifier declaration-specifiers(opt)
622132718Skan      type-specifier declaration-specifiers(opt)
623132718Skan      type-qualifier declaration-specifiers(opt)
624132718Skan      function-specifier declaration-specifiers(opt)  */
625132718Skan
626132718Skanvoid
627132718Skanpp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
628117395Skan{
629132718Skan  pp_storage_class_specifier (pp, t);
630132718Skan  pp_function_specifier (pp, t);
631132718Skan  pp_c_specifier_qualifier_list (pp, DECL_P (t) ?  TREE_TYPE (t) : t);
632117395Skan}
633117395Skan
634132718Skan/* direct-declarator
635132718Skan      identifier
636132718Skan      ( declarator )
637132718Skan      direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
638132718Skan      direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
639132718Skan      direct-declarator [ type-qualifier-list static assignment-expression ]
640132718Skan      direct-declarator [ type-qualifier-list * ]
641169689Skan      direct-declarator ( parameter-type-list )
642132718Skan      direct-declarator ( identifier-list(opt) )  */
643132718Skan
644132718Skanvoid
645132718Skanpp_c_direct_declarator (c_pretty_printer *pp, tree t)
646117395Skan{
647132718Skan  switch (TREE_CODE (t))
648132718Skan    {
649132718Skan    case VAR_DECL:
650132718Skan    case PARM_DECL:
651132718Skan    case TYPE_DECL:
652132718Skan    case FIELD_DECL:
653132718Skan    case LABEL_DECL:
654169689Skan      pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
655169689Skan      pp_c_tree_decl_identifier (pp, t);
656169689Skan      break;
657169689Skan
658132718Skan    case ARRAY_TYPE:
659132718Skan    case POINTER_TYPE:
660261188Spfg    /* APPLE LOCAL blocks */
661261188Spfg    case BLOCK_POINTER_TYPE:
662132718Skan      pp_abstract_declarator (pp, TREE_TYPE (t));
663132718Skan      break;
664117395Skan
665132718Skan    case FUNCTION_TYPE:
666132718Skan      pp_parameter_list (pp, t);
667132718Skan      pp_abstract_declarator (pp, TREE_TYPE (t));
668132718Skan      break;
669132718Skan
670132718Skan    case FUNCTION_DECL:
671132718Skan      pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
672169689Skan      pp_c_tree_decl_identifier (pp, t);
673132718Skan      if (pp_c_base (pp)->flags & pp_c_flag_abstract)
674169689Skan	pp_abstract_declarator (pp, TREE_TYPE (t));
675132718Skan      else
676169689Skan	{
677169689Skan	  pp_parameter_list (pp, t);
678169689Skan	  pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
679169689Skan	}
680132718Skan      break;
681132718Skan
682132718Skan    case INTEGER_TYPE:
683132718Skan    case REAL_TYPE:
684132718Skan    case ENUMERAL_TYPE:
685132718Skan    case UNION_TYPE:
686132718Skan    case RECORD_TYPE:
687132718Skan      break;
688132718Skan
689132718Skan    default:
690132718Skan      pp_unsupported_tree (pp, t);
691132718Skan      break;
692132718Skan    }
693117395Skan}
694117395Skan
695132718Skan
696132718Skan/* declarator:
697132718Skan      pointer(opt)  direct-declarator   */
698132718Skan
699132718Skanvoid
700132718Skanpp_c_declarator (c_pretty_printer *pp, tree t)
701117395Skan{
702132718Skan  switch (TREE_CODE (t))
703117395Skan    {
704132718Skan    case INTEGER_TYPE:
705132718Skan    case REAL_TYPE:
706132718Skan    case ENUMERAL_TYPE:
707132718Skan    case UNION_TYPE:
708132718Skan    case RECORD_TYPE:
709132718Skan      break;
710132718Skan
711132718Skan    case VAR_DECL:
712132718Skan    case PARM_DECL:
713132718Skan    case FIELD_DECL:
714132718Skan    case ARRAY_TYPE:
715132718Skan    case FUNCTION_TYPE:
716132718Skan    case FUNCTION_DECL:
717132718Skan    case TYPE_DECL:
718132718Skan      pp_direct_declarator (pp, t);
719132718Skan    break;
720132718Skan
721169689Skan
722132718Skan    default:
723132718Skan      pp_unsupported_tree (pp, t);
724132718Skan      break;
725117395Skan    }
726117395Skan}
727117395Skan
728132718Skan/* declaration:
729132718Skan      declaration-specifiers init-declarator-list(opt) ;  */
730132718Skan
731117395Skanvoid
732132718Skanpp_c_declaration (c_pretty_printer *pp, tree t)
733117395Skan{
734117395Skan  pp_declaration_specifiers (pp, t);
735117395Skan  pp_c_init_declarator (pp, t);
736117395Skan}
737117395Skan
738132718Skan/* Pretty-print ATTRIBUTES using GNU C extension syntax.  */
739117395Skan
740132718Skanvoid
741132718Skanpp_c_attributes (c_pretty_printer *pp, tree attributes)
742117395Skan{
743117395Skan  if (attributes == NULL_TREE)
744117395Skan    return;
745132718Skan
746117395Skan  pp_c_identifier (pp, "__attribute__");
747117395Skan  pp_c_left_paren (pp);
748132718Skan  pp_c_left_paren (pp);
749117395Skan  for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
750117395Skan    {
751117395Skan      pp_tree_identifier (pp, TREE_PURPOSE (attributes));
752117395Skan      if (TREE_VALUE (attributes))
753169689Skan	pp_c_call_argument_list (pp, TREE_VALUE (attributes));
754132718Skan
755117395Skan      if (TREE_CHAIN (attributes))
756117395Skan	pp_separate_with (pp, ',');
757117395Skan    }
758117395Skan  pp_c_right_paren (pp);
759117395Skan  pp_c_right_paren (pp);
760117395Skan}
761117395Skan
762132718Skan/* function-definition:
763132718Skan      declaration-specifiers declarator compound-statement  */
764132718Skan
765132718Skanvoid
766132718Skanpp_c_function_definition (c_pretty_printer *pp, tree t)
767132718Skan{
768132718Skan  pp_declaration_specifiers (pp, t);
769132718Skan  pp_declarator (pp, t);
770132718Skan  pp_needs_newline (pp) = true;
771132718Skan  pp_statement (pp, DECL_SAVED_TREE (t));
772132718Skan  pp_newline (pp);
773132718Skan  pp_flush (pp);
774132718Skan}
775132718Skan
776117395Skan
777117395Skan/* Expressions.  */
778117395Skan
779169689Skan/* Print out a c-char.  This is called solely for characters which are
780169689Skan   in the *target* execution character set.  We ought to convert them
781169689Skan   back to the *host* execution character set before printing, but we
782169689Skan   have no way to do this at present.  A decent compromise is to print
783169689Skan   all characters as if they were in the host execution character set,
784169689Skan   and not attempt to recover any named escape characters, but render
785169689Skan   all unprintables as octal escapes.  If the host and target character
786169689Skan   sets are the same, this produces relatively readable output.  If they
787169689Skan   are not the same, strings may appear as gibberish, but that's okay
788169689Skan   (in fact, it may well be what the reader wants, e.g. if they are looking
789169689Skan   to see if conversion to the target character set happened correctly).
790132718Skan
791169689Skan   A special case: we need to prefix \, ", and ' with backslashes.  It is
792169689Skan   correct to do so for the *host*'s \, ", and ', because the rest of the
793169689Skan   file appears in the host character set.  */
794169689Skan
795117395Skanstatic void
796132718Skanpp_c_char (c_pretty_printer *pp, int c)
797117395Skan{
798169689Skan  if (ISPRINT (c))
799117395Skan    {
800169689Skan      switch (c)
801169689Skan	{
802169689Skan	case '\\': pp_string (pp, "\\\\"); break;
803169689Skan	case '\'': pp_string (pp, "\\\'"); break;
804169689Skan	case '\"': pp_string (pp, "\\\""); break;
805169689Skan	default:   pp_character (pp, c);
806169689Skan	}
807117395Skan    }
808169689Skan  else
809169689Skan    pp_scalar (pp, "\\%03o", (unsigned) c);
810117395Skan}
811117395Skan
812117395Skan/* Print out a STRING literal.  */
813132718Skan
814132718Skanvoid
815132718Skanpp_c_string_literal (c_pretty_printer *pp, tree s)
816117395Skan{
817117395Skan  const char *p = TREE_STRING_POINTER (s);
818117395Skan  int n = TREE_STRING_LENGTH (s) - 1;
819117395Skan  int i;
820132718Skan  pp_doublequote (pp);
821117395Skan  for (i = 0; i < n; ++i)
822132718Skan    pp_c_char (pp, p[i]);
823132718Skan  pp_doublequote (pp);
824117395Skan}
825117395Skan
826169689Skan/* Pretty-print an INTEGER literal.  */
827169689Skan
828132718Skanstatic void
829132718Skanpp_c_integer_constant (c_pretty_printer *pp, tree i)
830132718Skan{
831132718Skan  tree type = TREE_TYPE (i);
832132718Skan
833132718Skan  if (TREE_INT_CST_HIGH (i) == 0)
834132718Skan    pp_wide_integer (pp, TREE_INT_CST_LOW (i));
835132718Skan  else
836132718Skan    {
837132718Skan      if (tree_int_cst_sgn (i) < 0)
838169689Skan	{
839169689Skan	  pp_character (pp, '-');
840169689Skan	  i = build_int_cst_wide (NULL_TREE,
841169689Skan				  -TREE_INT_CST_LOW (i),
842169689Skan				  ~TREE_INT_CST_HIGH (i)
843169689Skan				  + !TREE_INT_CST_LOW (i));
844169689Skan	}
845132718Skan      sprintf (pp_buffer (pp)->digit_buffer,
846169689Skan	       HOST_WIDE_INT_PRINT_DOUBLE_HEX,
847169689Skan	       TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i));
848132718Skan      pp_string (pp, pp_buffer (pp)->digit_buffer);
849132718Skan    }
850169689Skan  if (TYPE_UNSIGNED (type))
851132718Skan    pp_character (pp, 'u');
852132718Skan  if (type == long_integer_type_node || type == long_unsigned_type_node)
853132718Skan    pp_character (pp, 'l');
854132718Skan  else if (type == long_long_integer_type_node
855169689Skan	   || type == long_long_unsigned_type_node)
856132718Skan    pp_string (pp, "ll");
857132718Skan}
858132718Skan
859117395Skan/* Print out a CHARACTER literal.  */
860132718Skan
861132718Skanstatic void
862132718Skanpp_c_character_constant (c_pretty_printer *pp, tree c)
863117395Skan{
864132718Skan  tree type = TREE_TYPE (c);
865132718Skan  if (type == wchar_type_node)
866169689Skan    pp_character (pp, 'L');
867132718Skan  pp_quote (pp);
868169689Skan  if (host_integerp (c, TYPE_UNSIGNED (type)))
869169689Skan    pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type)));
870132718Skan  else
871132718Skan    pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c));
872132718Skan  pp_quote (pp);
873117395Skan}
874117395Skan
875117395Skan/* Print out a BOOLEAN literal.  */
876132718Skan
877132718Skanstatic void
878132718Skanpp_c_bool_constant (c_pretty_printer *pp, tree b)
879117395Skan{
880132718Skan  if (b == boolean_false_node)
881117395Skan    {
882132718Skan      if (c_dialect_cxx ())
883132718Skan	pp_c_identifier (pp, "false");
884132718Skan      else if (flag_isoc99)
885132718Skan	pp_c_identifier (pp, "_False");
886117395Skan      else
887132718Skan	pp_unsupported_tree (pp, b);
888117395Skan    }
889117395Skan  else if (b == boolean_true_node)
890117395Skan    {
891132718Skan      if (c_dialect_cxx ())
892132718Skan	pp_c_identifier (pp, "true");
893132718Skan      else if (flag_isoc99)
894132718Skan	pp_c_identifier (pp, "_True");
895117395Skan      else
896132718Skan	pp_unsupported_tree (pp, b);
897117395Skan    }
898132718Skan  else if (TREE_CODE (b) == INTEGER_CST)
899132718Skan    pp_c_integer_constant (pp, b);
900117395Skan  else
901132718Skan    pp_unsupported_tree (pp, b);
902117395Skan}
903117395Skan
904132718Skan/* Attempt to print out an ENUMERATOR.  Return true on success.  Else return
905117395Skan   false; that means the value was obtained by a cast, in which case
906117395Skan   print out the type-id part of the cast-expression -- the casted value
907117395Skan   is then printed by pp_c_integer_literal.  */
908132718Skan
909117395Skanstatic bool
910132718Skanpp_c_enumeration_constant (c_pretty_printer *pp, tree e)
911117395Skan{
912132718Skan  bool value_is_named = true;
913117395Skan  tree type = TREE_TYPE (e);
914117395Skan  tree value;
915117395Skan
916117395Skan  /* Find the name of this constant.  */
917132718Skan  for (value = TYPE_VALUES (type);
918117395Skan       value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
919117395Skan       value = TREE_CHAIN (value))
920117395Skan    ;
921132718Skan
922117395Skan  if (value != NULL_TREE)
923132718Skan    pp_id_expression (pp, TREE_PURPOSE (value));
924117395Skan  else
925117395Skan    {
926117395Skan      /* Value must have been cast.  */
927132718Skan      pp_c_type_cast (pp, type);
928132718Skan      value_is_named = false;
929117395Skan    }
930132718Skan
931132718Skan  return value_is_named;
932117395Skan}
933117395Skan
934132718Skan/* Print out a REAL value as a decimal-floating-constant.  */
935132718Skan
936117395Skanstatic void
937132718Skanpp_c_floating_constant (c_pretty_printer *pp, tree r)
938117395Skan{
939132718Skan  real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
940132718Skan		   sizeof (pp_buffer (pp)->digit_buffer), 0, 1);
941132718Skan  pp_string (pp, pp_buffer(pp)->digit_buffer);
942132718Skan  if (TREE_TYPE (r) == float_type_node)
943132718Skan    pp_character (pp, 'f');
944132718Skan  else if (TREE_TYPE (r) == long_double_type_node)
945132718Skan    pp_character (pp, 'l');
946169689Skan  else if (TREE_TYPE (r) == dfloat128_type_node)
947169689Skan    pp_string (pp, "dl");
948169689Skan  else if (TREE_TYPE (r) == dfloat64_type_node)
949169689Skan    pp_string (pp, "dd");
950169689Skan  else if (TREE_TYPE (r) == dfloat32_type_node)
951169689Skan    pp_string (pp, "df");
952132718Skan}
953132718Skan
954132718Skan/* Pretty-print a compound literal expression.  GNU extensions include
955169689Skan   vector constants.  */
956132718Skan
957132718Skanstatic void
958132718Skanpp_c_compound_literal (c_pretty_printer *pp, tree e)
959132718Skan{
960169689Skan  tree type = TREE_TYPE (e);
961132718Skan  pp_c_type_cast (pp, type);
962132718Skan
963132718Skan  switch (TREE_CODE (type))
964117395Skan    {
965132718Skan    case RECORD_TYPE:
966132718Skan    case UNION_TYPE:
967132718Skan    case ARRAY_TYPE:
968132718Skan    case VECTOR_TYPE:
969132718Skan    case COMPLEX_TYPE:
970132718Skan      pp_c_brace_enclosed_initializer_list (pp, e);
971132718Skan      break;
972117395Skan
973132718Skan    default:
974132718Skan      pp_unsupported_tree (pp, e);
975132718Skan      break;
976117395Skan    }
977117395Skan}
978117395Skan
979132718Skan/* constant:
980132718Skan      integer-constant
981132718Skan      floating-constant
982132718Skan      enumeration-constant
983132718Skan      character-constant   */
984117395Skan
985117395Skanvoid
986132718Skanpp_c_constant (c_pretty_printer *pp, tree e)
987117395Skan{
988132718Skan  const enum tree_code code = TREE_CODE (e);
989132718Skan
990132718Skan  switch (code)
991117395Skan    {
992117395Skan    case INTEGER_CST:
993132718Skan      {
994169689Skan	tree type = TREE_TYPE (e);
995169689Skan	if (type == boolean_type_node)
996169689Skan	  pp_c_bool_constant (pp, e);
997169689Skan	else if (type == char_type_node)
998169689Skan	  pp_c_character_constant (pp, e);
999169689Skan	else if (TREE_CODE (type) == ENUMERAL_TYPE
1000169689Skan		 && pp_c_enumeration_constant (pp, e))
1001169689Skan	  ;
1002169689Skan	else
1003169689Skan	  pp_c_integer_constant (pp, e);
1004132718Skan      }
1005117395Skan      break;
1006132718Skan
1007117395Skan    case REAL_CST:
1008132718Skan      pp_c_floating_constant (pp, e);
1009117395Skan      break;
1010132718Skan
1011117395Skan    case STRING_CST:
1012132718Skan      pp_c_string_literal (pp, e);
1013132718Skan      break;
1014117395Skan
1015117395Skan    default:
1016132718Skan      pp_unsupported_tree (pp, e);
1017117395Skan      break;
1018117395Skan    }
1019117395Skan}
1020117395Skan
1021169689Skan/* Pretty-print an IDENTIFIER_NODE, preceded by whitespace is necessary.  */
1022169689Skan
1023132718Skanvoid
1024132718Skanpp_c_identifier (c_pretty_printer *pp, const char *id)
1025117395Skan{
1026169689Skan  pp_c_maybe_whitespace (pp);
1027169689Skan  pp_identifier (pp, id);
1028132718Skan  pp_base (pp)->padding = pp_before;
1029132718Skan}
1030132718Skan
1031132718Skan/* Pretty-print a C primary-expression.
1032132718Skan   primary-expression:
1033132718Skan      identifier
1034132718Skan      constant
1035132718Skan      string-literal
1036132718Skan      ( expression )   */
1037132718Skan
1038132718Skanvoid
1039132718Skanpp_c_primary_expression (c_pretty_printer *pp, tree e)
1040132718Skan{
1041117395Skan  switch (TREE_CODE (e))
1042117395Skan    {
1043117395Skan    case VAR_DECL:
1044117395Skan    case PARM_DECL:
1045117395Skan    case FIELD_DECL:
1046117395Skan    case CONST_DECL:
1047117395Skan    case FUNCTION_DECL:
1048117395Skan    case LABEL_DECL:
1049169689Skan      pp_c_tree_decl_identifier (pp, e);
1050169689Skan      break;
1051169689Skan
1052117395Skan    case IDENTIFIER_NODE:
1053132718Skan      pp_c_tree_identifier (pp, e);
1054117395Skan      break;
1055117395Skan
1056117395Skan    case ERROR_MARK:
1057132718Skan      pp_c_identifier (pp, "<erroneous-expression>");
1058117395Skan      break;
1059132718Skan
1060117395Skan    case RESULT_DECL:
1061132718Skan      pp_c_identifier (pp, "<return-value>");
1062117395Skan      break;
1063117395Skan
1064117395Skan    case INTEGER_CST:
1065117395Skan    case REAL_CST:
1066117395Skan    case STRING_CST:
1067132718Skan      pp_c_constant (pp, e);
1068117395Skan      break;
1069117395Skan
1070169689Skan    case TARGET_EXPR:
1071169689Skan      pp_c_identifier (pp, "__builtin_memcpy");
1072132718Skan      pp_c_left_paren (pp);
1073169689Skan      pp_ampersand (pp);
1074169689Skan      pp_primary_expression (pp, TREE_OPERAND (e, 0));
1075169689Skan      pp_separate_with (pp, ',');
1076169689Skan      pp_ampersand (pp);
1077169689Skan      pp_initializer (pp, TREE_OPERAND (e, 1));
1078169689Skan      if (TREE_OPERAND (e, 2))
1079169689Skan	{
1080169689Skan	  pp_separate_with (pp, ',');
1081169689Skan	  pp_c_expression (pp, TREE_OPERAND (e, 2));
1082169689Skan	}
1083132718Skan      pp_c_right_paren (pp);
1084117395Skan      break;
1085117395Skan
1086117395Skan    default:
1087132718Skan      /* FIXME:  Make sure we won't get into an infinie loop.  */
1088132718Skan      pp_c_left_paren (pp);
1089132718Skan      pp_expression (pp, e);
1090132718Skan      pp_c_right_paren (pp);
1091117395Skan      break;
1092117395Skan    }
1093117395Skan}
1094117395Skan
1095132718Skan/* Print out a C initializer -- also support C compound-literals.
1096132718Skan   initializer:
1097132718Skan      assignment-expression:
1098132718Skan      { initializer-list }
1099132718Skan      { initializer-list , }   */
1100132718Skan
1101132718Skanstatic void
1102132718Skanpp_c_initializer (c_pretty_printer *pp, tree e)
1103117395Skan{
1104117395Skan  if (TREE_CODE (e) == CONSTRUCTOR)
1105169689Skan    pp_c_brace_enclosed_initializer_list (pp, e);
1106117395Skan  else
1107132718Skan    pp_expression (pp, e);
1108117395Skan}
1109117395Skan
1110132718Skan/* init-declarator:
1111132718Skan      declarator:
1112132718Skan      declarator = initializer   */
1113132718Skan
1114132718Skanvoid
1115132718Skanpp_c_init_declarator (c_pretty_printer *pp, tree t)
1116132718Skan{
1117132718Skan  pp_declarator (pp, t);
1118169689Skan  /* We don't want to output function definitions here.  There are handled
1119169689Skan     elsewhere (and the syntactic form is bogus anyway).  */
1120169689Skan  if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
1121132718Skan    {
1122132718Skan      tree init = DECL_INITIAL (t);
1123132718Skan      /* This C++ bit is handled here because it is easier to do so.
1124169689Skan	 In templates, the C++ parser builds a TREE_LIST for a
1125169689Skan	 direct-initialization; the TREE_PURPOSE is the variable to
1126169689Skan	 initialize and the TREE_VALUE is the initializer.  */
1127132718Skan      if (TREE_CODE (init) == TREE_LIST)
1128169689Skan	{
1129169689Skan	  pp_c_left_paren (pp);
1130169689Skan	  pp_expression (pp, TREE_VALUE (init));
1131169689Skan	  pp_right_paren (pp);
1132169689Skan	}
1133132718Skan      else
1134169689Skan	{
1135169689Skan	  pp_space (pp);
1136169689Skan	  pp_equal (pp);
1137169689Skan	  pp_space (pp);
1138169689Skan	  pp_c_initializer (pp, init);
1139169689Skan	}
1140132718Skan    }
1141132718Skan}
1142132718Skan
1143132718Skan/* initializer-list:
1144132718Skan      designation(opt) initializer
1145132718Skan      initializer-list , designation(opt) initializer
1146132718Skan
1147132718Skan   designation:
1148132718Skan      designator-list =
1149132718Skan
1150132718Skan   designator-list:
1151132718Skan      designator
1152132718Skan      designator-list designator
1153132718Skan
1154132718Skan   designator:
1155132718Skan      [ constant-expression ]
1156132718Skan      identifier   */
1157132718Skan
1158117395Skanstatic void
1159132718Skanpp_c_initializer_list (c_pretty_printer *pp, tree e)
1160117395Skan{
1161117395Skan  tree type = TREE_TYPE (e);
1162117395Skan  const enum tree_code code = TREE_CODE (type);
1163117395Skan
1164132718Skan  switch (code)
1165117395Skan    {
1166132718Skan    case RECORD_TYPE:
1167132718Skan    case UNION_TYPE:
1168132718Skan    case ARRAY_TYPE:
1169132718Skan      {
1170169689Skan	tree init = TREE_OPERAND (e, 0);
1171169689Skan	for (; init != NULL_TREE; init = TREE_CHAIN (init))
1172169689Skan	  {
1173169689Skan	    if (code == RECORD_TYPE || code == UNION_TYPE)
1174169689Skan	      {
1175169689Skan		pp_c_dot (pp);
1176169689Skan		pp_c_primary_expression (pp, TREE_PURPOSE (init));
1177169689Skan	      }
1178169689Skan	    else
1179169689Skan	      {
1180169689Skan		pp_c_left_bracket (pp);
1181169689Skan		if (TREE_PURPOSE (init))
1182169689Skan		  pp_c_constant (pp, TREE_PURPOSE (init));
1183169689Skan		pp_c_right_bracket (pp);
1184169689Skan	      }
1185169689Skan	    pp_c_whitespace (pp);
1186169689Skan	    pp_equal (pp);
1187169689Skan	    pp_c_whitespace (pp);
1188169689Skan	    pp_initializer (pp, TREE_VALUE (init));
1189169689Skan	    if (TREE_CHAIN (init))
1190169689Skan	      pp_separate_with (pp, ',');
1191169689Skan	  }
1192132718Skan      }
1193169689Skan      return;
1194132718Skan
1195132718Skan    case VECTOR_TYPE:
1196169689Skan      if (TREE_CODE (e) == VECTOR_CST)
1197169689Skan	pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
1198169689Skan      else if (TREE_CODE (e) == CONSTRUCTOR)
1199169689Skan	pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1200169689Skan      else
1201169689Skan	break;
1202169689Skan      return;
1203132718Skan
1204132718Skan    case COMPLEX_TYPE:
1205169689Skan      if (TREE_CODE (e) == CONSTRUCTOR)
1206169689Skan	pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1207169689Skan      else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
1208169689Skan	{
1209169689Skan	  const bool cst = TREE_CODE (e) == COMPLEX_CST;
1210169689Skan	  pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
1211169689Skan	  pp_separate_with (pp, ',');
1212169689Skan	  pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
1213169689Skan	}
1214169689Skan      else
1215169689Skan	break;
1216169689Skan      return;
1217132718Skan
1218132718Skan    default:
1219132718Skan      break;
1220117395Skan    }
1221169689Skan
1222169689Skan  pp_unsupported_tree (pp, type);
1223117395Skan}
1224117395Skan
1225132718Skan/* Pretty-print a brace-enclosed initializer-list.  */
1226132718Skan
1227132718Skanstatic void
1228132718Skanpp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
1229132718Skan{
1230132718Skan  pp_c_left_brace (pp);
1231132718Skan  pp_c_initializer_list (pp, l);
1232132718Skan  pp_c_right_brace (pp);
1233132718Skan}
1234132718Skan
1235132718Skan
1236132718Skan/*  This is a convenient function, used to bridge gap between C and C++
1237132718Skan    grammars.
1238132718Skan
1239132718Skan    id-expression:
1240132718Skan       identifier  */
1241132718Skan
1242117395Skanvoid
1243132718Skanpp_c_id_expression (c_pretty_printer *pp, tree t)
1244117395Skan{
1245132718Skan  switch (TREE_CODE (t))
1246132718Skan    {
1247132718Skan    case VAR_DECL:
1248132718Skan    case PARM_DECL:
1249132718Skan    case CONST_DECL:
1250132718Skan    case TYPE_DECL:
1251132718Skan    case FUNCTION_DECL:
1252132718Skan    case FIELD_DECL:
1253132718Skan    case LABEL_DECL:
1254169689Skan      pp_c_tree_decl_identifier (pp, t);
1255169689Skan      break;
1256169689Skan
1257132718Skan    case IDENTIFIER_NODE:
1258132718Skan      pp_c_tree_identifier (pp, t);
1259132718Skan      break;
1260132718Skan
1261132718Skan    default:
1262132718Skan      pp_unsupported_tree (pp, t);
1263132718Skan      break;
1264132718Skan    }
1265132718Skan}
1266132718Skan
1267132718Skan/* postfix-expression:
1268132718Skan      primary-expression
1269132718Skan      postfix-expression [ expression ]
1270132718Skan      postfix-expression ( argument-expression-list(opt) )
1271132718Skan      postfix-expression . identifier
1272132718Skan      postfix-expression -> identifier
1273132718Skan      postfix-expression ++
1274132718Skan      postfix-expression --
1275132718Skan      ( type-name ) { initializer-list }
1276132718Skan      ( type-name ) { initializer-list , }  */
1277132718Skan
1278132718Skanvoid
1279132718Skanpp_c_postfix_expression (c_pretty_printer *pp, tree e)
1280132718Skan{
1281117395Skan  enum tree_code code = TREE_CODE (e);
1282117395Skan  switch (code)
1283117395Skan    {
1284117395Skan    case POSTINCREMENT_EXPR:
1285117395Skan    case POSTDECREMENT_EXPR:
1286132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1287132718Skan      pp_identifier (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
1288117395Skan      break;
1289132718Skan
1290117395Skan    case ARRAY_REF:
1291132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1292132718Skan      pp_c_left_bracket (pp);
1293132718Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1294132718Skan      pp_c_right_bracket (pp);
1295117395Skan      break;
1296117395Skan
1297117395Skan    case CALL_EXPR:
1298132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1299132718Skan      pp_c_call_argument_list (pp, TREE_OPERAND (e, 1));
1300117395Skan      break;
1301117395Skan
1302169689Skan    case UNORDERED_EXPR:
1303169689Skan      pp_c_identifier (pp, flag_isoc99
1304169689Skan			   ? "isunordered"
1305169689Skan			   : "__builtin_isunordered");
1306169689Skan      goto two_args_fun;
1307169689Skan
1308169689Skan    case ORDERED_EXPR:
1309169689Skan      pp_c_identifier (pp, flag_isoc99
1310169689Skan			   ? "!isunordered"
1311169689Skan			   : "!__builtin_isunordered");
1312169689Skan      goto two_args_fun;
1313169689Skan
1314169689Skan    case UNLT_EXPR:
1315169689Skan      pp_c_identifier (pp, flag_isoc99
1316169689Skan			   ? "!isgreaterequal"
1317169689Skan			   : "!__builtin_isgreaterequal");
1318169689Skan      goto two_args_fun;
1319169689Skan
1320169689Skan    case UNLE_EXPR:
1321169689Skan      pp_c_identifier (pp, flag_isoc99
1322169689Skan			   ? "!isgreater"
1323169689Skan			   : "!__builtin_isgreater");
1324169689Skan      goto two_args_fun;
1325169689Skan
1326169689Skan    case UNGT_EXPR:
1327169689Skan      pp_c_identifier (pp, flag_isoc99
1328169689Skan			   ? "!islessequal"
1329169689Skan			   : "!__builtin_islessequal");
1330169689Skan      goto two_args_fun;
1331169689Skan
1332169689Skan    case UNGE_EXPR:
1333169689Skan      pp_c_identifier (pp, flag_isoc99
1334169689Skan			   ? "!isless"
1335169689Skan			   : "!__builtin_isless");
1336169689Skan      goto two_args_fun;
1337169689Skan
1338169689Skan    case UNEQ_EXPR:
1339169689Skan      pp_c_identifier (pp, flag_isoc99
1340169689Skan			   ? "!islessgreater"
1341169689Skan			   : "!__builtin_islessgreater");
1342169689Skan      goto two_args_fun;
1343169689Skan
1344169689Skan    case LTGT_EXPR:
1345169689Skan      pp_c_identifier (pp, flag_isoc99
1346169689Skan			   ? "islessgreater"
1347169689Skan			   : "__builtin_islessgreater");
1348169689Skan      goto two_args_fun;
1349169689Skan
1350169689Skan    two_args_fun:
1351169689Skan      pp_c_left_paren (pp);
1352169689Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1353169689Skan      pp_separate_with (pp, ',');
1354169689Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1355169689Skan      pp_c_right_paren (pp);
1356169689Skan      break;
1357169689Skan
1358117395Skan    case ABS_EXPR:
1359132718Skan      pp_c_identifier (pp, "__builtin_abs");
1360132718Skan      pp_c_left_paren (pp);
1361132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1362132718Skan      pp_c_right_paren (pp);
1363117395Skan      break;
1364117395Skan
1365117395Skan    case COMPONENT_REF:
1366117395Skan      {
1367117395Skan	tree object = TREE_OPERAND (e, 0);
1368117395Skan	if (TREE_CODE (object) == INDIRECT_REF)
1369117395Skan	  {
1370132718Skan	    pp_postfix_expression (pp, TREE_OPERAND (object, 0));
1371132718Skan	    pp_c_arrow (pp);
1372117395Skan	  }
1373117395Skan	else
1374117395Skan	  {
1375132718Skan	    pp_postfix_expression (pp, object);
1376132718Skan	    pp_c_dot (pp);
1377117395Skan	  }
1378132718Skan	pp_expression (pp, TREE_OPERAND (e, 1));
1379117395Skan      }
1380117395Skan      break;
1381117395Skan
1382117395Skan    case COMPLEX_CST:
1383117395Skan    case VECTOR_CST:
1384117395Skan    case COMPLEX_EXPR:
1385132718Skan      pp_c_compound_literal (pp, e);
1386117395Skan      break;
1387117395Skan
1388117395Skan    case COMPOUND_LITERAL_EXPR:
1389132718Skan      e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
1390117395Skan      /* Fall through.  */
1391117395Skan    case CONSTRUCTOR:
1392132718Skan      pp_initializer (pp, e);
1393117395Skan      break;
1394117395Skan
1395117395Skan    case VA_ARG_EXPR:
1396132718Skan      pp_c_identifier (pp, "__builtin_va_arg");
1397132718Skan      pp_c_left_paren (pp);
1398132718Skan      pp_assignment_expression (pp, TREE_OPERAND (e, 0));
1399132718Skan      pp_separate_with (pp, ',');
1400132718Skan      pp_type_id (pp, TREE_TYPE (e));
1401132718Skan      pp_c_right_paren (pp);
1402117395Skan      break;
1403117395Skan
1404132718Skan    case ADDR_EXPR:
1405132718Skan      if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
1406169689Skan	{
1407169689Skan	  pp_c_id_expression (pp, TREE_OPERAND (e, 0));
1408169689Skan	  break;
1409169689Skan	}
1410132718Skan      /* else fall through.  */
1411132718Skan
1412117395Skan    default:
1413132718Skan      pp_primary_expression (pp, e);
1414117395Skan      break;
1415117395Skan    }
1416117395Skan}
1417117395Skan
1418132718Skan/* Print out an expression-list; E is expected to be a TREE_LIST.  */
1419132718Skan
1420117395Skanvoid
1421132718Skanpp_c_expression_list (c_pretty_printer *pp, tree e)
1422117395Skan{
1423117395Skan  for (; e != NULL_TREE; e = TREE_CHAIN (e))
1424117395Skan    {
1425132718Skan      pp_expression (pp, TREE_VALUE (e));
1426117395Skan      if (TREE_CHAIN (e))
1427132718Skan	pp_separate_with (pp, ',');
1428117395Skan    }
1429117395Skan}
1430117395Skan
1431169689Skan/* Print out V, which contains the elements of a constructor.  */
1432169689Skan
1433169689Skanvoid
1434169689Skanpp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v)
1435169689Skan{
1436169689Skan  unsigned HOST_WIDE_INT ix;
1437169689Skan  tree value;
1438169689Skan
1439169689Skan  FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
1440169689Skan    {
1441169689Skan      pp_expression (pp, value);
1442169689Skan      if (ix != VEC_length (constructor_elt, v) - 1)
1443169689Skan	pp_separate_with (pp, ',');
1444169689Skan    }
1445169689Skan}
1446169689Skan
1447132718Skan/* Print out an expression-list in parens, as in a function call.  */
1448132718Skan
1449132718Skanvoid
1450132718Skanpp_c_call_argument_list (c_pretty_printer *pp, tree t)
1451117395Skan{
1452132718Skan  pp_c_left_paren (pp);
1453132718Skan  if (t && TREE_CODE (t) == TREE_LIST)
1454132718Skan    pp_c_expression_list (pp, t);
1455132718Skan  pp_c_right_paren (pp);
1456132718Skan}
1457132718Skan
1458132718Skan/* unary-expression:
1459132718Skan      postfix-expression
1460132718Skan      ++ cast-expression
1461132718Skan      -- cast-expression
1462132718Skan      unary-operator cast-expression
1463132718Skan      sizeof unary-expression
1464132718Skan      sizeof ( type-id )
1465132718Skan
1466132718Skan  unary-operator: one of
1467132718Skan      * &  + - ! ~
1468169689Skan
1469132718Skan   GNU extensions.
1470132718Skan   unary-expression:
1471132718Skan      __alignof__ unary-expression
1472132718Skan      __alignof__ ( type-id )
1473132718Skan      __real__ unary-expression
1474132718Skan      __imag__ unary-expression  */
1475132718Skan
1476132718Skanvoid
1477132718Skanpp_c_unary_expression (c_pretty_printer *pp, tree e)
1478132718Skan{
1479117395Skan  enum tree_code code = TREE_CODE (e);
1480117395Skan  switch (code)
1481117395Skan    {
1482117395Skan    case PREINCREMENT_EXPR:
1483117395Skan    case PREDECREMENT_EXPR:
1484132718Skan      pp_identifier (pp, code == PREINCREMENT_EXPR ? "++" : "--");
1485132718Skan      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
1486117395Skan      break;
1487132718Skan
1488117395Skan    case ADDR_EXPR:
1489117395Skan    case INDIRECT_REF:
1490117395Skan    case NEGATE_EXPR:
1491117395Skan    case BIT_NOT_EXPR:
1492117395Skan    case TRUTH_NOT_EXPR:
1493117395Skan    case CONJ_EXPR:
1494132718Skan      /* String literal are used by address.  */
1495132718Skan      if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
1496132718Skan	pp_ampersand (pp);
1497117395Skan      else if (code == INDIRECT_REF)
1498132718Skan	pp_c_star (pp);
1499117395Skan      else if (code == NEGATE_EXPR)
1500132718Skan	pp_minus (pp);
1501117395Skan      else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
1502132718Skan	pp_complement (pp);
1503117395Skan      else if (code == TRUTH_NOT_EXPR)
1504132718Skan	pp_exclamation (pp);
1505132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
1506117395Skan      break;
1507117395Skan
1508117395Skan    case REALPART_EXPR:
1509117395Skan    case IMAGPART_EXPR:
1510132718Skan      pp_c_identifier (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
1511132718Skan      pp_c_whitespace (pp);
1512132718Skan      pp_unary_expression (pp, TREE_OPERAND (e, 0));
1513117395Skan      break;
1514132718Skan
1515117395Skan    default:
1516132718Skan      pp_postfix_expression (pp, e);
1517117395Skan      break;
1518117395Skan    }
1519117395Skan}
1520117395Skan
1521132718Skan/* cast-expression:
1522132718Skan      unary-expression
1523132718Skan      ( type-name ) cast-expression  */
1524132718Skan
1525117395Skanvoid
1526132718Skanpp_c_cast_expression (c_pretty_printer *pp, tree e)
1527117395Skan{
1528132718Skan  switch (TREE_CODE (e))
1529117395Skan    {
1530132718Skan    case FLOAT_EXPR:
1531132718Skan    case FIX_TRUNC_EXPR:
1532132718Skan    case CONVERT_EXPR:
1533169689Skan    case NOP_EXPR:
1534132718Skan      pp_c_type_cast (pp, TREE_TYPE (e));
1535132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
1536132718Skan      break;
1537132718Skan
1538132718Skan    default:
1539132718Skan      pp_unary_expression (pp, e);
1540117395Skan    }
1541117395Skan}
1542117395Skan
1543132718Skan/* multiplicative-expression:
1544132718Skan      cast-expression
1545132718Skan      multiplicative-expression * cast-expression
1546132718Skan      multiplicative-expression / cast-expression
1547132718Skan      multiplicative-expression % cast-expression   */
1548132718Skan
1549117395Skanstatic void
1550132718Skanpp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
1551117395Skan{
1552117395Skan  enum tree_code code = TREE_CODE (e);
1553117395Skan  switch (code)
1554117395Skan    {
1555117395Skan    case MULT_EXPR:
1556117395Skan    case TRUNC_DIV_EXPR:
1557117395Skan    case TRUNC_MOD_EXPR:
1558132718Skan      pp_multiplicative_expression (pp, TREE_OPERAND (e, 0));
1559132718Skan      pp_c_whitespace (pp);
1560117395Skan      if (code == MULT_EXPR)
1561132718Skan	pp_c_star (pp);
1562117395Skan      else if (code == TRUNC_DIV_EXPR)
1563132718Skan	pp_slash (pp);
1564117395Skan      else
1565132718Skan	pp_modulo (pp);
1566132718Skan      pp_c_whitespace (pp);
1567132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 1));
1568117395Skan      break;
1569117395Skan
1570117395Skan    default:
1571132718Skan      pp_c_cast_expression (pp, e);
1572117395Skan      break;
1573117395Skan    }
1574117395Skan}
1575117395Skan
1576132718Skan/* additive-expression:
1577132718Skan      multiplicative-expression
1578132718Skan      additive-expression + multiplicative-expression
1579132718Skan      additive-expression - multiplicative-expression   */
1580132718Skan
1581132718Skanstatic void
1582132718Skanpp_c_additive_expression (c_pretty_printer *pp, tree e)
1583117395Skan{
1584117395Skan  enum tree_code code = TREE_CODE (e);
1585117395Skan  switch (code)
1586117395Skan    {
1587117395Skan    case PLUS_EXPR:
1588117395Skan    case MINUS_EXPR:
1589132718Skan      pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
1590132718Skan      pp_c_whitespace (pp);
1591117395Skan      if (code == PLUS_EXPR)
1592132718Skan	pp_plus (pp);
1593117395Skan      else
1594132718Skan	pp_minus (pp);
1595132718Skan      pp_c_whitespace (pp);
1596169689Skan      pp_multiplicative_expression (pp, TREE_OPERAND (e, 1));
1597117395Skan      break;
1598117395Skan
1599117395Skan    default:
1600132718Skan      pp_multiplicative_expression (pp, e);
1601117395Skan      break;
1602117395Skan    }
1603117395Skan}
1604117395Skan
1605132718Skan/* additive-expression:
1606132718Skan      additive-expression
1607132718Skan      shift-expression << additive-expression
1608132718Skan      shift-expression >> additive-expression   */
1609132718Skan
1610132718Skanstatic void
1611132718Skanpp_c_shift_expression (c_pretty_printer *pp, tree e)
1612117395Skan{
1613117395Skan  enum tree_code code = TREE_CODE (e);
1614117395Skan  switch (code)
1615117395Skan    {
1616117395Skan    case LSHIFT_EXPR:
1617117395Skan    case RSHIFT_EXPR:
1618132718Skan      pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
1619132718Skan      pp_c_whitespace (pp);
1620132718Skan      pp_identifier (pp, code == LSHIFT_EXPR ? "<<" : ">>");
1621132718Skan      pp_c_whitespace (pp);
1622132718Skan      pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
1623117395Skan      break;
1624117395Skan
1625117395Skan    default:
1626132718Skan      pp_c_additive_expression (pp, e);
1627117395Skan    }
1628117395Skan}
1629117395Skan
1630132718Skan/* relational-expression:
1631132718Skan      shift-expression
1632132718Skan      relational-expression < shift-expression
1633132718Skan      relational-expression > shift-expression
1634132718Skan      relational-expression <= shift-expression
1635132718Skan      relational-expression >= shift-expression   */
1636132718Skan
1637117395Skanstatic void
1638132718Skanpp_c_relational_expression (c_pretty_printer *pp, tree e)
1639117395Skan{
1640117395Skan  enum tree_code code = TREE_CODE (e);
1641117395Skan  switch (code)
1642117395Skan    {
1643117395Skan    case LT_EXPR:
1644117395Skan    case GT_EXPR:
1645117395Skan    case LE_EXPR:
1646117395Skan    case GE_EXPR:
1647132718Skan      pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
1648132718Skan      pp_c_whitespace (pp);
1649117395Skan      if (code == LT_EXPR)
1650132718Skan	pp_less (pp);
1651117395Skan      else if (code == GT_EXPR)
1652132718Skan	pp_greater (pp);
1653117395Skan      else if (code == LE_EXPR)
1654132718Skan	pp_identifier (pp, "<=");
1655117395Skan      else if (code == GE_EXPR)
1656132718Skan	pp_identifier (pp, ">=");
1657132718Skan      pp_c_whitespace (pp);
1658132718Skan      pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
1659117395Skan      break;
1660117395Skan
1661117395Skan    default:
1662132718Skan      pp_c_shift_expression (pp, e);
1663117395Skan      break;
1664117395Skan    }
1665117395Skan}
1666117395Skan
1667132718Skan/* equality-expression:
1668132718Skan      relational-expression
1669132718Skan      equality-expression == relational-expression
1670132718Skan      equality-equality != relational-expression  */
1671132718Skan
1672132718Skanstatic void
1673132718Skanpp_c_equality_expression (c_pretty_printer *pp, tree e)
1674117395Skan{
1675117395Skan  enum tree_code code = TREE_CODE (e);
1676117395Skan  switch (code)
1677117395Skan    {
1678117395Skan    case EQ_EXPR:
1679117395Skan    case NE_EXPR:
1680132718Skan      pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
1681132718Skan      pp_c_whitespace (pp);
1682132718Skan      pp_identifier (pp, code == EQ_EXPR ? "==" : "!=");
1683132718Skan      pp_c_whitespace (pp);
1684132718Skan      pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
1685132718Skan      break;
1686132718Skan
1687117395Skan    default:
1688132718Skan      pp_c_relational_expression (pp, e);
1689117395Skan      break;
1690117395Skan    }
1691117395Skan}
1692117395Skan
1693132718Skan/* AND-expression:
1694132718Skan      equality-expression
1695132718Skan      AND-expression & equality-equality   */
1696132718Skan
1697132718Skanstatic void
1698132718Skanpp_c_and_expression (c_pretty_printer *pp, tree e)
1699117395Skan{
1700117395Skan  if (TREE_CODE (e) == BIT_AND_EXPR)
1701117395Skan    {
1702132718Skan      pp_c_and_expression (pp, TREE_OPERAND (e, 0));
1703132718Skan      pp_c_whitespace (pp);
1704132718Skan      pp_ampersand (pp);
1705132718Skan      pp_c_whitespace (pp);
1706132718Skan      pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
1707117395Skan    }
1708117395Skan  else
1709132718Skan    pp_c_equality_expression (pp, e);
1710117395Skan}
1711117395Skan
1712132718Skan/* exclusive-OR-expression:
1713132718Skan     AND-expression
1714132718Skan     exclusive-OR-expression ^ AND-expression  */
1715132718Skan
1716132718Skanstatic void
1717132718Skanpp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
1718117395Skan{
1719117395Skan  if (TREE_CODE (e) == BIT_XOR_EXPR)
1720117395Skan    {
1721132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
1722132718Skan      pp_c_maybe_whitespace (pp);
1723132718Skan      pp_carret (pp);
1724132718Skan      pp_c_whitespace (pp);
1725132718Skan      pp_c_and_expression (pp, TREE_OPERAND (e, 1));
1726117395Skan    }
1727117395Skan  else
1728132718Skan    pp_c_and_expression (pp, e);
1729117395Skan}
1730117395Skan
1731132718Skan/* inclusive-OR-expression:
1732132718Skan     exclusive-OR-expression
1733132718Skan     inclusive-OR-expression | exclusive-OR-expression  */
1734132718Skan
1735132718Skanstatic void
1736132718Skanpp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
1737117395Skan{
1738117395Skan  if (TREE_CODE (e) == BIT_IOR_EXPR)
1739117395Skan    {
1740132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
1741132718Skan      pp_c_whitespace (pp);
1742132718Skan      pp_bar (pp);
1743132718Skan      pp_c_whitespace (pp);
1744132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
1745117395Skan    }
1746117395Skan  else
1747132718Skan    pp_c_exclusive_or_expression (pp, e);
1748117395Skan}
1749117395Skan
1750132718Skan/* logical-AND-expression:
1751132718Skan      inclusive-OR-expression
1752132718Skan      logical-AND-expression && inclusive-OR-expression  */
1753132718Skan
1754132718Skanstatic void
1755132718Skanpp_c_logical_and_expression (c_pretty_printer *pp, tree e)
1756117395Skan{
1757117395Skan  if (TREE_CODE (e) == TRUTH_ANDIF_EXPR)
1758117395Skan    {
1759132718Skan      pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
1760132718Skan      pp_c_whitespace (pp);
1761132718Skan      pp_identifier (pp, "&&");
1762132718Skan      pp_c_whitespace (pp);
1763132718Skan      pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
1764117395Skan    }
1765117395Skan  else
1766132718Skan    pp_c_inclusive_or_expression (pp, e);
1767117395Skan}
1768117395Skan
1769132718Skan/* logical-OR-expression:
1770132718Skan      logical-AND-expression
1771132718Skan      logical-OR-expression || logical-AND-expression  */
1772132718Skan
1773117395Skanvoid
1774132718Skanpp_c_logical_or_expression (c_pretty_printer *pp, tree e)
1775117395Skan{
1776117395Skan  if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
1777117395Skan    {
1778132718Skan      pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
1779132718Skan      pp_c_whitespace (pp);
1780132718Skan      pp_identifier (pp, "||");
1781132718Skan      pp_c_whitespace (pp);
1782132718Skan      pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
1783117395Skan    }
1784117395Skan  else
1785132718Skan    pp_c_logical_and_expression (pp, e);
1786117395Skan}
1787117395Skan
1788132718Skan/* conditional-expression:
1789132718Skan      logical-OR-expression
1790132718Skan      logical-OR-expression ? expression : conditional-expression  */
1791132718Skan
1792117395Skanstatic void
1793132718Skanpp_c_conditional_expression (c_pretty_printer *pp, tree e)
1794117395Skan{
1795117395Skan  if (TREE_CODE (e) == COND_EXPR)
1796117395Skan    {
1797132718Skan      pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
1798132718Skan      pp_c_whitespace (pp);
1799132718Skan      pp_question (pp);
1800132718Skan      pp_c_whitespace (pp);
1801132718Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1802132718Skan      pp_c_whitespace (pp);
1803132718Skan      pp_colon (pp);
1804132718Skan      pp_c_whitespace (pp);
1805132718Skan      pp_c_conditional_expression (pp, TREE_OPERAND (e, 2));
1806117395Skan    }
1807117395Skan  else
1808132718Skan    pp_c_logical_or_expression (pp, e);
1809117395Skan}
1810117395Skan
1811117395Skan
1812132718Skan/* assignment-expression:
1813132718Skan      conditional-expression
1814169689Skan      unary-expression assignment-operator  assignment-expression
1815132718Skan
1816132718Skan   assignment-expression: one of
1817132718Skan      =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
1818132718Skan
1819117395Skanstatic void
1820132718Skanpp_c_assignment_expression (c_pretty_printer *pp, tree e)
1821117395Skan{
1822117395Skan  if (TREE_CODE (e) == MODIFY_EXPR || TREE_CODE (e) == INIT_EXPR)
1823117395Skan    {
1824132718Skan      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
1825132718Skan      pp_c_whitespace (pp);
1826132718Skan      pp_equal (pp);
1827132718Skan      pp_space (pp);
1828132718Skan      pp_c_expression (pp, TREE_OPERAND (e, 1));
1829117395Skan    }
1830117395Skan  else
1831132718Skan    pp_c_conditional_expression (pp, e);
1832117395Skan}
1833117395Skan
1834132718Skan/* expression:
1835132718Skan       assignment-expression
1836132718Skan       expression , assignment-expression
1837132718Skan
1838132718Skan  Implementation note:  instead of going through the usual recursion
1839132718Skan  chain, I take the liberty of dispatching nodes to the appropriate
1840132718Skan  functions.  This makes some redundancy, but it worths it. That also
1841132718Skan  prevents a possible infinite recursion between pp_c_primary_expression ()
1842132718Skan  and pp_c_expression ().  */
1843132718Skan
1844117395Skanvoid
1845132718Skanpp_c_expression (c_pretty_printer *pp, tree e)
1846117395Skan{
1847117395Skan  switch (TREE_CODE (e))
1848117395Skan    {
1849117395Skan    case INTEGER_CST:
1850132718Skan      pp_c_integer_constant (pp, e);
1851117395Skan      break;
1852132718Skan
1853117395Skan    case REAL_CST:
1854132718Skan      pp_c_floating_constant (pp, e);
1855117395Skan      break;
1856117395Skan
1857117395Skan    case STRING_CST:
1858132718Skan      pp_c_string_literal (pp, e);
1859117395Skan      break;
1860132718Skan
1861132718Skan    case IDENTIFIER_NODE:
1862117395Skan    case FUNCTION_DECL:
1863117395Skan    case VAR_DECL:
1864117395Skan    case CONST_DECL:
1865117395Skan    case PARM_DECL:
1866117395Skan    case RESULT_DECL:
1867117395Skan    case FIELD_DECL:
1868117395Skan    case LABEL_DECL:
1869117395Skan    case ERROR_MARK:
1870132718Skan      pp_primary_expression (pp, e);
1871117395Skan      break;
1872117395Skan
1873117395Skan    case POSTINCREMENT_EXPR:
1874117395Skan    case POSTDECREMENT_EXPR:
1875117395Skan    case ARRAY_REF:
1876117395Skan    case CALL_EXPR:
1877117395Skan    case COMPONENT_REF:
1878117395Skan    case COMPLEX_CST:
1879132718Skan    case COMPLEX_EXPR:
1880117395Skan    case VECTOR_CST:
1881169689Skan    case ORDERED_EXPR:
1882169689Skan    case UNORDERED_EXPR:
1883169689Skan    case LTGT_EXPR:
1884169689Skan    case UNEQ_EXPR:
1885169689Skan    case UNLE_EXPR:
1886169689Skan    case UNLT_EXPR:
1887169689Skan    case UNGE_EXPR:
1888169689Skan    case UNGT_EXPR:
1889117395Skan    case ABS_EXPR:
1890117395Skan    case CONSTRUCTOR:
1891117395Skan    case COMPOUND_LITERAL_EXPR:
1892117395Skan    case VA_ARG_EXPR:
1893132718Skan      pp_postfix_expression (pp, e);
1894117395Skan      break;
1895117395Skan
1896117395Skan    case CONJ_EXPR:
1897117395Skan    case ADDR_EXPR:
1898117395Skan    case INDIRECT_REF:
1899117395Skan    case NEGATE_EXPR:
1900117395Skan    case BIT_NOT_EXPR:
1901117395Skan    case TRUTH_NOT_EXPR:
1902117395Skan    case PREINCREMENT_EXPR:
1903117395Skan    case PREDECREMENT_EXPR:
1904117395Skan    case REALPART_EXPR:
1905117395Skan    case IMAGPART_EXPR:
1906132718Skan      pp_c_unary_expression (pp, e);
1907117395Skan      break;
1908117395Skan
1909132718Skan    case FLOAT_EXPR:
1910132718Skan    case FIX_TRUNC_EXPR:
1911117395Skan    case CONVERT_EXPR:
1912169689Skan    case NOP_EXPR:
1913132718Skan      pp_c_cast_expression (pp, e);
1914117395Skan      break;
1915117395Skan
1916117395Skan    case MULT_EXPR:
1917117395Skan    case TRUNC_MOD_EXPR:
1918117395Skan    case TRUNC_DIV_EXPR:
1919132718Skan      pp_multiplicative_expression (pp, e);
1920117395Skan      break;
1921117395Skan
1922117395Skan    case LSHIFT_EXPR:
1923117395Skan    case RSHIFT_EXPR:
1924132718Skan      pp_c_shift_expression (pp, e);
1925117395Skan      break;
1926117395Skan
1927117395Skan    case LT_EXPR:
1928117395Skan    case GT_EXPR:
1929117395Skan    case LE_EXPR:
1930117395Skan    case GE_EXPR:
1931132718Skan      pp_c_relational_expression (pp, e);
1932117395Skan      break;
1933117395Skan
1934117395Skan    case BIT_AND_EXPR:
1935132718Skan      pp_c_and_expression (pp, e);
1936117395Skan      break;
1937117395Skan
1938117395Skan    case BIT_XOR_EXPR:
1939132718Skan      pp_c_exclusive_or_expression (pp, e);
1940117395Skan      break;
1941117395Skan
1942117395Skan    case BIT_IOR_EXPR:
1943132718Skan      pp_c_inclusive_or_expression (pp, e);
1944117395Skan      break;
1945117395Skan
1946117395Skan    case TRUTH_ANDIF_EXPR:
1947132718Skan      pp_c_logical_and_expression (pp, e);
1948117395Skan      break;
1949117395Skan
1950117395Skan    case TRUTH_ORIF_EXPR:
1951132718Skan      pp_c_logical_or_expression (pp, e);
1952117395Skan      break;
1953117395Skan
1954132718Skan    case EQ_EXPR:
1955132718Skan    case NE_EXPR:
1956132718Skan      pp_c_equality_expression (pp, e);
1957132718Skan      break;
1958169689Skan
1959117395Skan    case COND_EXPR:
1960132718Skan      pp_conditional_expression (pp, e);
1961117395Skan      break;
1962117395Skan
1963132718Skan    case PLUS_EXPR:
1964132718Skan    case MINUS_EXPR:
1965132718Skan      pp_c_additive_expression (pp, e);
1966132718Skan      break;
1967132718Skan
1968117395Skan    case MODIFY_EXPR:
1969117395Skan    case INIT_EXPR:
1970132718Skan      pp_assignment_expression (pp, e);
1971117395Skan      break;
1972117395Skan
1973132718Skan    case COMPOUND_EXPR:
1974132718Skan      pp_c_left_paren (pp);
1975132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1976132718Skan      pp_separate_with (pp, ',');
1977132718Skan      pp_assignment_expression (pp, TREE_OPERAND (e, 1));
1978132718Skan      pp_c_right_paren (pp);
1979132718Skan      break;
1980132718Skan
1981132718Skan    case NON_LVALUE_EXPR:
1982132718Skan    case SAVE_EXPR:
1983132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1984117395Skan      break;
1985117395Skan
1986132718Skan    case TARGET_EXPR:
1987132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 1));
1988117395Skan      break;
1989169689Skan
1990117395Skan    default:
1991132718Skan      pp_unsupported_tree (pp, e);
1992117395Skan      break;
1993117395Skan    }
1994117395Skan}
1995117395Skan
1996132718Skan
1997117395Skan
1998117395Skan/* Statements.  */
1999132718Skan
2000117395Skanvoid
2001132718Skanpp_c_statement (c_pretty_printer *pp, tree stmt)
2002117395Skan{
2003132718Skan  if (stmt == NULL)
2004132718Skan    return;
2005117395Skan
2006169689Skan  if (pp_needs_newline (pp))
2007169689Skan    pp_newline_and_indent (pp, 0);
2008132718Skan
2009169689Skan  dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
2010117395Skan}
2011117395Skan
2012117395Skan
2013117395Skan/* Initialize the PRETTY-PRINTER for handling C codes.  */
2014132718Skan
2015117395Skanvoid
2016132718Skanpp_c_pretty_printer_init (c_pretty_printer *pp)
2017117395Skan{
2018117395Skan  pp->offset_list               = 0;
2019117395Skan
2020117395Skan  pp->declaration               = pp_c_declaration;
2021117395Skan  pp->declaration_specifiers    = pp_c_declaration_specifiers;
2022117395Skan  pp->declarator                = pp_c_declarator;
2023117395Skan  pp->direct_declarator         = pp_c_direct_declarator;
2024132718Skan  pp->type_specifier_seq        = pp_c_specifier_qualifier_list;
2025132718Skan  pp->abstract_declarator       = pp_c_abstract_declarator;
2026132718Skan  pp->direct_abstract_declarator = pp_c_direct_abstract_declarator;
2027132718Skan  pp->ptr_operator              = pp_c_pointer;
2028132718Skan  pp->parameter_list            = pp_c_parameter_type_list;
2029117395Skan  pp->type_id                   = pp_c_type_id;
2030132718Skan  pp->simple_type_specifier     = pp_c_type_specifier;
2031132718Skan  pp->function_specifier        = pp_c_function_specifier;
2032132718Skan  pp->storage_class_specifier   = pp_c_storage_class_specifier;
2033117395Skan
2034117395Skan  pp->statement                 = pp_c_statement;
2035117395Skan
2036169689Skan  pp->constant                  = pp_c_constant;
2037132718Skan  pp->id_expression             = pp_c_id_expression;
2038117395Skan  pp->primary_expression        = pp_c_primary_expression;
2039117395Skan  pp->postfix_expression        = pp_c_postfix_expression;
2040117395Skan  pp->unary_expression          = pp_c_unary_expression;
2041117395Skan  pp->initializer               = pp_c_initializer;
2042117395Skan  pp->multiplicative_expression = pp_c_multiplicative_expression;
2043117395Skan  pp->conditional_expression    = pp_c_conditional_expression;
2044117395Skan  pp->assignment_expression     = pp_c_assignment_expression;
2045132718Skan  pp->expression                = pp_c_expression;
2046117395Skan}
2047169689Skan
2048169689Skan
2049169689Skan/* Print the tree T in full, on file FILE.  */
2050169689Skan
2051169689Skanvoid
2052169689Skanprint_c_tree (FILE *file, tree t)
2053169689Skan{
2054169689Skan  static c_pretty_printer pp_rec;
2055169689Skan  static bool initialized = 0;
2056169689Skan  c_pretty_printer *pp = &pp_rec;
2057169689Skan
2058169689Skan  if (!initialized)
2059169689Skan    {
2060169689Skan      initialized = 1;
2061169689Skan      pp_construct (pp_base (pp), NULL, 0);
2062169689Skan      pp_c_pretty_printer_init (pp);
2063169689Skan      pp_needs_newline (pp) = true;
2064169689Skan    }
2065169689Skan  pp_base (pp)->buffer->stream = file;
2066169689Skan
2067169689Skan  pp_statement (pp, t);
2068169689Skan
2069169689Skan  pp_newline (pp);
2070169689Skan  pp_flush (pp);
2071169689Skan}
2072169689Skan
2073169689Skan/* Print the tree T in full, on stderr.  */
2074169689Skan
2075169689Skanvoid
2076169689Skandebug_c_tree (tree t)
2077169689Skan{
2078169689Skan  print_c_tree (stderr, t);
2079169689Skan  fputc ('\n', stderr);
2080169689Skan}
2081169689Skan
2082169689Skan/* Output the DECL_NAME of T.  If T has no DECL_NAME, output a string made
2083169689Skan   up of T's memory address.  */
2084169689Skan
2085169689Skanvoid
2086169689Skanpp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
2087169689Skan{
2088169689Skan  const char *name;
2089169689Skan
2090169689Skan  gcc_assert (DECL_P (t));
2091169689Skan
2092169689Skan  if (DECL_NAME (t))
2093169689Skan    name = IDENTIFIER_POINTER (DECL_NAME (t));
2094169689Skan  else
2095169689Skan    {
2096169689Skan      static char xname[8];
2097169689Skan      sprintf (xname, "<U%4x>", ((unsigned)((unsigned long)(t) & 0xffff)));
2098169689Skan      name = xname;
2099169689Skan    }
2100169689Skan
2101169689Skan  pp_c_identifier (pp, name);
2102169689Skan}
2103