1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees. 2 Copyright (C) 2006-2022 Free Software Foundation, Inc. 3 4 GCC is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 GCC is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with GCC; see the file COPYING3. If not see 16 <http://www.gnu.org/licenses/>. */ 17 18 #include "config.h" 19 #include "system.h" 20 #include "coretypes.h" 21 22 #include "dmd/aggregate.h" 23 #include "dmd/ctfe.h" 24 #include "dmd/declaration.h" 25 #include "dmd/identifier.h" 26 #include "dmd/module.h" 27 #include "dmd/target.h" 28 #include "dmd/template.h" 29 30 #include "tree.h" 31 #include "tree-iterator.h" 32 #include "fold-const.h" 33 #include "diagnostic.h" 34 #include "langhooks.h" 35 #include "target.h" 36 #include "stringpool.h" 37 #include "varasm.h" 38 #include "stor-layout.h" 39 #include "attribs.h" 40 #include "function.h" 41 42 #include "d-tree.h" 43 44 45 /* Return the GCC location for the D frontend location LOC. */ 46 47 location_t 48 make_location_t (const Loc &loc) 49 { 50 location_t gcc_location = input_location; 51 52 if (loc.filename) 53 { 54 linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum); 55 linemap_line_start (line_table, loc.linnum, 0); 56 gcc_location = linemap_position_for_column (line_table, loc.charnum); 57 linemap_add (line_table, LC_LEAVE, 0, NULL, 0); 58 } 59 60 return gcc_location; 61 } 62 63 /* Return the DECL_CONTEXT for symbol DSYM. */ 64 65 tree 66 d_decl_context (Dsymbol *dsym) 67 { 68 Dsymbol *parent = dsym; 69 Declaration *decl = dsym->isDeclaration (); 70 AggregateDeclaration *ad = dsym->isAggregateDeclaration (); 71 72 while ((parent = parent->toParent2 ())) 73 { 74 /* We've reached the top-level module namespace. 75 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module, 76 but only for extern(D) symbols. */ 77 if (parent->isModule ()) 78 { 79 if ((decl != NULL && decl->resolvedLinkage () != LINK::d) 80 || (ad != NULL && ad->classKind != ClassKind::d)) 81 return NULL_TREE; 82 83 return build_import_decl (parent); 84 } 85 86 /* Declarations marked as `static' or `__gshared' are never 87 part of any context except at module level. */ 88 if (decl != NULL && decl->isDataseg ()) 89 continue; 90 91 /* Nested functions. */ 92 FuncDeclaration *fd = parent->isFuncDeclaration (); 93 if (fd != NULL) 94 return get_symbol_decl (fd); 95 96 /* Methods of classes or structs. */ 97 AggregateDeclaration *ad = parent->isAggregateDeclaration (); 98 if (ad != NULL) 99 { 100 tree context = build_ctype (ad->type); 101 /* Want the underlying RECORD_TYPE. */ 102 if (ad->isClassDeclaration ()) 103 context = TREE_TYPE (context); 104 105 return context; 106 } 107 } 108 109 return NULL_TREE; 110 } 111 112 /* Return a copy of record TYPE but safe to modify in any way. */ 113 114 tree 115 copy_aggregate_type (tree type) 116 { 117 tree newtype = build_distinct_type_copy (type); 118 TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type)); 119 120 for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f)) 121 DECL_FIELD_CONTEXT (f) = newtype; 122 123 return newtype; 124 } 125 126 /* Return TRUE if declaration DECL is a reference type. */ 127 128 bool 129 declaration_reference_p (Declaration *decl) 130 { 131 Type *tb = decl->type->toBasetype (); 132 133 /* Declaration is a reference type. */ 134 if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref)) 135 return true; 136 137 return false; 138 } 139 140 /* Returns the real type for declaration DECL. */ 141 142 tree 143 declaration_type (Declaration *decl) 144 { 145 /* Lazy declarations are converted to delegates. */ 146 if (decl->storage_class & STClazy) 147 { 148 TypeFunction *tf = TypeFunction::create (NULL, decl->type, 149 VARARGnone, LINK::d); 150 TypeDelegate *t = TypeDelegate::create (tf); 151 return build_ctype (t->merge2 ()); 152 } 153 154 /* Static array va_list have array->pointer conversions applied. */ 155 if (decl->isParameter () && valist_array_p (decl->type)) 156 { 157 Type *valist = decl->type->nextOf ()->pointerTo (); 158 valist = valist->castMod (decl->type->mod); 159 return build_ctype (valist); 160 } 161 162 tree type = build_ctype (decl->type); 163 164 /* Parameter is passed by reference. */ 165 if (declaration_reference_p (decl)) 166 return build_reference_type (type); 167 168 /* The `this' parameter is always const. */ 169 if (decl->isThisDeclaration ()) 170 return insert_type_modifiers (type, MODconst); 171 172 return type; 173 } 174 175 /* These should match the Declaration versions above 176 Return TRUE if parameter ARG is a reference type. */ 177 178 bool 179 parameter_reference_p (Parameter *arg) 180 { 181 Type *tb = arg->type->toBasetype (); 182 183 /* Parameter is a reference type. */ 184 if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref)) 185 return true; 186 187 return false; 188 } 189 190 /* Returns the real type for parameter ARG. */ 191 192 tree 193 parameter_type (Parameter *arg) 194 { 195 /* Lazy parameters are converted to delegates. */ 196 if (arg->storageClass & STClazy) 197 { 198 TypeFunction *tf = TypeFunction::create (NULL, arg->type, 199 VARARGnone, LINK::d); 200 TypeDelegate *t = TypeDelegate::create (tf); 201 return build_ctype (t->merge2 ()); 202 } 203 204 /* Static array va_list have array->pointer conversions applied. */ 205 if (valist_array_p (arg->type)) 206 { 207 Type *valist = arg->type->nextOf ()->pointerTo (); 208 valist = valist->castMod (arg->type->mod); 209 return build_ctype (valist); 210 } 211 212 tree type = build_ctype (arg->type); 213 214 /* Parameter is passed by reference. */ 215 if (parameter_reference_p (arg)) 216 return build_reference_type (type); 217 218 /* Pass non-POD structs by invisible reference. */ 219 if (TREE_ADDRESSABLE (type)) 220 { 221 type = build_reference_type (type); 222 /* There are no other pointer to this temporary. */ 223 type = build_qualified_type (type, TYPE_QUAL_RESTRICT); 224 } 225 226 /* Front-end has already taken care of type promotions. */ 227 return type; 228 } 229 230 /* Build INTEGER_CST of type TYPE with the value VALUE. */ 231 232 tree 233 build_integer_cst (dinteger_t value, tree type) 234 { 235 /* The type is error_mark_node, we can't do anything. */ 236 if (error_operand_p (type)) 237 return type; 238 239 return build_int_cst_type (type, value); 240 } 241 242 /* Build REAL_CST of type TOTYPE with the value VALUE. */ 243 244 tree 245 build_float_cst (const real_t &value, Type *totype) 246 { 247 real_value new_value; 248 TypeBasic *tb = totype->isTypeBasic (); 249 250 gcc_assert (tb != NULL); 251 252 tree type_node = build_ctype (tb); 253 real_convert (&new_value, TYPE_MODE (type_node), &value.rv ()); 254 255 return build_real (type_node, new_value); 256 } 257 258 /* Returns the .length component from the D dynamic array EXP. */ 259 260 tree 261 d_array_length (tree exp) 262 { 263 if (error_operand_p (exp)) 264 return exp; 265 266 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp))); 267 268 /* Get the back-end type for the array and pick out the array 269 length field (assumed to be the first field). */ 270 tree len_field = TYPE_FIELDS (TREE_TYPE (exp)); 271 return component_ref (exp, len_field); 272 } 273 274 /* Returns the .ptr component from the D dynamic array EXP. */ 275 276 tree 277 d_array_ptr (tree exp) 278 { 279 if (error_operand_p (exp)) 280 return exp; 281 282 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp))); 283 284 /* Get the back-end type for the array and pick out the array 285 data pointer field (assumed to be the second field). */ 286 tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))); 287 return component_ref (exp, ptr_field); 288 } 289 290 /* Returns a constructor for D dynamic array type TYPE of .length LEN 291 and .ptr pointing to DATA. */ 292 293 tree 294 d_array_value (tree type, tree len, tree data) 295 { 296 tree len_field, ptr_field; 297 vec <constructor_elt, va_gc> *ce = NULL; 298 299 gcc_assert (TYPE_DYNAMIC_ARRAY (type)); 300 len_field = TYPE_FIELDS (type); 301 ptr_field = TREE_CHAIN (len_field); 302 303 len = convert (TREE_TYPE (len_field), len); 304 data = convert (TREE_TYPE (ptr_field), data); 305 306 CONSTRUCTOR_APPEND_ELT (ce, len_field, len); 307 CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data); 308 309 return build_constructor (type, ce); 310 } 311 312 /* Returns value representing the array length of expression EXP. 313 TYPE could be a dynamic or static array. */ 314 315 tree 316 get_array_length (tree exp, Type *type) 317 { 318 Type *tb = type->toBasetype (); 319 320 switch (tb->ty) 321 { 322 case TY::Tsarray: 323 return size_int (tb->isTypeSArray ()->dim->toUInteger ()); 324 325 case TY::Tarray: 326 return d_array_length (exp); 327 328 default: 329 error ("cannot determine the length of a %qs", type->toChars ()); 330 return error_mark_node; 331 } 332 } 333 334 /* Create BINFO for a ClassDeclaration's inheritance tree. 335 InterfaceDeclaration's are not included. */ 336 337 tree 338 build_class_binfo (tree super, ClassDeclaration *cd) 339 { 340 tree binfo = make_tree_binfo (1); 341 tree ctype = build_ctype (cd->type); 342 343 /* Want RECORD_TYPE, not POINTER_TYPE. */ 344 BINFO_TYPE (binfo) = TREE_TYPE (ctype); 345 BINFO_INHERITANCE_CHAIN (binfo) = super; 346 BINFO_OFFSET (binfo) = integer_zero_node; 347 348 if (cd->baseClass) 349 BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass)); 350 351 return binfo; 352 } 353 354 /* Create BINFO for an InterfaceDeclaration's inheritance tree. 355 In order to access all inherited methods in the debugger, 356 the entire tree must be described. 357 This function makes assumptions about interface layout. */ 358 359 tree 360 build_interface_binfo (tree super, ClassDeclaration *cd, unsigned &offset) 361 { 362 tree binfo = make_tree_binfo (cd->baseclasses->length); 363 tree ctype = build_ctype (cd->type); 364 365 /* Want RECORD_TYPE, not POINTER_TYPE. */ 366 BINFO_TYPE (binfo) = TREE_TYPE (ctype); 367 BINFO_INHERITANCE_CHAIN (binfo) = super; 368 BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize); 369 BINFO_VIRTUAL_P (binfo) = 1; 370 371 for (size_t i = 0; i < cd->baseclasses->length; i++, offset++) 372 { 373 BaseClass *bc = (*cd->baseclasses)[i]; 374 BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset)); 375 } 376 377 return binfo; 378 } 379 380 /* Returns the .funcptr component from the D delegate EXP. */ 381 382 tree 383 delegate_method (tree exp) 384 { 385 /* Get the back-end type for the delegate and pick out the funcptr field 386 (assumed to be the second field). */ 387 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp))); 388 tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))); 389 return component_ref (exp, method_field); 390 } 391 392 /* Returns the .object component from the delegate EXP. */ 393 394 tree 395 delegate_object (tree exp) 396 { 397 /* Get the back-end type for the delegate and pick out the object field 398 (assumed to be the first field). */ 399 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp))); 400 tree obj_field = TYPE_FIELDS (TREE_TYPE (exp)); 401 return component_ref (exp, obj_field); 402 } 403 404 /* Build a delegate literal of type TYPE whose pointer function is 405 METHOD, and hidden object is OBJECT. */ 406 407 tree 408 build_delegate_cst (tree method, tree object, Type *type) 409 { 410 tree ctor = make_node (CONSTRUCTOR); 411 tree ctype; 412 413 Type *tb = type->toBasetype (); 414 if (tb->ty == TY::Tdelegate) 415 ctype = build_ctype (type); 416 else 417 { 418 /* Convert a function method into an anonymous delegate. */ 419 ctype = make_struct_type ("delegate()", 2, 420 get_identifier ("object"), TREE_TYPE (object), 421 get_identifier ("func"), TREE_TYPE (method)); 422 TYPE_DELEGATE (ctype) = 1; 423 } 424 425 vec <constructor_elt, va_gc> *ce = NULL; 426 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object); 427 CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method); 428 429 CONSTRUCTOR_ELTS (ctor) = ce; 430 TREE_TYPE (ctor) = ctype; 431 432 return ctor; 433 } 434 435 /* Builds a temporary tree to store the CALLEE and OBJECT 436 of a method call expression of type TYPE. */ 437 438 tree 439 build_method_call (tree callee, tree object, Type *type) 440 { 441 tree t = build_delegate_cst (callee, object, type); 442 METHOD_CALL_EXPR (t) = 1; 443 return t; 444 } 445 446 /* Extract callee and object from T and return in to CALLEE and OBJECT. */ 447 448 void 449 extract_from_method_call (tree t, tree &callee, tree &object) 450 { 451 gcc_assert (METHOD_CALL_EXPR (t)); 452 object = CONSTRUCTOR_ELT (t, 0)->value; 453 callee = CONSTRUCTOR_ELT (t, 1)->value; 454 } 455 456 /* Build a typeof(null) constant of type TYPE. Handles certain special case 457 conversions, where the underlying type is an aggregate with a nullable 458 interior pointer. */ 459 460 tree 461 build_typeof_null_value (Type *type) 462 { 463 Type *tb = type->toBasetype (); 464 tree value; 465 466 /* For dynamic arrays, set length and pointer fields to zero. */ 467 if (tb->ty == TY::Tarray) 468 value = d_array_value (build_ctype (type), size_int (0), null_pointer_node); 469 470 /* For associative arrays, set the pointer field to null. */ 471 else if (tb->ty == TY::Taarray) 472 { 473 tree ctype = build_ctype (type); 474 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype)); 475 476 value = build_constructor_single (ctype, TYPE_FIELDS (ctype), 477 null_pointer_node); 478 } 479 480 /* For delegates, set the frame and function pointer fields to null. */ 481 else if (tb->ty == TY::Tdelegate) 482 value = build_delegate_cst (null_pointer_node, null_pointer_node, type); 483 484 /* Simple zero constant for all other types. */ 485 else 486 value = build_zero_cst (build_ctype (type)); 487 488 TREE_CONSTANT (value) = 1; 489 return value; 490 } 491 492 /* Build a dereference into the virtual table for OBJECT to retrieve 493 a function pointer of type FNTYPE at position INDEX. */ 494 495 tree 496 build_vindex_ref (tree object, tree fntype, size_t index) 497 { 498 /* The vtable is the first field. Interface methods are also in the class's 499 vtable, so we don't need to convert from a class to an interface. */ 500 tree result = build_deref (object); 501 result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result))); 502 503 gcc_assert (POINTER_TYPE_P (fntype)); 504 505 return build_memref (fntype, result, size_int (target.ptrsize * index)); 506 } 507 508 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be 509 made into temporaries, otherwise any assignments will be lost. */ 510 511 static bool 512 lvalue_p (tree exp) 513 { 514 const enum tree_code code = TREE_CODE (exp); 515 516 switch (code) 517 { 518 case SAVE_EXPR: 519 return false; 520 521 case ARRAY_REF: 522 case INDIRECT_REF: 523 case VAR_DECL: 524 case PARM_DECL: 525 case RESULT_DECL: 526 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp)); 527 528 case IMAGPART_EXPR: 529 case REALPART_EXPR: 530 case COMPONENT_REF: 531 CASE_CONVERT: 532 return lvalue_p (TREE_OPERAND (exp, 0)); 533 534 case COND_EXPR: 535 return (lvalue_p (TREE_OPERAND (exp, 1) 536 ? TREE_OPERAND (exp, 1) 537 : TREE_OPERAND (exp, 0)) 538 && lvalue_p (TREE_OPERAND (exp, 2))); 539 540 case TARGET_EXPR: 541 return true; 542 543 case COMPOUND_EXPR: 544 return lvalue_p (TREE_OPERAND (exp, 1)); 545 546 default: 547 return false; 548 } 549 } 550 551 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced 552 more than once in an expression. */ 553 554 tree 555 d_save_expr (tree exp) 556 { 557 if (TREE_SIDE_EFFECTS (exp)) 558 { 559 if (lvalue_p (exp)) 560 return stabilize_reference (exp); 561 562 return save_expr (exp); 563 } 564 565 return exp; 566 } 567 568 /* VALUEP is an expression we want to pre-evaluate or perform a computation on. 569 The expression returned by this function is the part whose value we don't 570 care about, storing the value in VALUEP. Callers must ensure that the 571 returned expression is evaluated before VALUEP. */ 572 573 tree 574 stabilize_expr (tree *valuep) 575 { 576 tree expr = *valuep; 577 const enum tree_code code = TREE_CODE (expr); 578 tree lhs; 579 tree rhs; 580 581 switch (code) 582 { 583 case COMPOUND_EXPR: 584 /* Given ((e1, ...), eN): 585 Store the last RHS 'eN' expression in VALUEP. */ 586 lhs = TREE_OPERAND (expr, 0); 587 rhs = TREE_OPERAND (expr, 1); 588 lhs = compound_expr (lhs, stabilize_expr (&rhs)); 589 *valuep = rhs; 590 return lhs; 591 592 default: 593 return NULL_TREE; 594 } 595 } 596 597 /* Return a TARGET_EXPR, initializing the DECL with EXP. */ 598 599 tree 600 build_target_expr (tree decl, tree exp) 601 { 602 tree type = TREE_TYPE (decl); 603 tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE); 604 605 if (EXPR_HAS_LOCATION (exp)) 606 SET_EXPR_LOCATION (result, EXPR_LOCATION (exp)); 607 608 /* If decl must always reside in memory. */ 609 if (TREE_ADDRESSABLE (type)) 610 d_mark_addressable (decl); 611 612 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the 613 TARGET_EXPR. If there really turn out to be no side effects, then the 614 optimizer should be able to remove it. */ 615 TREE_SIDE_EFFECTS (result) = 1; 616 617 return result; 618 } 619 620 /* Like the above function, but initializes a new temporary. */ 621 622 tree 623 force_target_expr (tree exp) 624 { 625 tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, 626 TREE_TYPE (exp)); 627 DECL_CONTEXT (decl) = current_function_decl; 628 DECL_ARTIFICIAL (decl) = 1; 629 DECL_IGNORED_P (decl) = 1; 630 layout_decl (decl, 0); 631 632 return build_target_expr (decl, exp); 633 } 634 635 /* Returns the address of the expression EXP. */ 636 637 tree 638 build_address (tree exp) 639 { 640 if (error_operand_p (exp)) 641 return exp; 642 643 tree ptrtype; 644 tree type = TREE_TYPE (exp); 645 646 if (TREE_CODE (exp) == STRING_CST) 647 { 648 /* Just convert string literals (char[]) to C-style strings (char *), 649 otherwise the latter method (char[]*) causes conversion problems 650 during gimplification. */ 651 ptrtype = build_pointer_type (TREE_TYPE (type)); 652 } 653 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node) 654 && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE) 655 { 656 /* Special case for va_list, allow arrays to decay to a pointer. */ 657 ptrtype = build_pointer_type (TREE_TYPE (type)); 658 } 659 else 660 ptrtype = build_pointer_type (type); 661 662 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */ 663 tree init = stabilize_expr (&exp); 664 665 /* Can't take the address of a manifest constant, instead use its value. */ 666 if (TREE_CODE (exp) == CONST_DECL) 667 exp = DECL_INITIAL (exp); 668 669 /* Some expression lowering may request an address of a compile-time constant, 670 or other non-lvalue expression. Make sure it is assigned to a location we 671 can reference. */ 672 if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST) 673 exp = force_target_expr (exp); 674 else if (TREE_CODE (exp) == CALL_EXPR) 675 { 676 /* When a struct or array is returned in registers, we need to again fill 677 in all alignment holes. */ 678 if (AGGREGATE_TYPE_P (TREE_TYPE (exp)) 679 && !aggregate_value_p (TREE_TYPE (exp), exp)) 680 { 681 tree tmp = build_local_temp (TREE_TYPE (exp)); 682 init = compound_expr (init, build_memset_call (tmp)); 683 init = compound_expr (init, modify_expr (tmp, exp)); 684 exp = tmp; 685 } 686 else 687 exp = force_target_expr (exp); 688 } 689 690 d_mark_addressable (exp); 691 exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype); 692 693 if (TREE_CODE (exp) == ADDR_EXPR) 694 TREE_NO_TRAMPOLINE (exp) = 1; 695 696 return compound_expr (init, exp); 697 } 698 699 /* Mark EXP saying that we need to be able to take the 700 address of it; it should not be allocated in a register. */ 701 702 tree 703 d_mark_addressable (tree exp) 704 { 705 switch (TREE_CODE (exp)) 706 { 707 case ADDR_EXPR: 708 case COMPONENT_REF: 709 case ARRAY_REF: 710 case REALPART_EXPR: 711 case IMAGPART_EXPR: 712 d_mark_addressable (TREE_OPERAND (exp, 0)); 713 break; 714 715 case PARM_DECL: 716 case VAR_DECL: 717 case RESULT_DECL: 718 case CONST_DECL: 719 case FUNCTION_DECL: 720 TREE_ADDRESSABLE (exp) = 1; 721 break; 722 723 case CONSTRUCTOR: 724 TREE_ADDRESSABLE (exp) = 1; 725 break; 726 727 case TARGET_EXPR: 728 TREE_ADDRESSABLE (exp) = 1; 729 d_mark_addressable (TREE_OPERAND (exp, 0)); 730 break; 731 732 default: 733 break; 734 } 735 736 return exp; 737 } 738 739 /* Mark EXP as "used" in the program for the benefit of 740 -Wunused warning purposes. */ 741 742 tree 743 d_mark_used (tree exp) 744 { 745 switch (TREE_CODE (exp)) 746 { 747 case VAR_DECL: 748 case CONST_DECL: 749 case PARM_DECL: 750 case RESULT_DECL: 751 case FUNCTION_DECL: 752 TREE_USED (exp) = 1; 753 break; 754 755 case ARRAY_REF: 756 case COMPONENT_REF: 757 case MODIFY_EXPR: 758 case REALPART_EXPR: 759 case IMAGPART_EXPR: 760 case NOP_EXPR: 761 case CONVERT_EXPR: 762 case ADDR_EXPR: 763 d_mark_used (TREE_OPERAND (exp, 0)); 764 break; 765 766 case COMPOUND_EXPR: 767 d_mark_used (TREE_OPERAND (exp, 0)); 768 d_mark_used (TREE_OPERAND (exp, 1)); 769 break; 770 771 default: 772 break; 773 } 774 return exp; 775 } 776 777 /* Mark EXP as read, not just set, for set but not used -Wunused 778 warning purposes. */ 779 780 tree 781 d_mark_read (tree exp) 782 { 783 switch (TREE_CODE (exp)) 784 { 785 case VAR_DECL: 786 case PARM_DECL: 787 TREE_USED (exp) = 1; 788 DECL_READ_P (exp) = 1; 789 break; 790 791 case ARRAY_REF: 792 case COMPONENT_REF: 793 case MODIFY_EXPR: 794 case REALPART_EXPR: 795 case IMAGPART_EXPR: 796 case NOP_EXPR: 797 case CONVERT_EXPR: 798 case ADDR_EXPR: 799 d_mark_read (TREE_OPERAND (exp, 0)); 800 break; 801 802 case COMPOUND_EXPR: 803 d_mark_read (TREE_OPERAND (exp, 1)); 804 break; 805 806 default: 807 break; 808 } 809 return exp; 810 } 811 812 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */ 813 814 tree 815 build_memcmp_call (tree ptr1, tree ptr2, tree num) 816 { 817 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, 818 ptr1, ptr2, num); 819 } 820 821 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */ 822 823 tree 824 build_memcpy_call (tree dst, tree src, tree num) 825 { 826 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3, 827 dst, src, num); 828 } 829 830 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros. 831 If NUM is NULL, then we expect PTR to be object that requires filling. */ 832 833 tree 834 build_memset_call (tree ptr, tree num) 835 { 836 if (num == NULL_TREE) 837 { 838 gcc_assert (TREE_CODE (ptr) != ADDR_EXPR); 839 num = TYPE_SIZE_UNIT (TREE_TYPE (ptr)); 840 ptr = build_address (ptr); 841 } 842 843 /* Use a zero constant to fill the destination if setting the entire object. 844 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment, 845 which can then be merged with other stores to the object. */ 846 tree valtype = TREE_TYPE (TREE_TYPE (ptr)); 847 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num)) 848 { 849 tree cst = build_zero_cst (valtype); 850 if (TREE_CODE (cst) == CONSTRUCTOR) 851 return build_memcpy_call (ptr, build_address (cst), num); 852 853 return modify_expr (build_deref (ptr), cst); 854 } 855 856 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3, 857 ptr, integer_zero_node, num); 858 } 859 860 /* Return TRUE if the struct SD is suitable for comparison using memcmp. 861 This is because we don't guarantee that padding is zero-initialized for 862 a stack variable, so we can't use memcmp to compare struct values. */ 863 864 bool 865 identity_compare_p (StructDeclaration *sd) 866 { 867 if (sd->isUnionDeclaration ()) 868 return true; 869 870 unsigned offset = 0; 871 872 for (size_t i = 0; i < sd->fields.length; i++) 873 { 874 VarDeclaration *vd = sd->fields[i]; 875 Type *tb = vd->type->toBasetype (); 876 877 /* Check inner data structures. */ 878 if (TypeStruct *ts = tb->isTypeStruct ()) 879 { 880 if (!identity_compare_p (ts->sym)) 881 return false; 882 } 883 884 /* Check for types that may have padding. */ 885 if ((tb->ty == TY::Tcomplex80 886 || tb->ty == TY::Tfloat80 887 || tb->ty == TY::Timaginary80) 888 && target.realpad != 0) 889 return false; 890 891 if (offset <= vd->offset) 892 { 893 /* There's a hole in the struct. */ 894 if (offset != vd->offset) 895 return false; 896 897 offset += vd->type->size (); 898 } 899 } 900 901 /* Any trailing padding may not be zero. */ 902 if (offset < sd->structsize) 903 return false; 904 905 return true; 906 } 907 908 /* Build a floating-point identity comparison between T1 and T2, ignoring any 909 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */ 910 911 tree 912 build_float_identity (tree_code code, tree t1, tree t2) 913 { 914 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT); 915 tree result = build_memcmp_call (build_address (t1), 916 build_address (t2), size); 917 return build_boolop (code, result, integer_zero_node); 918 } 919 920 /* Lower a field-by-field equality expression between T1 and T2 of type SD. 921 CODE is the EQ_EXPR or NE_EXPR comparison. */ 922 923 static tree 924 lower_struct_comparison (tree_code code, StructDeclaration *sd, 925 tree t1, tree t2) 926 { 927 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; 928 tree tmemcmp = NULL_TREE; 929 930 /* We can skip the compare if the structs are empty. */ 931 if (sd->fields.length == 0) 932 { 933 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node); 934 if (TREE_SIDE_EFFECTS (t2)) 935 tmemcmp = compound_expr (t2, tmemcmp); 936 if (TREE_SIDE_EFFECTS (t1)) 937 tmemcmp = compound_expr (t1, tmemcmp); 938 939 return tmemcmp; 940 } 941 942 /* Let back-end take care of union comparisons. */ 943 if (sd->isUnionDeclaration ()) 944 { 945 tmemcmp = build_memcmp_call (build_address (t1), build_address (t2), 946 size_int (sd->structsize)); 947 return build_boolop (code, tmemcmp, integer_zero_node); 948 } 949 950 for (size_t i = 0; i < sd->fields.length; i++) 951 { 952 VarDeclaration *vd = sd->fields[i]; 953 Type *type = vd->type->toBasetype (); 954 tree sfield = get_symbol_decl (vd); 955 956 tree t1ref = component_ref (t1, sfield); 957 tree t2ref = component_ref (t2, sfield); 958 tree tcmp; 959 960 if (TypeStruct *ts = type->isTypeStruct ()) 961 { 962 /* Compare inner data structures. */ 963 tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref); 964 } 965 else if (type->ty != TY::Tvector && type->isintegral ()) 966 { 967 /* Integer comparison, no special handling required. */ 968 tcmp = build_boolop (code, t1ref, t2ref); 969 } 970 else if (type->ty != TY::Tvector && type->isfloating ()) 971 { 972 /* Floating-point comparison, don't compare padding in type. */ 973 if (!type->iscomplex ()) 974 tcmp = build_float_identity (code, t1ref, t2ref); 975 else 976 { 977 tree req = build_float_identity (code, real_part (t1ref), 978 real_part (t2ref)); 979 tree ieq = build_float_identity (code, imaginary_part (t1ref), 980 imaginary_part (t2ref)); 981 982 tcmp = build_boolop (tcode, req, ieq); 983 } 984 } 985 else 986 { 987 tree stype = build_ctype (type); 988 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype)); 989 990 if (mode.exists ()) 991 { 992 /* Compare field bits as their corresponding integer type. 993 *((T*) &t1) == *((T*) &t2) */ 994 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1); 995 996 if (tmode == NULL_TREE) 997 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ())); 998 999 tmode = build_aligned_type (tmode, TYPE_ALIGN (stype)); 1000 t1ref = build_vconvert (tmode, t1ref); 1001 t2ref = build_vconvert (tmode, t2ref); 1002 1003 tcmp = build_boolop (code, t1ref, t2ref); 1004 } 1005 else 1006 { 1007 /* Simple memcmp between types. */ 1008 tcmp = build_memcmp_call (build_address (t1ref), 1009 build_address (t2ref), 1010 TYPE_SIZE_UNIT (stype)); 1011 tcmp = build_boolop (code, tcmp, integer_zero_node); 1012 } 1013 } 1014 1015 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp; 1016 } 1017 1018 return tmemcmp; 1019 } 1020 1021 1022 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD. 1023 If possible, use memcmp, otherwise field-by-field comparison is done. 1024 CODE is the EQ_EXPR or NE_EXPR comparison. */ 1025 1026 tree 1027 build_struct_comparison (tree_code code, StructDeclaration *sd, 1028 tree t1, tree t2) 1029 { 1030 /* We can skip the compare if the structs are empty. */ 1031 if (sd->fields.length == 0) 1032 { 1033 tree exp = build_boolop (code, integer_zero_node, integer_zero_node); 1034 if (TREE_SIDE_EFFECTS (t2)) 1035 exp = compound_expr (t2, exp); 1036 if (TREE_SIDE_EFFECTS (t1)) 1037 exp = compound_expr (t1, exp); 1038 1039 return exp; 1040 } 1041 1042 /* Make temporaries to prevent multiple evaluations. */ 1043 tree t1init = stabilize_expr (&t1); 1044 tree t2init = stabilize_expr (&t2); 1045 tree result; 1046 1047 t1 = d_save_expr (t1); 1048 t2 = d_save_expr (t2); 1049 1050 /* Bitwise comparison of structs not returned in memory may not work 1051 due to data holes loosing its zero padding upon return. 1052 As a heuristic, small structs are not compared using memcmp either. */ 1053 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd)) 1054 result = lower_struct_comparison (code, sd, t1, t2); 1055 else 1056 { 1057 /* Do bit compare of structs. */ 1058 tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2), 1059 size_int (sd->structsize)); 1060 result = build_boolop (code, tmemcmp, integer_zero_node); 1061 } 1062 1063 return compound_expr (compound_expr (t1init, t2init), result); 1064 } 1065 1066 /* Build an equality expression between two ARRAY_TYPES of size LENGTH. 1067 The pointer references are T1 and T2, and the element type is SD. 1068 CODE is the EQ_EXPR or NE_EXPR comparison. */ 1069 1070 tree 1071 build_array_struct_comparison (tree_code code, StructDeclaration *sd, 1072 tree length, tree t1, tree t2) 1073 { 1074 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; 1075 1076 /* Build temporary for the result of the comparison. 1077 Initialize as either 0 or 1 depending on operation. */ 1078 tree result = build_local_temp (d_bool_type); 1079 tree init = build_boolop (code, integer_zero_node, integer_zero_node); 1080 add_stmt (build_assign (INIT_EXPR, result, init)); 1081 1082 /* Cast pointer-to-array to pointer-to-struct. */ 1083 tree ptrtype = build_ctype (sd->type->pointerTo ()); 1084 tree lentype = TREE_TYPE (length); 1085 1086 push_binding_level (level_block); 1087 push_stmt_list (); 1088 1089 /* Build temporary locals for length and pointers. */ 1090 tree t = build_local_temp (size_type_node); 1091 add_stmt (build_assign (INIT_EXPR, t, length)); 1092 length = t; 1093 1094 t = build_local_temp (ptrtype); 1095 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1))); 1096 t1 = t; 1097 1098 t = build_local_temp (ptrtype); 1099 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2))); 1100 t2 = t; 1101 1102 /* Build loop for comparing each element. */ 1103 push_stmt_list (); 1104 1105 /* Exit logic for the loop. 1106 if (length == 0 || result OP 0) break; */ 1107 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node)); 1108 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result, 1109 d_bool_false_node)); 1110 t = build1 (EXIT_EXPR, void_type_node, t); 1111 add_stmt (t); 1112 1113 /* Do comparison, caching the value. 1114 result = result OP (*t1 == *t2); */ 1115 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2)); 1116 t = build_boolop (tcode, result, t); 1117 t = modify_expr (result, t); 1118 add_stmt (t); 1119 1120 /* Move both pointers to next element position. 1121 t1++, t2++; */ 1122 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype))); 1123 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size); 1124 add_stmt (t); 1125 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size); 1126 add_stmt (t); 1127 1128 /* Decrease loop counter. 1129 length -= 1; */ 1130 t = build2 (POSTDECREMENT_EXPR, lentype, length, 1131 d_convert (lentype, integer_one_node)); 1132 add_stmt (t); 1133 1134 /* Pop statements and finish loop. */ 1135 tree body = pop_stmt_list (); 1136 add_stmt (build1 (LOOP_EXPR, void_type_node, body)); 1137 1138 /* Wrap it up into a bind expression. */ 1139 tree stmt_list = pop_stmt_list (); 1140 tree block = pop_binding_level (); 1141 1142 body = build3 (BIND_EXPR, void_type_node, 1143 BLOCK_VARS (block), stmt_list, block); 1144 1145 return compound_expr (body, result); 1146 } 1147 1148 /* Build a constructor for a variable of aggregate type TYPE using the 1149 initializer INIT, an ordered flat list of fields and values provided 1150 by the frontend. The returned constructor should be a value that 1151 matches the layout of TYPE. */ 1152 1153 tree 1154 build_struct_literal (tree type, vec <constructor_elt, va_gc> *init) 1155 { 1156 /* If the initializer was empty, use default zero initialization. */ 1157 if (vec_safe_is_empty (init)) 1158 return build_constructor (type, NULL); 1159 1160 /* Struct literals can be seen for special enums representing `_Complex', 1161 make sure to reinterpret the literal as the correct type. */ 1162 if (COMPLEX_FLOAT_TYPE_P (type)) 1163 { 1164 gcc_assert (vec_safe_length (init) == 2); 1165 return complex_expr (type, (*init)[0].value, (*init)[1].value); 1166 } 1167 1168 vec <constructor_elt, va_gc> *ve = NULL; 1169 HOST_WIDE_INT bitoffset = 0; 1170 bool constant_p = true; 1171 bool finished = false; 1172 1173 /* Walk through each field, matching our initializer list. */ 1174 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 1175 { 1176 bool is_initialized = false; 1177 tree value; 1178 1179 if (DECL_NAME (field) == NULL_TREE 1180 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) 1181 && ANON_AGGR_TYPE_P (TREE_TYPE (field))) 1182 { 1183 /* Search all nesting aggregates, if nothing is found, then 1184 this will return an empty initializer to fill the hole. */ 1185 value = build_struct_literal (TREE_TYPE (field), init); 1186 1187 if (!initializer_zerop (value)) 1188 is_initialized = true; 1189 } 1190 else 1191 { 1192 /* Search for the value to initialize the next field. Once found, 1193 pop it from the init list so we don't look at it again. */ 1194 unsigned HOST_WIDE_INT idx; 1195 tree index; 1196 1197 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value) 1198 { 1199 /* If the index is NULL, then just assign it to the next field. 1200 This comes from layout_typeinfo(), which generates a flat 1201 list of values that we must shape into the record type. */ 1202 if (index == field || index == NULL_TREE) 1203 { 1204 init->ordered_remove (idx); 1205 if (!finished) 1206 is_initialized = true; 1207 break; 1208 } 1209 } 1210 } 1211 1212 if (is_initialized) 1213 { 1214 HOST_WIDE_INT fieldpos = int_bit_position (field); 1215 gcc_assert (value != NULL_TREE); 1216 1217 /* Must not initialize fields that overlap. */ 1218 if (fieldpos < bitoffset) 1219 { 1220 /* Find the nearest user defined type and field. */ 1221 tree vtype = type; 1222 while (ANON_AGGR_TYPE_P (vtype)) 1223 vtype = TYPE_CONTEXT (vtype); 1224 1225 tree vfield = field; 1226 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield)) 1227 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield))) 1228 vfield = TYPE_FIELDS (TREE_TYPE (vfield)); 1229 1230 /* Must not generate errors for compiler generated fields. */ 1231 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield)); 1232 error ("overlapping initializer for field %qT.%qD", 1233 TYPE_NAME (vtype), DECL_NAME (vfield)); 1234 } 1235 1236 if (!TREE_CONSTANT (value)) 1237 constant_p = false; 1238 1239 CONSTRUCTOR_APPEND_ELT (ve, field, value); 1240 1241 /* For unions, only the first field is initialized, any other field 1242 initializers found for this union are drained and ignored. */ 1243 if (TREE_CODE (type) == UNION_TYPE) 1244 finished = true; 1245 } 1246 1247 /* Move bit offset to the next position in the struct. */ 1248 if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field)) 1249 bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field)); 1250 1251 /* If all initializers have been assigned, there's nothing else to do. */ 1252 if (vec_safe_is_empty (init)) 1253 break; 1254 } 1255 1256 /* Ensure that we have consumed all values. */ 1257 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type)); 1258 1259 tree ctor = build_constructor (type, ve); 1260 1261 if (constant_p) 1262 TREE_CONSTANT (ctor) = 1; 1263 1264 return ctor; 1265 } 1266 1267 /* Given the TYPE of an anonymous field inside T, return the 1268 FIELD_DECL for the field. If not found return NULL_TREE. 1269 Because anonymous types can nest, we must also search all 1270 anonymous fields that are directly reachable. */ 1271 1272 static tree 1273 lookup_anon_field (tree t, tree type) 1274 { 1275 t = TYPE_MAIN_VARIANT (t); 1276 1277 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) 1278 { 1279 if (DECL_NAME (field) == NULL_TREE) 1280 { 1281 /* If we find it directly, return the field. */ 1282 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field))) 1283 return field; 1284 1285 /* Otherwise, it could be nested, search harder. */ 1286 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) 1287 && ANON_AGGR_TYPE_P (TREE_TYPE (field))) 1288 { 1289 tree subfield = lookup_anon_field (TREE_TYPE (field), type); 1290 if (subfield) 1291 return subfield; 1292 } 1293 } 1294 } 1295 1296 return NULL_TREE; 1297 } 1298 1299 /* Builds OBJECT.FIELD component reference. */ 1300 1301 tree 1302 component_ref (tree object, tree field) 1303 { 1304 if (error_operand_p (object) || error_operand_p (field)) 1305 return error_mark_node; 1306 1307 gcc_assert (TREE_CODE (field) == FIELD_DECL); 1308 1309 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */ 1310 tree init = stabilize_expr (&object); 1311 1312 /* If the FIELD is from an anonymous aggregate, generate a reference 1313 to the anonymous data member, and recur to find FIELD. */ 1314 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field))) 1315 { 1316 tree anonymous_field = lookup_anon_field (TREE_TYPE (object), 1317 DECL_CONTEXT (field)); 1318 object = component_ref (object, anonymous_field); 1319 } 1320 1321 tree result = fold_build3_loc (input_location, COMPONENT_REF, 1322 TREE_TYPE (field), object, field, NULL_TREE); 1323 1324 return compound_expr (init, result); 1325 } 1326 1327 /* Build an assignment expression of lvalue LHS from value RHS. 1328 CODE is the code for a binary operator that we use to combine 1329 the old value of LHS with RHS to get the new value. */ 1330 1331 tree 1332 build_assign (tree_code code, tree lhs, tree rhs) 1333 { 1334 tree result; 1335 tree init = stabilize_expr (&lhs); 1336 init = compound_expr (init, stabilize_expr (&rhs)); 1337 1338 /* If initializing the LHS using a function that returns via NRVO. */ 1339 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR 1340 && AGGREGATE_TYPE_P (TREE_TYPE (rhs)) 1341 && aggregate_value_p (TREE_TYPE (rhs), rhs)) 1342 { 1343 /* Mark as addressable here, which should ensure the return slot is the 1344 address of the LHS expression, taken care of by back-end. */ 1345 d_mark_addressable (lhs); 1346 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true; 1347 } 1348 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */ 1349 else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs)) 1350 && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR) 1351 { 1352 /* LHS may be referenced by the RHS expression, so force a temporary. */ 1353 rhs = force_target_expr (rhs); 1354 } 1355 1356 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */ 1357 if (TREE_CODE (rhs) == TARGET_EXPR) 1358 { 1359 /* If CODE is not INIT_EXPR, can't initialize LHS directly, 1360 since that would cause the LHS to be constructed twice. */ 1361 if (code != INIT_EXPR) 1362 { 1363 init = compound_expr (init, rhs); 1364 result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs)); 1365 } 1366 else 1367 { 1368 d_mark_addressable (lhs); 1369 TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs, 1370 TARGET_EXPR_INITIAL (rhs)); 1371 result = rhs; 1372 } 1373 } 1374 else 1375 { 1376 /* Simple assignment. */ 1377 result = fold_build2_loc (input_location, code, 1378 TREE_TYPE (lhs), lhs, rhs); 1379 } 1380 1381 return compound_expr (init, result); 1382 } 1383 1384 /* Build an assignment expression of lvalue LHS from value RHS. */ 1385 1386 tree 1387 modify_expr (tree lhs, tree rhs) 1388 { 1389 return build_assign (MODIFY_EXPR, lhs, rhs); 1390 } 1391 1392 /* Return EXP represented as TYPE. */ 1393 1394 tree 1395 build_nop (tree type, tree exp) 1396 { 1397 if (error_operand_p (exp)) 1398 return exp; 1399 1400 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */ 1401 tree init = stabilize_expr (&exp); 1402 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp); 1403 1404 return compound_expr (init, exp); 1405 } 1406 1407 /* Return EXP to be viewed as being another type TYPE. Same as build_nop, 1408 except that EXP is type-punned, rather than a straight-forward cast. */ 1409 1410 tree 1411 build_vconvert (tree type, tree exp) 1412 { 1413 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR 1414 makes sure this works for vector-to-array viewing, or if EXP ends up being 1415 used as the LHS of a MODIFY_EXPR. */ 1416 return indirect_ref (type, build_address (exp)); 1417 } 1418 1419 /* Maybe warn about ARG being an address that can never be null. */ 1420 1421 static void 1422 warn_for_null_address (tree arg) 1423 { 1424 if (TREE_CODE (arg) == ADDR_EXPR 1425 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0))) 1426 warning (OPT_Waddress, 1427 "the address of %qD will never be %<null%>", 1428 TREE_OPERAND (arg, 0)); 1429 } 1430 1431 /* Build a boolean ARG0 op ARG1 expression. */ 1432 1433 tree 1434 build_boolop (tree_code code, tree arg0, tree arg1) 1435 { 1436 /* Aggregate comparisons may get lowered to a call to builtin memcmp, 1437 so need to remove all side effects incase its address is taken. */ 1438 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0))) 1439 arg0 = d_save_expr (arg0); 1440 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1))) 1441 arg1 = d_save_expr (arg1); 1442 1443 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1))) 1444 { 1445 /* Build a vector comparison. 1446 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */ 1447 tree type = TREE_TYPE (arg0); 1448 tree cmptype = truth_type_for (type); 1449 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1); 1450 1451 return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp, 1452 build_minus_one_cst (type), 1453 build_zero_cst (type)); 1454 } 1455 1456 if (code == EQ_EXPR || code == NE_EXPR) 1457 { 1458 /* Check if comparing the address of a variable to null. */ 1459 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1)) 1460 warn_for_null_address (arg0); 1461 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0)) 1462 warn_for_null_address (arg1); 1463 } 1464 1465 return fold_build2_loc (input_location, code, d_bool_type, 1466 arg0, d_convert (TREE_TYPE (arg0), arg1)); 1467 } 1468 1469 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three 1470 arguments to the conditional expression. */ 1471 1472 tree 1473 build_condition (tree type, tree arg0, tree arg1, tree arg2) 1474 { 1475 if (arg1 == void_node) 1476 arg1 = build_empty_stmt (input_location); 1477 1478 if (arg2 == void_node) 1479 arg2 = build_empty_stmt (input_location); 1480 1481 return fold_build3_loc (input_location, COND_EXPR, 1482 type, arg0, arg1, arg2); 1483 } 1484 1485 tree 1486 build_vcondition (tree arg0, tree arg1, tree arg2) 1487 { 1488 return build_condition (void_type_node, arg0, arg1, arg2); 1489 } 1490 1491 /* Build a compound expr to join ARG0 and ARG1 together. */ 1492 1493 tree 1494 compound_expr (tree arg0, tree arg1) 1495 { 1496 if (arg1 == NULL_TREE) 1497 return arg0; 1498 1499 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0)) 1500 return arg1; 1501 1502 /* Remove intermediate expressions that have no side-effects. */ 1503 while (TREE_CODE (arg0) == COMPOUND_EXPR 1504 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1))) 1505 arg0 = TREE_OPERAND (arg0, 0); 1506 1507 if (TREE_CODE (arg1) == TARGET_EXPR) 1508 { 1509 /* If the rhs is a TARGET_EXPR, then build the compound expression 1510 inside the target_expr's initializer. This helps the compiler 1511 to eliminate unnecessary temporaries. */ 1512 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1)); 1513 TARGET_EXPR_INITIAL (arg1) = init; 1514 1515 return arg1; 1516 } 1517 1518 return fold_build2_loc (input_location, COMPOUND_EXPR, 1519 TREE_TYPE (arg1), arg0, arg1); 1520 } 1521 1522 /* Build a return expression. */ 1523 1524 tree 1525 return_expr (tree ret) 1526 { 1527 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary 1528 in TARGET_EXPR_SLOT. */ 1529 if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR) 1530 { 1531 tree exp = TARGET_EXPR_INITIAL (ret); 1532 tree init = stabilize_expr (&exp); 1533 1534 exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp); 1535 TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp); 1536 1537 return ret; 1538 } 1539 1540 return fold_build1_loc (input_location, RETURN_EXPR, 1541 void_type_node, ret); 1542 } 1543 1544 /* Return the product of ARG0 and ARG1 as a size_type_node. */ 1545 1546 tree 1547 size_mult_expr (tree arg0, tree arg1) 1548 { 1549 return fold_build2_loc (input_location, MULT_EXPR, size_type_node, 1550 d_convert (size_type_node, arg0), 1551 d_convert (size_type_node, arg1)); 1552 1553 } 1554 1555 /* Return the real part of CE, which should be a complex expression. */ 1556 1557 tree 1558 real_part (tree ce) 1559 { 1560 return fold_build1_loc (input_location, REALPART_EXPR, 1561 TREE_TYPE (TREE_TYPE (ce)), ce); 1562 } 1563 1564 /* Return the imaginary part of CE, which should be a complex expression. */ 1565 1566 tree 1567 imaginary_part (tree ce) 1568 { 1569 return fold_build1_loc (input_location, IMAGPART_EXPR, 1570 TREE_TYPE (TREE_TYPE (ce)), ce); 1571 } 1572 1573 /* Build a complex expression of type TYPE using RE and IM. */ 1574 1575 tree 1576 complex_expr (tree type, tree re, tree im) 1577 { 1578 return fold_build2_loc (input_location, COMPLEX_EXPR, 1579 type, re, im); 1580 } 1581 1582 /* Build a two-field record TYPE representing the complex expression EXPR. */ 1583 1584 tree 1585 underlying_complex_expr (tree type, tree expr) 1586 { 1587 gcc_assert (list_length (TYPE_FIELDS (type)) == 2); 1588 1589 expr = d_save_expr (expr); 1590 1591 /* Build a constructor from the real and imaginary parts. */ 1592 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr)) && 1593 (!INDIRECT_REF_P (expr) 1594 || !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0))))) 1595 { 1596 vec <constructor_elt, va_gc> *ve = NULL; 1597 CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type), 1598 real_part (expr)); 1599 CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)), 1600 imaginary_part (expr)); 1601 return build_constructor (type, ve); 1602 } 1603 1604 /* Replace type in the reinterpret cast with a cast to the record type. */ 1605 return build_vconvert (type, expr); 1606 } 1607 1608 /* Cast EXP (which should be a pointer) to TYPE* and then indirect. 1609 The back-end requires this cast in many cases. */ 1610 1611 tree 1612 indirect_ref (tree type, tree exp) 1613 { 1614 if (error_operand_p (exp)) 1615 return exp; 1616 1617 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */ 1618 tree init = stabilize_expr (&exp); 1619 1620 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE) 1621 exp = fold_build1 (INDIRECT_REF, type, exp); 1622 else 1623 { 1624 exp = build_nop (build_pointer_type (type), exp); 1625 exp = build_deref (exp); 1626 } 1627 1628 return compound_expr (init, exp); 1629 } 1630 1631 /* Returns indirect reference of EXP, which must be a pointer type. */ 1632 1633 tree 1634 build_deref (tree exp) 1635 { 1636 if (error_operand_p (exp)) 1637 return exp; 1638 1639 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */ 1640 tree init = stabilize_expr (&exp); 1641 1642 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp))); 1643 1644 if (TREE_CODE (exp) == ADDR_EXPR) 1645 exp = TREE_OPERAND (exp, 0); 1646 else 1647 exp = build_fold_indirect_ref (exp); 1648 1649 return compound_expr (init, exp); 1650 } 1651 1652 /* Builds pointer offset expression PTR[INDEX]. */ 1653 1654 tree 1655 build_array_index (tree ptr, tree index) 1656 { 1657 if (error_operand_p (ptr) || error_operand_p (index)) 1658 return error_mark_node; 1659 1660 tree ptr_type = TREE_TYPE (ptr); 1661 tree target_type = TREE_TYPE (ptr_type); 1662 1663 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype), 1664 TYPE_UNSIGNED (sizetype)); 1665 1666 /* Array element size. */ 1667 tree size_exp = size_in_bytes (target_type); 1668 1669 if (integer_zerop (size_exp) || integer_onep (size_exp)) 1670 { 1671 /* Array of void or bytes -- No need to multiply. */ 1672 index = fold_convert (type, index); 1673 } 1674 else 1675 { 1676 index = d_convert (type, index); 1677 index = fold_build2 (MULT_EXPR, TREE_TYPE (index), 1678 index, d_convert (TREE_TYPE (index), size_exp)); 1679 index = fold_convert (type, index); 1680 } 1681 1682 if (integer_zerop (index)) 1683 return ptr; 1684 1685 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index); 1686 } 1687 1688 /* Builds pointer offset expression *(PTR OP OFFSET) 1689 OP could be a plus or minus expression. */ 1690 1691 tree 1692 build_offset_op (tree_code op, tree ptr, tree offset) 1693 { 1694 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR); 1695 1696 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype), 1697 TYPE_UNSIGNED (sizetype)); 1698 offset = fold_convert (type, offset); 1699 1700 if (op == MINUS_EXPR) 1701 offset = fold_build1 (NEGATE_EXPR, type, offset); 1702 1703 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset); 1704 } 1705 1706 /* Builds pointer offset expression *(PTR + OFFSET). */ 1707 1708 tree 1709 build_offset (tree ptr, tree offset) 1710 { 1711 return build_offset_op (PLUS_EXPR, ptr, offset); 1712 } 1713 1714 tree 1715 build_memref (tree type, tree ptr, tree offset) 1716 { 1717 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset)); 1718 } 1719 1720 /* Create a tree node to set multiple elements to a single value. */ 1721 1722 tree 1723 build_array_set (tree ptr, tree length, tree value) 1724 { 1725 tree ptrtype = TREE_TYPE (ptr); 1726 tree lentype = TREE_TYPE (length); 1727 1728 push_binding_level (level_block); 1729 push_stmt_list (); 1730 1731 /* Build temporary locals for length and ptr, and maybe value. */ 1732 tree t = build_local_temp (size_type_node); 1733 add_stmt (build_assign (INIT_EXPR, t, length)); 1734 length = t; 1735 1736 t = build_local_temp (ptrtype); 1737 add_stmt (build_assign (INIT_EXPR, t, ptr)); 1738 ptr = t; 1739 1740 if (TREE_SIDE_EFFECTS (value)) 1741 { 1742 t = build_local_temp (TREE_TYPE (value)); 1743 add_stmt (build_assign (INIT_EXPR, t, value)); 1744 value = t; 1745 } 1746 1747 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */ 1748 push_stmt_list (); 1749 1750 /* Exit logic for the loop. 1751 if (length == 0) break; */ 1752 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node)); 1753 t = build1 (EXIT_EXPR, void_type_node, t); 1754 add_stmt (t); 1755 1756 /* Assign value to the current pointer position. 1757 *ptr = value; */ 1758 t = modify_expr (build_deref (ptr), value); 1759 add_stmt (t); 1760 1761 /* Move pointer to next element position. 1762 ptr++; */ 1763 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)); 1764 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size)); 1765 add_stmt (t); 1766 1767 /* Decrease loop counter. 1768 length -= 1; */ 1769 t = build2 (POSTDECREMENT_EXPR, lentype, length, 1770 d_convert (lentype, integer_one_node)); 1771 add_stmt (t); 1772 1773 /* Pop statements and finish loop. */ 1774 tree loop_body = pop_stmt_list (); 1775 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body)); 1776 1777 /* Wrap it up into a bind expression. */ 1778 tree stmt_list = pop_stmt_list (); 1779 tree block = pop_binding_level (); 1780 1781 return build3 (BIND_EXPR, void_type_node, 1782 BLOCK_VARS (block), stmt_list, block); 1783 } 1784 1785 1786 /* Build an array of type TYPE where all the elements are VAL. */ 1787 1788 tree 1789 build_array_from_val (Type *type, tree val) 1790 { 1791 tree etype = build_ctype (type->nextOf ()); 1792 1793 /* Initializing a multidimensional array. */ 1794 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype) 1795 val = build_array_from_val (type->nextOf (), val); 1796 1797 size_t dims = type->isTypeSArray ()->dim->toInteger (); 1798 vec <constructor_elt, va_gc> *elms = NULL; 1799 vec_safe_reserve (elms, dims); 1800 1801 val = d_convert (etype, val); 1802 1803 for (size_t i = 0; i < dims; i++) 1804 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val); 1805 1806 return build_constructor (build_ctype (type), elms); 1807 } 1808 1809 /* Build a static array of type TYPE from an array of EXPS. 1810 If CONST_P is true, then all elements in EXPS are constants. */ 1811 1812 tree 1813 build_array_from_exprs (Type *type, Expressions *exps, bool const_p) 1814 { 1815 /* Build a CONSTRUCTOR from all expressions. */ 1816 vec <constructor_elt, va_gc> *elms = NULL; 1817 vec_safe_reserve (elms, exps->length); 1818 1819 Type *etype = type->nextOf (); 1820 tree satype = make_array_type (etype, exps->length); 1821 1822 for (size_t i = 0; i < exps->length; i++) 1823 { 1824 Expression *expr = (*exps)[i]; 1825 tree t = build_expr (expr, const_p); 1826 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 1827 convert_expr (t, expr->type, etype)); 1828 } 1829 1830 /* Create a new temporary to store the array. */ 1831 tree var = build_local_temp (satype); 1832 1833 /* Fill any alignment holes with zeroes. */ 1834 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct (); 1835 tree init = NULL; 1836 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ())) 1837 init = build_memset_call (var); 1838 1839 /* Initialize the temporary. */ 1840 tree assign = modify_expr (var, build_constructor (satype, elms)); 1841 return compound_expr (compound_expr (init, assign), var); 1842 } 1843 1844 1845 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */ 1846 1847 tree 1848 void_okay_p (tree t) 1849 { 1850 tree type = TREE_TYPE (t); 1851 1852 if (VOID_TYPE_P (TREE_TYPE (type))) 1853 { 1854 tree totype = build_ctype (Type::tuns8->pointerTo ()); 1855 return fold_convert (totype, t); 1856 } 1857 1858 return t; 1859 } 1860 1861 /* Builds a STRING_CST representing the filename of location LOC. When the 1862 location is not valid, the name of the source module is used instead. */ 1863 1864 static tree 1865 build_filename_from_loc (const Loc &loc) 1866 { 1867 const char *filename = loc.filename 1868 ? loc.filename : d_function_chain->module->srcfile.toChars (); 1869 1870 unsigned length = strlen (filename); 1871 tree str = build_string (length, filename); 1872 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1); 1873 1874 return build_address (str); 1875 } 1876 1877 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when 1878 an assert check fails. When calling the msg variant functions, MSG is the 1879 error message supplied by the user. */ 1880 1881 tree 1882 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg) 1883 { 1884 tree file; 1885 tree line = size_int (loc.linnum); 1886 1887 switch (libcall) 1888 { 1889 case LIBCALL_ASSERT_MSG: 1890 case LIBCALL_UNITTEST_MSG: 1891 /* File location is passed as a D string. */ 1892 if (loc.filename) 1893 { 1894 unsigned len = strlen (loc.filename); 1895 tree str = build_string (len, loc.filename); 1896 TREE_TYPE (str) = make_array_type (Type::tchar, len); 1897 1898 file = d_array_value (build_ctype (Type::tchar->arrayOf ()), 1899 size_int (len), build_address (str)); 1900 } 1901 else 1902 file = null_array_node; 1903 break; 1904 1905 case LIBCALL_ASSERTP: 1906 case LIBCALL_UNITTESTP: 1907 file = build_filename_from_loc (loc); 1908 break; 1909 1910 default: 1911 gcc_unreachable (); 1912 } 1913 1914 1915 if (msg != NULL_TREE) 1916 return build_libcall (libcall, Type::tvoid, 3, msg, file, line); 1917 else 1918 return build_libcall (libcall, Type::tvoid, 2, file, line); 1919 } 1920 1921 /* Builds a CALL_EXPR at location LOC in the source file to execute when an 1922 array bounds check fails. */ 1923 1924 tree 1925 build_array_bounds_call (const Loc &loc) 1926 { 1927 /* Terminate the program with a trap if no D runtime present. */ 1928 if (checkaction_trap_p ()) 1929 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 1930 else 1931 { 1932 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2, 1933 build_filename_from_loc (loc), 1934 size_int (loc.linnum)); 1935 } 1936 } 1937 1938 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH 1939 in the index expression IE. The condition returns the INDEX if true, or 1940 throws a `ArrayIndexError`. */ 1941 1942 tree 1943 build_bounds_index_condition (IndexExp *ie, tree index, tree length) 1944 { 1945 if (ie->indexIsInBounds || !array_bounds_check ()) 1946 return index; 1947 1948 /* Prevent multiple evaluations of the index. */ 1949 index = d_save_expr (index); 1950 1951 /* Generate INDEX >= LENGTH && throw RangeError. 1952 No need to check whether INDEX >= 0 as the front-end should 1953 have already taken care of implicit casts to unsigned. */ 1954 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length); 1955 tree boundserr; 1956 1957 if (checkaction_trap_p ()) 1958 boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 1959 else 1960 { 1961 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4, 1962 build_filename_from_loc (ie->e2->loc), 1963 size_int (ie->e2->loc.linnum), index, length); 1964 } 1965 1966 return build_condition (TREE_TYPE (index), condition, boundserr, index); 1967 } 1968 1969 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap 1970 the slice expression SE of the source array length LENGTH. The condition 1971 returns the new array length if true, or throws an `ArraySliceError`. */ 1972 1973 tree 1974 build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) 1975 { 1976 if (array_bounds_check ()) 1977 { 1978 tree condition = NULL_TREE; 1979 1980 /* Enforces that `upper <= length`. */ 1981 if (!se->upperIsInBounds && length != NULL_TREE) 1982 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length); 1983 else 1984 length = integer_zero_node; 1985 1986 /* Enforces that `lower <= upper`. No need to check `lower <= length` as 1987 we've already ensured that `upper <= length`. */ 1988 if (!se->lowerIsLessThanUpper) 1989 { 1990 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper); 1991 1992 if (condition != NULL_TREE) 1993 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond); 1994 else 1995 condition = lwr_cond; 1996 } 1997 1998 if (condition != NULL_TREE) 1999 { 2000 tree boundserr; 2001 2002 if (checkaction_trap_p ()) 2003 { 2004 boundserr = 2005 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 2006 } 2007 else 2008 { 2009 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, 2010 Type::tvoid, 5, 2011 build_filename_from_loc (se->loc), 2012 size_int (se->loc.linnum), 2013 lower, upper, length); 2014 } 2015 2016 upper = build_condition (TREE_TYPE (upper), condition, 2017 boundserr, upper); 2018 } 2019 } 2020 2021 /* Need to ensure lower always gets evaluated first, as it may be a function 2022 call. Generates (lower, upper) - lower. */ 2023 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper), 2024 compound_expr (lower, upper), lower); 2025 } 2026 2027 /* Returns TRUE if array bounds checking code generation is turned on. */ 2028 2029 bool 2030 array_bounds_check (void) 2031 { 2032 FuncDeclaration *fd; 2033 2034 switch (global.params.useArrayBounds) 2035 { 2036 case CHECKENABLEoff: 2037 return false; 2038 2039 case CHECKENABLEon: 2040 return true; 2041 2042 case CHECKENABLEsafeonly: 2043 /* For D2 safe functions only. */ 2044 fd = d_function_chain->function; 2045 if (fd && fd->type->ty == TY::Tfunction) 2046 { 2047 if (fd->type->isTypeFunction ()->trust == TRUST::safe) 2048 return true; 2049 } 2050 return false; 2051 2052 default: 2053 gcc_unreachable (); 2054 } 2055 } 2056 2057 /* Returns TRUE if we terminate the program with a trap if an array bounds or 2058 contract check fails. */ 2059 2060 bool 2061 checkaction_trap_p (void) 2062 { 2063 switch (global.params.checkAction) 2064 { 2065 case CHECKACTION_D: 2066 case CHECKACTION_context: 2067 return false; 2068 2069 case CHECKACTION_C: 2070 case CHECKACTION_halt: 2071 return true; 2072 2073 default: 2074 gcc_unreachable (); 2075 } 2076 } 2077 2078 /* Returns the TypeFunction class for Type T. 2079 Assumes T is already ->toBasetype(). */ 2080 2081 TypeFunction * 2082 get_function_type (Type *t) 2083 { 2084 TypeFunction *tf = NULL; 2085 if (t->ty == TY::Tpointer) 2086 t = t->nextOf ()->toBasetype (); 2087 if (t->ty == TY::Tfunction) 2088 tf = t->isTypeFunction (); 2089 else if (t->ty == TY::Tdelegate) 2090 tf = t->isTypeDelegate ()->next->isTypeFunction (); 2091 return tf; 2092 } 2093 2094 /* Returns TRUE if CALLEE is a plain nested function outside the scope of 2095 CALLER. In which case, CALLEE is being called through an alias that was 2096 passed to CALLER. */ 2097 2098 bool 2099 call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee) 2100 { 2101 if (!callee->isNested ()) 2102 return false; 2103 2104 if (caller->toParent () == callee->toParent ()) 2105 return false; 2106 2107 Dsymbol *dsym = callee; 2108 2109 while (dsym) 2110 { 2111 if (dsym->isTemplateInstance ()) 2112 return false; 2113 else if (dsym->isFuncDeclaration () == caller) 2114 return false; 2115 dsym = dsym->toParent (); 2116 } 2117 2118 return true; 2119 } 2120 2121 /* Entry point for call routines. Builds a function call to FD. 2122 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */ 2123 2124 tree 2125 d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments) 2126 { 2127 return d_build_call (get_function_type (fd->type), 2128 build_address (get_symbol_decl (fd)), object, arguments); 2129 } 2130 2131 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer, 2132 ARGUMENTS are evaluated in left to right order, saved and promoted 2133 before passing. */ 2134 2135 tree 2136 d_build_call (TypeFunction *tf, tree callable, tree object, 2137 Expressions *arguments) 2138 { 2139 tree ctype = TREE_TYPE (callable); 2140 tree callee = callable; 2141 2142 if (POINTER_TYPE_P (ctype)) 2143 ctype = TREE_TYPE (ctype); 2144 else 2145 callee = build_address (callable); 2146 2147 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype)); 2148 gcc_assert (tf != NULL); 2149 gcc_assert (tf->ty == TY::Tfunction); 2150 2151 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE) 2152 { 2153 /* Front-end apparently doesn't check this. */ 2154 if (TREE_CODE (callable) == FUNCTION_DECL) 2155 { 2156 error ("need %<this%> to access member %qE", DECL_NAME (callable)); 2157 return error_mark_node; 2158 } 2159 2160 /* Probably an internal error. */ 2161 gcc_unreachable (); 2162 } 2163 2164 /* Build the argument list for the call. */ 2165 vec <tree, va_gc> *args = NULL; 2166 tree saved_args = NULL_TREE; 2167 bool noreturn_call = false; 2168 2169 /* If this is a delegate call or a nested function being called as 2170 a delegate, the object should not be NULL. */ 2171 if (object != NULL_TREE) 2172 vec_safe_push (args, object); 2173 2174 if (arguments) 2175 { 2176 /* First pass, evaluated expanded tuples in function arguments. */ 2177 for (size_t i = 0; i < arguments->length; ++i) 2178 { 2179 Lagain: 2180 Expression *arg = (*arguments)[i]; 2181 gcc_assert (arg->op != EXP::tuple); 2182 2183 if (arg->op == EXP::comma) 2184 { 2185 CommaExp *ce = arg->isCommaExp (); 2186 tree tce = build_expr (ce->e1); 2187 saved_args = compound_expr (saved_args, tce); 2188 (*arguments)[i] = ce->e2; 2189 goto Lagain; 2190 } 2191 } 2192 2193 const size_t nparams = tf->parameterList.length (); 2194 /* if _arguments[] is the first argument. */ 2195 const size_t varargs = tf->isDstyleVariadic (); 2196 2197 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */ 2198 for (size_t i = 0; i < arguments->length; ++i) 2199 { 2200 Expression *arg = (*arguments)[i]; 2201 tree targ; 2202 2203 if (i - varargs < nparams && i >= varargs) 2204 { 2205 /* Actual arguments for declared formal arguments. */ 2206 Parameter *parg = tf->parameterList[i - varargs]; 2207 targ = convert_for_argument (arg, parg); 2208 } 2209 else 2210 targ = build_expr (arg); 2211 2212 /* Don't pass empty aggregates by value. */ 2213 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ) 2214 && TREE_CODE (targ) != CONSTRUCTOR) 2215 { 2216 tree t = build_constructor (TREE_TYPE (targ), NULL); 2217 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t); 2218 } 2219 2220 /* Parameter is a struct or array passed by invisible reference. */ 2221 if (TREE_ADDRESSABLE (TREE_TYPE (targ))) 2222 { 2223 Type *t = arg->type->toBasetype (); 2224 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym; 2225 2226 /* Need to take care of copying its value before passing the 2227 argument in the following scenarios: 2228 - The argument is a literal expression; a CONSTRUCTOR can't 2229 have its address taken. 2230 - The type has neither a copy constructor nor a destructor 2231 available; nested structs also have ADDRESSABLE set. 2232 - The ABI of the function expects the callee to destroy its 2233 arguments; when the caller is handles destruction, then `targ' 2234 has already been made into a temporary. */ 2235 if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor) 2236 || target.isCalleeDestroyingArgs (tf)) 2237 targ = force_target_expr (targ); 2238 2239 targ = convert (build_reference_type (TREE_TYPE (targ)), 2240 build_address (targ)); 2241 } 2242 2243 /* Complex types are exposed as special types with an underlying 2244 struct representation, if we are passing the native type to a 2245 function that accepts the library-defined version, then ensure 2246 it is properly reinterpreted as the underlying struct type. */ 2247 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ)) 2248 && arg->type->isTypeStruct ()) 2249 targ = underlying_complex_expr (build_ctype (arg->type), targ); 2250 2251 /* Type `noreturn` is a terminator, as no other arguments can possibly 2252 be evaluated after it. */ 2253 if (TREE_TYPE (targ) == noreturn_type_node) 2254 noreturn_call = true; 2255 2256 vec_safe_push (args, targ); 2257 } 2258 } 2259 2260 /* Evaluate the callee before calling it. */ 2261 if (TREE_SIDE_EFFECTS (callee)) 2262 { 2263 callee = d_save_expr (callee); 2264 saved_args = compound_expr (callee, saved_args); 2265 } 2266 2267 /* If we saw a `noreturn` parameter, any unreachable argument evaluations 2268 after it are discarded, as well as the function call itself. */ 2269 if (noreturn_call) 2270 { 2271 if (TREE_SIDE_EFFECTS (callee)) 2272 saved_args = compound_expr (callee, saved_args); 2273 2274 tree arg; 2275 unsigned int ix; 2276 2277 FOR_EACH_VEC_SAFE_ELT (args, ix, arg) 2278 saved_args = compound_expr (saved_args, arg); 2279 2280 /* Add a stub result type for the expression. */ 2281 tree result = build_zero_cst (TREE_TYPE (ctype)); 2282 return compound_expr (saved_args, result); 2283 } 2284 2285 tree result = build_call_vec (TREE_TYPE (ctype), callee, args); 2286 SET_EXPR_LOCATION (result, input_location); 2287 2288 result = maybe_expand_intrinsic (result); 2289 2290 /* Return the value in a temporary slot so that it can be evaluated 2291 multiple times by the caller. */ 2292 if (TREE_CODE (result) == CALL_EXPR 2293 && AGGREGATE_TYPE_P (TREE_TYPE (result)) 2294 && TREE_ADDRESSABLE (TREE_TYPE (result))) 2295 { 2296 CALL_EXPR_RETURN_SLOT_OPT (result) = true; 2297 result = force_target_expr (result); 2298 } 2299 2300 return compound_expr (saved_args, result); 2301 } 2302 2303 /* Build and return the correct call to fmod depending on TYPE. 2304 ARG0 and ARG1 are the arguments pass to the function. */ 2305 2306 tree 2307 build_float_modulus (tree type, tree arg0, tree arg1) 2308 { 2309 tree fmodfn = NULL_TREE; 2310 tree basetype = type; 2311 2312 if (COMPLEX_FLOAT_TYPE_P (basetype)) 2313 basetype = TREE_TYPE (basetype); 2314 2315 if (TYPE_MAIN_VARIANT (basetype) == double_type_node 2316 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node) 2317 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD); 2318 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node 2319 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node) 2320 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF); 2321 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node 2322 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node) 2323 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL); 2324 2325 if (!fmodfn) 2326 { 2327 error ("tried to perform floating-point modulo division on %qT", type); 2328 return error_mark_node; 2329 } 2330 2331 if (COMPLEX_FLOAT_TYPE_P (type)) 2332 { 2333 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1); 2334 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1); 2335 2336 return complex_expr (type, re, im); 2337 } 2338 2339 if (SCALAR_FLOAT_TYPE_P (type)) 2340 return build_call_expr (fmodfn, 2, arg0, arg1); 2341 2342 /* Should have caught this above. */ 2343 gcc_unreachable (); 2344 } 2345 2346 /* Build a function type whose first argument is a pointer to BASETYPE, 2347 which is to be used for the `vthis' context parameter for TYPE. 2348 The base type may be a record for member functions, or a void for 2349 nested functions and delegates. */ 2350 2351 tree 2352 build_vthis_function (tree basetype, tree type) 2353 { 2354 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE); 2355 2356 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), 2357 TYPE_ARG_TYPES (type)); 2358 tree fntype = build_function_type (TREE_TYPE (type), argtypes); 2359 2360 /* Copy volatile qualifiers from the original function type. */ 2361 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE) 2362 fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE); 2363 2364 if (RECORD_OR_UNION_TYPE_P (basetype)) 2365 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype); 2366 else 2367 gcc_assert (VOID_TYPE_P (basetype)); 2368 2369 return fntype; 2370 } 2371 2372 /* Raise an error at that the context pointer of the function or object SYM is 2373 not accessible from the current scope. */ 2374 2375 tree 2376 error_no_frame_access (Dsymbol *sym) 2377 { 2378 error_at (input_location, "cannot get frame pointer to %qs", 2379 sym->toPrettyChars ()); 2380 return null_pointer_node; 2381 } 2382 2383 /* If SYM is a nested function, return the static chain to be 2384 used when calling that function from the current function. 2385 2386 If SYM is a nested class or struct, return the static chain 2387 to be used when creating an instance of the class from CFUN. */ 2388 2389 tree 2390 get_frame_for_symbol (Dsymbol *sym) 2391 { 2392 FuncDeclaration *thisfd 2393 = d_function_chain ? d_function_chain->function : NULL; 2394 FuncDeclaration *fd = sym->isFuncDeclaration (); 2395 FuncDeclaration *fdparent = NULL; 2396 FuncDeclaration *fdoverride = NULL; 2397 2398 if (fd != NULL) 2399 { 2400 /* Check that the nested function is properly defined. */ 2401 if (!fd->fbody) 2402 { 2403 /* Should instead error on line that references `fd'. */ 2404 error_at (make_location_t (fd->loc), "nested function missing body"); 2405 return null_pointer_node; 2406 } 2407 2408 fdparent = fd->toParent2 ()->isFuncDeclaration (); 2409 2410 /* Special case for __ensure and __require. */ 2411 if ((fd->ident == Identifier::idPool ("__ensure") 2412 || fd->ident == Identifier::idPool ("__require")) 2413 && fdparent != thisfd) 2414 { 2415 fdoverride = fdparent; 2416 fdparent = thisfd; 2417 } 2418 } 2419 else 2420 { 2421 /* It's a class (or struct). NewExp codegen has already determined its 2422 outer scope is not another class, so it must be a function. */ 2423 while (sym && !sym->isFuncDeclaration ()) 2424 sym = sym->toParent2 (); 2425 2426 fdparent = (FuncDeclaration *) sym; 2427 } 2428 2429 /* Not a nested function, there is no frame pointer to pass. */ 2430 if (fdparent == NULL) 2431 { 2432 /* Only delegate literals report as being nested, even if they are in 2433 global scope. */ 2434 gcc_assert (fd && fd->isFuncLiteralDeclaration ()); 2435 return null_pointer_node; 2436 } 2437 2438 gcc_assert (thisfd != NULL); 2439 2440 if (thisfd != fdparent) 2441 { 2442 /* If no frame pointer for this function. */ 2443 if (!thisfd->vthis) 2444 { 2445 error_at (make_location_t (sym->loc), 2446 "%qs is a nested function and cannot be accessed from %qs", 2447 fdparent->toPrettyChars (), thisfd->toPrettyChars ()); 2448 return null_pointer_node; 2449 } 2450 2451 /* Make sure we can get the frame pointer to the outer function. 2452 Go up each nesting level until we find the enclosing function. */ 2453 Dsymbol *dsym = thisfd; 2454 2455 while (fd != dsym) 2456 { 2457 /* Check if enclosing function is a function. */ 2458 FuncDeclaration *fdp = dsym->isFuncDeclaration (); 2459 Dsymbol *parent = dsym->toParent2 (); 2460 2461 if (fdp != NULL) 2462 { 2463 if (fdparent == parent) 2464 break; 2465 2466 gcc_assert (fdp->isNested () || fdp->vthis); 2467 dsym = parent; 2468 continue; 2469 } 2470 2471 /* Check if enclosed by an aggregate. That means the current 2472 function must be a member function of that aggregate. */ 2473 AggregateDeclaration *adp = dsym->isAggregateDeclaration (); 2474 2475 if (adp != NULL) 2476 { 2477 if ((adp->isClassDeclaration () || adp->isStructDeclaration ()) 2478 && fdparent == parent) 2479 break; 2480 } 2481 2482 /* No frame to outer function found. */ 2483 if (!adp || !adp->isNested () || !adp->vthis) 2484 return error_no_frame_access (sym); 2485 2486 dsym = parent; 2487 } 2488 } 2489 2490 tree ffo = get_frameinfo (fdparent); 2491 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)) 2492 { 2493 tree frame_ref = get_framedecl (thisfd, fdparent); 2494 2495 /* If `thisfd' is a derived member function, then `fdparent' is the 2496 overridden member function in the base class. Even if there's a 2497 closure environment, we should give the original stack data as the 2498 nested function frame. */ 2499 if (fdoverride) 2500 { 2501 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration (); 2502 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration (); 2503 gcc_assert (cdo && cd); 2504 2505 int offset; 2506 if (cdo->isBaseOf (cd, &offset) && offset != 0) 2507 { 2508 /* Generate a new frame to pass to the overriden function that 2509 has the `this' pointer adjusted. */ 2510 gcc_assert (offset != OFFSET_RUNTIME); 2511 2512 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride)); 2513 tree fields = TYPE_FIELDS (type); 2514 /* The `this' field comes immediately after the `__chain'. */ 2515 tree thisfield = chain_index (1, fields); 2516 vec <constructor_elt, va_gc> *ve = NULL; 2517 2518 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo)); 2519 frame_ref = build_deref (frame_ref); 2520 2521 for (tree field = fields; field; field = DECL_CHAIN (field)) 2522 { 2523 tree value = component_ref (frame_ref, framefields); 2524 if (field == thisfield) 2525 value = build_offset (value, size_int (offset)); 2526 2527 CONSTRUCTOR_APPEND_ELT (ve, field, value); 2528 framefields = DECL_CHAIN (framefields); 2529 } 2530 2531 frame_ref = build_address (build_constructor (type, ve)); 2532 } 2533 } 2534 2535 return frame_ref; 2536 } 2537 2538 return null_pointer_node; 2539 } 2540 2541 /* Return the parent function of a nested class or struct AD. */ 2542 2543 static FuncDeclaration * 2544 get_outer_function (AggregateDeclaration *ad) 2545 { 2546 FuncDeclaration *fd = NULL; 2547 while (ad && ad->isNested ()) 2548 { 2549 Dsymbol *dsym = ad->toParent2 (); 2550 if ((fd = dsym->isFuncDeclaration ())) 2551 return fd; 2552 else 2553 ad = dsym->isAggregateDeclaration (); 2554 } 2555 2556 return NULL; 2557 } 2558 2559 /* Starting from the current function FD, try to find a suitable value of 2560 `this' in nested function instances. A suitable `this' value is an 2561 instance of OCD or a class that has OCD as a base. */ 2562 2563 static tree 2564 find_this_tree (ClassDeclaration *ocd) 2565 { 2566 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL; 2567 2568 while (fd) 2569 { 2570 AggregateDeclaration *ad = fd->isThis (); 2571 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL; 2572 2573 if (cd != NULL) 2574 { 2575 if (ocd == cd) 2576 return get_decl_tree (fd->vthis); 2577 else if (ocd->isBaseOf (cd, NULL)) 2578 return convert_expr (get_decl_tree (fd->vthis), 2579 cd->type, ocd->type); 2580 2581 fd = get_outer_function (cd); 2582 continue; 2583 } 2584 2585 if (fd->isNested ()) 2586 { 2587 fd = fd->toParent2 ()->isFuncDeclaration (); 2588 continue; 2589 } 2590 2591 fd = NULL; 2592 } 2593 2594 return NULL_TREE; 2595 } 2596 2597 /* Retrieve the outer class/struct `this' value of DECL from 2598 the current function. */ 2599 2600 tree 2601 build_vthis (AggregateDeclaration *decl) 2602 { 2603 ClassDeclaration *cd = decl->isClassDeclaration (); 2604 StructDeclaration *sd = decl->isStructDeclaration (); 2605 2606 /* If an aggregate nested in a function has no methods and there are no 2607 other nested functions, any static chain created here will never be 2608 translated. Use a null pointer for the link in this case. */ 2609 tree vthis_value = null_pointer_node; 2610 2611 if (cd != NULL || sd != NULL) 2612 { 2613 Dsymbol *outer = decl->toParent2 (); 2614 2615 /* If the parent is a templated struct, the outer context is instead 2616 the enclosing symbol of where the instantiation happened. */ 2617 if (outer->isStructDeclaration ()) 2618 { 2619 gcc_assert (outer->parent && outer->parent->isTemplateInstance ()); 2620 outer = ((TemplateInstance *) outer->parent)->enclosing; 2621 } 2622 2623 /* For outer classes, get a suitable `this' value. 2624 For outer functions, get a suitable frame/closure pointer. */ 2625 ClassDeclaration *cdo = outer->isClassDeclaration (); 2626 FuncDeclaration *fdo = outer->isFuncDeclaration (); 2627 2628 if (cdo) 2629 { 2630 vthis_value = find_this_tree (cdo); 2631 gcc_assert (vthis_value != NULL_TREE); 2632 } 2633 else if (fdo) 2634 { 2635 tree ffo = get_frameinfo (fdo); 2636 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo) 2637 || fdo->hasNestedFrameRefs ()) 2638 vthis_value = get_frame_for_symbol (decl); 2639 else if (cd != NULL) 2640 { 2641 /* Classes nested in methods are allowed to access any outer 2642 class fields, use the function chain in this case. */ 2643 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) 2644 vthis_value = get_decl_tree (fdo->vthis); 2645 } 2646 } 2647 else 2648 gcc_unreachable (); 2649 } 2650 2651 return vthis_value; 2652 } 2653 2654 /* Build the RECORD_TYPE that describes the function frame or closure type for 2655 the function FD. FFI is the tree holding all frame information. */ 2656 2657 static tree 2658 build_frame_type (tree ffi, FuncDeclaration *fd) 2659 { 2660 if (FRAMEINFO_TYPE (ffi)) 2661 return FRAMEINFO_TYPE (ffi); 2662 2663 tree frame_rec_type = make_node (RECORD_TYPE); 2664 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.", 2665 fd->toPrettyChars (), NULL); 2666 TYPE_NAME (frame_rec_type) = get_identifier (name); 2667 free (name); 2668 2669 tree fields = NULL_TREE; 2670 2671 /* Function is a member or nested, so must have field for outer context. */ 2672 if (fd->vthis) 2673 { 2674 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, 2675 get_identifier ("__chain"), ptr_type_node); 2676 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type; 2677 fields = chainon (NULL_TREE, ptr_field); 2678 DECL_NONADDRESSABLE_P (ptr_field) = 1; 2679 } 2680 2681 /* The __ensure and __require are called directly, so never make the outer 2682 functions closure, but nevertheless could still be referencing parameters 2683 of the calling function non-locally. So we add all parameters with nested 2684 refs to the function frame, this should also mean overriding methods will 2685 have the same frame layout when inheriting a contract. */ 2686 if ((global.params.useIn == CHECKENABLEon && fd->frequire) 2687 || (global.params.useOut == CHECKENABLEon && fd->fensure)) 2688 { 2689 if (fd->parameters) 2690 { 2691 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++) 2692 { 2693 VarDeclaration *v = (*fd->parameters)[i]; 2694 /* Remove if already in closureVars so can push to front. */ 2695 size_t j = fd->closureVars.find (v); 2696 2697 if (j < fd->closureVars.length) 2698 fd->closureVars.remove (j); 2699 2700 fd->closureVars.insert (i, v); 2701 } 2702 } 2703 2704 /* Also add hidden `this' to outer context. */ 2705 if (fd->vthis) 2706 { 2707 size_t i = fd->closureVars.find (fd->vthis); 2708 2709 if (i < fd->closureVars.length) 2710 fd->closureVars.remove (i); 2711 2712 fd->closureVars.insert (0, fd->vthis); 2713 } 2714 } 2715 2716 for (size_t i = 0; i < fd->closureVars.length; i++) 2717 { 2718 VarDeclaration *v = fd->closureVars[i]; 2719 tree vsym = get_symbol_decl (v); 2720 tree ident = v->ident 2721 ? get_identifier (v->ident->toChars ()) : NULL_TREE; 2722 2723 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident, 2724 TREE_TYPE (vsym)); 2725 SET_DECL_LANG_FRAME_FIELD (vsym, field); 2726 DECL_FIELD_CONTEXT (field) = frame_rec_type; 2727 fields = chainon (fields, field); 2728 TREE_USED (vsym) = 1; 2729 2730 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym); 2731 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym); 2732 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym); 2733 SET_DECL_ALIGN (field, DECL_ALIGN (vsym)); 2734 2735 /* Update alignment for frame record type. */ 2736 if (TYPE_ALIGN (frame_rec_type) < DECL_ALIGN (field)) 2737 SET_TYPE_ALIGN (frame_rec_type, DECL_ALIGN (field)); 2738 2739 if (DECL_LANG_NRVO (vsym)) 2740 { 2741 /* Store the nrvo variable in the frame by reference. */ 2742 TREE_TYPE (field) = build_reference_type (TREE_TYPE (field)); 2743 2744 /* Can't do nrvo if the variable is put in a closure, since what the 2745 return slot points to may no longer exist. */ 2746 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi)); 2747 } 2748 2749 if (FRAMEINFO_IS_CLOSURE (ffi)) 2750 { 2751 /* Because the value needs to survive the end of the scope. */ 2752 if ((v->edtor && (v->storage_class & STCparameter)) 2753 || v->needsScopeDtor ()) 2754 error_at (make_location_t (v->loc), 2755 "has scoped destruction, cannot build closure"); 2756 } 2757 } 2758 2759 TYPE_FIELDS (frame_rec_type) = fields; 2760 TYPE_READONLY (frame_rec_type) = 1; 2761 TYPE_CXX_ODR_P (frame_rec_type) = 1; 2762 layout_type (frame_rec_type); 2763 d_keep (frame_rec_type); 2764 2765 return frame_rec_type; 2766 } 2767 2768 /* Closures are implemented by taking the local variables that 2769 need to survive the scope of the function, and copying them 2770 into a GC allocated chuck of memory. That chunk, called the 2771 closure here, is inserted into the linked list of stack 2772 frames instead of the usual stack frame. 2773 2774 If a closure is not required, but FD still needs a frame to lower 2775 nested refs, then instead build custom static chain decl on stack. */ 2776 2777 void 2778 build_closure (FuncDeclaration *fd) 2779 { 2780 tree ffi = get_frameinfo (fd); 2781 2782 if (!FRAMEINFO_CREATES_FRAME (ffi)) 2783 return; 2784 2785 tree type = FRAMEINFO_TYPE (ffi); 2786 gcc_assert (COMPLETE_TYPE_P (type)); 2787 2788 tree decl, decl_ref; 2789 2790 if (FRAMEINFO_IS_CLOSURE (ffi)) 2791 { 2792 decl = build_local_temp (build_pointer_type (type)); 2793 DECL_NAME (decl) = get_identifier ("__closptr"); 2794 decl_ref = build_deref (decl); 2795 2796 /* Allocate memory for closure. */ 2797 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type)); 2798 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg); 2799 2800 tree init_exp = build_assign (INIT_EXPR, decl, 2801 build_nop (TREE_TYPE (decl), init)); 2802 add_stmt (init_exp); 2803 } 2804 else 2805 { 2806 decl = build_local_temp (type); 2807 DECL_NAME (decl) = get_identifier ("__frame"); 2808 decl_ref = decl; 2809 } 2810 2811 /* Set the first entry to the parent closure/frame, if any. */ 2812 if (fd->vthis) 2813 { 2814 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type)); 2815 tree chain_expr = modify_expr (chain_field, 2816 d_function_chain->static_chain); 2817 add_stmt (chain_expr); 2818 } 2819 2820 /* Copy parameters that are referenced nonlocally. */ 2821 for (size_t i = 0; i < fd->closureVars.length; i++) 2822 { 2823 VarDeclaration *v = fd->closureVars[i]; 2824 tree vsym = get_symbol_decl (v); 2825 2826 if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym)) 2827 continue; 2828 2829 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym)); 2830 2831 /* Variable is an alias for the NRVO slot, store the reference. */ 2832 if (DECL_LANG_NRVO (vsym)) 2833 vsym = build_address (DECL_LANG_NRVO (vsym)); 2834 2835 tree expr = modify_expr (field, vsym); 2836 add_stmt (expr); 2837 } 2838 2839 if (!FRAMEINFO_IS_CLOSURE (ffi)) 2840 decl = build_address (decl); 2841 2842 d_function_chain->static_chain = decl; 2843 } 2844 2845 /* Return the frame of FD. This could be a static chain or a closure 2846 passed via the hidden `this' pointer. */ 2847 2848 tree 2849 get_frameinfo (FuncDeclaration *fd) 2850 { 2851 tree fds = get_symbol_decl (fd); 2852 if (DECL_LANG_FRAMEINFO (fds)) 2853 return DECL_LANG_FRAMEINFO (fds); 2854 2855 tree ffi = make_node (FUNCFRAME_INFO); 2856 2857 DECL_LANG_FRAMEINFO (fds) = ffi; 2858 2859 if (fd->needsClosure ()) 2860 { 2861 /* Set-up a closure frame, this will be allocated on the heap. */ 2862 FRAMEINFO_CREATES_FRAME (ffi) = 1; 2863 FRAMEINFO_IS_CLOSURE (ffi) = 1; 2864 } 2865 else if (fd->hasNestedFrameRefs ()) 2866 { 2867 /* Functions with nested refs must create a static frame for local 2868 variables to be referenced from. */ 2869 FRAMEINFO_CREATES_FRAME (ffi) = 1; 2870 } 2871 else 2872 { 2873 /* For nested functions, default to creating a frame. Even if there are 2874 no fields to populate the frame, create it anyway, as this will be 2875 used as the record type instead of `void*` for the this parameter. */ 2876 if (fd->vthis && fd->vthis->type == Type::tvoidptr) 2877 FRAMEINFO_CREATES_FRAME (ffi) = 1; 2878 2879 /* In checkNestedReference, references from contracts are not added to the 2880 closureVars array, so assume all parameters referenced. */ 2881 if ((global.params.useIn == CHECKENABLEon && fd->frequire) 2882 || (global.params.useOut == CHECKENABLEon && fd->fensure)) 2883 FRAMEINFO_CREATES_FRAME (ffi) = 1; 2884 2885 /* If however `fd` is nested (deeply) in a function that creates a 2886 closure, then `fd` instead inherits that closure via hidden vthis 2887 pointer, and doesn't create a stack frame at all. */ 2888 FuncDeclaration *ff = fd; 2889 2890 while (ff) 2891 { 2892 tree ffo = get_frameinfo (ff); 2893 2894 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo)) 2895 { 2896 gcc_assert (FRAMEINFO_TYPE (ffo)); 2897 FRAMEINFO_CREATES_FRAME (ffi) = 0; 2898 FRAMEINFO_STATIC_CHAIN (ffi) = 1; 2899 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo); 2900 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo))); 2901 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo); 2902 break; 2903 } 2904 2905 /* Stop looking if no frame pointer for this function. */ 2906 if (ff->vthis == NULL) 2907 break; 2908 2909 AggregateDeclaration *ad = ff->isThis (); 2910 if (ad && ad->isNested ()) 2911 { 2912 while (ad->isNested ()) 2913 { 2914 Dsymbol *d = ad->toParent2 (); 2915 ad = d->isAggregateDeclaration (); 2916 ff = d->isFuncDeclaration (); 2917 2918 if (ad == NULL) 2919 break; 2920 } 2921 } 2922 else 2923 ff = ff->toParent2 ()->isFuncDeclaration (); 2924 } 2925 } 2926 2927 /* Build type now as may be referenced from another module. */ 2928 if (FRAMEINFO_CREATES_FRAME (ffi)) 2929 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd); 2930 2931 return ffi; 2932 } 2933 2934 /* Return a pointer to the frame/closure block of OUTER 2935 so can be accessed from the function INNER. */ 2936 2937 tree 2938 get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer) 2939 { 2940 tree result = d_function_chain->static_chain; 2941 FuncDeclaration *fd = inner; 2942 2943 while (fd && fd != outer) 2944 { 2945 /* Parent frame link is the first field. */ 2946 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd))) 2947 result = indirect_ref (ptr_type_node, result); 2948 2949 if (fd->isNested ()) 2950 fd = fd->toParent2 ()->isFuncDeclaration (); 2951 /* The frame/closure record always points to the outer function's 2952 frame, even if there are intervening nested classes or structs. 2953 So, we can just skip over these. */ 2954 else 2955 fd = get_outer_function (fd->isThis ()); 2956 } 2957 2958 if (fd != outer) 2959 return error_no_frame_access (outer); 2960 2961 /* Go get our frame record. */ 2962 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer)); 2963 2964 if (frame_type != NULL_TREE) 2965 { 2966 result = build_nop (build_pointer_type (frame_type), result); 2967 return result; 2968 } 2969 else 2970 { 2971 error_at (make_location_t (inner->loc), 2972 "forward reference to frame of %qs", outer->toChars ()); 2973 return null_pointer_node; 2974 } 2975 } 2976