1/* Implementation of subroutines for the GNU C++ pretty-printer. 2 Copyright (C) 2003-2022 Free Software Foundation, Inc. 3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21#include "config.h" 22#include "system.h" 23#include "coretypes.h" 24#include "cp-tree.h" 25#include "cxx-pretty-print.h" 26#include "tree-pretty-print.h" 27 28static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree); 29static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree); 30static void pp_cxx_qualified_id (cxx_pretty_printer *, tree); 31static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree); 32static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree); 33static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree); 34static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree); 35static void pp_cxx_template_parameter (cxx_pretty_printer *, tree); 36static void pp_cxx_cast_expression (cxx_pretty_printer *, tree); 37static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree); 38static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree); 39static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree); 40static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree); 41static void pp_cxx_concept_definition (cxx_pretty_printer *, tree); 42 43 44static inline void 45pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c) 46{ 47 const char *p = pp_last_position_in_text (pp); 48 49 if (p != NULL && *p == c) 50 pp_cxx_whitespace (pp); 51 pp_character (pp, c); 52 pp->padding = pp_none; 53} 54 55#define pp_cxx_expression_list(PP, T) \ 56 pp_c_expression_list (PP, T) 57#define pp_cxx_space_for_pointer_operator(PP, T) \ 58 pp_c_space_for_pointer_operator (PP, T) 59#define pp_cxx_init_declarator(PP, T) \ 60 pp_c_init_declarator (PP, T) 61#define pp_cxx_call_argument_list(PP, T) \ 62 pp_c_call_argument_list (PP, T) 63 64void 65pp_cxx_colon_colon (cxx_pretty_printer *pp) 66{ 67 pp_colon_colon (pp); 68 pp->padding = pp_none; 69} 70 71void 72pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp) 73{ 74 pp_cxx_nonconsecutive_character (pp, '<'); 75} 76 77void 78pp_cxx_end_template_argument_list (cxx_pretty_printer *pp) 79{ 80 pp_cxx_nonconsecutive_character (pp, '>'); 81} 82 83void 84pp_cxx_separate_with (cxx_pretty_printer *pp, int c) 85{ 86 pp_separate_with (pp, c); 87 pp->padding = pp_none; 88} 89 90/* Expressions. */ 91 92/* conversion-function-id: 93 operator conversion-type-id 94 95 conversion-type-id: 96 type-specifier-seq conversion-declarator(opt) 97 98 conversion-declarator: 99 ptr-operator conversion-declarator(opt) */ 100 101static inline void 102pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t) 103{ 104 pp_cxx_ws_string (pp, "operator"); 105 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t)); 106} 107 108static inline void 109pp_cxx_template_id (cxx_pretty_printer *pp, tree t) 110{ 111 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0)); 112 pp_cxx_begin_template_argument_list (pp); 113 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1)); 114 pp_cxx_end_template_argument_list (pp); 115} 116 117/* Prints the unqualified part of the id-expression T. 118 119 unqualified-id: 120 identifier 121 operator-function-id 122 conversion-function-id 123 ~ class-name 124 template-id */ 125 126static void 127pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t) 128{ 129 enum tree_code code = TREE_CODE (t); 130 switch (code) 131 { 132 case RESULT_DECL: 133 pp->translate_string ("<return-value>"); 134 break; 135 136 case OVERLOAD: 137 t = OVL_FIRST (t); 138 /* FALLTHRU */ 139 case VAR_DECL: 140 case PARM_DECL: 141 case CONST_DECL: 142 case TYPE_DECL: 143 case FUNCTION_DECL: 144 case NAMESPACE_DECL: 145 case FIELD_DECL: 146 case LABEL_DECL: 147 case USING_DECL: 148 case TEMPLATE_DECL: 149 t = DECL_NAME (t); 150 /* FALLTHRU */ 151 152 case IDENTIFIER_NODE: 153 if (t == NULL) 154 pp->translate_string ("<unnamed>"); 155 else if (IDENTIFIER_CONV_OP_P (t)) 156 pp_cxx_conversion_function_id (pp, t); 157 else 158 pp_cxx_tree_identifier (pp, t); 159 break; 160 161 case TEMPLATE_ID_EXPR: 162 pp_cxx_template_id (pp, t); 163 break; 164 165 case BASELINK: 166 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t)); 167 break; 168 169 case RECORD_TYPE: 170 case UNION_TYPE: 171 case ENUMERAL_TYPE: 172 case TYPENAME_TYPE: 173 case UNBOUND_CLASS_TEMPLATE: 174 pp_cxx_unqualified_id (pp, TYPE_NAME (t)); 175 if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (t)) 176 if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti))) 177 { 178 pp_cxx_begin_template_argument_list (pp); 179 tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti)); 180 pp_cxx_template_argument_list (pp, args); 181 pp_cxx_end_template_argument_list (pp); 182 } 183 break; 184 185 case BIT_NOT_EXPR: 186 pp_cxx_complement (pp); 187 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0)); 188 break; 189 190 case TEMPLATE_TYPE_PARM: 191 case TEMPLATE_TEMPLATE_PARM: 192 if (template_placeholder_p (t)) 193 { 194 t = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t)); 195 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t)); 196 pp_string (pp, "<...auto...>"); 197 } 198 else if (TYPE_IDENTIFIER (t)) 199 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t)); 200 else 201 pp_cxx_canonical_template_parameter (pp, t); 202 break; 203 204 case TEMPLATE_PARM_INDEX: 205 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t)); 206 break; 207 208 case BOUND_TEMPLATE_TEMPLATE_PARM: 209 pp_cxx_cv_qualifier_seq (pp, t); 210 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t)); 211 pp_cxx_begin_template_argument_list (pp); 212 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t)); 213 pp_cxx_end_template_argument_list (pp); 214 break; 215 216 default: 217 pp_unsupported_tree (pp, t); 218 break; 219 } 220} 221 222/* Pretty-print out the token sequence ":: template" in template codes 223 where it is needed to "inline declare" the (following) member as 224 a template. This situation arises when SCOPE of T is dependent 225 on template parameters. */ 226 227static inline void 228pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t) 229{ 230 if (TREE_CODE (t) == TEMPLATE_ID_EXPR 231 && TYPE_P (scope) && dependent_type_p (scope)) 232 pp_cxx_ws_string (pp, "template"); 233} 234 235/* nested-name-specifier: 236 class-or-namespace-name :: nested-name-specifier(opt) 237 class-or-namespace-name :: template nested-name-specifier */ 238 239static void 240pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t) 241{ 242 /* FIXME: When diagnosing references to concepts (especially as types?) 243 we end up adding too many '::' to the name. This is partially due 244 to the fact that pp->enclosing_namespace is null. */ 245 if (t == global_namespace) 246 { 247 pp_cxx_colon_colon (pp); 248 } 249 else if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope) 250 { 251 tree scope = get_containing_scope (t); 252 pp_cxx_nested_name_specifier (pp, scope); 253 pp_cxx_template_keyword_if_needed (pp, scope, t); 254 pp_cxx_unqualified_id (pp, t); 255 pp_cxx_colon_colon (pp); 256 } 257} 258 259/* qualified-id: 260 nested-name-specifier template(opt) unqualified-id */ 261 262static void 263pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t) 264{ 265 switch (TREE_CODE (t)) 266 { 267 /* A pointer-to-member is always qualified. */ 268 case PTRMEM_CST: 269 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t)); 270 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t)); 271 break; 272 273 /* In Standard C++, functions cannot possibly be used as 274 nested-name-specifiers. However, there are situations where 275 is "makes sense" to output the surrounding function name for the 276 purpose of emphasizing on the scope kind. Just printing the 277 function name might not be sufficient as it may be overloaded; so, 278 we decorate the function with its signature too. 279 FIXME: This is probably the wrong pretty-printing for conversion 280 functions and some function templates. */ 281 case OVERLOAD: 282 t = OVL_FIRST (t); 283 /* FALLTHRU */ 284 case FUNCTION_DECL: 285 if (DECL_FUNCTION_MEMBER_P (t)) 286 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 287 pp_cxx_unqualified_id 288 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t); 289 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t)); 290 break; 291 292 case OFFSET_REF: 293 case SCOPE_REF: 294 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0)); 295 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1)); 296 break; 297 298 default: 299 { 300 tree scope = get_containing_scope (t); 301 if (scope != pp->enclosing_scope) 302 { 303 pp_cxx_nested_name_specifier (pp, scope); 304 pp_cxx_template_keyword_if_needed (pp, scope, t); 305 } 306 pp_cxx_unqualified_id (pp, t); 307 } 308 break; 309 } 310} 311 312/* Given a value e of ENUMERAL_TYPE: 313 Print out the first ENUMERATOR id with value e, if one is found, 314 (including nested names but excluding the enum name if unscoped) 315 else print out the value as a C-style cast (type-id)value. */ 316 317static void 318pp_cxx_enumeration_constant (cxx_pretty_printer *pp, tree e) 319{ 320 tree type = TREE_TYPE (e); 321 tree value = NULL_TREE; 322 323 /* Find the name of this constant. */ 324 if ((pp->flags & pp_c_flag_gnu_v3) == 0) 325 for (value = TYPE_VALUES (type); value != NULL_TREE; 326 value = TREE_CHAIN (value)) 327 if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e)) 328 break; 329 330 if (value != NULL_TREE) 331 { 332 if (!ENUM_IS_SCOPED (type)) 333 type = get_containing_scope (type); 334 pp_cxx_nested_name_specifier (pp, type); 335 pp->id_expression (TREE_PURPOSE (value)); 336 } 337 else 338 { 339 /* Value must have been cast. */ 340 pp_c_type_cast (pp, type); 341 pp_c_integer_constant (pp, e); 342 } 343} 344 345 346void 347cxx_pretty_printer::constant (tree t) 348{ 349 switch (TREE_CODE (t)) 350 { 351 case STRING_CST: 352 { 353 const bool in_parens = PAREN_STRING_LITERAL_P (t); 354 if (in_parens) 355 pp_cxx_left_paren (this); 356 c_pretty_printer::constant (t); 357 if (in_parens) 358 pp_cxx_right_paren (this); 359 } 360 break; 361 362 case INTEGER_CST: 363 if (NULLPTR_TYPE_P (TREE_TYPE (t))) 364 { 365 pp_string (this, "nullptr"); 366 break; 367 } 368 else if (TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) 369 { 370 pp_cxx_enumeration_constant (this, t); 371 break; 372 } 373 /* fall through. */ 374 375 default: 376 c_pretty_printer::constant (t); 377 break; 378 } 379} 380 381/* id-expression: 382 unqualified-id 383 qualified-id */ 384 385void 386cxx_pretty_printer::id_expression (tree t) 387{ 388 if (TREE_CODE (t) == OVERLOAD) 389 t = OVL_FIRST (t); 390 if (DECL_P (t) && DECL_CONTEXT (t)) 391 pp_cxx_qualified_id (this, t); 392 else 393 pp_cxx_unqualified_id (this, t); 394} 395 396/* user-defined literal: 397 literal ud-suffix */ 398 399void 400pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t) 401{ 402 pp->constant (USERDEF_LITERAL_VALUE (t)); 403 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t)); 404} 405 406 407/* primary-expression: 408 literal 409 this 410 :: identifier 411 :: operator-function-id 412 :: qualifier-id 413 ( expression ) 414 id-expression 415 416 GNU Extensions: 417 __builtin_va_arg ( assignment-expression , type-id ) 418 __builtin_offsetof ( type-id, offsetof-expression ) 419 __builtin_addressof ( expression ) 420 421 __has_nothrow_assign ( type-id ) 422 __has_nothrow_constructor ( type-id ) 423 __has_nothrow_copy ( type-id ) 424 __has_trivial_assign ( type-id ) 425 __has_trivial_constructor ( type-id ) 426 __has_trivial_copy ( type-id ) 427 __has_unique_object_representations ( type-id ) 428 __has_trivial_destructor ( type-id ) 429 __has_virtual_destructor ( type-id ) 430 __is_abstract ( type-id ) 431 __is_base_of ( type-id , type-id ) 432 __is_class ( type-id ) 433 __is_empty ( type-id ) 434 __is_enum ( type-id ) 435 __is_literal_type ( type-id ) 436 __is_pod ( type-id ) 437 __is_polymorphic ( type-id ) 438 __is_std_layout ( type-id ) 439 __is_trivial ( type-id ) 440 __is_union ( type-id ) */ 441 442void 443cxx_pretty_printer::primary_expression (tree t) 444{ 445 switch (TREE_CODE (t)) 446 { 447 case VOID_CST: 448 case INTEGER_CST: 449 case REAL_CST: 450 case COMPLEX_CST: 451 case STRING_CST: 452 constant (t); 453 break; 454 455 case USERDEF_LITERAL: 456 pp_cxx_userdef_literal (this, t); 457 break; 458 459 case BASELINK: 460 t = BASELINK_FUNCTIONS (t); 461 /* FALLTHRU */ 462 case VAR_DECL: 463 case PARM_DECL: 464 case FIELD_DECL: 465 case FUNCTION_DECL: 466 case OVERLOAD: 467 case CONST_DECL: 468 case TEMPLATE_DECL: 469 id_expression (t); 470 break; 471 472 case RESULT_DECL: 473 case TEMPLATE_TYPE_PARM: 474 case TEMPLATE_TEMPLATE_PARM: 475 case TEMPLATE_PARM_INDEX: 476 pp_cxx_unqualified_id (this, t); 477 break; 478 479 case STMT_EXPR: 480 pp_cxx_left_paren (this); 481 statement (STMT_EXPR_STMT (t)); 482 pp_cxx_right_paren (this); 483 break; 484 485 case TRAIT_EXPR: 486 pp_cxx_trait_expression (this, t); 487 break; 488 489 case VA_ARG_EXPR: 490 pp_cxx_va_arg_expression (this, t); 491 break; 492 493 case OFFSETOF_EXPR: 494 pp_cxx_offsetof_expression (this, t); 495 break; 496 497 case ADDRESSOF_EXPR: 498 pp_cxx_addressof_expression (this, t); 499 break; 500 501 case REQUIRES_EXPR: 502 pp_cxx_requires_expr (this, t); 503 break; 504 505 default: 506 c_pretty_printer::primary_expression (t); 507 break; 508 } 509} 510 511/* postfix-expression: 512 primary-expression 513 postfix-expression [ expression ] 514 postfix-expression ( expression-list(opt) ) 515 simple-type-specifier ( expression-list(opt) ) 516 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) ) 517 typename ::(opt) nested-name-specifier template(opt) 518 template-id ( expression-list(opt) ) 519 postfix-expression . template(opt) ::(opt) id-expression 520 postfix-expression -> template(opt) ::(opt) id-expression 521 postfix-expression . pseudo-destructor-name 522 postfix-expression -> pseudo-destructor-name 523 postfix-expression ++ 524 postfix-expression -- 525 dynamic_cast < type-id > ( expression ) 526 static_cast < type-id > ( expression ) 527 reinterpret_cast < type-id > ( expression ) 528 const_cast < type-id > ( expression ) 529 typeid ( expression ) 530 typeid ( type-id ) */ 531 532void 533cxx_pretty_printer::postfix_expression (tree t) 534{ 535 enum tree_code code = TREE_CODE (t); 536 537 switch (code) 538 { 539 case AGGR_INIT_EXPR: 540 case CALL_EXPR: 541 { 542 tree fun = cp_get_callee (t); 543 tree saved_scope = enclosing_scope; 544 bool skipfirst = false; 545 tree arg; 546 547 if (TREE_CODE (fun) == ADDR_EXPR) 548 fun = TREE_OPERAND (fun, 0); 549 550 /* In templates, where there is no way to tell whether a given 551 call uses an actual member function. So the parser builds 552 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until 553 instantiation time. */ 554 if (TREE_CODE (fun) != FUNCTION_DECL) 555 ; 556 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)) 557 { 558 tree object = (code == AGGR_INIT_EXPR 559 ? (AGGR_INIT_VIA_CTOR_P (t) 560 ? AGGR_INIT_EXPR_SLOT (t) 561 : AGGR_INIT_EXPR_ARG (t, 0)) 562 : CALL_EXPR_ARG (t, 0)); 563 564 while (TREE_CODE (object) == NOP_EXPR) 565 object = TREE_OPERAND (object, 0); 566 567 if (TREE_CODE (object) == ADDR_EXPR) 568 object = TREE_OPERAND (object, 0); 569 570 if (!TYPE_PTR_P (TREE_TYPE (object))) 571 { 572 postfix_expression (object); 573 pp_cxx_dot (this); 574 } 575 else 576 { 577 postfix_expression (object); 578 pp_cxx_arrow (this); 579 } 580 skipfirst = true; 581 enclosing_scope = strip_pointer_operator (TREE_TYPE (object)); 582 } 583 584 postfix_expression (fun); 585 enclosing_scope = saved_scope; 586 pp_cxx_left_paren (this); 587 if (code == AGGR_INIT_EXPR) 588 { 589 aggr_init_expr_arg_iterator iter; 590 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t) 591 { 592 if (skipfirst) 593 skipfirst = false; 594 else 595 { 596 expression (arg); 597 if (more_aggr_init_expr_args_p (&iter)) 598 pp_cxx_separate_with (this, ','); 599 } 600 } 601 } 602 else 603 { 604 call_expr_arg_iterator iter; 605 FOR_EACH_CALL_EXPR_ARG (arg, iter, t) 606 { 607 if (skipfirst) 608 skipfirst = false; 609 else 610 { 611 expression (arg); 612 if (more_call_expr_args_p (&iter)) 613 pp_cxx_separate_with (this, ','); 614 } 615 } 616 } 617 pp_cxx_right_paren (this); 618 } 619 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)) 620 { 621 pp_cxx_separate_with (this, ','); 622 postfix_expression (AGGR_INIT_EXPR_SLOT (t)); 623 } 624 break; 625 626 case BASELINK: 627 case VAR_DECL: 628 case PARM_DECL: 629 case FIELD_DECL: 630 case FUNCTION_DECL: 631 case OVERLOAD: 632 case CONST_DECL: 633 case TEMPLATE_DECL: 634 case RESULT_DECL: 635 primary_expression (t); 636 break; 637 638 case DYNAMIC_CAST_EXPR: 639 case STATIC_CAST_EXPR: 640 case REINTERPRET_CAST_EXPR: 641 case CONST_CAST_EXPR: 642 if (code == DYNAMIC_CAST_EXPR) 643 pp_cxx_ws_string (this, "dynamic_cast"); 644 else if (code == STATIC_CAST_EXPR) 645 pp_cxx_ws_string (this, "static_cast"); 646 else if (code == REINTERPRET_CAST_EXPR) 647 pp_cxx_ws_string (this, "reinterpret_cast"); 648 else 649 pp_cxx_ws_string (this, "const_cast"); 650 pp_cxx_begin_template_argument_list (this); 651 type_id (TREE_TYPE (t)); 652 pp_cxx_end_template_argument_list (this); 653 pp_left_paren (this); 654 expression (TREE_OPERAND (t, 0)); 655 pp_right_paren (this); 656 break; 657 658 case BIT_CAST_EXPR: 659 pp_cxx_ws_string (this, "__builtin_bit_cast"); 660 pp_left_paren (this); 661 type_id (TREE_TYPE (t)); 662 pp_comma (this); 663 expression (TREE_OPERAND (t, 0)); 664 pp_right_paren (this); 665 break; 666 667 case EMPTY_CLASS_EXPR: 668 type_id (TREE_TYPE (t)); 669 pp_left_paren (this); 670 pp_right_paren (this); 671 break; 672 673 case TYPEID_EXPR: 674 pp_cxx_typeid_expression (this, t); 675 break; 676 677 case PSEUDO_DTOR_EXPR: 678 postfix_expression (TREE_OPERAND (t, 0)); 679 pp_cxx_dot (this); 680 if (TREE_OPERAND (t, 1)) 681 { 682 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1)); 683 pp_cxx_colon_colon (this); 684 } 685 pp_complement (this); 686 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2)); 687 break; 688 689 case ARROW_EXPR: 690 postfix_expression (TREE_OPERAND (t, 0)); 691 pp_cxx_arrow (this); 692 break; 693 694 default: 695 c_pretty_printer::postfix_expression (t); 696 break; 697 } 698} 699 700/* new-expression: 701 ::(opt) new new-placement(opt) new-type-id new-initializer(opt) 702 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt) 703 704 new-placement: 705 ( expression-list ) 706 707 new-type-id: 708 type-specifier-seq new-declarator(opt) 709 710 new-declarator: 711 ptr-operator new-declarator(opt) 712 direct-new-declarator 713 714 direct-new-declarator 715 [ expression ] 716 direct-new-declarator [ constant-expression ] 717 718 new-initializer: 719 ( expression-list(opt) ) */ 720 721static void 722pp_cxx_new_expression (cxx_pretty_printer *pp, tree t) 723{ 724 enum tree_code code = TREE_CODE (t); 725 tree type = TREE_OPERAND (t, 1); 726 tree init = TREE_OPERAND (t, 2); 727 switch (code) 728 { 729 case NEW_EXPR: 730 case VEC_NEW_EXPR: 731 if (NEW_EXPR_USE_GLOBAL (t)) 732 pp_cxx_colon_colon (pp); 733 pp_cxx_ws_string (pp, "new"); 734 if (TREE_OPERAND (t, 0)) 735 { 736 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0)); 737 pp_space (pp); 738 } 739 if (TREE_CODE (type) == ARRAY_REF) 740 type = build_cplus_array_type 741 (TREE_OPERAND (type, 0), 742 build_index_type (fold_build2_loc (input_location, 743 MINUS_EXPR, integer_type_node, 744 TREE_OPERAND (type, 1), 745 integer_one_node))); 746 pp->type_id (type); 747 if (init) 748 { 749 pp_left_paren (pp); 750 if (TREE_CODE (init) == TREE_LIST) 751 pp_c_expression_list (pp, init); 752 else if (init == void_node) 753 ; /* OK, empty initializer list. */ 754 else 755 pp->expression (init); 756 pp_right_paren (pp); 757 } 758 break; 759 760 default: 761 pp_unsupported_tree (pp, t); 762 } 763} 764 765/* delete-expression: 766 ::(opt) delete cast-expression 767 ::(opt) delete [ ] cast-expression */ 768 769static void 770pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t) 771{ 772 enum tree_code code = TREE_CODE (t); 773 switch (code) 774 { 775 case DELETE_EXPR: 776 case VEC_DELETE_EXPR: 777 if (DELETE_EXPR_USE_GLOBAL (t)) 778 pp_cxx_colon_colon (pp); 779 pp_cxx_ws_string (pp, "delete"); 780 pp_space (pp); 781 if (code == VEC_DELETE_EXPR 782 || DELETE_EXPR_USE_VEC (t)) 783 { 784 pp_left_bracket (pp); 785 pp_right_bracket (pp); 786 pp_space (pp); 787 } 788 pp_c_cast_expression (pp, TREE_OPERAND (t, 0)); 789 break; 790 791 default: 792 pp_unsupported_tree (pp, t); 793 } 794} 795 796/* unary-expression: 797 postfix-expression 798 ++ cast-expression 799 -- cast-expression 800 unary-operator cast-expression 801 sizeof unary-expression 802 sizeof ( type-id ) 803 sizeof ... ( identifier ) 804 new-expression 805 delete-expression 806 807 unary-operator: one of 808 * & + - ! 809 810 GNU extensions: 811 __alignof__ unary-expression 812 __alignof__ ( type-id ) */ 813 814void 815cxx_pretty_printer::unary_expression (tree t) 816{ 817 enum tree_code code = TREE_CODE (t); 818 switch (code) 819 { 820 case NEW_EXPR: 821 case VEC_NEW_EXPR: 822 pp_cxx_new_expression (this, t); 823 break; 824 825 case DELETE_EXPR: 826 case VEC_DELETE_EXPR: 827 pp_cxx_delete_expression (this, t); 828 break; 829 830 case SIZEOF_EXPR: 831 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) 832 { 833 pp_cxx_ws_string (this, "sizeof"); 834 pp_cxx_ws_string (this, "..."); 835 pp_cxx_whitespace (this); 836 pp_cxx_left_paren (this); 837 if (TYPE_P (TREE_OPERAND (t, 0))) 838 type_id (TREE_OPERAND (t, 0)); 839 else 840 unary_expression (TREE_OPERAND (t, 0)); 841 pp_cxx_right_paren (this); 842 break; 843 } 844 /* Fall through */ 845 846 case ALIGNOF_EXPR: 847 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__"); 848 pp_cxx_whitespace (this); 849 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) 850 { 851 pp_cxx_left_paren (this); 852 type_id (TREE_TYPE (TREE_OPERAND (t, 0))); 853 pp_cxx_right_paren (this); 854 } 855 else if (TYPE_P (TREE_OPERAND (t, 0))) 856 { 857 pp_cxx_left_paren (this); 858 type_id (TREE_OPERAND (t, 0)); 859 pp_cxx_right_paren (this); 860 } 861 else 862 unary_expression (TREE_OPERAND (t, 0)); 863 break; 864 865 case AT_ENCODE_EXPR: 866 pp_cxx_ws_string (this, "@encode"); 867 pp_cxx_whitespace (this); 868 pp_cxx_left_paren (this); 869 type_id (TREE_OPERAND (t, 0)); 870 pp_cxx_right_paren (this); 871 break; 872 873 case NOEXCEPT_EXPR: 874 pp_cxx_ws_string (this, "noexcept"); 875 pp_cxx_whitespace (this); 876 pp_cxx_left_paren (this); 877 expression (TREE_OPERAND (t, 0)); 878 pp_cxx_right_paren (this); 879 break; 880 881 case UNARY_PLUS_EXPR: 882 pp_plus (this); 883 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0)); 884 break; 885 886 default: 887 c_pretty_printer::unary_expression (t); 888 break; 889 } 890} 891 892/* cast-expression: 893 unary-expression 894 ( type-id ) cast-expression */ 895 896static void 897pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t) 898{ 899 switch (TREE_CODE (t)) 900 { 901 case CAST_EXPR: 902 case IMPLICIT_CONV_EXPR: 903 pp->type_id (TREE_TYPE (t)); 904 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0)); 905 break; 906 907 default: 908 pp_c_cast_expression (pp, t); 909 break; 910 } 911} 912 913/* pm-expression: 914 cast-expression 915 pm-expression .* cast-expression 916 pm-expression ->* cast-expression */ 917 918static void 919pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t) 920{ 921 switch (TREE_CODE (t)) 922 { 923 /* Handle unfortunate OFFSET_REF overloading here. */ 924 case OFFSET_REF: 925 if (TYPE_P (TREE_OPERAND (t, 0))) 926 { 927 pp_cxx_qualified_id (pp, t); 928 break; 929 } 930 /* Fall through. */ 931 case MEMBER_REF: 932 case DOTSTAR_EXPR: 933 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0)); 934 if (TREE_CODE (t) == MEMBER_REF) 935 pp_cxx_arrow (pp); 936 else 937 pp_cxx_dot (pp); 938 pp_star(pp); 939 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1)); 940 break; 941 942 943 default: 944 pp_cxx_cast_expression (pp, t); 945 break; 946 } 947} 948 949/* multiplicative-expression: 950 pm-expression 951 multiplicative-expression * pm-expression 952 multiplicative-expression / pm-expression 953 multiplicative-expression % pm-expression */ 954 955void 956cxx_pretty_printer::multiplicative_expression (tree e) 957{ 958 enum tree_code code = TREE_CODE (e); 959 switch (code) 960 { 961 case MULT_EXPR: 962 case TRUNC_DIV_EXPR: 963 case TRUNC_MOD_EXPR: 964 case EXACT_DIV_EXPR: 965 case RDIV_EXPR: 966 multiplicative_expression (TREE_OPERAND (e, 0)); 967 pp_space (this); 968 if (code == MULT_EXPR) 969 pp_star (this); 970 else if (code != TRUNC_MOD_EXPR) 971 pp_slash (this); 972 else 973 pp_modulo (this); 974 pp_space (this); 975 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1)); 976 break; 977 978 default: 979 pp_cxx_pm_expression (this, e); 980 break; 981 } 982} 983 984/* conditional-expression: 985 logical-or-expression 986 logical-or-expression ? expression : assignment-expression */ 987 988void 989cxx_pretty_printer::conditional_expression (tree e) 990{ 991 if (TREE_CODE (e) == COND_EXPR) 992 { 993 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0)); 994 pp_space (this); 995 pp_question (this); 996 pp_space (this); 997 expression (TREE_OPERAND (e, 1)); 998 pp_space (this); 999 assignment_expression (TREE_OPERAND (e, 2)); 1000 } 1001 else 1002 pp_c_logical_or_expression (this, e); 1003} 1004 1005/* Pretty-print a compound assignment operator token as indicated by T. */ 1006 1007static void 1008pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t) 1009{ 1010 const char *op; 1011 1012 switch (TREE_CODE (t)) 1013 { 1014 case NOP_EXPR: 1015 op = "="; 1016 break; 1017 1018 case PLUS_EXPR: 1019 op = "+="; 1020 break; 1021 1022 case MINUS_EXPR: 1023 op = "-="; 1024 break; 1025 1026 case TRUNC_DIV_EXPR: 1027 op = "/="; 1028 break; 1029 1030 case TRUNC_MOD_EXPR: 1031 op = "%="; 1032 break; 1033 1034 default: 1035 op = get_tree_code_name (TREE_CODE (t)); 1036 break; 1037 } 1038 1039 pp_cxx_ws_string (pp, op); 1040} 1041 1042 1043/* assignment-expression: 1044 conditional-expression 1045 logical-or-expression assignment-operator assignment-expression 1046 throw-expression 1047 1048 throw-expression: 1049 throw assignment-expression(opt) 1050 1051 assignment-operator: one of 1052 = *= /= %= += -= >>= <<= &= ^= |= */ 1053 1054void 1055cxx_pretty_printer::assignment_expression (tree e) 1056{ 1057 switch (TREE_CODE (e)) 1058 { 1059 case MODIFY_EXPR: 1060 case INIT_EXPR: 1061 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0)); 1062 pp_space (this); 1063 pp_equal (this); 1064 pp_space (this); 1065 assignment_expression (TREE_OPERAND (e, 1)); 1066 break; 1067 1068 case THROW_EXPR: 1069 pp_cxx_ws_string (this, "throw"); 1070 if (TREE_OPERAND (e, 0)) 1071 assignment_expression (TREE_OPERAND (e, 0)); 1072 break; 1073 1074 case MODOP_EXPR: 1075 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0)); 1076 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1)); 1077 assignment_expression (TREE_OPERAND (e, 2)); 1078 break; 1079 1080 default: 1081 conditional_expression (e); 1082 break; 1083 } 1084} 1085 1086void 1087cxx_pretty_printer::expression (tree t) 1088{ 1089 switch (TREE_CODE (t)) 1090 { 1091 case STRING_CST: 1092 case VOID_CST: 1093 case INTEGER_CST: 1094 case REAL_CST: 1095 case COMPLEX_CST: 1096 constant (t); 1097 break; 1098 1099 case USERDEF_LITERAL: 1100 pp_cxx_userdef_literal (this, t); 1101 break; 1102 1103 case RESULT_DECL: 1104 pp_cxx_unqualified_id (this, t); 1105 break; 1106 1107#if 0 1108 case OFFSET_REF: 1109#endif 1110 case SCOPE_REF: 1111 case PTRMEM_CST: 1112 pp_cxx_qualified_id (this, t); 1113 break; 1114 1115 case OVERLOAD: 1116 t = OVL_FIRST (t); 1117 /* FALLTHRU */ 1118 case VAR_DECL: 1119 case PARM_DECL: 1120 case FIELD_DECL: 1121 case CONST_DECL: 1122 case FUNCTION_DECL: 1123 case BASELINK: 1124 case TEMPLATE_DECL: 1125 case TEMPLATE_TYPE_PARM: 1126 case TEMPLATE_PARM_INDEX: 1127 case TEMPLATE_TEMPLATE_PARM: 1128 case STMT_EXPR: 1129 case REQUIRES_EXPR: 1130 primary_expression (t); 1131 break; 1132 1133 case CALL_EXPR: 1134 case DYNAMIC_CAST_EXPR: 1135 case STATIC_CAST_EXPR: 1136 case REINTERPRET_CAST_EXPR: 1137 case CONST_CAST_EXPR: 1138#if 0 1139 case MEMBER_REF: 1140#endif 1141 case EMPTY_CLASS_EXPR: 1142 case TYPEID_EXPR: 1143 case PSEUDO_DTOR_EXPR: 1144 case AGGR_INIT_EXPR: 1145 case ARROW_EXPR: 1146 postfix_expression (t); 1147 break; 1148 1149 case NEW_EXPR: 1150 case VEC_NEW_EXPR: 1151 pp_cxx_new_expression (this, t); 1152 break; 1153 1154 case DELETE_EXPR: 1155 case VEC_DELETE_EXPR: 1156 pp_cxx_delete_expression (this, t); 1157 break; 1158 1159 case SIZEOF_EXPR: 1160 case ALIGNOF_EXPR: 1161 case NOEXCEPT_EXPR: 1162 case UNARY_PLUS_EXPR: 1163 unary_expression (t); 1164 break; 1165 1166 case CAST_EXPR: 1167 case IMPLICIT_CONV_EXPR: 1168 pp_cxx_cast_expression (this, t); 1169 break; 1170 1171 case OFFSET_REF: 1172 case MEMBER_REF: 1173 case DOTSTAR_EXPR: 1174 pp_cxx_pm_expression (this, t); 1175 break; 1176 1177 case MULT_EXPR: 1178 case TRUNC_DIV_EXPR: 1179 case TRUNC_MOD_EXPR: 1180 case EXACT_DIV_EXPR: 1181 case RDIV_EXPR: 1182 multiplicative_expression (t); 1183 break; 1184 1185 case COND_EXPR: 1186 conditional_expression (t); 1187 break; 1188 1189 case MODIFY_EXPR: 1190 case INIT_EXPR: 1191 case THROW_EXPR: 1192 case MODOP_EXPR: 1193 assignment_expression (t); 1194 break; 1195 1196 case NON_DEPENDENT_EXPR: 1197 case MUST_NOT_THROW_EXPR: 1198 expression (TREE_OPERAND (t, 0)); 1199 break; 1200 1201 case EXPR_PACK_EXPANSION: 1202 expression (PACK_EXPANSION_PATTERN (t)); 1203 pp_cxx_ws_string (this, "..."); 1204 break; 1205 1206 case UNARY_LEFT_FOLD_EXPR: 1207 pp_cxx_unary_left_fold_expression (this, t); 1208 break; 1209 1210 case UNARY_RIGHT_FOLD_EXPR: 1211 pp_cxx_unary_right_fold_expression (this, t); 1212 break; 1213 1214 case BINARY_LEFT_FOLD_EXPR: 1215 case BINARY_RIGHT_FOLD_EXPR: 1216 pp_cxx_binary_fold_expression (this, t); 1217 break; 1218 1219 case TEMPLATE_ID_EXPR: 1220 pp_cxx_template_id (this, t); 1221 break; 1222 1223 case NONTYPE_ARGUMENT_PACK: 1224 { 1225 tree args = ARGUMENT_PACK_ARGS (t); 1226 int i, len = TREE_VEC_LENGTH (args); 1227 pp_cxx_left_brace (this); 1228 for (i = 0; i < len; ++i) 1229 { 1230 if (i > 0) 1231 pp_cxx_separate_with (this, ','); 1232 expression (TREE_VEC_ELT (args, i)); 1233 } 1234 pp_cxx_right_brace (this); 1235 } 1236 break; 1237 1238 case LAMBDA_EXPR: 1239 pp_cxx_ws_string (this, "<lambda>"); 1240 break; 1241 1242 case TRAIT_EXPR: 1243 pp_cxx_trait_expression (this, t); 1244 break; 1245 1246 case ATOMIC_CONSTR: 1247 case CHECK_CONSTR: 1248 case CONJ_CONSTR: 1249 case DISJ_CONSTR: 1250 pp_cxx_constraint (this, t); 1251 break; 1252 1253 case PAREN_EXPR: 1254 pp_cxx_left_paren (this); 1255 expression (TREE_OPERAND (t, 0)); 1256 pp_cxx_right_paren (this); 1257 break; 1258 1259 default: 1260 c_pretty_printer::expression (t); 1261 break; 1262 } 1263} 1264 1265 1266/* Declarations. */ 1267 1268/* function-specifier: 1269 inline 1270 virtual 1271 explicit */ 1272 1273void 1274cxx_pretty_printer::function_specifier (tree t) 1275{ 1276 switch (TREE_CODE (t)) 1277 { 1278 case FUNCTION_DECL: 1279 if (DECL_VIRTUAL_P (t)) 1280 pp_cxx_ws_string (this, "virtual"); 1281 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t)) 1282 pp_cxx_ws_string (this, "explicit"); 1283 else 1284 c_pretty_printer::function_specifier (t); 1285 1286 default: 1287 break; 1288 } 1289} 1290 1291/* decl-specifier-seq: 1292 decl-specifier-seq(opt) decl-specifier 1293 1294 decl-specifier: 1295 storage-class-specifier 1296 type-specifier 1297 function-specifier 1298 friend 1299 typedef */ 1300 1301void 1302cxx_pretty_printer::declaration_specifiers (tree t) 1303{ 1304 switch (TREE_CODE (t)) 1305 { 1306 case VAR_DECL: 1307 case PARM_DECL: 1308 case CONST_DECL: 1309 case FIELD_DECL: 1310 storage_class_specifier (t); 1311 declaration_specifiers (TREE_TYPE (t)); 1312 break; 1313 1314 case TYPE_DECL: 1315 pp_cxx_ws_string (this, "typedef"); 1316 declaration_specifiers (TREE_TYPE (t)); 1317 break; 1318 1319 case FUNCTION_DECL: 1320 /* Constructors don't have return types. And conversion functions 1321 do not have a type-specifier in their return types. */ 1322 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t)) 1323 function_specifier (t); 1324 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) 1325 declaration_specifiers (TREE_TYPE (TREE_TYPE (t))); 1326 else 1327 c_pretty_printer::declaration_specifiers (t); 1328 break; 1329 default: 1330 c_pretty_printer::declaration_specifiers (t); 1331 break; 1332 } 1333} 1334 1335/* simple-type-specifier: 1336 ::(opt) nested-name-specifier(opt) type-name 1337 ::(opt) nested-name-specifier(opt) template(opt) template-id 1338 decltype-specifier 1339 char 1340 wchar_t 1341 bool 1342 short 1343 int 1344 long 1345 signed 1346 unsigned 1347 float 1348 double 1349 void */ 1350 1351void 1352cxx_pretty_printer::simple_type_specifier (tree t) 1353{ 1354 switch (TREE_CODE (t)) 1355 { 1356 case RECORD_TYPE: 1357 case UNION_TYPE: 1358 case ENUMERAL_TYPE: 1359 pp_cxx_qualified_id (this, t); 1360 break; 1361 1362 case TEMPLATE_TYPE_PARM: 1363 case TEMPLATE_TEMPLATE_PARM: 1364 case TEMPLATE_PARM_INDEX: 1365 case BOUND_TEMPLATE_TEMPLATE_PARM: 1366 pp_cxx_unqualified_id (this, t); 1367 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t)) 1368 pp_cxx_constrained_type_spec (this, c); 1369 break; 1370 1371 case TYPENAME_TYPE: 1372 pp_cxx_ws_string (this, "typename"); 1373 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t)); 1374 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t)); 1375 break; 1376 1377 case DECLTYPE_TYPE: 1378 pp_cxx_ws_string (this, "decltype"); 1379 pp_cxx_left_paren (this); 1380 this->expression (DECLTYPE_TYPE_EXPR (t)); 1381 pp_cxx_right_paren (this); 1382 break; 1383 1384 case NULLPTR_TYPE: 1385 pp_cxx_ws_string (this, "std::nullptr_t"); 1386 break; 1387 1388 default: 1389 c_pretty_printer::simple_type_specifier (t); 1390 break; 1391 } 1392} 1393 1394/* type-specifier-seq: 1395 type-specifier type-specifier-seq(opt) 1396 1397 type-specifier: 1398 simple-type-specifier 1399 class-specifier 1400 enum-specifier 1401 elaborated-type-specifier 1402 cv-qualifier */ 1403 1404static void 1405pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t) 1406{ 1407 switch (TREE_CODE (t)) 1408 { 1409 case TEMPLATE_DECL: 1410 case TEMPLATE_TYPE_PARM: 1411 case TEMPLATE_TEMPLATE_PARM: 1412 case TYPE_DECL: 1413 case BOUND_TEMPLATE_TEMPLATE_PARM: 1414 case DECLTYPE_TYPE: 1415 case NULLPTR_TYPE: 1416 pp_cxx_cv_qualifier_seq (pp, t); 1417 pp->simple_type_specifier (t); 1418 break; 1419 1420 case METHOD_TYPE: 1421 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t)); 1422 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t)); 1423 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t)); 1424 break; 1425 1426 case RECORD_TYPE: 1427 if (TYPE_PTRMEMFUNC_P (t)) 1428 { 1429 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t); 1430 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm))); 1431 pp_cxx_whitespace (pp); 1432 pp_cxx_ptr_operator (pp, t); 1433 break; 1434 } 1435 /* fall through */ 1436 1437 case OFFSET_TYPE: 1438 if (TYPE_PTRDATAMEM_P (t)) 1439 { 1440 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t)); 1441 pp_cxx_whitespace (pp); 1442 pp_cxx_ptr_operator (pp, t); 1443 break; 1444 } 1445 /* fall through */ 1446 1447 default: 1448 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t))) 1449 pp_c_specifier_qualifier_list (pp, t); 1450 } 1451} 1452 1453/* ptr-operator: 1454 * cv-qualifier-seq(opt) 1455 & 1456 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */ 1457 1458static void 1459pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t) 1460{ 1461 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL) 1462 t = TREE_TYPE (t); 1463 switch (TREE_CODE (t)) 1464 { 1465 case REFERENCE_TYPE: 1466 case POINTER_TYPE: 1467 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t))) 1468 pp_cxx_ptr_operator (pp, TREE_TYPE (t)); 1469 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t))); 1470 if (TYPE_PTR_P (t)) 1471 { 1472 pp_star (pp); 1473 pp_cxx_cv_qualifier_seq (pp, t); 1474 } 1475 else 1476 pp_ampersand (pp); 1477 break; 1478 1479 case RECORD_TYPE: 1480 if (TYPE_PTRMEMFUNC_P (t)) 1481 { 1482 pp_cxx_left_paren (pp); 1483 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t)); 1484 pp_star (pp); 1485 break; 1486 } 1487 /* FALLTHRU */ 1488 case OFFSET_TYPE: 1489 if (TYPE_PTRMEM_P (t)) 1490 { 1491 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 1492 pp_cxx_left_paren (pp); 1493 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t)); 1494 pp_star (pp); 1495 pp_cxx_cv_qualifier_seq (pp, t); 1496 break; 1497 } 1498 /* fall through. */ 1499 1500 default: 1501 pp_unsupported_tree (pp, t); 1502 break; 1503 } 1504} 1505 1506static inline tree 1507pp_cxx_implicit_parameter_type (tree mf) 1508{ 1509 return class_of_this_parm (TREE_TYPE (mf)); 1510} 1511 1512/* 1513 parameter-declaration: 1514 decl-specifier-seq declarator 1515 decl-specifier-seq declarator = assignment-expression 1516 decl-specifier-seq abstract-declarator(opt) 1517 decl-specifier-seq abstract-declarator(opt) assignment-expression */ 1518 1519static inline void 1520pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t) 1521{ 1522 pp->declaration_specifiers (t); 1523 if (TYPE_P (t)) 1524 pp->abstract_declarator (t); 1525 else 1526 pp->declarator (t); 1527} 1528 1529/* parameter-declaration-clause: 1530 parameter-declaration-list(opt) ...(opt) 1531 parameter-declaration-list , ... 1532 1533 parameter-declaration-list: 1534 parameter-declaration 1535 parameter-declaration-list , parameter-declaration */ 1536 1537static void 1538pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t) 1539{ 1540 gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL); 1541 tree types, args; 1542 if (TYPE_P (t)) 1543 { 1544 types = TYPE_ARG_TYPES (t); 1545 args = NULL_TREE; 1546 } 1547 else 1548 { 1549 types = FUNCTION_FIRST_USER_PARMTYPE (t); 1550 args = FUNCTION_FIRST_USER_PARM (t); 1551 } 1552 bool abstract = !args || (pp->flags & pp_c_flag_abstract); 1553 1554 /* Skip artificial parameter for non-static member functions. */ 1555 if (TREE_CODE (t) == METHOD_TYPE) 1556 types = TREE_CHAIN (types); 1557 1558 bool first = true; 1559 pp_cxx_left_paren (pp); 1560 for (; types != void_list_node; types = TREE_CHAIN (types)) 1561 { 1562 if (!first) 1563 pp_cxx_separate_with (pp, ','); 1564 first = false; 1565 if (!types) 1566 { 1567 pp_cxx_ws_string (pp, "..."); 1568 break; 1569 } 1570 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args); 1571 if (!abstract && pp->flags & pp_cxx_flag_default_argument) 1572 { 1573 pp_cxx_whitespace (pp); 1574 pp_equal (pp); 1575 pp_cxx_whitespace (pp); 1576 pp->assignment_expression (TREE_PURPOSE (types)); 1577 } 1578 if (!abstract) 1579 args = TREE_CHAIN (args); 1580 } 1581 pp_cxx_right_paren (pp); 1582} 1583 1584/* exception-specification: 1585 throw ( type-id-list(opt) ) 1586 1587 type-id-list 1588 type-id 1589 type-id-list , type-id */ 1590 1591static void 1592pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t) 1593{ 1594 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t); 1595 bool need_comma = false; 1596 1597 if (ex_spec == NULL) 1598 return; 1599 if (TREE_PURPOSE (ex_spec)) 1600 { 1601 pp_cxx_ws_string (pp, "noexcept"); 1602 pp_cxx_whitespace (pp); 1603 pp_cxx_left_paren (pp); 1604 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec)) 1605 pp_cxx_ws_string (pp, "<uninstantiated>"); 1606 else 1607 pp->expression (TREE_PURPOSE (ex_spec)); 1608 pp_cxx_right_paren (pp); 1609 return; 1610 } 1611 pp_cxx_ws_string (pp, "throw"); 1612 pp_cxx_left_paren (pp); 1613 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec)) 1614 { 1615 tree type = TREE_VALUE (ex_spec); 1616 tree argpack = NULL_TREE; 1617 int i, len = 1; 1618 1619 if (ARGUMENT_PACK_P (type)) 1620 { 1621 argpack = ARGUMENT_PACK_ARGS (type); 1622 len = TREE_VEC_LENGTH (argpack); 1623 } 1624 1625 for (i = 0; i < len; ++i) 1626 { 1627 if (argpack) 1628 type = TREE_VEC_ELT (argpack, i); 1629 1630 if (need_comma) 1631 pp_cxx_separate_with (pp, ','); 1632 else 1633 need_comma = true; 1634 1635 pp->type_id (type); 1636 } 1637 } 1638 pp_cxx_right_paren (pp); 1639} 1640 1641/* direct-declarator: 1642 declarator-id 1643 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt) 1644 exception-specification(opt) 1645 direct-declaration [ constant-expression(opt) ] 1646 ( declarator ) */ 1647 1648void 1649cxx_pretty_printer::direct_declarator (tree t) 1650{ 1651 switch (TREE_CODE (t)) 1652 { 1653 case VAR_DECL: 1654 case PARM_DECL: 1655 case CONST_DECL: 1656 case FIELD_DECL: 1657 if (DECL_NAME (t)) 1658 { 1659 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t)); 1660 1661 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t)) 1662 || template_parameter_pack_p (t)) 1663 /* A function parameter pack or non-type template 1664 parameter pack. */ 1665 pp_cxx_ws_string (this, "..."); 1666 1667 id_expression (DECL_NAME (t)); 1668 } 1669 abstract_declarator (TREE_TYPE (t)); 1670 break; 1671 1672 case FUNCTION_DECL: 1673 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t))); 1674 expression (t); 1675 pp_cxx_parameter_declaration_clause (this, t); 1676 1677 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) 1678 { 1679 padding = pp_before; 1680 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t)); 1681 } 1682 1683 pp_cxx_exception_specification (this, TREE_TYPE (t)); 1684 break; 1685 1686 case TYPENAME_TYPE: 1687 case TEMPLATE_DECL: 1688 case TEMPLATE_TYPE_PARM: 1689 case TEMPLATE_PARM_INDEX: 1690 case TEMPLATE_TEMPLATE_PARM: 1691 break; 1692 1693 default: 1694 c_pretty_printer::direct_declarator (t); 1695 break; 1696 } 1697} 1698 1699/* declarator: 1700 direct-declarator 1701 ptr-operator declarator */ 1702 1703void 1704cxx_pretty_printer::declarator (tree t) 1705{ 1706 direct_declarator (t); 1707 1708 // Print a requires clause. 1709 if (flag_concepts) 1710 if (tree ci = get_constraints (t)) 1711 if (tree reqs = CI_DECLARATOR_REQS (ci)) 1712 pp_cxx_requires_clause (this, reqs); 1713} 1714 1715/* ctor-initializer: 1716 : mem-initializer-list 1717 1718 mem-initializer-list: 1719 mem-initializer 1720 mem-initializer , mem-initializer-list 1721 1722 mem-initializer: 1723 mem-initializer-id ( expression-list(opt) ) 1724 1725 mem-initializer-id: 1726 ::(opt) nested-name-specifier(opt) class-name 1727 identifier */ 1728 1729static void 1730pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t) 1731{ 1732 t = TREE_OPERAND (t, 0); 1733 pp_cxx_whitespace (pp); 1734 pp_colon (pp); 1735 pp_cxx_whitespace (pp); 1736 for (; t; t = TREE_CHAIN (t)) 1737 { 1738 tree purpose = TREE_PURPOSE (t); 1739 bool is_pack = PACK_EXPANSION_P (purpose); 1740 1741 if (is_pack) 1742 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose)); 1743 else 1744 pp->primary_expression (purpose); 1745 pp_cxx_call_argument_list (pp, TREE_VALUE (t)); 1746 if (is_pack) 1747 pp_cxx_ws_string (pp, "..."); 1748 if (TREE_CHAIN (t)) 1749 pp_cxx_separate_with (pp, ','); 1750 } 1751} 1752 1753/* function-definition: 1754 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body 1755 decl-specifier-seq(opt) declarator function-try-block */ 1756 1757static void 1758pp_cxx_function_definition (cxx_pretty_printer *pp, tree t) 1759{ 1760 tree saved_scope = pp->enclosing_scope; 1761 pp->declaration_specifiers (t); 1762 pp->declarator (t); 1763 pp_needs_newline (pp) = true; 1764 pp->enclosing_scope = DECL_CONTEXT (t); 1765 if (DECL_SAVED_TREE (t)) 1766 pp->statement (DECL_SAVED_TREE (t)); 1767 else 1768 pp_cxx_semicolon (pp); 1769 pp_newline_and_flush (pp); 1770 pp->enclosing_scope = saved_scope; 1771} 1772 1773/* abstract-declarator: 1774 ptr-operator abstract-declarator(opt) 1775 direct-abstract-declarator */ 1776 1777void 1778cxx_pretty_printer::abstract_declarator (tree t) 1779{ 1780 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function, 1781 or a pointer-to-data-member of array type: 1782 1783 void (X::*)() 1784 int (X::*)[5] 1785 1786 but not for a pointer-to-data-member of non-array type: 1787 1788 int X::* 1789 1790 so be mindful of that. */ 1791 if (TYPE_PTRMEMFUNC_P (t) 1792 || (TYPE_PTRDATAMEM_P (t) 1793 && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)) 1794 pp_cxx_right_paren (this); 1795 else if (INDIRECT_TYPE_P (t)) 1796 { 1797 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE 1798 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) 1799 pp_cxx_right_paren (this); 1800 t = TREE_TYPE (t); 1801 } 1802 direct_abstract_declarator (t); 1803} 1804 1805/* direct-abstract-declarator: 1806 direct-abstract-declarator(opt) ( parameter-declaration-clause ) 1807 cv-qualifier-seq(opt) exception-specification(opt) 1808 direct-abstract-declarator(opt) [ constant-expression(opt) ] 1809 ( abstract-declarator ) */ 1810 1811void 1812cxx_pretty_printer::direct_abstract_declarator (tree t) 1813{ 1814 switch (TREE_CODE (t)) 1815 { 1816 case REFERENCE_TYPE: 1817 abstract_declarator (t); 1818 break; 1819 1820 case RECORD_TYPE: 1821 if (TYPE_PTRMEMFUNC_P (t)) 1822 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t)); 1823 break; 1824 1825 case OFFSET_TYPE: 1826 if (TYPE_PTRDATAMEM_P (t)) 1827 direct_abstract_declarator (TREE_TYPE (t)); 1828 break; 1829 1830 case METHOD_TYPE: 1831 case FUNCTION_TYPE: 1832 pp_cxx_parameter_declaration_clause (this, t); 1833 direct_abstract_declarator (TREE_TYPE (t)); 1834 if (TREE_CODE (t) == METHOD_TYPE) 1835 { 1836 padding = pp_before; 1837 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t)); 1838 } 1839 pp_cxx_exception_specification (this, t); 1840 break; 1841 1842 case TYPENAME_TYPE: 1843 case TEMPLATE_TYPE_PARM: 1844 case TEMPLATE_TEMPLATE_PARM: 1845 case BOUND_TEMPLATE_TEMPLATE_PARM: 1846 case UNBOUND_CLASS_TEMPLATE: 1847 case DECLTYPE_TYPE: 1848 break; 1849 1850 default: 1851 c_pretty_printer::direct_abstract_declarator (t); 1852 break; 1853 } 1854} 1855 1856/* type-id: 1857 type-specifier-seq abstract-declarator(opt) */ 1858 1859void 1860cxx_pretty_printer::type_id (tree t) 1861{ 1862 pp_flags saved_flags = flags; 1863 flags |= pp_c_flag_abstract; 1864 1865 switch (TREE_CODE (t)) 1866 { 1867 case TYPE_DECL: 1868 case UNION_TYPE: 1869 case RECORD_TYPE: 1870 case ENUMERAL_TYPE: 1871 case TYPENAME_TYPE: 1872 case BOUND_TEMPLATE_TEMPLATE_PARM: 1873 case UNBOUND_CLASS_TEMPLATE: 1874 case TEMPLATE_TEMPLATE_PARM: 1875 case TEMPLATE_TYPE_PARM: 1876 case TEMPLATE_PARM_INDEX: 1877 case TEMPLATE_DECL: 1878 case TYPEOF_TYPE: 1879 case UNDERLYING_TYPE: 1880 case DECLTYPE_TYPE: 1881 case NULLPTR_TYPE: 1882 case TEMPLATE_ID_EXPR: 1883 case OFFSET_TYPE: 1884 pp_cxx_type_specifier_seq (this, t); 1885 if (TYPE_PTRMEM_P (t)) 1886 abstract_declarator (t); 1887 break; 1888 1889 case TYPE_PACK_EXPANSION: 1890 type_id (PACK_EXPANSION_PATTERN (t)); 1891 pp_cxx_ws_string (this, "..."); 1892 break; 1893 1894 case TYPE_ARGUMENT_PACK: 1895 { 1896 tree args = ARGUMENT_PACK_ARGS (t); 1897 int len = TREE_VEC_LENGTH (args); 1898 pp_cxx_left_brace (this); 1899 for (int i = 0; i < len; ++i) 1900 { 1901 if (i > 0) 1902 pp_cxx_separate_with (this, ','); 1903 type_id (TREE_VEC_ELT (args, i)); 1904 } 1905 pp_cxx_right_brace (this); 1906 } 1907 break; 1908 1909 default: 1910 c_pretty_printer::type_id (t); 1911 break; 1912 } 1913 1914 flags = saved_flags; 1915} 1916 1917/* template-argument-list: 1918 template-argument ...(opt) 1919 template-argument-list, template-argument ...(opt) 1920 1921 template-argument: 1922 assignment-expression 1923 type-id 1924 template-name */ 1925 1926static void 1927pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t) 1928{ 1929 int i; 1930 bool need_comma = false; 1931 1932 if (t == NULL) 1933 return; 1934 for (i = 0; i < TREE_VEC_LENGTH (t); ++i) 1935 { 1936 tree arg = TREE_VEC_ELT (t, i); 1937 tree argpack = NULL_TREE; 1938 int idx, len = 1; 1939 1940 if (ARGUMENT_PACK_P (arg)) 1941 { 1942 argpack = ARGUMENT_PACK_ARGS (arg); 1943 len = TREE_VEC_LENGTH (argpack); 1944 } 1945 1946 for (idx = 0; idx < len; idx++) 1947 { 1948 if (argpack) 1949 arg = TREE_VEC_ELT (argpack, idx); 1950 1951 if (need_comma) 1952 pp_cxx_separate_with (pp, ','); 1953 else 1954 need_comma = true; 1955 1956 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL 1957 && TYPE_P (DECL_TEMPLATE_RESULT (arg)))) 1958 pp->type_id (arg); 1959 else if (template_parm_object_p (arg)) 1960 pp->expression (DECL_INITIAL (arg)); 1961 else 1962 pp->expression (arg); 1963 } 1964 } 1965} 1966 1967 1968static void 1969pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t) 1970{ 1971 t = DECL_EXPR_DECL (t); 1972 pp_cxx_type_specifier_seq (pp, t); 1973 if (TYPE_P (t)) 1974 pp->abstract_declarator (t); 1975 else 1976 pp->declarator (t); 1977} 1978 1979/* Statements. */ 1980 1981void 1982cxx_pretty_printer::statement (tree t) 1983{ 1984 switch (TREE_CODE (t)) 1985 { 1986 case CTOR_INITIALIZER: 1987 pp_cxx_ctor_initializer (this, t); 1988 break; 1989 1990 case USING_STMT: 1991 pp_cxx_ws_string (this, "using"); 1992 pp_cxx_ws_string (this, "namespace"); 1993 if (DECL_CONTEXT (t)) 1994 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t)); 1995 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t)); 1996 break; 1997 1998 case USING_DECL: 1999 pp_cxx_ws_string (this, "using"); 2000 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t)); 2001 pp_cxx_unqualified_id (this, DECL_NAME (t)); 2002 break; 2003 2004 case EH_SPEC_BLOCK: 2005 break; 2006 2007 /* try-block: 2008 try compound-statement handler-seq */ 2009 case TRY_BLOCK: 2010 pp_maybe_newline_and_indent (this, 0); 2011 pp_cxx_ws_string (this, "try"); 2012 pp_newline_and_indent (this, 3); 2013 statement (TRY_STMTS (t)); 2014 pp_newline_and_indent (this, -3); 2015 if (CLEANUP_P (t)) 2016 ; 2017 else 2018 statement (TRY_HANDLERS (t)); 2019 break; 2020 2021 /* 2022 handler-seq: 2023 handler handler-seq(opt) 2024 2025 handler: 2026 catch ( exception-declaration ) compound-statement 2027 2028 exception-declaration: 2029 type-specifier-seq declarator 2030 type-specifier-seq abstract-declarator 2031 ... */ 2032 case HANDLER: 2033 pp_cxx_ws_string (this, "catch"); 2034 pp_cxx_left_paren (this); 2035 pp_cxx_exception_declaration (this, HANDLER_PARMS (t)); 2036 pp_cxx_right_paren (this); 2037 pp_indentation (this) += 3; 2038 pp_needs_newline (this) = true; 2039 statement (HANDLER_BODY (t)); 2040 pp_indentation (this) -= 3; 2041 pp_needs_newline (this) = true; 2042 break; 2043 2044 /* selection-statement: 2045 if ( expression ) statement 2046 if ( expression ) statement else statement */ 2047 case IF_STMT: 2048 pp_cxx_ws_string (this, "if"); 2049 pp_cxx_whitespace (this); 2050 pp_cxx_left_paren (this); 2051 expression (IF_COND (t)); 2052 pp_cxx_right_paren (this); 2053 pp_newline_and_indent (this, 2); 2054 statement (THEN_CLAUSE (t)); 2055 pp_newline_and_indent (this, -2); 2056 if (ELSE_CLAUSE (t)) 2057 { 2058 tree else_clause = ELSE_CLAUSE (t); 2059 pp_cxx_ws_string (this, "else"); 2060 if (TREE_CODE (else_clause) == IF_STMT) 2061 pp_cxx_whitespace (this); 2062 else 2063 pp_newline_and_indent (this, 2); 2064 statement (else_clause); 2065 if (TREE_CODE (else_clause) != IF_STMT) 2066 pp_newline_and_indent (this, -2); 2067 } 2068 break; 2069 2070 case RANGE_FOR_STMT: 2071 pp_cxx_ws_string (this, "for"); 2072 pp_space (this); 2073 pp_cxx_left_paren (this); 2074 if (RANGE_FOR_INIT_STMT (t)) 2075 { 2076 statement (RANGE_FOR_INIT_STMT (t)); 2077 pp_needs_newline (this) = false; 2078 pp_cxx_whitespace (this); 2079 } 2080 statement (RANGE_FOR_DECL (t)); 2081 pp_space (this); 2082 pp_needs_newline (this) = false; 2083 pp_colon (this); 2084 pp_space (this); 2085 statement (RANGE_FOR_EXPR (t)); 2086 pp_cxx_right_paren (this); 2087 pp_newline_and_indent (this, 3); 2088 statement (FOR_BODY (t)); 2089 pp_indentation (this) -= 3; 2090 pp_needs_newline (this) = true; 2091 break; 2092 2093 /* expression-statement: 2094 expression(opt) ; */ 2095 case EXPR_STMT: 2096 expression (EXPR_STMT_EXPR (t)); 2097 pp_cxx_semicolon (this); 2098 pp_needs_newline (this) = true; 2099 break; 2100 2101 case CLEANUP_STMT: 2102 pp_cxx_ws_string (this, "try"); 2103 pp_newline_and_indent (this, 2); 2104 statement (CLEANUP_BODY (t)); 2105 pp_newline_and_indent (this, -2); 2106 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally"); 2107 pp_newline_and_indent (this, 2); 2108 statement (CLEANUP_EXPR (t)); 2109 pp_newline_and_indent (this, -2); 2110 break; 2111 2112 case STATIC_ASSERT: 2113 declaration (t); 2114 break; 2115 2116 case OMP_DEPOBJ: 2117 pp_cxx_ws_string (this, "#pragma omp depobj"); 2118 pp_space (this); 2119 pp_cxx_left_paren (this); 2120 expression (OMP_DEPOBJ_DEPOBJ (t)); 2121 pp_cxx_right_paren (this); 2122 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node) 2123 { 2124 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE) 2125 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t), 2126 pp_indentation (this), TDF_NONE); 2127 else 2128 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t))) 2129 { 2130 case OMP_CLAUSE_DEPEND_IN: 2131 pp_cxx_ws_string (this, " update(in)"); 2132 break; 2133 case OMP_CLAUSE_DEPEND_INOUT: 2134 pp_cxx_ws_string (this, " update(inout)"); 2135 break; 2136 case OMP_CLAUSE_DEPEND_OUT: 2137 pp_cxx_ws_string (this, " update(out)"); 2138 break; 2139 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: 2140 pp_cxx_ws_string (this, " update(mutexinoutset)"); 2141 break; 2142 case OMP_CLAUSE_DEPEND_LAST: 2143 pp_cxx_ws_string (this, " destroy"); 2144 break; 2145 default: 2146 break; 2147 } 2148 } 2149 pp_needs_newline (this) = true; 2150 break; 2151 2152 default: 2153 c_pretty_printer::statement (t); 2154 break; 2155 } 2156} 2157 2158/* original-namespace-definition: 2159 namespace identifier { namespace-body } 2160 2161 As an edge case, we also handle unnamed namespace definition here. */ 2162 2163static void 2164pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t) 2165{ 2166 pp_cxx_ws_string (pp, "namespace"); 2167 if (DECL_CONTEXT (t)) 2168 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 2169 if (DECL_NAME (t)) 2170 pp_cxx_unqualified_id (pp, t); 2171 pp_cxx_whitespace (pp); 2172 pp_cxx_left_brace (pp); 2173 /* We do not print the namespace-body. */ 2174 pp_cxx_whitespace (pp); 2175 pp_cxx_right_brace (pp); 2176} 2177 2178/* namespace-alias: 2179 identifier 2180 2181 namespace-alias-definition: 2182 namespace identifier = qualified-namespace-specifier ; 2183 2184 qualified-namespace-specifier: 2185 ::(opt) nested-name-specifier(opt) namespace-name */ 2186 2187static void 2188pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t) 2189{ 2190 pp_cxx_ws_string (pp, "namespace"); 2191 if (DECL_CONTEXT (t)) 2192 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t)); 2193 pp_cxx_unqualified_id (pp, t); 2194 pp_cxx_whitespace (pp); 2195 pp_equal (pp); 2196 pp_cxx_whitespace (pp); 2197 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t))) 2198 pp_cxx_nested_name_specifier (pp, 2199 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t))); 2200 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t)); 2201 pp_cxx_semicolon (pp); 2202} 2203 2204/* simple-declaration: 2205 decl-specifier-seq(opt) init-declarator-list(opt) */ 2206 2207static void 2208pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t) 2209{ 2210 pp->declaration_specifiers (t); 2211 pp_cxx_init_declarator (pp, t); 2212 pp_cxx_semicolon (pp); 2213 pp_needs_newline (pp) = true; 2214} 2215 2216/* 2217 template-parameter-list: 2218 template-parameter 2219 template-parameter-list , template-parameter */ 2220 2221static inline void 2222pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t) 2223{ 2224 const int n = TREE_VEC_LENGTH (t); 2225 int i; 2226 for (i = 0; i < n; ++i) 2227 { 2228 if (i) 2229 pp_cxx_separate_with (pp, ','); 2230 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i)); 2231 } 2232} 2233 2234/* template-parameter: 2235 type-parameter 2236 parameter-declaration 2237 2238 type-parameter: 2239 class ...(opt) identifier(opt) 2240 class identifier(opt) = type-id 2241 typename identifier(opt) 2242 typename ...(opt) identifier(opt) = type-id 2243 template < template-parameter-list > class ...(opt) identifier(opt) 2244 template < template-parameter-list > class identifier(opt) = template-name */ 2245 2246static void 2247pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t) 2248{ 2249 tree parameter = TREE_VALUE (t); 2250 switch (TREE_CODE (parameter)) 2251 { 2252 case TYPE_DECL: 2253 pp_cxx_ws_string (pp, "class"); 2254 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) 2255 pp_cxx_ws_string (pp, "..."); 2256 if (DECL_NAME (parameter)) 2257 pp_cxx_tree_identifier (pp, DECL_NAME (parameter)); 2258 /* FIXME: Check if we should print also default argument. */ 2259 break; 2260 2261 case PARM_DECL: 2262 pp_cxx_parameter_declaration (pp, parameter); 2263 break; 2264 2265 case TEMPLATE_DECL: 2266 break; 2267 2268 default: 2269 pp_unsupported_tree (pp, t); 2270 break; 2271 } 2272} 2273 2274/* Pretty-print a template parameter in the canonical form 2275 "template-parameter-<level>-<position in parameter list>". */ 2276 2277void 2278pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm) 2279{ 2280 const enum tree_code code = TREE_CODE (parm); 2281 2282 /* Brings type template parameters to the canonical forms. */ 2283 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM 2284 || code == BOUND_TEMPLATE_TEMPLATE_PARM) 2285 parm = TEMPLATE_TYPE_PARM_INDEX (parm); 2286 2287 pp_cxx_begin_template_argument_list (pp); 2288 pp->translate_string ("template-parameter-"); 2289 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm)); 2290 pp_minus (pp); 2291 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1); 2292 pp_cxx_end_template_argument_list (pp); 2293} 2294 2295/* Print a constrained-type-specifier. */ 2296 2297void 2298pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c) 2299{ 2300 pp_cxx_whitespace (pp); 2301 pp_cxx_left_bracket (pp); 2302 pp->translate_string ("requires"); 2303 pp_cxx_whitespace (pp); 2304 if (c == error_mark_node) 2305 { 2306 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>"); 2307 return; 2308 } 2309 tree t, a; 2310 placeholder_extract_concept_and_args (c, t, a); 2311 pp->id_expression (t); 2312 pp_cxx_begin_template_argument_list (pp); 2313 pp_cxx_ws_string (pp, "<placeholder>"); 2314 pp_cxx_separate_with (pp, ','); 2315 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1); 2316 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i) 2317 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1); 2318 pp_cxx_template_argument_list (pp, args); 2319 ggc_free (args); 2320 pp_cxx_end_template_argument_list (pp); 2321 pp_cxx_right_bracket (pp); 2322} 2323 2324/* 2325 template-declaration: 2326 export(opt) template < template-parameter-list > declaration 2327 2328 Concept extensions: 2329 2330 template-declaration: 2331 export(opt) template < template-parameter-list > 2332 requires-clause(opt) declaration */ 2333 2334static void 2335pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t) 2336{ 2337 tree tmpl = most_general_template (t); 2338 tree level; 2339 2340 pp_maybe_newline_and_indent (pp, 0); 2341 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level)) 2342 { 2343 pp_cxx_ws_string (pp, "template"); 2344 pp_cxx_begin_template_argument_list (pp); 2345 pp_cxx_template_parameter_list (pp, TREE_VALUE (level)); 2346 pp_cxx_end_template_argument_list (pp); 2347 pp_newline_and_indent (pp, 3); 2348 } 2349 2350 if (flag_concepts) 2351 if (tree ci = get_constraints (t)) 2352 if (tree reqs = CI_TEMPLATE_REQS (ci)) 2353 { 2354 pp_cxx_requires_clause (pp, reqs); 2355 pp_newline_and_indent (pp, 6); 2356 } 2357 2358 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t)) 2359 pp_cxx_function_definition (pp, t); 2360 else if (TREE_CODE (t) == CONCEPT_DECL) 2361 pp_cxx_concept_definition (pp, t); 2362 else 2363 pp_cxx_simple_declaration (pp, t); 2364} 2365 2366static void 2367pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t) 2368{ 2369 pp_unsupported_tree (pp, t); 2370} 2371 2372static void 2373pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t) 2374{ 2375 pp_unsupported_tree (pp, t); 2376} 2377 2378static void 2379pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t) 2380{ 2381 pp_cxx_unqualified_id (pp, DECL_NAME (t)); 2382 pp_cxx_whitespace (pp); 2383 pp_cxx_ws_string (pp, "="); 2384 pp_cxx_whitespace (pp); 2385 pp->expression (DECL_INITIAL (t)); 2386 pp_cxx_semicolon (pp); 2387} 2388 2389/* 2390 declaration: 2391 block-declaration 2392 function-definition 2393 template-declaration 2394 explicit-instantiation 2395 explicit-specialization 2396 linkage-specification 2397 namespace-definition 2398 2399 block-declaration: 2400 simple-declaration 2401 asm-definition 2402 namespace-alias-definition 2403 using-declaration 2404 using-directive 2405 static_assert-declaration */ 2406void 2407cxx_pretty_printer::declaration (tree t) 2408{ 2409 if (TREE_CODE (t) == STATIC_ASSERT) 2410 { 2411 pp_cxx_ws_string (this, "static_assert"); 2412 pp_cxx_left_paren (this); 2413 expression (STATIC_ASSERT_CONDITION (t)); 2414 pp_cxx_separate_with (this, ','); 2415 expression (STATIC_ASSERT_MESSAGE (t)); 2416 pp_cxx_right_paren (this); 2417 } 2418 else if (!DECL_LANG_SPECIFIC (t)) 2419 pp_cxx_simple_declaration (this, t); 2420 else if (DECL_USE_TEMPLATE (t)) 2421 switch (DECL_USE_TEMPLATE (t)) 2422 { 2423 case 1: 2424 pp_cxx_template_declaration (this, t); 2425 break; 2426 2427 case 2: 2428 pp_cxx_explicit_specialization (this, t); 2429 break; 2430 2431 case 3: 2432 pp_cxx_explicit_instantiation (this, t); 2433 break; 2434 2435 default: 2436 break; 2437 } 2438 else switch (TREE_CODE (t)) 2439 { 2440 case VAR_DECL: 2441 case TYPE_DECL: 2442 pp_cxx_simple_declaration (this, t); 2443 break; 2444 2445 case FUNCTION_DECL: 2446 if (DECL_SAVED_TREE (t)) 2447 pp_cxx_function_definition (this, t); 2448 else 2449 pp_cxx_simple_declaration (this, t); 2450 break; 2451 2452 case NAMESPACE_DECL: 2453 if (DECL_NAMESPACE_ALIAS (t)) 2454 pp_cxx_namespace_alias_definition (this, t); 2455 else 2456 pp_cxx_original_namespace_definition (this, t); 2457 break; 2458 2459 default: 2460 pp_unsupported_tree (this, t); 2461 break; 2462 } 2463} 2464 2465static void 2466pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t) 2467{ 2468 t = TREE_OPERAND (t, 0); 2469 pp_cxx_ws_string (pp, "typeid"); 2470 pp_cxx_left_paren (pp); 2471 if (TYPE_P (t)) 2472 pp->type_id (t); 2473 else 2474 pp->expression (t); 2475 pp_cxx_right_paren (pp); 2476} 2477 2478void 2479pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t) 2480{ 2481 pp_cxx_ws_string (pp, "va_arg"); 2482 pp_cxx_left_paren (pp); 2483 pp->assignment_expression (TREE_OPERAND (t, 0)); 2484 pp_cxx_separate_with (pp, ','); 2485 pp->type_id (TREE_TYPE (t)); 2486 pp_cxx_right_paren (pp); 2487} 2488 2489static bool 2490pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t) 2491{ 2492 switch (TREE_CODE (t)) 2493 { 2494 case ARROW_EXPR: 2495 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR 2496 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))) 2497 { 2498 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)))); 2499 pp_cxx_separate_with (pp, ','); 2500 return true; 2501 } 2502 return false; 2503 case COMPONENT_REF: 2504 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) 2505 return false; 2506 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR) 2507 pp_cxx_dot (pp); 2508 pp->expression (TREE_OPERAND (t, 1)); 2509 return true; 2510 case ARRAY_REF: 2511 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) 2512 return false; 2513 pp_left_bracket (pp); 2514 pp->expression (TREE_OPERAND (t, 1)); 2515 pp_right_bracket (pp); 2516 return true; 2517 default: 2518 return false; 2519 } 2520} 2521 2522void 2523pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t) 2524{ 2525 pp_cxx_ws_string (pp, "offsetof"); 2526 pp_cxx_left_paren (pp); 2527 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) 2528 pp->expression (TREE_OPERAND (t, 0)); 2529 pp_cxx_right_paren (pp); 2530} 2531 2532void 2533pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t) 2534{ 2535 pp_cxx_ws_string (pp, "__builtin_addressof"); 2536 pp_cxx_left_paren (pp); 2537 pp->expression (TREE_OPERAND (t, 0)); 2538 pp_cxx_right_paren (pp); 2539} 2540 2541static char const* 2542get_fold_operator (tree t) 2543{ 2544 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t), 2545 FOLD_EXPR_OP (t)); 2546 return info->name; 2547} 2548 2549void 2550pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t) 2551{ 2552 char const* op = get_fold_operator (t); 2553 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t)); 2554 pp_cxx_left_paren (pp); 2555 pp_cxx_ws_string (pp, "..."); 2556 pp_cxx_ws_string (pp, op); 2557 pp->expression (expr); 2558 pp_cxx_right_paren (pp); 2559} 2560 2561void 2562pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t) 2563{ 2564 char const* op = get_fold_operator (t); 2565 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t)); 2566 pp_cxx_left_paren (pp); 2567 pp->expression (expr); 2568 pp_space (pp); 2569 pp_cxx_ws_string (pp, op); 2570 pp_cxx_ws_string (pp, "..."); 2571 pp_cxx_right_paren (pp); 2572} 2573 2574void 2575pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t) 2576{ 2577 char const* op = get_fold_operator (t); 2578 tree t1 = TREE_OPERAND (t, 1); 2579 tree t2 = TREE_OPERAND (t, 2); 2580 if (t1 == FOLD_EXPR_PACK (t)) 2581 t1 = PACK_EXPANSION_PATTERN (t1); 2582 else 2583 t2 = PACK_EXPANSION_PATTERN (t2); 2584 pp_cxx_left_paren (pp); 2585 pp->expression (t1); 2586 pp_cxx_ws_string (pp, op); 2587 pp_cxx_ws_string (pp, "..."); 2588 pp_cxx_ws_string (pp, op); 2589 pp->expression (t2); 2590 pp_cxx_right_paren (pp); 2591} 2592 2593void 2594pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t) 2595{ 2596 cp_trait_kind kind = TRAIT_EXPR_KIND (t); 2597 2598 switch (kind) 2599 { 2600 case CPTK_HAS_NOTHROW_ASSIGN: 2601 pp_cxx_ws_string (pp, "__has_nothrow_assign"); 2602 break; 2603 case CPTK_HAS_TRIVIAL_ASSIGN: 2604 pp_cxx_ws_string (pp, "__has_trivial_assign"); 2605 break; 2606 case CPTK_HAS_NOTHROW_CONSTRUCTOR: 2607 pp_cxx_ws_string (pp, "__has_nothrow_constructor"); 2608 break; 2609 case CPTK_HAS_TRIVIAL_CONSTRUCTOR: 2610 pp_cxx_ws_string (pp, "__has_trivial_constructor"); 2611 break; 2612 case CPTK_HAS_NOTHROW_COPY: 2613 pp_cxx_ws_string (pp, "__has_nothrow_copy"); 2614 break; 2615 case CPTK_HAS_TRIVIAL_COPY: 2616 pp_cxx_ws_string (pp, "__has_trivial_copy"); 2617 break; 2618 case CPTK_HAS_TRIVIAL_DESTRUCTOR: 2619 pp_cxx_ws_string (pp, "__has_trivial_destructor"); 2620 break; 2621 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: 2622 pp_cxx_ws_string (pp, "__has_unique_object_representations"); 2623 break; 2624 case CPTK_HAS_VIRTUAL_DESTRUCTOR: 2625 pp_cxx_ws_string (pp, "__has_virtual_destructor"); 2626 break; 2627 case CPTK_IS_ABSTRACT: 2628 pp_cxx_ws_string (pp, "__is_abstract"); 2629 break; 2630 case CPTK_IS_AGGREGATE: 2631 pp_cxx_ws_string (pp, "__is_aggregate"); 2632 break; 2633 case CPTK_IS_BASE_OF: 2634 pp_cxx_ws_string (pp, "__is_base_of"); 2635 break; 2636 case CPTK_IS_CLASS: 2637 pp_cxx_ws_string (pp, "__is_class"); 2638 break; 2639 case CPTK_IS_EMPTY: 2640 pp_cxx_ws_string (pp, "__is_empty"); 2641 break; 2642 case CPTK_IS_ENUM: 2643 pp_cxx_ws_string (pp, "__is_enum"); 2644 break; 2645 case CPTK_IS_FINAL: 2646 pp_cxx_ws_string (pp, "__is_final"); 2647 break; 2648 case CPTK_IS_LAYOUT_COMPATIBLE: 2649 pp_cxx_ws_string (pp, "__is_layout_compatible"); 2650 break; 2651 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF: 2652 pp_cxx_ws_string (pp, "__is_pointer_interconvertible_base_of"); 2653 break; 2654 case CPTK_IS_POD: 2655 pp_cxx_ws_string (pp, "__is_pod"); 2656 break; 2657 case CPTK_IS_POLYMORPHIC: 2658 pp_cxx_ws_string (pp, "__is_polymorphic"); 2659 break; 2660 case CPTK_IS_SAME_AS: 2661 pp_cxx_ws_string (pp, "__is_same"); 2662 break; 2663 case CPTK_IS_STD_LAYOUT: 2664 pp_cxx_ws_string (pp, "__is_std_layout"); 2665 break; 2666 case CPTK_IS_TRIVIAL: 2667 pp_cxx_ws_string (pp, "__is_trivial"); 2668 break; 2669 case CPTK_IS_TRIVIALLY_ASSIGNABLE: 2670 pp_cxx_ws_string (pp, "__is_trivially_assignable"); 2671 break; 2672 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE: 2673 pp_cxx_ws_string (pp, "__is_trivially_constructible"); 2674 break; 2675 case CPTK_IS_TRIVIALLY_COPYABLE: 2676 pp_cxx_ws_string (pp, "__is_trivially_copyable"); 2677 break; 2678 case CPTK_IS_UNION: 2679 pp_cxx_ws_string (pp, "__is_union"); 2680 break; 2681 case CPTK_IS_LITERAL_TYPE: 2682 pp_cxx_ws_string (pp, "__is_literal_type"); 2683 break; 2684 case CPTK_IS_ASSIGNABLE: 2685 pp_cxx_ws_string (pp, "__is_assignable"); 2686 break; 2687 case CPTK_IS_CONSTRUCTIBLE: 2688 pp_cxx_ws_string (pp, "__is_constructible"); 2689 break; 2690 case CPTK_IS_NOTHROW_ASSIGNABLE: 2691 pp_cxx_ws_string (pp, "__is_nothrow_assignable"); 2692 break; 2693 case CPTK_IS_NOTHROW_CONSTRUCTIBLE: 2694 pp_cxx_ws_string (pp, "__is_nothrow_constructible"); 2695 break; 2696 2697 default: 2698 gcc_unreachable (); 2699 } 2700 2701 pp_cxx_left_paren (pp); 2702 pp->type_id (TRAIT_EXPR_TYPE1 (t)); 2703 2704 if (kind == CPTK_IS_BASE_OF 2705 || kind == CPTK_IS_SAME_AS 2706 || kind == CPTK_IS_LAYOUT_COMPATIBLE 2707 || kind == CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF) 2708 { 2709 pp_cxx_separate_with (pp, ','); 2710 pp->type_id (TRAIT_EXPR_TYPE2 (t)); 2711 } 2712 2713 pp_cxx_right_paren (pp); 2714} 2715 2716// requires-clause: 2717// 'requires' logical-or-expression 2718void 2719pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t) 2720{ 2721 if (!t) 2722 return; 2723 pp->padding = pp_before; 2724 pp_cxx_ws_string (pp, "requires"); 2725 pp_space (pp); 2726 pp->expression (t); 2727} 2728 2729/* requirement: 2730 simple-requirement 2731 compound-requirement 2732 type-requirement 2733 nested-requirement */ 2734static void 2735pp_cxx_requirement (cxx_pretty_printer *pp, tree t) 2736{ 2737 switch (TREE_CODE (t)) 2738 { 2739 case SIMPLE_REQ: 2740 pp_cxx_simple_requirement (pp, t); 2741 break; 2742 2743 case TYPE_REQ: 2744 pp_cxx_type_requirement (pp, t); 2745 break; 2746 2747 case COMPOUND_REQ: 2748 pp_cxx_compound_requirement (pp, t); 2749 break; 2750 2751 case NESTED_REQ: 2752 pp_cxx_nested_requirement (pp, t); 2753 break; 2754 2755 default: 2756 gcc_unreachable (); 2757 } 2758} 2759 2760// requirement-list: 2761// requirement 2762// requirement-list ';' requirement[opt] 2763// 2764static void 2765pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t) 2766{ 2767 for (; t; t = TREE_CHAIN (t)) 2768 pp_cxx_requirement (pp, TREE_VALUE (t)); 2769} 2770 2771// requirement-body: 2772// '{' requirement-list '}' 2773static void 2774pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t) 2775{ 2776 pp_cxx_left_brace (pp); 2777 pp_cxx_requirement_list (pp, t); 2778 pp_cxx_right_brace (pp); 2779} 2780 2781// requires-expression: 2782// 'requires' requirement-parameter-list requirement-body 2783void 2784pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t) 2785{ 2786 pp_string (pp, "requires"); 2787 if (tree parms = REQUIRES_EXPR_PARMS (t)) 2788 { 2789 bool first = true; 2790 pp_cxx_left_paren (pp); 2791 for (; parms; parms = TREE_CHAIN (parms)) 2792 { 2793 if (!first) 2794 pp_cxx_separate_with (pp, ',' ); 2795 first = false; 2796 pp_cxx_parameter_declaration (pp, parms); 2797 } 2798 pp_cxx_right_paren (pp); 2799 pp_cxx_whitespace (pp); 2800 } 2801 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1)); 2802} 2803 2804/* simple-requirement: 2805 expression ';' */ 2806void 2807pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t) 2808{ 2809 pp->expression (TREE_OPERAND (t, 0)); 2810 pp_cxx_semicolon (pp); 2811} 2812 2813/* type-requirement: 2814 typename type-name ';' */ 2815void 2816pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t) 2817{ 2818 pp->type_id (TREE_OPERAND (t, 0)); 2819 pp_cxx_semicolon (pp); 2820} 2821 2822/* compound-requirement: 2823 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */ 2824void 2825pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t) 2826{ 2827 pp_cxx_left_brace (pp); 2828 pp->expression (TREE_OPERAND (t, 0)); 2829 pp_cxx_right_brace (pp); 2830 2831 if (COMPOUND_REQ_NOEXCEPT_P (t)) 2832 pp_cxx_ws_string (pp, "noexcept"); 2833 2834 if (tree type = TREE_OPERAND (t, 1)) 2835 { 2836 pp_cxx_whitespace (pp); 2837 pp_cxx_ws_string (pp, "->"); 2838 pp->type_id (type); 2839 } 2840 pp_cxx_semicolon (pp); 2841} 2842 2843/* nested requirement: 2844 'requires' constraint-expression */ 2845void 2846pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t) 2847{ 2848 pp_cxx_ws_string (pp, "requires"); 2849 pp->expression (TREE_OPERAND (t, 0)); 2850 pp_cxx_semicolon (pp); 2851} 2852 2853void 2854pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t) 2855{ 2856 tree decl = CHECK_CONSTR_CONCEPT (t); 2857 tree tmpl = DECL_TI_TEMPLATE (decl); 2858 tree args = CHECK_CONSTR_ARGS (t); 2859 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args); 2860 2861 if (TREE_CODE (decl) == CONCEPT_DECL) 2862 pp->expression (id); 2863 else if (VAR_P (decl)) 2864 pp->expression (id); 2865 else if (TREE_CODE (decl) == FUNCTION_DECL) 2866 { 2867 tree call = build_vl_exp (CALL_EXPR, 2); 2868 TREE_OPERAND (call, 0) = integer_two_node; 2869 TREE_OPERAND (call, 1) = id; 2870 pp->expression (call); 2871 } 2872 else 2873 gcc_unreachable (); 2874} 2875 2876/* Output the "[with ...]" clause for a parameter mapping of an atomic 2877 constraint. */ 2878 2879void 2880pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map) 2881{ 2882 pp_cxx_whitespace (pp); 2883 pp_cxx_left_bracket (pp); 2884 pp->translate_string ("with"); 2885 pp_cxx_whitespace (pp); 2886 2887 for (tree p = map; p; p = TREE_CHAIN (p)) 2888 { 2889 tree parm = TREE_VALUE (p); 2890 tree arg = TREE_PURPOSE (p); 2891 2892 if (TYPE_P (parm)) 2893 pp->type_id (parm); 2894 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm))) 2895 pp_cxx_tree_identifier (pp, name); 2896 else 2897 pp->translate_string ("<unnamed>"); 2898 2899 pp_cxx_whitespace (pp); 2900 pp_equal (pp); 2901 pp_cxx_whitespace (pp); 2902 2903 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg)) 2904 pp->type_id (arg); 2905 else 2906 pp->expression (arg); 2907 2908 if (TREE_CHAIN (p) != NULL_TREE) 2909 pp_cxx_separate_with (pp, ';'); 2910 } 2911 2912 pp_cxx_right_bracket (pp); 2913} 2914 2915void 2916pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t) 2917{ 2918 /* Emit the expression. */ 2919 pp->expression (ATOMIC_CONSTR_EXPR (t)); 2920 2921 /* Emit the parameter mapping. */ 2922 tree map = ATOMIC_CONSTR_MAP (t); 2923 if (map && map != error_mark_node) 2924 pp_cxx_parameter_mapping (pp, map); 2925} 2926 2927void 2928pp_cxx_conjunction (cxx_pretty_printer *pp, tree t) 2929{ 2930 pp_cxx_constraint (pp, TREE_OPERAND (t, 0)); 2931 pp_string (pp, " /\\ "); 2932 pp_cxx_constraint (pp, TREE_OPERAND (t, 1)); 2933} 2934 2935void 2936pp_cxx_disjunction (cxx_pretty_printer *pp, tree t) 2937{ 2938 pp_cxx_constraint (pp, TREE_OPERAND (t, 0)); 2939 pp_string (pp, " \\/ "); 2940 pp_cxx_constraint (pp, TREE_OPERAND (t, 1)); 2941} 2942 2943void 2944pp_cxx_constraint (cxx_pretty_printer *pp, tree t) 2945{ 2946 if (t == error_mark_node) 2947 return pp->expression (t); 2948 2949 switch (TREE_CODE (t)) 2950 { 2951 case ATOMIC_CONSTR: 2952 pp_cxx_atomic_constraint (pp, t); 2953 break; 2954 2955 case CHECK_CONSTR: 2956 pp_cxx_check_constraint (pp, t); 2957 break; 2958 2959 case CONJ_CONSTR: 2960 pp_cxx_conjunction (pp, t); 2961 break; 2962 2963 case DISJ_CONSTR: 2964 pp_cxx_disjunction (pp, t); 2965 break; 2966 2967 case EXPR_PACK_EXPANSION: 2968 pp->expression (TREE_OPERAND (t, 0)); 2969 break; 2970 2971 default: 2972 gcc_unreachable (); 2973 } 2974} 2975 2976 2977typedef c_pretty_print_fn pp_fun; 2978 2979/* Initialization of a C++ pretty-printer object. */ 2980 2981cxx_pretty_printer::cxx_pretty_printer () 2982 : c_pretty_printer (), 2983 enclosing_scope (global_namespace) 2984{ 2985 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq; 2986 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause; 2987} 2988 2989/* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */ 2990 2991pretty_printer * 2992cxx_pretty_printer::clone () const 2993{ 2994 return new cxx_pretty_printer (*this); 2995} 2996