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