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