1132718Skan/* Implementation of subroutines for the GNU C++ pretty-printer. 2169689Skan Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3132718Skan Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 4132718Skan 5132718SkanThis file is part of GCC. 6132718Skan 7132718SkanGCC is free software; you can redistribute it and/or modify it under 8132718Skanthe terms of the GNU General Public License as published by the Free 9132718SkanSoftware Foundation; either version 2, or (at your option) any later 10132718Skanversion. 11132718Skan 12132718SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13132718SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 14132718SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15132718Skanfor more details. 16132718Skan 17132718SkanYou should have received a copy of the GNU General Public License 18132718Skanalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 21132718Skan 22132718Skan#include "config.h" 23132718Skan#include "system.h" 24132718Skan#include "coretypes.h" 25132718Skan#include "tm.h" 26132718Skan#include "real.h" 27132718Skan#include "cxx-pretty-print.h" 28132718Skan#include "cp-tree.h" 29132718Skan#include "toplev.h" 30132718Skan 31132718Skanstatic void pp_cxx_unqualified_id (cxx_pretty_printer *, tree); 32132718Skanstatic void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree); 33132718Skanstatic void pp_cxx_qualified_id (cxx_pretty_printer *, tree); 34132718Skanstatic void pp_cxx_assignment_expression (cxx_pretty_printer *, tree); 35132718Skanstatic void pp_cxx_expression (cxx_pretty_printer *, tree); 36132718Skanstatic void pp_cxx_template_argument_list (cxx_pretty_printer *, tree); 37132718Skanstatic void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree); 38132718Skanstatic void pp_cxx_ptr_operator (cxx_pretty_printer *, tree); 39132718Skanstatic void pp_cxx_type_id (cxx_pretty_printer *, tree); 40132718Skanstatic void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree); 41132718Skanstatic void pp_cxx_declarator (cxx_pretty_printer *, tree); 42169689Skanstatic void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree); 43132718Skanstatic void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree); 44169689Skanstatic void pp_cxx_statement (cxx_pretty_printer *, tree); 45132718Skanstatic void pp_cxx_template_parameter (cxx_pretty_printer *, tree); 46169689Skanstatic void pp_cxx_cast_expression (cxx_pretty_printer *, tree); 47132718Skan 48132718Skan 49132718Skanstatic inline void 50132718Skanpp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c) 51132718Skan{ 52132718Skan const char *p = pp_last_position_in_text (pp); 53132718Skan 54132718Skan if (p != NULL && *p == c) 55132718Skan pp_cxx_whitespace (pp); 56132718Skan pp_character (pp, c); 57132718Skan pp_base (pp)->padding = pp_none; 58132718Skan} 59132718Skan 60132718Skan#define pp_cxx_storage_class_specifier(PP, T) \ 61132718Skan pp_c_storage_class_specifier (pp_c_base (PP), T) 62132718Skan#define pp_cxx_expression_list(PP, T) \ 63132718Skan pp_c_expression_list (pp_c_base (PP), T) 64132718Skan#define pp_cxx_space_for_pointer_operator(PP, T) \ 65132718Skan pp_c_space_for_pointer_operator (pp_c_base (PP), T) 66132718Skan#define pp_cxx_init_declarator(PP, T) \ 67132718Skan pp_c_init_declarator (pp_c_base (PP), T) 68132718Skan#define pp_cxx_call_argument_list(PP, T) \ 69132718Skan pp_c_call_argument_list (pp_c_base (PP), T) 70132718Skan 71169689Skanvoid 72132718Skanpp_cxx_colon_colon (cxx_pretty_printer *pp) 73132718Skan{ 74132718Skan pp_colon_colon (pp); 75132718Skan pp_base (pp)->padding = pp_none; 76132718Skan} 77132718Skan 78169689Skanvoid 79169689Skanpp_cxx_begin_template_argument_list (cxx_pretty_printer *pp) 80169689Skan{ 81169689Skan pp_cxx_nonconsecutive_character (pp, '<'); 82169689Skan} 83132718Skan 84169689Skanvoid 85169689Skanpp_cxx_end_template_argument_list (cxx_pretty_printer *pp) 86169689Skan{ 87169689Skan pp_cxx_nonconsecutive_character (pp, '>'); 88169689Skan} 89169689Skan 90169689Skanvoid 91169689Skanpp_cxx_separate_with (cxx_pretty_printer *pp, int c) 92169689Skan{ 93169689Skan pp_separate_with (pp, c); 94169689Skan pp_base (pp)->padding = pp_none; 95169689Skan} 96169689Skan 97132718Skan/* Expressions. */ 98132718Skan 99132718Skanstatic inline bool 100132718Skanis_destructor_name (tree name) 101132718Skan{ 102132718Skan return name == complete_dtor_identifier 103132718Skan || name == base_dtor_identifier 104132718Skan || name == deleting_dtor_identifier; 105132718Skan} 106132718Skan 107132718Skan/* conversion-function-id: 108132718Skan operator conversion-type-id 109132718Skan 110132718Skan conversion-type-id: 111132718Skan type-specifier-seq conversion-declarator(opt) 112132718Skan 113132718Skan conversion-declarator: 114132718Skan ptr-operator conversion-declarator(opt) */ 115169689Skan 116132718Skanstatic inline void 117132718Skanpp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t) 118132718Skan{ 119132718Skan pp_cxx_identifier (pp, "operator"); 120132718Skan pp_cxx_type_specifier_seq (pp, TREE_TYPE (t)); 121132718Skan} 122132718Skan 123132718Skanstatic inline void 124132718Skanpp_cxx_template_id (cxx_pretty_printer *pp, tree t) 125132718Skan{ 126132718Skan pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0)); 127132718Skan pp_cxx_begin_template_argument_list (pp); 128132718Skan pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1)); 129132718Skan pp_cxx_end_template_argument_list (pp); 130132718Skan} 131132718Skan 132132718Skan/* unqualified-id: 133132718Skan identifier 134132718Skan operator-function-id 135132718Skan conversion-function-id 136132718Skan ~ class-name 137132718Skan template-id */ 138169689Skan 139132718Skanstatic void 140132718Skanpp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t) 141132718Skan{ 142132718Skan enum tree_code code = TREE_CODE (t); 143132718Skan switch (code) 144132718Skan { 145132718Skan case RESULT_DECL: 146132718Skan pp_cxx_identifier (pp, "<return-value>"); 147132718Skan break; 148132718Skan 149132718Skan case OVERLOAD: 150169689Skan t = OVL_CURRENT (t); 151132718Skan case VAR_DECL: 152132718Skan case PARM_DECL: 153132718Skan case CONST_DECL: 154132718Skan case TYPE_DECL: 155132718Skan case FUNCTION_DECL: 156132718Skan case NAMESPACE_DECL: 157132718Skan case FIELD_DECL: 158132718Skan case LABEL_DECL: 159132718Skan case USING_DECL: 160132718Skan case TEMPLATE_DECL: 161132718Skan t = DECL_NAME (t); 162169689Skan 163132718Skan case IDENTIFIER_NODE: 164132718Skan if (t == NULL) 165169689Skan pp_cxx_identifier (pp, "<unnamed>"); 166132718Skan else if (IDENTIFIER_TYPENAME_P (t)) 167169689Skan pp_cxx_conversion_function_id (pp, t); 168132718Skan else 169169689Skan { 170169689Skan if (is_destructor_name (t)) 171169689Skan { 172169689Skan pp_complement (pp); 173169689Skan /* FIXME: Why is this necessary? */ 174169689Skan if (TREE_TYPE (t)) 175169689Skan t = constructor_name (TREE_TYPE (t)); 176169689Skan } 177169689Skan pp_cxx_tree_identifier (pp, t); 178169689Skan } 179132718Skan break; 180132718Skan 181132718Skan case TEMPLATE_ID_EXPR: 182132718Skan pp_cxx_template_id (pp, t); 183132718Skan break; 184132718Skan 185146895Skan case BASELINK: 186146895Skan pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t)); 187146895Skan break; 188146895Skan 189132718Skan case RECORD_TYPE: 190132718Skan case UNION_TYPE: 191132718Skan case ENUMERAL_TYPE: 192132718Skan pp_cxx_unqualified_id (pp, TYPE_NAME (t)); 193132718Skan break; 194132718Skan 195132718Skan case TEMPLATE_TYPE_PARM: 196169689Skan case TEMPLATE_TEMPLATE_PARM: 197169689Skan if (TYPE_IDENTIFIER (t)) 198169689Skan pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t)); 199169689Skan else 200169689Skan pp_cxx_canonical_template_parameter (pp, t); 201169689Skan break; 202169689Skan 203132718Skan case TEMPLATE_PARM_INDEX: 204132718Skan pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t)); 205132718Skan break; 206132718Skan 207220150Smm case UNBOUND_CLASS_TEMPLATE: 208220150Smm pp_cxx_unqualified_id (pp, TYPE_NAME (t)); 209220150Smm break; 210220150Smm 211132718Skan default: 212132718Skan pp_unsupported_tree (pp, t); 213132718Skan break; 214132718Skan } 215132718Skan} 216132718Skan 217169689Skan/* Pretty-print out the token sequence ":: template" in template codes 218169689Skan where it is needed to "inline declare" the (following) member as 219169689Skan a template. This situation arises when SCOPE of T is dependent 220169689Skan on template parameters. */ 221169689Skan 222132718Skanstatic inline void 223132718Skanpp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t) 224132718Skan{ 225132718Skan if (TREE_CODE (t) == TEMPLATE_ID_EXPR 226132718Skan && TYPE_P (scope) && dependent_type_p (scope)) 227132718Skan pp_cxx_identifier (pp, "template"); 228132718Skan} 229132718Skan 230132718Skan/* nested-name-specifier: 231132718Skan class-or-namespace-name :: nested-name-specifier(opt) 232132718Skan class-or-namespace-name :: template nested-name-specifier */ 233169689Skan 234132718Skanstatic void 235132718Skanpp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t) 236132718Skan{ 237132718Skan if (t != NULL && t != pp->enclosing_scope) 238132718Skan { 239132718Skan tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t); 240132718Skan pp_cxx_nested_name_specifier (pp, scope); 241132718Skan pp_cxx_template_keyword_if_needed (pp, scope, t); 242132718Skan pp_cxx_unqualified_id (pp, t); 243132718Skan pp_cxx_colon_colon (pp); 244132718Skan } 245132718Skan} 246132718Skan 247132718Skan/* qualified-id: 248132718Skan nested-name-specifier template(opt) unqualified-id */ 249169689Skan 250132718Skanstatic void 251132718Skanpp_cxx_qualified_id (cxx_pretty_printer *pp, tree t) 252132718Skan{ 253132718Skan switch (TREE_CODE (t)) 254132718Skan { 255169689Skan /* A pointer-to-member is always qualified. */ 256132718Skan case PTRMEM_CST: 257132718Skan pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t)); 258132718Skan pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t)); 259132718Skan break; 260132718Skan 261169689Skan /* In Standard C++, functions cannot possibly be used as 262169689Skan nested-name-specifiers. However, there are situations where 263169689Skan is "makes sense" to output the surrounding function name for the 264169689Skan purpose of emphasizing on the scope kind. Just printing the 265169689Skan function name might not be sufficient as it may be overloaded; so, 266169689Skan we decorate the function with its signature too. 267169689Skan FIXME: This is probably the wrong pretty-printing for conversion 268169689Skan functions and some function templates. */ 269132718Skan case OVERLOAD: 270132718Skan t = OVL_CURRENT (t); 271132718Skan case FUNCTION_DECL: 272132718Skan if (DECL_FUNCTION_MEMBER_P (t)) 273169689Skan pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 274132718Skan pp_cxx_unqualified_id 275169689Skan (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t); 276169689Skan pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t)); 277132718Skan break; 278132718Skan 279132718Skan case OFFSET_REF: 280132718Skan case SCOPE_REF: 281132718Skan pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0)); 282132718Skan pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1)); 283132718Skan break; 284132718Skan 285132718Skan default: 286132718Skan { 287169689Skan tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t); 288169689Skan if (scope != pp->enclosing_scope) 289169689Skan { 290169689Skan pp_cxx_nested_name_specifier (pp, scope); 291169689Skan pp_cxx_template_keyword_if_needed (pp, scope, t); 292169689Skan } 293169689Skan pp_cxx_unqualified_id (pp, t); 294132718Skan } 295132718Skan break; 296132718Skan } 297132718Skan} 298132718Skan 299169689Skan 300169689Skanstatic void 301169689Skanpp_cxx_constant (cxx_pretty_printer *pp, tree t) 302169689Skan{ 303169689Skan switch (TREE_CODE (t)) 304169689Skan { 305169689Skan case STRING_CST: 306169689Skan { 307169689Skan const bool in_parens = PAREN_STRING_LITERAL_P (t); 308169689Skan if (in_parens) 309169689Skan pp_cxx_left_paren (pp); 310169689Skan pp_c_constant (pp_c_base (pp), t); 311169689Skan if (in_parens) 312169689Skan pp_cxx_right_paren (pp); 313169689Skan } 314169689Skan break; 315169689Skan 316169689Skan default: 317169689Skan pp_c_constant (pp_c_base (pp), t); 318169689Skan break; 319169689Skan } 320169689Skan} 321169689Skan 322132718Skan/* id-expression: 323132718Skan unqualified-id 324132718Skan qualified-id */ 325169689Skan 326132718Skanstatic inline void 327132718Skanpp_cxx_id_expression (cxx_pretty_printer *pp, tree t) 328132718Skan{ 329132718Skan if (TREE_CODE (t) == OVERLOAD) 330132718Skan t = OVL_CURRENT (t); 331132718Skan if (DECL_P (t) && DECL_CONTEXT (t)) 332132718Skan pp_cxx_qualified_id (pp, t); 333132718Skan else 334132718Skan pp_cxx_unqualified_id (pp, t); 335132718Skan} 336132718Skan 337132718Skan/* primary-expression: 338132718Skan literal 339132718Skan this 340132718Skan :: identifier 341132718Skan :: operator-function-id 342132718Skan :: qualifier-id 343132718Skan ( expression ) 344132718Skan id-expression */ 345169689Skan 346132718Skanstatic void 347132718Skanpp_cxx_primary_expression (cxx_pretty_printer *pp, tree t) 348132718Skan{ 349132718Skan switch (TREE_CODE (t)) 350132718Skan { 351132718Skan case INTEGER_CST: 352132718Skan case REAL_CST: 353169689Skan case STRING_CST: 354169689Skan pp_cxx_constant (pp, t); 355132718Skan break; 356132718Skan 357132718Skan case BASELINK: 358132718Skan t = BASELINK_FUNCTIONS (t); 359132718Skan case VAR_DECL: 360132718Skan case PARM_DECL: 361132718Skan case FIELD_DECL: 362132718Skan case FUNCTION_DECL: 363132718Skan case OVERLOAD: 364132718Skan case CONST_DECL: 365132718Skan case TEMPLATE_DECL: 366132718Skan pp_cxx_id_expression (pp, t); 367132718Skan break; 368132718Skan 369132718Skan case RESULT_DECL: 370132718Skan case TEMPLATE_TYPE_PARM: 371169689Skan case TEMPLATE_TEMPLATE_PARM: 372132718Skan case TEMPLATE_PARM_INDEX: 373132718Skan pp_cxx_unqualified_id (pp, t); 374132718Skan break; 375132718Skan 376169689Skan case STMT_EXPR: 377169689Skan pp_cxx_left_paren (pp); 378169689Skan pp_cxx_statement (pp, STMT_EXPR_STMT (t)); 379169689Skan pp_cxx_right_paren (pp); 380169689Skan break; 381169689Skan 382132718Skan default: 383132718Skan pp_c_primary_expression (pp_c_base (pp), t); 384132718Skan break; 385132718Skan } 386132718Skan} 387132718Skan 388132718Skan/* postfix-expression: 389132718Skan primary-expression 390132718Skan postfix-expression [ expression ] 391132718Skan postfix-expression ( expression-list(opt) ) 392132718Skan simple-type-specifier ( expression-list(opt) ) 393132718Skan typename ::(opt) nested-name-specifier identifier ( expression-list(opt) ) 394132718Skan typename ::(opt) nested-name-specifier template(opt) 395169689Skan template-id ( expression-list(opt) ) 396132718Skan postfix-expression . template(opt) ::(opt) id-expression 397132718Skan postfix-expression -> template(opt) ::(opt) id-expression 398132718Skan postfix-expression . pseudo-destructor-name 399132718Skan postfix-expression -> pseudo-destructor-name 400132718Skan postfix-expression ++ 401132718Skan postfix-expression -- 402132718Skan dynamic_cast < type-id > ( expression ) 403132718Skan static_cast < type-id > ( expression ) 404132718Skan reinterpret_cast < type-id > ( expression ) 405132718Skan const_cast < type-id > ( expression ) 406132718Skan typeid ( expression ) 407132718Skan typeif ( type-id ) */ 408132718Skan 409132718Skanstatic void 410132718Skanpp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t) 411132718Skan{ 412132718Skan enum tree_code code = TREE_CODE (t); 413169689Skan 414132718Skan switch (code) 415132718Skan { 416132718Skan case AGGR_INIT_EXPR: 417132718Skan case CALL_EXPR: 418132718Skan { 419169689Skan tree fun = TREE_OPERAND (t, 0); 420169689Skan tree args = TREE_OPERAND (t, 1); 421169689Skan tree saved_scope = pp->enclosing_scope; 422132718Skan 423169689Skan if (TREE_CODE (fun) == ADDR_EXPR) 424169689Skan fun = TREE_OPERAND (fun, 0); 425132718Skan 426169689Skan /* In templates, where there is no way to tell whether a given 427169689Skan call uses an actual member function. So the parser builds 428169689Skan FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until 429169689Skan instantiation time. */ 430169689Skan if (TREE_CODE (fun) != FUNCTION_DECL) 431169689Skan ; 432169689Skan else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)) 433169689Skan { 434169689Skan tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t) 435169689Skan ? TREE_OPERAND (t, 2) 436169689Skan : TREE_VALUE (args); 437132718Skan 438169689Skan while (TREE_CODE (object) == NOP_EXPR) 439169689Skan object = TREE_OPERAND (object, 0); 440132718Skan 441169689Skan if (TREE_CODE (object) == ADDR_EXPR) 442169689Skan object = TREE_OPERAND (object, 0); 443169689Skan 444169689Skan if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE) 445169689Skan { 446169689Skan pp_cxx_postfix_expression (pp, object); 447169689Skan pp_cxx_dot (pp); 448169689Skan } 449169689Skan else 450169689Skan { 451169689Skan pp_cxx_postfix_expression (pp, object); 452169689Skan pp_cxx_arrow (pp); 453169689Skan } 454169689Skan args = TREE_CHAIN (args); 455169689Skan pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object)); 456169689Skan } 457169689Skan 458169689Skan pp_cxx_postfix_expression (pp, fun); 459169689Skan pp->enclosing_scope = saved_scope; 460169689Skan pp_cxx_call_argument_list (pp, args); 461132718Skan } 462132718Skan if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)) 463169689Skan { 464169689Skan pp_cxx_separate_with (pp, ','); 465169689Skan pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2)); 466169689Skan } 467132718Skan break; 468132718Skan 469132718Skan case BASELINK: 470132718Skan case VAR_DECL: 471132718Skan case PARM_DECL: 472132718Skan case FIELD_DECL: 473132718Skan case FUNCTION_DECL: 474132718Skan case OVERLOAD: 475132718Skan case CONST_DECL: 476132718Skan case TEMPLATE_DECL: 477132718Skan case RESULT_DECL: 478132718Skan pp_cxx_primary_expression (pp, t); 479132718Skan break; 480132718Skan 481132718Skan case DYNAMIC_CAST_EXPR: 482132718Skan case STATIC_CAST_EXPR: 483132718Skan case REINTERPRET_CAST_EXPR: 484132718Skan case CONST_CAST_EXPR: 485132718Skan if (code == DYNAMIC_CAST_EXPR) 486169689Skan pp_cxx_identifier (pp, "dynamic_cast"); 487132718Skan else if (code == STATIC_CAST_EXPR) 488169689Skan pp_cxx_identifier (pp, "static_cast"); 489132718Skan else if (code == REINTERPRET_CAST_EXPR) 490169689Skan pp_cxx_identifier (pp, "reinterpret_cast"); 491132718Skan else 492169689Skan pp_cxx_identifier (pp, "const_cast"); 493132718Skan pp_cxx_begin_template_argument_list (pp); 494132718Skan pp_cxx_type_id (pp, TREE_TYPE (t)); 495132718Skan pp_cxx_end_template_argument_list (pp); 496132718Skan pp_left_paren (pp); 497132718Skan pp_cxx_expression (pp, TREE_OPERAND (t, 0)); 498132718Skan pp_right_paren (pp); 499132718Skan break; 500132718Skan 501132718Skan case EMPTY_CLASS_EXPR: 502132718Skan pp_cxx_type_id (pp, TREE_TYPE (t)); 503132718Skan pp_left_paren (pp); 504132718Skan pp_right_paren (pp); 505132718Skan break; 506132718Skan 507132718Skan case TYPEID_EXPR: 508132718Skan t = TREE_OPERAND (t, 0); 509132718Skan pp_cxx_identifier (pp, "typeid"); 510132718Skan pp_left_paren (pp); 511132718Skan if (TYPE_P (t)) 512169689Skan pp_cxx_type_id (pp, t); 513132718Skan else 514169689Skan pp_cxx_expression (pp, t); 515132718Skan pp_right_paren (pp); 516132718Skan break; 517132718Skan 518132718Skan case PSEUDO_DTOR_EXPR: 519132718Skan pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0)); 520132718Skan pp_cxx_dot (pp); 521132718Skan pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1)); 522132718Skan pp_cxx_colon_colon (pp); 523132718Skan pp_complement (pp); 524132718Skan pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2)); 525132718Skan break; 526132718Skan 527169689Skan case ARROW_EXPR: 528169689Skan pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0)); 529169689Skan pp_cxx_arrow (pp); 530169689Skan break; 531169689Skan 532132718Skan default: 533132718Skan pp_c_postfix_expression (pp_c_base (pp), t); 534132718Skan break; 535132718Skan } 536132718Skan} 537132718Skan 538132718Skan/* new-expression: 539132718Skan ::(opt) new new-placement(opt) new-type-id new-initializer(opt) 540132718Skan ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt) 541132718Skan 542132718Skan new-placement: 543132718Skan ( expression-list ) 544132718Skan 545132718Skan new-type-id: 546132718Skan type-specifier-seq new-declarator(opt) 547132718Skan 548132718Skan new-declarator: 549132718Skan ptr-operator new-declarator(opt) 550132718Skan direct-new-declarator 551132718Skan 552132718Skan direct-new-declarator 553132718Skan [ expression ] 554132718Skan direct-new-declarator [ constant-expression ] 555132718Skan 556132718Skan new-initializer: 557132718Skan ( expression-list(opt) ) */ 558169689Skan 559132718Skanstatic void 560132718Skanpp_cxx_new_expression (cxx_pretty_printer *pp, tree t) 561132718Skan{ 562132718Skan enum tree_code code = TREE_CODE (t); 563132718Skan switch (code) 564132718Skan { 565132718Skan case NEW_EXPR: 566132718Skan case VEC_NEW_EXPR: 567132718Skan if (NEW_EXPR_USE_GLOBAL (t)) 568169689Skan pp_cxx_colon_colon (pp); 569132718Skan pp_cxx_identifier (pp, "new"); 570132718Skan if (TREE_OPERAND (t, 0)) 571169689Skan { 572169689Skan pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0)); 573169689Skan pp_space (pp); 574169689Skan } 575132718Skan /* FIXME: array-types are built with one more element. */ 576132718Skan pp_cxx_type_id (pp, TREE_OPERAND (t, 1)); 577132718Skan if (TREE_OPERAND (t, 2)) 578169689Skan { 579169689Skan pp_left_paren (pp); 580169689Skan t = TREE_OPERAND (t, 2); 581169689Skan if (TREE_CODE (t) == TREE_LIST) 582169689Skan pp_c_expression_list (pp_c_base (pp), t); 583169689Skan else if (t == void_zero_node) 584169689Skan ; /* OK, empty initializer list. */ 585169689Skan else 586169689Skan pp_cxx_expression (pp, t); 587169689Skan pp_right_paren (pp); 588169689Skan } 589132718Skan break; 590132718Skan 591132718Skan default: 592132718Skan pp_unsupported_tree (pp, t); 593132718Skan } 594132718Skan} 595132718Skan 596132718Skan/* delete-expression: 597132718Skan ::(opt) delete cast-expression 598132718Skan ::(opt) delete [ ] cast-expression */ 599169689Skan 600132718Skanstatic void 601132718Skanpp_cxx_delete_expression (cxx_pretty_printer *pp, tree t) 602132718Skan{ 603132718Skan enum tree_code code = TREE_CODE (t); 604132718Skan switch (code) 605132718Skan { 606132718Skan case DELETE_EXPR: 607132718Skan case VEC_DELETE_EXPR: 608132718Skan if (DELETE_EXPR_USE_GLOBAL (t)) 609169689Skan pp_cxx_colon_colon (pp); 610132718Skan pp_cxx_identifier (pp, "delete"); 611132718Skan if (code == VEC_DELETE_EXPR) 612169689Skan { 613169689Skan pp_left_bracket (pp); 614169689Skan pp_right_bracket (pp); 615169689Skan } 616132718Skan pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0)); 617169689Skan break; 618169689Skan 619132718Skan default: 620132718Skan pp_unsupported_tree (pp, t); 621132718Skan } 622132718Skan} 623132718Skan 624132718Skan/* unary-expression: 625132718Skan postfix-expression 626132718Skan ++ cast-expression 627132718Skan -- cast-expression 628132718Skan unary-operator cast-expression 629132718Skan sizeof unary-expression 630132718Skan sizeof ( type-id ) 631132718Skan new-expression 632132718Skan delete-expression 633132718Skan 634132718Skan unary-operator: one of 635132718Skan * & + - ! 636132718Skan 637132718Skan GNU extensions: 638132718Skan __alignof__ unary-expression 639132718Skan __alignof__ ( type-id ) */ 640169689Skan 641132718Skanstatic void 642132718Skanpp_cxx_unary_expression (cxx_pretty_printer *pp, tree t) 643132718Skan{ 644132718Skan enum tree_code code = TREE_CODE (t); 645132718Skan switch (code) 646132718Skan { 647132718Skan case NEW_EXPR: 648132718Skan case VEC_NEW_EXPR: 649132718Skan pp_cxx_new_expression (pp, t); 650132718Skan break; 651132718Skan 652132718Skan case DELETE_EXPR: 653132718Skan case VEC_DELETE_EXPR: 654132718Skan pp_cxx_delete_expression (pp, t); 655132718Skan break; 656169689Skan 657169689Skan case SIZEOF_EXPR: 658169689Skan case ALIGNOF_EXPR: 659169689Skan pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__"); 660169689Skan pp_cxx_whitespace (pp); 661169689Skan if (TYPE_P (TREE_OPERAND (t, 0))) 662169689Skan { 663169689Skan pp_cxx_left_paren (pp); 664169689Skan pp_cxx_type_id (pp, TREE_OPERAND (t, 0)); 665169689Skan pp_cxx_right_paren (pp); 666169689Skan } 667169689Skan else 668169689Skan pp_unary_expression (pp, TREE_OPERAND (t, 0)); 669169689Skan break; 670169689Skan 671169689Skan case UNARY_PLUS_EXPR: 672169689Skan pp_plus (pp); 673169689Skan pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0)); 674169689Skan break; 675169689Skan 676132718Skan default: 677132718Skan pp_c_unary_expression (pp_c_base (pp), t); 678132718Skan break; 679132718Skan } 680132718Skan} 681132718Skan 682132718Skan/* cast-expression: 683132718Skan unary-expression 684132718Skan ( type-id ) cast-expression */ 685169689Skan 686132718Skanstatic void 687132718Skanpp_cxx_cast_expression (cxx_pretty_printer *pp, tree t) 688132718Skan{ 689132718Skan switch (TREE_CODE (t)) 690132718Skan { 691132718Skan case CAST_EXPR: 692132718Skan pp_cxx_type_id (pp, TREE_TYPE (t)); 693132718Skan pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0)); 694132718Skan break; 695132718Skan 696132718Skan default: 697132718Skan pp_c_cast_expression (pp_c_base (pp), t); 698132718Skan break; 699132718Skan } 700132718Skan} 701132718Skan 702132718Skan/* pm-expression: 703132718Skan cast-expression 704132718Skan pm-expression .* cast-expression 705132718Skan pm-expression ->* cast-expression */ 706169689Skan 707132718Skanstatic void 708132718Skanpp_cxx_pm_expression (cxx_pretty_printer *pp, tree t) 709132718Skan{ 710132718Skan switch (TREE_CODE (t)) 711132718Skan { 712132718Skan /* Handle unfortunate OFFESET_REF overloading here. */ 713132718Skan case OFFSET_REF: 714132718Skan if (TYPE_P (TREE_OPERAND (t, 0))) 715169689Skan { 716169689Skan pp_cxx_qualified_id (pp, t); 717169689Skan break; 718169689Skan } 719132718Skan /* Else fall through. */ 720132718Skan case MEMBER_REF: 721132718Skan case DOTSTAR_EXPR: 722132718Skan pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0)); 723132718Skan pp_cxx_dot (pp); 724132718Skan pp_star(pp); 725132718Skan pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1)); 726132718Skan break; 727132718Skan 728132718Skan 729132718Skan default: 730132718Skan pp_cxx_cast_expression (pp, t); 731132718Skan break; 732132718Skan } 733132718Skan} 734132718Skan 735132718Skan/* multiplicative-expression: 736132718Skan pm-expression 737132718Skan multiplicative-expression * pm-expression 738132718Skan multiplicative-expression / pm-expression 739132718Skan multiplicative-expression % pm-expression */ 740169689Skan 741132718Skanstatic void 742132718Skanpp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e) 743132718Skan{ 744132718Skan enum tree_code code = TREE_CODE (e); 745132718Skan switch (code) 746132718Skan { 747132718Skan case MULT_EXPR: 748132718Skan case TRUNC_DIV_EXPR: 749132718Skan case TRUNC_MOD_EXPR: 750132718Skan pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0)); 751132718Skan pp_space (pp); 752132718Skan if (code == MULT_EXPR) 753132718Skan pp_star (pp); 754132718Skan else if (code == TRUNC_DIV_EXPR) 755132718Skan pp_slash (pp); 756132718Skan else 757132718Skan pp_modulo (pp); 758132718Skan pp_space (pp); 759132718Skan pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1)); 760132718Skan break; 761132718Skan 762132718Skan default: 763132718Skan pp_cxx_pm_expression (pp, e); 764132718Skan break; 765132718Skan } 766132718Skan} 767132718Skan 768132718Skan/* conditional-expression: 769132718Skan logical-or-expression 770132718Skan logical-or-expression ? expression : assignment-expression */ 771169689Skan 772132718Skanstatic void 773132718Skanpp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e) 774132718Skan{ 775132718Skan if (TREE_CODE (e) == COND_EXPR) 776132718Skan { 777132718Skan pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0)); 778132718Skan pp_space (pp); 779132718Skan pp_question (pp); 780132718Skan pp_space (pp); 781132718Skan pp_cxx_expression (pp, TREE_OPERAND (e, 1)); 782132718Skan pp_space (pp); 783132718Skan pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2)); 784132718Skan } 785132718Skan else 786132718Skan pp_c_logical_or_expression (pp_c_base (pp), e); 787132718Skan} 788132718Skan 789169689Skan/* Pretty-print a compound assignment operator token as indicated by T. */ 790169689Skan 791132718Skanstatic void 792132718Skanpp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t) 793132718Skan{ 794132718Skan const char *op; 795132718Skan 796132718Skan switch (TREE_CODE (t)) 797132718Skan { 798132718Skan case NOP_EXPR: 799132718Skan op = "="; 800132718Skan break; 801132718Skan 802132718Skan case PLUS_EXPR: 803132718Skan op = "+="; 804132718Skan break; 805132718Skan 806132718Skan case MINUS_EXPR: 807132718Skan op = "-="; 808132718Skan break; 809132718Skan 810132718Skan case TRUNC_DIV_EXPR: 811132718Skan op = "/="; 812132718Skan break; 813132718Skan 814132718Skan case TRUNC_MOD_EXPR: 815132718Skan op = "%="; 816132718Skan break; 817132718Skan 818132718Skan default: 819132718Skan op = tree_code_name[TREE_CODE (t)]; 820132718Skan break; 821132718Skan } 822132718Skan 823132718Skan pp_cxx_identifier (pp, op); 824132718Skan} 825132718Skan 826132718Skan 827132718Skan/* assignment-expression: 828132718Skan conditional-expression 829132718Skan logical-or-expression assignment-operator assignment-expression 830132718Skan throw-expression 831132718Skan 832132718Skan throw-expression: 833132718Skan throw assignment-expression(opt) 834132718Skan 835132718Skan assignment-operator: one of 836132718Skan = *= /= %= += -= >>= <<= &= ^= |= */ 837169689Skan 838132718Skanstatic void 839132718Skanpp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e) 840132718Skan{ 841132718Skan switch (TREE_CODE (e)) 842132718Skan { 843132718Skan case MODIFY_EXPR: 844132718Skan case INIT_EXPR: 845132718Skan pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0)); 846132718Skan pp_space (pp); 847132718Skan pp_equal (pp); 848132718Skan pp_space (pp); 849132718Skan pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1)); 850132718Skan break; 851132718Skan 852132718Skan case THROW_EXPR: 853132718Skan pp_cxx_identifier (pp, "throw"); 854132718Skan if (TREE_OPERAND (e, 0)) 855169689Skan pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0)); 856132718Skan break; 857132718Skan 858132718Skan case MODOP_EXPR: 859132718Skan pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0)); 860132718Skan pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1)); 861132718Skan pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2)); 862132718Skan break; 863132718Skan 864132718Skan default: 865132718Skan pp_cxx_conditional_expression (pp, e); 866132718Skan break; 867132718Skan } 868132718Skan} 869132718Skan 870132718Skanstatic void 871132718Skanpp_cxx_expression (cxx_pretty_printer *pp, tree t) 872132718Skan{ 873132718Skan switch (TREE_CODE (t)) 874132718Skan { 875132718Skan case STRING_CST: 876132718Skan case INTEGER_CST: 877132718Skan case REAL_CST: 878169689Skan pp_cxx_constant (pp, t); 879132718Skan break; 880132718Skan 881132718Skan case RESULT_DECL: 882132718Skan pp_cxx_unqualified_id (pp, t); 883132718Skan break; 884132718Skan 885169689Skan#if 0 886132718Skan case OFFSET_REF: 887169689Skan#endif 888132718Skan case SCOPE_REF: 889132718Skan case PTRMEM_CST: 890132718Skan pp_cxx_qualified_id (pp, t); 891132718Skan break; 892132718Skan 893132718Skan case OVERLOAD: 894132718Skan t = OVL_CURRENT (t); 895132718Skan case VAR_DECL: 896132718Skan case PARM_DECL: 897132718Skan case FIELD_DECL: 898132718Skan case CONST_DECL: 899132718Skan case FUNCTION_DECL: 900132718Skan case BASELINK: 901132718Skan case TEMPLATE_DECL: 902132718Skan case TEMPLATE_TYPE_PARM: 903132718Skan case TEMPLATE_PARM_INDEX: 904169689Skan case TEMPLATE_TEMPLATE_PARM: 905169689Skan case STMT_EXPR: 906132718Skan pp_cxx_primary_expression (pp, t); 907132718Skan break; 908132718Skan 909132718Skan case CALL_EXPR: 910132718Skan case DYNAMIC_CAST_EXPR: 911132718Skan case STATIC_CAST_EXPR: 912132718Skan case REINTERPRET_CAST_EXPR: 913132718Skan case CONST_CAST_EXPR: 914169689Skan#if 0 915132718Skan case MEMBER_REF: 916169689Skan#endif 917132718Skan case EMPTY_CLASS_EXPR: 918132718Skan case TYPEID_EXPR: 919132718Skan case PSEUDO_DTOR_EXPR: 920132718Skan case AGGR_INIT_EXPR: 921169689Skan case ARROW_EXPR: 922132718Skan pp_cxx_postfix_expression (pp, t); 923132718Skan break; 924132718Skan 925132718Skan case NEW_EXPR: 926132718Skan case VEC_NEW_EXPR: 927132718Skan pp_cxx_new_expression (pp, t); 928132718Skan break; 929132718Skan 930132718Skan case DELETE_EXPR: 931132718Skan case VEC_DELETE_EXPR: 932132718Skan pp_cxx_delete_expression (pp, t); 933132718Skan break; 934132718Skan 935169689Skan case SIZEOF_EXPR: 936169689Skan case ALIGNOF_EXPR: 937169689Skan pp_cxx_unary_expression (pp, t); 938169689Skan break; 939169689Skan 940132718Skan case CAST_EXPR: 941132718Skan pp_cxx_cast_expression (pp, t); 942132718Skan break; 943132718Skan 944132718Skan case OFFSET_REF: 945132718Skan case MEMBER_REF: 946132718Skan case DOTSTAR_EXPR: 947132718Skan pp_cxx_pm_expression (pp, t); 948132718Skan break; 949132718Skan 950132718Skan case MULT_EXPR: 951132718Skan case TRUNC_DIV_EXPR: 952132718Skan case TRUNC_MOD_EXPR: 953132718Skan pp_cxx_multiplicative_expression (pp, t); 954132718Skan break; 955132718Skan 956132718Skan case COND_EXPR: 957132718Skan pp_cxx_conditional_expression (pp, t); 958132718Skan break; 959132718Skan 960132718Skan case MODIFY_EXPR: 961132718Skan case INIT_EXPR: 962132718Skan case THROW_EXPR: 963132718Skan case MODOP_EXPR: 964132718Skan pp_cxx_assignment_expression (pp, t); 965132718Skan break; 966132718Skan 967169689Skan case NON_DEPENDENT_EXPR: 968169689Skan case MUST_NOT_THROW_EXPR: 969169689Skan pp_cxx_expression (pp, t); 970169689Skan break; 971169689Skan 972132718Skan default: 973132718Skan pp_c_expression (pp_c_base (pp), t); 974169689Skan break; 975132718Skan } 976132718Skan} 977132718Skan 978132718Skan 979132718Skan/* Declarations. */ 980132718Skan 981132718Skan/* function-specifier: 982132718Skan inline 983132718Skan virtual 984132718Skan explicit */ 985169689Skan 986132718Skanstatic void 987132718Skanpp_cxx_function_specifier (cxx_pretty_printer *pp, tree t) 988132718Skan{ 989132718Skan switch (TREE_CODE (t)) 990132718Skan { 991132718Skan case FUNCTION_DECL: 992132718Skan if (DECL_VIRTUAL_P (t)) 993169689Skan pp_cxx_identifier (pp, "virtual"); 994132718Skan else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t)) 995169689Skan pp_cxx_identifier (pp, "explicit"); 996132718Skan else 997169689Skan pp_c_function_specifier (pp_c_base (pp), t); 998132718Skan 999132718Skan default: 1000132718Skan break; 1001132718Skan } 1002132718Skan} 1003132718Skan 1004132718Skan/* decl-specifier-seq: 1005132718Skan decl-specifier-seq(opt) decl-specifier 1006132718Skan 1007132718Skan decl-specifier: 1008132718Skan storage-class-specifier 1009132718Skan type-specifier 1010132718Skan function-specifier 1011132718Skan friend 1012132718Skan typedef */ 1013169689Skan 1014132718Skanstatic void 1015132718Skanpp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t) 1016132718Skan{ 1017132718Skan switch (TREE_CODE (t)) 1018132718Skan { 1019132718Skan case VAR_DECL: 1020132718Skan case PARM_DECL: 1021132718Skan case CONST_DECL: 1022132718Skan case FIELD_DECL: 1023132718Skan pp_cxx_storage_class_specifier (pp, t); 1024132718Skan pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t)); 1025132718Skan break; 1026169689Skan 1027132718Skan case TYPE_DECL: 1028132718Skan pp_cxx_identifier (pp, "typedef"); 1029132718Skan pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t)); 1030132718Skan break; 1031132718Skan 1032132718Skan case RECORD_TYPE: 1033132718Skan if (TYPE_PTRMEMFUNC_P (t)) 1034169689Skan { 1035169689Skan tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t); 1036169689Skan pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm))); 1037169689Skan pp_cxx_whitespace (pp); 1038169689Skan pp_cxx_ptr_operator (pp, t); 1039169689Skan } 1040132718Skan break; 1041132718Skan 1042132718Skan case FUNCTION_DECL: 1043132718Skan /* Constructors don't have return types. And conversion functions 1044169689Skan do not have a type-specifier in their return types. */ 1045132718Skan if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t)) 1046169689Skan pp_cxx_function_specifier (pp, t); 1047132718Skan else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) 1048169689Skan pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t))); 1049132718Skan else 1050169689Skan default: 1051132718Skan pp_c_declaration_specifiers (pp_c_base (pp), t); 1052132718Skan break; 1053132718Skan } 1054132718Skan} 1055132718Skan 1056132718Skan/* simple-type-specifier: 1057132718Skan ::(opt) nested-name-specifier(opt) type-name 1058132718Skan ::(opt) nested-name-specifier(opt) template(opt) template-id 1059132718Skan char 1060132718Skan wchar_t 1061132718Skan bool 1062132718Skan short 1063132718Skan int 1064132718Skan long 1065132718Skan signed 1066132718Skan unsigned 1067132718Skan float 1068132718Skan double 1069132718Skan void */ 1070169689Skan 1071132718Skanstatic void 1072132718Skanpp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t) 1073132718Skan{ 1074132718Skan switch (TREE_CODE (t)) 1075132718Skan { 1076132718Skan case RECORD_TYPE: 1077132718Skan case UNION_TYPE: 1078132718Skan case ENUMERAL_TYPE: 1079132718Skan pp_cxx_qualified_id (pp, t); 1080132718Skan break; 1081132718Skan 1082132718Skan case TEMPLATE_TYPE_PARM: 1083169689Skan case TEMPLATE_TEMPLATE_PARM: 1084132718Skan case TEMPLATE_PARM_INDEX: 1085132718Skan pp_cxx_unqualified_id (pp, t); 1086132718Skan break; 1087132718Skan 1088132718Skan case TYPENAME_TYPE: 1089132718Skan pp_cxx_identifier (pp, "typename"); 1090132718Skan pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t)); 1091132718Skan pp_cxx_unqualified_id (pp, TYPE_NAME (t)); 1092132718Skan break; 1093132718Skan 1094132718Skan default: 1095132718Skan pp_c_type_specifier (pp_c_base (pp), t); 1096132718Skan break; 1097132718Skan } 1098132718Skan} 1099132718Skan 1100132718Skan/* type-specifier-seq: 1101132718Skan type-specifier type-specifier-seq(opt) 1102132718Skan 1103132718Skan type-specifier: 1104132718Skan simple-type-specifier 1105132718Skan class-specifier 1106132718Skan enum-specifier 1107132718Skan elaborated-type-specifier 1108132718Skan cv-qualifier */ 1109132718Skan 1110132718Skanstatic void 1111132718Skanpp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t) 1112132718Skan{ 1113132718Skan switch (TREE_CODE (t)) 1114132718Skan { 1115132718Skan case TEMPLATE_DECL: 1116132718Skan case TEMPLATE_TYPE_PARM: 1117169689Skan case TEMPLATE_TEMPLATE_PARM: 1118132718Skan case TYPE_DECL: 1119132718Skan case BOUND_TEMPLATE_TEMPLATE_PARM: 1120169689Skan pp_cxx_cv_qualifier_seq (pp, t); 1121132718Skan pp_cxx_simple_type_specifier (pp, t); 1122132718Skan break; 1123132718Skan 1124132718Skan case METHOD_TYPE: 1125132718Skan pp_cxx_type_specifier_seq (pp, TREE_TYPE (t)); 1126132718Skan pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t)); 1127132718Skan pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t)); 1128132718Skan break; 1129132718Skan 1130132718Skan default: 1131132718Skan if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t))) 1132169689Skan pp_c_specifier_qualifier_list (pp_c_base (pp), t); 1133132718Skan } 1134132718Skan} 1135132718Skan 1136132718Skan/* ptr-operator: 1137132718Skan * cv-qualifier-seq(opt) 1138132718Skan & 1139132718Skan ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */ 1140132718Skan 1141132718Skanstatic void 1142132718Skanpp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t) 1143132718Skan{ 1144132718Skan if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL) 1145132718Skan t = TREE_TYPE (t); 1146132718Skan switch (TREE_CODE (t)) 1147132718Skan { 1148132718Skan case REFERENCE_TYPE: 1149132718Skan case POINTER_TYPE: 1150132718Skan if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE 1151169689Skan || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t))) 1152169689Skan pp_cxx_ptr_operator (pp, TREE_TYPE (t)); 1153132718Skan if (TREE_CODE (t) == POINTER_TYPE) 1154169689Skan { 1155169689Skan pp_star (pp); 1156169689Skan pp_cxx_cv_qualifier_seq (pp, t); 1157169689Skan } 1158132718Skan else 1159169689Skan pp_ampersand (pp); 1160132718Skan break; 1161132718Skan 1162132718Skan case RECORD_TYPE: 1163132718Skan if (TYPE_PTRMEMFUNC_P (t)) 1164169689Skan { 1165169689Skan pp_cxx_left_paren (pp); 1166169689Skan pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t)); 1167169689Skan pp_star (pp); 1168169689Skan break; 1169169689Skan } 1170132718Skan case OFFSET_TYPE: 1171132718Skan if (TYPE_PTR_TO_MEMBER_P (t)) 1172169689Skan { 1173169689Skan if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 1174169689Skan pp_cxx_left_paren (pp); 1175169689Skan pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t)); 1176169689Skan pp_star (pp); 1177169689Skan pp_cxx_cv_qualifier_seq (pp, t); 1178169689Skan break; 1179169689Skan } 1180132718Skan /* else fall through. */ 1181132718Skan 1182132718Skan default: 1183132718Skan pp_unsupported_tree (pp, t); 1184132718Skan break; 1185132718Skan } 1186132718Skan} 1187132718Skan 1188132718Skanstatic inline tree 1189132718Skanpp_cxx_implicit_parameter_type (tree mf) 1190132718Skan{ 1191132718Skan return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf)))); 1192132718Skan} 1193132718Skan 1194132718Skan/* 1195132718Skan parameter-declaration: 1196132718Skan decl-specifier-seq declarator 1197132718Skan decl-specifier-seq declarator = assignment-expression 1198132718Skan decl-specifier-seq abstract-declarator(opt) 1199132718Skan decl-specifier-seq abstract-declarator(opt) assignment-expression */ 1200169689Skan 1201132718Skanstatic inline void 1202132718Skanpp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t) 1203132718Skan{ 1204132718Skan pp_cxx_decl_specifier_seq (pp, t); 1205132718Skan if (TYPE_P (t)) 1206132718Skan pp_cxx_abstract_declarator (pp, t); 1207132718Skan else 1208132718Skan pp_cxx_declarator (pp, t); 1209132718Skan} 1210132718Skan 1211132718Skan/* parameter-declaration-clause: 1212132718Skan parameter-declaration-list(opt) ...(opt) 1213132718Skan parameter-declaration-list , ... 1214132718Skan 1215132718Skan parameter-declaration-list: 1216132718Skan parameter-declaration 1217132718Skan parameter-declaration-list , parameter-declaration */ 1218169689Skan 1219132718Skanstatic void 1220132718Skanpp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t) 1221132718Skan{ 1222132718Skan tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t); 1223169689Skan tree types = 1224169689Skan TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t); 1225132718Skan const bool abstract = args == NULL 1226132718Skan || pp_c_base (pp)->flags & pp_c_flag_abstract; 1227132718Skan bool first = true; 1228132718Skan 1229132718Skan /* Skip artificial parameter for nonstatic member functions. */ 1230132718Skan if (TREE_CODE (t) == METHOD_TYPE) 1231132718Skan types = TREE_CHAIN (types); 1232132718Skan 1233132718Skan pp_cxx_left_paren (pp); 1234132718Skan for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types)) 1235132718Skan { 1236132718Skan if (!first) 1237169689Skan pp_cxx_separate_with (pp, ','); 1238132718Skan first = false; 1239132718Skan pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args); 1240132718Skan if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument) 1241169689Skan { 1242169689Skan pp_cxx_whitespace (pp); 1243169689Skan pp_equal (pp); 1244169689Skan pp_cxx_whitespace (pp); 1245169689Skan pp_cxx_assignment_expression (pp, TREE_PURPOSE (types)); 1246169689Skan } 1247132718Skan } 1248132718Skan pp_cxx_right_paren (pp); 1249132718Skan} 1250132718Skan 1251132718Skan/* exception-specification: 1252132718Skan throw ( type-id-list(opt) ) 1253132718Skan 1254132718Skan type-id-list 1255132718Skan type-id 1256132718Skan type-id-list , type-id */ 1257169689Skan 1258132718Skanstatic void 1259132718Skanpp_cxx_exception_specification (cxx_pretty_printer *pp, tree t) 1260132718Skan{ 1261132718Skan tree ex_spec = TYPE_RAISES_EXCEPTIONS (t); 1262132718Skan 1263132718Skan if (!TYPE_NOTHROW_P (t) && ex_spec == NULL) 1264132718Skan return; 1265132718Skan pp_cxx_identifier (pp, "throw"); 1266132718Skan pp_cxx_left_paren (pp); 1267132718Skan for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec)) 1268132718Skan { 1269132718Skan pp_cxx_type_id (pp, TREE_VALUE (ex_spec)); 1270132718Skan if (TREE_CHAIN (ex_spec)) 1271169689Skan pp_cxx_separate_with (pp, ','); 1272132718Skan } 1273132718Skan pp_cxx_right_paren (pp); 1274132718Skan} 1275132718Skan 1276132718Skan/* direct-declarator: 1277132718Skan declarator-id 1278132718Skan direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt) 1279169689Skan exception-specification(opt) 1280132718Skan direct-declaration [ constant-expression(opt) ] 1281132718Skan ( declarator ) */ 1282169689Skan 1283132718Skanstatic void 1284132718Skanpp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t) 1285132718Skan{ 1286132718Skan switch (TREE_CODE (t)) 1287132718Skan { 1288132718Skan case VAR_DECL: 1289132718Skan case PARM_DECL: 1290132718Skan case CONST_DECL: 1291132718Skan case FIELD_DECL: 1292132718Skan if (DECL_NAME (t)) 1293169689Skan { 1294169689Skan pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t)); 1295169689Skan pp_cxx_id_expression (pp, DECL_NAME (t)); 1296169689Skan } 1297132718Skan pp_cxx_abstract_declarator (pp, TREE_TYPE (t)); 1298132718Skan break; 1299169689Skan 1300132718Skan case FUNCTION_DECL: 1301132718Skan pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t))); 1302132718Skan pp_cxx_id_expression (pp, t); 1303132718Skan pp_cxx_parameter_declaration_clause (pp, t); 1304169689Skan 1305132718Skan if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) 1306169689Skan { 1307169689Skan pp_base (pp)->padding = pp_before; 1308169689Skan pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t)); 1309169689Skan } 1310132718Skan 1311132718Skan pp_cxx_exception_specification (pp, TREE_TYPE (t)); 1312132718Skan break; 1313132718Skan 1314132718Skan case TYPENAME_TYPE: 1315132718Skan case TEMPLATE_DECL: 1316132718Skan case TEMPLATE_TYPE_PARM: 1317132718Skan case TEMPLATE_PARM_INDEX: 1318169689Skan case TEMPLATE_TEMPLATE_PARM: 1319132718Skan break; 1320132718Skan 1321132718Skan default: 1322132718Skan pp_c_direct_declarator (pp_c_base (pp), t); 1323132718Skan break; 1324132718Skan } 1325132718Skan} 1326132718Skan 1327132718Skan/* declarator: 1328132718Skan direct-declarator 1329132718Skan ptr-operator declarator */ 1330169689Skan 1331132718Skanstatic void 1332132718Skanpp_cxx_declarator (cxx_pretty_printer *pp, tree t) 1333132718Skan{ 1334132718Skan pp_cxx_direct_declarator (pp, t); 1335132718Skan} 1336132718Skan 1337132718Skan/* ctor-initializer: 1338132718Skan : mem-initializer-list 1339132718Skan 1340132718Skan mem-initializer-list: 1341132718Skan mem-initializer 1342132718Skan mem-initializer , mem-initializer-list 1343132718Skan 1344132718Skan mem-initializer: 1345132718Skan mem-initializer-id ( expression-list(opt) ) 1346132718Skan 1347132718Skan mem-initializer-id: 1348132718Skan ::(opt) nested-name-specifier(opt) class-name 1349132718Skan identifier */ 1350169689Skan 1351132718Skanstatic void 1352132718Skanpp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t) 1353132718Skan{ 1354132718Skan t = TREE_OPERAND (t, 0); 1355132718Skan pp_cxx_whitespace (pp); 1356132718Skan pp_colon (pp); 1357132718Skan pp_cxx_whitespace (pp); 1358132718Skan for (; t; t = TREE_CHAIN (t)) 1359132718Skan { 1360132718Skan pp_cxx_primary_expression (pp, TREE_PURPOSE (t)); 1361132718Skan pp_cxx_call_argument_list (pp, TREE_VALUE (t)); 1362132718Skan if (TREE_CHAIN (t)) 1363169689Skan pp_cxx_separate_with (pp, ','); 1364132718Skan } 1365132718Skan} 1366132718Skan 1367132718Skan/* function-definition: 1368132718Skan decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body 1369132718Skan decl-specifier-seq(opt) declarator function-try-block */ 1370132718Skan 1371169689Skanstatic void 1372132718Skanpp_cxx_function_definition (cxx_pretty_printer *pp, tree t) 1373132718Skan{ 1374132718Skan tree saved_scope = pp->enclosing_scope; 1375132718Skan pp_cxx_decl_specifier_seq (pp, t); 1376132718Skan pp_cxx_declarator (pp, t); 1377132718Skan pp_needs_newline (pp) = true; 1378132718Skan pp->enclosing_scope = DECL_CONTEXT (t); 1379132718Skan if (DECL_SAVED_TREE (t)) 1380169689Skan pp_cxx_statement (pp, DECL_SAVED_TREE (t)); 1381132718Skan else 1382132718Skan { 1383132718Skan pp_cxx_semicolon (pp); 1384132718Skan pp_needs_newline (pp) = true; 1385132718Skan } 1386132718Skan pp_flush (pp); 1387132718Skan pp->enclosing_scope = saved_scope; 1388132718Skan} 1389132718Skan 1390132718Skan/* abstract-declarator: 1391132718Skan ptr-operator abstract-declarator(opt) 1392132718Skan direct-abstract-declarator */ 1393169689Skan 1394132718Skanstatic void 1395132718Skanpp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t) 1396132718Skan{ 1397132718Skan if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t)) 1398132718Skan pp_cxx_right_paren (pp); 1399132718Skan else if (POINTER_TYPE_P (t)) 1400132718Skan { 1401132718Skan if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE 1402169689Skan || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) 1403169689Skan pp_cxx_right_paren (pp); 1404132718Skan t = TREE_TYPE (t); 1405132718Skan } 1406132718Skan pp_cxx_direct_abstract_declarator (pp, t); 1407132718Skan} 1408132718Skan 1409132718Skan/* direct-abstract-declarator: 1410132718Skan direct-abstract-declarator(opt) ( parameter-declaration-clause ) 1411169689Skan cv-qualifier-seq(opt) exception-specification(opt) 1412132718Skan direct-abstract-declarator(opt) [ constant-expression(opt) ] 1413132718Skan ( abstract-declarator ) */ 1414169689Skan 1415132718Skanstatic void 1416132718Skanpp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t) 1417132718Skan{ 1418132718Skan switch (TREE_CODE (t)) 1419132718Skan { 1420132718Skan case REFERENCE_TYPE: 1421132718Skan pp_cxx_abstract_declarator (pp, t); 1422132718Skan break; 1423132718Skan 1424132718Skan case RECORD_TYPE: 1425132718Skan if (TYPE_PTRMEMFUNC_P (t)) 1426169689Skan pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t)); 1427132718Skan break; 1428132718Skan 1429132718Skan case METHOD_TYPE: 1430132718Skan case FUNCTION_TYPE: 1431132718Skan pp_cxx_parameter_declaration_clause (pp, t); 1432132718Skan pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t)); 1433132718Skan if (TREE_CODE (t) == METHOD_TYPE) 1434169689Skan { 1435169689Skan pp_base (pp)->padding = pp_before; 1436169689Skan pp_cxx_cv_qualifier_seq 1437169689Skan (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); 1438169689Skan } 1439132718Skan pp_cxx_exception_specification (pp, t); 1440132718Skan break; 1441132718Skan 1442132718Skan case TYPENAME_TYPE: 1443132718Skan case TEMPLATE_TYPE_PARM: 1444132718Skan case TEMPLATE_TEMPLATE_PARM: 1445132718Skan case BOUND_TEMPLATE_TEMPLATE_PARM: 1446132718Skan case UNBOUND_CLASS_TEMPLATE: 1447132718Skan break; 1448132718Skan 1449132718Skan default: 1450132718Skan pp_c_direct_abstract_declarator (pp_c_base (pp), t); 1451169689Skan break; 1452132718Skan } 1453132718Skan} 1454132718Skan 1455132718Skan/* type-id: 1456132718Skan type-specifier-seq abstract-declarator(opt) */ 1457169689Skan 1458132718Skanstatic void 1459132718Skanpp_cxx_type_id (cxx_pretty_printer *pp, tree t) 1460132718Skan{ 1461132718Skan pp_flags saved_flags = pp_c_base (pp)->flags; 1462132718Skan pp_c_base (pp)->flags |= pp_c_flag_abstract; 1463132718Skan 1464132718Skan switch (TREE_CODE (t)) 1465132718Skan { 1466132718Skan case TYPE_DECL: 1467132718Skan case UNION_TYPE: 1468132718Skan case RECORD_TYPE: 1469132718Skan case ENUMERAL_TYPE: 1470132718Skan case TYPENAME_TYPE: 1471132718Skan case BOUND_TEMPLATE_TEMPLATE_PARM: 1472132718Skan case UNBOUND_CLASS_TEMPLATE: 1473132718Skan case TEMPLATE_TEMPLATE_PARM: 1474132718Skan case TEMPLATE_TYPE_PARM: 1475132718Skan case TEMPLATE_PARM_INDEX: 1476132718Skan case TEMPLATE_DECL: 1477132718Skan case TYPEOF_TYPE: 1478132718Skan case TEMPLATE_ID_EXPR: 1479132718Skan pp_cxx_type_specifier_seq (pp, t); 1480132718Skan break; 1481132718Skan 1482132718Skan default: 1483132718Skan pp_c_type_id (pp_c_base (pp), t); 1484132718Skan break; 1485132718Skan } 1486132718Skan 1487132718Skan pp_c_base (pp)->flags = saved_flags; 1488132718Skan} 1489132718Skan 1490132718Skan/* template-argument-list: 1491132718Skan template-argument 1492132718Skan template-argument-list, template-argument 1493132718Skan 1494132718Skan template-argument: 1495132718Skan assignment-expression 1496132718Skan type-id 1497132718Skan template-name */ 1498169689Skan 1499132718Skanstatic void 1500132718Skanpp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t) 1501132718Skan{ 1502132718Skan int i; 1503132718Skan if (t == NULL) 1504132718Skan return; 1505132718Skan for (i = 0; i < TREE_VEC_LENGTH (t); ++i) 1506132718Skan { 1507132718Skan tree arg = TREE_VEC_ELT (t, i); 1508132718Skan if (i != 0) 1509169689Skan pp_cxx_separate_with (pp, ','); 1510132718Skan if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL 1511169689Skan && TYPE_P (DECL_TEMPLATE_RESULT (arg)))) 1512169689Skan pp_cxx_type_id (pp, arg); 1513132718Skan else 1514169689Skan pp_cxx_expression (pp, arg); 1515132718Skan } 1516132718Skan} 1517132718Skan 1518132718Skan 1519132718Skanstatic void 1520132718Skanpp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t) 1521132718Skan{ 1522169689Skan t = DECL_EXPR_DECL (t); 1523132718Skan pp_cxx_type_specifier_seq (pp, t); 1524132718Skan if (TYPE_P (t)) 1525132718Skan pp_cxx_abstract_declarator (pp, t); 1526132718Skan else 1527132718Skan pp_cxx_declarator (pp, t); 1528132718Skan} 1529132718Skan 1530132718Skan/* Statements. */ 1531132718Skan 1532169689Skanstatic void 1533132718Skanpp_cxx_statement (cxx_pretty_printer *pp, tree t) 1534132718Skan{ 1535132718Skan switch (TREE_CODE (t)) 1536132718Skan { 1537169689Skan case CTOR_INITIALIZER: 1538169689Skan pp_cxx_ctor_initializer (pp, t); 1539169689Skan break; 1540169689Skan 1541132718Skan case USING_STMT: 1542132718Skan pp_cxx_identifier (pp, "using"); 1543132718Skan pp_cxx_identifier (pp, "namespace"); 1544169689Skan if (DECL_CONTEXT (t)) 1545169689Skan pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 1546132718Skan pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t)); 1547132718Skan break; 1548132718Skan 1549132718Skan case USING_DECL: 1550132718Skan pp_cxx_identifier (pp, "using"); 1551169689Skan pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t)); 1552132718Skan pp_cxx_unqualified_id (pp, DECL_NAME (t)); 1553132718Skan break; 1554132718Skan 1555132718Skan case EH_SPEC_BLOCK: 1556132718Skan break; 1557132718Skan 1558132718Skan /* try-block: 1559169689Skan try compound-statement handler-seq */ 1560132718Skan case TRY_BLOCK: 1561132718Skan pp_maybe_newline_and_indent (pp, 0); 1562132718Skan pp_cxx_identifier (pp, "try"); 1563132718Skan pp_newline_and_indent (pp, 3); 1564132718Skan pp_cxx_statement (pp, TRY_STMTS (t)); 1565132718Skan pp_newline_and_indent (pp, -3); 1566132718Skan if (CLEANUP_P (t)) 1567169689Skan ; 1568132718Skan else 1569169689Skan pp_cxx_statement (pp, TRY_HANDLERS (t)); 1570132718Skan break; 1571132718Skan 1572132718Skan /* 1573169689Skan handler-seq: 1574169689Skan handler handler-seq(opt) 1575132718Skan 1576169689Skan handler: 1577169689Skan catch ( exception-declaration ) compound-statement 1578132718Skan 1579169689Skan exception-declaration: 1580169689Skan type-specifier-seq declarator 1581169689Skan type-specifier-seq abstract-declarator 1582169689Skan ... */ 1583132718Skan case HANDLER: 1584132718Skan pp_cxx_identifier (pp, "catch"); 1585132718Skan pp_cxx_left_paren (pp); 1586132718Skan pp_cxx_exception_declaration (pp, HANDLER_PARMS (t)); 1587132718Skan pp_cxx_right_paren (pp); 1588132718Skan pp_indentation (pp) += 3; 1589132718Skan pp_needs_newline (pp) = true; 1590132718Skan pp_cxx_statement (pp, HANDLER_BODY (t)); 1591132718Skan pp_indentation (pp) -= 3; 1592132718Skan pp_needs_newline (pp) = true; 1593132718Skan break; 1594132718Skan 1595169689Skan /* selection-statement: 1596169689Skan if ( expression ) statement 1597169689Skan if ( expression ) statement else statement */ 1598169689Skan case IF_STMT: 1599169689Skan pp_cxx_identifier (pp, "if"); 1600169689Skan pp_cxx_whitespace (pp); 1601169689Skan pp_cxx_left_paren (pp); 1602169689Skan pp_cxx_expression (pp, IF_COND (t)); 1603169689Skan pp_cxx_right_paren (pp); 1604169689Skan pp_newline_and_indent (pp, 2); 1605169689Skan pp_cxx_statement (pp, THEN_CLAUSE (t)); 1606169689Skan pp_newline_and_indent (pp, -2); 1607169689Skan if (ELSE_CLAUSE (t)) 1608169689Skan { 1609169689Skan tree else_clause = ELSE_CLAUSE (t); 1610169689Skan pp_cxx_identifier (pp, "else"); 1611169689Skan if (TREE_CODE (else_clause) == IF_STMT) 1612169689Skan pp_cxx_whitespace (pp); 1613169689Skan else 1614169689Skan pp_newline_and_indent (pp, 2); 1615169689Skan pp_cxx_statement (pp, else_clause); 1616169689Skan if (TREE_CODE (else_clause) != IF_STMT) 1617169689Skan pp_newline_and_indent (pp, -2); 1618169689Skan } 1619169689Skan break; 1620169689Skan 1621169689Skan case SWITCH_STMT: 1622169689Skan pp_cxx_identifier (pp, "switch"); 1623169689Skan pp_space (pp); 1624169689Skan pp_cxx_left_paren (pp); 1625169689Skan pp_cxx_expression (pp, SWITCH_STMT_COND (t)); 1626169689Skan pp_cxx_right_paren (pp); 1627169689Skan pp_indentation (pp) += 3; 1628169689Skan pp_needs_newline (pp) = true; 1629169689Skan pp_cxx_statement (pp, SWITCH_STMT_BODY (t)); 1630169689Skan pp_newline_and_indent (pp, -3); 1631169689Skan break; 1632169689Skan 1633169689Skan /* iteration-statement: 1634169689Skan while ( expression ) statement 1635169689Skan do statement while ( expression ) ; 1636169689Skan for ( expression(opt) ; expression(opt) ; expression(opt) ) statement 1637169689Skan for ( declaration expression(opt) ; expression(opt) ) statement */ 1638169689Skan case WHILE_STMT: 1639169689Skan pp_cxx_identifier (pp, "while"); 1640169689Skan pp_space (pp); 1641169689Skan pp_cxx_left_paren (pp); 1642169689Skan pp_cxx_expression (pp, WHILE_COND (t)); 1643169689Skan pp_cxx_right_paren (pp); 1644169689Skan pp_newline_and_indent (pp, 3); 1645169689Skan pp_cxx_statement (pp, WHILE_BODY (t)); 1646169689Skan pp_indentation (pp) -= 3; 1647169689Skan pp_needs_newline (pp) = true; 1648169689Skan break; 1649169689Skan 1650169689Skan case DO_STMT: 1651169689Skan pp_cxx_identifier (pp, "do"); 1652169689Skan pp_newline_and_indent (pp, 3); 1653169689Skan pp_cxx_statement (pp, DO_BODY (t)); 1654169689Skan pp_newline_and_indent (pp, -3); 1655169689Skan pp_cxx_identifier (pp, "while"); 1656169689Skan pp_space (pp); 1657169689Skan pp_cxx_left_paren (pp); 1658169689Skan pp_cxx_expression (pp, DO_COND (t)); 1659169689Skan pp_cxx_right_paren (pp); 1660169689Skan pp_cxx_semicolon (pp); 1661169689Skan pp_needs_newline (pp) = true; 1662169689Skan break; 1663169689Skan 1664169689Skan case FOR_STMT: 1665169689Skan pp_cxx_identifier (pp, "for"); 1666169689Skan pp_space (pp); 1667169689Skan pp_cxx_left_paren (pp); 1668169689Skan if (FOR_INIT_STMT (t)) 1669169689Skan pp_cxx_statement (pp, FOR_INIT_STMT (t)); 1670169689Skan else 1671169689Skan pp_cxx_semicolon (pp); 1672169689Skan pp_needs_newline (pp) = false; 1673169689Skan pp_cxx_whitespace (pp); 1674169689Skan if (FOR_COND (t)) 1675169689Skan pp_cxx_expression (pp, FOR_COND (t)); 1676169689Skan pp_cxx_semicolon (pp); 1677169689Skan pp_needs_newline (pp) = false; 1678169689Skan pp_cxx_whitespace (pp); 1679169689Skan if (FOR_EXPR (t)) 1680169689Skan pp_cxx_expression (pp, FOR_EXPR (t)); 1681169689Skan pp_cxx_right_paren (pp); 1682169689Skan pp_newline_and_indent (pp, 3); 1683169689Skan pp_cxx_statement (pp, FOR_BODY (t)); 1684169689Skan pp_indentation (pp) -= 3; 1685169689Skan pp_needs_newline (pp) = true; 1686169689Skan break; 1687169689Skan 1688169689Skan /* jump-statement: 1689169689Skan goto identifier; 1690169689Skan continue ; 1691169689Skan return expression(opt) ; */ 1692169689Skan case BREAK_STMT: 1693169689Skan case CONTINUE_STMT: 1694169689Skan pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue"); 1695169689Skan pp_cxx_semicolon (pp); 1696169689Skan pp_needs_newline (pp) = true; 1697169689Skan break; 1698169689Skan 1699169689Skan /* expression-statement: 1700169689Skan expression(opt) ; */ 1701169689Skan case EXPR_STMT: 1702169689Skan pp_cxx_expression (pp, EXPR_STMT_EXPR (t)); 1703169689Skan pp_cxx_semicolon (pp); 1704169689Skan pp_needs_newline (pp) = true; 1705169689Skan break; 1706169689Skan 1707169689Skan case CLEANUP_STMT: 1708169689Skan pp_cxx_identifier (pp, "try"); 1709169689Skan pp_newline_and_indent (pp, 2); 1710169689Skan pp_cxx_statement (pp, CLEANUP_BODY (t)); 1711169689Skan pp_newline_and_indent (pp, -2); 1712169689Skan pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally"); 1713169689Skan pp_newline_and_indent (pp, 2); 1714169689Skan pp_cxx_statement (pp, CLEANUP_EXPR (t)); 1715169689Skan pp_newline_and_indent (pp, -2); 1716169689Skan break; 1717169689Skan 1718132718Skan default: 1719132718Skan pp_c_statement (pp_c_base (pp), t); 1720132718Skan break; 1721132718Skan } 1722132718Skan} 1723132718Skan 1724132718Skan/* original-namespace-definition: 1725132718Skan namespace identifier { namespace-body } 1726132718Skan 1727132718Skan As an edge case, we also handle unnamed namespace definition here. */ 1728132718Skan 1729132718Skanstatic void 1730132718Skanpp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t) 1731132718Skan{ 1732132718Skan pp_cxx_identifier (pp, "namespace"); 1733169689Skan if (DECL_CONTEXT (t)) 1734169689Skan pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 1735132718Skan if (DECL_NAME (t)) 1736132718Skan pp_cxx_unqualified_id (pp, t); 1737132718Skan pp_cxx_whitespace (pp); 1738132718Skan pp_cxx_left_brace (pp); 1739132718Skan /* We do not print the namespace-body. */ 1740132718Skan pp_cxx_whitespace (pp); 1741132718Skan pp_cxx_right_brace (pp); 1742132718Skan} 1743132718Skan 1744132718Skan/* namespace-alias: 1745132718Skan identifier 1746132718Skan 1747132718Skan namespace-alias-definition: 1748132718Skan namespace identifier = qualified-namespace-specifier ; 1749132718Skan 1750132718Skan qualified-namespace-specifier: 1751132718Skan ::(opt) nested-name-specifier(opt) namespace-name */ 1752132718Skan 1753132718Skanstatic void 1754132718Skanpp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t) 1755132718Skan{ 1756132718Skan pp_cxx_identifier (pp, "namespace"); 1757169689Skan if (DECL_CONTEXT (t)) 1758169689Skan pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 1759132718Skan pp_cxx_unqualified_id (pp, t); 1760132718Skan pp_cxx_whitespace (pp); 1761132718Skan pp_equal (pp); 1762132718Skan pp_cxx_whitespace (pp); 1763169689Skan if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t))) 1764169689Skan pp_cxx_nested_name_specifier (pp, 1765169689Skan DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t))); 1766132718Skan pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t)); 1767132718Skan pp_cxx_semicolon (pp); 1768132718Skan} 1769132718Skan 1770132718Skan/* simple-declaration: 1771132718Skan decl-specifier-seq(opt) init-declarator-list(opt) */ 1772169689Skan 1773132718Skanstatic void 1774132718Skanpp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t) 1775132718Skan{ 1776132718Skan pp_cxx_decl_specifier_seq (pp, t); 1777132718Skan pp_cxx_init_declarator (pp, t); 1778132718Skan pp_cxx_semicolon (pp); 1779132718Skan pp_needs_newline (pp) = true; 1780132718Skan} 1781132718Skan 1782132718Skan/* 1783132718Skan template-parameter-list: 1784132718Skan template-parameter 1785132718Skan template-parameter-list , template-parameter */ 1786132718Skan 1787132718Skanstatic inline void 1788132718Skanpp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t) 1789132718Skan{ 1790132718Skan const int n = TREE_VEC_LENGTH (t); 1791132718Skan int i; 1792132718Skan for (i = 0; i < n; ++i) 1793132718Skan { 1794132718Skan if (i) 1795169689Skan pp_cxx_separate_with (pp, ','); 1796132718Skan pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i)); 1797132718Skan } 1798132718Skan} 1799132718Skan 1800132718Skan/* template-parameter: 1801132718Skan type-parameter 1802132718Skan parameter-declaration 1803132718Skan 1804132718Skan type-parameter: 1805132718Skan class identifier(opt) 1806132718Skan class identifier(op) = type-id 1807132718Skan typename identifier(opt) 1808132718Skan typename identifier(opt) = type-id 1809132718Skan template < template-parameter-list > class identifier(opt) 1810169689Skan template < template-parameter-list > class identifier(opt) = template-name */ 1811169689Skan 1812132718Skanstatic void 1813132718Skanpp_cxx_template_parameter (cxx_pretty_printer *pp, tree t) 1814132718Skan{ 1815132718Skan tree parameter = TREE_VALUE (t); 1816132718Skan switch (TREE_CODE (parameter)) 1817132718Skan { 1818132718Skan case TYPE_DECL: 1819132718Skan pp_cxx_identifier (pp, "class"); 1820132718Skan if (DECL_NAME (parameter)) 1821169689Skan pp_cxx_tree_identifier (pp, DECL_NAME (parameter)); 1822132718Skan /* FIXME: Chech if we should print also default argument. */ 1823132718Skan break; 1824132718Skan 1825132718Skan case PARM_DECL: 1826132718Skan pp_cxx_parameter_declaration (pp, parameter); 1827132718Skan break; 1828132718Skan 1829132718Skan case TEMPLATE_DECL: 1830132718Skan break; 1831132718Skan 1832132718Skan default: 1833132718Skan pp_unsupported_tree (pp, t); 1834132718Skan break; 1835132718Skan } 1836132718Skan} 1837132718Skan 1838132718Skan/* Pretty-print a template parameter in the canonical form 1839132718Skan "template-parameter-<level>-<position in parameter list>". */ 1840132718Skan 1841132718Skanvoid 1842132718Skanpp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm) 1843132718Skan{ 1844132718Skan const enum tree_code code = TREE_CODE (parm); 1845132718Skan 1846132718Skan /* Brings type template parameters to the canonical forms. */ 1847132718Skan if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM 1848132718Skan || code == BOUND_TEMPLATE_TEMPLATE_PARM) 1849132718Skan parm = TEMPLATE_TYPE_PARM_INDEX (parm); 1850169689Skan 1851132718Skan pp_cxx_begin_template_argument_list (pp); 1852132718Skan pp_cxx_identifier (pp, "template-parameter-"); 1853132718Skan pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm)); 1854132718Skan pp_minus (pp); 1855132718Skan pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1); 1856132718Skan pp_cxx_end_template_argument_list (pp); 1857132718Skan} 1858132718Skan 1859132718Skan/* 1860132718Skan template-declaration: 1861132718Skan export(opt) template < template-parameter-list > declaration */ 1862169689Skan 1863132718Skanstatic void 1864132718Skanpp_cxx_template_declaration (cxx_pretty_printer *pp, tree t) 1865132718Skan{ 1866132718Skan tree tmpl = most_general_template (t); 1867132718Skan tree level; 1868132718Skan int i = 0; 1869132718Skan 1870132718Skan pp_maybe_newline_and_indent (pp, 0); 1871132718Skan for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level)) 1872132718Skan { 1873132718Skan pp_cxx_identifier (pp, "template"); 1874132718Skan pp_cxx_begin_template_argument_list (pp); 1875132718Skan pp_cxx_template_parameter_list (pp, TREE_VALUE (level)); 1876132718Skan pp_cxx_end_template_argument_list (pp); 1877132718Skan pp_newline_and_indent (pp, 3); 1878132718Skan i += 3; 1879132718Skan } 1880132718Skan if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t)) 1881132718Skan pp_cxx_function_definition (pp, t); 1882132718Skan else 1883132718Skan pp_cxx_simple_declaration (pp, t); 1884132718Skan} 1885132718Skan 1886132718Skanstatic void 1887132718Skanpp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t) 1888132718Skan{ 1889132718Skan pp_unsupported_tree (pp, t); 1890132718Skan} 1891132718Skan 1892132718Skanstatic void 1893132718Skanpp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t) 1894132718Skan{ 1895132718Skan pp_unsupported_tree (pp, t); 1896132718Skan} 1897132718Skan 1898132718Skan/* 1899132718Skan declaration: 1900132718Skan block-declaration 1901132718Skan function-definition 1902132718Skan template-declaration 1903132718Skan explicit-instantiation 1904132718Skan explicit-specialization 1905132718Skan linkage-specification 1906132718Skan namespace-definition 1907132718Skan 1908132718Skan block-declaration: 1909132718Skan simple-declaration 1910132718Skan asm-definition 1911132718Skan namespace-alias-definition 1912132718Skan using-declaration 1913132718Skan using-directive */ 1914132718Skanvoid 1915132718Skanpp_cxx_declaration (cxx_pretty_printer *pp, tree t) 1916132718Skan{ 1917132718Skan if (!DECL_LANG_SPECIFIC (t)) 1918132718Skan pp_cxx_simple_declaration (pp, t); 1919132718Skan else if (DECL_USE_TEMPLATE (t)) 1920132718Skan switch (DECL_USE_TEMPLATE (t)) 1921132718Skan { 1922132718Skan case 1: 1923169689Skan pp_cxx_template_declaration (pp, t); 1924169689Skan break; 1925169689Skan 1926132718Skan case 2: 1927169689Skan pp_cxx_explicit_specialization (pp, t); 1928169689Skan break; 1929132718Skan 1930132718Skan case 3: 1931169689Skan pp_cxx_explicit_instantiation (pp, t); 1932169689Skan break; 1933132718Skan 1934132718Skan default: 1935169689Skan break; 1936132718Skan } 1937132718Skan else switch (TREE_CODE (t)) 1938132718Skan { 1939132718Skan case VAR_DECL: 1940132718Skan case TYPE_DECL: 1941132718Skan pp_cxx_simple_declaration (pp, t); 1942132718Skan break; 1943169689Skan 1944132718Skan case FUNCTION_DECL: 1945132718Skan if (DECL_SAVED_TREE (t)) 1946169689Skan pp_cxx_function_definition (pp, t); 1947132718Skan else 1948169689Skan pp_cxx_simple_declaration (pp, t); 1949132718Skan break; 1950132718Skan 1951132718Skan case NAMESPACE_DECL: 1952132718Skan if (DECL_NAMESPACE_ALIAS (t)) 1953169689Skan pp_cxx_namespace_alias_definition (pp, t); 1954132718Skan else 1955169689Skan pp_cxx_original_namespace_definition (pp, t); 1956132718Skan break; 1957132718Skan 1958132718Skan default: 1959132718Skan pp_unsupported_tree (pp, t); 1960132718Skan break; 1961132718Skan } 1962132718Skan} 1963132718Skan 1964132718Skan 1965132718Skantypedef c_pretty_print_fn pp_fun; 1966132718Skan 1967169689Skan/* Initialization of a C++ pretty-printer object. */ 1968169689Skan 1969132718Skanvoid 1970132718Skanpp_cxx_pretty_printer_init (cxx_pretty_printer *pp) 1971132718Skan{ 1972132718Skan pp_c_pretty_printer_init (pp_c_base (pp)); 1973132718Skan pp_set_line_maximum_length (pp, 0); 1974132718Skan 1975132718Skan pp->c_base.declaration = (pp_fun) pp_cxx_declaration; 1976132718Skan pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq; 1977132718Skan pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier; 1978132718Skan pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq; 1979132718Skan pp->c_base.declarator = (pp_fun) pp_cxx_declarator; 1980132718Skan pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator; 1981132718Skan pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause; 1982132718Skan pp->c_base.type_id = (pp_fun) pp_cxx_type_id; 1983132718Skan pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator; 1984132718Skan pp->c_base.direct_abstract_declarator = 1985132718Skan (pp_fun) pp_cxx_direct_abstract_declarator; 1986132718Skan pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier; 1987132718Skan 1988132718Skan /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */ 1989132718Skan 1990169689Skan pp->c_base.constant = (pp_fun) pp_cxx_constant; 1991132718Skan pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression; 1992132718Skan pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression; 1993132718Skan pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression; 1994132718Skan pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression; 1995132718Skan pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression; 1996132718Skan pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression; 1997132718Skan pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression; 1998132718Skan pp->c_base.expression = (pp_fun) pp_cxx_expression; 1999132718Skan pp->enclosing_scope = global_namespace; 2000132718Skan} 2001