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