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