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
140169689Skanvoid
141132718Skanpp_c_arrow (c_pretty_printer *pp)
142132718Skan{
143132718Skan  pp_arrow (pp);
144132718Skan  pp_base (pp)->padding = pp_none;
145132718Skan}
146132718Skan
147132718Skanvoid
148169689Skanpp_c_semicolon (c_pretty_printer *pp)
149132718Skan{
150132718Skan  pp_semicolon (pp);
151132718Skan  pp_base (pp)->padding = pp_none;
152132718Skan}
153132718Skan
154169689Skanvoid
155169689Skanpp_c_complement (c_pretty_printer *pp)
156169689Skan{
157169689Skan  pp_complement (pp);
158169689Skan  pp_base (pp)->padding = pp_none;
159169689Skan}
160169689Skan
161169689Skanvoid
162169689Skanpp_c_exclamation (c_pretty_printer *pp)
163169689Skan{
164169689Skan  pp_exclamation (pp);
165169689Skan  pp_base (pp)->padding = pp_none;
166169689Skan}
167169689Skan
168169689Skan/* Print out the external representation of CV-QUALIFIER.  */
169169689Skan
170132718Skanstatic void
171132718Skanpp_c_cv_qualifier (c_pretty_printer *pp, const char *cv)
172132718Skan{
173132718Skan  const char *p = pp_last_position_in_text (pp);
174169689Skan  /* The C programming language does not have references, but it is much
175169689Skan     simpler to handle those here rather than going through the same
176169689Skan     logic in the C++ pretty-printer.  */
177169689Skan  if (p != NULL && (*p == '*' || *p == '&'))
178132718Skan    pp_c_whitespace (pp);
179132718Skan  pp_c_identifier (pp, cv);
180132718Skan}
181132718Skan
182132718Skan/* Pretty-print T using the type-cast notation '( type-name )'.  */
183132718Skan
184132718Skanstatic void
185132718Skanpp_c_type_cast (c_pretty_printer *pp, tree t)
186132718Skan{
187132718Skan  pp_c_left_paren (pp);
188132718Skan  pp_type_id (pp, t);
189132718Skan  pp_c_right_paren (pp);
190132718Skan}
191132718Skan
192169689Skan/* We're about to pretty-print a pointer type as indicated by T.
193169689Skan   Output a whitespace, if needed, preparing for subsequent output.  */
194169689Skan
195132718Skanvoid
196132718Skanpp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
197132718Skan{
198132718Skan  if (POINTER_TYPE_P (t))
199132718Skan    {
200132718Skan      tree pointee = strip_pointer_operator (TREE_TYPE (t));
201132718Skan      if (TREE_CODE (pointee) != ARRAY_TYPE
202169689Skan	  && TREE_CODE (pointee) != FUNCTION_TYPE)
203169689Skan	pp_c_whitespace (pp);
204132718Skan    }
205132718Skan}
206132718Skan
207132718Skan
208117395Skan/* Declarations.  */
209117395Skan
210132718Skan/* C++ cv-qualifiers are called type-qualifiers in C.  Print out the
211132718Skan   cv-qualifiers of T.  If T is a declaration then it is the cv-qualifier
212132718Skan   of its type.  Take care of possible extensions.
213132718Skan
214132718Skan   type-qualifier-list:
215132718Skan       type-qualifier
216132718Skan       type-qualifier-list type-qualifier
217132718Skan
218132718Skan   type-qualifier:
219132718Skan       const
220132718Skan       restrict                              -- C99
221132718Skan       __restrict__                          -- GNU C
222132718Skan       volatile    */
223132718Skan
224117395Skanvoid
225132718Skanpp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
226117395Skan{
227132718Skan   int qualifiers;
228169689Skan
229132718Skan  if (!TYPE_P (t))
230132718Skan    t = TREE_TYPE (t);
231132718Skan
232132718Skan  qualifiers = TYPE_QUALS (t);
233132718Skan  if (qualifiers & TYPE_QUAL_CONST)
234132718Skan    pp_c_cv_qualifier (pp, "const");
235132718Skan  if (qualifiers & TYPE_QUAL_VOLATILE)
236132718Skan    pp_c_cv_qualifier (pp, "volatile");
237132718Skan  if (qualifiers & TYPE_QUAL_RESTRICT)
238132718Skan    pp_c_cv_qualifier (pp, flag_isoc99 ? "restrict" : "__restrict__");
239117395Skan}
240117395Skan
241132718Skan/* pointer:
242132718Skan      * type-qualifier-list(opt)
243132718Skan      * type-qualifier-list(opt) pointer  */
244132718Skan
245117395Skanstatic void
246132718Skanpp_c_pointer (c_pretty_printer *pp, tree t)
247117395Skan{
248132718Skan  if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
249132718Skan    t = TREE_TYPE (t);
250132718Skan  switch (TREE_CODE (t))
251132718Skan    {
252132718Skan    case POINTER_TYPE:
253132718Skan      /* It is easier to handle C++ reference types here.  */
254132718Skan    case REFERENCE_TYPE:
255132718Skan      if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
256169689Skan	pp_c_pointer (pp, TREE_TYPE (t));
257132718Skan      if (TREE_CODE (t) == POINTER_TYPE)
258169689Skan	pp_c_star (pp);
259132718Skan      else
260169689Skan	pp_c_ampersand (pp);
261132718Skan      pp_c_type_qualifier_list (pp, t);
262132718Skan      break;
263132718Skan
264169689Skan      /* ??? This node is now in GENERIC and so shouldn't be here.  But
265169689Skan	 we'll fix that later.  */
266169689Skan    case DECL_EXPR:
267169689Skan      pp_declaration (pp, DECL_EXPR_DECL (t));
268169689Skan      pp_needs_newline (pp) = true;
269169689Skan      break;
270169689Skan
271132718Skan    default:
272132718Skan      pp_unsupported_tree (pp, t);
273132718Skan    }
274132718Skan}
275132718Skan
276132718Skan/* type-specifier:
277132718Skan      void
278132718Skan      char
279132718Skan      short
280132718Skan      int
281132718Skan      long
282132718Skan      float
283132718Skan      double
284132718Skan      signed
285132718Skan      unsigned
286132718Skan      _Bool                          -- C99
287132718Skan      _Complex                       -- C99
288132718Skan      _Imaginary                     -- C99
289132718Skan      struct-or-union-specifier
290132718Skan      enum-specifier
291132718Skan      typedef-name.
292132718Skan
293132718Skan  GNU extensions.
294132718Skan  simple-type-specifier:
295132718Skan      __complex__
296132718Skan      __vector__   */
297132718Skan
298132718Skanvoid
299132718Skanpp_c_type_specifier (c_pretty_printer *pp, tree t)
300132718Skan{
301117395Skan  const enum tree_code code = TREE_CODE (t);
302117395Skan  switch (code)
303117395Skan    {
304117395Skan    case ERROR_MARK:
305132718Skan      pp_c_identifier (pp, "<type-error>");
306117395Skan      break;
307117395Skan
308132718Skan    case IDENTIFIER_NODE:
309169689Skan      pp_c_tree_decl_identifier (pp, t);
310117395Skan      break;
311117395Skan
312117395Skan    case VOID_TYPE:
313117395Skan    case BOOLEAN_TYPE:
314117395Skan    case INTEGER_TYPE:
315117395Skan    case REAL_TYPE:
316132718Skan      if (TYPE_NAME (t))
317169689Skan	{
318169689Skan	  t = TYPE_NAME (t);
319169689Skan	  pp_c_type_specifier (pp, t);
320169689Skan	}
321132718Skan      else
322169689Skan	{
323169689Skan	  int prec = TYPE_PRECISION (t);
324169689Skan	  t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
325169689Skan	  if (TYPE_NAME (t))
326169689Skan	    {
327169689Skan	      pp_c_type_specifier (pp, t);
328169689Skan	      if (TYPE_PRECISION (t) != prec)
329169689Skan		{
330169689Skan		  pp_string (pp, ":");
331169689Skan		  pp_decimal_int (pp, prec);
332169689Skan		}
333169689Skan	    }
334169689Skan	  else
335169689Skan	    {
336169689Skan	      switch (code)
337169689Skan		{
338169689Skan		case INTEGER_TYPE:
339169689Skan		  pp_string (pp, (TYPE_UNSIGNED (t)
340169689Skan				  ? "<unnamed-unsigned:"
341169689Skan				  : "<unnamed-signed:"));
342169689Skan		  break;
343169689Skan		case REAL_TYPE:
344169689Skan		  pp_string (pp, "<unnamed-float:");
345169689Skan		  break;
346169689Skan		default:
347169689Skan		  gcc_unreachable ();
348169689Skan		}
349169689Skan	      pp_decimal_int (pp, prec);
350169689Skan	      pp_string (pp, ">");
351169689Skan	    }
352169689Skan	}
353117395Skan      break;
354117395Skan
355117395Skan    case TYPE_DECL:
356117395Skan      if (DECL_NAME (t))
357132718Skan	pp_id_expression (pp, t);
358117395Skan      else
359132718Skan	pp_c_identifier (pp, "<typedef-error>");
360117395Skan      break;
361117395Skan
362117395Skan    case UNION_TYPE:
363117395Skan    case RECORD_TYPE:
364117395Skan    case ENUMERAL_TYPE:
365117395Skan      if (code == UNION_TYPE)
366132718Skan	pp_c_identifier (pp, "union");
367117395Skan      else if (code == RECORD_TYPE)
368132718Skan	pp_c_identifier (pp, "struct");
369117395Skan      else if (code == ENUMERAL_TYPE)
370132718Skan	pp_c_identifier (pp, "enum");
371117395Skan      else
372132718Skan	pp_c_identifier (pp, "<tag-error>");
373132718Skan
374117395Skan      if (TYPE_NAME (t))
375132718Skan	pp_id_expression (pp, TYPE_NAME (t));
376117395Skan      else
377132718Skan	pp_c_identifier (pp, "<anonymous>");
378117395Skan      break;
379117395Skan
380117395Skan    default:
381132718Skan      pp_unsupported_tree (pp, t);
382132718Skan      break;
383117395Skan    }
384117395Skan}
385117395Skan
386132718Skan/* specifier-qualifier-list:
387132718Skan      type-specifier specifier-qualifier-list-opt
388132718Skan      type-qualifier specifier-qualifier-list-opt
389132718Skan
390132718Skan
391132718Skan  Implementation note:  Because of the non-linearities in array or
392132718Skan  function declarations, this routine prints not just the
393132718Skan  specifier-qualifier-list of such entities or types of such entities,
394132718Skan  but also the 'pointer' production part of their declarators.  The
395132718Skan  remaining part is done by pp_declarator or pp_c_abstract_declarator.  */
396132718Skan
397132718Skanvoid
398132718Skanpp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
399117395Skan{
400132718Skan  const enum tree_code code = TREE_CODE (t);
401132718Skan
402132718Skan  if (TREE_CODE (t) != POINTER_TYPE)
403132718Skan    pp_c_type_qualifier_list (pp, t);
404132718Skan  switch (code)
405132718Skan    {
406132718Skan    case REFERENCE_TYPE:
407132718Skan    case POINTER_TYPE:
408132718Skan      {
409169689Skan	/* Get the types-specifier of this type.  */
410169689Skan	tree pointee = strip_pointer_operator (TREE_TYPE (t));
411169689Skan	pp_c_specifier_qualifier_list (pp, pointee);
412169689Skan	if (TREE_CODE (pointee) == ARRAY_TYPE
413169689Skan	    || TREE_CODE (pointee) == FUNCTION_TYPE)
414169689Skan	  {
415169689Skan	    pp_c_whitespace (pp);
416169689Skan	    pp_c_left_paren (pp);
417169689Skan	  }
418169689Skan	else if (!c_dialect_cxx ())
419169689Skan	  pp_c_whitespace (pp);
420169689Skan	pp_ptr_operator (pp, t);
421132718Skan      }
422132718Skan      break;
423132718Skan
424132718Skan    case FUNCTION_TYPE:
425132718Skan    case ARRAY_TYPE:
426132718Skan      pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
427132718Skan      break;
428132718Skan
429132718Skan    case VECTOR_TYPE:
430132718Skan    case COMPLEX_TYPE:
431132718Skan      pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
432132718Skan      if (code == COMPLEX_TYPE)
433169689Skan	pp_c_identifier (pp, flag_isoc99 ? "_Complex" : "__complex__");
434132718Skan      else if (code == VECTOR_TYPE)
435169689Skan	pp_c_identifier (pp, "__vector__");
436132718Skan      break;
437132718Skan
438132718Skan    default:
439132718Skan      pp_simple_type_specifier (pp, t);
440132718Skan      break;
441132718Skan    }
442117395Skan}
443117395Skan
444132718Skan/* parameter-type-list:
445132718Skan      parameter-list
446132718Skan      parameter-list , ...
447132718Skan
448132718Skan   parameter-list:
449132718Skan      parameter-declaration
450132718Skan      parameter-list , parameter-declaration
451132718Skan
452132718Skan   parameter-declaration:
453132718Skan      declaration-specifiers declarator
454132718Skan      declaration-specifiers abstract-declarator(opt)   */
455132718Skan
456132718Skanvoid
457132718Skanpp_c_parameter_type_list (c_pretty_printer *pp, tree t)
458132718Skan{
459132718Skan  bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
460132718Skan  tree parms = want_parm_decl ? DECL_ARGUMENTS (t) :  TYPE_ARG_TYPES (t);
461132718Skan  pp_c_left_paren (pp);
462132718Skan  if (parms == void_list_node)
463132718Skan    pp_c_identifier (pp, "void");
464132718Skan  else
465132718Skan    {
466132718Skan      bool first = true;
467132718Skan      for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
468169689Skan	{
469169689Skan	  if (!first)
470169689Skan	    pp_separate_with (pp, ',');
471169689Skan	  first = false;
472169689Skan	  pp_declaration_specifiers
473169689Skan	    (pp, want_parm_decl ? parms : TREE_VALUE (parms));
474169689Skan	  if (want_parm_decl)
475169689Skan	    pp_declarator (pp, parms);
476169689Skan	  else
477169689Skan	    pp_abstract_declarator (pp, TREE_VALUE (parms));
478169689Skan	}
479132718Skan    }
480132718Skan  pp_c_right_paren (pp);
481132718Skan}
482132718Skan
483132718Skan/* abstract-declarator:
484132718Skan      pointer
485132718Skan      pointer(opt) direct-abstract-declarator  */
486132718Skan
487117395Skanstatic void
488132718Skanpp_c_abstract_declarator (c_pretty_printer *pp, tree t)
489117395Skan{
490132718Skan  if (TREE_CODE (t) == POINTER_TYPE)
491132718Skan    {
492132718Skan      if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
493169689Skan	  || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
494169689Skan	pp_c_right_paren (pp);
495132718Skan      t = TREE_TYPE (t);
496132718Skan    }
497132718Skan
498132718Skan  pp_direct_abstract_declarator (pp, t);
499117395Skan}
500117395Skan
501132718Skan/* direct-abstract-declarator:
502132718Skan      ( abstract-declarator )
503132718Skan      direct-abstract-declarator(opt) [ assignment-expression(opt) ]
504132718Skan      direct-abstract-declarator(opt) [ * ]
505132718Skan      direct-abstract-declarator(opt) ( parameter-type-list(opt) )  */
506117395Skan
507132718Skanvoid
508132718Skanpp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
509117395Skan{
510132718Skan  switch (TREE_CODE (t))
511132718Skan    {
512132718Skan    case POINTER_TYPE:
513132718Skan      pp_abstract_declarator (pp, t);
514132718Skan      break;
515169689Skan
516132718Skan    case FUNCTION_TYPE:
517132718Skan      pp_c_parameter_type_list (pp, t);
518132718Skan      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
519132718Skan      break;
520132718Skan
521132718Skan    case ARRAY_TYPE:
522132718Skan      pp_c_left_bracket (pp);
523169689Skan      if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
524169689Skan	{
525169689Skan	  tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t));
526169689Skan	  tree type = TREE_TYPE (maxval);
527169689Skan
528169689Skan	  if (host_integerp (maxval, 0))
529169689Skan	    pp_wide_integer (pp, tree_low_cst (maxval, 0) + 1);
530169689Skan	  else
531169689Skan	    pp_expression (pp, fold (build2 (PLUS_EXPR, type, maxval,
532169689Skan					     build_int_cst (type, 1))));
533169689Skan	}
534132718Skan      pp_c_right_bracket (pp);
535132718Skan      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
536132718Skan      break;
537132718Skan
538132718Skan    case IDENTIFIER_NODE:
539132718Skan    case VOID_TYPE:
540132718Skan    case BOOLEAN_TYPE:
541132718Skan    case INTEGER_TYPE:
542132718Skan    case REAL_TYPE:
543132718Skan    case ENUMERAL_TYPE:
544132718Skan    case RECORD_TYPE:
545132718Skan    case UNION_TYPE:
546132718Skan    case VECTOR_TYPE:
547132718Skan    case COMPLEX_TYPE:
548132718Skan    case TYPE_DECL:
549132718Skan      break;
550169689Skan
551132718Skan    default:
552132718Skan      pp_unsupported_tree (pp, t);
553132718Skan      break;
554132718Skan    }
555117395Skan}
556117395Skan
557132718Skan/* type-name:
558132718Skan      specifier-qualifier-list  abstract-declarator(opt)  */
559132718Skan
560132718Skanvoid
561132718Skanpp_c_type_id (c_pretty_printer *pp, tree t)
562117395Skan{
563132718Skan  pp_c_specifier_qualifier_list (pp, t);
564132718Skan  pp_abstract_declarator (pp, t);
565132718Skan}
566132718Skan
567132718Skan/* storage-class-specifier:
568132718Skan      typedef
569132718Skan      extern
570132718Skan      static
571132718Skan      auto
572132718Skan      register  */
573132718Skan
574132718Skanvoid
575132718Skanpp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
576132718Skan{
577117395Skan  if (TREE_CODE (t) == TYPE_DECL)
578117395Skan    pp_c_identifier (pp, "typedef");
579132718Skan  else if (DECL_P (t))
580132718Skan    {
581132718Skan      if (DECL_REGISTER (t))
582169689Skan	pp_c_identifier (pp, "register");
583132718Skan      else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
584169689Skan	pp_c_identifier (pp, "static");
585132718Skan    }
586117395Skan}
587117395Skan
588132718Skan/* function-specifier:
589132718Skan      inline   */
590132718Skan
591132718Skanvoid
592132718Skanpp_c_function_specifier (c_pretty_printer *pp, tree t)
593117395Skan{
594117395Skan  if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
595117395Skan    pp_c_identifier (pp, "inline");
596117395Skan}
597117395Skan
598132718Skan/* declaration-specifiers:
599132718Skan      storage-class-specifier declaration-specifiers(opt)
600132718Skan      type-specifier declaration-specifiers(opt)
601132718Skan      type-qualifier declaration-specifiers(opt)
602132718Skan      function-specifier declaration-specifiers(opt)  */
603132718Skan
604132718Skanvoid
605132718Skanpp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
606117395Skan{
607132718Skan  pp_storage_class_specifier (pp, t);
608132718Skan  pp_function_specifier (pp, t);
609132718Skan  pp_c_specifier_qualifier_list (pp, DECL_P (t) ?  TREE_TYPE (t) : t);
610117395Skan}
611117395Skan
612132718Skan/* direct-declarator
613132718Skan      identifier
614132718Skan      ( declarator )
615132718Skan      direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
616132718Skan      direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
617132718Skan      direct-declarator [ type-qualifier-list static assignment-expression ]
618132718Skan      direct-declarator [ type-qualifier-list * ]
619169689Skan      direct-declarator ( parameter-type-list )
620132718Skan      direct-declarator ( identifier-list(opt) )  */
621132718Skan
622132718Skanvoid
623132718Skanpp_c_direct_declarator (c_pretty_printer *pp, tree t)
624117395Skan{
625132718Skan  switch (TREE_CODE (t))
626132718Skan    {
627132718Skan    case VAR_DECL:
628132718Skan    case PARM_DECL:
629132718Skan    case TYPE_DECL:
630132718Skan    case FIELD_DECL:
631132718Skan    case LABEL_DECL:
632169689Skan      pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
633169689Skan      pp_c_tree_decl_identifier (pp, t);
634169689Skan      break;
635169689Skan
636132718Skan    case ARRAY_TYPE:
637132718Skan    case POINTER_TYPE:
638132718Skan      pp_abstract_declarator (pp, TREE_TYPE (t));
639132718Skan      break;
640117395Skan
641132718Skan    case FUNCTION_TYPE:
642132718Skan      pp_parameter_list (pp, t);
643132718Skan      pp_abstract_declarator (pp, TREE_TYPE (t));
644132718Skan      break;
645132718Skan
646132718Skan    case FUNCTION_DECL:
647132718Skan      pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
648169689Skan      pp_c_tree_decl_identifier (pp, t);
649132718Skan      if (pp_c_base (pp)->flags & pp_c_flag_abstract)
650169689Skan	pp_abstract_declarator (pp, TREE_TYPE (t));
651132718Skan      else
652169689Skan	{
653169689Skan	  pp_parameter_list (pp, t);
654169689Skan	  pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
655169689Skan	}
656132718Skan      break;
657132718Skan
658132718Skan    case INTEGER_TYPE:
659132718Skan    case REAL_TYPE:
660132718Skan    case ENUMERAL_TYPE:
661132718Skan    case UNION_TYPE:
662132718Skan    case RECORD_TYPE:
663132718Skan      break;
664132718Skan
665132718Skan    default:
666132718Skan      pp_unsupported_tree (pp, t);
667132718Skan      break;
668132718Skan    }
669117395Skan}
670117395Skan
671132718Skan
672132718Skan/* declarator:
673132718Skan      pointer(opt)  direct-declarator   */
674132718Skan
675132718Skanvoid
676132718Skanpp_c_declarator (c_pretty_printer *pp, tree t)
677117395Skan{
678132718Skan  switch (TREE_CODE (t))
679117395Skan    {
680132718Skan    case INTEGER_TYPE:
681132718Skan    case REAL_TYPE:
682132718Skan    case ENUMERAL_TYPE:
683132718Skan    case UNION_TYPE:
684132718Skan    case RECORD_TYPE:
685132718Skan      break;
686132718Skan
687132718Skan    case VAR_DECL:
688132718Skan    case PARM_DECL:
689132718Skan    case FIELD_DECL:
690132718Skan    case ARRAY_TYPE:
691132718Skan    case FUNCTION_TYPE:
692132718Skan    case FUNCTION_DECL:
693132718Skan    case TYPE_DECL:
694132718Skan      pp_direct_declarator (pp, t);
695132718Skan    break;
696132718Skan
697169689Skan
698132718Skan    default:
699132718Skan      pp_unsupported_tree (pp, t);
700132718Skan      break;
701117395Skan    }
702117395Skan}
703117395Skan
704132718Skan/* declaration:
705132718Skan      declaration-specifiers init-declarator-list(opt) ;  */
706132718Skan
707117395Skanvoid
708132718Skanpp_c_declaration (c_pretty_printer *pp, tree t)
709117395Skan{
710117395Skan  pp_declaration_specifiers (pp, t);
711117395Skan  pp_c_init_declarator (pp, t);
712117395Skan}
713117395Skan
714132718Skan/* Pretty-print ATTRIBUTES using GNU C extension syntax.  */
715117395Skan
716132718Skanvoid
717132718Skanpp_c_attributes (c_pretty_printer *pp, tree attributes)
718117395Skan{
719117395Skan  if (attributes == NULL_TREE)
720117395Skan    return;
721132718Skan
722117395Skan  pp_c_identifier (pp, "__attribute__");
723117395Skan  pp_c_left_paren (pp);
724132718Skan  pp_c_left_paren (pp);
725117395Skan  for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
726117395Skan    {
727117395Skan      pp_tree_identifier (pp, TREE_PURPOSE (attributes));
728117395Skan      if (TREE_VALUE (attributes))
729169689Skan	pp_c_call_argument_list (pp, TREE_VALUE (attributes));
730132718Skan
731117395Skan      if (TREE_CHAIN (attributes))
732117395Skan	pp_separate_with (pp, ',');
733117395Skan    }
734117395Skan  pp_c_right_paren (pp);
735117395Skan  pp_c_right_paren (pp);
736117395Skan}
737117395Skan
738132718Skan/* function-definition:
739132718Skan      declaration-specifiers declarator compound-statement  */
740132718Skan
741132718Skanvoid
742132718Skanpp_c_function_definition (c_pretty_printer *pp, tree t)
743132718Skan{
744132718Skan  pp_declaration_specifiers (pp, t);
745132718Skan  pp_declarator (pp, t);
746132718Skan  pp_needs_newline (pp) = true;
747132718Skan  pp_statement (pp, DECL_SAVED_TREE (t));
748132718Skan  pp_newline (pp);
749132718Skan  pp_flush (pp);
750132718Skan}
751132718Skan
752117395Skan
753117395Skan/* Expressions.  */
754117395Skan
755169689Skan/* Print out a c-char.  This is called solely for characters which are
756169689Skan   in the *target* execution character set.  We ought to convert them
757169689Skan   back to the *host* execution character set before printing, but we
758169689Skan   have no way to do this at present.  A decent compromise is to print
759169689Skan   all characters as if they were in the host execution character set,
760169689Skan   and not attempt to recover any named escape characters, but render
761169689Skan   all unprintables as octal escapes.  If the host and target character
762169689Skan   sets are the same, this produces relatively readable output.  If they
763169689Skan   are not the same, strings may appear as gibberish, but that's okay
764169689Skan   (in fact, it may well be what the reader wants, e.g. if they are looking
765169689Skan   to see if conversion to the target character set happened correctly).
766132718Skan
767169689Skan   A special case: we need to prefix \, ", and ' with backslashes.  It is
768169689Skan   correct to do so for the *host*'s \, ", and ', because the rest of the
769169689Skan   file appears in the host character set.  */
770169689Skan
771117395Skanstatic void
772132718Skanpp_c_char (c_pretty_printer *pp, int c)
773117395Skan{
774169689Skan  if (ISPRINT (c))
775117395Skan    {
776169689Skan      switch (c)
777169689Skan	{
778169689Skan	case '\\': pp_string (pp, "\\\\"); break;
779169689Skan	case '\'': pp_string (pp, "\\\'"); break;
780169689Skan	case '\"': pp_string (pp, "\\\""); break;
781169689Skan	default:   pp_character (pp, c);
782169689Skan	}
783117395Skan    }
784169689Skan  else
785169689Skan    pp_scalar (pp, "\\%03o", (unsigned) c);
786117395Skan}
787117395Skan
788117395Skan/* Print out a STRING literal.  */
789132718Skan
790132718Skanvoid
791132718Skanpp_c_string_literal (c_pretty_printer *pp, tree s)
792117395Skan{
793117395Skan  const char *p = TREE_STRING_POINTER (s);
794117395Skan  int n = TREE_STRING_LENGTH (s) - 1;
795117395Skan  int i;
796132718Skan  pp_doublequote (pp);
797117395Skan  for (i = 0; i < n; ++i)
798132718Skan    pp_c_char (pp, p[i]);
799132718Skan  pp_doublequote (pp);
800117395Skan}
801117395Skan
802169689Skan/* Pretty-print an INTEGER literal.  */
803169689Skan
804132718Skanstatic void
805132718Skanpp_c_integer_constant (c_pretty_printer *pp, tree i)
806132718Skan{
807132718Skan  tree type = TREE_TYPE (i);
808132718Skan
809132718Skan  if (TREE_INT_CST_HIGH (i) == 0)
810132718Skan    pp_wide_integer (pp, TREE_INT_CST_LOW (i));
811132718Skan  else
812132718Skan    {
813132718Skan      if (tree_int_cst_sgn (i) < 0)
814169689Skan	{
815169689Skan	  pp_character (pp, '-');
816169689Skan	  i = build_int_cst_wide (NULL_TREE,
817169689Skan				  -TREE_INT_CST_LOW (i),
818169689Skan				  ~TREE_INT_CST_HIGH (i)
819169689Skan				  + !TREE_INT_CST_LOW (i));
820169689Skan	}
821132718Skan      sprintf (pp_buffer (pp)->digit_buffer,
822169689Skan	       HOST_WIDE_INT_PRINT_DOUBLE_HEX,
823169689Skan	       TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i));
824132718Skan      pp_string (pp, pp_buffer (pp)->digit_buffer);
825132718Skan    }
826169689Skan  if (TYPE_UNSIGNED (type))
827132718Skan    pp_character (pp, 'u');
828132718Skan  if (type == long_integer_type_node || type == long_unsigned_type_node)
829132718Skan    pp_character (pp, 'l');
830132718Skan  else if (type == long_long_integer_type_node
831169689Skan	   || type == long_long_unsigned_type_node)
832132718Skan    pp_string (pp, "ll");
833132718Skan}
834132718Skan
835117395Skan/* Print out a CHARACTER literal.  */
836132718Skan
837132718Skanstatic void
838132718Skanpp_c_character_constant (c_pretty_printer *pp, tree c)
839117395Skan{
840132718Skan  tree type = TREE_TYPE (c);
841132718Skan  if (type == wchar_type_node)
842169689Skan    pp_character (pp, 'L');
843132718Skan  pp_quote (pp);
844169689Skan  if (host_integerp (c, TYPE_UNSIGNED (type)))
845169689Skan    pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type)));
846132718Skan  else
847132718Skan    pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c));
848132718Skan  pp_quote (pp);
849117395Skan}
850117395Skan
851117395Skan/* Print out a BOOLEAN literal.  */
852132718Skan
853132718Skanstatic void
854132718Skanpp_c_bool_constant (c_pretty_printer *pp, tree b)
855117395Skan{
856132718Skan  if (b == boolean_false_node)
857117395Skan    {
858132718Skan      if (c_dialect_cxx ())
859132718Skan	pp_c_identifier (pp, "false");
860132718Skan      else if (flag_isoc99)
861132718Skan	pp_c_identifier (pp, "_False");
862117395Skan      else
863132718Skan	pp_unsupported_tree (pp, b);
864117395Skan    }
865117395Skan  else if (b == boolean_true_node)
866117395Skan    {
867132718Skan      if (c_dialect_cxx ())
868132718Skan	pp_c_identifier (pp, "true");
869132718Skan      else if (flag_isoc99)
870132718Skan	pp_c_identifier (pp, "_True");
871117395Skan      else
872132718Skan	pp_unsupported_tree (pp, b);
873117395Skan    }
874132718Skan  else if (TREE_CODE (b) == INTEGER_CST)
875132718Skan    pp_c_integer_constant (pp, b);
876117395Skan  else
877132718Skan    pp_unsupported_tree (pp, b);
878117395Skan}
879117395Skan
880132718Skan/* Attempt to print out an ENUMERATOR.  Return true on success.  Else return
881117395Skan   false; that means the value was obtained by a cast, in which case
882117395Skan   print out the type-id part of the cast-expression -- the casted value
883117395Skan   is then printed by pp_c_integer_literal.  */
884132718Skan
885117395Skanstatic bool
886132718Skanpp_c_enumeration_constant (c_pretty_printer *pp, tree e)
887117395Skan{
888132718Skan  bool value_is_named = true;
889117395Skan  tree type = TREE_TYPE (e);
890117395Skan  tree value;
891117395Skan
892117395Skan  /* Find the name of this constant.  */
893132718Skan  for (value = TYPE_VALUES (type);
894117395Skan       value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
895117395Skan       value = TREE_CHAIN (value))
896117395Skan    ;
897132718Skan
898117395Skan  if (value != NULL_TREE)
899132718Skan    pp_id_expression (pp, TREE_PURPOSE (value));
900117395Skan  else
901117395Skan    {
902117395Skan      /* Value must have been cast.  */
903132718Skan      pp_c_type_cast (pp, type);
904132718Skan      value_is_named = false;
905117395Skan    }
906132718Skan
907132718Skan  return value_is_named;
908117395Skan}
909117395Skan
910132718Skan/* Print out a REAL value as a decimal-floating-constant.  */
911132718Skan
912117395Skanstatic void
913132718Skanpp_c_floating_constant (c_pretty_printer *pp, tree r)
914117395Skan{
915132718Skan  real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
916132718Skan		   sizeof (pp_buffer (pp)->digit_buffer), 0, 1);
917132718Skan  pp_string (pp, pp_buffer(pp)->digit_buffer);
918132718Skan  if (TREE_TYPE (r) == float_type_node)
919132718Skan    pp_character (pp, 'f');
920132718Skan  else if (TREE_TYPE (r) == long_double_type_node)
921132718Skan    pp_character (pp, 'l');
922169689Skan  else if (TREE_TYPE (r) == dfloat128_type_node)
923169689Skan    pp_string (pp, "dl");
924169689Skan  else if (TREE_TYPE (r) == dfloat64_type_node)
925169689Skan    pp_string (pp, "dd");
926169689Skan  else if (TREE_TYPE (r) == dfloat32_type_node)
927169689Skan    pp_string (pp, "df");
928132718Skan}
929132718Skan
930132718Skan/* Pretty-print a compound literal expression.  GNU extensions include
931169689Skan   vector constants.  */
932132718Skan
933132718Skanstatic void
934132718Skanpp_c_compound_literal (c_pretty_printer *pp, tree e)
935132718Skan{
936169689Skan  tree type = TREE_TYPE (e);
937132718Skan  pp_c_type_cast (pp, type);
938132718Skan
939132718Skan  switch (TREE_CODE (type))
940117395Skan    {
941132718Skan    case RECORD_TYPE:
942132718Skan    case UNION_TYPE:
943132718Skan    case ARRAY_TYPE:
944132718Skan    case VECTOR_TYPE:
945132718Skan    case COMPLEX_TYPE:
946132718Skan      pp_c_brace_enclosed_initializer_list (pp, e);
947132718Skan      break;
948117395Skan
949132718Skan    default:
950132718Skan      pp_unsupported_tree (pp, e);
951132718Skan      break;
952117395Skan    }
953117395Skan}
954117395Skan
955132718Skan/* constant:
956132718Skan      integer-constant
957132718Skan      floating-constant
958132718Skan      enumeration-constant
959132718Skan      character-constant   */
960117395Skan
961117395Skanvoid
962132718Skanpp_c_constant (c_pretty_printer *pp, tree e)
963117395Skan{
964132718Skan  const enum tree_code code = TREE_CODE (e);
965132718Skan
966132718Skan  switch (code)
967117395Skan    {
968117395Skan    case INTEGER_CST:
969132718Skan      {
970169689Skan	tree type = TREE_TYPE (e);
971169689Skan	if (type == boolean_type_node)
972169689Skan	  pp_c_bool_constant (pp, e);
973169689Skan	else if (type == char_type_node)
974169689Skan	  pp_c_character_constant (pp, e);
975169689Skan	else if (TREE_CODE (type) == ENUMERAL_TYPE
976169689Skan		 && pp_c_enumeration_constant (pp, e))
977169689Skan	  ;
978169689Skan	else
979169689Skan	  pp_c_integer_constant (pp, e);
980132718Skan      }
981117395Skan      break;
982132718Skan
983117395Skan    case REAL_CST:
984132718Skan      pp_c_floating_constant (pp, e);
985117395Skan      break;
986132718Skan
987117395Skan    case STRING_CST:
988132718Skan      pp_c_string_literal (pp, e);
989132718Skan      break;
990117395Skan
991117395Skan    default:
992132718Skan      pp_unsupported_tree (pp, e);
993117395Skan      break;
994117395Skan    }
995117395Skan}
996117395Skan
997169689Skan/* Pretty-print an IDENTIFIER_NODE, preceded by whitespace is necessary.  */
998169689Skan
999132718Skanvoid
1000132718Skanpp_c_identifier (c_pretty_printer *pp, const char *id)
1001117395Skan{
1002169689Skan  pp_c_maybe_whitespace (pp);
1003169689Skan  pp_identifier (pp, id);
1004132718Skan  pp_base (pp)->padding = pp_before;
1005132718Skan}
1006132718Skan
1007132718Skan/* Pretty-print a C primary-expression.
1008132718Skan   primary-expression:
1009132718Skan      identifier
1010132718Skan      constant
1011132718Skan      string-literal
1012132718Skan      ( expression )   */
1013132718Skan
1014132718Skanvoid
1015132718Skanpp_c_primary_expression (c_pretty_printer *pp, tree e)
1016132718Skan{
1017117395Skan  switch (TREE_CODE (e))
1018117395Skan    {
1019117395Skan    case VAR_DECL:
1020117395Skan    case PARM_DECL:
1021117395Skan    case FIELD_DECL:
1022117395Skan    case CONST_DECL:
1023117395Skan    case FUNCTION_DECL:
1024117395Skan    case LABEL_DECL:
1025169689Skan      pp_c_tree_decl_identifier (pp, e);
1026169689Skan      break;
1027169689Skan
1028117395Skan    case IDENTIFIER_NODE:
1029132718Skan      pp_c_tree_identifier (pp, e);
1030117395Skan      break;
1031117395Skan
1032117395Skan    case ERROR_MARK:
1033132718Skan      pp_c_identifier (pp, "<erroneous-expression>");
1034117395Skan      break;
1035132718Skan
1036117395Skan    case RESULT_DECL:
1037132718Skan      pp_c_identifier (pp, "<return-value>");
1038117395Skan      break;
1039117395Skan
1040117395Skan    case INTEGER_CST:
1041117395Skan    case REAL_CST:
1042117395Skan    case STRING_CST:
1043132718Skan      pp_c_constant (pp, e);
1044117395Skan      break;
1045117395Skan
1046169689Skan    case TARGET_EXPR:
1047169689Skan      pp_c_identifier (pp, "__builtin_memcpy");
1048132718Skan      pp_c_left_paren (pp);
1049169689Skan      pp_ampersand (pp);
1050169689Skan      pp_primary_expression (pp, TREE_OPERAND (e, 0));
1051169689Skan      pp_separate_with (pp, ',');
1052169689Skan      pp_ampersand (pp);
1053169689Skan      pp_initializer (pp, TREE_OPERAND (e, 1));
1054169689Skan      if (TREE_OPERAND (e, 2))
1055169689Skan	{
1056169689Skan	  pp_separate_with (pp, ',');
1057169689Skan	  pp_c_expression (pp, TREE_OPERAND (e, 2));
1058169689Skan	}
1059132718Skan      pp_c_right_paren (pp);
1060117395Skan      break;
1061117395Skan
1062117395Skan    default:
1063132718Skan      /* FIXME:  Make sure we won't get into an infinie loop.  */
1064132718Skan      pp_c_left_paren (pp);
1065132718Skan      pp_expression (pp, e);
1066132718Skan      pp_c_right_paren (pp);
1067117395Skan      break;
1068117395Skan    }
1069117395Skan}
1070117395Skan
1071132718Skan/* Print out a C initializer -- also support C compound-literals.
1072132718Skan   initializer:
1073132718Skan      assignment-expression:
1074132718Skan      { initializer-list }
1075132718Skan      { initializer-list , }   */
1076132718Skan
1077132718Skanstatic void
1078132718Skanpp_c_initializer (c_pretty_printer *pp, tree e)
1079117395Skan{
1080117395Skan  if (TREE_CODE (e) == CONSTRUCTOR)
1081169689Skan    pp_c_brace_enclosed_initializer_list (pp, e);
1082117395Skan  else
1083132718Skan    pp_expression (pp, e);
1084117395Skan}
1085117395Skan
1086132718Skan/* init-declarator:
1087132718Skan      declarator:
1088132718Skan      declarator = initializer   */
1089132718Skan
1090132718Skanvoid
1091132718Skanpp_c_init_declarator (c_pretty_printer *pp, tree t)
1092132718Skan{
1093132718Skan  pp_declarator (pp, t);
1094169689Skan  /* We don't want to output function definitions here.  There are handled
1095169689Skan     elsewhere (and the syntactic form is bogus anyway).  */
1096169689Skan  if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
1097132718Skan    {
1098132718Skan      tree init = DECL_INITIAL (t);
1099132718Skan      /* This C++ bit is handled here because it is easier to do so.
1100169689Skan	 In templates, the C++ parser builds a TREE_LIST for a
1101169689Skan	 direct-initialization; the TREE_PURPOSE is the variable to
1102169689Skan	 initialize and the TREE_VALUE is the initializer.  */
1103132718Skan      if (TREE_CODE (init) == TREE_LIST)
1104169689Skan	{
1105169689Skan	  pp_c_left_paren (pp);
1106169689Skan	  pp_expression (pp, TREE_VALUE (init));
1107169689Skan	  pp_right_paren (pp);
1108169689Skan	}
1109132718Skan      else
1110169689Skan	{
1111169689Skan	  pp_space (pp);
1112169689Skan	  pp_equal (pp);
1113169689Skan	  pp_space (pp);
1114169689Skan	  pp_c_initializer (pp, init);
1115169689Skan	}
1116132718Skan    }
1117132718Skan}
1118132718Skan
1119132718Skan/* initializer-list:
1120132718Skan      designation(opt) initializer
1121132718Skan      initializer-list , designation(opt) initializer
1122132718Skan
1123132718Skan   designation:
1124132718Skan      designator-list =
1125132718Skan
1126132718Skan   designator-list:
1127132718Skan      designator
1128132718Skan      designator-list designator
1129132718Skan
1130132718Skan   designator:
1131132718Skan      [ constant-expression ]
1132132718Skan      identifier   */
1133132718Skan
1134117395Skanstatic void
1135132718Skanpp_c_initializer_list (c_pretty_printer *pp, tree e)
1136117395Skan{
1137117395Skan  tree type = TREE_TYPE (e);
1138117395Skan  const enum tree_code code = TREE_CODE (type);
1139117395Skan
1140132718Skan  switch (code)
1141117395Skan    {
1142132718Skan    case RECORD_TYPE:
1143132718Skan    case UNION_TYPE:
1144132718Skan    case ARRAY_TYPE:
1145132718Skan      {
1146169689Skan	tree init = TREE_OPERAND (e, 0);
1147169689Skan	for (; init != NULL_TREE; init = TREE_CHAIN (init))
1148169689Skan	  {
1149169689Skan	    if (code == RECORD_TYPE || code == UNION_TYPE)
1150169689Skan	      {
1151169689Skan		pp_c_dot (pp);
1152169689Skan		pp_c_primary_expression (pp, TREE_PURPOSE (init));
1153169689Skan	      }
1154169689Skan	    else
1155169689Skan	      {
1156169689Skan		pp_c_left_bracket (pp);
1157169689Skan		if (TREE_PURPOSE (init))
1158169689Skan		  pp_c_constant (pp, TREE_PURPOSE (init));
1159169689Skan		pp_c_right_bracket (pp);
1160169689Skan	      }
1161169689Skan	    pp_c_whitespace (pp);
1162169689Skan	    pp_equal (pp);
1163169689Skan	    pp_c_whitespace (pp);
1164169689Skan	    pp_initializer (pp, TREE_VALUE (init));
1165169689Skan	    if (TREE_CHAIN (init))
1166169689Skan	      pp_separate_with (pp, ',');
1167169689Skan	  }
1168132718Skan      }
1169169689Skan      return;
1170132718Skan
1171132718Skan    case VECTOR_TYPE:
1172169689Skan      if (TREE_CODE (e) == VECTOR_CST)
1173169689Skan	pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
1174169689Skan      else if (TREE_CODE (e) == CONSTRUCTOR)
1175169689Skan	pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1176169689Skan      else
1177169689Skan	break;
1178169689Skan      return;
1179132718Skan
1180132718Skan    case COMPLEX_TYPE:
1181169689Skan      if (TREE_CODE (e) == CONSTRUCTOR)
1182169689Skan	pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1183169689Skan      else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
1184169689Skan	{
1185169689Skan	  const bool cst = TREE_CODE (e) == COMPLEX_CST;
1186169689Skan	  pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
1187169689Skan	  pp_separate_with (pp, ',');
1188169689Skan	  pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
1189169689Skan	}
1190169689Skan      else
1191169689Skan	break;
1192169689Skan      return;
1193132718Skan
1194132718Skan    default:
1195132718Skan      break;
1196117395Skan    }
1197169689Skan
1198169689Skan  pp_unsupported_tree (pp, type);
1199117395Skan}
1200117395Skan
1201132718Skan/* Pretty-print a brace-enclosed initializer-list.  */
1202132718Skan
1203132718Skanstatic void
1204132718Skanpp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
1205132718Skan{
1206132718Skan  pp_c_left_brace (pp);
1207132718Skan  pp_c_initializer_list (pp, l);
1208132718Skan  pp_c_right_brace (pp);
1209132718Skan}
1210132718Skan
1211132718Skan
1212132718Skan/*  This is a convenient function, used to bridge gap between C and C++
1213132718Skan    grammars.
1214132718Skan
1215132718Skan    id-expression:
1216132718Skan       identifier  */
1217132718Skan
1218117395Skanvoid
1219132718Skanpp_c_id_expression (c_pretty_printer *pp, tree t)
1220117395Skan{
1221132718Skan  switch (TREE_CODE (t))
1222132718Skan    {
1223132718Skan    case VAR_DECL:
1224132718Skan    case PARM_DECL:
1225132718Skan    case CONST_DECL:
1226132718Skan    case TYPE_DECL:
1227132718Skan    case FUNCTION_DECL:
1228132718Skan    case FIELD_DECL:
1229132718Skan    case LABEL_DECL:
1230169689Skan      pp_c_tree_decl_identifier (pp, t);
1231169689Skan      break;
1232169689Skan
1233132718Skan    case IDENTIFIER_NODE:
1234132718Skan      pp_c_tree_identifier (pp, t);
1235132718Skan      break;
1236132718Skan
1237132718Skan    default:
1238132718Skan      pp_unsupported_tree (pp, t);
1239132718Skan      break;
1240132718Skan    }
1241132718Skan}
1242132718Skan
1243132718Skan/* postfix-expression:
1244132718Skan      primary-expression
1245132718Skan      postfix-expression [ expression ]
1246132718Skan      postfix-expression ( argument-expression-list(opt) )
1247132718Skan      postfix-expression . identifier
1248132718Skan      postfix-expression -> identifier
1249132718Skan      postfix-expression ++
1250132718Skan      postfix-expression --
1251132718Skan      ( type-name ) { initializer-list }
1252132718Skan      ( type-name ) { initializer-list , }  */
1253132718Skan
1254132718Skanvoid
1255132718Skanpp_c_postfix_expression (c_pretty_printer *pp, tree e)
1256132718Skan{
1257117395Skan  enum tree_code code = TREE_CODE (e);
1258117395Skan  switch (code)
1259117395Skan    {
1260117395Skan    case POSTINCREMENT_EXPR:
1261117395Skan    case POSTDECREMENT_EXPR:
1262132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1263132718Skan      pp_identifier (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
1264117395Skan      break;
1265132718Skan
1266117395Skan    case ARRAY_REF:
1267132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1268132718Skan      pp_c_left_bracket (pp);
1269132718Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1270132718Skan      pp_c_right_bracket (pp);
1271117395Skan      break;
1272117395Skan
1273117395Skan    case CALL_EXPR:
1274132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
1275132718Skan      pp_c_call_argument_list (pp, TREE_OPERAND (e, 1));
1276117395Skan      break;
1277117395Skan
1278169689Skan    case UNORDERED_EXPR:
1279169689Skan      pp_c_identifier (pp, flag_isoc99
1280169689Skan			   ? "isunordered"
1281169689Skan			   : "__builtin_isunordered");
1282169689Skan      goto two_args_fun;
1283169689Skan
1284169689Skan    case ORDERED_EXPR:
1285169689Skan      pp_c_identifier (pp, flag_isoc99
1286169689Skan			   ? "!isunordered"
1287169689Skan			   : "!__builtin_isunordered");
1288169689Skan      goto two_args_fun;
1289169689Skan
1290169689Skan    case UNLT_EXPR:
1291169689Skan      pp_c_identifier (pp, flag_isoc99
1292169689Skan			   ? "!isgreaterequal"
1293169689Skan			   : "!__builtin_isgreaterequal");
1294169689Skan      goto two_args_fun;
1295169689Skan
1296169689Skan    case UNLE_EXPR:
1297169689Skan      pp_c_identifier (pp, flag_isoc99
1298169689Skan			   ? "!isgreater"
1299169689Skan			   : "!__builtin_isgreater");
1300169689Skan      goto two_args_fun;
1301169689Skan
1302169689Skan    case UNGT_EXPR:
1303169689Skan      pp_c_identifier (pp, flag_isoc99
1304169689Skan			   ? "!islessequal"
1305169689Skan			   : "!__builtin_islessequal");
1306169689Skan      goto two_args_fun;
1307169689Skan
1308169689Skan    case UNGE_EXPR:
1309169689Skan      pp_c_identifier (pp, flag_isoc99
1310169689Skan			   ? "!isless"
1311169689Skan			   : "!__builtin_isless");
1312169689Skan      goto two_args_fun;
1313169689Skan
1314169689Skan    case UNEQ_EXPR:
1315169689Skan      pp_c_identifier (pp, flag_isoc99
1316169689Skan			   ? "!islessgreater"
1317169689Skan			   : "!__builtin_islessgreater");
1318169689Skan      goto two_args_fun;
1319169689Skan
1320169689Skan    case LTGT_EXPR:
1321169689Skan      pp_c_identifier (pp, flag_isoc99
1322169689Skan			   ? "islessgreater"
1323169689Skan			   : "__builtin_islessgreater");
1324169689Skan      goto two_args_fun;
1325169689Skan
1326169689Skan    two_args_fun:
1327169689Skan      pp_c_left_paren (pp);
1328169689Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1329169689Skan      pp_separate_with (pp, ',');
1330169689Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1331169689Skan      pp_c_right_paren (pp);
1332169689Skan      break;
1333169689Skan
1334117395Skan    case ABS_EXPR:
1335132718Skan      pp_c_identifier (pp, "__builtin_abs");
1336132718Skan      pp_c_left_paren (pp);
1337132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1338132718Skan      pp_c_right_paren (pp);
1339117395Skan      break;
1340117395Skan
1341117395Skan    case COMPONENT_REF:
1342117395Skan      {
1343117395Skan	tree object = TREE_OPERAND (e, 0);
1344117395Skan	if (TREE_CODE (object) == INDIRECT_REF)
1345117395Skan	  {
1346132718Skan	    pp_postfix_expression (pp, TREE_OPERAND (object, 0));
1347132718Skan	    pp_c_arrow (pp);
1348117395Skan	  }
1349117395Skan	else
1350117395Skan	  {
1351132718Skan	    pp_postfix_expression (pp, object);
1352132718Skan	    pp_c_dot (pp);
1353117395Skan	  }
1354132718Skan	pp_expression (pp, TREE_OPERAND (e, 1));
1355117395Skan      }
1356117395Skan      break;
1357117395Skan
1358117395Skan    case COMPLEX_CST:
1359117395Skan    case VECTOR_CST:
1360117395Skan    case COMPLEX_EXPR:
1361132718Skan      pp_c_compound_literal (pp, e);
1362117395Skan      break;
1363117395Skan
1364117395Skan    case COMPOUND_LITERAL_EXPR:
1365132718Skan      e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
1366117395Skan      /* Fall through.  */
1367117395Skan    case CONSTRUCTOR:
1368132718Skan      pp_initializer (pp, e);
1369117395Skan      break;
1370117395Skan
1371117395Skan    case VA_ARG_EXPR:
1372132718Skan      pp_c_identifier (pp, "__builtin_va_arg");
1373132718Skan      pp_c_left_paren (pp);
1374132718Skan      pp_assignment_expression (pp, TREE_OPERAND (e, 0));
1375132718Skan      pp_separate_with (pp, ',');
1376132718Skan      pp_type_id (pp, TREE_TYPE (e));
1377132718Skan      pp_c_right_paren (pp);
1378117395Skan      break;
1379117395Skan
1380132718Skan    case ADDR_EXPR:
1381132718Skan      if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
1382169689Skan	{
1383169689Skan	  pp_c_id_expression (pp, TREE_OPERAND (e, 0));
1384169689Skan	  break;
1385169689Skan	}
1386132718Skan      /* else fall through.  */
1387132718Skan
1388117395Skan    default:
1389132718Skan      pp_primary_expression (pp, e);
1390117395Skan      break;
1391117395Skan    }
1392117395Skan}
1393117395Skan
1394132718Skan/* Print out an expression-list; E is expected to be a TREE_LIST.  */
1395132718Skan
1396117395Skanvoid
1397132718Skanpp_c_expression_list (c_pretty_printer *pp, tree e)
1398117395Skan{
1399117395Skan  for (; e != NULL_TREE; e = TREE_CHAIN (e))
1400117395Skan    {
1401132718Skan      pp_expression (pp, TREE_VALUE (e));
1402117395Skan      if (TREE_CHAIN (e))
1403132718Skan	pp_separate_with (pp, ',');
1404117395Skan    }
1405117395Skan}
1406117395Skan
1407169689Skan/* Print out V, which contains the elements of a constructor.  */
1408169689Skan
1409169689Skanvoid
1410169689Skanpp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v)
1411169689Skan{
1412169689Skan  unsigned HOST_WIDE_INT ix;
1413169689Skan  tree value;
1414169689Skan
1415169689Skan  FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
1416169689Skan    {
1417169689Skan      pp_expression (pp, value);
1418169689Skan      if (ix != VEC_length (constructor_elt, v) - 1)
1419169689Skan	pp_separate_with (pp, ',');
1420169689Skan    }
1421169689Skan}
1422169689Skan
1423132718Skan/* Print out an expression-list in parens, as in a function call.  */
1424132718Skan
1425132718Skanvoid
1426132718Skanpp_c_call_argument_list (c_pretty_printer *pp, tree t)
1427117395Skan{
1428132718Skan  pp_c_left_paren (pp);
1429132718Skan  if (t && TREE_CODE (t) == TREE_LIST)
1430132718Skan    pp_c_expression_list (pp, t);
1431132718Skan  pp_c_right_paren (pp);
1432132718Skan}
1433132718Skan
1434132718Skan/* unary-expression:
1435132718Skan      postfix-expression
1436132718Skan      ++ cast-expression
1437132718Skan      -- cast-expression
1438132718Skan      unary-operator cast-expression
1439132718Skan      sizeof unary-expression
1440132718Skan      sizeof ( type-id )
1441132718Skan
1442132718Skan  unary-operator: one of
1443132718Skan      * &  + - ! ~
1444169689Skan
1445132718Skan   GNU extensions.
1446132718Skan   unary-expression:
1447132718Skan      __alignof__ unary-expression
1448132718Skan      __alignof__ ( type-id )
1449132718Skan      __real__ unary-expression
1450132718Skan      __imag__ unary-expression  */
1451132718Skan
1452132718Skanvoid
1453132718Skanpp_c_unary_expression (c_pretty_printer *pp, tree e)
1454132718Skan{
1455117395Skan  enum tree_code code = TREE_CODE (e);
1456117395Skan  switch (code)
1457117395Skan    {
1458117395Skan    case PREINCREMENT_EXPR:
1459117395Skan    case PREDECREMENT_EXPR:
1460132718Skan      pp_identifier (pp, code == PREINCREMENT_EXPR ? "++" : "--");
1461132718Skan      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
1462117395Skan      break;
1463132718Skan
1464117395Skan    case ADDR_EXPR:
1465117395Skan    case INDIRECT_REF:
1466117395Skan    case NEGATE_EXPR:
1467117395Skan    case BIT_NOT_EXPR:
1468117395Skan    case TRUTH_NOT_EXPR:
1469117395Skan    case CONJ_EXPR:
1470132718Skan      /* String literal are used by address.  */
1471132718Skan      if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
1472132718Skan	pp_ampersand (pp);
1473117395Skan      else if (code == INDIRECT_REF)
1474132718Skan	pp_c_star (pp);
1475117395Skan      else if (code == NEGATE_EXPR)
1476132718Skan	pp_minus (pp);
1477117395Skan      else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
1478132718Skan	pp_complement (pp);
1479117395Skan      else if (code == TRUTH_NOT_EXPR)
1480132718Skan	pp_exclamation (pp);
1481132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
1482117395Skan      break;
1483117395Skan
1484117395Skan    case REALPART_EXPR:
1485117395Skan    case IMAGPART_EXPR:
1486132718Skan      pp_c_identifier (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
1487132718Skan      pp_c_whitespace (pp);
1488132718Skan      pp_unary_expression (pp, TREE_OPERAND (e, 0));
1489117395Skan      break;
1490132718Skan
1491117395Skan    default:
1492132718Skan      pp_postfix_expression (pp, e);
1493117395Skan      break;
1494117395Skan    }
1495117395Skan}
1496117395Skan
1497132718Skan/* cast-expression:
1498132718Skan      unary-expression
1499132718Skan      ( type-name ) cast-expression  */
1500132718Skan
1501117395Skanvoid
1502132718Skanpp_c_cast_expression (c_pretty_printer *pp, tree e)
1503117395Skan{
1504132718Skan  switch (TREE_CODE (e))
1505117395Skan    {
1506132718Skan    case FLOAT_EXPR:
1507132718Skan    case FIX_TRUNC_EXPR:
1508132718Skan    case CONVERT_EXPR:
1509169689Skan    case NOP_EXPR:
1510132718Skan      pp_c_type_cast (pp, TREE_TYPE (e));
1511132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
1512132718Skan      break;
1513132718Skan
1514132718Skan    default:
1515132718Skan      pp_unary_expression (pp, e);
1516117395Skan    }
1517117395Skan}
1518117395Skan
1519132718Skan/* multiplicative-expression:
1520132718Skan      cast-expression
1521132718Skan      multiplicative-expression * cast-expression
1522132718Skan      multiplicative-expression / cast-expression
1523132718Skan      multiplicative-expression % cast-expression   */
1524132718Skan
1525117395Skanstatic void
1526132718Skanpp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
1527117395Skan{
1528117395Skan  enum tree_code code = TREE_CODE (e);
1529117395Skan  switch (code)
1530117395Skan    {
1531117395Skan    case MULT_EXPR:
1532117395Skan    case TRUNC_DIV_EXPR:
1533117395Skan    case TRUNC_MOD_EXPR:
1534132718Skan      pp_multiplicative_expression (pp, TREE_OPERAND (e, 0));
1535132718Skan      pp_c_whitespace (pp);
1536117395Skan      if (code == MULT_EXPR)
1537132718Skan	pp_c_star (pp);
1538117395Skan      else if (code == TRUNC_DIV_EXPR)
1539132718Skan	pp_slash (pp);
1540117395Skan      else
1541132718Skan	pp_modulo (pp);
1542132718Skan      pp_c_whitespace (pp);
1543132718Skan      pp_c_cast_expression (pp, TREE_OPERAND (e, 1));
1544117395Skan      break;
1545117395Skan
1546117395Skan    default:
1547132718Skan      pp_c_cast_expression (pp, e);
1548117395Skan      break;
1549117395Skan    }
1550117395Skan}
1551117395Skan
1552132718Skan/* additive-expression:
1553132718Skan      multiplicative-expression
1554132718Skan      additive-expression + multiplicative-expression
1555132718Skan      additive-expression - multiplicative-expression   */
1556132718Skan
1557132718Skanstatic void
1558132718Skanpp_c_additive_expression (c_pretty_printer *pp, tree e)
1559117395Skan{
1560117395Skan  enum tree_code code = TREE_CODE (e);
1561117395Skan  switch (code)
1562117395Skan    {
1563117395Skan    case PLUS_EXPR:
1564117395Skan    case MINUS_EXPR:
1565132718Skan      pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
1566132718Skan      pp_c_whitespace (pp);
1567117395Skan      if (code == PLUS_EXPR)
1568132718Skan	pp_plus (pp);
1569117395Skan      else
1570132718Skan	pp_minus (pp);
1571132718Skan      pp_c_whitespace (pp);
1572169689Skan      pp_multiplicative_expression (pp, TREE_OPERAND (e, 1));
1573117395Skan      break;
1574117395Skan
1575117395Skan    default:
1576132718Skan      pp_multiplicative_expression (pp, e);
1577117395Skan      break;
1578117395Skan    }
1579117395Skan}
1580117395Skan
1581132718Skan/* additive-expression:
1582132718Skan      additive-expression
1583132718Skan      shift-expression << additive-expression
1584132718Skan      shift-expression >> additive-expression   */
1585132718Skan
1586132718Skanstatic void
1587132718Skanpp_c_shift_expression (c_pretty_printer *pp, tree e)
1588117395Skan{
1589117395Skan  enum tree_code code = TREE_CODE (e);
1590117395Skan  switch (code)
1591117395Skan    {
1592117395Skan    case LSHIFT_EXPR:
1593117395Skan    case RSHIFT_EXPR:
1594132718Skan      pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
1595132718Skan      pp_c_whitespace (pp);
1596132718Skan      pp_identifier (pp, code == LSHIFT_EXPR ? "<<" : ">>");
1597132718Skan      pp_c_whitespace (pp);
1598132718Skan      pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
1599117395Skan      break;
1600117395Skan
1601117395Skan    default:
1602132718Skan      pp_c_additive_expression (pp, e);
1603117395Skan    }
1604117395Skan}
1605117395Skan
1606132718Skan/* relational-expression:
1607132718Skan      shift-expression
1608132718Skan      relational-expression < shift-expression
1609132718Skan      relational-expression > shift-expression
1610132718Skan      relational-expression <= shift-expression
1611132718Skan      relational-expression >= shift-expression   */
1612132718Skan
1613117395Skanstatic void
1614132718Skanpp_c_relational_expression (c_pretty_printer *pp, tree e)
1615117395Skan{
1616117395Skan  enum tree_code code = TREE_CODE (e);
1617117395Skan  switch (code)
1618117395Skan    {
1619117395Skan    case LT_EXPR:
1620117395Skan    case GT_EXPR:
1621117395Skan    case LE_EXPR:
1622117395Skan    case GE_EXPR:
1623132718Skan      pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
1624132718Skan      pp_c_whitespace (pp);
1625117395Skan      if (code == LT_EXPR)
1626132718Skan	pp_less (pp);
1627117395Skan      else if (code == GT_EXPR)
1628132718Skan	pp_greater (pp);
1629117395Skan      else if (code == LE_EXPR)
1630132718Skan	pp_identifier (pp, "<=");
1631117395Skan      else if (code == GE_EXPR)
1632132718Skan	pp_identifier (pp, ">=");
1633132718Skan      pp_c_whitespace (pp);
1634132718Skan      pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
1635117395Skan      break;
1636117395Skan
1637117395Skan    default:
1638132718Skan      pp_c_shift_expression (pp, e);
1639117395Skan      break;
1640117395Skan    }
1641117395Skan}
1642117395Skan
1643132718Skan/* equality-expression:
1644132718Skan      relational-expression
1645132718Skan      equality-expression == relational-expression
1646132718Skan      equality-equality != relational-expression  */
1647132718Skan
1648132718Skanstatic void
1649132718Skanpp_c_equality_expression (c_pretty_printer *pp, tree e)
1650117395Skan{
1651117395Skan  enum tree_code code = TREE_CODE (e);
1652117395Skan  switch (code)
1653117395Skan    {
1654117395Skan    case EQ_EXPR:
1655117395Skan    case NE_EXPR:
1656132718Skan      pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
1657132718Skan      pp_c_whitespace (pp);
1658132718Skan      pp_identifier (pp, code == EQ_EXPR ? "==" : "!=");
1659132718Skan      pp_c_whitespace (pp);
1660132718Skan      pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
1661132718Skan      break;
1662132718Skan
1663117395Skan    default:
1664132718Skan      pp_c_relational_expression (pp, e);
1665117395Skan      break;
1666117395Skan    }
1667117395Skan}
1668117395Skan
1669132718Skan/* AND-expression:
1670132718Skan      equality-expression
1671132718Skan      AND-expression & equality-equality   */
1672132718Skan
1673132718Skanstatic void
1674132718Skanpp_c_and_expression (c_pretty_printer *pp, tree e)
1675117395Skan{
1676117395Skan  if (TREE_CODE (e) == BIT_AND_EXPR)
1677117395Skan    {
1678132718Skan      pp_c_and_expression (pp, TREE_OPERAND (e, 0));
1679132718Skan      pp_c_whitespace (pp);
1680132718Skan      pp_ampersand (pp);
1681132718Skan      pp_c_whitespace (pp);
1682132718Skan      pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
1683117395Skan    }
1684117395Skan  else
1685132718Skan    pp_c_equality_expression (pp, e);
1686117395Skan}
1687117395Skan
1688132718Skan/* exclusive-OR-expression:
1689132718Skan     AND-expression
1690132718Skan     exclusive-OR-expression ^ AND-expression  */
1691132718Skan
1692132718Skanstatic void
1693132718Skanpp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
1694117395Skan{
1695117395Skan  if (TREE_CODE (e) == BIT_XOR_EXPR)
1696117395Skan    {
1697132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
1698132718Skan      pp_c_maybe_whitespace (pp);
1699132718Skan      pp_carret (pp);
1700132718Skan      pp_c_whitespace (pp);
1701132718Skan      pp_c_and_expression (pp, TREE_OPERAND (e, 1));
1702117395Skan    }
1703117395Skan  else
1704132718Skan    pp_c_and_expression (pp, e);
1705117395Skan}
1706117395Skan
1707132718Skan/* inclusive-OR-expression:
1708132718Skan     exclusive-OR-expression
1709132718Skan     inclusive-OR-expression | exclusive-OR-expression  */
1710132718Skan
1711132718Skanstatic void
1712132718Skanpp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
1713117395Skan{
1714117395Skan  if (TREE_CODE (e) == BIT_IOR_EXPR)
1715117395Skan    {
1716132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
1717132718Skan      pp_c_whitespace (pp);
1718132718Skan      pp_bar (pp);
1719132718Skan      pp_c_whitespace (pp);
1720132718Skan      pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
1721117395Skan    }
1722117395Skan  else
1723132718Skan    pp_c_exclusive_or_expression (pp, e);
1724117395Skan}
1725117395Skan
1726132718Skan/* logical-AND-expression:
1727132718Skan      inclusive-OR-expression
1728132718Skan      logical-AND-expression && inclusive-OR-expression  */
1729132718Skan
1730132718Skanstatic void
1731132718Skanpp_c_logical_and_expression (c_pretty_printer *pp, tree e)
1732117395Skan{
1733117395Skan  if (TREE_CODE (e) == TRUTH_ANDIF_EXPR)
1734117395Skan    {
1735132718Skan      pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
1736132718Skan      pp_c_whitespace (pp);
1737132718Skan      pp_identifier (pp, "&&");
1738132718Skan      pp_c_whitespace (pp);
1739132718Skan      pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
1740117395Skan    }
1741117395Skan  else
1742132718Skan    pp_c_inclusive_or_expression (pp, e);
1743117395Skan}
1744117395Skan
1745132718Skan/* logical-OR-expression:
1746132718Skan      logical-AND-expression
1747132718Skan      logical-OR-expression || logical-AND-expression  */
1748132718Skan
1749117395Skanvoid
1750132718Skanpp_c_logical_or_expression (c_pretty_printer *pp, tree e)
1751117395Skan{
1752117395Skan  if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
1753117395Skan    {
1754132718Skan      pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
1755132718Skan      pp_c_whitespace (pp);
1756132718Skan      pp_identifier (pp, "||");
1757132718Skan      pp_c_whitespace (pp);
1758132718Skan      pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
1759117395Skan    }
1760117395Skan  else
1761132718Skan    pp_c_logical_and_expression (pp, e);
1762117395Skan}
1763117395Skan
1764132718Skan/* conditional-expression:
1765132718Skan      logical-OR-expression
1766132718Skan      logical-OR-expression ? expression : conditional-expression  */
1767132718Skan
1768117395Skanstatic void
1769132718Skanpp_c_conditional_expression (c_pretty_printer *pp, tree e)
1770117395Skan{
1771117395Skan  if (TREE_CODE (e) == COND_EXPR)
1772117395Skan    {
1773132718Skan      pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
1774132718Skan      pp_c_whitespace (pp);
1775132718Skan      pp_question (pp);
1776132718Skan      pp_c_whitespace (pp);
1777132718Skan      pp_expression (pp, TREE_OPERAND (e, 1));
1778132718Skan      pp_c_whitespace (pp);
1779132718Skan      pp_colon (pp);
1780132718Skan      pp_c_whitespace (pp);
1781132718Skan      pp_c_conditional_expression (pp, TREE_OPERAND (e, 2));
1782117395Skan    }
1783117395Skan  else
1784132718Skan    pp_c_logical_or_expression (pp, e);
1785117395Skan}
1786117395Skan
1787117395Skan
1788132718Skan/* assignment-expression:
1789132718Skan      conditional-expression
1790169689Skan      unary-expression assignment-operator  assignment-expression
1791132718Skan
1792132718Skan   assignment-expression: one of
1793132718Skan      =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
1794132718Skan
1795117395Skanstatic void
1796132718Skanpp_c_assignment_expression (c_pretty_printer *pp, tree e)
1797117395Skan{
1798117395Skan  if (TREE_CODE (e) == MODIFY_EXPR || TREE_CODE (e) == INIT_EXPR)
1799117395Skan    {
1800132718Skan      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
1801132718Skan      pp_c_whitespace (pp);
1802132718Skan      pp_equal (pp);
1803132718Skan      pp_space (pp);
1804132718Skan      pp_c_expression (pp, TREE_OPERAND (e, 1));
1805117395Skan    }
1806117395Skan  else
1807132718Skan    pp_c_conditional_expression (pp, e);
1808117395Skan}
1809117395Skan
1810132718Skan/* expression:
1811132718Skan       assignment-expression
1812132718Skan       expression , assignment-expression
1813132718Skan
1814132718Skan  Implementation note:  instead of going through the usual recursion
1815132718Skan  chain, I take the liberty of dispatching nodes to the appropriate
1816132718Skan  functions.  This makes some redundancy, but it worths it. That also
1817132718Skan  prevents a possible infinite recursion between pp_c_primary_expression ()
1818132718Skan  and pp_c_expression ().  */
1819132718Skan
1820117395Skanvoid
1821132718Skanpp_c_expression (c_pretty_printer *pp, tree e)
1822117395Skan{
1823117395Skan  switch (TREE_CODE (e))
1824117395Skan    {
1825117395Skan    case INTEGER_CST:
1826132718Skan      pp_c_integer_constant (pp, e);
1827117395Skan      break;
1828132718Skan
1829117395Skan    case REAL_CST:
1830132718Skan      pp_c_floating_constant (pp, e);
1831117395Skan      break;
1832117395Skan
1833117395Skan    case STRING_CST:
1834132718Skan      pp_c_string_literal (pp, e);
1835117395Skan      break;
1836132718Skan
1837132718Skan    case IDENTIFIER_NODE:
1838117395Skan    case FUNCTION_DECL:
1839117395Skan    case VAR_DECL:
1840117395Skan    case CONST_DECL:
1841117395Skan    case PARM_DECL:
1842117395Skan    case RESULT_DECL:
1843117395Skan    case FIELD_DECL:
1844117395Skan    case LABEL_DECL:
1845117395Skan    case ERROR_MARK:
1846132718Skan      pp_primary_expression (pp, e);
1847117395Skan      break;
1848117395Skan
1849117395Skan    case POSTINCREMENT_EXPR:
1850117395Skan    case POSTDECREMENT_EXPR:
1851117395Skan    case ARRAY_REF:
1852117395Skan    case CALL_EXPR:
1853117395Skan    case COMPONENT_REF:
1854117395Skan    case COMPLEX_CST:
1855132718Skan    case COMPLEX_EXPR:
1856117395Skan    case VECTOR_CST:
1857169689Skan    case ORDERED_EXPR:
1858169689Skan    case UNORDERED_EXPR:
1859169689Skan    case LTGT_EXPR:
1860169689Skan    case UNEQ_EXPR:
1861169689Skan    case UNLE_EXPR:
1862169689Skan    case UNLT_EXPR:
1863169689Skan    case UNGE_EXPR:
1864169689Skan    case UNGT_EXPR:
1865117395Skan    case ABS_EXPR:
1866117395Skan    case CONSTRUCTOR:
1867117395Skan    case COMPOUND_LITERAL_EXPR:
1868117395Skan    case VA_ARG_EXPR:
1869132718Skan      pp_postfix_expression (pp, e);
1870117395Skan      break;
1871117395Skan
1872117395Skan    case CONJ_EXPR:
1873117395Skan    case ADDR_EXPR:
1874117395Skan    case INDIRECT_REF:
1875117395Skan    case NEGATE_EXPR:
1876117395Skan    case BIT_NOT_EXPR:
1877117395Skan    case TRUTH_NOT_EXPR:
1878117395Skan    case PREINCREMENT_EXPR:
1879117395Skan    case PREDECREMENT_EXPR:
1880117395Skan    case REALPART_EXPR:
1881117395Skan    case IMAGPART_EXPR:
1882132718Skan      pp_c_unary_expression (pp, e);
1883117395Skan      break;
1884117395Skan
1885132718Skan    case FLOAT_EXPR:
1886132718Skan    case FIX_TRUNC_EXPR:
1887117395Skan    case CONVERT_EXPR:
1888169689Skan    case NOP_EXPR:
1889132718Skan      pp_c_cast_expression (pp, e);
1890117395Skan      break;
1891117395Skan
1892117395Skan    case MULT_EXPR:
1893117395Skan    case TRUNC_MOD_EXPR:
1894117395Skan    case TRUNC_DIV_EXPR:
1895132718Skan      pp_multiplicative_expression (pp, e);
1896117395Skan      break;
1897117395Skan
1898117395Skan    case LSHIFT_EXPR:
1899117395Skan    case RSHIFT_EXPR:
1900132718Skan      pp_c_shift_expression (pp, e);
1901117395Skan      break;
1902117395Skan
1903117395Skan    case LT_EXPR:
1904117395Skan    case GT_EXPR:
1905117395Skan    case LE_EXPR:
1906117395Skan    case GE_EXPR:
1907132718Skan      pp_c_relational_expression (pp, e);
1908117395Skan      break;
1909117395Skan
1910117395Skan    case BIT_AND_EXPR:
1911132718Skan      pp_c_and_expression (pp, e);
1912117395Skan      break;
1913117395Skan
1914117395Skan    case BIT_XOR_EXPR:
1915132718Skan      pp_c_exclusive_or_expression (pp, e);
1916117395Skan      break;
1917117395Skan
1918117395Skan    case BIT_IOR_EXPR:
1919132718Skan      pp_c_inclusive_or_expression (pp, e);
1920117395Skan      break;
1921117395Skan
1922117395Skan    case TRUTH_ANDIF_EXPR:
1923132718Skan      pp_c_logical_and_expression (pp, e);
1924117395Skan      break;
1925117395Skan
1926117395Skan    case TRUTH_ORIF_EXPR:
1927132718Skan      pp_c_logical_or_expression (pp, e);
1928117395Skan      break;
1929117395Skan
1930132718Skan    case EQ_EXPR:
1931132718Skan    case NE_EXPR:
1932132718Skan      pp_c_equality_expression (pp, e);
1933132718Skan      break;
1934169689Skan
1935117395Skan    case COND_EXPR:
1936132718Skan      pp_conditional_expression (pp, e);
1937117395Skan      break;
1938117395Skan
1939132718Skan    case PLUS_EXPR:
1940132718Skan    case MINUS_EXPR:
1941132718Skan      pp_c_additive_expression (pp, e);
1942132718Skan      break;
1943132718Skan
1944117395Skan    case MODIFY_EXPR:
1945117395Skan    case INIT_EXPR:
1946132718Skan      pp_assignment_expression (pp, e);
1947117395Skan      break;
1948117395Skan
1949132718Skan    case COMPOUND_EXPR:
1950132718Skan      pp_c_left_paren (pp);
1951132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1952132718Skan      pp_separate_with (pp, ',');
1953132718Skan      pp_assignment_expression (pp, TREE_OPERAND (e, 1));
1954132718Skan      pp_c_right_paren (pp);
1955132718Skan      break;
1956132718Skan
1957132718Skan    case NON_LVALUE_EXPR:
1958132718Skan    case SAVE_EXPR:
1959132718Skan      pp_expression (pp, TREE_OPERAND (e, 0));
1960117395Skan      break;
1961117395Skan
1962132718Skan    case TARGET_EXPR:
1963132718Skan      pp_postfix_expression (pp, TREE_OPERAND (e, 1));
1964117395Skan      break;
1965169689Skan
1966117395Skan    default:
1967132718Skan      pp_unsupported_tree (pp, e);
1968117395Skan      break;
1969117395Skan    }
1970117395Skan}
1971117395Skan
1972132718Skan
1973117395Skan
1974117395Skan/* Statements.  */
1975132718Skan
1976117395Skanvoid
1977132718Skanpp_c_statement (c_pretty_printer *pp, tree stmt)
1978117395Skan{
1979132718Skan  if (stmt == NULL)
1980132718Skan    return;
1981117395Skan
1982169689Skan  if (pp_needs_newline (pp))
1983169689Skan    pp_newline_and_indent (pp, 0);
1984132718Skan
1985169689Skan  dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
1986117395Skan}
1987117395Skan
1988117395Skan
1989117395Skan/* Initialize the PRETTY-PRINTER for handling C codes.  */
1990132718Skan
1991117395Skanvoid
1992132718Skanpp_c_pretty_printer_init (c_pretty_printer *pp)
1993117395Skan{
1994117395Skan  pp->offset_list               = 0;
1995117395Skan
1996117395Skan  pp->declaration               = pp_c_declaration;
1997117395Skan  pp->declaration_specifiers    = pp_c_declaration_specifiers;
1998117395Skan  pp->declarator                = pp_c_declarator;
1999117395Skan  pp->direct_declarator         = pp_c_direct_declarator;
2000132718Skan  pp->type_specifier_seq        = pp_c_specifier_qualifier_list;
2001132718Skan  pp->abstract_declarator       = pp_c_abstract_declarator;
2002132718Skan  pp->direct_abstract_declarator = pp_c_direct_abstract_declarator;
2003132718Skan  pp->ptr_operator              = pp_c_pointer;
2004132718Skan  pp->parameter_list            = pp_c_parameter_type_list;
2005117395Skan  pp->type_id                   = pp_c_type_id;
2006132718Skan  pp->simple_type_specifier     = pp_c_type_specifier;
2007132718Skan  pp->function_specifier        = pp_c_function_specifier;
2008132718Skan  pp->storage_class_specifier   = pp_c_storage_class_specifier;
2009117395Skan
2010117395Skan  pp->statement                 = pp_c_statement;
2011117395Skan
2012169689Skan  pp->constant                  = pp_c_constant;
2013132718Skan  pp->id_expression             = pp_c_id_expression;
2014117395Skan  pp->primary_expression        = pp_c_primary_expression;
2015117395Skan  pp->postfix_expression        = pp_c_postfix_expression;
2016117395Skan  pp->unary_expression          = pp_c_unary_expression;
2017117395Skan  pp->initializer               = pp_c_initializer;
2018117395Skan  pp->multiplicative_expression = pp_c_multiplicative_expression;
2019117395Skan  pp->conditional_expression    = pp_c_conditional_expression;
2020117395Skan  pp->assignment_expression     = pp_c_assignment_expression;
2021132718Skan  pp->expression                = pp_c_expression;
2022117395Skan}
2023169689Skan
2024169689Skan
2025169689Skan/* Print the tree T in full, on file FILE.  */
2026169689Skan
2027169689Skanvoid
2028169689Skanprint_c_tree (FILE *file, tree t)
2029169689Skan{
2030169689Skan  static c_pretty_printer pp_rec;
2031169689Skan  static bool initialized = 0;
2032169689Skan  c_pretty_printer *pp = &pp_rec;
2033169689Skan
2034169689Skan  if (!initialized)
2035169689Skan    {
2036169689Skan      initialized = 1;
2037169689Skan      pp_construct (pp_base (pp), NULL, 0);
2038169689Skan      pp_c_pretty_printer_init (pp);
2039169689Skan      pp_needs_newline (pp) = true;
2040169689Skan    }
2041169689Skan  pp_base (pp)->buffer->stream = file;
2042169689Skan
2043169689Skan  pp_statement (pp, t);
2044169689Skan
2045169689Skan  pp_newline (pp);
2046169689Skan  pp_flush (pp);
2047169689Skan}
2048169689Skan
2049169689Skan/* Print the tree T in full, on stderr.  */
2050169689Skan
2051169689Skanvoid
2052169689Skandebug_c_tree (tree t)
2053169689Skan{
2054169689Skan  print_c_tree (stderr, t);
2055169689Skan  fputc ('\n', stderr);
2056169689Skan}
2057169689Skan
2058169689Skan/* Output the DECL_NAME of T.  If T has no DECL_NAME, output a string made
2059169689Skan   up of T's memory address.  */
2060169689Skan
2061169689Skanvoid
2062169689Skanpp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
2063169689Skan{
2064169689Skan  const char *name;
2065169689Skan
2066169689Skan  gcc_assert (DECL_P (t));
2067169689Skan
2068169689Skan  if (DECL_NAME (t))
2069169689Skan    name = IDENTIFIER_POINTER (DECL_NAME (t));
2070169689Skan  else
2071169689Skan    {
2072169689Skan      static char xname[8];
2073169689Skan      sprintf (xname, "<U%4x>", ((unsigned)((unsigned long)(t) & 0xffff)));
2074169689Skan      name = xname;
2075169689Skan    }
2076169689Skan
2077169689Skan  pp_c_identifier (pp, name);
2078169689Skan}
2079