c-pretty-print.c revision 117395
1117395Skan/* Subroutines common to both C and C++ pretty-printers.
2117395Skan   Copyright (C) 2002 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
19117395SkanSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
20117395Skan02111-1307, USA.  */
21117395Skan
22117395Skan#include "config.h"
23117395Skan#include "system.h"
24117395Skan#include "real.h"
25117395Skan#include "c-pretty-print.h"
26117395Skan#include "c-tree.h"
27117395Skan
28117395Skan/* literal  */
29117395Skanstatic void pp_c_char              PARAMS ((c_pretty_printer, int));
30117395Skanstatic void pp_c_character_literal PARAMS ((c_pretty_printer, tree));
31117395Skanstatic void pp_c_bool_literal      PARAMS ((c_pretty_printer, tree));
32117395Skanstatic bool pp_c_enumerator        PARAMS ((c_pretty_printer, tree));
33117395Skanstatic void pp_c_integer_literal   PARAMS ((c_pretty_printer, tree));
34117395Skanstatic void pp_c_real_literal      PARAMS ((c_pretty_printer, tree));
35117395Skanstatic void pp_c_string_literal    PARAMS ((c_pretty_printer, tree));
36117395Skan
37117395Skanstatic void pp_c_primary_expression PARAMS ((c_pretty_printer, tree));
38117395Skan
39117395Skan/* postfix-expression  */
40117395Skanstatic void pp_c_initializer_list        PARAMS ((c_pretty_printer, tree));
41117395Skan
42117395Skanstatic void pp_c_unary_expression        PARAMS ((c_pretty_printer, tree));
43117395Skanstatic void pp_c_multiplicative_expression PARAMS ((c_pretty_printer, tree));
44117395Skanstatic void pp_c_additive_expression     PARAMS ((c_pretty_printer, tree));
45117395Skanstatic void pp_c_shift_expression        PARAMS ((c_pretty_printer, tree));
46117395Skanstatic void pp_c_relational_expression   PARAMS ((c_pretty_printer, tree));
47117395Skanstatic void pp_c_equality_expression     PARAMS ((c_pretty_printer, tree));
48117395Skanstatic void pp_c_and_expression          PARAMS ((c_pretty_printer, tree));
49117395Skanstatic void pp_c_exclusive_or_expression PARAMS ((c_pretty_printer,
50117395Skan						  tree));
51117395Skanstatic void pp_c_inclusive_or_expression PARAMS ((c_pretty_printer,
52117395Skan						  tree));
53117395Skanstatic void pp_c_logical_and_expression PARAMS ((c_pretty_printer, tree));
54117395Skanstatic void pp_c_conditional_expression PARAMS ((c_pretty_printer, tree));
55117395Skanstatic void pp_c_assignment_expression  PARAMS ((c_pretty_printer, tree));
56117395Skan
57117395Skan/* declarations.  */
58117395Skanstatic void pp_c_declaration_specifiers   PARAMS ((c_pretty_printer, tree));
59117395Skanstatic void pp_c_init_declarator          PARAMS ((c_pretty_printer, tree));
60117395Skanstatic void pp_c_declarator               PARAMS ((c_pretty_printer, tree));
61117395Skanstatic void pp_c_direct_declarator        PARAMS ((c_pretty_printer, tree));
62117395Skanstatic void pp_c_abstract_declarator      PARAMS ((c_pretty_printer, tree));
63117395Skanstatic void pp_c_specifier_qualifier_list PARAMS ((c_pretty_printer, tree));
64117395Skanstatic void pp_c_simple_type_specifier    PARAMS ((c_pretty_printer, tree));
65117395Skanstatic void pp_c_parameter_declaration    PARAMS ((c_pretty_printer, tree));
66117395Skanstatic void pp_c_type_id                  PARAMS ((c_pretty_printer, tree));
67117395Skanstatic void pp_c_storage_class_specifier  PARAMS ((c_pretty_printer, tree));
68117395Skanstatic void pp_c_function_specifier       PARAMS ((c_pretty_printer, tree));
69117395Skan
70117395Skan
71117395Skan/* Declarations.  */
72117395Skan
73117395Skan/* Print out CV-qualifiers.  Take care of possible extensions.  */
74117395Skanvoid
75117395Skanpp_c_cv_qualifier (ppi, cv)
76117395Skan     c_pretty_printer ppi;
77117395Skan     int cv;
78117395Skan{
79117395Skan  if (cv & TYPE_QUAL_CONST)
80117395Skan    pp_c_identifier (ppi, "const");
81117395Skan  if (cv & TYPE_QUAL_VOLATILE)
82117395Skan    pp_c_identifier (ppi, "volatile");
83117395Skan  if (cv & TYPE_QUAL_RESTRICT)
84117395Skan    pp_c_identifier (ppi, flag_isoc99 ? "restrict" : "__restrict__");
85117395Skan}
86117395Skan
87117395Skanstatic void
88117395Skanpp_c_simple_type_specifier (ppi, t)
89117395Skan     c_pretty_printer ppi;
90117395Skan     tree t;
91117395Skan{
92117395Skan  const enum tree_code code = TREE_CODE (t);
93117395Skan  switch (code)
94117395Skan    {
95117395Skan    case ERROR_MARK:
96117395Skan      pp_c_identifier (ppi, "<type-error>");
97117395Skan      break;
98117395Skan
99117395Skan#if 0
100117395Skan    case UNKNOWN_TYPE:
101117395Skan      pp_c_identifier (ppi, "<unkown-type>");
102117395Skan      break;
103117395Skan#endif
104117395Skan
105117395Skan    case IDENTIFIER_NODE:
106117395Skan      pp_c_tree_identifier (ppi, t);
107117395Skan      break;
108117395Skan
109117395Skan    case VOID_TYPE:
110117395Skan    case BOOLEAN_TYPE:
111117395Skan    case CHAR_TYPE:
112117395Skan    case INTEGER_TYPE:
113117395Skan    case REAL_TYPE:
114117395Skan      pp_c_tree_identifier (ppi, DECL_NAME (t));
115117395Skan      break;
116117395Skan
117117395Skan    case COMPLEX_TYPE:
118117395Skan    case VECTOR_TYPE:
119117395Skan      pp_c_simple_type_specifier (ppi, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
120117395Skan      if (code == COMPLEX_TYPE)
121117395Skan	pp_c_identifier (ppi, flag_isoc99 ? "_Complex" : "__complex__");
122117395Skan      else if (code == VECTOR_TYPE)
123117395Skan	pp_c_identifier (ppi, "__vector__");
124117395Skan      break;
125117395Skan
126117395Skan    case TYPE_DECL:
127117395Skan      if (DECL_NAME (t))
128117395Skan	pp_c_tree_identifier (ppi, DECL_NAME (t));
129117395Skan      else
130117395Skan	pp_c_identifier (ppi, "<typedef-error>");
131117395Skan      break;
132117395Skan
133117395Skan    case UNION_TYPE:
134117395Skan    case RECORD_TYPE:
135117395Skan    case ENUMERAL_TYPE:
136117395Skan      if (code == UNION_TYPE)
137117395Skan	pp_c_identifier (ppi, "union");
138117395Skan      else if (code == RECORD_TYPE)
139117395Skan	pp_c_identifier (ppi, "struct");
140117395Skan      else if (code == ENUMERAL_TYPE)
141117395Skan	pp_c_identifier (ppi, "enum");
142117395Skan      else
143117395Skan	pp_c_identifier (ppi, "<tag-error>");
144117395Skan
145117395Skan      if (TYPE_NAME (t))
146117395Skan	pp_c_tree_identifier (ppi, TYPE_NAME (t));
147117395Skan      else
148117395Skan	pp_c_identifier (ppi, "<anonymous>");
149117395Skan      break;
150117395Skan
151117395Skan    default:
152117395Skan      pp_unsupported_tree (ppi, t);
153117395Skan    }
154117395Skan}
155117395Skan
156117395Skanstatic inline void
157117395Skanpp_c_specifier_qualifier_list (ppi, t)
158117395Skan     c_pretty_printer ppi;
159117395Skan     tree t;
160117395Skan{
161117395Skan  pp_c_simple_type_specifier (ppi, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
162117395Skan  pp_c_cv_qualifier (ppi, TYPE_QUALS (t));
163117395Skan}
164117395Skan
165117395Skanstatic void
166117395Skanpp_c_abstract_declarator (ppi, t)
167117395Skan     c_pretty_printer ppi;
168117395Skan     tree t;
169117395Skan{
170117395Skan  pp_unsupported_tree (ppi, t);
171117395Skan}
172117395Skan
173117395Skan
174117395Skanstatic inline void
175117395Skanpp_c_type_id (ppi, t)
176117395Skan     c_pretty_printer ppi;
177117395Skan     tree t;
178117395Skan{
179117395Skan  pp_c_specifier_qualifier_list (ppi, t);
180117395Skan  pp_c_abstract_declarator (ppi, t);
181117395Skan}
182117395Skan
183117395Skanstatic inline void
184117395Skanpp_c_storage_class_specifier (pp, t)
185117395Skan     c_pretty_printer pp;
186117395Skan     tree t;
187117395Skan{
188117395Skan  if (TREE_CODE (t) == TYPE_DECL)
189117395Skan    pp_c_identifier (pp, "typedef");
190117395Skan  else if (DECL_REGISTER (t))
191117395Skan    pp_c_identifier (pp, "register");
192117395Skan}
193117395Skan
194117395Skanstatic inline void
195117395Skanpp_c_function_specifier (pp, t)
196117395Skan     c_pretty_printer pp;
197117395Skan     tree t;
198117395Skan{
199117395Skan  if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
200117395Skan    pp_c_identifier (pp, "inline");
201117395Skan}
202117395Skan
203117395Skanstatic inline void
204117395Skanpp_c_declaration_specifiers (pp, t)
205117395Skan     c_pretty_printer pp;
206117395Skan     tree t;
207117395Skan{
208117395Skan  pp_c_storage_class_specifier (pp, t);
209117395Skan  pp_c_function_specifier (pp, t);
210117395Skan  pp_type_specifier (pp, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
211117395Skan  pp_c_cv_qualifier (pp, TYPE_QUALS (TREE_TYPE (t)));
212117395Skan}
213117395Skan
214117395Skanstatic inline void
215117395Skanpp_c_direct_declarator (pp, t)
216117395Skan     c_pretty_printer pp;
217117395Skan     tree t;
218117395Skan{
219117395Skan  pp_unsupported_tree (pp, t);
220117395Skan}
221117395Skan
222117395Skanstatic inline void
223117395Skanpp_c_declarator (pp, t)
224117395Skan     c_pretty_printer pp;
225117395Skan     tree t;
226117395Skan{
227117395Skan  pp_unsupported_tree (pp, t);
228117395Skan}
229117395Skan
230117395Skanstatic inline void
231117395Skanpp_c_init_declarator (pp, t)
232117395Skan     c_pretty_printer pp;
233117395Skan     tree t;
234117395Skan{
235117395Skan  pp_declarator (pp, t);
236117395Skan  if (DECL_INITIAL (t))
237117395Skan    {
238117395Skan      pp_whitespace (pp);
239117395Skan      pp_equal (pp);
240117395Skan      pp_whitespace (pp);
241117395Skan      pp_c_initializer (pp, DECL_INITIAL (t));
242117395Skan    }
243117395Skan}
244117395Skan
245117395Skanvoid
246117395Skanpp_c_declaration (pp, t)
247117395Skan     c_pretty_printer pp;
248117395Skan     tree t;
249117395Skan{
250117395Skan  pp_declaration_specifiers (pp, t);
251117395Skan  pp_c_init_declarator (pp, t);
252117395Skan}
253117395Skan
254117395Skanstatic void
255117395Skanpp_c_parameter_declaration (pp, t)
256117395Skan     c_pretty_printer pp;
257117395Skan     tree t;
258117395Skan{
259117395Skan  pp_unsupported_tree (pp, t);
260117395Skan}
261117395Skan
262117395Skan/* Pretty-print ATTRIBUTES using GNU C extension syntax.  */
263117395Skanvoid
264117395Skanpp_c_attributes (pp, attributes)
265117395Skan     c_pretty_printer pp;
266117395Skan     tree attributes;
267117395Skan{
268117395Skan  if (attributes == NULL_TREE)
269117395Skan    return;
270117395Skan
271117395Skan  pp_c_identifier (pp, "__attribute__");
272117395Skan  pp_c_left_paren (pp);
273117395Skan  pp_c_left_paren (pp);
274117395Skan  for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
275117395Skan    {
276117395Skan      pp_tree_identifier (pp, TREE_PURPOSE (attributes));
277117395Skan      if (TREE_VALUE (attributes))
278117395Skan	{
279117395Skan	  pp_c_left_paren (pp);
280117395Skan	  pp_c_expression_list (pp, TREE_VALUE (attributes));
281117395Skan	  pp_c_right_paren (pp);
282117395Skan	}
283117395Skan
284117395Skan      if (TREE_CHAIN (attributes))
285117395Skan	pp_separate_with (pp, ',');
286117395Skan    }
287117395Skan  pp_c_right_paren (pp);
288117395Skan  pp_c_right_paren (pp);
289117395Skan}
290117395Skan
291117395Skan
292117395Skan/* Expressions.  */
293117395Skan
294117395Skan/* Print out a c-char.  */
295117395Skanstatic void
296117395Skanpp_c_char (ppi, c)
297117395Skan     c_pretty_printer ppi;
298117395Skan     int c;
299117395Skan{
300117395Skan  switch (c)
301117395Skan    {
302117395Skan    case TARGET_NEWLINE:
303117395Skan      pp_identifier (ppi, "\\n");
304117395Skan      break;
305117395Skan    case TARGET_TAB:
306117395Skan      pp_identifier (ppi, "\\t");
307117395Skan      break;
308117395Skan    case TARGET_VT:
309117395Skan      pp_identifier (ppi, "\\v");
310117395Skan      break;
311117395Skan    case TARGET_BS:
312117395Skan      pp_identifier (ppi, "\\b");
313117395Skan      break;
314117395Skan    case TARGET_CR:
315117395Skan      pp_identifier (ppi, "\\r");
316117395Skan      break;
317117395Skan    case TARGET_FF:
318117395Skan      pp_identifier (ppi, "\\f");
319117395Skan      break;
320117395Skan    case TARGET_BELL:
321117395Skan      pp_identifier (ppi, "\\a");
322117395Skan      break;
323117395Skan    case '\\':
324117395Skan      pp_identifier (ppi, "\\\\");
325117395Skan      break;
326117395Skan    case '\'':
327117395Skan      pp_identifier (ppi, "\\'");
328117395Skan      break;
329117395Skan    case '\"':
330117395Skan      pp_identifier (ppi, "\\\"");
331117395Skan      break;
332117395Skan    default:
333117395Skan      if (ISPRINT (c))
334117395Skan	pp_character (ppi, c);
335117395Skan      else
336117395Skan	pp_format_scalar (ppi, "\\%03o", (unsigned) c);
337117395Skan      break;
338117395Skan    }
339117395Skan}
340117395Skan
341117395Skan/* Print out a STRING literal.  */
342117395Skanstatic inline void
343117395Skanpp_c_string_literal (ppi, s)
344117395Skan     c_pretty_printer ppi;
345117395Skan     tree s;
346117395Skan{
347117395Skan  const char *p = TREE_STRING_POINTER (s);
348117395Skan  int n = TREE_STRING_LENGTH (s) - 1;
349117395Skan  int i;
350117395Skan  pp_doublequote (ppi);
351117395Skan  for (i = 0; i < n; ++i)
352117395Skan    pp_c_char (ppi, p[i]);
353117395Skan  pp_doublequote (ppi);
354117395Skan}
355117395Skan
356117395Skan/* Print out a CHARACTER literal.  */
357117395Skanstatic inline void
358117395Skanpp_c_character_literal (ppi, c)
359117395Skan     c_pretty_printer ppi;
360117395Skan     tree c;
361117395Skan{
362117395Skan  pp_quote (ppi);
363117395Skan  pp_c_char (ppi, tree_low_cst (c, 0));
364117395Skan  pp_quote (ppi);
365117395Skan}
366117395Skan
367117395Skan/* Print out a BOOLEAN literal.  */
368117395Skanstatic inline void
369117395Skanpp_c_bool_literal (ppi, b)
370117395Skan     c_pretty_printer ppi;
371117395Skan     tree b;
372117395Skan{
373117395Skan  if (b == boolean_false_node || integer_zerop (b))
374117395Skan    {
375117395Skan      if (c_language == clk_cplusplus)
376117395Skan	pp_c_identifier (ppi, "false");
377117395Skan      else if (c_language == clk_c && flag_isoc99)
378117395Skan	pp_c_identifier (ppi, "_False");
379117395Skan      else
380117395Skan	pp_unsupported_tree (ppi, b);
381117395Skan    }
382117395Skan  else if (b == boolean_true_node)
383117395Skan    {
384117395Skan      if (c_language == clk_cplusplus)
385117395Skan	pp_c_identifier (ppi, "true");
386117395Skan      else if (c_language == clk_c && flag_isoc99)
387117395Skan	pp_c_identifier (ppi, "_True");
388117395Skan      else
389117395Skan	pp_unsupported_tree (ppi, b);
390117395Skan    }
391117395Skan  else
392117395Skan    pp_unsupported_tree (ppi, b);
393117395Skan}
394117395Skan
395117395Skan/* Attempt to print out an ENUMERATOR.  Return true on success.  Else return
396117395Skan   false; that means the value was obtained by a cast, in which case
397117395Skan   print out the type-id part of the cast-expression -- the casted value
398117395Skan   is then printed by pp_c_integer_literal.  */
399117395Skanstatic bool
400117395Skanpp_c_enumerator (ppi, e)
401117395Skan     c_pretty_printer ppi;
402117395Skan     tree e;
403117395Skan{
404117395Skan  tree type = TREE_TYPE (e);
405117395Skan  tree value;
406117395Skan
407117395Skan  /* Find the name of this constant.  */
408117395Skan  for (value = TYPE_VALUES (type);
409117395Skan       value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
410117395Skan       value = TREE_CHAIN (value))
411117395Skan    ;
412117395Skan
413117395Skan  if (value != NULL_TREE)
414117395Skan    pp_c_tree_identifier (ppi, TREE_PURPOSE (value));
415117395Skan  else
416117395Skan    {
417117395Skan      /* Value must have been cast.  */
418117395Skan      pp_c_left_paren (ppi);
419117395Skan      pp_type_id (ppi, type);
420117395Skan      pp_c_right_paren (ppi);
421117395Skan      return false;
422117395Skan    }
423117395Skan
424117395Skan  return true;
425117395Skan}
426117395Skan
427117395Skan/* Print out an INTEGER constant value.  */
428117395Skanstatic void
429117395Skanpp_c_integer_literal (ppi, i)
430117395Skan     c_pretty_printer ppi;
431117395Skan     tree i;
432117395Skan{
433117395Skan  tree type = TREE_TYPE (i);
434117395Skan
435117395Skan  if (type == boolean_type_node)
436117395Skan    pp_c_bool_literal (ppi, i);
437117395Skan  else if (type == char_type_node)
438117395Skan    pp_c_character_literal (ppi, i);
439117395Skan  else if (TREE_CODE (type) == ENUMERAL_TYPE
440117395Skan	   && pp_c_enumerator (ppi, i))
441117395Skan    ;
442117395Skan  else
443117395Skan    {
444117395Skan      if (host_integerp (i, 0))
445117395Skan	pp_wide_integer (ppi, TREE_INT_CST_LOW (i));
446117395Skan      else
447117395Skan	{
448117395Skan	  if (tree_int_cst_sgn (i) < 0)
449117395Skan	    {
450117395Skan	      static char format[10]; /* "%x%09999x\0" */
451117395Skan	      if (!format[0])
452117395Skan		sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
453117395Skan
454117395Skan	      pp_c_char (ppi, '-');
455117395Skan	      i = build_int_2 (-TREE_INT_CST_LOW (i),
456117395Skan			       ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i));
457117395Skan	      sprintf (pp_buffer (ppi)->digit_buffer, format,
458117395Skan		       TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i));
459117395Skan	      pp_identifier (ppi, pp_buffer (ppi)->digit_buffer);
460117395Skan
461117395Skan	    }
462117395Skan	}
463117395Skan    }
464117395Skan}
465117395Skan
466117395Skan/* Print out a REAL value.  */
467117395Skanstatic inline void
468117395Skanpp_c_real_literal (ppi, r)
469117395Skan     c_pretty_printer ppi;
470117395Skan     tree r;
471117395Skan{
472117395Skan  real_to_decimal (pp_buffer (ppi)->digit_buffer, &TREE_REAL_CST (r),
473117395Skan		   sizeof (pp_buffer (ppi)->digit_buffer), 0, 1);
474117395Skan  pp_identifier (ppi, pp_buffer(ppi)->digit_buffer);
475117395Skan}
476117395Skan
477117395Skan
478117395Skanvoid
479117395Skanpp_c_literal (ppi, e)
480117395Skan     c_pretty_printer ppi;
481117395Skan     tree e;
482117395Skan{
483117395Skan  switch (TREE_CODE (e))
484117395Skan    {
485117395Skan    case INTEGER_CST:
486117395Skan      pp_c_integer_literal (ppi, e);
487117395Skan      break;
488117395Skan
489117395Skan    case REAL_CST:
490117395Skan      pp_c_real_literal (ppi, e);
491117395Skan      break;
492117395Skan
493117395Skan    case STRING_CST:
494117395Skan      pp_c_string_literal (ppi, e);
495117395Skan      break;
496117395Skan
497117395Skan    default:
498117395Skan      pp_unsupported_tree (ppi, e);
499117395Skan      break;
500117395Skan    }
501117395Skan}
502117395Skan
503117395Skan/* Pretty-print a C primary-expression.  */
504117395Skanstatic void
505117395Skanpp_c_primary_expression (ppi, e)
506117395Skan     c_pretty_printer ppi;
507117395Skan     tree e;
508117395Skan{
509117395Skan  switch (TREE_CODE (e))
510117395Skan    {
511117395Skan    case VAR_DECL:
512117395Skan    case PARM_DECL:
513117395Skan    case FIELD_DECL:
514117395Skan    case CONST_DECL:
515117395Skan    case FUNCTION_DECL:
516117395Skan    case LABEL_DECL:
517117395Skan      e = DECL_NAME (e);
518117395Skan      /* Fall through.  */
519117395Skan    case IDENTIFIER_NODE:
520117395Skan      pp_c_tree_identifier (ppi, e);
521117395Skan      break;
522117395Skan
523117395Skan    case ERROR_MARK:
524117395Skan      pp_c_identifier (ppi, "<erroneous-expression>");
525117395Skan      break;
526117395Skan
527117395Skan    case RESULT_DECL:
528117395Skan      pp_c_identifier (ppi, "<return-value>");
529117395Skan      break;
530117395Skan
531117395Skan    case INTEGER_CST:
532117395Skan    case REAL_CST:
533117395Skan    case STRING_CST:
534117395Skan      pp_c_literal (ppi, e);
535117395Skan      break;
536117395Skan
537117395Skan    case TARGET_EXPR:
538117395Skan      pp_c_left_paren (ppi);
539117395Skan      pp_c_identifier (ppi, "__builtin_memcpy");
540117395Skan      pp_c_left_paren (ppi);
541117395Skan      pp_ampersand (ppi);
542117395Skan      pp_c_primary_expression (ppi, TREE_OPERAND (e, 0));
543117395Skan      pp_separate_with (ppi, ',');
544117395Skan      pp_ampersand (ppi);
545117395Skan      pp_initializer (ppi, TREE_OPERAND (e, 1));
546117395Skan      if (TREE_OPERAND (e, 2))
547117395Skan	{
548117395Skan	  pp_separate_with (ppi, ',');
549117395Skan	  pp_c_expression (ppi, TREE_OPERAND (e, 2));
550117395Skan	}
551117395Skan      pp_c_right_paren (ppi);
552117395Skan
553117395Skan    case STMT_EXPR:
554117395Skan      pp_c_left_paren (ppi);
555117395Skan      pp_statement (ppi, STMT_EXPR_STMT (e));
556117395Skan      pp_c_right_paren (ppi);
557117395Skan      break;
558117395Skan
559117395Skan    default:
560117395Skan      /*  Make sure this call won't cause any infinite loop.  */
561117395Skan      pp_c_left_paren (ppi);
562117395Skan      pp_c_expression (ppi, e);
563117395Skan      pp_c_right_paren (ppi);
564117395Skan      break;
565117395Skan    }
566117395Skan}
567117395Skan
568117395Skan/* Print out a C initializer -- also support C compound-literals.  */
569117395Skanvoid
570117395Skanpp_c_initializer (ppi, e)
571117395Skan     c_pretty_printer ppi;
572117395Skan     tree e;
573117395Skan{
574117395Skan  if (TREE_CODE (e) == CONSTRUCTOR)
575117395Skan    {
576117395Skan      enum tree_code code = TREE_CODE (TREE_TYPE (e));
577117395Skan      if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE)
578117395Skan	{
579117395Skan	  pp_left_brace (ppi);
580117395Skan	  pp_c_initializer_list (ppi, e);
581117395Skan	  pp_right_brace (ppi);
582117395Skan	}
583117395Skan      else
584117395Skan	pp_unsupported_tree (ppi, TREE_OPERAND (e, 1));
585117395Skan    }
586117395Skan  else
587117395Skan    pp_assignment_expression (ppi, e);
588117395Skan}
589117395Skan
590117395Skanstatic void
591117395Skanpp_c_initializer_list (ppi, e)
592117395Skan     c_pretty_printer ppi;
593117395Skan     tree e;
594117395Skan{
595117395Skan  tree type = TREE_TYPE (e);
596117395Skan  const enum tree_code code = TREE_CODE (type);
597117395Skan
598117395Skan  if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE)
599117395Skan    {
600117395Skan      tree init = TREE_OPERAND (e, 1);
601117395Skan      for (; init != NULL_TREE; init = TREE_CHAIN (init))
602117395Skan	{
603117395Skan	  if (code == RECORD_TYPE || code == UNION_TYPE)
604117395Skan	    {
605117395Skan	      pp_dot (ppi);
606117395Skan	      pp_c_primary_expression (ppi, TREE_PURPOSE (init));
607117395Skan	    }
608117395Skan	  else
609117395Skan	    {
610117395Skan	      pp_c_left_bracket (ppi);
611117395Skan	      if (TREE_PURPOSE (init))
612117395Skan		pp_c_literal (ppi, TREE_PURPOSE (init));
613117395Skan	      pp_c_right_bracket (ppi);
614117395Skan	    }
615117395Skan	  pp_c_whitespace (ppi);
616117395Skan	  pp_equal (ppi);
617117395Skan	  pp_c_whitespace (ppi);
618117395Skan	  pp_initializer (ppi, TREE_VALUE (init));
619117395Skan	  if (TREE_CHAIN (init))
620117395Skan	    pp_separate_with (ppi, ',');
621117395Skan	}
622117395Skan    }
623117395Skan  else
624117395Skan    pp_unsupported_tree (ppi, type);
625117395Skan}
626117395Skan
627117395Skanvoid
628117395Skanpp_c_postfix_expression (ppi, e)
629117395Skan     c_pretty_printer ppi;
630117395Skan     tree e;
631117395Skan{
632117395Skan  enum tree_code code = TREE_CODE (e);
633117395Skan  switch (code)
634117395Skan    {
635117395Skan    case POSTINCREMENT_EXPR:
636117395Skan    case POSTDECREMENT_EXPR:
637117395Skan      pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
638117395Skan      pp_identifier (ppi, code == POSTINCREMENT_EXPR ? "++" : "--");
639117395Skan      break;
640117395Skan
641117395Skan    case ARROW_EXPR:
642117395Skan      pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
643117395Skan      pp_arrow (ppi);
644117395Skan      break;
645117395Skan
646117395Skan    case ARRAY_REF:
647117395Skan      pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
648117395Skan      pp_c_left_bracket (ppi);
649117395Skan      pp_c_expression (ppi, TREE_OPERAND (e, 1));
650117395Skan      pp_c_right_bracket (ppi);
651117395Skan      break;
652117395Skan
653117395Skan    case CALL_EXPR:
654117395Skan      pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
655117395Skan      pp_c_left_paren (ppi);
656117395Skan      pp_c_expression_list (ppi, TREE_OPERAND (e, 1));
657117395Skan      pp_c_right_paren (ppi);
658117395Skan      break;
659117395Skan
660117395Skan    case ABS_EXPR:
661117395Skan    case FFS_EXPR:
662117395Skan      pp_c_identifier (ppi,
663117395Skan		       code == ABS_EXPR ? "__builtin_abs" : "__builtin_ffs");
664117395Skan      pp_c_left_paren (ppi);
665117395Skan      pp_c_expression (ppi, TREE_OPERAND (e, 0));
666117395Skan      pp_c_right_paren (ppi);
667117395Skan      break;
668117395Skan
669117395Skan    case COMPONENT_REF:
670117395Skan      {
671117395Skan	tree object = TREE_OPERAND (e, 0);
672117395Skan	if (TREE_CODE (object) == INDIRECT_REF)
673117395Skan	  {
674117395Skan	    pp_postfix_expression (ppi, TREE_OPERAND (object, 0));
675117395Skan	    pp_arrow (ppi);
676117395Skan	  }
677117395Skan	else
678117395Skan	  {
679117395Skan	    pp_postfix_expression (ppi, object);
680117395Skan	    pp_dot (ppi);
681117395Skan	  }
682117395Skan	pp_c_expression (ppi, TREE_OPERAND (e, 1));
683117395Skan      }
684117395Skan      break;
685117395Skan
686117395Skan    case COMPLEX_CST:
687117395Skan    case VECTOR_CST:
688117395Skan    case COMPLEX_EXPR:
689117395Skan      pp_c_left_paren (ppi);
690117395Skan      pp_type_id (ppi, TREE_TYPE (e));
691117395Skan      pp_c_right_paren (ppi);
692117395Skan      pp_left_brace (ppi);
693117395Skan
694117395Skan      if (code == COMPLEX_CST)
695117395Skan	{
696117395Skan	  pp_c_expression (ppi, TREE_REALPART (e));
697117395Skan	  pp_separate_with (ppi, ',');
698117395Skan	  pp_c_expression (ppi, TREE_IMAGPART (e));
699117395Skan	}
700117395Skan      else if (code == VECTOR_CST)
701117395Skan	pp_c_expression_list (ppi, TREE_VECTOR_CST_ELTS (e));
702117395Skan      else if (code == COMPLEX_EXPR)
703117395Skan	{
704117395Skan	  pp_c_expression (ppi, TREE_OPERAND (e, 0));
705117395Skan	  pp_separate_with (ppi, ',');
706117395Skan	  pp_c_expression (ppi, TREE_OPERAND (e, 1));
707117395Skan	}
708117395Skan
709117395Skan      pp_right_brace (ppi);
710117395Skan      break;
711117395Skan
712117395Skan    case COMPOUND_LITERAL_EXPR:
713117395Skan      e = DECL_INITIAL (e);
714117395Skan      /* Fall through.  */
715117395Skan    case CONSTRUCTOR:
716117395Skan      pp_initializer (ppi, e);
717117395Skan      break;
718117395Skan
719117395Skan#if 0
720117395Skan    case SRCLOC:
721117395Skan      pp_left_paren (ppi);
722117395Skan      pp_identifier (ppi, "__location__");
723117395Skan      pp_right_paren (ppi);
724117395Skan      pp_whitespace (ppi);
725117395Skan      pp_left_brace (ppi);
726117395Skan      pp_dot (ppi);
727117395Skan      pp_identifier (ppi, "file");
728117395Skan      pp_whitespace (ppi);
729117395Skan      pp_equal (ppi);
730117395Skan      pp_c_whitespace (ppi);
731117395Skan      pp_c_expression (ppi, SRCLOC_FILE (e));
732117395Skan      pp_separate_with (ppi, ',');
733117395Skan      pp_dot (ppi);
734117395Skan      pp_identifier (ppi, "line");
735117395Skan      pp_whitespace (ppi);
736117395Skan      pp_equal (ppi);
737117395Skan      pp_c_whitespace (ppi);
738117395Skan      pp_c_expression (ppi, SRCLOC_LINE (e));
739117395Skan      pp_right_brace (ppi);
740117395Skan      break;
741117395Skan#endif
742117395Skan
743117395Skan    case VA_ARG_EXPR:
744117395Skan      pp_c_identifier (ppi, "__builtin_va_arg");
745117395Skan      pp_c_left_paren (ppi);
746117395Skan      pp_assignment_expression (ppi, TREE_OPERAND (e, 0));
747117395Skan      pp_separate_with (ppi, ',');
748117395Skan      pp_type_id (ppi, TREE_TYPE (e));
749117395Skan      pp_c_right_paren (ppi);
750117395Skan      break;
751117395Skan
752117395Skan    default:
753117395Skan      pp_primary_expression (ppi, e);
754117395Skan      break;
755117395Skan    }
756117395Skan}
757117395Skan
758117395Skan/* Print out an expression-list; E is expected to be a TREE_LIST  */
759117395Skanvoid
760117395Skanpp_c_expression_list (ppi, e)
761117395Skan     c_pretty_printer ppi;
762117395Skan     tree e;
763117395Skan{
764117395Skan  for (; e != NULL_TREE; e = TREE_CHAIN (e))
765117395Skan    {
766117395Skan      pp_c_assignment_expression (ppi, TREE_VALUE (e));
767117395Skan      if (TREE_CHAIN (e))
768117395Skan	pp_separate_with (ppi, ',');
769117395Skan    }
770117395Skan}
771117395Skan
772117395Skanstatic void
773117395Skanpp_c_unary_expression (ppi, e)
774117395Skan     c_pretty_printer ppi;
775117395Skan     tree e;
776117395Skan{
777117395Skan  enum tree_code code = TREE_CODE (e);
778117395Skan  switch (code)
779117395Skan    {
780117395Skan    case PREINCREMENT_EXPR:
781117395Skan    case PREDECREMENT_EXPR:
782117395Skan      pp_identifier (ppi, code == PREINCREMENT_EXPR ? "++" : "--");
783117395Skan      pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
784117395Skan      break;
785117395Skan
786117395Skan    case ADDR_EXPR:
787117395Skan    case INDIRECT_REF:
788117395Skan    case CONVERT_EXPR:
789117395Skan    case NEGATE_EXPR:
790117395Skan    case BIT_NOT_EXPR:
791117395Skan    case TRUTH_NOT_EXPR:
792117395Skan    case CONJ_EXPR:
793117395Skan      if (code == ADDR_EXPR)
794117395Skan	pp_ampersand (ppi);
795117395Skan      else if (code == INDIRECT_REF)
796117395Skan	pp_star (ppi);
797117395Skan      else if (code == NEGATE_EXPR)
798117395Skan	pp_minus (ppi);
799117395Skan      else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
800117395Skan	pp_complement (ppi);
801117395Skan      else if (code == TRUTH_NOT_EXPR)
802117395Skan	pp_exclamation (ppi);
803117395Skan      pp_c_cast_expression (ppi, TREE_OPERAND (e, 0));
804117395Skan      break;
805117395Skan
806117395Skan    case SIZEOF_EXPR:
807117395Skan    case ALIGNOF_EXPR:
808117395Skan      pp_c_identifier (ppi, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
809117395Skan      pp_c_whitespace (ppi);
810117395Skan      if (TYPE_P (TREE_OPERAND (e, 0)))
811117395Skan	{
812117395Skan	  pp_c_left_paren (ppi);
813117395Skan	  pp_type_id (ppi, TREE_OPERAND (e, 0));
814117395Skan	  pp_c_right_paren (ppi);
815117395Skan	}
816117395Skan      else
817117395Skan	pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
818117395Skan      break;
819117395Skan
820117395Skan    case REALPART_EXPR:
821117395Skan    case IMAGPART_EXPR:
822117395Skan      pp_c_identifier (ppi, code == REALPART_EXPR ? "__real__" : "__imag__");
823117395Skan      pp_c_whitespace (ppi);
824117395Skan      pp_unary_expression (ppi, TREE_OPERAND (e, 0));
825117395Skan      break;
826117395Skan
827117395Skan    default:
828117395Skan      pp_postfix_expression (ppi, e);
829117395Skan      break;
830117395Skan    }
831117395Skan}
832117395Skan
833117395Skanvoid
834117395Skanpp_c_cast_expression (ppi, e)
835117395Skan     c_pretty_printer ppi;
836117395Skan     tree e;
837117395Skan{
838117395Skan  if (TREE_CODE (e) == CONVERT_EXPR || TREE_CODE (e) == FLOAT_EXPR)
839117395Skan    {
840117395Skan      pp_c_left_paren (ppi);
841117395Skan      pp_type_id (ppi, TREE_TYPE (e));
842117395Skan      pp_c_right_paren (ppi);
843117395Skan      pp_c_cast_expression (ppi, TREE_OPERAND (e, 0));
844117395Skan    }
845117395Skan  else
846117395Skan    pp_unary_expression (ppi, e);
847117395Skan}
848117395Skan
849117395Skanstatic void
850117395Skanpp_c_multiplicative_expression (ppi, e)
851117395Skan     c_pretty_printer ppi;
852117395Skan     tree e;
853117395Skan{
854117395Skan  enum tree_code code = TREE_CODE (e);
855117395Skan  switch (code)
856117395Skan    {
857117395Skan    case MULT_EXPR:
858117395Skan    case TRUNC_DIV_EXPR:
859117395Skan    case TRUNC_MOD_EXPR:
860117395Skan      pp_c_multiplicative_expression (ppi, TREE_OPERAND (e, 0));
861117395Skan      pp_c_whitespace (ppi);
862117395Skan      if (code == MULT_EXPR)
863117395Skan	pp_star (ppi);
864117395Skan      else if (code == TRUNC_DIV_EXPR)
865117395Skan	pp_slash (ppi);
866117395Skan      else
867117395Skan	pp_modulo (ppi);
868117395Skan      pp_c_whitespace (ppi);
869117395Skan      pp_c_cast_expression (ppi, TREE_OPERAND (e, 1));
870117395Skan      break;
871117395Skan
872117395Skan    default:
873117395Skan      pp_c_cast_expression (ppi, e);
874117395Skan      break;
875117395Skan    }
876117395Skan}
877117395Skan
878117395Skanstatic inline void
879117395Skanpp_c_additive_expression (ppi, e)
880117395Skan     c_pretty_printer ppi;
881117395Skan     tree e;
882117395Skan{
883117395Skan  enum tree_code code = TREE_CODE (e);
884117395Skan  switch (code)
885117395Skan    {
886117395Skan    case PLUS_EXPR:
887117395Skan    case MINUS_EXPR:
888117395Skan      pp_c_additive_expression (ppi, TREE_OPERAND (e, 0));
889117395Skan      pp_c_whitespace (ppi);
890117395Skan      if (code == PLUS_EXPR)
891117395Skan	pp_plus (ppi);
892117395Skan      else
893117395Skan	pp_minus (ppi);
894117395Skan      pp_c_whitespace (ppi);
895117395Skan      pp_multiplicative_expression (ppi, TREE_OPERAND (e, 1));
896117395Skan      break;
897117395Skan
898117395Skan    default:
899117395Skan      pp_multiplicative_expression (ppi, e);
900117395Skan      break;
901117395Skan    }
902117395Skan}
903117395Skan
904117395Skanstatic inline void
905117395Skanpp_c_shift_expression (ppi, e)
906117395Skan     c_pretty_printer ppi;
907117395Skan     tree e;
908117395Skan{
909117395Skan  enum tree_code code = TREE_CODE (e);
910117395Skan  switch (code)
911117395Skan    {
912117395Skan    case LSHIFT_EXPR:
913117395Skan    case RSHIFT_EXPR:
914117395Skan      pp_c_shift_expression (ppi, TREE_OPERAND (e, 0));
915117395Skan      pp_c_whitespace (ppi);
916117395Skan      pp_identifier (ppi, code == LSHIFT_EXPR ? "<<" : ">>");
917117395Skan      pp_c_whitespace (ppi);
918117395Skan      pp_c_additive_expression (ppi, TREE_OPERAND (e, 1));
919117395Skan      break;
920117395Skan
921117395Skan    default:
922117395Skan      pp_c_additive_expression (ppi, e);
923117395Skan    }
924117395Skan}
925117395Skan
926117395Skanstatic void
927117395Skanpp_c_relational_expression (ppi, e)
928117395Skan     c_pretty_printer ppi;
929117395Skan     tree e;
930117395Skan{
931117395Skan  enum tree_code code = TREE_CODE (e);
932117395Skan  switch (code)
933117395Skan    {
934117395Skan    case LT_EXPR:
935117395Skan    case GT_EXPR:
936117395Skan    case LE_EXPR:
937117395Skan    case GE_EXPR:
938117395Skan      pp_c_relational_expression (ppi, TREE_OPERAND (e, 0));
939117395Skan      pp_c_whitespace (ppi);
940117395Skan      if (code == LT_EXPR)
941117395Skan	pp_less (ppi);
942117395Skan      else if (code == GT_EXPR)
943117395Skan	pp_greater (ppi);
944117395Skan      else if (code == LE_EXPR)
945117395Skan	pp_identifier (ppi, "<=");
946117395Skan      else if (code == GE_EXPR)
947117395Skan	pp_identifier (ppi, ">=");
948117395Skan      pp_c_whitespace (ppi);
949117395Skan      pp_c_shift_expression (ppi, TREE_OPERAND (e, 1));
950117395Skan      break;
951117395Skan
952117395Skan    default:
953117395Skan      pp_c_shift_expression (ppi, e);
954117395Skan      break;
955117395Skan    }
956117395Skan}
957117395Skan
958117395Skanstatic inline void
959117395Skanpp_c_equality_expression (ppi, e)
960117395Skan     c_pretty_printer ppi;
961117395Skan     tree e;
962117395Skan{
963117395Skan  enum tree_code code = TREE_CODE (e);
964117395Skan  switch (code)
965117395Skan    {
966117395Skan    case EQ_EXPR:
967117395Skan    case NE_EXPR:
968117395Skan      pp_c_equality_expression (ppi, TREE_OPERAND (e, 0));
969117395Skan      pp_c_maybe_whitespace (ppi);
970117395Skan      pp_identifier (ppi, code == EQ_EXPR ? "==" : "!=");
971117395Skan      pp_c_whitespace (ppi);
972117395Skan      pp_c_relational_expression (ppi, TREE_OPERAND (e, 1));
973117395Skan      break;
974117395Skan
975117395Skan    default:
976117395Skan      pp_c_relational_expression (ppi, e);
977117395Skan      break;
978117395Skan    }
979117395Skan}
980117395Skan
981117395Skanstatic inline void
982117395Skanpp_c_and_expression (ppi, e)
983117395Skan     c_pretty_printer ppi;
984117395Skan     tree e;
985117395Skan{
986117395Skan  if (TREE_CODE (e) == BIT_AND_EXPR)
987117395Skan    {
988117395Skan      pp_c_and_expression (ppi, TREE_OPERAND (e, 0));
989117395Skan      pp_c_maybe_whitespace (ppi);
990117395Skan      pp_ampersand (ppi);
991117395Skan      pp_c_whitespace (ppi);
992117395Skan      pp_c_equality_expression (ppi, TREE_OPERAND (e, 1));
993117395Skan    }
994117395Skan  else
995117395Skan    pp_c_equality_expression (ppi, e);
996117395Skan}
997117395Skan
998117395Skanstatic inline void
999117395Skanpp_c_exclusive_or_expression (ppi, e)
1000117395Skan     c_pretty_printer ppi;
1001117395Skan     tree e;
1002117395Skan{
1003117395Skan  if (TREE_CODE (e) == BIT_XOR_EXPR)
1004117395Skan    {
1005117395Skan      pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 0));
1006117395Skan      pp_c_maybe_whitespace (ppi);
1007117395Skan      pp_carret (ppi);
1008117395Skan      pp_c_whitespace (ppi);
1009117395Skan      pp_c_and_expression (ppi, TREE_OPERAND (e, 1));
1010117395Skan    }
1011117395Skan  else
1012117395Skan    pp_c_and_expression (ppi, e);
1013117395Skan}
1014117395Skan
1015117395Skanstatic inline void
1016117395Skanpp_c_inclusive_or_expression (ppi, e)
1017117395Skan     c_pretty_printer ppi;
1018117395Skan     tree e;
1019117395Skan{
1020117395Skan  if (TREE_CODE (e) == BIT_IOR_EXPR)
1021117395Skan    {
1022117395Skan      pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 0));
1023117395Skan      pp_c_maybe_whitespace (ppi);
1024117395Skan      pp_bar (ppi);
1025117395Skan      pp_c_whitespace (ppi);
1026117395Skan      pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 1));
1027117395Skan    }
1028117395Skan  else
1029117395Skan    pp_c_exclusive_or_expression (ppi, e);
1030117395Skan}
1031117395Skan
1032117395Skanstatic inline void
1033117395Skanpp_c_logical_and_expression (ppi, e)
1034117395Skan     c_pretty_printer ppi;
1035117395Skan     tree e;
1036117395Skan{
1037117395Skan  if (TREE_CODE (e) == TRUTH_ANDIF_EXPR)
1038117395Skan    {
1039117395Skan      pp_c_logical_and_expression (ppi, TREE_OPERAND (e, 0));
1040117395Skan      pp_c_maybe_whitespace (ppi);
1041117395Skan      pp_identifier (ppi, "&&");
1042117395Skan      pp_c_whitespace (ppi);
1043117395Skan      pp_c_inclusive_or_expression (ppi, TREE_OPERAND (e, 1));
1044117395Skan    }
1045117395Skan  else
1046117395Skan    pp_c_inclusive_or_expression (ppi, e);
1047117395Skan}
1048117395Skan
1049117395Skanvoid
1050117395Skanpp_c_logical_or_expression (ppi, e)
1051117395Skan     c_pretty_printer ppi;
1052117395Skan     tree e;
1053117395Skan{
1054117395Skan  if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
1055117395Skan    {
1056117395Skan      pp_c_logical_or_expression (ppi, TREE_OPERAND (e, 0));
1057117395Skan      pp_c_maybe_whitespace (ppi);
1058117395Skan      pp_identifier (ppi, "||");
1059117395Skan      pp_c_whitespace (ppi);
1060117395Skan      pp_c_logical_and_expression (ppi, TREE_OPERAND (e, 1));
1061117395Skan    }
1062117395Skan  else
1063117395Skan    pp_c_logical_and_expression (ppi, e);
1064117395Skan}
1065117395Skan
1066117395Skanstatic void
1067117395Skanpp_c_conditional_expression (ppi, e)
1068117395Skan     c_pretty_printer ppi;
1069117395Skan     tree e;
1070117395Skan{
1071117395Skan  if (TREE_CODE (e) == COND_EXPR)
1072117395Skan    {
1073117395Skan      pp_c_logical_or_expression (ppi, TREE_OPERAND (e, 0));
1074117395Skan      pp_c_maybe_whitespace (ppi);
1075117395Skan      pp_question (ppi);
1076117395Skan      pp_c_whitespace (ppi);
1077117395Skan      pp_c_expression (ppi, TREE_OPERAND (e, 1));
1078117395Skan      pp_c_maybe_whitespace (ppi);
1079117395Skan      pp_colon (ppi);
1080117395Skan      pp_c_whitespace (ppi);
1081117395Skan      pp_c_conditional_expression (ppi, TREE_OPERAND (e, 2));
1082117395Skan    }
1083117395Skan  else
1084117395Skan    pp_c_logical_or_expression (ppi, e);
1085117395Skan}
1086117395Skan
1087117395Skan
1088117395Skan/* Pretty-print a C assignment-expression.  */
1089117395Skanstatic void
1090117395Skanpp_c_assignment_expression (ppi, e)
1091117395Skan     c_pretty_printer ppi;
1092117395Skan     tree e;
1093117395Skan{
1094117395Skan  if (TREE_CODE (e) == MODIFY_EXPR || TREE_CODE (e) == INIT_EXPR)
1095117395Skan    {
1096117395Skan      pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
1097117395Skan      pp_c_maybe_whitespace (ppi);
1098117395Skan      pp_equal (ppi);
1099117395Skan      pp_whitespace (ppi);
1100117395Skan      pp_c_assignment_expression (ppi, TREE_OPERAND (e, 1));
1101117395Skan    }
1102117395Skan  else
1103117395Skan    pp_c_conditional_expression (ppi, e);
1104117395Skan}
1105117395Skan
1106117395Skan/* Pretty-print an expression.  */
1107117395Skanvoid
1108117395Skanpp_c_expression (ppi, e)
1109117395Skan     c_pretty_printer ppi;
1110117395Skan     tree e;
1111117395Skan{
1112117395Skan  switch (TREE_CODE (e))
1113117395Skan    {
1114117395Skan    case INTEGER_CST:
1115117395Skan      pp_c_integer_literal (ppi, e);
1116117395Skan      break;
1117117395Skan
1118117395Skan    case REAL_CST:
1119117395Skan      pp_c_real_literal (ppi, e);
1120117395Skan      break;
1121117395Skan
1122117395Skan    case STRING_CST:
1123117395Skan      pp_c_string_literal (ppi, e);
1124117395Skan      break;
1125117395Skan
1126117395Skan    case FUNCTION_DECL:
1127117395Skan    case VAR_DECL:
1128117395Skan    case CONST_DECL:
1129117395Skan    case PARM_DECL:
1130117395Skan    case RESULT_DECL:
1131117395Skan    case FIELD_DECL:
1132117395Skan    case LABEL_DECL:
1133117395Skan    case ERROR_MARK:
1134117395Skan    case TARGET_EXPR:
1135117395Skan    case STMT_EXPR:
1136117395Skan      pp_c_primary_expression (ppi, e);
1137117395Skan      break;
1138117395Skan
1139117395Skan    case POSTINCREMENT_EXPR:
1140117395Skan    case POSTDECREMENT_EXPR:
1141117395Skan    case ARROW_EXPR:
1142117395Skan    case ARRAY_REF:
1143117395Skan    case CALL_EXPR:
1144117395Skan    case COMPONENT_REF:
1145117395Skan    case COMPLEX_CST:
1146117395Skan    case VECTOR_CST:
1147117395Skan    case ABS_EXPR:
1148117395Skan    case FFS_EXPR:
1149117395Skan    case CONSTRUCTOR:
1150117395Skan    case COMPOUND_LITERAL_EXPR:
1151117395Skan    case COMPLEX_EXPR:
1152117395Skan    case VA_ARG_EXPR:
1153117395Skan      pp_c_postfix_expression (ppi, e);
1154117395Skan      break;
1155117395Skan
1156117395Skan    case CONJ_EXPR:
1157117395Skan    case ADDR_EXPR:
1158117395Skan    case INDIRECT_REF:
1159117395Skan    case NEGATE_EXPR:
1160117395Skan    case BIT_NOT_EXPR:
1161117395Skan    case TRUTH_NOT_EXPR:
1162117395Skan    case PREINCREMENT_EXPR:
1163117395Skan    case PREDECREMENT_EXPR:
1164117395Skan    case SIZEOF_EXPR:
1165117395Skan    case ALIGNOF_EXPR:
1166117395Skan    case REALPART_EXPR:
1167117395Skan    case IMAGPART_EXPR:
1168117395Skan      pp_c_unary_expression (ppi, e);
1169117395Skan      break;
1170117395Skan
1171117395Skan    case CONVERT_EXPR:
1172117395Skan    case FLOAT_EXPR:
1173117395Skan      pp_c_cast_expression (ppi, e);
1174117395Skan      break;
1175117395Skan
1176117395Skan    case MULT_EXPR:
1177117395Skan    case TRUNC_MOD_EXPR:
1178117395Skan    case TRUNC_DIV_EXPR:
1179117395Skan      pp_c_multiplicative_expression (ppi, e);
1180117395Skan      break;
1181117395Skan
1182117395Skan    case LSHIFT_EXPR:
1183117395Skan    case RSHIFT_EXPR:
1184117395Skan      pp_c_shift_expression (ppi, e);
1185117395Skan      break;
1186117395Skan
1187117395Skan    case LT_EXPR:
1188117395Skan    case GT_EXPR:
1189117395Skan    case LE_EXPR:
1190117395Skan    case GE_EXPR:
1191117395Skan      pp_c_relational_expression (ppi, e);
1192117395Skan      break;
1193117395Skan
1194117395Skan    case BIT_AND_EXPR:
1195117395Skan      pp_c_and_expression (ppi, e);
1196117395Skan      break;
1197117395Skan
1198117395Skan    case BIT_XOR_EXPR:
1199117395Skan      pp_c_exclusive_or_expression (ppi, e);
1200117395Skan      break;
1201117395Skan
1202117395Skan    case BIT_IOR_EXPR:
1203117395Skan      pp_c_inclusive_or_expression (ppi, e);
1204117395Skan      break;
1205117395Skan
1206117395Skan    case TRUTH_ANDIF_EXPR:
1207117395Skan      pp_c_logical_and_expression (ppi, e);
1208117395Skan      break;
1209117395Skan
1210117395Skan    case TRUTH_ORIF_EXPR:
1211117395Skan      pp_c_logical_or_expression (ppi, e);
1212117395Skan      break;
1213117395Skan
1214117395Skan    case COND_EXPR:
1215117395Skan      pp_c_conditional_expression (ppi, e);
1216117395Skan      break;
1217117395Skan
1218117395Skan    case MODIFY_EXPR:
1219117395Skan    case INIT_EXPR:
1220117395Skan      pp_c_assignment_expression (ppi, e);
1221117395Skan      break;
1222117395Skan
1223117395Skan    case NOP_EXPR:
1224117395Skan      pp_c_expression (ppi, TREE_OPERAND (e, 0));
1225117395Skan      break;
1226117395Skan
1227117395Skan    case COMPOUND_EXPR:
1228117395Skan      pp_c_left_paren (ppi);
1229117395Skan      pp_c_expression (ppi, TREE_OPERAND (e, 0));
1230117395Skan      pp_separate_with (ppi, ',');
1231117395Skan      pp_assignment_expression (ppi, TREE_OPERAND (e, 1));
1232117395Skan      pp_c_right_paren (ppi);
1233117395Skan      break;
1234117395Skan
1235117395Skan
1236117395Skan    default:
1237117395Skan      pp_unsupported_tree (ppi, e);
1238117395Skan      break;
1239117395Skan    }
1240117395Skan}
1241117395Skan
1242117395Skan
1243117395Skan/* Statements.  */
1244117395Skanvoid
1245117395Skanpp_c_statement (ppi, stmt)
1246117395Skan     c_pretty_printer ppi;
1247117395Skan     tree stmt;
1248117395Skan{
1249117395Skan  const enum tree_code code = TREE_CODE (stmt);
1250117395Skan  switch (code)
1251117395Skan    {
1252117395Skan    case LABEL_STMT:
1253117395Skan    case CASE_LABEL:
1254117395Skan      pp_newline (ppi);
1255117395Skan      if (code == LABEL_STMT)
1256117395Skan	pp_tree_identifier (ppi, DECL_NAME (LABEL_STMT_LABEL (stmt)));
1257117395Skan      else if (code == LABEL_STMT)
1258117395Skan	{
1259117395Skan	  if (CASE_LOW (stmt) == NULL_TREE)
1260117395Skan	    pp_identifier (ppi, "default");
1261117395Skan	  else
1262117395Skan	    {
1263117395Skan	      pp_c_identifier (ppi, "case");
1264117395Skan	      pp_c_whitespace (ppi);
1265117395Skan	      pp_conditional_expression (ppi, CASE_LOW (stmt));
1266117395Skan	      if (CASE_HIGH (stmt))
1267117395Skan		{
1268117395Skan		  pp_identifier (ppi, "...");
1269117395Skan		  pp_conditional_expression (ppi, CASE_HIGH (stmt));
1270117395Skan		}
1271117395Skan	    }
1272117395Skan	}
1273117395Skan      pp_colon (ppi);
1274117395Skan      pp_newline_and_indent (ppi, 3);
1275117395Skan      break;
1276117395Skan
1277117395Skan    case COMPOUND_STMT:
1278117395Skan      pp_left_brace (ppi);
1279117395Skan      pp_newline_and_indent (ppi, 3);
1280117395Skan      for (stmt = COMPOUND_BODY (stmt); stmt; stmt = TREE_CHAIN (stmt))
1281117395Skan	pp_c_statement (ppi, stmt);
1282117395Skan      pp_newline_and_indent (ppi, -3);
1283117395Skan      pp_right_brace (ppi);
1284117395Skan      pp_newline (ppi);
1285117395Skan      break;
1286117395Skan
1287117395Skan    case EXPR_STMT:
1288117395Skan    case CLEANUP_STMT:
1289117395Skan      pp_newline (ppi);
1290117395Skan      pp_c_expression (ppi, code == EXPR_STMT
1291117395Skan		       ? EXPR_STMT_EXPR (stmt)
1292117395Skan		       : CLEANUP_EXPR (stmt));
1293117395Skan      pp_semicolon (ppi);
1294117395Skan      pp_newline (ppi);
1295117395Skan      break;
1296117395Skan
1297117395Skan    case IF_STMT:
1298117395Skan      pp_c_identifier (ppi, "if");
1299117395Skan      pp_whitespace (ppi);
1300117395Skan      pp_c_left_paren (ppi);
1301117395Skan      pp_c_expression (ppi, IF_COND (stmt));
1302117395Skan      pp_right_paren (ppi);
1303117395Skan      pp_newline_and_indent (ppi, 3);
1304117395Skan      pp_statement (ppi, THEN_CLAUSE (stmt));
1305117395Skan      pp_newline_and_indent (ppi, -3);
1306117395Skan      if (ELSE_CLAUSE (stmt))
1307117395Skan	{
1308117395Skan	  tree else_clause = ELSE_CLAUSE (stmt);
1309117395Skan	  pp_c_identifier (ppi, "else");
1310117395Skan	  if (TREE_CODE (else_clause) == IF_STMT)
1311117395Skan	    pp_c_whitespace (ppi);
1312117395Skan	  else
1313117395Skan	    pp_newline_and_indent (ppi, 3);
1314117395Skan	  pp_statement (ppi, else_clause);
1315117395Skan	  if (TREE_CODE (else_clause) != IF_STMT)
1316117395Skan	    pp_newline_and_indent (ppi, -3);
1317117395Skan	}
1318117395Skan      break;
1319117395Skan
1320117395Skan    case SWITCH_STMT:
1321117395Skan      pp_newline (ppi);
1322117395Skan      pp_c_identifier (ppi, "switch");
1323117395Skan      pp_whitespace (ppi);
1324117395Skan      pp_c_left_paren (ppi);
1325117395Skan      pp_c_expression (ppi, SWITCH_COND (stmt));
1326117395Skan      pp_right_paren (ppi);
1327117395Skan      pp_newline_and_indent (ppi, 3);
1328117395Skan      pp_statement (ppi, SWITCH_BODY (stmt));
1329117395Skan      pp_newline_and_indent (ppi, -3);
1330117395Skan      break;
1331117395Skan
1332117395Skan    case WHILE_STMT:
1333117395Skan      pp_c_identifier (ppi, "while");
1334117395Skan      pp_whitespace (ppi);
1335117395Skan      pp_c_left_paren (ppi);
1336117395Skan      pp_c_expression (ppi, WHILE_COND (stmt));
1337117395Skan      pp_right_paren (ppi);
1338117395Skan      pp_newline_and_indent (ppi, 3);
1339117395Skan      pp_statement (ppi, WHILE_BODY (stmt));
1340117395Skan      pp_newline_and_indent (ppi, -3);
1341117395Skan      break;
1342117395Skan
1343117395Skan    case DO_STMT:
1344117395Skan      pp_c_identifier (ppi, "do");
1345117395Skan      pp_newline_and_indent (ppi, 3);
1346117395Skan      pp_statement (ppi, DO_BODY (stmt));
1347117395Skan      pp_newline_and_indent (ppi, -3);
1348117395Skan      pp_c_identifier (ppi, "while");
1349117395Skan      pp_whitespace (ppi);
1350117395Skan      pp_c_left_paren (ppi);
1351117395Skan      pp_c_expression (ppi, DO_COND (stmt));
1352117395Skan      pp_c_right_paren (ppi);
1353117395Skan      pp_semicolon (ppi);
1354117395Skan      pp_newline (ppi);
1355117395Skan      break;
1356117395Skan
1357117395Skan    case FOR_STMT:
1358117395Skan      pp_c_identifier (ppi, "for");
1359117395Skan      pp_whitespace (ppi);
1360117395Skan      pp_c_left_paren (ppi);
1361117395Skan      pp_statement (ppi, FOR_INIT_STMT (stmt));
1362117395Skan      pp_c_whitespace (ppi);
1363117395Skan      if (FOR_COND (stmt))
1364117395Skan	pp_c_expression (ppi, FOR_COND (stmt));
1365117395Skan      pp_semicolon (ppi);
1366117395Skan      pp_c_whitespace (ppi);
1367117395Skan      if (FOR_EXPR (stmt))
1368117395Skan	pp_c_expression (ppi, FOR_EXPR (stmt));
1369117395Skan      pp_right_paren (ppi);
1370117395Skan      pp_newline_and_indent (ppi, 3);
1371117395Skan      pp_statement (ppi, FOR_BODY (stmt));
1372117395Skan      pp_newline_and_indent (ppi, -3);
1373117395Skan      break;
1374117395Skan
1375117395Skan    case BREAK_STMT:
1376117395Skan    case CONTINUE_STMT:
1377117395Skan      pp_newline (ppi);
1378117395Skan      pp_identifier (ppi, code == BREAK_STMT ? "break" : "continue");
1379117395Skan      pp_semicolon (ppi);
1380117395Skan      pp_newline (ppi);
1381117395Skan      break;
1382117395Skan
1383117395Skan    case RETURN_STMT:
1384117395Skan    case GOTO_STMT:
1385117395Skan      {
1386117395Skan	tree e = code == RETURN_STMT
1387117395Skan	  ? RETURN_STMT_EXPR (stmt)
1388117395Skan	  : GOTO_DESTINATION (stmt);
1389117395Skan
1390117395Skan	pp_newline (ppi);
1391117395Skan	pp_c_identifier (ppi, code == RETURN_STMT ? "return" : "goto");
1392117395Skan	if (e)
1393117395Skan	  pp_c_expression (ppi, e);
1394117395Skan	pp_semicolon (ppi);
1395117395Skan	pp_newline (ppi);
1396117395Skan      }
1397117395Skan      break;
1398117395Skan
1399117395Skan    case SCOPE_STMT:
1400117395Skan      if (!SCOPE_NULLIFIED_P (stmt) && SCOPE_NO_CLEANUPS_P (stmt))
1401117395Skan	{
1402117395Skan	  if (SCOPE_BEGIN_P (stmt))
1403117395Skan	    {
1404117395Skan	      pp_left_brace (ppi);
1405117395Skan	      pp_newline_and_indent (ppi, 3);
1406117395Skan	    }
1407117395Skan	  else if (SCOPE_END_P (stmt))
1408117395Skan	    {
1409117395Skan	      pp_right_brace (ppi);
1410117395Skan	      pp_newline_and_indent (ppi, -3);
1411117395Skan	    }
1412117395Skan	}
1413117395Skan      break;
1414117395Skan
1415117395Skan    case DECL_STMT:
1416117395Skan      pp_declaration (ppi, DECL_STMT_DECL (stmt));
1417117395Skan      pp_semicolon (ppi);
1418117395Skan      pp_newline (ppi);
1419117395Skan      break;
1420117395Skan
1421117395Skan    case ASM_STMT:
1422117395Skan      {
1423117395Skan	bool has_volatile_p = ASM_VOLATILE_P (stmt);
1424117395Skan	bool is_extended = has_volatile_p || ASM_INPUTS (stmt)
1425117395Skan	  || ASM_OUTPUTS (stmt) || ASM_CLOBBERS (stmt);
1426117395Skan	pp_c_identifier (ppi, is_extended ? "__asm__" : "asm");
1427117395Skan	if (has_volatile_p)
1428117395Skan	  pp_c_identifier (ppi, "__volatile__");
1429117395Skan	pp_whitespace (ppi);
1430117395Skan	pp_c_left_paren (ppi);
1431117395Skan	pp_c_string_literal (ppi, ASM_STRING (stmt));
1432117395Skan	if (is_extended)
1433117395Skan	  {
1434117395Skan	    pp_whitespace (ppi);
1435117395Skan	    pp_separate_with (ppi, ':');
1436117395Skan	    if (ASM_OUTPUTS (stmt))
1437117395Skan	      pp_c_expression (ppi, ASM_OUTPUTS (stmt));
1438117395Skan	    pp_whitespace (ppi);
1439117395Skan	    pp_separate_with (ppi, ':');
1440117395Skan	    if (ASM_INPUTS (stmt))
1441117395Skan	      pp_c_expression (ppi, ASM_INPUTS (stmt));
1442117395Skan	    pp_whitespace (ppi);
1443117395Skan	    pp_separate_with (ppi, ':');
1444117395Skan	    if (ASM_CLOBBERS (stmt))
1445117395Skan	      pp_c_expression (ppi, ASM_CLOBBERS (stmt));
1446117395Skan	  }
1447117395Skan	pp_right_paren (ppi);
1448117395Skan	pp_newline (ppi);
1449117395Skan      }
1450117395Skan      break;
1451117395Skan
1452117395Skan    case FILE_STMT:
1453117395Skan      pp_c_identifier (ppi, "__FILE__");
1454117395Skan      pp_whitespace (ppi);
1455117395Skan      pp_equal (ppi);
1456117395Skan      pp_c_whitespace (ppi);
1457117395Skan      pp_c_identifier (ppi, FILE_STMT_FILENAME (stmt));
1458117395Skan      pp_semicolon (ppi);
1459117395Skan      pp_newline (ppi);
1460117395Skan      break;
1461117395Skan
1462117395Skan    default:
1463117395Skan      pp_unsupported_tree (ppi, stmt);
1464117395Skan    }
1465117395Skan
1466117395Skan}
1467117395Skan
1468117395Skan
1469117395Skan/* Initialize the PRETTY-PRINTER for handling C codes.  */
1470117395Skanvoid
1471117395Skanpp_c_pretty_printer_init (pp)
1472117395Skan     c_pretty_printer pp;
1473117395Skan{
1474117395Skan  pp->offset_list               = 0;
1475117395Skan
1476117395Skan  pp->declaration               = pp_c_declaration;
1477117395Skan  pp->declaration_specifiers    = pp_c_declaration_specifiers;
1478117395Skan  pp->type_specifier            = pp_c_simple_type_specifier;
1479117395Skan  pp->declarator                = pp_c_declarator;
1480117395Skan  pp->direct_declarator         = pp_c_direct_declarator;
1481117395Skan  pp->parameter_declaration     = pp_c_parameter_declaration;
1482117395Skan  pp->type_id                   = pp_c_type_id;
1483117395Skan
1484117395Skan  pp->statement                 = pp_c_statement;
1485117395Skan
1486117395Skan  pp->primary_expression        = pp_c_primary_expression;
1487117395Skan  pp->postfix_expression        = pp_c_postfix_expression;
1488117395Skan  pp->unary_expression          = pp_c_unary_expression;
1489117395Skan  pp->initializer               = pp_c_initializer;
1490117395Skan  pp->multiplicative_expression = pp_c_multiplicative_expression;
1491117395Skan  pp->conditional_expression    = pp_c_conditional_expression;
1492117395Skan  pp->assignment_expression     = pp_c_assignment_expression;
1493117395Skan}
1494