1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- E X P _ U T I L -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2019, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNAT; see file COPYING3. If not, go to -- 19-- http://www.gnu.org/licenses for a complete copy of the license. -- 20-- -- 21-- GNAT was originally developed by the GNAT team at New York University. -- 22-- Extensive contributions were provided by Ada Core Technologies Inc. -- 23-- -- 24------------------------------------------------------------------------------ 25 26with Aspects; use Aspects; 27with Atree; use Atree; 28with Casing; use Casing; 29with Checks; use Checks; 30with Debug; use Debug; 31with Einfo; use Einfo; 32with Elists; use Elists; 33with Errout; use Errout; 34with Exp_Aggr; use Exp_Aggr; 35with Exp_Ch6; use Exp_Ch6; 36with Exp_Ch7; use Exp_Ch7; 37with Exp_Ch11; use Exp_Ch11; 38with Ghost; use Ghost; 39with Inline; use Inline; 40with Itypes; use Itypes; 41with Lib; use Lib; 42with Nlists; use Nlists; 43with Nmake; use Nmake; 44with Opt; use Opt; 45with Restrict; use Restrict; 46with Rident; use Rident; 47with Sem; use Sem; 48with Sem_Aux; use Sem_Aux; 49with Sem_Ch3; use Sem_Ch3; 50with Sem_Ch6; use Sem_Ch6; 51with Sem_Ch8; use Sem_Ch8; 52with Sem_Ch12; use Sem_Ch12; 53with Sem_Ch13; use Sem_Ch13; 54with Sem_Disp; use Sem_Disp; 55with Sem_Elab; use Sem_Elab; 56with Sem_Eval; use Sem_Eval; 57with Sem_Res; use Sem_Res; 58with Sem_Type; use Sem_Type; 59with Sem_Util; use Sem_Util; 60with Snames; use Snames; 61with Stand; use Stand; 62with Stringt; use Stringt; 63with Targparm; use Targparm; 64with Tbuild; use Tbuild; 65with Ttypes; use Ttypes; 66with Urealp; use Urealp; 67with Validsw; use Validsw; 68 69with GNAT.HTable; 70package body Exp_Util is 71 72 --------------------------------------------------------- 73 -- Handling of inherited class-wide pre/postconditions -- 74 --------------------------------------------------------- 75 76 -- Following AI12-0113, the expression for a class-wide condition is 77 -- transformed for a subprogram that inherits it, by replacing calls 78 -- to primitive operations of the original controlling type into the 79 -- corresponding overriding operations of the derived type. The following 80 -- hash table manages this mapping, and is expanded on demand whenever 81 -- such inherited expression needs to be constructed. 82 83 -- The mapping is also used to check whether an inherited operation has 84 -- a condition that depends on overridden operations. For such an 85 -- operation we must create a wrapper that is then treated as a normal 86 -- overriding. In SPARK mode such operations are illegal. 87 88 -- For a given root type there may be several type extensions with their 89 -- own overriding operations, so at various times a given operation of 90 -- the root will be mapped into different overridings. The root type is 91 -- also mapped into the current type extension to indicate that its 92 -- operations are mapped into the overriding operations of that current 93 -- type extension. 94 95 -- The contents of the map are as follows: 96 97 -- Key Value 98 99 -- Discriminant (Entity_Id) Discriminant (Entity_Id) 100 -- Discriminant (Entity_Id) Non-discriminant name (Entity_Id) 101 -- Discriminant (Entity_Id) Expression (Node_Id) 102 -- Primitive subprogram (Entity_Id) Primitive subprogram (Entity_Id) 103 -- Type (Entity_Id) Type (Entity_Id) 104 105 Type_Map_Size : constant := 511; 106 107 subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1; 108 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header; 109 110 package Type_Map is new GNAT.HTable.Simple_HTable 111 (Header_Num => Type_Map_Header, 112 Key => Entity_Id, 113 Element => Node_Or_Entity_Id, 114 No_element => Empty, 115 Hash => Type_Map_Hash, 116 Equal => "="); 117 118 ----------------------- 119 -- Local Subprograms -- 120 ----------------------- 121 122 function Build_Task_Array_Image 123 (Loc : Source_Ptr; 124 Id_Ref : Node_Id; 125 A_Type : Entity_Id; 126 Dyn : Boolean := False) return Node_Id; 127 -- Build function to generate the image string for a task that is an array 128 -- component, concatenating the images of each index. To avoid storage 129 -- leaks, the string is built with successive slice assignments. The flag 130 -- Dyn indicates whether this is called for the initialization procedure of 131 -- an array of tasks, or for the name of a dynamically created task that is 132 -- assigned to an indexed component. 133 134 function Build_Task_Image_Function 135 (Loc : Source_Ptr; 136 Decls : List_Id; 137 Stats : List_Id; 138 Res : Entity_Id) return Node_Id; 139 -- Common processing for Task_Array_Image and Task_Record_Image. Build 140 -- function body that computes image. 141 142 procedure Build_Task_Image_Prefix 143 (Loc : Source_Ptr; 144 Len : out Entity_Id; 145 Res : out Entity_Id; 146 Pos : out Entity_Id; 147 Prefix : Entity_Id; 148 Sum : Node_Id; 149 Decls : List_Id; 150 Stats : List_Id); 151 -- Common processing for Task_Array_Image and Task_Record_Image. Create 152 -- local variables and assign prefix of name to result string. 153 154 function Build_Task_Record_Image 155 (Loc : Source_Ptr; 156 Id_Ref : Node_Id; 157 Dyn : Boolean := False) return Node_Id; 158 -- Build function to generate the image string for a task that is a record 159 -- component. Concatenate name of variable with that of selector. The flag 160 -- Dyn indicates whether this is called for the initialization procedure of 161 -- record with task components, or for a dynamically created task that is 162 -- assigned to a selected component. 163 164 procedure Evaluate_Slice_Bounds (Slice : Node_Id); 165 -- Force evaluation of bounds of a slice, which may be given by a range 166 -- or by a subtype indication with or without a constraint. 167 168 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean; 169 -- Determine whether pragma Default_Initial_Condition denoted by Prag has 170 -- an assertion expression that should be verified at run time. 171 172 function Make_CW_Equivalent_Type 173 (T : Entity_Id; 174 E : Node_Id) return Entity_Id; 175 -- T is a class-wide type entity, E is the initial expression node that 176 -- constrains T in case such as: " X: T := E" or "new T'(E)". This function 177 -- returns the entity of the Equivalent type and inserts on the fly the 178 -- necessary declaration such as: 179 -- 180 -- type anon is record 181 -- _parent : Root_Type (T); constrained with E discriminants (if any) 182 -- Extension : String (1 .. expr to match size of E); 183 -- end record; 184 -- 185 -- This record is compatible with any object of the class of T thanks to 186 -- the first field and has the same size as E thanks to the second. 187 188 function Make_Literal_Range 189 (Loc : Source_Ptr; 190 Literal_Typ : Entity_Id) return Node_Id; 191 -- Produce a Range node whose bounds are: 192 -- Low_Bound (Literal_Type) .. 193 -- Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1) 194 -- this is used for expanding declarations like X : String := "sdfgdfg"; 195 -- 196 -- If the index type of the target array is not integer, we generate: 197 -- Low_Bound (Literal_Type) .. 198 -- Literal_Type'Val 199 -- (Literal_Type'Pos (Low_Bound (Literal_Type)) 200 -- + (Length (Literal_Typ) -1)) 201 202 function Make_Non_Empty_Check 203 (Loc : Source_Ptr; 204 N : Node_Id) return Node_Id; 205 -- Produce a boolean expression checking that the unidimensional array 206 -- node N is not empty. 207 208 function New_Class_Wide_Subtype 209 (CW_Typ : Entity_Id; 210 N : Node_Id) return Entity_Id; 211 -- Create an implicit subtype of CW_Typ attached to node N 212 213 function Requires_Cleanup_Actions 214 (L : List_Id; 215 Lib_Level : Boolean; 216 Nested_Constructs : Boolean) return Boolean; 217 -- Given a list L, determine whether it contains one of the following: 218 -- 219 -- 1) controlled objects 220 -- 2) library-level tagged types 221 -- 222 -- Lib_Level is True when the list comes from a construct at the library 223 -- level, and False otherwise. Nested_Constructs is True when any nested 224 -- packages declared in L must be processed, and False otherwise. 225 226 ------------------------------------- 227 -- Activate_Atomic_Synchronization -- 228 ------------------------------------- 229 230 procedure Activate_Atomic_Synchronization (N : Node_Id) is 231 Msg_Node : Node_Id; 232 233 begin 234 case Nkind (Parent (N)) is 235 236 -- Check for cases of appearing in the prefix of a construct where we 237 -- don't need atomic synchronization for this kind of usage. 238 239 when 240 -- Nothing to do if we are the prefix of an attribute, since we 241 -- do not want an atomic sync operation for things like 'Size. 242 243 N_Attribute_Reference 244 245 -- The N_Reference node is like an attribute 246 247 | N_Reference 248 249 -- Nothing to do for a reference to a component (or components) 250 -- of a composite object. Only reads and updates of the object 251 -- as a whole require atomic synchronization (RM C.6 (15)). 252 253 | N_Indexed_Component 254 | N_Selected_Component 255 | N_Slice 256 => 257 -- For all the above cases, nothing to do if we are the prefix 258 259 if Prefix (Parent (N)) = N then 260 return; 261 end if; 262 263 when others => 264 null; 265 end case; 266 267 -- Nothing to do for the identifier in an object renaming declaration, 268 -- the renaming itself does not need atomic synchronization. 269 270 if Nkind (Parent (N)) = N_Object_Renaming_Declaration then 271 return; 272 end if; 273 274 -- Go ahead and set the flag 275 276 Set_Atomic_Sync_Required (N); 277 278 -- Generate info message if requested 279 280 if Warn_On_Atomic_Synchronization then 281 case Nkind (N) is 282 when N_Identifier => 283 Msg_Node := N; 284 285 when N_Expanded_Name 286 | N_Selected_Component 287 => 288 Msg_Node := Selector_Name (N); 289 290 when N_Explicit_Dereference 291 | N_Indexed_Component 292 => 293 Msg_Node := Empty; 294 295 when others => 296 pragma Assert (False); 297 return; 298 end case; 299 300 if Present (Msg_Node) then 301 Error_Msg_N 302 ("info: atomic synchronization set for &?N?", Msg_Node); 303 else 304 Error_Msg_N 305 ("info: atomic synchronization set?N?", N); 306 end if; 307 end if; 308 end Activate_Atomic_Synchronization; 309 310 ---------------------- 311 -- Adjust_Condition -- 312 ---------------------- 313 314 procedure Adjust_Condition (N : Node_Id) is 315 begin 316 if No (N) then 317 return; 318 end if; 319 320 declare 321 Loc : constant Source_Ptr := Sloc (N); 322 T : constant Entity_Id := Etype (N); 323 Ti : Entity_Id; 324 325 begin 326 -- Defend against a call where the argument has no type, or has a 327 -- type that is not Boolean. This can occur because of prior errors. 328 329 if No (T) or else not Is_Boolean_Type (T) then 330 return; 331 end if; 332 333 -- Apply validity checking if needed 334 335 if Validity_Checks_On and Validity_Check_Tests then 336 Ensure_Valid (N); 337 end if; 338 339 -- Immediate return if standard boolean, the most common case, 340 -- where nothing needs to be done. 341 342 if Base_Type (T) = Standard_Boolean then 343 return; 344 end if; 345 346 -- Case of zero/non-zero semantics or non-standard enumeration 347 -- representation. In each case, we rewrite the node as: 348 349 -- ityp!(N) /= False'Enum_Rep 350 351 -- where ityp is an integer type with large enough size to hold any 352 -- value of type T. 353 354 if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then 355 if Esize (T) <= Esize (Standard_Integer) then 356 Ti := Standard_Integer; 357 else 358 Ti := Standard_Long_Long_Integer; 359 end if; 360 361 Rewrite (N, 362 Make_Op_Ne (Loc, 363 Left_Opnd => Unchecked_Convert_To (Ti, N), 364 Right_Opnd => 365 Make_Attribute_Reference (Loc, 366 Attribute_Name => Name_Enum_Rep, 367 Prefix => 368 New_Occurrence_Of (First_Literal (T), Loc)))); 369 Analyze_And_Resolve (N, Standard_Boolean); 370 371 else 372 Rewrite (N, Convert_To (Standard_Boolean, N)); 373 Analyze_And_Resolve (N, Standard_Boolean); 374 end if; 375 end; 376 end Adjust_Condition; 377 378 ------------------------ 379 -- Adjust_Result_Type -- 380 ------------------------ 381 382 procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is 383 begin 384 -- Ignore call if current type is not Standard.Boolean 385 386 if Etype (N) /= Standard_Boolean then 387 return; 388 end if; 389 390 -- If result is already of correct type, nothing to do. Note that 391 -- this will get the most common case where everything has a type 392 -- of Standard.Boolean. 393 394 if Base_Type (T) = Standard_Boolean then 395 return; 396 397 else 398 declare 399 KP : constant Node_Kind := Nkind (Parent (N)); 400 401 begin 402 -- If result is to be used as a Condition in the syntax, no need 403 -- to convert it back, since if it was changed to Standard.Boolean 404 -- using Adjust_Condition, that is just fine for this usage. 405 406 if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then 407 return; 408 409 -- If result is an operand of another logical operation, no need 410 -- to reset its type, since Standard.Boolean is just fine, and 411 -- such operations always do Adjust_Condition on their operands. 412 413 elsif KP in N_Op_Boolean 414 or else KP in N_Short_Circuit 415 or else KP = N_Op_Not 416 then 417 return; 418 419 -- Otherwise we perform a conversion from the current type, which 420 -- must be Standard.Boolean, to the desired type. Use the base 421 -- type to prevent spurious constraint checks that are extraneous 422 -- to the transformation. The type and its base have the same 423 -- representation, standard or otherwise. 424 425 else 426 Set_Analyzed (N); 427 Rewrite (N, Convert_To (Base_Type (T), N)); 428 Analyze_And_Resolve (N, Base_Type (T)); 429 end if; 430 end; 431 end if; 432 end Adjust_Result_Type; 433 434 -------------------------- 435 -- Append_Freeze_Action -- 436 -------------------------- 437 438 procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is 439 Fnode : Node_Id; 440 441 begin 442 Ensure_Freeze_Node (T); 443 Fnode := Freeze_Node (T); 444 445 if No (Actions (Fnode)) then 446 Set_Actions (Fnode, New_List (N)); 447 else 448 Append (N, Actions (Fnode)); 449 end if; 450 451 end Append_Freeze_Action; 452 453 --------------------------- 454 -- Append_Freeze_Actions -- 455 --------------------------- 456 457 procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is 458 Fnode : Node_Id; 459 460 begin 461 if No (L) then 462 return; 463 end if; 464 465 Ensure_Freeze_Node (T); 466 Fnode := Freeze_Node (T); 467 468 if No (Actions (Fnode)) then 469 Set_Actions (Fnode, L); 470 else 471 Append_List (L, Actions (Fnode)); 472 end if; 473 end Append_Freeze_Actions; 474 475 ------------------------------------ 476 -- Build_Allocate_Deallocate_Proc -- 477 ------------------------------------ 478 479 procedure Build_Allocate_Deallocate_Proc 480 (N : Node_Id; 481 Is_Allocate : Boolean) 482 is 483 function Find_Object (E : Node_Id) return Node_Id; 484 -- Given an arbitrary expression of an allocator, try to find an object 485 -- reference in it, otherwise return the original expression. 486 487 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean; 488 -- Determine whether subprogram Subp denotes a custom allocate or 489 -- deallocate. 490 491 ----------------- 492 -- Find_Object -- 493 ----------------- 494 495 function Find_Object (E : Node_Id) return Node_Id is 496 Expr : Node_Id; 497 498 begin 499 pragma Assert (Is_Allocate); 500 501 Expr := E; 502 loop 503 if Nkind (Expr) = N_Explicit_Dereference then 504 Expr := Prefix (Expr); 505 506 elsif Nkind (Expr) = N_Qualified_Expression then 507 Expr := Expression (Expr); 508 509 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then 510 511 -- When interface class-wide types are involved in allocation, 512 -- the expander introduces several levels of address arithmetic 513 -- to perform dispatch table displacement. In this scenario the 514 -- object appears as: 515 516 -- Tag_Ptr (Base_Address (<object>'Address)) 517 518 -- Detect this case and utilize the whole expression as the 519 -- "object" since it now points to the proper dispatch table. 520 521 if Is_RTE (Etype (Expr), RE_Tag_Ptr) then 522 exit; 523 524 -- Continue to strip the object 525 526 else 527 Expr := Expression (Expr); 528 end if; 529 530 else 531 exit; 532 end if; 533 end loop; 534 535 return Expr; 536 end Find_Object; 537 538 --------------------------------- 539 -- Is_Allocate_Deallocate_Proc -- 540 --------------------------------- 541 542 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is 543 begin 544 -- Look for a subprogram body with only one statement which is a 545 -- call to Allocate_Any_Controlled / Deallocate_Any_Controlled. 546 547 if Ekind (Subp) = E_Procedure 548 and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body 549 then 550 declare 551 HSS : constant Node_Id := 552 Handled_Statement_Sequence (Parent (Parent (Subp))); 553 Proc : Entity_Id; 554 555 begin 556 if Present (Statements (HSS)) 557 and then Nkind (First (Statements (HSS))) = 558 N_Procedure_Call_Statement 559 then 560 Proc := Entity (Name (First (Statements (HSS)))); 561 562 return 563 Is_RTE (Proc, RE_Allocate_Any_Controlled) 564 or else Is_RTE (Proc, RE_Deallocate_Any_Controlled); 565 end if; 566 end; 567 end if; 568 569 return False; 570 end Is_Allocate_Deallocate_Proc; 571 572 -- Local variables 573 574 Desig_Typ : Entity_Id; 575 Expr : Node_Id; 576 Needs_Fin : Boolean; 577 Pool_Id : Entity_Id; 578 Proc_To_Call : Node_Id := Empty; 579 Ptr_Typ : Entity_Id; 580 581 -- Start of processing for Build_Allocate_Deallocate_Proc 582 583 begin 584 -- Obtain the attributes of the allocation / deallocation 585 586 if Nkind (N) = N_Free_Statement then 587 Expr := Expression (N); 588 Ptr_Typ := Base_Type (Etype (Expr)); 589 Proc_To_Call := Procedure_To_Call (N); 590 591 else 592 if Nkind (N) = N_Object_Declaration then 593 Expr := Expression (N); 594 else 595 Expr := N; 596 end if; 597 598 -- In certain cases an allocator with a qualified expression may 599 -- be relocated and used as the initialization expression of a 600 -- temporary: 601 602 -- before: 603 -- Obj : Ptr_Typ := new Desig_Typ'(...); 604 605 -- after: 606 -- Tmp : Ptr_Typ := new Desig_Typ'(...); 607 -- Obj : Ptr_Typ := Tmp; 608 609 -- Since the allocator is always marked as analyzed to avoid infinite 610 -- expansion, it will never be processed by this routine given that 611 -- the designated type needs finalization actions. Detect this case 612 -- and complete the expansion of the allocator. 613 614 if Nkind (Expr) = N_Identifier 615 and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration 616 and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator 617 then 618 Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True); 619 return; 620 end if; 621 622 -- The allocator may have been rewritten into something else in which 623 -- case the expansion performed by this routine does not apply. 624 625 if Nkind (Expr) /= N_Allocator then 626 return; 627 end if; 628 629 Ptr_Typ := Base_Type (Etype (Expr)); 630 Proc_To_Call := Procedure_To_Call (Expr); 631 end if; 632 633 Pool_Id := Associated_Storage_Pool (Ptr_Typ); 634 Desig_Typ := Available_View (Designated_Type (Ptr_Typ)); 635 636 -- Handle concurrent types 637 638 if Is_Concurrent_Type (Desig_Typ) 639 and then Present (Corresponding_Record_Type (Desig_Typ)) 640 then 641 Desig_Typ := Corresponding_Record_Type (Desig_Typ); 642 end if; 643 644 -- Do not process allocations / deallocations without a pool 645 646 if No (Pool_Id) then 647 return; 648 649 -- Do not process allocations on / deallocations from the secondary 650 -- stack. 651 652 elsif Is_RTE (Pool_Id, RE_SS_Pool) 653 or else (Nkind (Expr) = N_Allocator 654 and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool)) 655 then 656 return; 657 658 -- Optimize the case where we are using the default Global_Pool_Object, 659 -- and we don't need the heavy finalization machinery. 660 661 elsif Pool_Id = RTE (RE_Global_Pool_Object) 662 and then not Needs_Finalization (Desig_Typ) 663 then 664 return; 665 666 -- Do not replicate the machinery if the allocator / free has already 667 -- been expanded and has a custom Allocate / Deallocate. 668 669 elsif Present (Proc_To_Call) 670 and then Is_Allocate_Deallocate_Proc (Proc_To_Call) 671 then 672 return; 673 end if; 674 675 -- Finalization actions are required when the object to be allocated or 676 -- deallocated needs these actions and the associated access type is not 677 -- subject to pragma No_Heap_Finalization. 678 679 Needs_Fin := 680 Needs_Finalization (Desig_Typ) 681 and then not No_Heap_Finalization (Ptr_Typ); 682 683 if Needs_Fin then 684 685 -- Do nothing if the access type may never allocate / deallocate 686 -- objects. 687 688 if No_Pool_Assigned (Ptr_Typ) then 689 return; 690 end if; 691 692 -- The allocation / deallocation of a controlled object must be 693 -- chained on / detached from a finalization master. 694 695 pragma Assert (Present (Finalization_Master (Ptr_Typ))); 696 697 -- The only other kind of allocation / deallocation supported by this 698 -- routine is on / from a subpool. 699 700 elsif Nkind (Expr) = N_Allocator 701 and then No (Subpool_Handle_Name (Expr)) 702 then 703 return; 704 end if; 705 706 declare 707 Loc : constant Source_Ptr := Sloc (N); 708 Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A'); 709 Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L'); 710 Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P'); 711 Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S'); 712 713 Actuals : List_Id; 714 Fin_Addr_Id : Entity_Id; 715 Fin_Mas_Act : Node_Id; 716 Fin_Mas_Id : Entity_Id; 717 Proc_To_Call : Entity_Id; 718 Subpool : Node_Id := Empty; 719 720 begin 721 -- Step 1: Construct all the actuals for the call to library routine 722 -- Allocate_Any_Controlled / Deallocate_Any_Controlled. 723 724 -- a) Storage pool 725 726 Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc)); 727 728 if Is_Allocate then 729 730 -- b) Subpool 731 732 if Nkind (Expr) = N_Allocator then 733 Subpool := Subpool_Handle_Name (Expr); 734 end if; 735 736 -- If a subpool is present it can be an arbitrary name, so make 737 -- the actual by copying the tree. 738 739 if Present (Subpool) then 740 Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc)); 741 else 742 Append_To (Actuals, Make_Null (Loc)); 743 end if; 744 745 -- c) Finalization master 746 747 if Needs_Fin then 748 Fin_Mas_Id := Finalization_Master (Ptr_Typ); 749 Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc); 750 751 -- Handle the case where the master is actually a pointer to a 752 -- master. This case arises in build-in-place functions. 753 754 if Is_Access_Type (Etype (Fin_Mas_Id)) then 755 Append_To (Actuals, Fin_Mas_Act); 756 else 757 Append_To (Actuals, 758 Make_Attribute_Reference (Loc, 759 Prefix => Fin_Mas_Act, 760 Attribute_Name => Name_Unrestricted_Access)); 761 end if; 762 else 763 Append_To (Actuals, Make_Null (Loc)); 764 end if; 765 766 -- d) Finalize_Address 767 768 -- Primitive Finalize_Address is never generated in CodePeer mode 769 -- since it contains an Unchecked_Conversion. 770 771 if Needs_Fin and then not CodePeer_Mode then 772 Fin_Addr_Id := Finalize_Address (Desig_Typ); 773 pragma Assert (Present (Fin_Addr_Id)); 774 775 Append_To (Actuals, 776 Make_Attribute_Reference (Loc, 777 Prefix => New_Occurrence_Of (Fin_Addr_Id, Loc), 778 Attribute_Name => Name_Unrestricted_Access)); 779 else 780 Append_To (Actuals, Make_Null (Loc)); 781 end if; 782 end if; 783 784 -- e) Address 785 -- f) Storage_Size 786 -- g) Alignment 787 788 Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc)); 789 Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc)); 790 791 if Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ) then 792 Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc)); 793 794 -- For deallocation of class-wide types we obtain the value of 795 -- alignment from the Type Specific Record of the deallocated object. 796 -- This is needed because the frontend expansion of class-wide types 797 -- into equivalent types confuses the back end. 798 799 else 800 -- Generate: 801 -- Obj.all'Alignment 802 803 -- ... because 'Alignment applied to class-wide types is expanded 804 -- into the code that reads the value of alignment from the TSD 805 -- (see Expand_N_Attribute_Reference) 806 807 Append_To (Actuals, 808 Unchecked_Convert_To (RTE (RE_Storage_Offset), 809 Make_Attribute_Reference (Loc, 810 Prefix => 811 Make_Explicit_Dereference (Loc, Relocate_Node (Expr)), 812 Attribute_Name => Name_Alignment))); 813 end if; 814 815 -- h) Is_Controlled 816 817 if Needs_Fin then 818 Is_Controlled : declare 819 Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F'); 820 Flag_Expr : Node_Id; 821 Param : Node_Id; 822 Pref : Node_Id; 823 Temp : Node_Id; 824 825 begin 826 if Is_Allocate then 827 Temp := Find_Object (Expression (Expr)); 828 else 829 Temp := Expr; 830 end if; 831 832 -- Processing for allocations where the expression is a subtype 833 -- indication. 834 835 if Is_Allocate 836 and then Is_Entity_Name (Temp) 837 and then Is_Type (Entity (Temp)) 838 then 839 Flag_Expr := 840 New_Occurrence_Of 841 (Boolean_Literals 842 (Needs_Finalization (Entity (Temp))), Loc); 843 844 -- The allocation / deallocation of a class-wide object relies 845 -- on a runtime check to determine whether the object is truly 846 -- controlled or not. Depending on this check, the finalization 847 -- machinery will request or reclaim extra storage reserved for 848 -- a list header. 849 850 elsif Is_Class_Wide_Type (Desig_Typ) then 851 852 -- Detect a special case where interface class-wide types 853 -- are involved as the object appears as: 854 855 -- Tag_Ptr (Base_Address (<object>'Address)) 856 857 -- The expression already yields the proper tag, generate: 858 859 -- Temp.all 860 861 if Is_RTE (Etype (Temp), RE_Tag_Ptr) then 862 Param := 863 Make_Explicit_Dereference (Loc, 864 Prefix => Relocate_Node (Temp)); 865 866 -- In the default case, obtain the tag of the object about 867 -- to be allocated / deallocated. Generate: 868 869 -- Temp'Tag 870 871 -- If the object is an unchecked conversion (typically to 872 -- an access to class-wide type), we must preserve the 873 -- conversion to ensure that the object is seen as tagged 874 -- in the code that follows. 875 876 else 877 Pref := Temp; 878 879 if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion 880 then 881 Pref := Parent (Pref); 882 end if; 883 884 Param := 885 Make_Attribute_Reference (Loc, 886 Prefix => Relocate_Node (Pref), 887 Attribute_Name => Name_Tag); 888 end if; 889 890 -- Generate: 891 -- Needs_Finalization (<Param>) 892 893 Flag_Expr := 894 Make_Function_Call (Loc, 895 Name => 896 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc), 897 Parameter_Associations => New_List (Param)); 898 899 -- Processing for generic actuals 900 901 elsif Is_Generic_Actual_Type (Desig_Typ) then 902 Flag_Expr := 903 New_Occurrence_Of (Boolean_Literals 904 (Needs_Finalization (Base_Type (Desig_Typ))), Loc); 905 906 -- The object does not require any specialized checks, it is 907 -- known to be controlled. 908 909 else 910 Flag_Expr := New_Occurrence_Of (Standard_True, Loc); 911 end if; 912 913 -- Create the temporary which represents the finalization state 914 -- of the expression. Generate: 915 -- 916 -- F : constant Boolean := <Flag_Expr>; 917 918 Insert_Action (N, 919 Make_Object_Declaration (Loc, 920 Defining_Identifier => Flag_Id, 921 Constant_Present => True, 922 Object_Definition => 923 New_Occurrence_Of (Standard_Boolean, Loc), 924 Expression => Flag_Expr)); 925 926 Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc)); 927 end Is_Controlled; 928 929 -- The object is not controlled 930 931 else 932 Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc)); 933 end if; 934 935 -- i) On_Subpool 936 937 if Is_Allocate then 938 Append_To (Actuals, 939 New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc)); 940 end if; 941 942 -- Step 2: Build a wrapper Allocate / Deallocate which internally 943 -- calls Allocate_Any_Controlled / Deallocate_Any_Controlled. 944 945 -- Select the proper routine to call 946 947 if Is_Allocate then 948 Proc_To_Call := RTE (RE_Allocate_Any_Controlled); 949 else 950 Proc_To_Call := RTE (RE_Deallocate_Any_Controlled); 951 end if; 952 953 -- Create a custom Allocate / Deallocate routine which has identical 954 -- profile to that of System.Storage_Pools. 955 956 Insert_Action (N, 957 Make_Subprogram_Body (Loc, 958 Specification => 959 960 -- procedure Pnn 961 962 Make_Procedure_Specification (Loc, 963 Defining_Unit_Name => Proc_Id, 964 Parameter_Specifications => New_List ( 965 966 -- P : Root_Storage_Pool 967 968 Make_Parameter_Specification (Loc, 969 Defining_Identifier => Make_Temporary (Loc, 'P'), 970 Parameter_Type => 971 New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)), 972 973 -- A : [out] Address 974 975 Make_Parameter_Specification (Loc, 976 Defining_Identifier => Addr_Id, 977 Out_Present => Is_Allocate, 978 Parameter_Type => 979 New_Occurrence_Of (RTE (RE_Address), Loc)), 980 981 -- S : Storage_Count 982 983 Make_Parameter_Specification (Loc, 984 Defining_Identifier => Size_Id, 985 Parameter_Type => 986 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)), 987 988 -- L : Storage_Count 989 990 Make_Parameter_Specification (Loc, 991 Defining_Identifier => Alig_Id, 992 Parameter_Type => 993 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)))), 994 995 Declarations => No_List, 996 997 Handled_Statement_Sequence => 998 Make_Handled_Sequence_Of_Statements (Loc, 999 Statements => New_List ( 1000 Make_Procedure_Call_Statement (Loc, 1001 Name => 1002 New_Occurrence_Of (Proc_To_Call, Loc), 1003 Parameter_Associations => Actuals)))), 1004 Suppress => All_Checks); 1005 1006 -- The newly generated Allocate / Deallocate becomes the default 1007 -- procedure to call when the back end processes the allocation / 1008 -- deallocation. 1009 1010 if Is_Allocate then 1011 Set_Procedure_To_Call (Expr, Proc_Id); 1012 else 1013 Set_Procedure_To_Call (N, Proc_Id); 1014 end if; 1015 end; 1016 end Build_Allocate_Deallocate_Proc; 1017 1018 ------------------------------- 1019 -- Build_Abort_Undefer_Block -- 1020 ------------------------------- 1021 1022 function Build_Abort_Undefer_Block 1023 (Loc : Source_Ptr; 1024 Stmts : List_Id; 1025 Context : Node_Id) return Node_Id 1026 is 1027 Exceptions_OK : constant Boolean := 1028 not Restriction_Active (No_Exception_Propagation); 1029 1030 AUD : Entity_Id; 1031 Blk : Node_Id; 1032 Blk_Id : Entity_Id; 1033 HSS : Node_Id; 1034 1035 begin 1036 -- The block should be generated only when undeferring abort in the 1037 -- context of a potential exception. 1038 1039 pragma Assert (Abort_Allowed and Exceptions_OK); 1040 1041 -- Generate: 1042 -- begin 1043 -- <Stmts> 1044 -- at end 1045 -- Abort_Undefer_Direct; 1046 -- end; 1047 1048 AUD := RTE (RE_Abort_Undefer_Direct); 1049 1050 HSS := 1051 Make_Handled_Sequence_Of_Statements (Loc, 1052 Statements => Stmts, 1053 At_End_Proc => New_Occurrence_Of (AUD, Loc)); 1054 1055 Blk := 1056 Make_Block_Statement (Loc, 1057 Handled_Statement_Sequence => HSS); 1058 Set_Is_Abort_Block (Blk); 1059 1060 Add_Block_Identifier (Blk, Blk_Id); 1061 Expand_At_End_Handler (HSS, Blk_Id); 1062 1063 -- Present the Abort_Undefer_Direct function to the back end to inline 1064 -- the call to the routine. 1065 1066 Add_Inlined_Body (AUD, Context); 1067 1068 return Blk; 1069 end Build_Abort_Undefer_Block; 1070 1071 --------------------------------- 1072 -- Build_Class_Wide_Expression -- 1073 --------------------------------- 1074 1075 procedure Build_Class_Wide_Expression 1076 (Prag : Node_Id; 1077 Subp : Entity_Id; 1078 Par_Subp : Entity_Id; 1079 Adjust_Sloc : Boolean; 1080 Needs_Wrapper : out Boolean) 1081 is 1082 function Replace_Entity (N : Node_Id) return Traverse_Result; 1083 -- Replace reference to formal of inherited operation or to primitive 1084 -- operation of root type, with corresponding entity for derived type, 1085 -- when constructing the class-wide condition of an overriding 1086 -- subprogram. 1087 1088 -------------------- 1089 -- Replace_Entity -- 1090 -------------------- 1091 1092 function Replace_Entity (N : Node_Id) return Traverse_Result is 1093 New_E : Entity_Id; 1094 1095 begin 1096 if Adjust_Sloc then 1097 Adjust_Inherited_Pragma_Sloc (N); 1098 end if; 1099 1100 if Nkind (N) = N_Identifier 1101 and then Present (Entity (N)) 1102 and then 1103 (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N))) 1104 and then 1105 (Nkind (Parent (N)) /= N_Attribute_Reference 1106 or else Attribute_Name (Parent (N)) /= Name_Class) 1107 then 1108 -- The replacement does not apply to dispatching calls within the 1109 -- condition, but only to calls whose static tag is that of the 1110 -- parent type. 1111 1112 if Is_Subprogram (Entity (N)) 1113 and then Nkind (Parent (N)) = N_Function_Call 1114 and then Present (Controlling_Argument (Parent (N))) 1115 then 1116 return OK; 1117 end if; 1118 1119 -- Determine whether entity has a renaming 1120 1121 New_E := Type_Map.Get (Entity (N)); 1122 1123 if Present (New_E) then 1124 Rewrite (N, New_Occurrence_Of (New_E, Sloc (N))); 1125 1126 -- AI12-0166: a precondition for a protected operation 1127 -- cannot include an internal call to a protected function 1128 -- of the type. In the case of an inherited condition for an 1129 -- overriding operation, both the operation and the function 1130 -- are given by primitive wrappers. 1131 1132 if Ekind (New_E) = E_Function 1133 and then Is_Primitive_Wrapper (New_E) 1134 and then Is_Primitive_Wrapper (Subp) 1135 and then Scope (Subp) = Scope (New_E) 1136 then 1137 Error_Msg_Node_2 := Wrapped_Entity (Subp); 1138 Error_Msg_NE 1139 ("internal call to& cannot appear in inherited " 1140 & "precondition of protected operation&", 1141 N, Wrapped_Entity (New_E)); 1142 end if; 1143 1144 -- If the entity is an overridden primitive and we are not 1145 -- in GNATprove mode, we must build a wrapper for the current 1146 -- inherited operation. If the reference is the prefix of an 1147 -- attribute such as 'Result (or others ???) there is no need 1148 -- for a wrapper: the condition is just rewritten in terms of 1149 -- the inherited subprogram. 1150 1151 if Is_Subprogram (New_E) 1152 and then Nkind (Parent (N)) /= N_Attribute_Reference 1153 and then not GNATprove_Mode 1154 then 1155 Needs_Wrapper := True; 1156 end if; 1157 end if; 1158 1159 -- Check that there are no calls left to abstract operations if 1160 -- the current subprogram is not abstract. 1161 1162 if Nkind (Parent (N)) = N_Function_Call 1163 and then N = Name (Parent (N)) 1164 then 1165 if not Is_Abstract_Subprogram (Subp) 1166 and then Is_Abstract_Subprogram (Entity (N)) 1167 then 1168 Error_Msg_Sloc := Sloc (Current_Scope); 1169 Error_Msg_Node_2 := Subp; 1170 if Comes_From_Source (Subp) then 1171 Error_Msg_NE 1172 ("cannot call abstract subprogram & in inherited " 1173 & "condition for&#", Subp, Entity (N)); 1174 else 1175 Error_Msg_NE 1176 ("cannot call abstract subprogram & in inherited " 1177 & "condition for inherited&#", Subp, Entity (N)); 1178 end if; 1179 1180 -- In SPARK mode, reject an inherited condition for an 1181 -- inherited operation if it contains a call to an overriding 1182 -- operation, because this implies that the pre/postconditions 1183 -- of the inherited operation have changed silently. 1184 1185 elsif SPARK_Mode = On 1186 and then Warn_On_Suspicious_Contract 1187 and then Present (Alias (Subp)) 1188 and then Present (New_E) 1189 and then Comes_From_Source (New_E) 1190 then 1191 Error_Msg_N 1192 ("cannot modify inherited condition (SPARK RM 6.1.1(1))", 1193 Parent (Subp)); 1194 Error_Msg_Sloc := Sloc (New_E); 1195 Error_Msg_Node_2 := Subp; 1196 Error_Msg_NE 1197 ("\overriding of&# forces overriding of&", 1198 Parent (Subp), New_E); 1199 end if; 1200 end if; 1201 1202 -- Update type of function call node, which should be the same as 1203 -- the function's return type. 1204 1205 if Is_Subprogram (Entity (N)) 1206 and then Nkind (Parent (N)) = N_Function_Call 1207 then 1208 Set_Etype (Parent (N), Etype (Entity (N))); 1209 end if; 1210 1211 -- The whole expression will be reanalyzed 1212 1213 elsif Nkind (N) in N_Has_Etype then 1214 Set_Analyzed (N, False); 1215 end if; 1216 1217 return OK; 1218 end Replace_Entity; 1219 1220 procedure Replace_Condition_Entities is 1221 new Traverse_Proc (Replace_Entity); 1222 1223 -- Local variables 1224 1225 Par_Formal : Entity_Id; 1226 Subp_Formal : Entity_Id; 1227 1228 -- Start of processing for Build_Class_Wide_Expression 1229 1230 begin 1231 Needs_Wrapper := False; 1232 1233 -- Add mapping from old formals to new formals 1234 1235 Par_Formal := First_Formal (Par_Subp); 1236 Subp_Formal := First_Formal (Subp); 1237 1238 while Present (Par_Formal) and then Present (Subp_Formal) loop 1239 Type_Map.Set (Par_Formal, Subp_Formal); 1240 Next_Formal (Par_Formal); 1241 Next_Formal (Subp_Formal); 1242 end loop; 1243 1244 Replace_Condition_Entities (Prag); 1245 end Build_Class_Wide_Expression; 1246 1247 -------------------- 1248 -- Build_DIC_Call -- 1249 -------------------- 1250 1251 function Build_DIC_Call 1252 (Loc : Source_Ptr; 1253 Obj_Id : Entity_Id; 1254 Typ : Entity_Id) return Node_Id 1255 is 1256 Proc_Id : constant Entity_Id := DIC_Procedure (Typ); 1257 Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id)); 1258 1259 begin 1260 return 1261 Make_Procedure_Call_Statement (Loc, 1262 Name => New_Occurrence_Of (Proc_Id, Loc), 1263 Parameter_Associations => New_List ( 1264 Make_Unchecked_Type_Conversion (Loc, 1265 Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc), 1266 Expression => New_Occurrence_Of (Obj_Id, Loc)))); 1267 end Build_DIC_Call; 1268 1269 ------------------------------ 1270 -- Build_DIC_Procedure_Body -- 1271 ------------------------------ 1272 1273 -- WARNING: This routine manages Ghost regions. Return statements must be 1274 -- replaced by gotos which jump to the end of the routine and restore the 1275 -- Ghost mode. 1276 1277 procedure Build_DIC_Procedure_Body 1278 (Typ : Entity_Id; 1279 For_Freeze : Boolean := False) 1280 is 1281 procedure Add_DIC_Check 1282 (DIC_Prag : Node_Id; 1283 DIC_Expr : Node_Id; 1284 Stmts : in out List_Id); 1285 -- Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify 1286 -- assertion expression DIC_Expr of pragma DIC_Prag. All generated code 1287 -- is added to list Stmts. 1288 1289 procedure Add_Inherited_DIC 1290 (DIC_Prag : Node_Id; 1291 Par_Typ : Entity_Id; 1292 Deriv_Typ : Entity_Id; 1293 Stmts : in out List_Id); 1294 -- Add a runtime check to verify the assertion expression of inherited 1295 -- pragma DIC_Prag. Par_Typ is parent type, which is also the owner of 1296 -- the DIC pragma. Deriv_Typ is the derived type inheriting the DIC 1297 -- pragma. All generated code is added to list Stmts. 1298 1299 procedure Add_Inherited_Tagged_DIC 1300 (DIC_Prag : Node_Id; 1301 Par_Typ : Entity_Id; 1302 Deriv_Typ : Entity_Id; 1303 Stmts : in out List_Id); 1304 -- Add a runtime check to verify assertion expression DIC_Expr of 1305 -- inherited pragma DIC_Prag. This routine applies class-wide pre- and 1306 -- postcondition-like runtime semantics to the check. Par_Typ is the 1307 -- parent type whose DIC pragma is being inherited. Deriv_Typ is the 1308 -- derived type inheriting the DIC pragma. All generated code is added 1309 -- to list Stmts. 1310 1311 procedure Add_Own_DIC 1312 (DIC_Prag : Node_Id; 1313 DIC_Typ : Entity_Id; 1314 Stmts : in out List_Id); 1315 -- Add a runtime check to verify the assertion expression of pragma 1316 -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. All generated code 1317 -- is added to list Stmts. 1318 1319 ------------------- 1320 -- Add_DIC_Check -- 1321 ------------------- 1322 1323 procedure Add_DIC_Check 1324 (DIC_Prag : Node_Id; 1325 DIC_Expr : Node_Id; 1326 Stmts : in out List_Id) 1327 is 1328 Loc : constant Source_Ptr := Sloc (DIC_Prag); 1329 Nam : constant Name_Id := Original_Aspect_Pragma_Name (DIC_Prag); 1330 1331 begin 1332 -- The DIC pragma is ignored, nothing left to do 1333 1334 if Is_Ignored (DIC_Prag) then 1335 null; 1336 1337 -- Otherwise the DIC expression must be checked at run time. 1338 -- Generate: 1339 1340 -- pragma Check (<Nam>, <DIC_Expr>); 1341 1342 else 1343 Append_New_To (Stmts, 1344 Make_Pragma (Loc, 1345 Pragma_Identifier => 1346 Make_Identifier (Loc, Name_Check), 1347 1348 Pragma_Argument_Associations => New_List ( 1349 Make_Pragma_Argument_Association (Loc, 1350 Expression => Make_Identifier (Loc, Nam)), 1351 1352 Make_Pragma_Argument_Association (Loc, 1353 Expression => DIC_Expr)))); 1354 end if; 1355 end Add_DIC_Check; 1356 1357 ----------------------- 1358 -- Add_Inherited_DIC -- 1359 ----------------------- 1360 1361 procedure Add_Inherited_DIC 1362 (DIC_Prag : Node_Id; 1363 Par_Typ : Entity_Id; 1364 Deriv_Typ : Entity_Id; 1365 Stmts : in out List_Id) 1366 is 1367 Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ); 1368 Deriv_Obj : constant Entity_Id := First_Entity (Deriv_Proc); 1369 Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ); 1370 Par_Obj : constant Entity_Id := First_Entity (Par_Proc); 1371 Loc : constant Source_Ptr := Sloc (DIC_Prag); 1372 1373 begin 1374 pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc)); 1375 1376 -- Verify the inherited DIC assertion expression by calling the DIC 1377 -- procedure of the parent type. 1378 1379 -- Generate: 1380 -- <Par_Typ>DIC (Par_Typ (_object)); 1381 1382 Append_New_To (Stmts, 1383 Make_Procedure_Call_Statement (Loc, 1384 Name => New_Occurrence_Of (Par_Proc, Loc), 1385 Parameter_Associations => New_List ( 1386 Convert_To 1387 (Typ => Etype (Par_Obj), 1388 Expr => New_Occurrence_Of (Deriv_Obj, Loc))))); 1389 end Add_Inherited_DIC; 1390 1391 ------------------------------ 1392 -- Add_Inherited_Tagged_DIC -- 1393 ------------------------------ 1394 1395 procedure Add_Inherited_Tagged_DIC 1396 (DIC_Prag : Node_Id; 1397 Par_Typ : Entity_Id; 1398 Deriv_Typ : Entity_Id; 1399 Stmts : in out List_Id) 1400 is 1401 Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ); 1402 DIC_Args : constant List_Id := 1403 Pragma_Argument_Associations (DIC_Prag); 1404 DIC_Arg : constant Node_Id := First (DIC_Args); 1405 DIC_Expr : constant Node_Id := Expression_Copy (DIC_Arg); 1406 Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ); 1407 1408 Expr : Node_Id; 1409 1410 begin 1411 -- The processing of an inherited DIC assertion expression starts off 1412 -- with a copy of the original parent expression where all references 1413 -- to the parent type have already been replaced with references to 1414 -- the _object formal parameter of the parent type's DIC procedure. 1415 1416 pragma Assert (Present (DIC_Expr)); 1417 Expr := New_Copy_Tree (DIC_Expr); 1418 1419 -- Perform the following substitutions: 1420 1421 -- * Replace a reference to the _object parameter of the parent 1422 -- type's DIC procedure with a reference to the _object parameter 1423 -- of the derived types' DIC procedure. 1424 1425 -- * Replace a reference to a discriminant of the parent type with 1426 -- a suitable value from the point of view of the derived type. 1427 1428 -- * Replace a call to an overridden parent primitive with a call 1429 -- to the overriding derived type primitive. 1430 1431 -- * Replace a call to an inherited parent primitive with a call to 1432 -- the internally-generated inherited derived type primitive. 1433 1434 -- Note that primitives defined in the private part are automatically 1435 -- handled by the overriding/inheritance mechanism and do not require 1436 -- an extra replacement pass. 1437 1438 pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc)); 1439 1440 Replace_References 1441 (Expr => Expr, 1442 Par_Typ => Par_Typ, 1443 Deriv_Typ => Deriv_Typ, 1444 Par_Obj => First_Formal (Par_Proc), 1445 Deriv_Obj => First_Formal (Deriv_Proc)); 1446 1447 -- Once the DIC assertion expression is fully processed, add a check 1448 -- to the statements of the DIC procedure. 1449 1450 Add_DIC_Check 1451 (DIC_Prag => DIC_Prag, 1452 DIC_Expr => Expr, 1453 Stmts => Stmts); 1454 end Add_Inherited_Tagged_DIC; 1455 1456 ----------------- 1457 -- Add_Own_DIC -- 1458 ----------------- 1459 1460 procedure Add_Own_DIC 1461 (DIC_Prag : Node_Id; 1462 DIC_Typ : Entity_Id; 1463 Stmts : in out List_Id) 1464 is 1465 DIC_Args : constant List_Id := 1466 Pragma_Argument_Associations (DIC_Prag); 1467 DIC_Arg : constant Node_Id := First (DIC_Args); 1468 DIC_Asp : constant Node_Id := Corresponding_Aspect (DIC_Prag); 1469 DIC_Expr : constant Node_Id := Get_Pragma_Arg (DIC_Arg); 1470 DIC_Proc : constant Entity_Id := DIC_Procedure (DIC_Typ); 1471 Obj_Id : constant Entity_Id := First_Formal (DIC_Proc); 1472 1473 procedure Preanalyze_Own_DIC_For_ASIS; 1474 -- Preanalyze the original DIC expression of an aspect or a source 1475 -- pragma for ASIS. 1476 1477 --------------------------------- 1478 -- Preanalyze_Own_DIC_For_ASIS -- 1479 --------------------------------- 1480 1481 procedure Preanalyze_Own_DIC_For_ASIS is 1482 Expr : Node_Id := Empty; 1483 1484 begin 1485 -- The DIC pragma is a source construct, preanalyze the original 1486 -- expression of the pragma. 1487 1488 if Comes_From_Source (DIC_Prag) then 1489 Expr := DIC_Expr; 1490 1491 -- Otherwise preanalyze the expression of the corresponding aspect 1492 1493 elsif Present (DIC_Asp) then 1494 Expr := Expression (DIC_Asp); 1495 end if; 1496 1497 -- The expression must be subjected to the same substitutions as 1498 -- the copy used in the generation of the runtime check. 1499 1500 if Present (Expr) then 1501 Replace_Type_References 1502 (Expr => Expr, 1503 Typ => DIC_Typ, 1504 Obj_Id => Obj_Id); 1505 1506 Preanalyze_Assert_Expression (Expr, Any_Boolean); 1507 end if; 1508 end Preanalyze_Own_DIC_For_ASIS; 1509 1510 -- Local variables 1511 1512 Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ); 1513 1514 Expr : Node_Id; 1515 1516 -- Start of processing for Add_Own_DIC 1517 1518 begin 1519 pragma Assert (Present (DIC_Expr)); 1520 Expr := New_Copy_Tree (DIC_Expr); 1521 1522 -- Perform the following substitution: 1523 1524 -- * Replace the current instance of DIC_Typ with a reference to 1525 -- the _object formal parameter of the DIC procedure. 1526 1527 Replace_Type_References 1528 (Expr => Expr, 1529 Typ => DIC_Typ, 1530 Obj_Id => Obj_Id); 1531 1532 -- Preanalyze the DIC expression to detect errors and at the same 1533 -- time capture the visibility of the proper package part. 1534 1535 Set_Parent (Expr, Typ_Decl); 1536 Preanalyze_Assert_Expression (Expr, Any_Boolean); 1537 1538 -- Save a copy of the expression with all replacements and analysis 1539 -- already taken place in case a derived type inherits the pragma. 1540 -- The copy will be used as the foundation of the derived type's own 1541 -- version of the DIC assertion expression. 1542 1543 if Is_Tagged_Type (DIC_Typ) then 1544 Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr)); 1545 end if; 1546 1547 -- If the pragma comes from an aspect specification, replace the 1548 -- saved expression because all type references must be substituted 1549 -- for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx 1550 -- routines. 1551 1552 if Present (DIC_Asp) then 1553 Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr)); 1554 end if; 1555 1556 -- Preanalyze the original DIC expression for ASIS 1557 1558 if ASIS_Mode then 1559 Preanalyze_Own_DIC_For_ASIS; 1560 end if; 1561 1562 -- Once the DIC assertion expression is fully processed, add a check 1563 -- to the statements of the DIC procedure. 1564 1565 Add_DIC_Check 1566 (DIC_Prag => DIC_Prag, 1567 DIC_Expr => Expr, 1568 Stmts => Stmts); 1569 end Add_Own_DIC; 1570 1571 -- Local variables 1572 1573 Loc : constant Source_Ptr := Sloc (Typ); 1574 1575 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 1576 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 1577 -- Save the Ghost-related attributes to restore on exit 1578 1579 DIC_Prag : Node_Id; 1580 DIC_Typ : Entity_Id; 1581 Dummy_1 : Entity_Id; 1582 Dummy_2 : Entity_Id; 1583 Proc_Body : Node_Id; 1584 Proc_Body_Id : Entity_Id; 1585 Proc_Decl : Node_Id; 1586 Proc_Id : Entity_Id; 1587 Stmts : List_Id := No_List; 1588 1589 Build_Body : Boolean := False; 1590 -- Flag set when the type requires a DIC procedure body to be built 1591 1592 Work_Typ : Entity_Id; 1593 -- The working type 1594 1595 -- Start of processing for Build_DIC_Procedure_Body 1596 1597 begin 1598 Work_Typ := Base_Type (Typ); 1599 1600 -- Do not process class-wide types as these are Itypes, but lack a first 1601 -- subtype (see below). 1602 1603 if Is_Class_Wide_Type (Work_Typ) then 1604 return; 1605 1606 -- Do not process the underlying full view of a private type. There is 1607 -- no way to get back to the partial view, plus the body will be built 1608 -- by the full view or the base type. 1609 1610 elsif Is_Underlying_Full_View (Work_Typ) then 1611 return; 1612 1613 -- Use the first subtype when dealing with various base types 1614 1615 elsif Is_Itype (Work_Typ) then 1616 Work_Typ := First_Subtype (Work_Typ); 1617 1618 -- The input denotes the corresponding record type of a protected or a 1619 -- task type. Work with the concurrent type because the corresponding 1620 -- record type may not be visible to clients of the type. 1621 1622 elsif Ekind (Work_Typ) = E_Record_Type 1623 and then Is_Concurrent_Record_Type (Work_Typ) 1624 then 1625 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 1626 end if; 1627 1628 -- The working type may be subject to pragma Ghost. Set the mode now to 1629 -- ensure that the DIC procedure is properly marked as Ghost. 1630 1631 Set_Ghost_Mode (Work_Typ); 1632 1633 -- The working type must be either define a DIC pragma of its own or 1634 -- inherit one from a parent type. 1635 1636 pragma Assert (Has_DIC (Work_Typ)); 1637 1638 -- Recover the type which defines the DIC pragma. This is either the 1639 -- working type itself or a parent type when the pragma is inherited. 1640 1641 DIC_Typ := Find_DIC_Type (Work_Typ); 1642 pragma Assert (Present (DIC_Typ)); 1643 1644 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition); 1645 pragma Assert (Present (DIC_Prag)); 1646 1647 -- Nothing to do if pragma DIC appears without an argument or its sole 1648 -- argument is "null". 1649 1650 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then 1651 goto Leave; 1652 end if; 1653 1654 -- The working type may lack a DIC procedure declaration. This may be 1655 -- due to several reasons: 1656 1657 -- * The working type's own DIC pragma does not contain a verifiable 1658 -- assertion expression. In this case there is no need to build a 1659 -- DIC procedure because there is nothing to check. 1660 1661 -- * The working type derives from a parent type. In this case a DIC 1662 -- procedure should be built only when the inherited DIC pragma has 1663 -- a verifiable assertion expression. 1664 1665 Proc_Id := DIC_Procedure (Work_Typ); 1666 1667 -- Build a DIC procedure declaration when the working type derives from 1668 -- a parent type. 1669 1670 if No (Proc_Id) then 1671 Build_DIC_Procedure_Declaration (Work_Typ); 1672 Proc_Id := DIC_Procedure (Work_Typ); 1673 end if; 1674 1675 -- At this point there should be a DIC procedure declaration 1676 1677 pragma Assert (Present (Proc_Id)); 1678 Proc_Decl := Unit_Declaration_Node (Proc_Id); 1679 1680 -- Nothing to do if the DIC procedure already has a body 1681 1682 if Present (Corresponding_Body (Proc_Decl)) then 1683 goto Leave; 1684 end if; 1685 1686 -- Emulate the environment of the DIC procedure by installing its scope 1687 -- and formal parameters. 1688 1689 Push_Scope (Proc_Id); 1690 Install_Formals (Proc_Id); 1691 1692 -- The working type defines its own DIC pragma. Replace the current 1693 -- instance of the working type with the formal of the DIC procedure. 1694 -- Note that there is no need to consider inherited DIC pragmas from 1695 -- parent types because the working type's DIC pragma "hides" all 1696 -- inherited DIC pragmas. 1697 1698 if Has_Own_DIC (Work_Typ) then 1699 pragma Assert (DIC_Typ = Work_Typ); 1700 1701 Add_Own_DIC 1702 (DIC_Prag => DIC_Prag, 1703 DIC_Typ => DIC_Typ, 1704 Stmts => Stmts); 1705 1706 Build_Body := True; 1707 1708 -- Otherwise the working type inherits a DIC pragma from a parent type. 1709 -- This processing is carried out when the type is frozen because the 1710 -- state of all parent discriminants is known at that point. Note that 1711 -- it is semantically sound to delay the creation of the DIC procedure 1712 -- body till the freeze point. If the type has a DIC pragma of its own, 1713 -- then the DIC procedure body would have already been constructed at 1714 -- the end of the visible declarations and all parent DIC pragmas are 1715 -- effectively "hidden" and irrelevant. 1716 1717 elsif For_Freeze then 1718 pragma Assert (Has_Inherited_DIC (Work_Typ)); 1719 pragma Assert (DIC_Typ /= Work_Typ); 1720 1721 -- The working type is tagged. The verification of the assertion 1722 -- expression is subject to the same semantics as class-wide pre- 1723 -- and postconditions. 1724 1725 if Is_Tagged_Type (Work_Typ) then 1726 Add_Inherited_Tagged_DIC 1727 (DIC_Prag => DIC_Prag, 1728 Par_Typ => DIC_Typ, 1729 Deriv_Typ => Work_Typ, 1730 Stmts => Stmts); 1731 1732 -- Otherwise the working type is not tagged. Verify the assertion 1733 -- expression of the inherited DIC pragma by directly calling the 1734 -- DIC procedure of the parent type. 1735 1736 else 1737 Add_Inherited_DIC 1738 (DIC_Prag => DIC_Prag, 1739 Par_Typ => DIC_Typ, 1740 Deriv_Typ => Work_Typ, 1741 Stmts => Stmts); 1742 end if; 1743 1744 Build_Body := True; 1745 end if; 1746 1747 End_Scope; 1748 1749 if Build_Body then 1750 1751 -- Produce an empty completing body in the following cases: 1752 -- * Assertions are disabled 1753 -- * The DIC Assertion_Policy is Ignore 1754 1755 if No (Stmts) then 1756 Stmts := New_List (Make_Null_Statement (Loc)); 1757 end if; 1758 1759 -- Generate: 1760 -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is 1761 -- begin 1762 -- <Stmts> 1763 -- end <Work_Typ>DIC; 1764 1765 Proc_Body := 1766 Make_Subprogram_Body (Loc, 1767 Specification => 1768 Copy_Subprogram_Spec (Parent (Proc_Id)), 1769 Declarations => Empty_List, 1770 Handled_Statement_Sequence => 1771 Make_Handled_Sequence_Of_Statements (Loc, 1772 Statements => Stmts)); 1773 Proc_Body_Id := Defining_Entity (Proc_Body); 1774 1775 -- Perform minor decoration in case the body is not analyzed 1776 1777 Set_Ekind (Proc_Body_Id, E_Subprogram_Body); 1778 Set_Etype (Proc_Body_Id, Standard_Void_Type); 1779 Set_Scope (Proc_Body_Id, Current_Scope); 1780 Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id)); 1781 Set_SPARK_Pragma_Inherited 1782 (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id)); 1783 1784 -- Link both spec and body to avoid generating duplicates 1785 1786 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id); 1787 Set_Corresponding_Spec (Proc_Body, Proc_Id); 1788 1789 -- The body should not be inserted into the tree when the context 1790 -- is ASIS or a generic unit because it is not part of the template. 1791 -- Note that the body must still be generated in order to resolve the 1792 -- DIC assertion expression. 1793 1794 if ASIS_Mode or Inside_A_Generic then 1795 null; 1796 1797 -- Semi-insert the body into the tree for GNATprove by setting its 1798 -- Parent field. This allows for proper upstream tree traversals. 1799 1800 elsif GNATprove_Mode then 1801 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ))); 1802 1803 -- Otherwise the body is part of the freezing actions of the working 1804 -- type. 1805 1806 else 1807 Append_Freeze_Action (Work_Typ, Proc_Body); 1808 end if; 1809 end if; 1810 1811 <<Leave>> 1812 Restore_Ghost_Region (Saved_GM, Saved_IGR); 1813 end Build_DIC_Procedure_Body; 1814 1815 ------------------------------------- 1816 -- Build_DIC_Procedure_Declaration -- 1817 ------------------------------------- 1818 1819 -- WARNING: This routine manages Ghost regions. Return statements must be 1820 -- replaced by gotos which jump to the end of the routine and restore the 1821 -- Ghost mode. 1822 1823 procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id) is 1824 Loc : constant Source_Ptr := Sloc (Typ); 1825 1826 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 1827 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 1828 -- Save the Ghost-related attributes to restore on exit 1829 1830 DIC_Prag : Node_Id; 1831 DIC_Typ : Entity_Id; 1832 Proc_Decl : Node_Id; 1833 Proc_Id : Entity_Id; 1834 Typ_Decl : Node_Id; 1835 1836 CRec_Typ : Entity_Id; 1837 -- The corresponding record type of Full_Typ 1838 1839 Full_Base : Entity_Id; 1840 -- The base type of Full_Typ 1841 1842 Full_Typ : Entity_Id; 1843 -- The full view of working type 1844 1845 Obj_Id : Entity_Id; 1846 -- The _object formal parameter of the DIC procedure 1847 1848 Priv_Typ : Entity_Id; 1849 -- The partial view of working type 1850 1851 Work_Typ : Entity_Id; 1852 -- The working type 1853 1854 begin 1855 Work_Typ := Base_Type (Typ); 1856 1857 -- Do not process class-wide types as these are Itypes, but lack a first 1858 -- subtype (see below). 1859 1860 if Is_Class_Wide_Type (Work_Typ) then 1861 return; 1862 1863 -- Do not process the underlying full view of a private type. There is 1864 -- no way to get back to the partial view, plus the body will be built 1865 -- by the full view or the base type. 1866 1867 elsif Is_Underlying_Full_View (Work_Typ) then 1868 return; 1869 1870 -- Use the first subtype when dealing with various base types 1871 1872 elsif Is_Itype (Work_Typ) then 1873 Work_Typ := First_Subtype (Work_Typ); 1874 1875 -- The input denotes the corresponding record type of a protected or a 1876 -- task type. Work with the concurrent type because the corresponding 1877 -- record type may not be visible to clients of the type. 1878 1879 elsif Ekind (Work_Typ) = E_Record_Type 1880 and then Is_Concurrent_Record_Type (Work_Typ) 1881 then 1882 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 1883 end if; 1884 1885 -- The working type may be subject to pragma Ghost. Set the mode now to 1886 -- ensure that the DIC procedure is properly marked as Ghost. 1887 1888 Set_Ghost_Mode (Work_Typ); 1889 1890 -- The type must be either subject to a DIC pragma or inherit one from a 1891 -- parent type. 1892 1893 pragma Assert (Has_DIC (Work_Typ)); 1894 1895 -- Recover the type which defines the DIC pragma. This is either the 1896 -- working type itself or a parent type when the pragma is inherited. 1897 1898 DIC_Typ := Find_DIC_Type (Work_Typ); 1899 pragma Assert (Present (DIC_Typ)); 1900 1901 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition); 1902 pragma Assert (Present (DIC_Prag)); 1903 1904 -- Nothing to do if pragma DIC appears without an argument or its sole 1905 -- argument is "null". 1906 1907 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then 1908 goto Leave; 1909 1910 -- Nothing to do if the type already has a DIC procedure 1911 1912 elsif Present (DIC_Procedure (Work_Typ)) then 1913 goto Leave; 1914 end if; 1915 1916 Proc_Id := 1917 Make_Defining_Identifier (Loc, 1918 Chars => 1919 New_External_Name (Chars (Work_Typ), "Default_Initial_Condition")); 1920 1921 -- Perform minor decoration in case the declaration is not analyzed 1922 1923 Set_Ekind (Proc_Id, E_Procedure); 1924 Set_Etype (Proc_Id, Standard_Void_Type); 1925 Set_Is_DIC_Procedure (Proc_Id); 1926 Set_Scope (Proc_Id, Current_Scope); 1927 Set_SPARK_Pragma (Proc_Id, SPARK_Mode_Pragma); 1928 Set_SPARK_Pragma_Inherited (Proc_Id); 1929 1930 Set_DIC_Procedure (Work_Typ, Proc_Id); 1931 1932 -- The DIC procedure requires debug info when the assertion expression 1933 -- is subject to Source Coverage Obligations. 1934 1935 if Generate_SCO then 1936 Set_Debug_Info_Needed (Proc_Id); 1937 end if; 1938 1939 -- Obtain all views of the input type 1940 1941 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ); 1942 1943 -- Associate the DIC procedure and various relevant flags with all views 1944 1945 Propagate_DIC_Attributes (Priv_Typ, From_Typ => Work_Typ); 1946 Propagate_DIC_Attributes (Full_Typ, From_Typ => Work_Typ); 1947 Propagate_DIC_Attributes (Full_Base, From_Typ => Work_Typ); 1948 Propagate_DIC_Attributes (CRec_Typ, From_Typ => Work_Typ); 1949 1950 -- The declaration of the DIC procedure must be inserted after the 1951 -- declaration of the partial view as this allows for proper external 1952 -- visibility. 1953 1954 if Present (Priv_Typ) then 1955 Typ_Decl := Declaration_Node (Priv_Typ); 1956 1957 -- Derived types with the full view as parent do not have a partial 1958 -- view. Insert the DIC procedure after the derived type. 1959 1960 else 1961 Typ_Decl := Declaration_Node (Full_Typ); 1962 end if; 1963 1964 -- The type should have a declarative node 1965 1966 pragma Assert (Present (Typ_Decl)); 1967 1968 -- Create the formal parameter which emulates the variable-like behavior 1969 -- of the type's current instance. 1970 1971 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject); 1972 1973 -- Perform minor decoration in case the declaration is not analyzed 1974 1975 Set_Ekind (Obj_Id, E_In_Parameter); 1976 Set_Etype (Obj_Id, Work_Typ); 1977 Set_Scope (Obj_Id, Proc_Id); 1978 1979 Set_First_Entity (Proc_Id, Obj_Id); 1980 1981 -- Generate: 1982 -- procedure <Work_Typ>DIC (_object : <Work_Typ>); 1983 1984 Proc_Decl := 1985 Make_Subprogram_Declaration (Loc, 1986 Specification => 1987 Make_Procedure_Specification (Loc, 1988 Defining_Unit_Name => Proc_Id, 1989 Parameter_Specifications => New_List ( 1990 Make_Parameter_Specification (Loc, 1991 Defining_Identifier => Obj_Id, 1992 Parameter_Type => 1993 New_Occurrence_Of (Work_Typ, Loc))))); 1994 1995 -- The declaration should not be inserted into the tree when the context 1996 -- is ASIS or a generic unit because it is not part of the template. 1997 1998 if ASIS_Mode or Inside_A_Generic then 1999 null; 2000 2001 -- Semi-insert the declaration into the tree for GNATprove by setting 2002 -- its Parent field. This allows for proper upstream tree traversals. 2003 2004 elsif GNATprove_Mode then 2005 Set_Parent (Proc_Decl, Parent (Typ_Decl)); 2006 2007 -- Otherwise insert the declaration 2008 2009 else 2010 Insert_After_And_Analyze (Typ_Decl, Proc_Decl); 2011 end if; 2012 2013 <<Leave>> 2014 Restore_Ghost_Region (Saved_GM, Saved_IGR); 2015 end Build_DIC_Procedure_Declaration; 2016 2017 ------------------------------------ 2018 -- Build_Invariant_Procedure_Body -- 2019 ------------------------------------ 2020 2021 -- WARNING: This routine manages Ghost regions. Return statements must be 2022 -- replaced by gotos which jump to the end of the routine and restore the 2023 -- Ghost mode. 2024 2025 procedure Build_Invariant_Procedure_Body 2026 (Typ : Entity_Id; 2027 Partial_Invariant : Boolean := False) 2028 is 2029 Loc : constant Source_Ptr := Sloc (Typ); 2030 2031 Pragmas_Seen : Elist_Id := No_Elist; 2032 -- This list contains all invariant pragmas processed so far. The list 2033 -- is used to avoid generating redundant invariant checks. 2034 2035 Produced_Check : Boolean := False; 2036 -- This flag tracks whether the type has produced at least one invariant 2037 -- check. The flag is used as a sanity check at the end of the routine. 2038 2039 -- NOTE: most of the routines in Build_Invariant_Procedure_Body are 2040 -- intentionally unnested to avoid deep indentation of code. 2041 2042 -- NOTE: all Add_xxx_Invariants routines are reactive. In other words 2043 -- they emit checks, loops (for arrays) and case statements (for record 2044 -- variant parts) only when there are invariants to verify. This keeps 2045 -- the body of the invariant procedure free of useless code. 2046 2047 procedure Add_Array_Component_Invariants 2048 (T : Entity_Id; 2049 Obj_Id : Entity_Id; 2050 Checks : in out List_Id); 2051 -- Generate an invariant check for each component of array type T. 2052 -- Obj_Id denotes the entity of the _object formal parameter of the 2053 -- invariant procedure. All created checks are added to list Checks. 2054 2055 procedure Add_Inherited_Invariants 2056 (T : Entity_Id; 2057 Priv_Typ : Entity_Id; 2058 Full_Typ : Entity_Id; 2059 Obj_Id : Entity_Id; 2060 Checks : in out List_Id); 2061 -- Generate an invariant check for each inherited class-wide invariant 2062 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote 2063 -- the partial and full view of the parent type. Obj_Id denotes the 2064 -- entity of the _object formal parameter of the invariant procedure. 2065 -- All created checks are added to list Checks. 2066 2067 procedure Add_Interface_Invariants 2068 (T : Entity_Id; 2069 Obj_Id : Entity_Id; 2070 Checks : in out List_Id); 2071 -- Generate an invariant check for each inherited class-wide invariant 2072 -- coming from all interfaces implemented by type T. Obj_Id denotes the 2073 -- entity of the _object formal parameter of the invariant procedure. 2074 -- All created checks are added to list Checks. 2075 2076 procedure Add_Invariant_Check 2077 (Prag : Node_Id; 2078 Expr : Node_Id; 2079 Checks : in out List_Id; 2080 Inherited : Boolean := False); 2081 -- Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to 2082 -- verify assertion expression Expr of pragma Prag. All generated code 2083 -- is added to list Checks. Flag Inherited should be set when the pragma 2084 -- is inherited from a parent or interface type. 2085 2086 procedure Add_Own_Invariants 2087 (T : Entity_Id; 2088 Obj_Id : Entity_Id; 2089 Checks : in out List_Id; 2090 Priv_Item : Node_Id := Empty); 2091 -- Generate an invariant check for each invariant found for type T. 2092 -- Obj_Id denotes the entity of the _object formal parameter of the 2093 -- invariant procedure. All created checks are added to list Checks. 2094 -- Priv_Item denotes the first rep item of the private type. 2095 2096 procedure Add_Parent_Invariants 2097 (T : Entity_Id; 2098 Obj_Id : Entity_Id; 2099 Checks : in out List_Id); 2100 -- Generate an invariant check for each inherited class-wide invariant 2101 -- coming from all parent types of type T. Obj_Id denotes the entity of 2102 -- the _object formal parameter of the invariant procedure. All created 2103 -- checks are added to list Checks. 2104 2105 procedure Add_Record_Component_Invariants 2106 (T : Entity_Id; 2107 Obj_Id : Entity_Id; 2108 Checks : in out List_Id); 2109 -- Generate an invariant check for each component of record type T. 2110 -- Obj_Id denotes the entity of the _object formal parameter of the 2111 -- invariant procedure. All created checks are added to list Checks. 2112 2113 ------------------------------------ 2114 -- Add_Array_Component_Invariants -- 2115 ------------------------------------ 2116 2117 procedure Add_Array_Component_Invariants 2118 (T : Entity_Id; 2119 Obj_Id : Entity_Id; 2120 Checks : in out List_Id) 2121 is 2122 Comp_Typ : constant Entity_Id := Component_Type (T); 2123 Dims : constant Pos := Number_Dimensions (T); 2124 2125 procedure Process_Array_Component 2126 (Indices : List_Id; 2127 Comp_Checks : in out List_Id); 2128 -- Generate an invariant check for an array component identified by 2129 -- the indices in list Indices. All created checks are added to list 2130 -- Comp_Checks. 2131 2132 procedure Process_One_Dimension 2133 (Dim : Pos; 2134 Indices : List_Id; 2135 Dim_Checks : in out List_Id); 2136 -- Generate a loop over the Nth dimension Dim of an array type. List 2137 -- Indices contains all array indices for the dimension. All created 2138 -- checks are added to list Dim_Checks. 2139 2140 ----------------------------- 2141 -- Process_Array_Component -- 2142 ----------------------------- 2143 2144 procedure Process_Array_Component 2145 (Indices : List_Id; 2146 Comp_Checks : in out List_Id) 2147 is 2148 Proc_Id : Entity_Id; 2149 2150 begin 2151 if Has_Invariants (Comp_Typ) then 2152 2153 -- In GNATprove mode, the component invariants are checked by 2154 -- other means. They should not be added to the array type 2155 -- invariant procedure, so that the procedure can be used to 2156 -- check the array type invariants if any. 2157 2158 if GNATprove_Mode then 2159 null; 2160 2161 else 2162 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ)); 2163 2164 -- The component type should have an invariant procedure 2165 -- if it has invariants of its own or inherits class-wide 2166 -- invariants from parent or interface types. 2167 2168 pragma Assert (Present (Proc_Id)); 2169 2170 -- Generate: 2171 -- <Comp_Typ>Invariant (_object (<Indices>)); 2172 2173 -- Note that the invariant procedure may have a null body if 2174 -- assertions are disabled or Assertion_Policy Ignore is in 2175 -- effect. 2176 2177 if not Has_Null_Body (Proc_Id) then 2178 Append_New_To (Comp_Checks, 2179 Make_Procedure_Call_Statement (Loc, 2180 Name => 2181 New_Occurrence_Of (Proc_Id, Loc), 2182 Parameter_Associations => New_List ( 2183 Make_Indexed_Component (Loc, 2184 Prefix => New_Occurrence_Of (Obj_Id, Loc), 2185 Expressions => New_Copy_List (Indices))))); 2186 end if; 2187 end if; 2188 2189 Produced_Check := True; 2190 end if; 2191 end Process_Array_Component; 2192 2193 --------------------------- 2194 -- Process_One_Dimension -- 2195 --------------------------- 2196 2197 procedure Process_One_Dimension 2198 (Dim : Pos; 2199 Indices : List_Id; 2200 Dim_Checks : in out List_Id) 2201 is 2202 Comp_Checks : List_Id := No_List; 2203 Index : Entity_Id; 2204 2205 begin 2206 -- Generate the invariant checks for the array component after all 2207 -- dimensions have produced their respective loops. 2208 2209 if Dim > Dims then 2210 Process_Array_Component 2211 (Indices => Indices, 2212 Comp_Checks => Dim_Checks); 2213 2214 -- Otherwise create a loop for the current dimension 2215 2216 else 2217 -- Create a new loop variable for each dimension 2218 2219 Index := 2220 Make_Defining_Identifier (Loc, 2221 Chars => New_External_Name ('I', Dim)); 2222 Append_To (Indices, New_Occurrence_Of (Index, Loc)); 2223 2224 Process_One_Dimension 2225 (Dim => Dim + 1, 2226 Indices => Indices, 2227 Dim_Checks => Comp_Checks); 2228 2229 -- Generate: 2230 -- for I<Dim> in _object'Range (<Dim>) loop 2231 -- <Comp_Checks> 2232 -- end loop; 2233 2234 -- Note that the invariant procedure may have a null body if 2235 -- assertions are disabled or Assertion_Policy Ignore is in 2236 -- effect. 2237 2238 if Present (Comp_Checks) then 2239 Append_New_To (Dim_Checks, 2240 Make_Implicit_Loop_Statement (T, 2241 Identifier => Empty, 2242 Iteration_Scheme => 2243 Make_Iteration_Scheme (Loc, 2244 Loop_Parameter_Specification => 2245 Make_Loop_Parameter_Specification (Loc, 2246 Defining_Identifier => Index, 2247 Discrete_Subtype_Definition => 2248 Make_Attribute_Reference (Loc, 2249 Prefix => 2250 New_Occurrence_Of (Obj_Id, Loc), 2251 Attribute_Name => Name_Range, 2252 Expressions => New_List ( 2253 Make_Integer_Literal (Loc, Dim))))), 2254 Statements => Comp_Checks)); 2255 end if; 2256 end if; 2257 end Process_One_Dimension; 2258 2259 -- Start of processing for Add_Array_Component_Invariants 2260 2261 begin 2262 Process_One_Dimension 2263 (Dim => 1, 2264 Indices => New_List, 2265 Dim_Checks => Checks); 2266 end Add_Array_Component_Invariants; 2267 2268 ------------------------------ 2269 -- Add_Inherited_Invariants -- 2270 ------------------------------ 2271 2272 procedure Add_Inherited_Invariants 2273 (T : Entity_Id; 2274 Priv_Typ : Entity_Id; 2275 Full_Typ : Entity_Id; 2276 Obj_Id : Entity_Id; 2277 Checks : in out List_Id) 2278 is 2279 Deriv_Typ : Entity_Id; 2280 Expr : Node_Id; 2281 Prag : Node_Id; 2282 Prag_Expr : Node_Id; 2283 Prag_Expr_Arg : Node_Id; 2284 Prag_Typ : Node_Id; 2285 Prag_Typ_Arg : Node_Id; 2286 2287 Par_Proc : Entity_Id; 2288 -- The "partial" invariant procedure of Par_Typ 2289 2290 Par_Typ : Entity_Id; 2291 -- The suitable view of the parent type used in the substitution of 2292 -- type attributes. 2293 2294 begin 2295 if not Present (Priv_Typ) and then not Present (Full_Typ) then 2296 return; 2297 end if; 2298 2299 -- When the type inheriting the class-wide invariant is a concurrent 2300 -- type, use the corresponding record type because it contains all 2301 -- primitive operations of the concurrent type and allows for proper 2302 -- substitution. 2303 2304 if Is_Concurrent_Type (T) then 2305 Deriv_Typ := Corresponding_Record_Type (T); 2306 else 2307 Deriv_Typ := T; 2308 end if; 2309 2310 pragma Assert (Present (Deriv_Typ)); 2311 2312 -- Determine which rep item chain to use. Precedence is given to that 2313 -- of the parent type's partial view since it usually carries all the 2314 -- class-wide invariants. 2315 2316 if Present (Priv_Typ) then 2317 Prag := First_Rep_Item (Priv_Typ); 2318 else 2319 Prag := First_Rep_Item (Full_Typ); 2320 end if; 2321 2322 while Present (Prag) loop 2323 if Nkind (Prag) = N_Pragma 2324 and then Pragma_Name (Prag) = Name_Invariant 2325 then 2326 -- Nothing to do if the pragma was already processed 2327 2328 if Contains (Pragmas_Seen, Prag) then 2329 return; 2330 2331 -- Nothing to do when the caller requests the processing of all 2332 -- inherited class-wide invariants, but the pragma does not 2333 -- fall in this category. 2334 2335 elsif not Class_Present (Prag) then 2336 return; 2337 end if; 2338 2339 -- Extract the arguments of the invariant pragma 2340 2341 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag)); 2342 Prag_Expr_Arg := Next (Prag_Typ_Arg); 2343 Prag_Expr := Expression_Copy (Prag_Expr_Arg); 2344 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg); 2345 2346 -- The pragma applies to the partial view of the parent type 2347 2348 if Present (Priv_Typ) 2349 and then Entity (Prag_Typ) = Priv_Typ 2350 then 2351 Par_Typ := Priv_Typ; 2352 2353 -- The pragma applies to the full view of the parent type 2354 2355 elsif Present (Full_Typ) 2356 and then Entity (Prag_Typ) = Full_Typ 2357 then 2358 Par_Typ := Full_Typ; 2359 2360 -- Otherwise the pragma does not belong to the parent type and 2361 -- should not be considered. 2362 2363 else 2364 return; 2365 end if; 2366 2367 -- Perform the following substitutions: 2368 2369 -- * Replace a reference to the _object parameter of the 2370 -- parent type's partial invariant procedure with a 2371 -- reference to the _object parameter of the derived 2372 -- type's full invariant procedure. 2373 2374 -- * Replace a reference to a discriminant of the parent type 2375 -- with a suitable value from the point of view of the 2376 -- derived type. 2377 2378 -- * Replace a call to an overridden parent primitive with a 2379 -- call to the overriding derived type primitive. 2380 2381 -- * Replace a call to an inherited parent primitive with a 2382 -- call to the internally-generated inherited derived type 2383 -- primitive. 2384 2385 Expr := New_Copy_Tree (Prag_Expr); 2386 2387 -- The parent type must have a "partial" invariant procedure 2388 -- because class-wide invariants are captured exclusively by 2389 -- it. 2390 2391 Par_Proc := Partial_Invariant_Procedure (Par_Typ); 2392 pragma Assert (Present (Par_Proc)); 2393 2394 Replace_References 2395 (Expr => Expr, 2396 Par_Typ => Par_Typ, 2397 Deriv_Typ => Deriv_Typ, 2398 Par_Obj => First_Formal (Par_Proc), 2399 Deriv_Obj => Obj_Id); 2400 2401 Add_Invariant_Check (Prag, Expr, Checks, Inherited => True); 2402 end if; 2403 2404 Next_Rep_Item (Prag); 2405 end loop; 2406 end Add_Inherited_Invariants; 2407 2408 ------------------------------ 2409 -- Add_Interface_Invariants -- 2410 ------------------------------ 2411 2412 procedure Add_Interface_Invariants 2413 (T : Entity_Id; 2414 Obj_Id : Entity_Id; 2415 Checks : in out List_Id) 2416 is 2417 Iface_Elmt : Elmt_Id; 2418 Ifaces : Elist_Id; 2419 2420 begin 2421 -- Generate an invariant check for each class-wide invariant coming 2422 -- from all interfaces implemented by type T. 2423 2424 if Is_Tagged_Type (T) then 2425 Collect_Interfaces (T, Ifaces); 2426 2427 -- Process the class-wide invariants of all implemented interfaces 2428 2429 Iface_Elmt := First_Elmt (Ifaces); 2430 while Present (Iface_Elmt) loop 2431 2432 -- The Full_Typ parameter is intentionally left Empty because 2433 -- interfaces are treated as the partial view of a private type 2434 -- in order to achieve uniformity with the general case. 2435 2436 Add_Inherited_Invariants 2437 (T => T, 2438 Priv_Typ => Node (Iface_Elmt), 2439 Full_Typ => Empty, 2440 Obj_Id => Obj_Id, 2441 Checks => Checks); 2442 2443 Next_Elmt (Iface_Elmt); 2444 end loop; 2445 end if; 2446 end Add_Interface_Invariants; 2447 2448 ------------------------- 2449 -- Add_Invariant_Check -- 2450 ------------------------- 2451 2452 procedure Add_Invariant_Check 2453 (Prag : Node_Id; 2454 Expr : Node_Id; 2455 Checks : in out List_Id; 2456 Inherited : Boolean := False) 2457 is 2458 Args : constant List_Id := Pragma_Argument_Associations (Prag); 2459 Nam : constant Name_Id := Original_Aspect_Pragma_Name (Prag); 2460 Ploc : constant Source_Ptr := Sloc (Prag); 2461 Str_Arg : constant Node_Id := Next (Next (First (Args))); 2462 2463 Assoc : List_Id; 2464 Str : String_Id; 2465 2466 begin 2467 -- The invariant is ignored, nothing left to do 2468 2469 if Is_Ignored (Prag) then 2470 null; 2471 2472 -- Otherwise the invariant is checked. Build a pragma Check to verify 2473 -- the expression at run time. 2474 2475 else 2476 Assoc := New_List ( 2477 Make_Pragma_Argument_Association (Ploc, 2478 Expression => Make_Identifier (Ploc, Nam)), 2479 Make_Pragma_Argument_Association (Ploc, 2480 Expression => Expr)); 2481 2482 -- Handle the String argument (if any) 2483 2484 if Present (Str_Arg) then 2485 Str := Strval (Get_Pragma_Arg (Str_Arg)); 2486 2487 -- When inheriting an invariant, modify the message from 2488 -- "failed invariant" to "failed inherited invariant". 2489 2490 if Inherited then 2491 String_To_Name_Buffer (Str); 2492 2493 if Name_Buffer (1 .. 16) = "failed invariant" then 2494 Insert_Str_In_Name_Buffer ("inherited ", 8); 2495 Str := String_From_Name_Buffer; 2496 end if; 2497 end if; 2498 2499 Append_To (Assoc, 2500 Make_Pragma_Argument_Association (Ploc, 2501 Expression => Make_String_Literal (Ploc, Str))); 2502 end if; 2503 2504 -- Generate: 2505 -- pragma Check (<Nam>, <Expr>, <Str>); 2506 2507 Append_New_To (Checks, 2508 Make_Pragma (Ploc, 2509 Chars => Name_Check, 2510 Pragma_Argument_Associations => Assoc)); 2511 end if; 2512 2513 -- Output an info message when inheriting an invariant and the 2514 -- listing option is enabled. 2515 2516 if Inherited and Opt.List_Inherited_Aspects then 2517 Error_Msg_Sloc := Sloc (Prag); 2518 Error_Msg_N 2519 ("info: & inherits `Invariant''Class` aspect from #?L?", Typ); 2520 end if; 2521 2522 -- Add the pragma to the list of processed pragmas 2523 2524 Append_New_Elmt (Prag, Pragmas_Seen); 2525 Produced_Check := True; 2526 end Add_Invariant_Check; 2527 2528 --------------------------- 2529 -- Add_Parent_Invariants -- 2530 --------------------------- 2531 2532 procedure Add_Parent_Invariants 2533 (T : Entity_Id; 2534 Obj_Id : Entity_Id; 2535 Checks : in out List_Id) 2536 is 2537 Dummy_1 : Entity_Id; 2538 Dummy_2 : Entity_Id; 2539 2540 Curr_Typ : Entity_Id; 2541 -- The entity of the current type being examined 2542 2543 Full_Typ : Entity_Id; 2544 -- The full view of Par_Typ 2545 2546 Par_Typ : Entity_Id; 2547 -- The entity of the parent type 2548 2549 Priv_Typ : Entity_Id; 2550 -- The partial view of Par_Typ 2551 2552 begin 2553 -- Do not process array types because they cannot have true parent 2554 -- types. This also prevents the generation of a duplicate invariant 2555 -- check when the input type is an array base type because its Etype 2556 -- denotes the first subtype, both of which share the same component 2557 -- type. 2558 2559 if Is_Array_Type (T) then 2560 return; 2561 end if; 2562 2563 -- Climb the parent type chain 2564 2565 Curr_Typ := T; 2566 loop 2567 -- Do not consider subtypes as they inherit the invariants 2568 -- from their base types. 2569 2570 Par_Typ := Base_Type (Etype (Curr_Typ)); 2571 2572 -- Stop the climb once the root of the parent chain is 2573 -- reached. 2574 2575 exit when Curr_Typ = Par_Typ; 2576 2577 -- Process the class-wide invariants of the parent type 2578 2579 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2); 2580 2581 -- Process the elements of an array type 2582 2583 if Is_Array_Type (Full_Typ) then 2584 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks); 2585 2586 -- Process the components of a record type 2587 2588 elsif Ekind (Full_Typ) = E_Record_Type then 2589 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks); 2590 end if; 2591 2592 Add_Inherited_Invariants 2593 (T => T, 2594 Priv_Typ => Priv_Typ, 2595 Full_Typ => Full_Typ, 2596 Obj_Id => Obj_Id, 2597 Checks => Checks); 2598 2599 Curr_Typ := Par_Typ; 2600 end loop; 2601 end Add_Parent_Invariants; 2602 2603 ------------------------ 2604 -- Add_Own_Invariants -- 2605 ------------------------ 2606 2607 procedure Add_Own_Invariants 2608 (T : Entity_Id; 2609 Obj_Id : Entity_Id; 2610 Checks : in out List_Id; 2611 Priv_Item : Node_Id := Empty) 2612 is 2613 ASIS_Expr : Node_Id; 2614 Expr : Node_Id; 2615 Prag : Node_Id; 2616 Prag_Asp : Node_Id; 2617 Prag_Expr : Node_Id; 2618 Prag_Expr_Arg : Node_Id; 2619 Prag_Typ : Node_Id; 2620 Prag_Typ_Arg : Node_Id; 2621 2622 begin 2623 if not Present (T) then 2624 return; 2625 end if; 2626 2627 Prag := First_Rep_Item (T); 2628 while Present (Prag) loop 2629 if Nkind (Prag) = N_Pragma 2630 and then Pragma_Name (Prag) = Name_Invariant 2631 then 2632 -- Stop the traversal of the rep item chain once a specific 2633 -- item is encountered. 2634 2635 if Present (Priv_Item) and then Prag = Priv_Item then 2636 exit; 2637 end if; 2638 2639 -- Nothing to do if the pragma was already processed 2640 2641 if Contains (Pragmas_Seen, Prag) then 2642 return; 2643 end if; 2644 2645 -- Extract the arguments of the invariant pragma 2646 2647 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag)); 2648 Prag_Expr_Arg := Next (Prag_Typ_Arg); 2649 Prag_Expr := Get_Pragma_Arg (Prag_Expr_Arg); 2650 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg); 2651 Prag_Asp := Corresponding_Aspect (Prag); 2652 2653 -- Verify the pragma belongs to T, otherwise the pragma applies 2654 -- to a parent type in which case it will be processed later by 2655 -- Add_Parent_Invariants or Add_Interface_Invariants. 2656 2657 if Entity (Prag_Typ) /= T then 2658 return; 2659 end if; 2660 2661 Expr := New_Copy_Tree (Prag_Expr); 2662 2663 -- Substitute all references to type T with references to the 2664 -- _object formal parameter. 2665 2666 Replace_Type_References (Expr, T, Obj_Id); 2667 2668 -- Preanalyze the invariant expression to detect errors and at 2669 -- the same time capture the visibility of the proper package 2670 -- part. 2671 2672 Set_Parent (Expr, Parent (Prag_Expr)); 2673 Preanalyze_Assert_Expression (Expr, Any_Boolean); 2674 2675 -- Save a copy of the expression when T is tagged to detect 2676 -- errors and capture the visibility of the proper package part 2677 -- for the generation of inherited type invariants. 2678 2679 if Is_Tagged_Type (T) then 2680 Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr)); 2681 end if; 2682 2683 -- If the pragma comes from an aspect specification, replace 2684 -- the saved expression because all type references must be 2685 -- substituted for the call to Preanalyze_Spec_Expression in 2686 -- Check_Aspect_At_xxx routines. 2687 2688 if Present (Prag_Asp) then 2689 Set_Entity (Identifier (Prag_Asp), New_Copy_Tree (Expr)); 2690 end if; 2691 2692 -- Analyze the original invariant expression for ASIS 2693 2694 if ASIS_Mode then 2695 ASIS_Expr := Empty; 2696 2697 if Comes_From_Source (Prag) then 2698 ASIS_Expr := Prag_Expr; 2699 elsif Present (Prag_Asp) then 2700 ASIS_Expr := Expression (Prag_Asp); 2701 end if; 2702 2703 if Present (ASIS_Expr) then 2704 Replace_Type_References (ASIS_Expr, T, Obj_Id); 2705 Preanalyze_Assert_Expression (ASIS_Expr, Any_Boolean); 2706 end if; 2707 end if; 2708 2709 Add_Invariant_Check (Prag, Expr, Checks); 2710 end if; 2711 2712 Next_Rep_Item (Prag); 2713 end loop; 2714 end Add_Own_Invariants; 2715 2716 ------------------------------------- 2717 -- Add_Record_Component_Invariants -- 2718 ------------------------------------- 2719 2720 procedure Add_Record_Component_Invariants 2721 (T : Entity_Id; 2722 Obj_Id : Entity_Id; 2723 Checks : in out List_Id) 2724 is 2725 procedure Process_Component_List 2726 (Comp_List : Node_Id; 2727 CL_Checks : in out List_Id); 2728 -- Generate invariant checks for all record components found in 2729 -- component list Comp_List, including variant parts. All created 2730 -- checks are added to list CL_Checks. 2731 2732 procedure Process_Record_Component 2733 (Comp_Id : Entity_Id; 2734 Comp_Checks : in out List_Id); 2735 -- Generate an invariant check for a record component identified by 2736 -- Comp_Id. All created checks are added to list Comp_Checks. 2737 2738 ---------------------------- 2739 -- Process_Component_List -- 2740 ---------------------------- 2741 2742 procedure Process_Component_List 2743 (Comp_List : Node_Id; 2744 CL_Checks : in out List_Id) 2745 is 2746 Comp : Node_Id; 2747 Var : Node_Id; 2748 Var_Alts : List_Id := No_List; 2749 Var_Checks : List_Id := No_List; 2750 Var_Stmts : List_Id; 2751 2752 Produced_Variant_Check : Boolean := False; 2753 -- This flag tracks whether the component has produced at least 2754 -- one invariant check. 2755 2756 begin 2757 -- Traverse the component items 2758 2759 Comp := First (Component_Items (Comp_List)); 2760 while Present (Comp) loop 2761 if Nkind (Comp) = N_Component_Declaration then 2762 2763 -- Generate the component invariant check 2764 2765 Process_Record_Component 2766 (Comp_Id => Defining_Entity (Comp), 2767 Comp_Checks => CL_Checks); 2768 end if; 2769 2770 Next (Comp); 2771 end loop; 2772 2773 -- Traverse the variant part 2774 2775 if Present (Variant_Part (Comp_List)) then 2776 Var := First (Variants (Variant_Part (Comp_List))); 2777 while Present (Var) loop 2778 Var_Checks := No_List; 2779 2780 -- Generate invariant checks for all components and variant 2781 -- parts that qualify. 2782 2783 Process_Component_List 2784 (Comp_List => Component_List (Var), 2785 CL_Checks => Var_Checks); 2786 2787 -- The components of the current variant produced at least 2788 -- one invariant check. 2789 2790 if Present (Var_Checks) then 2791 Var_Stmts := Var_Checks; 2792 Produced_Variant_Check := True; 2793 2794 -- Otherwise there are either no components with invariants, 2795 -- assertions are disabled, or Assertion_Policy Ignore is in 2796 -- effect. 2797 2798 else 2799 Var_Stmts := New_List (Make_Null_Statement (Loc)); 2800 end if; 2801 2802 Append_New_To (Var_Alts, 2803 Make_Case_Statement_Alternative (Loc, 2804 Discrete_Choices => 2805 New_Copy_List (Discrete_Choices (Var)), 2806 Statements => Var_Stmts)); 2807 2808 Next (Var); 2809 end loop; 2810 2811 -- Create a case statement which verifies the invariant checks 2812 -- of a particular component list depending on the discriminant 2813 -- values only when there is at least one real invariant check. 2814 2815 if Produced_Variant_Check then 2816 Append_New_To (CL_Checks, 2817 Make_Case_Statement (Loc, 2818 Expression => 2819 Make_Selected_Component (Loc, 2820 Prefix => New_Occurrence_Of (Obj_Id, Loc), 2821 Selector_Name => 2822 New_Occurrence_Of 2823 (Entity (Name (Variant_Part (Comp_List))), Loc)), 2824 Alternatives => Var_Alts)); 2825 end if; 2826 end if; 2827 end Process_Component_List; 2828 2829 ------------------------------ 2830 -- Process_Record_Component -- 2831 ------------------------------ 2832 2833 procedure Process_Record_Component 2834 (Comp_Id : Entity_Id; 2835 Comp_Checks : in out List_Id) 2836 is 2837 Comp_Typ : constant Entity_Id := Etype (Comp_Id); 2838 Proc_Id : Entity_Id; 2839 2840 Produced_Component_Check : Boolean := False; 2841 -- This flag tracks whether the component has produced at least 2842 -- one invariant check. 2843 2844 begin 2845 -- Nothing to do for internal component _parent. Note that it is 2846 -- not desirable to check whether the component comes from source 2847 -- because protected type components are relocated to an internal 2848 -- corresponding record, but still need processing. 2849 2850 if Chars (Comp_Id) = Name_uParent then 2851 return; 2852 end if; 2853 2854 -- Verify the invariant of the component. Note that an access 2855 -- type may have an invariant when it acts as the full view of a 2856 -- private type and the invariant appears on the partial view. In 2857 -- this case verify the access value itself. 2858 2859 if Has_Invariants (Comp_Typ) then 2860 2861 -- In GNATprove mode, the component invariants are checked by 2862 -- other means. They should not be added to the record type 2863 -- invariant procedure, so that the procedure can be used to 2864 -- check the record type invariants if any. 2865 2866 if GNATprove_Mode then 2867 null; 2868 2869 else 2870 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ)); 2871 2872 -- The component type should have an invariant procedure 2873 -- if it has invariants of its own or inherits class-wide 2874 -- invariants from parent or interface types. 2875 2876 pragma Assert (Present (Proc_Id)); 2877 2878 -- Generate: 2879 -- <Comp_Typ>Invariant (T (_object).<Comp_Id>); 2880 2881 -- Note that the invariant procedure may have a null body if 2882 -- assertions are disabled or Assertion_Policy Ignore is in 2883 -- effect. 2884 2885 if not Has_Null_Body (Proc_Id) then 2886 Append_New_To (Comp_Checks, 2887 Make_Procedure_Call_Statement (Loc, 2888 Name => 2889 New_Occurrence_Of (Proc_Id, Loc), 2890 Parameter_Associations => New_List ( 2891 Make_Selected_Component (Loc, 2892 Prefix => 2893 Unchecked_Convert_To 2894 (T, New_Occurrence_Of (Obj_Id, Loc)), 2895 Selector_Name => 2896 New_Occurrence_Of (Comp_Id, Loc))))); 2897 end if; 2898 end if; 2899 2900 Produced_Check := True; 2901 Produced_Component_Check := True; 2902 end if; 2903 2904 if Produced_Component_Check and then Has_Unchecked_Union (T) then 2905 Error_Msg_NE 2906 ("invariants cannot be checked on components of " 2907 & "unchecked_union type &?", Comp_Id, T); 2908 end if; 2909 end Process_Record_Component; 2910 2911 -- Local variables 2912 2913 Comps : Node_Id; 2914 Def : Node_Id; 2915 2916 -- Start of processing for Add_Record_Component_Invariants 2917 2918 begin 2919 -- An untagged derived type inherits the components of its parent 2920 -- type. In order to avoid creating redundant invariant checks, do 2921 -- not process the components now. Instead wait until the ultimate 2922 -- parent of the untagged derivation chain is reached. 2923 2924 if not Is_Untagged_Derivation (T) then 2925 Def := Type_Definition (Parent (T)); 2926 2927 if Nkind (Def) = N_Derived_Type_Definition then 2928 Def := Record_Extension_Part (Def); 2929 end if; 2930 2931 pragma Assert (Nkind (Def) = N_Record_Definition); 2932 Comps := Component_List (Def); 2933 2934 if Present (Comps) then 2935 Process_Component_List 2936 (Comp_List => Comps, 2937 CL_Checks => Checks); 2938 end if; 2939 end if; 2940 end Add_Record_Component_Invariants; 2941 2942 -- Local variables 2943 2944 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 2945 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 2946 -- Save the Ghost-related attributes to restore on exit 2947 2948 Dummy : Entity_Id; 2949 Priv_Item : Node_Id; 2950 Proc_Body : Node_Id; 2951 Proc_Body_Id : Entity_Id; 2952 Proc_Decl : Node_Id; 2953 Proc_Id : Entity_Id; 2954 Stmts : List_Id := No_List; 2955 2956 CRec_Typ : Entity_Id := Empty; 2957 -- The corresponding record type of Full_Typ 2958 2959 Full_Proc : Entity_Id := Empty; 2960 -- The entity of the "full" invariant procedure 2961 2962 Full_Typ : Entity_Id := Empty; 2963 -- The full view of the working type 2964 2965 Obj_Id : Entity_Id := Empty; 2966 -- The _object formal parameter of the invariant procedure 2967 2968 Part_Proc : Entity_Id := Empty; 2969 -- The entity of the "partial" invariant procedure 2970 2971 Priv_Typ : Entity_Id := Empty; 2972 -- The partial view of the working type 2973 2974 Work_Typ : Entity_Id := Empty; 2975 -- The working type 2976 2977 -- Start of processing for Build_Invariant_Procedure_Body 2978 2979 begin 2980 Work_Typ := Typ; 2981 2982 -- The input type denotes the implementation base type of a constrained 2983 -- array type. Work with the first subtype as all invariant pragmas are 2984 -- on its rep item chain. 2985 2986 if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then 2987 Work_Typ := First_Subtype (Work_Typ); 2988 2989 -- The input type denotes the corresponding record type of a protected 2990 -- or task type. Work with the concurrent type because the corresponding 2991 -- record type may not be visible to clients of the type. 2992 2993 elsif Ekind (Work_Typ) = E_Record_Type 2994 and then Is_Concurrent_Record_Type (Work_Typ) 2995 then 2996 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 2997 end if; 2998 2999 -- The working type may be subject to pragma Ghost. Set the mode now to 3000 -- ensure that the invariant procedure is properly marked as Ghost. 3001 3002 Set_Ghost_Mode (Work_Typ); 3003 3004 -- The type must either have invariants of its own, inherit class-wide 3005 -- invariants from parent types or interfaces, or be an array or record 3006 -- type whose components have invariants. 3007 3008 pragma Assert (Has_Invariants (Work_Typ)); 3009 3010 -- Interfaces are treated as the partial view of a private type in order 3011 -- to achieve uniformity with the general case. 3012 3013 if Is_Interface (Work_Typ) then 3014 Priv_Typ := Work_Typ; 3015 3016 -- Otherwise obtain both views of the type 3017 3018 else 3019 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ); 3020 end if; 3021 3022 -- The caller requests a body for the partial invariant procedure 3023 3024 if Partial_Invariant then 3025 Full_Proc := Invariant_Procedure (Work_Typ); 3026 Proc_Id := Partial_Invariant_Procedure (Work_Typ); 3027 3028 -- The "full" invariant procedure body was already created 3029 3030 if Present (Full_Proc) 3031 and then Present 3032 (Corresponding_Body (Unit_Declaration_Node (Full_Proc))) 3033 then 3034 -- This scenario happens only when the type is an untagged 3035 -- derivation from a private parent and the underlying full 3036 -- view was processed before the partial view. 3037 3038 pragma Assert 3039 (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ)); 3040 3041 -- Nothing to do because the processing of the underlying full 3042 -- view already checked the invariants of the partial view. 3043 3044 goto Leave; 3045 end if; 3046 3047 -- Create a declaration for the "partial" invariant procedure if it 3048 -- is not available. 3049 3050 if No (Proc_Id) then 3051 Build_Invariant_Procedure_Declaration 3052 (Typ => Work_Typ, 3053 Partial_Invariant => True); 3054 3055 Proc_Id := Partial_Invariant_Procedure (Work_Typ); 3056 end if; 3057 3058 -- The caller requests a body for the "full" invariant procedure 3059 3060 else 3061 Proc_Id := Invariant_Procedure (Work_Typ); 3062 Part_Proc := Partial_Invariant_Procedure (Work_Typ); 3063 3064 -- Create a declaration for the "full" invariant procedure if it is 3065 -- not available. 3066 3067 if No (Proc_Id) then 3068 Build_Invariant_Procedure_Declaration (Work_Typ); 3069 Proc_Id := Invariant_Procedure (Work_Typ); 3070 end if; 3071 end if; 3072 3073 -- At this point there should be an invariant procedure declaration 3074 3075 pragma Assert (Present (Proc_Id)); 3076 Proc_Decl := Unit_Declaration_Node (Proc_Id); 3077 3078 -- Nothing to do if the invariant procedure already has a body 3079 3080 if Present (Corresponding_Body (Proc_Decl)) then 3081 goto Leave; 3082 end if; 3083 3084 -- Emulate the environment of the invariant procedure by installing its 3085 -- scope and formal parameters. Note that this is not needed, but having 3086 -- the scope installed helps with the detection of invariant-related 3087 -- errors. 3088 3089 Push_Scope (Proc_Id); 3090 Install_Formals (Proc_Id); 3091 3092 Obj_Id := First_Formal (Proc_Id); 3093 pragma Assert (Present (Obj_Id)); 3094 3095 -- The "partial" invariant procedure verifies the invariants of the 3096 -- partial view only. 3097 3098 if Partial_Invariant then 3099 pragma Assert (Present (Priv_Typ)); 3100 3101 Add_Own_Invariants 3102 (T => Priv_Typ, 3103 Obj_Id => Obj_Id, 3104 Checks => Stmts); 3105 3106 -- Otherwise the "full" invariant procedure verifies the invariants of 3107 -- the full view, all array or record components, as well as class-wide 3108 -- invariants inherited from parent types or interfaces. In addition, it 3109 -- indirectly verifies the invariants of the partial view by calling the 3110 -- "partial" invariant procedure. 3111 3112 else 3113 pragma Assert (Present (Full_Typ)); 3114 3115 -- Check the invariants of the partial view by calling the "partial" 3116 -- invariant procedure. Generate: 3117 3118 -- <Work_Typ>Partial_Invariant (_object); 3119 3120 if Present (Part_Proc) then 3121 Append_New_To (Stmts, 3122 Make_Procedure_Call_Statement (Loc, 3123 Name => New_Occurrence_Of (Part_Proc, Loc), 3124 Parameter_Associations => New_List ( 3125 New_Occurrence_Of (Obj_Id, Loc)))); 3126 3127 Produced_Check := True; 3128 end if; 3129 3130 Priv_Item := Empty; 3131 3132 -- Derived subtypes do not have a partial view 3133 3134 if Present (Priv_Typ) then 3135 3136 -- The processing of the "full" invariant procedure intentionally 3137 -- skips the partial view because a) this may result in changes of 3138 -- visibility and b) lead to duplicate checks. However, when the 3139 -- full view is the underlying full view of an untagged derived 3140 -- type whose parent type is private, partial invariants appear on 3141 -- the rep item chain of the partial view only. 3142 3143 -- package Pack_1 is 3144 -- type Root ... is private; 3145 -- private 3146 -- <full view of Root> 3147 -- end Pack_1; 3148 3149 -- with Pack_1; 3150 -- package Pack_2 is 3151 -- type Child is new Pack_1.Root with Type_Invariant => ...; 3152 -- <underlying full view of Child> 3153 -- end Pack_2; 3154 3155 -- As a result, the processing of the full view must also consider 3156 -- all invariants of the partial view. 3157 3158 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then 3159 null; 3160 3161 -- Otherwise the invariants of the partial view are ignored 3162 3163 else 3164 -- Note that the rep item chain is shared between the partial 3165 -- and full views of a type. To avoid processing the invariants 3166 -- of the partial view, signal the logic to stop when the first 3167 -- rep item of the partial view has been reached. 3168 3169 Priv_Item := First_Rep_Item (Priv_Typ); 3170 3171 -- Ignore the invariants of the partial view by eliminating the 3172 -- view. 3173 3174 Priv_Typ := Empty; 3175 end if; 3176 end if; 3177 3178 -- Process the invariants of the full view and in certain cases those 3179 -- of the partial view. This also handles any invariants on array or 3180 -- record components. 3181 3182 Add_Own_Invariants 3183 (T => Priv_Typ, 3184 Obj_Id => Obj_Id, 3185 Checks => Stmts, 3186 Priv_Item => Priv_Item); 3187 3188 Add_Own_Invariants 3189 (T => Full_Typ, 3190 Obj_Id => Obj_Id, 3191 Checks => Stmts, 3192 Priv_Item => Priv_Item); 3193 3194 -- Process the elements of an array type 3195 3196 if Is_Array_Type (Full_Typ) then 3197 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts); 3198 3199 -- Process the components of a record type 3200 3201 elsif Ekind (Full_Typ) = E_Record_Type then 3202 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts); 3203 3204 -- Process the components of a corresponding record 3205 3206 elsif Present (CRec_Typ) then 3207 Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts); 3208 end if; 3209 3210 -- Process the inherited class-wide invariants of all parent types. 3211 -- This also handles any invariants on record components. 3212 3213 Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts); 3214 3215 -- Process the inherited class-wide invariants of all implemented 3216 -- interface types. 3217 3218 Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts); 3219 end if; 3220 3221 End_Scope; 3222 3223 -- At this point there should be at least one invariant check. If this 3224 -- is not the case, then the invariant-related flags were not properly 3225 -- set, or there is a missing invariant procedure on one of the array 3226 -- or record components. 3227 3228 pragma Assert (Produced_Check); 3229 3230 -- Account for the case where assertions are disabled or all invariant 3231 -- checks are subject to Assertion_Policy Ignore. Produce a completing 3232 -- empty body. 3233 3234 if No (Stmts) then 3235 Stmts := New_List (Make_Null_Statement (Loc)); 3236 end if; 3237 3238 -- Generate: 3239 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is 3240 -- begin 3241 -- <Stmts> 3242 -- end <Work_Typ>[Partial_]Invariant; 3243 3244 Proc_Body := 3245 Make_Subprogram_Body (Loc, 3246 Specification => 3247 Copy_Subprogram_Spec (Parent (Proc_Id)), 3248 Declarations => Empty_List, 3249 Handled_Statement_Sequence => 3250 Make_Handled_Sequence_Of_Statements (Loc, 3251 Statements => Stmts)); 3252 Proc_Body_Id := Defining_Entity (Proc_Body); 3253 3254 -- Perform minor decoration in case the body is not analyzed 3255 3256 Set_Ekind (Proc_Body_Id, E_Subprogram_Body); 3257 Set_Etype (Proc_Body_Id, Standard_Void_Type); 3258 Set_Scope (Proc_Body_Id, Current_Scope); 3259 3260 -- Link both spec and body to avoid generating duplicates 3261 3262 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id); 3263 Set_Corresponding_Spec (Proc_Body, Proc_Id); 3264 3265 -- The body should not be inserted into the tree when the context is 3266 -- ASIS or a generic unit because it is not part of the template. Note 3267 -- that the body must still be generated in order to resolve the 3268 -- invariants. 3269 3270 if ASIS_Mode or Inside_A_Generic then 3271 null; 3272 3273 -- Semi-insert the body into the tree for GNATprove by setting its 3274 -- Parent field. This allows for proper upstream tree traversals. 3275 3276 elsif GNATprove_Mode then 3277 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ))); 3278 3279 -- Otherwise the body is part of the freezing actions of the type 3280 3281 else 3282 Append_Freeze_Action (Work_Typ, Proc_Body); 3283 end if; 3284 3285 <<Leave>> 3286 Restore_Ghost_Region (Saved_GM, Saved_IGR); 3287 end Build_Invariant_Procedure_Body; 3288 3289 ------------------------------------------- 3290 -- Build_Invariant_Procedure_Declaration -- 3291 ------------------------------------------- 3292 3293 -- WARNING: This routine manages Ghost regions. Return statements must be 3294 -- replaced by gotos which jump to the end of the routine and restore the 3295 -- Ghost mode. 3296 3297 procedure Build_Invariant_Procedure_Declaration 3298 (Typ : Entity_Id; 3299 Partial_Invariant : Boolean := False) 3300 is 3301 Loc : constant Source_Ptr := Sloc (Typ); 3302 3303 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 3304 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 3305 -- Save the Ghost-related attributes to restore on exit 3306 3307 Proc_Decl : Node_Id; 3308 Proc_Id : Entity_Id; 3309 Proc_Nam : Name_Id; 3310 Typ_Decl : Node_Id; 3311 3312 CRec_Typ : Entity_Id; 3313 -- The corresponding record type of Full_Typ 3314 3315 Full_Base : Entity_Id; 3316 -- The base type of Full_Typ 3317 3318 Full_Typ : Entity_Id; 3319 -- The full view of working type 3320 3321 Obj_Id : Entity_Id; 3322 -- The _object formal parameter of the invariant procedure 3323 3324 Obj_Typ : Entity_Id; 3325 -- The type of the _object formal parameter 3326 3327 Priv_Typ : Entity_Id; 3328 -- The partial view of working type 3329 3330 Work_Typ : Entity_Id; 3331 -- The working type 3332 3333 begin 3334 Work_Typ := Typ; 3335 3336 -- The input type denotes the implementation base type of a constrained 3337 -- array type. Work with the first subtype as all invariant pragmas are 3338 -- on its rep item chain. 3339 3340 if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then 3341 Work_Typ := First_Subtype (Work_Typ); 3342 3343 -- The input denotes the corresponding record type of a protected or a 3344 -- task type. Work with the concurrent type because the corresponding 3345 -- record type may not be visible to clients of the type. 3346 3347 elsif Ekind (Work_Typ) = E_Record_Type 3348 and then Is_Concurrent_Record_Type (Work_Typ) 3349 then 3350 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 3351 end if; 3352 3353 -- The working type may be subject to pragma Ghost. Set the mode now to 3354 -- ensure that the invariant procedure is properly marked as Ghost. 3355 3356 Set_Ghost_Mode (Work_Typ); 3357 3358 -- The type must either have invariants of its own, inherit class-wide 3359 -- invariants from parent or interface types, or be an array or record 3360 -- type whose components have invariants. 3361 3362 pragma Assert (Has_Invariants (Work_Typ)); 3363 3364 -- Nothing to do if the type already has a "partial" invariant procedure 3365 3366 if Partial_Invariant then 3367 if Present (Partial_Invariant_Procedure (Work_Typ)) then 3368 goto Leave; 3369 end if; 3370 3371 -- Nothing to do if the type already has a "full" invariant procedure 3372 3373 elsif Present (Invariant_Procedure (Work_Typ)) then 3374 goto Leave; 3375 end if; 3376 3377 -- The caller requests the declaration of the "partial" invariant 3378 -- procedure. 3379 3380 if Partial_Invariant then 3381 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant"); 3382 3383 -- Otherwise the caller requests the declaration of the "full" invariant 3384 -- procedure. 3385 3386 else 3387 Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant"); 3388 end if; 3389 3390 Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam); 3391 3392 -- Perform minor decoration in case the declaration is not analyzed 3393 3394 Set_Ekind (Proc_Id, E_Procedure); 3395 Set_Etype (Proc_Id, Standard_Void_Type); 3396 Set_Scope (Proc_Id, Current_Scope); 3397 3398 if Partial_Invariant then 3399 Set_Is_Partial_Invariant_Procedure (Proc_Id); 3400 Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id); 3401 else 3402 Set_Is_Invariant_Procedure (Proc_Id); 3403 Set_Invariant_Procedure (Work_Typ, Proc_Id); 3404 end if; 3405 3406 -- The invariant procedure requires debug info when the invariants are 3407 -- subject to Source Coverage Obligations. 3408 3409 if Generate_SCO then 3410 Set_Debug_Info_Needed (Proc_Id); 3411 end if; 3412 3413 -- Obtain all views of the input type 3414 3415 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ); 3416 3417 -- Associate the invariant procedure with all views 3418 3419 Propagate_Invariant_Attributes (Priv_Typ, From_Typ => Work_Typ); 3420 Propagate_Invariant_Attributes (Full_Typ, From_Typ => Work_Typ); 3421 Propagate_Invariant_Attributes (Full_Base, From_Typ => Work_Typ); 3422 Propagate_Invariant_Attributes (CRec_Typ, From_Typ => Work_Typ); 3423 3424 -- The declaration of the invariant procedure is inserted after the 3425 -- declaration of the partial view as this allows for proper external 3426 -- visibility. 3427 3428 if Present (Priv_Typ) then 3429 Typ_Decl := Declaration_Node (Priv_Typ); 3430 3431 -- Anonymous arrays in object declarations have no explicit declaration 3432 -- so use the related object declaration as the insertion point. 3433 3434 elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then 3435 Typ_Decl := Associated_Node_For_Itype (Work_Typ); 3436 3437 -- Derived types with the full view as parent do not have a partial 3438 -- view. Insert the invariant procedure after the derived type. 3439 3440 else 3441 Typ_Decl := Declaration_Node (Full_Typ); 3442 end if; 3443 3444 -- The type should have a declarative node 3445 3446 pragma Assert (Present (Typ_Decl)); 3447 3448 -- Create the formal parameter which emulates the variable-like behavior 3449 -- of the current type instance. 3450 3451 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject); 3452 3453 -- When generating an invariant procedure declaration for an abstract 3454 -- type (including interfaces), use the class-wide type as the _object 3455 -- type. This has several desirable effects: 3456 3457 -- * The invariant procedure does not become a primitive of the type. 3458 -- This eliminates the need to either special case the treatment of 3459 -- invariant procedures, or to make it a predefined primitive and 3460 -- force every derived type to potentially provide an empty body. 3461 3462 -- * The invariant procedure does not need to be declared as abstract. 3463 -- This allows for a proper body, which in turn avoids redundant 3464 -- processing of the same invariants for types with multiple views. 3465 3466 -- * The class-wide type allows for calls to abstract primitives 3467 -- within a nonabstract subprogram. The calls are treated as 3468 -- dispatching and require additional processing when they are 3469 -- remapped to call primitives of derived types. See routine 3470 -- Replace_References for details. 3471 3472 if Is_Abstract_Type (Work_Typ) then 3473 Obj_Typ := Class_Wide_Type (Work_Typ); 3474 else 3475 Obj_Typ := Work_Typ; 3476 end if; 3477 3478 -- Perform minor decoration in case the declaration is not analyzed 3479 3480 Set_Ekind (Obj_Id, E_In_Parameter); 3481 Set_Etype (Obj_Id, Obj_Typ); 3482 Set_Scope (Obj_Id, Proc_Id); 3483 3484 Set_First_Entity (Proc_Id, Obj_Id); 3485 Set_Last_Entity (Proc_Id, Obj_Id); 3486 3487 -- Generate: 3488 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>); 3489 3490 Proc_Decl := 3491 Make_Subprogram_Declaration (Loc, 3492 Specification => 3493 Make_Procedure_Specification (Loc, 3494 Defining_Unit_Name => Proc_Id, 3495 Parameter_Specifications => New_List ( 3496 Make_Parameter_Specification (Loc, 3497 Defining_Identifier => Obj_Id, 3498 Parameter_Type => New_Occurrence_Of (Obj_Typ, Loc))))); 3499 3500 -- The declaration should not be inserted into the tree when the context 3501 -- is ASIS or a generic unit because it is not part of the template. 3502 3503 if ASIS_Mode or Inside_A_Generic then 3504 null; 3505 3506 -- Semi-insert the declaration into the tree for GNATprove by setting 3507 -- its Parent field. This allows for proper upstream tree traversals. 3508 3509 elsif GNATprove_Mode then 3510 Set_Parent (Proc_Decl, Parent (Typ_Decl)); 3511 3512 -- Otherwise insert the declaration 3513 3514 else 3515 pragma Assert (Present (Typ_Decl)); 3516 Insert_After_And_Analyze (Typ_Decl, Proc_Decl); 3517 end if; 3518 3519 <<Leave>> 3520 Restore_Ghost_Region (Saved_GM, Saved_IGR); 3521 end Build_Invariant_Procedure_Declaration; 3522 3523 -------------------------- 3524 -- Build_Procedure_Form -- 3525 -------------------------- 3526 3527 procedure Build_Procedure_Form (N : Node_Id) is 3528 Loc : constant Source_Ptr := Sloc (N); 3529 Subp : constant Entity_Id := Defining_Entity (N); 3530 3531 Func_Formal : Entity_Id; 3532 Proc_Formals : List_Id; 3533 Proc_Decl : Node_Id; 3534 3535 begin 3536 -- No action needed if this transformation was already done, or in case 3537 -- of subprogram renaming declarations. 3538 3539 if Nkind (Specification (N)) = N_Procedure_Specification 3540 or else Nkind (N) = N_Subprogram_Renaming_Declaration 3541 then 3542 return; 3543 end if; 3544 3545 -- Ditto when dealing with an expression function, where both the 3546 -- original expression and the generated declaration end up being 3547 -- expanded here. 3548 3549 if Rewritten_For_C (Subp) then 3550 return; 3551 end if; 3552 3553 Proc_Formals := New_List; 3554 3555 -- Create a list of formal parameters with the same types as the 3556 -- function. 3557 3558 Func_Formal := First_Formal (Subp); 3559 while Present (Func_Formal) loop 3560 Append_To (Proc_Formals, 3561 Make_Parameter_Specification (Loc, 3562 Defining_Identifier => 3563 Make_Defining_Identifier (Loc, Chars (Func_Formal)), 3564 Parameter_Type => 3565 New_Occurrence_Of (Etype (Func_Formal), Loc))); 3566 3567 Next_Formal (Func_Formal); 3568 end loop; 3569 3570 -- Add an extra out parameter to carry the function result 3571 3572 Name_Len := 6; 3573 Name_Buffer (1 .. Name_Len) := "RESULT"; 3574 Append_To (Proc_Formals, 3575 Make_Parameter_Specification (Loc, 3576 Defining_Identifier => 3577 Make_Defining_Identifier (Loc, Chars => Name_Find), 3578 Out_Present => True, 3579 Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc))); 3580 3581 -- The new procedure declaration is inserted immediately after the 3582 -- function declaration. The processing in Build_Procedure_Body_Form 3583 -- relies on this order. 3584 3585 Proc_Decl := 3586 Make_Subprogram_Declaration (Loc, 3587 Specification => 3588 Make_Procedure_Specification (Loc, 3589 Defining_Unit_Name => 3590 Make_Defining_Identifier (Loc, Chars (Subp)), 3591 Parameter_Specifications => Proc_Formals)); 3592 3593 Insert_After_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl); 3594 3595 -- Entity of procedure must remain invisible so that it does not 3596 -- overload subsequent references to the original function. 3597 3598 Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False); 3599 3600 -- Mark the function as having a procedure form and link the function 3601 -- and its internally built procedure. 3602 3603 Set_Rewritten_For_C (Subp); 3604 Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl)); 3605 Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp); 3606 end Build_Procedure_Form; 3607 3608 ------------------------ 3609 -- Build_Runtime_Call -- 3610 ------------------------ 3611 3612 function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is 3613 begin 3614 -- If entity is not available, we can skip making the call (this avoids 3615 -- junk duplicated error messages in a number of cases). 3616 3617 if not RTE_Available (RE) then 3618 return Make_Null_Statement (Loc); 3619 else 3620 return 3621 Make_Procedure_Call_Statement (Loc, 3622 Name => New_Occurrence_Of (RTE (RE), Loc)); 3623 end if; 3624 end Build_Runtime_Call; 3625 3626 ------------------------ 3627 -- Build_SS_Mark_Call -- 3628 ------------------------ 3629 3630 function Build_SS_Mark_Call 3631 (Loc : Source_Ptr; 3632 Mark : Entity_Id) return Node_Id 3633 is 3634 begin 3635 -- Generate: 3636 -- Mark : constant Mark_Id := SS_Mark; 3637 3638 return 3639 Make_Object_Declaration (Loc, 3640 Defining_Identifier => Mark, 3641 Constant_Present => True, 3642 Object_Definition => 3643 New_Occurrence_Of (RTE (RE_Mark_Id), Loc), 3644 Expression => 3645 Make_Function_Call (Loc, 3646 Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc))); 3647 end Build_SS_Mark_Call; 3648 3649 --------------------------- 3650 -- Build_SS_Release_Call -- 3651 --------------------------- 3652 3653 function Build_SS_Release_Call 3654 (Loc : Source_Ptr; 3655 Mark : Entity_Id) return Node_Id 3656 is 3657 begin 3658 -- Generate: 3659 -- SS_Release (Mark); 3660 3661 return 3662 Make_Procedure_Call_Statement (Loc, 3663 Name => 3664 New_Occurrence_Of (RTE (RE_SS_Release), Loc), 3665 Parameter_Associations => New_List ( 3666 New_Occurrence_Of (Mark, Loc))); 3667 end Build_SS_Release_Call; 3668 3669 ---------------------------- 3670 -- Build_Task_Array_Image -- 3671 ---------------------------- 3672 3673 -- This function generates the body for a function that constructs the 3674 -- image string for a task that is an array component. The function is 3675 -- local to the init proc for the array type, and is called for each one 3676 -- of the components. The constructed image has the form of an indexed 3677 -- component, whose prefix is the outer variable of the array type. 3678 -- The n-dimensional array type has known indexes Index, Index2... 3679 3680 -- Id_Ref is an indexed component form created by the enclosing init proc. 3681 -- Its successive indexes are Val1, Val2, ... which are the loop variables 3682 -- in the loops that call the individual task init proc on each component. 3683 3684 -- The generated function has the following structure: 3685 3686 -- function F return String is 3687 -- Pref : string renames Task_Name; 3688 -- T1 : String := Index1'Image (Val1); 3689 -- ... 3690 -- Tn : String := indexn'image (Valn); 3691 -- Len : Integer := T1'Length + ... + Tn'Length + n + 1; 3692 -- -- Len includes commas and the end parentheses. 3693 -- Res : String (1..Len); 3694 -- Pos : Integer := Pref'Length; 3695 -- 3696 -- begin 3697 -- Res (1 .. Pos) := Pref; 3698 -- Pos := Pos + 1; 3699 -- Res (Pos) := '('; 3700 -- Pos := Pos + 1; 3701 -- Res (Pos .. Pos + T1'Length - 1) := T1; 3702 -- Pos := Pos + T1'Length; 3703 -- Res (Pos) := '.'; 3704 -- Pos := Pos + 1; 3705 -- ... 3706 -- Res (Pos .. Pos + Tn'Length - 1) := Tn; 3707 -- Res (Len) := ')'; 3708 -- 3709 -- return Res; 3710 -- end F; 3711 -- 3712 -- Needless to say, multidimensional arrays of tasks are rare enough that 3713 -- the bulkiness of this code is not really a concern. 3714 3715 function Build_Task_Array_Image 3716 (Loc : Source_Ptr; 3717 Id_Ref : Node_Id; 3718 A_Type : Entity_Id; 3719 Dyn : Boolean := False) return Node_Id 3720 is 3721 Dims : constant Nat := Number_Dimensions (A_Type); 3722 -- Number of dimensions for array of tasks 3723 3724 Temps : array (1 .. Dims) of Entity_Id; 3725 -- Array of temporaries to hold string for each index 3726 3727 Indx : Node_Id; 3728 -- Index expression 3729 3730 Len : Entity_Id; 3731 -- Total length of generated name 3732 3733 Pos : Entity_Id; 3734 -- Running index for substring assignments 3735 3736 Pref : constant Entity_Id := Make_Temporary (Loc, 'P'); 3737 -- Name of enclosing variable, prefix of resulting name 3738 3739 Res : Entity_Id; 3740 -- String to hold result 3741 3742 Val : Node_Id; 3743 -- Value of successive indexes 3744 3745 Sum : Node_Id; 3746 -- Expression to compute total size of string 3747 3748 T : Entity_Id; 3749 -- Entity for name at one index position 3750 3751 Decls : constant List_Id := New_List; 3752 Stats : constant List_Id := New_List; 3753 3754 begin 3755 -- For a dynamic task, the name comes from the target variable. For a 3756 -- static one it is a formal of the enclosing init proc. 3757 3758 if Dyn then 3759 Get_Name_String (Chars (Entity (Prefix (Id_Ref)))); 3760 Append_To (Decls, 3761 Make_Object_Declaration (Loc, 3762 Defining_Identifier => Pref, 3763 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 3764 Expression => 3765 Make_String_Literal (Loc, 3766 Strval => String_From_Name_Buffer))); 3767 3768 else 3769 Append_To (Decls, 3770 Make_Object_Renaming_Declaration (Loc, 3771 Defining_Identifier => Pref, 3772 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 3773 Name => Make_Identifier (Loc, Name_uTask_Name))); 3774 end if; 3775 3776 Indx := First_Index (A_Type); 3777 Val := First (Expressions (Id_Ref)); 3778 3779 for J in 1 .. Dims loop 3780 T := Make_Temporary (Loc, 'T'); 3781 Temps (J) := T; 3782 3783 Append_To (Decls, 3784 Make_Object_Declaration (Loc, 3785 Defining_Identifier => T, 3786 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 3787 Expression => 3788 Make_Attribute_Reference (Loc, 3789 Attribute_Name => Name_Image, 3790 Prefix => New_Occurrence_Of (Etype (Indx), Loc), 3791 Expressions => New_List (New_Copy_Tree (Val))))); 3792 3793 Next_Index (Indx); 3794 Next (Val); 3795 end loop; 3796 3797 Sum := Make_Integer_Literal (Loc, Dims + 1); 3798 3799 Sum := 3800 Make_Op_Add (Loc, 3801 Left_Opnd => Sum, 3802 Right_Opnd => 3803 Make_Attribute_Reference (Loc, 3804 Attribute_Name => Name_Length, 3805 Prefix => New_Occurrence_Of (Pref, Loc), 3806 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 3807 3808 for J in 1 .. Dims loop 3809 Sum := 3810 Make_Op_Add (Loc, 3811 Left_Opnd => Sum, 3812 Right_Opnd => 3813 Make_Attribute_Reference (Loc, 3814 Attribute_Name => Name_Length, 3815 Prefix => 3816 New_Occurrence_Of (Temps (J), Loc), 3817 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 3818 end loop; 3819 3820 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats); 3821 3822 Set_Character_Literal_Name (Char_Code (Character'Pos ('('))); 3823 3824 Append_To (Stats, 3825 Make_Assignment_Statement (Loc, 3826 Name => 3827 Make_Indexed_Component (Loc, 3828 Prefix => New_Occurrence_Of (Res, Loc), 3829 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 3830 Expression => 3831 Make_Character_Literal (Loc, 3832 Chars => Name_Find, 3833 Char_Literal_Value => UI_From_Int (Character'Pos ('('))))); 3834 3835 Append_To (Stats, 3836 Make_Assignment_Statement (Loc, 3837 Name => New_Occurrence_Of (Pos, Loc), 3838 Expression => 3839 Make_Op_Add (Loc, 3840 Left_Opnd => New_Occurrence_Of (Pos, Loc), 3841 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 3842 3843 for J in 1 .. Dims loop 3844 3845 Append_To (Stats, 3846 Make_Assignment_Statement (Loc, 3847 Name => 3848 Make_Slice (Loc, 3849 Prefix => New_Occurrence_Of (Res, Loc), 3850 Discrete_Range => 3851 Make_Range (Loc, 3852 Low_Bound => New_Occurrence_Of (Pos, Loc), 3853 High_Bound => 3854 Make_Op_Subtract (Loc, 3855 Left_Opnd => 3856 Make_Op_Add (Loc, 3857 Left_Opnd => New_Occurrence_Of (Pos, Loc), 3858 Right_Opnd => 3859 Make_Attribute_Reference (Loc, 3860 Attribute_Name => Name_Length, 3861 Prefix => 3862 New_Occurrence_Of (Temps (J), Loc), 3863 Expressions => 3864 New_List (Make_Integer_Literal (Loc, 1)))), 3865 Right_Opnd => Make_Integer_Literal (Loc, 1)))), 3866 3867 Expression => New_Occurrence_Of (Temps (J), Loc))); 3868 3869 if J < Dims then 3870 Append_To (Stats, 3871 Make_Assignment_Statement (Loc, 3872 Name => New_Occurrence_Of (Pos, Loc), 3873 Expression => 3874 Make_Op_Add (Loc, 3875 Left_Opnd => New_Occurrence_Of (Pos, Loc), 3876 Right_Opnd => 3877 Make_Attribute_Reference (Loc, 3878 Attribute_Name => Name_Length, 3879 Prefix => New_Occurrence_Of (Temps (J), Loc), 3880 Expressions => 3881 New_List (Make_Integer_Literal (Loc, 1)))))); 3882 3883 Set_Character_Literal_Name (Char_Code (Character'Pos (','))); 3884 3885 Append_To (Stats, 3886 Make_Assignment_Statement (Loc, 3887 Name => Make_Indexed_Component (Loc, 3888 Prefix => New_Occurrence_Of (Res, Loc), 3889 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 3890 Expression => 3891 Make_Character_Literal (Loc, 3892 Chars => Name_Find, 3893 Char_Literal_Value => UI_From_Int (Character'Pos (','))))); 3894 3895 Append_To (Stats, 3896 Make_Assignment_Statement (Loc, 3897 Name => New_Occurrence_Of (Pos, Loc), 3898 Expression => 3899 Make_Op_Add (Loc, 3900 Left_Opnd => New_Occurrence_Of (Pos, Loc), 3901 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 3902 end if; 3903 end loop; 3904 3905 Set_Character_Literal_Name (Char_Code (Character'Pos (')'))); 3906 3907 Append_To (Stats, 3908 Make_Assignment_Statement (Loc, 3909 Name => 3910 Make_Indexed_Component (Loc, 3911 Prefix => New_Occurrence_Of (Res, Loc), 3912 Expressions => New_List (New_Occurrence_Of (Len, Loc))), 3913 Expression => 3914 Make_Character_Literal (Loc, 3915 Chars => Name_Find, 3916 Char_Literal_Value => UI_From_Int (Character'Pos (')'))))); 3917 return Build_Task_Image_Function (Loc, Decls, Stats, Res); 3918 end Build_Task_Array_Image; 3919 3920 ---------------------------- 3921 -- Build_Task_Image_Decls -- 3922 ---------------------------- 3923 3924 function Build_Task_Image_Decls 3925 (Loc : Source_Ptr; 3926 Id_Ref : Node_Id; 3927 A_Type : Entity_Id; 3928 In_Init_Proc : Boolean := False) return List_Id 3929 is 3930 Decls : constant List_Id := New_List; 3931 T_Id : Entity_Id := Empty; 3932 Decl : Node_Id; 3933 Expr : Node_Id := Empty; 3934 Fun : Node_Id := Empty; 3935 Is_Dyn : constant Boolean := 3936 Nkind (Parent (Id_Ref)) = N_Assignment_Statement 3937 and then 3938 Nkind (Expression (Parent (Id_Ref))) = N_Allocator; 3939 3940 begin 3941 -- If Discard_Names or No_Implicit_Heap_Allocations are in effect, 3942 -- generate a dummy declaration only. 3943 3944 if Restriction_Active (No_Implicit_Heap_Allocations) 3945 or else Global_Discard_Names 3946 then 3947 T_Id := Make_Temporary (Loc, 'J'); 3948 Name_Len := 0; 3949 3950 return 3951 New_List ( 3952 Make_Object_Declaration (Loc, 3953 Defining_Identifier => T_Id, 3954 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 3955 Expression => 3956 Make_String_Literal (Loc, 3957 Strval => String_From_Name_Buffer))); 3958 3959 else 3960 if Nkind (Id_Ref) = N_Identifier 3961 or else Nkind (Id_Ref) = N_Defining_Identifier 3962 then 3963 -- For a simple variable, the image of the task is built from 3964 -- the name of the variable. To avoid possible conflict with the 3965 -- anonymous type created for a single protected object, add a 3966 -- numeric suffix. 3967 3968 T_Id := 3969 Make_Defining_Identifier (Loc, 3970 New_External_Name (Chars (Id_Ref), 'T', 1)); 3971 3972 Get_Name_String (Chars (Id_Ref)); 3973 3974 Expr := 3975 Make_String_Literal (Loc, 3976 Strval => String_From_Name_Buffer); 3977 3978 elsif Nkind (Id_Ref) = N_Selected_Component then 3979 T_Id := 3980 Make_Defining_Identifier (Loc, 3981 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T')); 3982 Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn); 3983 3984 elsif Nkind (Id_Ref) = N_Indexed_Component then 3985 T_Id := 3986 Make_Defining_Identifier (Loc, 3987 New_External_Name (Chars (A_Type), 'N')); 3988 3989 Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn); 3990 end if; 3991 end if; 3992 3993 if Present (Fun) then 3994 Append (Fun, Decls); 3995 Expr := Make_Function_Call (Loc, 3996 Name => New_Occurrence_Of (Defining_Entity (Fun), Loc)); 3997 3998 if not In_Init_Proc then 3999 Set_Uses_Sec_Stack (Defining_Entity (Fun)); 4000 end if; 4001 end if; 4002 4003 Decl := Make_Object_Declaration (Loc, 4004 Defining_Identifier => T_Id, 4005 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4006 Constant_Present => True, 4007 Expression => Expr); 4008 4009 Append (Decl, Decls); 4010 return Decls; 4011 end Build_Task_Image_Decls; 4012 4013 ------------------------------- 4014 -- Build_Task_Image_Function -- 4015 ------------------------------- 4016 4017 function Build_Task_Image_Function 4018 (Loc : Source_Ptr; 4019 Decls : List_Id; 4020 Stats : List_Id; 4021 Res : Entity_Id) return Node_Id 4022 is 4023 Spec : Node_Id; 4024 4025 begin 4026 Append_To (Stats, 4027 Make_Simple_Return_Statement (Loc, 4028 Expression => New_Occurrence_Of (Res, Loc))); 4029 4030 Spec := Make_Function_Specification (Loc, 4031 Defining_Unit_Name => Make_Temporary (Loc, 'F'), 4032 Result_Definition => New_Occurrence_Of (Standard_String, Loc)); 4033 4034 -- Calls to 'Image use the secondary stack, which must be cleaned up 4035 -- after the task name is built. 4036 4037 return Make_Subprogram_Body (Loc, 4038 Specification => Spec, 4039 Declarations => Decls, 4040 Handled_Statement_Sequence => 4041 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats)); 4042 end Build_Task_Image_Function; 4043 4044 ----------------------------- 4045 -- Build_Task_Image_Prefix -- 4046 ----------------------------- 4047 4048 procedure Build_Task_Image_Prefix 4049 (Loc : Source_Ptr; 4050 Len : out Entity_Id; 4051 Res : out Entity_Id; 4052 Pos : out Entity_Id; 4053 Prefix : Entity_Id; 4054 Sum : Node_Id; 4055 Decls : List_Id; 4056 Stats : List_Id) 4057 is 4058 begin 4059 Len := Make_Temporary (Loc, 'L', Sum); 4060 4061 Append_To (Decls, 4062 Make_Object_Declaration (Loc, 4063 Defining_Identifier => Len, 4064 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc), 4065 Expression => Sum)); 4066 4067 Res := Make_Temporary (Loc, 'R'); 4068 4069 Append_To (Decls, 4070 Make_Object_Declaration (Loc, 4071 Defining_Identifier => Res, 4072 Object_Definition => 4073 Make_Subtype_Indication (Loc, 4074 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 4075 Constraint => 4076 Make_Index_Or_Discriminant_Constraint (Loc, 4077 Constraints => 4078 New_List ( 4079 Make_Range (Loc, 4080 Low_Bound => Make_Integer_Literal (Loc, 1), 4081 High_Bound => New_Occurrence_Of (Len, Loc))))))); 4082 4083 -- Indicate that the result is an internal temporary, so it does not 4084 -- receive a bogus initialization when declaration is expanded. This 4085 -- is both efficient, and prevents anomalies in the handling of 4086 -- dynamic objects on the secondary stack. 4087 4088 Set_Is_Internal (Res); 4089 Pos := Make_Temporary (Loc, 'P'); 4090 4091 Append_To (Decls, 4092 Make_Object_Declaration (Loc, 4093 Defining_Identifier => Pos, 4094 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc))); 4095 4096 -- Pos := Prefix'Length; 4097 4098 Append_To (Stats, 4099 Make_Assignment_Statement (Loc, 4100 Name => New_Occurrence_Of (Pos, Loc), 4101 Expression => 4102 Make_Attribute_Reference (Loc, 4103 Attribute_Name => Name_Length, 4104 Prefix => New_Occurrence_Of (Prefix, Loc), 4105 Expressions => New_List (Make_Integer_Literal (Loc, 1))))); 4106 4107 -- Res (1 .. Pos) := Prefix; 4108 4109 Append_To (Stats, 4110 Make_Assignment_Statement (Loc, 4111 Name => 4112 Make_Slice (Loc, 4113 Prefix => New_Occurrence_Of (Res, Loc), 4114 Discrete_Range => 4115 Make_Range (Loc, 4116 Low_Bound => Make_Integer_Literal (Loc, 1), 4117 High_Bound => New_Occurrence_Of (Pos, Loc))), 4118 4119 Expression => New_Occurrence_Of (Prefix, Loc))); 4120 4121 Append_To (Stats, 4122 Make_Assignment_Statement (Loc, 4123 Name => New_Occurrence_Of (Pos, Loc), 4124 Expression => 4125 Make_Op_Add (Loc, 4126 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4127 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4128 end Build_Task_Image_Prefix; 4129 4130 ----------------------------- 4131 -- Build_Task_Record_Image -- 4132 ----------------------------- 4133 4134 function Build_Task_Record_Image 4135 (Loc : Source_Ptr; 4136 Id_Ref : Node_Id; 4137 Dyn : Boolean := False) return Node_Id 4138 is 4139 Len : Entity_Id; 4140 -- Total length of generated name 4141 4142 Pos : Entity_Id; 4143 -- Index into result 4144 4145 Res : Entity_Id; 4146 -- String to hold result 4147 4148 Pref : constant Entity_Id := Make_Temporary (Loc, 'P'); 4149 -- Name of enclosing variable, prefix of resulting name 4150 4151 Sum : Node_Id; 4152 -- Expression to compute total size of string 4153 4154 Sel : Entity_Id; 4155 -- Entity for selector name 4156 4157 Decls : constant List_Id := New_List; 4158 Stats : constant List_Id := New_List; 4159 4160 begin 4161 -- For a dynamic task, the name comes from the target variable. For a 4162 -- static one it is a formal of the enclosing init proc. 4163 4164 if Dyn then 4165 Get_Name_String (Chars (Entity (Prefix (Id_Ref)))); 4166 Append_To (Decls, 4167 Make_Object_Declaration (Loc, 4168 Defining_Identifier => Pref, 4169 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4170 Expression => 4171 Make_String_Literal (Loc, 4172 Strval => String_From_Name_Buffer))); 4173 4174 else 4175 Append_To (Decls, 4176 Make_Object_Renaming_Declaration (Loc, 4177 Defining_Identifier => Pref, 4178 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 4179 Name => Make_Identifier (Loc, Name_uTask_Name))); 4180 end if; 4181 4182 Sel := Make_Temporary (Loc, 'S'); 4183 4184 Get_Name_String (Chars (Selector_Name (Id_Ref))); 4185 4186 Append_To (Decls, 4187 Make_Object_Declaration (Loc, 4188 Defining_Identifier => Sel, 4189 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4190 Expression => 4191 Make_String_Literal (Loc, 4192 Strval => String_From_Name_Buffer))); 4193 4194 Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1)); 4195 4196 Sum := 4197 Make_Op_Add (Loc, 4198 Left_Opnd => Sum, 4199 Right_Opnd => 4200 Make_Attribute_Reference (Loc, 4201 Attribute_Name => Name_Length, 4202 Prefix => 4203 New_Occurrence_Of (Pref, Loc), 4204 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 4205 4206 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats); 4207 4208 Set_Character_Literal_Name (Char_Code (Character'Pos ('.'))); 4209 4210 -- Res (Pos) := '.'; 4211 4212 Append_To (Stats, 4213 Make_Assignment_Statement (Loc, 4214 Name => Make_Indexed_Component (Loc, 4215 Prefix => New_Occurrence_Of (Res, Loc), 4216 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 4217 Expression => 4218 Make_Character_Literal (Loc, 4219 Chars => Name_Find, 4220 Char_Literal_Value => 4221 UI_From_Int (Character'Pos ('.'))))); 4222 4223 Append_To (Stats, 4224 Make_Assignment_Statement (Loc, 4225 Name => New_Occurrence_Of (Pos, Loc), 4226 Expression => 4227 Make_Op_Add (Loc, 4228 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4229 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4230 4231 -- Res (Pos .. Len) := Selector; 4232 4233 Append_To (Stats, 4234 Make_Assignment_Statement (Loc, 4235 Name => Make_Slice (Loc, 4236 Prefix => New_Occurrence_Of (Res, Loc), 4237 Discrete_Range => 4238 Make_Range (Loc, 4239 Low_Bound => New_Occurrence_Of (Pos, Loc), 4240 High_Bound => New_Occurrence_Of (Len, Loc))), 4241 Expression => New_Occurrence_Of (Sel, Loc))); 4242 4243 return Build_Task_Image_Function (Loc, Decls, Stats, Res); 4244 end Build_Task_Record_Image; 4245 4246 --------------------------------------- 4247 -- Build_Transient_Object_Statements -- 4248 --------------------------------------- 4249 4250 procedure Build_Transient_Object_Statements 4251 (Obj_Decl : Node_Id; 4252 Fin_Call : out Node_Id; 4253 Hook_Assign : out Node_Id; 4254 Hook_Clear : out Node_Id; 4255 Hook_Decl : out Node_Id; 4256 Ptr_Decl : out Node_Id; 4257 Finalize_Obj : Boolean := True) 4258 is 4259 Loc : constant Source_Ptr := Sloc (Obj_Decl); 4260 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl); 4261 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 4262 4263 Desig_Typ : Entity_Id; 4264 Hook_Expr : Node_Id; 4265 Hook_Id : Entity_Id; 4266 Obj_Ref : Node_Id; 4267 Ptr_Typ : Entity_Id; 4268 4269 begin 4270 -- Recover the type of the object 4271 4272 Desig_Typ := Obj_Typ; 4273 4274 if Is_Access_Type (Desig_Typ) then 4275 Desig_Typ := Available_View (Designated_Type (Desig_Typ)); 4276 end if; 4277 4278 -- Create an access type which provides a reference to the transient 4279 -- object. Generate: 4280 4281 -- type Ptr_Typ is access all Desig_Typ; 4282 4283 Ptr_Typ := Make_Temporary (Loc, 'A'); 4284 Set_Ekind (Ptr_Typ, E_General_Access_Type); 4285 Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ); 4286 4287 Ptr_Decl := 4288 Make_Full_Type_Declaration (Loc, 4289 Defining_Identifier => Ptr_Typ, 4290 Type_Definition => 4291 Make_Access_To_Object_Definition (Loc, 4292 All_Present => True, 4293 Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc))); 4294 4295 -- Create a temporary check which acts as a hook to the transient 4296 -- object. Generate: 4297 4298 -- Hook : Ptr_Typ := null; 4299 4300 Hook_Id := Make_Temporary (Loc, 'T'); 4301 Set_Ekind (Hook_Id, E_Variable); 4302 Set_Etype (Hook_Id, Ptr_Typ); 4303 4304 Hook_Decl := 4305 Make_Object_Declaration (Loc, 4306 Defining_Identifier => Hook_Id, 4307 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc), 4308 Expression => Make_Null (Loc)); 4309 4310 -- Mark the temporary as a hook. This signals the machinery in 4311 -- Build_Finalizer to recognize this special case. 4312 4313 Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl); 4314 4315 -- Hook the transient object to the temporary. Generate: 4316 4317 -- Hook := Ptr_Typ (Obj_Id); 4318 -- <or> 4319 -- Hool := Obj_Id'Unrestricted_Access; 4320 4321 if Is_Access_Type (Obj_Typ) then 4322 Hook_Expr := 4323 Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc)); 4324 else 4325 Hook_Expr := 4326 Make_Attribute_Reference (Loc, 4327 Prefix => New_Occurrence_Of (Obj_Id, Loc), 4328 Attribute_Name => Name_Unrestricted_Access); 4329 end if; 4330 4331 Hook_Assign := 4332 Make_Assignment_Statement (Loc, 4333 Name => New_Occurrence_Of (Hook_Id, Loc), 4334 Expression => Hook_Expr); 4335 4336 -- Crear the hook prior to finalizing the object. Generate: 4337 4338 -- Hook := null; 4339 4340 Hook_Clear := 4341 Make_Assignment_Statement (Loc, 4342 Name => New_Occurrence_Of (Hook_Id, Loc), 4343 Expression => Make_Null (Loc)); 4344 4345 -- Finalize the object. Generate: 4346 4347 -- [Deep_]Finalize (Obj_Ref[.all]); 4348 4349 if Finalize_Obj then 4350 Obj_Ref := New_Occurrence_Of (Obj_Id, Loc); 4351 4352 if Is_Access_Type (Obj_Typ) then 4353 Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref); 4354 Set_Etype (Obj_Ref, Desig_Typ); 4355 end if; 4356 4357 Fin_Call := 4358 Make_Final_Call 4359 (Obj_Ref => Obj_Ref, 4360 Typ => Desig_Typ); 4361 4362 -- Otherwise finalize the hook. Generate: 4363 4364 -- [Deep_]Finalize (Hook.all); 4365 4366 else 4367 Fin_Call := 4368 Make_Final_Call ( 4369 Obj_Ref => 4370 Make_Explicit_Dereference (Loc, 4371 Prefix => New_Occurrence_Of (Hook_Id, Loc)), 4372 Typ => Desig_Typ); 4373 end if; 4374 end Build_Transient_Object_Statements; 4375 4376 ----------------------------- 4377 -- Check_Float_Op_Overflow -- 4378 ----------------------------- 4379 4380 procedure Check_Float_Op_Overflow (N : Node_Id) is 4381 begin 4382 -- Return if no check needed 4383 4384 if not Is_Floating_Point_Type (Etype (N)) 4385 or else not (Do_Overflow_Check (N) and then Check_Float_Overflow) 4386 4387 -- In CodePeer_Mode, rely on the overflow check flag being set instead 4388 -- and do not expand the code for float overflow checking. 4389 4390 or else CodePeer_Mode 4391 then 4392 return; 4393 end if; 4394 4395 -- Otherwise we replace the expression by 4396 4397 -- do Tnn : constant ftype := expression; 4398 -- constraint_error when not Tnn'Valid; 4399 -- in Tnn; 4400 4401 declare 4402 Loc : constant Source_Ptr := Sloc (N); 4403 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N); 4404 Typ : constant Entity_Id := Etype (N); 4405 4406 begin 4407 -- Turn off the Do_Overflow_Check flag, since we are doing that work 4408 -- right here. We also set the node as analyzed to prevent infinite 4409 -- recursion from repeating the operation in the expansion. 4410 4411 Set_Do_Overflow_Check (N, False); 4412 Set_Analyzed (N, True); 4413 4414 -- Do the rewrite to include the check 4415 4416 Rewrite (N, 4417 Make_Expression_With_Actions (Loc, 4418 Actions => New_List ( 4419 Make_Object_Declaration (Loc, 4420 Defining_Identifier => Tnn, 4421 Object_Definition => New_Occurrence_Of (Typ, Loc), 4422 Constant_Present => True, 4423 Expression => Relocate_Node (N)), 4424 Make_Raise_Constraint_Error (Loc, 4425 Condition => 4426 Make_Op_Not (Loc, 4427 Right_Opnd => 4428 Make_Attribute_Reference (Loc, 4429 Prefix => New_Occurrence_Of (Tnn, Loc), 4430 Attribute_Name => Name_Valid)), 4431 Reason => CE_Overflow_Check_Failed)), 4432 Expression => New_Occurrence_Of (Tnn, Loc))); 4433 4434 Analyze_And_Resolve (N, Typ); 4435 end; 4436 end Check_Float_Op_Overflow; 4437 4438 ---------------------------------- 4439 -- Component_May_Be_Bit_Aligned -- 4440 ---------------------------------- 4441 4442 function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is 4443 UT : Entity_Id; 4444 4445 begin 4446 -- If no component clause, then everything is fine, since the back end 4447 -- never bit-misaligns by default, even if there is a pragma Packed for 4448 -- the record. 4449 4450 if No (Comp) or else No (Component_Clause (Comp)) then 4451 return False; 4452 end if; 4453 4454 UT := Underlying_Type (Etype (Comp)); 4455 4456 -- It is only array and record types that cause trouble 4457 4458 if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then 4459 return False; 4460 4461 -- If we know that we have a small (64 bits or less) record or small 4462 -- bit-packed array, then everything is fine, since the back end can 4463 -- handle these cases correctly. 4464 4465 elsif Esize (Comp) <= 64 4466 and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT)) 4467 then 4468 return False; 4469 4470 -- Otherwise if the component is not byte aligned, we know we have the 4471 -- nasty unaligned case. 4472 4473 elsif Normalized_First_Bit (Comp) /= Uint_0 4474 or else Esize (Comp) mod System_Storage_Unit /= Uint_0 4475 then 4476 return True; 4477 4478 -- If we are large and byte aligned, then OK at this level 4479 4480 else 4481 return False; 4482 end if; 4483 end Component_May_Be_Bit_Aligned; 4484 4485 ---------------------------------------- 4486 -- Containing_Package_With_Ext_Axioms -- 4487 ---------------------------------------- 4488 4489 function Containing_Package_With_Ext_Axioms 4490 (E : Entity_Id) return Entity_Id 4491 is 4492 begin 4493 -- E is the package or generic package which is externally axiomatized 4494 4495 if Ekind_In (E, E_Generic_Package, E_Package) 4496 and then Has_Annotate_Pragma_For_External_Axiomatization (E) 4497 then 4498 return E; 4499 end if; 4500 4501 -- If E's scope is axiomatized, E is axiomatized 4502 4503 if Present (Scope (E)) then 4504 declare 4505 First_Ax_Parent_Scope : constant Entity_Id := 4506 Containing_Package_With_Ext_Axioms (Scope (E)); 4507 begin 4508 if Present (First_Ax_Parent_Scope) then 4509 return First_Ax_Parent_Scope; 4510 end if; 4511 end; 4512 end if; 4513 4514 -- Otherwise, if E is a package instance, it is axiomatized if the 4515 -- corresponding generic package is axiomatized. 4516 4517 if Ekind (E) = E_Package then 4518 declare 4519 Par : constant Node_Id := Parent (E); 4520 Decl : Node_Id; 4521 4522 begin 4523 if Nkind (Par) = N_Defining_Program_Unit_Name then 4524 Decl := Parent (Par); 4525 else 4526 Decl := Par; 4527 end if; 4528 4529 if Present (Generic_Parent (Decl)) then 4530 return 4531 Containing_Package_With_Ext_Axioms (Generic_Parent (Decl)); 4532 end if; 4533 end; 4534 end if; 4535 4536 return Empty; 4537 end Containing_Package_With_Ext_Axioms; 4538 4539 ------------------------------- 4540 -- Convert_To_Actual_Subtype -- 4541 ------------------------------- 4542 4543 procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is 4544 Act_ST : Entity_Id; 4545 4546 begin 4547 Act_ST := Get_Actual_Subtype (Exp); 4548 4549 if Act_ST = Etype (Exp) then 4550 return; 4551 else 4552 Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp))); 4553 Analyze_And_Resolve (Exp, Act_ST); 4554 end if; 4555 end Convert_To_Actual_Subtype; 4556 4557 ----------------------------------- 4558 -- Corresponding_Runtime_Package -- 4559 ----------------------------------- 4560 4561 function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is 4562 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean; 4563 -- Return True if protected type T has one entry and the maximum queue 4564 -- length is one. 4565 4566 -------------------------------- 4567 -- Has_One_Entry_And_No_Queue -- 4568 -------------------------------- 4569 4570 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is 4571 Item : Entity_Id; 4572 Is_First : Boolean := True; 4573 4574 begin 4575 Item := First_Entity (T); 4576 while Present (Item) loop 4577 if Is_Entry (Item) then 4578 4579 -- The protected type has more than one entry 4580 4581 if not Is_First then 4582 return False; 4583 end if; 4584 4585 -- The queue length is not one 4586 4587 if not Restriction_Active (No_Entry_Queue) 4588 and then Get_Max_Queue_Length (Item) /= Uint_1 4589 then 4590 return False; 4591 end if; 4592 4593 Is_First := False; 4594 end if; 4595 4596 Next_Entity (Item); 4597 end loop; 4598 4599 return True; 4600 end Has_One_Entry_And_No_Queue; 4601 4602 -- Local variables 4603 4604 Pkg_Id : RTU_Id := RTU_Null; 4605 4606 -- Start of processing for Corresponding_Runtime_Package 4607 4608 begin 4609 pragma Assert (Is_Concurrent_Type (Typ)); 4610 4611 if Ekind (Typ) in Protected_Kind then 4612 if Has_Entries (Typ) 4613 4614 -- A protected type without entries that covers an interface and 4615 -- overrides the abstract routines with protected procedures is 4616 -- considered equivalent to a protected type with entries in the 4617 -- context of dispatching select statements. It is sufficient to 4618 -- check for the presence of an interface list in the declaration 4619 -- node to recognize this case. 4620 4621 or else Present (Interface_List (Parent (Typ))) 4622 4623 -- Protected types with interrupt handlers (when not using a 4624 -- restricted profile) are also considered equivalent to 4625 -- protected types with entries. The types which are used 4626 -- (Static_Interrupt_Protection and Dynamic_Interrupt_Protection) 4627 -- are derived from Protection_Entries. 4628 4629 or else (Has_Attach_Handler (Typ) and then not Restricted_Profile) 4630 or else Has_Interrupt_Handler (Typ) 4631 then 4632 if Abort_Allowed 4633 or else Restriction_Active (No_Select_Statements) = False 4634 or else not Has_One_Entry_And_No_Queue (Typ) 4635 or else (Has_Attach_Handler (Typ) 4636 and then not Restricted_Profile) 4637 then 4638 Pkg_Id := System_Tasking_Protected_Objects_Entries; 4639 else 4640 Pkg_Id := System_Tasking_Protected_Objects_Single_Entry; 4641 end if; 4642 4643 else 4644 Pkg_Id := System_Tasking_Protected_Objects; 4645 end if; 4646 end if; 4647 4648 return Pkg_Id; 4649 end Corresponding_Runtime_Package; 4650 4651 ----------------------------------- 4652 -- Current_Sem_Unit_Declarations -- 4653 ----------------------------------- 4654 4655 function Current_Sem_Unit_Declarations return List_Id is 4656 U : Node_Id := Unit (Cunit (Current_Sem_Unit)); 4657 Decls : List_Id; 4658 4659 begin 4660 -- If the current unit is a package body, locate the visible 4661 -- declarations of the package spec. 4662 4663 if Nkind (U) = N_Package_Body then 4664 U := Unit (Library_Unit (Cunit (Current_Sem_Unit))); 4665 end if; 4666 4667 if Nkind (U) = N_Package_Declaration then 4668 U := Specification (U); 4669 Decls := Visible_Declarations (U); 4670 4671 if No (Decls) then 4672 Decls := New_List; 4673 Set_Visible_Declarations (U, Decls); 4674 end if; 4675 4676 else 4677 Decls := Declarations (U); 4678 4679 if No (Decls) then 4680 Decls := New_List; 4681 Set_Declarations (U, Decls); 4682 end if; 4683 end if; 4684 4685 return Decls; 4686 end Current_Sem_Unit_Declarations; 4687 4688 ----------------------- 4689 -- Duplicate_Subexpr -- 4690 ----------------------- 4691 4692 function Duplicate_Subexpr 4693 (Exp : Node_Id; 4694 Name_Req : Boolean := False; 4695 Renaming_Req : Boolean := False) return Node_Id 4696 is 4697 begin 4698 Remove_Side_Effects (Exp, Name_Req, Renaming_Req); 4699 return New_Copy_Tree (Exp); 4700 end Duplicate_Subexpr; 4701 4702 --------------------------------- 4703 -- Duplicate_Subexpr_No_Checks -- 4704 --------------------------------- 4705 4706 function Duplicate_Subexpr_No_Checks 4707 (Exp : Node_Id; 4708 Name_Req : Boolean := False; 4709 Renaming_Req : Boolean := False; 4710 Related_Id : Entity_Id := Empty; 4711 Is_Low_Bound : Boolean := False; 4712 Is_High_Bound : Boolean := False) return Node_Id 4713 is 4714 New_Exp : Node_Id; 4715 4716 begin 4717 Remove_Side_Effects 4718 (Exp => Exp, 4719 Name_Req => Name_Req, 4720 Renaming_Req => Renaming_Req, 4721 Related_Id => Related_Id, 4722 Is_Low_Bound => Is_Low_Bound, 4723 Is_High_Bound => Is_High_Bound); 4724 4725 New_Exp := New_Copy_Tree (Exp); 4726 Remove_Checks (New_Exp); 4727 return New_Exp; 4728 end Duplicate_Subexpr_No_Checks; 4729 4730 ----------------------------------- 4731 -- Duplicate_Subexpr_Move_Checks -- 4732 ----------------------------------- 4733 4734 function Duplicate_Subexpr_Move_Checks 4735 (Exp : Node_Id; 4736 Name_Req : Boolean := False; 4737 Renaming_Req : Boolean := False) return Node_Id 4738 is 4739 New_Exp : Node_Id; 4740 4741 begin 4742 Remove_Side_Effects (Exp, Name_Req, Renaming_Req); 4743 New_Exp := New_Copy_Tree (Exp); 4744 Remove_Checks (Exp); 4745 return New_Exp; 4746 end Duplicate_Subexpr_Move_Checks; 4747 4748 ------------------------- 4749 -- Enclosing_Init_Proc -- 4750 ------------------------- 4751 4752 function Enclosing_Init_Proc return Entity_Id is 4753 S : Entity_Id; 4754 4755 begin 4756 S := Current_Scope; 4757 while Present (S) and then S /= Standard_Standard loop 4758 if Is_Init_Proc (S) then 4759 return S; 4760 else 4761 S := Scope (S); 4762 end if; 4763 end loop; 4764 4765 return Empty; 4766 end Enclosing_Init_Proc; 4767 4768 -------------------- 4769 -- Ensure_Defined -- 4770 -------------------- 4771 4772 procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is 4773 IR : Node_Id; 4774 4775 begin 4776 -- An itype reference must only be created if this is a local itype, so 4777 -- that gigi can elaborate it on the proper objstack. 4778 4779 if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then 4780 IR := Make_Itype_Reference (Sloc (N)); 4781 Set_Itype (IR, Typ); 4782 Insert_Action (N, IR); 4783 end if; 4784 end Ensure_Defined; 4785 4786 -------------------- 4787 -- Entry_Names_OK -- 4788 -------------------- 4789 4790 function Entry_Names_OK return Boolean is 4791 begin 4792 return 4793 not Restricted_Profile 4794 and then not Global_Discard_Names 4795 and then not Restriction_Active (No_Implicit_Heap_Allocations) 4796 and then not Restriction_Active (No_Local_Allocators); 4797 end Entry_Names_OK; 4798 4799 ------------------- 4800 -- Evaluate_Name -- 4801 ------------------- 4802 4803 procedure Evaluate_Name (Nam : Node_Id) is 4804 begin 4805 -- For an attribute reference or an indexed component, evaluate the 4806 -- prefix, which is itself a name, recursively, and then force the 4807 -- evaluation of all the subscripts (or attribute expressions). 4808 4809 case Nkind (Nam) is 4810 when N_Attribute_Reference 4811 | N_Indexed_Component 4812 => 4813 Evaluate_Name (Prefix (Nam)); 4814 4815 declare 4816 E : Node_Id; 4817 4818 begin 4819 E := First (Expressions (Nam)); 4820 while Present (E) loop 4821 Force_Evaluation (E); 4822 4823 if Is_Rewrite_Substitution (E) then 4824 Set_Do_Range_Check 4825 (E, Do_Range_Check (Original_Node (E))); 4826 end if; 4827 4828 Next (E); 4829 end loop; 4830 end; 4831 4832 -- For an explicit dereference, we simply force the evaluation of 4833 -- the name expression. The dereference provides a value that is the 4834 -- address for the renamed object, and it is precisely this value 4835 -- that we want to preserve. 4836 4837 when N_Explicit_Dereference => 4838 Force_Evaluation (Prefix (Nam)); 4839 4840 -- For a function call, we evaluate the call 4841 4842 when N_Function_Call => 4843 Force_Evaluation (Nam); 4844 4845 -- For a qualified expression, we evaluate the underlying object 4846 -- name if any, otherwise we force the evaluation of the underlying 4847 -- expression. 4848 4849 when N_Qualified_Expression => 4850 if Is_Object_Reference (Expression (Nam)) then 4851 Evaluate_Name (Expression (Nam)); 4852 else 4853 Force_Evaluation (Expression (Nam)); 4854 end if; 4855 4856 -- For a selected component, we simply evaluate the prefix 4857 4858 when N_Selected_Component => 4859 Evaluate_Name (Prefix (Nam)); 4860 4861 -- For a slice, we evaluate the prefix, as for the indexed component 4862 -- case and then, if there is a range present, either directly or as 4863 -- the constraint of a discrete subtype indication, we evaluate the 4864 -- two bounds of this range. 4865 4866 when N_Slice => 4867 Evaluate_Name (Prefix (Nam)); 4868 Evaluate_Slice_Bounds (Nam); 4869 4870 -- For a type conversion, the expression of the conversion must be 4871 -- the name of an object, and we simply need to evaluate this name. 4872 4873 when N_Type_Conversion => 4874 Evaluate_Name (Expression (Nam)); 4875 4876 -- The remaining cases are direct name, operator symbol and character 4877 -- literal. In all these cases, we do nothing, since we want to 4878 -- reevaluate each time the renamed object is used. 4879 4880 when others => 4881 null; 4882 end case; 4883 end Evaluate_Name; 4884 4885 --------------------------- 4886 -- Evaluate_Slice_Bounds -- 4887 --------------------------- 4888 4889 procedure Evaluate_Slice_Bounds (Slice : Node_Id) is 4890 DR : constant Node_Id := Discrete_Range (Slice); 4891 Constr : Node_Id; 4892 Rexpr : Node_Id; 4893 4894 begin 4895 if Nkind (DR) = N_Range then 4896 Force_Evaluation (Low_Bound (DR)); 4897 Force_Evaluation (High_Bound (DR)); 4898 4899 elsif Nkind (DR) = N_Subtype_Indication then 4900 Constr := Constraint (DR); 4901 4902 if Nkind (Constr) = N_Range_Constraint then 4903 Rexpr := Range_Expression (Constr); 4904 4905 Force_Evaluation (Low_Bound (Rexpr)); 4906 Force_Evaluation (High_Bound (Rexpr)); 4907 end if; 4908 end if; 4909 end Evaluate_Slice_Bounds; 4910 4911 --------------------- 4912 -- Evolve_And_Then -- 4913 --------------------- 4914 4915 procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is 4916 begin 4917 if No (Cond) then 4918 Cond := Cond1; 4919 else 4920 Cond := 4921 Make_And_Then (Sloc (Cond1), 4922 Left_Opnd => Cond, 4923 Right_Opnd => Cond1); 4924 end if; 4925 end Evolve_And_Then; 4926 4927 -------------------- 4928 -- Evolve_Or_Else -- 4929 -------------------- 4930 4931 procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is 4932 begin 4933 if No (Cond) then 4934 Cond := Cond1; 4935 else 4936 Cond := 4937 Make_Or_Else (Sloc (Cond1), 4938 Left_Opnd => Cond, 4939 Right_Opnd => Cond1); 4940 end if; 4941 end Evolve_Or_Else; 4942 4943 ------------------- 4944 -- Exceptions_OK -- 4945 ------------------- 4946 4947 function Exceptions_OK return Boolean is 4948 begin 4949 return 4950 not (Restriction_Active (No_Exception_Handlers) or else 4951 Restriction_Active (No_Exception_Propagation) or else 4952 Restriction_Active (No_Exceptions)); 4953 end Exceptions_OK; 4954 4955 ----------------------------------------- 4956 -- Expand_Static_Predicates_In_Choices -- 4957 ----------------------------------------- 4958 4959 procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is 4960 pragma Assert (Nkind_In (N, N_Case_Statement_Alternative, N_Variant)); 4961 4962 Choices : constant List_Id := Discrete_Choices (N); 4963 4964 Choice : Node_Id; 4965 Next_C : Node_Id; 4966 P : Node_Id; 4967 C : Node_Id; 4968 4969 begin 4970 Choice := First (Choices); 4971 while Present (Choice) loop 4972 Next_C := Next (Choice); 4973 4974 -- Check for name of subtype with static predicate 4975 4976 if Is_Entity_Name (Choice) 4977 and then Is_Type (Entity (Choice)) 4978 and then Has_Predicates (Entity (Choice)) 4979 then 4980 -- Loop through entries in predicate list, converting to choices 4981 -- and inserting in the list before the current choice. Note that 4982 -- if the list is empty, corresponding to a False predicate, then 4983 -- no choices are inserted. 4984 4985 P := First (Static_Discrete_Predicate (Entity (Choice))); 4986 while Present (P) loop 4987 4988 -- If low bound and high bounds are equal, copy simple choice 4989 4990 if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then 4991 C := New_Copy (Low_Bound (P)); 4992 4993 -- Otherwise copy a range 4994 4995 else 4996 C := New_Copy (P); 4997 end if; 4998 4999 -- Change Sloc to referencing choice (rather than the Sloc of 5000 -- the predicate declaration element itself). 5001 5002 Set_Sloc (C, Sloc (Choice)); 5003 Insert_Before (Choice, C); 5004 Next (P); 5005 end loop; 5006 5007 -- Delete the predicated entry 5008 5009 Remove (Choice); 5010 end if; 5011 5012 -- Move to next choice to check 5013 5014 Choice := Next_C; 5015 end loop; 5016 5017 Set_Has_SP_Choice (N, False); 5018 end Expand_Static_Predicates_In_Choices; 5019 5020 ------------------------------ 5021 -- Expand_Subtype_From_Expr -- 5022 ------------------------------ 5023 5024 -- This function is applicable for both static and dynamic allocation of 5025 -- objects which are constrained by an initial expression. Basically it 5026 -- transforms an unconstrained subtype indication into a constrained one. 5027 5028 -- The expression may also be transformed in certain cases in order to 5029 -- avoid multiple evaluation. In the static allocation case, the general 5030 -- scheme is: 5031 5032 -- Val : T := Expr; 5033 5034 -- is transformed into 5035 5036 -- Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr; 5037 -- 5038 -- Here are the main cases : 5039 -- 5040 -- <if Expr is a Slice> 5041 -- Val : T ([Index_Subtype (Expr)]) := Expr; 5042 -- 5043 -- <elsif Expr is a String Literal> 5044 -- Val : T (T'First .. T'First + Length (string literal) - 1) := Expr; 5045 -- 5046 -- <elsif Expr is Constrained> 5047 -- subtype T is Type_Of_Expr 5048 -- Val : T := Expr; 5049 -- 5050 -- <elsif Expr is an entity_name> 5051 -- Val : T (constraints taken from Expr) := Expr; 5052 -- 5053 -- <else> 5054 -- type Axxx is access all T; 5055 -- Rval : Axxx := Expr'ref; 5056 -- Val : T (constraints taken from Rval) := Rval.all; 5057 5058 -- ??? note: when the Expression is allocated in the secondary stack 5059 -- we could use it directly instead of copying it by declaring 5060 -- Val : T (...) renames Rval.all 5061 5062 procedure Expand_Subtype_From_Expr 5063 (N : Node_Id; 5064 Unc_Type : Entity_Id; 5065 Subtype_Indic : Node_Id; 5066 Exp : Node_Id; 5067 Related_Id : Entity_Id := Empty) 5068 is 5069 Loc : constant Source_Ptr := Sloc (N); 5070 Exp_Typ : constant Entity_Id := Etype (Exp); 5071 T : Entity_Id; 5072 5073 begin 5074 -- In general we cannot build the subtype if expansion is disabled, 5075 -- because internal entities may not have been defined. However, to 5076 -- avoid some cascaded errors, we try to continue when the expression is 5077 -- an array (or string), because it is safe to compute the bounds. It is 5078 -- in fact required to do so even in a generic context, because there 5079 -- may be constants that depend on the bounds of a string literal, both 5080 -- standard string types and more generally arrays of characters. 5081 5082 -- In GNATprove mode, these extra subtypes are not needed 5083 5084 if GNATprove_Mode then 5085 return; 5086 end if; 5087 5088 if not Expander_Active 5089 and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp))) 5090 then 5091 return; 5092 end if; 5093 5094 if Nkind (Exp) = N_Slice then 5095 declare 5096 Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ)); 5097 5098 begin 5099 Rewrite (Subtype_Indic, 5100 Make_Subtype_Indication (Loc, 5101 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc), 5102 Constraint => 5103 Make_Index_Or_Discriminant_Constraint (Loc, 5104 Constraints => New_List 5105 (New_Occurrence_Of (Slice_Type, Loc))))); 5106 5107 -- This subtype indication may be used later for constraint checks 5108 -- we better make sure that if a variable was used as a bound of 5109 -- of the original slice, its value is frozen. 5110 5111 Evaluate_Slice_Bounds (Exp); 5112 end; 5113 5114 elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then 5115 Rewrite (Subtype_Indic, 5116 Make_Subtype_Indication (Loc, 5117 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc), 5118 Constraint => 5119 Make_Index_Or_Discriminant_Constraint (Loc, 5120 Constraints => New_List ( 5121 Make_Literal_Range (Loc, 5122 Literal_Typ => Exp_Typ))))); 5123 5124 -- If the type of the expression is an internally generated type it 5125 -- may not be necessary to create a new subtype. However there are two 5126 -- exceptions: references to the current instances, and aliased array 5127 -- object declarations for which the back end has to create a template. 5128 5129 elsif Is_Constrained (Exp_Typ) 5130 and then not Is_Class_Wide_Type (Unc_Type) 5131 and then 5132 (Nkind (N) /= N_Object_Declaration 5133 or else not Is_Entity_Name (Expression (N)) 5134 or else not Comes_From_Source (Entity (Expression (N))) 5135 or else not Is_Array_Type (Exp_Typ) 5136 or else not Aliased_Present (N)) 5137 then 5138 if Is_Itype (Exp_Typ) then 5139 5140 -- Within an initialization procedure, a selected component 5141 -- denotes a component of the enclosing record, and it appears as 5142 -- an actual in a call to its own initialization procedure. If 5143 -- this component depends on the outer discriminant, we must 5144 -- generate the proper actual subtype for it. 5145 5146 if Nkind (Exp) = N_Selected_Component 5147 and then Within_Init_Proc 5148 then 5149 declare 5150 Decl : constant Node_Id := 5151 Build_Actual_Subtype_Of_Component (Exp_Typ, Exp); 5152 begin 5153 if Present (Decl) then 5154 Insert_Action (N, Decl); 5155 T := Defining_Identifier (Decl); 5156 else 5157 T := Exp_Typ; 5158 end if; 5159 end; 5160 5161 -- No need to generate a new subtype 5162 5163 else 5164 T := Exp_Typ; 5165 end if; 5166 5167 else 5168 T := Make_Temporary (Loc, 'T'); 5169 5170 Insert_Action (N, 5171 Make_Subtype_Declaration (Loc, 5172 Defining_Identifier => T, 5173 Subtype_Indication => New_Occurrence_Of (Exp_Typ, Loc))); 5174 5175 -- This type is marked as an itype even though it has an explicit 5176 -- declaration since otherwise Is_Generic_Actual_Type can get 5177 -- set, resulting in the generation of spurious errors. (See 5178 -- sem_ch8.Analyze_Package_Renaming and sem_type.covers) 5179 5180 Set_Is_Itype (T); 5181 Set_Associated_Node_For_Itype (T, Exp); 5182 end if; 5183 5184 Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc)); 5185 5186 -- Nothing needs to be done for private types with unknown discriminants 5187 -- if the underlying type is not an unconstrained composite type or it 5188 -- is an unchecked union. 5189 5190 elsif Is_Private_Type (Unc_Type) 5191 and then Has_Unknown_Discriminants (Unc_Type) 5192 and then (not Is_Composite_Type (Underlying_Type (Unc_Type)) 5193 or else Is_Constrained (Underlying_Type (Unc_Type)) 5194 or else Is_Unchecked_Union (Underlying_Type (Unc_Type))) 5195 then 5196 null; 5197 5198 -- Case of derived type with unknown discriminants where the parent type 5199 -- also has unknown discriminants. 5200 5201 elsif Is_Record_Type (Unc_Type) 5202 and then not Is_Class_Wide_Type (Unc_Type) 5203 and then Has_Unknown_Discriminants (Unc_Type) 5204 and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type)) 5205 then 5206 -- Nothing to be done if no underlying record view available 5207 5208 -- If this is a limited type derived from a type with unknown 5209 -- discriminants, do not expand either, so that subsequent expansion 5210 -- of the call can add build-in-place parameters to call. 5211 5212 if No (Underlying_Record_View (Unc_Type)) 5213 or else Is_Limited_Type (Unc_Type) 5214 then 5215 null; 5216 5217 -- Otherwise use the Underlying_Record_View to create the proper 5218 -- constrained subtype for an object of a derived type with unknown 5219 -- discriminants. 5220 5221 else 5222 Remove_Side_Effects (Exp); 5223 Rewrite (Subtype_Indic, 5224 Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type))); 5225 end if; 5226 5227 -- Renamings of class-wide interface types require no equivalent 5228 -- constrained type declarations because we only need to reference 5229 -- the tag component associated with the interface. The same is 5230 -- presumably true for class-wide types in general, so this test 5231 -- is broadened to include all class-wide renamings, which also 5232 -- avoids cases of unbounded recursion in Remove_Side_Effects. 5233 -- (Is this really correct, or are there some cases of class-wide 5234 -- renamings that require action in this procedure???) 5235 5236 elsif Present (N) 5237 and then Nkind (N) = N_Object_Renaming_Declaration 5238 and then Is_Class_Wide_Type (Unc_Type) 5239 then 5240 null; 5241 5242 -- In Ada 95 nothing to be done if the type of the expression is limited 5243 -- because in this case the expression cannot be copied, and its use can 5244 -- only be by reference. 5245 5246 -- In Ada 2005 the context can be an object declaration whose expression 5247 -- is a function that returns in place. If the nominal subtype has 5248 -- unknown discriminants, the call still provides constraints on the 5249 -- object, and we have to create an actual subtype from it. 5250 5251 -- If the type is class-wide, the expression is dynamically tagged and 5252 -- we do not create an actual subtype either. Ditto for an interface. 5253 -- For now this applies only if the type is immutably limited, and the 5254 -- function being called is build-in-place. This will have to be revised 5255 -- when build-in-place functions are generalized to other types. 5256 5257 elsif Is_Limited_View (Exp_Typ) 5258 and then 5259 (Is_Class_Wide_Type (Exp_Typ) 5260 or else Is_Interface (Exp_Typ) 5261 or else not Has_Unknown_Discriminants (Exp_Typ) 5262 or else not Is_Composite_Type (Unc_Type)) 5263 then 5264 null; 5265 5266 -- For limited objects initialized with build in place function calls, 5267 -- nothing to be done; otherwise we prematurely introduce an N_Reference 5268 -- node in the expression initializing the object, which breaks the 5269 -- circuitry that detects and adds the additional arguments to the 5270 -- called function. 5271 5272 elsif Is_Build_In_Place_Function_Call (Exp) then 5273 null; 5274 5275 else 5276 Remove_Side_Effects (Exp); 5277 Rewrite (Subtype_Indic, 5278 Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id)); 5279 end if; 5280 end Expand_Subtype_From_Expr; 5281 5282 --------------------------------------------- 5283 -- Expression_Contains_Primitives_Calls_Of -- 5284 --------------------------------------------- 5285 5286 function Expression_Contains_Primitives_Calls_Of 5287 (Expr : Node_Id; 5288 Typ : Entity_Id) return Boolean 5289 is 5290 U_Typ : constant Entity_Id := Unique_Entity (Typ); 5291 5292 Calls_OK : Boolean := False; 5293 -- This flag is set to True when expression Expr contains at least one 5294 -- call to a nondispatching primitive function of Typ. 5295 5296 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result; 5297 -- Search for nondispatching calls to primitive functions of type Typ 5298 5299 ---------------------------- 5300 -- Search_Primitive_Calls -- 5301 ---------------------------- 5302 5303 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is 5304 Disp_Typ : Entity_Id; 5305 Subp : Entity_Id; 5306 5307 begin 5308 -- Detect a function call that could denote a nondispatching 5309 -- primitive of the input type. 5310 5311 if Nkind (N) = N_Function_Call 5312 and then Is_Entity_Name (Name (N)) 5313 then 5314 Subp := Entity (Name (N)); 5315 5316 -- Do not consider function calls with a controlling argument, as 5317 -- those are always dispatching calls. 5318 5319 if Is_Dispatching_Operation (Subp) 5320 and then No (Controlling_Argument (N)) 5321 then 5322 Disp_Typ := Find_Dispatching_Type (Subp); 5323 5324 -- To qualify as a suitable primitive, the dispatching type of 5325 -- the function must be the input type. 5326 5327 if Present (Disp_Typ) 5328 and then Unique_Entity (Disp_Typ) = U_Typ 5329 then 5330 Calls_OK := True; 5331 5332 -- There is no need to continue the traversal, as one such 5333 -- call suffices. 5334 5335 return Abandon; 5336 end if; 5337 end if; 5338 end if; 5339 5340 return OK; 5341 end Search_Primitive_Calls; 5342 5343 procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls); 5344 5345 -- Start of processing for Expression_Contains_Primitives_Calls_Of_Type 5346 5347 begin 5348 Search_Calls (Expr); 5349 return Calls_OK; 5350 end Expression_Contains_Primitives_Calls_Of; 5351 5352 ---------------------- 5353 -- Finalize_Address -- 5354 ---------------------- 5355 5356 function Finalize_Address (Typ : Entity_Id) return Entity_Id is 5357 Utyp : Entity_Id := Typ; 5358 5359 begin 5360 -- Handle protected class-wide or task class-wide types 5361 5362 if Is_Class_Wide_Type (Utyp) then 5363 if Is_Concurrent_Type (Root_Type (Utyp)) then 5364 Utyp := Root_Type (Utyp); 5365 5366 elsif Is_Private_Type (Root_Type (Utyp)) 5367 and then Present (Full_View (Root_Type (Utyp))) 5368 and then Is_Concurrent_Type (Full_View (Root_Type (Utyp))) 5369 then 5370 Utyp := Full_View (Root_Type (Utyp)); 5371 end if; 5372 end if; 5373 5374 -- Handle private types 5375 5376 if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then 5377 Utyp := Full_View (Utyp); 5378 end if; 5379 5380 -- Handle protected and task types 5381 5382 if Is_Concurrent_Type (Utyp) 5383 and then Present (Corresponding_Record_Type (Utyp)) 5384 then 5385 Utyp := Corresponding_Record_Type (Utyp); 5386 end if; 5387 5388 Utyp := Underlying_Type (Base_Type (Utyp)); 5389 5390 -- Deal with untagged derivation of private views. If the parent is 5391 -- now known to be protected, the finalization routine is the one 5392 -- defined on the corresponding record of the ancestor (corresponding 5393 -- records do not automatically inherit operations, but maybe they 5394 -- should???) 5395 5396 if Is_Untagged_Derivation (Typ) then 5397 if Is_Protected_Type (Typ) then 5398 Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ))); 5399 5400 else 5401 Utyp := Underlying_Type (Root_Type (Base_Type (Typ))); 5402 5403 if Is_Protected_Type (Utyp) then 5404 Utyp := Corresponding_Record_Type (Utyp); 5405 end if; 5406 end if; 5407 end if; 5408 5409 -- If the underlying_type is a subtype, we are dealing with the 5410 -- completion of a private type. We need to access the base type and 5411 -- generate a conversion to it. 5412 5413 if Utyp /= Base_Type (Utyp) then 5414 pragma Assert (Is_Private_Type (Typ)); 5415 5416 Utyp := Base_Type (Utyp); 5417 end if; 5418 5419 -- When dealing with an internally built full view for a type with 5420 -- unknown discriminants, use the original record type. 5421 5422 if Is_Underlying_Record_View (Utyp) then 5423 Utyp := Etype (Utyp); 5424 end if; 5425 5426 return TSS (Utyp, TSS_Finalize_Address); 5427 end Finalize_Address; 5428 5429 ------------------------ 5430 -- Find_Interface_ADT -- 5431 ------------------------ 5432 5433 function Find_Interface_ADT 5434 (T : Entity_Id; 5435 Iface : Entity_Id) return Elmt_Id 5436 is 5437 ADT : Elmt_Id; 5438 Typ : Entity_Id := T; 5439 5440 begin 5441 pragma Assert (Is_Interface (Iface)); 5442 5443 -- Handle private types 5444 5445 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then 5446 Typ := Full_View (Typ); 5447 end if; 5448 5449 -- Handle access types 5450 5451 if Is_Access_Type (Typ) then 5452 Typ := Designated_Type (Typ); 5453 end if; 5454 5455 -- Handle task and protected types implementing interfaces 5456 5457 if Is_Concurrent_Type (Typ) then 5458 Typ := Corresponding_Record_Type (Typ); 5459 end if; 5460 5461 pragma Assert 5462 (not Is_Class_Wide_Type (Typ) 5463 and then Ekind (Typ) /= E_Incomplete_Type); 5464 5465 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then 5466 return First_Elmt (Access_Disp_Table (Typ)); 5467 5468 else 5469 ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))); 5470 while Present (ADT) 5471 and then Present (Related_Type (Node (ADT))) 5472 and then Related_Type (Node (ADT)) /= Iface 5473 and then not Is_Ancestor (Iface, Related_Type (Node (ADT)), 5474 Use_Full_View => True) 5475 loop 5476 Next_Elmt (ADT); 5477 end loop; 5478 5479 pragma Assert (Present (Related_Type (Node (ADT)))); 5480 return ADT; 5481 end if; 5482 end Find_Interface_ADT; 5483 5484 ------------------------ 5485 -- Find_Interface_Tag -- 5486 ------------------------ 5487 5488 function Find_Interface_Tag 5489 (T : Entity_Id; 5490 Iface : Entity_Id) return Entity_Id 5491 is 5492 AI_Tag : Entity_Id := Empty; 5493 Found : Boolean := False; 5494 Typ : Entity_Id := T; 5495 5496 procedure Find_Tag (Typ : Entity_Id); 5497 -- Internal subprogram used to recursively climb to the ancestors 5498 5499 -------------- 5500 -- Find_Tag -- 5501 -------------- 5502 5503 procedure Find_Tag (Typ : Entity_Id) is 5504 AI_Elmt : Elmt_Id; 5505 AI : Node_Id; 5506 5507 begin 5508 -- This routine does not handle the case in which the interface is an 5509 -- ancestor of Typ. That case is handled by the enclosing subprogram. 5510 5511 pragma Assert (Typ /= Iface); 5512 5513 -- Climb to the root type handling private types 5514 5515 if Present (Full_View (Etype (Typ))) then 5516 if Full_View (Etype (Typ)) /= Typ then 5517 Find_Tag (Full_View (Etype (Typ))); 5518 end if; 5519 5520 elsif Etype (Typ) /= Typ then 5521 Find_Tag (Etype (Typ)); 5522 end if; 5523 5524 -- Traverse the list of interfaces implemented by the type 5525 5526 if not Found 5527 and then Present (Interfaces (Typ)) 5528 and then not (Is_Empty_Elmt_List (Interfaces (Typ))) 5529 then 5530 -- Skip the tag associated with the primary table 5531 5532 AI_Tag := Next_Tag_Component (First_Tag_Component (Typ)); 5533 pragma Assert (Present (AI_Tag)); 5534 5535 AI_Elmt := First_Elmt (Interfaces (Typ)); 5536 while Present (AI_Elmt) loop 5537 AI := Node (AI_Elmt); 5538 5539 if AI = Iface 5540 or else Is_Ancestor (Iface, AI, Use_Full_View => True) 5541 then 5542 Found := True; 5543 return; 5544 end if; 5545 5546 AI_Tag := Next_Tag_Component (AI_Tag); 5547 Next_Elmt (AI_Elmt); 5548 end loop; 5549 end if; 5550 end Find_Tag; 5551 5552 -- Start of processing for Find_Interface_Tag 5553 5554 begin 5555 pragma Assert (Is_Interface (Iface)); 5556 5557 -- Handle access types 5558 5559 if Is_Access_Type (Typ) then 5560 Typ := Designated_Type (Typ); 5561 end if; 5562 5563 -- Handle class-wide types 5564 5565 if Is_Class_Wide_Type (Typ) then 5566 Typ := Root_Type (Typ); 5567 end if; 5568 5569 -- Handle private types 5570 5571 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then 5572 Typ := Full_View (Typ); 5573 end if; 5574 5575 -- Handle entities from the limited view 5576 5577 if Ekind (Typ) = E_Incomplete_Type then 5578 pragma Assert (Present (Non_Limited_View (Typ))); 5579 Typ := Non_Limited_View (Typ); 5580 end if; 5581 5582 -- Handle task and protected types implementing interfaces 5583 5584 if Is_Concurrent_Type (Typ) then 5585 Typ := Corresponding_Record_Type (Typ); 5586 end if; 5587 5588 -- If the interface is an ancestor of the type, then it shared the 5589 -- primary dispatch table. 5590 5591 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then 5592 return First_Tag_Component (Typ); 5593 5594 -- Otherwise we need to search for its associated tag component 5595 5596 else 5597 Find_Tag (Typ); 5598 return AI_Tag; 5599 end if; 5600 end Find_Interface_Tag; 5601 5602 --------------------------- 5603 -- Find_Optional_Prim_Op -- 5604 --------------------------- 5605 5606 function Find_Optional_Prim_Op 5607 (T : Entity_Id; Name : Name_Id) return Entity_Id 5608 is 5609 Prim : Elmt_Id; 5610 Typ : Entity_Id := T; 5611 Op : Entity_Id; 5612 5613 begin 5614 if Is_Class_Wide_Type (Typ) then 5615 Typ := Root_Type (Typ); 5616 end if; 5617 5618 Typ := Underlying_Type (Typ); 5619 5620 -- Loop through primitive operations 5621 5622 Prim := First_Elmt (Primitive_Operations (Typ)); 5623 while Present (Prim) loop 5624 Op := Node (Prim); 5625 5626 -- We can retrieve primitive operations by name if it is an internal 5627 -- name. For equality we must check that both of its operands have 5628 -- the same type, to avoid confusion with user-defined equalities 5629 -- than may have a non-symmetric signature. 5630 5631 exit when Chars (Op) = Name 5632 and then 5633 (Name /= Name_Op_Eq 5634 or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op))); 5635 5636 Next_Elmt (Prim); 5637 end loop; 5638 5639 return Node (Prim); -- Empty if not found 5640 end Find_Optional_Prim_Op; 5641 5642 --------------------------- 5643 -- Find_Optional_Prim_Op -- 5644 --------------------------- 5645 5646 function Find_Optional_Prim_Op 5647 (T : Entity_Id; 5648 Name : TSS_Name_Type) return Entity_Id 5649 is 5650 Inher_Op : Entity_Id := Empty; 5651 Own_Op : Entity_Id := Empty; 5652 Prim_Elmt : Elmt_Id; 5653 Prim_Id : Entity_Id; 5654 Typ : Entity_Id := T; 5655 5656 begin 5657 if Is_Class_Wide_Type (Typ) then 5658 Typ := Root_Type (Typ); 5659 end if; 5660 5661 Typ := Underlying_Type (Typ); 5662 5663 -- This search is based on the assertion that the dispatching version 5664 -- of the TSS routine always precedes the real primitive. 5665 5666 Prim_Elmt := First_Elmt (Primitive_Operations (Typ)); 5667 while Present (Prim_Elmt) loop 5668 Prim_Id := Node (Prim_Elmt); 5669 5670 if Is_TSS (Prim_Id, Name) then 5671 if Present (Alias (Prim_Id)) then 5672 Inher_Op := Prim_Id; 5673 else 5674 Own_Op := Prim_Id; 5675 end if; 5676 end if; 5677 5678 Next_Elmt (Prim_Elmt); 5679 end loop; 5680 5681 if Present (Own_Op) then 5682 return Own_Op; 5683 elsif Present (Inher_Op) then 5684 return Inher_Op; 5685 else 5686 return Empty; 5687 end if; 5688 end Find_Optional_Prim_Op; 5689 5690 ------------------ 5691 -- Find_Prim_Op -- 5692 ------------------ 5693 5694 function Find_Prim_Op 5695 (T : Entity_Id; Name : Name_Id) return Entity_Id 5696 is 5697 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name); 5698 begin 5699 if No (Result) then 5700 raise Program_Error; 5701 end if; 5702 5703 return Result; 5704 end Find_Prim_Op; 5705 5706 ------------------ 5707 -- Find_Prim_Op -- 5708 ------------------ 5709 5710 function Find_Prim_Op 5711 (T : Entity_Id; 5712 Name : TSS_Name_Type) return Entity_Id 5713 is 5714 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name); 5715 begin 5716 if No (Result) then 5717 raise Program_Error; 5718 end if; 5719 5720 return Result; 5721 end Find_Prim_Op; 5722 5723 ---------------------------- 5724 -- Find_Protection_Object -- 5725 ---------------------------- 5726 5727 function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is 5728 S : Entity_Id; 5729 5730 begin 5731 S := Scop; 5732 while Present (S) loop 5733 if Ekind_In (S, E_Entry, E_Entry_Family, E_Function, E_Procedure) 5734 and then Present (Protection_Object (S)) 5735 then 5736 return Protection_Object (S); 5737 end if; 5738 5739 S := Scope (S); 5740 end loop; 5741 5742 -- If we do not find a Protection object in the scope chain, then 5743 -- something has gone wrong, most likely the object was never created. 5744 5745 raise Program_Error; 5746 end Find_Protection_Object; 5747 5748 -------------------------- 5749 -- Find_Protection_Type -- 5750 -------------------------- 5751 5752 function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is 5753 Comp : Entity_Id; 5754 Typ : Entity_Id := Conc_Typ; 5755 5756 begin 5757 if Is_Concurrent_Type (Typ) then 5758 Typ := Corresponding_Record_Type (Typ); 5759 end if; 5760 5761 -- Since restriction violations are not considered serious errors, the 5762 -- expander remains active, but may leave the corresponding record type 5763 -- malformed. In such cases, component _object is not available so do 5764 -- not look for it. 5765 5766 if not Analyzed (Typ) then 5767 return Empty; 5768 end if; 5769 5770 Comp := First_Component (Typ); 5771 while Present (Comp) loop 5772 if Chars (Comp) = Name_uObject then 5773 return Base_Type (Etype (Comp)); 5774 end if; 5775 5776 Next_Component (Comp); 5777 end loop; 5778 5779 -- The corresponding record of a protected type should always have an 5780 -- _object field. 5781 5782 raise Program_Error; 5783 end Find_Protection_Type; 5784 5785 ----------------------- 5786 -- Find_Hook_Context -- 5787 ----------------------- 5788 5789 function Find_Hook_Context (N : Node_Id) return Node_Id is 5790 Par : Node_Id; 5791 Top : Node_Id; 5792 5793 Wrapped_Node : Node_Id; 5794 -- Note: if we are in a transient scope, we want to reuse it as 5795 -- the context for actions insertion, if possible. But if N is itself 5796 -- part of the stored actions for the current transient scope, 5797 -- then we need to insert at the appropriate (inner) location in 5798 -- the not as an action on Node_To_Be_Wrapped. 5799 5800 In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N); 5801 5802 begin 5803 -- When the node is inside a case/if expression, the lifetime of any 5804 -- temporary controlled object is extended. Find a suitable insertion 5805 -- node by locating the topmost case or if expressions. 5806 5807 if In_Cond_Expr then 5808 Par := N; 5809 Top := N; 5810 while Present (Par) loop 5811 if Nkind_In (Original_Node (Par), N_Case_Expression, 5812 N_If_Expression) 5813 then 5814 Top := Par; 5815 5816 -- Prevent the search from going too far 5817 5818 elsif Is_Body_Or_Package_Declaration (Par) then 5819 exit; 5820 end if; 5821 5822 Par := Parent (Par); 5823 end loop; 5824 5825 -- The topmost case or if expression is now recovered, but it may 5826 -- still not be the correct place to add generated code. Climb to 5827 -- find a parent that is part of a declarative or statement list, 5828 -- and is not a list of actuals in a call. 5829 5830 Par := Top; 5831 while Present (Par) loop 5832 if Is_List_Member (Par) 5833 and then not Nkind_In (Par, N_Component_Association, 5834 N_Discriminant_Association, 5835 N_Parameter_Association, 5836 N_Pragma_Argument_Association) 5837 and then not Nkind_In (Parent (Par), N_Function_Call, 5838 N_Procedure_Call_Statement, 5839 N_Entry_Call_Statement) 5840 5841 then 5842 return Par; 5843 5844 -- Prevent the search from going too far 5845 5846 elsif Is_Body_Or_Package_Declaration (Par) then 5847 exit; 5848 end if; 5849 5850 Par := Parent (Par); 5851 end loop; 5852 5853 return Par; 5854 5855 else 5856 Par := N; 5857 while Present (Par) loop 5858 5859 -- Keep climbing past various operators 5860 5861 if Nkind (Parent (Par)) in N_Op 5862 or else Nkind_In (Parent (Par), N_And_Then, N_Or_Else) 5863 then 5864 Par := Parent (Par); 5865 else 5866 exit; 5867 end if; 5868 end loop; 5869 5870 Top := Par; 5871 5872 -- The node may be located in a pragma in which case return the 5873 -- pragma itself: 5874 5875 -- pragma Precondition (... and then Ctrl_Func_Call ...); 5876 5877 -- Similar case occurs when the node is related to an object 5878 -- declaration or assignment: 5879 5880 -- Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...; 5881 5882 -- Another case to consider is when the node is part of a return 5883 -- statement: 5884 5885 -- return ... and then Ctrl_Func_Call ...; 5886 5887 -- Another case is when the node acts as a formal in a procedure 5888 -- call statement: 5889 5890 -- Proc (... and then Ctrl_Func_Call ...); 5891 5892 if Scope_Is_Transient then 5893 Wrapped_Node := Node_To_Be_Wrapped; 5894 else 5895 Wrapped_Node := Empty; 5896 end if; 5897 5898 while Present (Par) loop 5899 if Par = Wrapped_Node 5900 or else Nkind_In (Par, N_Assignment_Statement, 5901 N_Object_Declaration, 5902 N_Pragma, 5903 N_Procedure_Call_Statement, 5904 N_Simple_Return_Statement) 5905 then 5906 return Par; 5907 5908 -- Prevent the search from going too far 5909 5910 elsif Is_Body_Or_Package_Declaration (Par) then 5911 exit; 5912 end if; 5913 5914 Par := Parent (Par); 5915 end loop; 5916 5917 -- Return the topmost short circuit operator 5918 5919 return Top; 5920 end if; 5921 end Find_Hook_Context; 5922 5923 ------------------------------ 5924 -- Following_Address_Clause -- 5925 ------------------------------ 5926 5927 function Following_Address_Clause (D : Node_Id) return Node_Id is 5928 Id : constant Entity_Id := Defining_Identifier (D); 5929 Result : Node_Id; 5930 Par : Node_Id; 5931 5932 function Check_Decls (D : Node_Id) return Node_Id; 5933 -- This internal function differs from the main function in that it 5934 -- gets called to deal with a following package private part, and 5935 -- it checks declarations starting with D (the main function checks 5936 -- declarations following D). If D is Empty, then Empty is returned. 5937 5938 ----------------- 5939 -- Check_Decls -- 5940 ----------------- 5941 5942 function Check_Decls (D : Node_Id) return Node_Id is 5943 Decl : Node_Id; 5944 5945 begin 5946 Decl := D; 5947 while Present (Decl) loop 5948 if Nkind (Decl) = N_At_Clause 5949 and then Chars (Identifier (Decl)) = Chars (Id) 5950 then 5951 return Decl; 5952 5953 elsif Nkind (Decl) = N_Attribute_Definition_Clause 5954 and then Chars (Decl) = Name_Address 5955 and then Chars (Name (Decl)) = Chars (Id) 5956 then 5957 return Decl; 5958 end if; 5959 5960 Next (Decl); 5961 end loop; 5962 5963 -- Otherwise not found, return Empty 5964 5965 return Empty; 5966 end Check_Decls; 5967 5968 -- Start of processing for Following_Address_Clause 5969 5970 begin 5971 -- If parser detected no address clause for the identifier in question, 5972 -- then the answer is a quick NO, without the need for a search. 5973 5974 if not Get_Name_Table_Boolean1 (Chars (Id)) then 5975 return Empty; 5976 end if; 5977 5978 -- Otherwise search current declarative unit 5979 5980 Result := Check_Decls (Next (D)); 5981 5982 if Present (Result) then 5983 return Result; 5984 end if; 5985 5986 -- Check for possible package private part following 5987 5988 Par := Parent (D); 5989 5990 if Nkind (Par) = N_Package_Specification 5991 and then Visible_Declarations (Par) = List_Containing (D) 5992 and then Present (Private_Declarations (Par)) 5993 then 5994 -- Private part present, check declarations there 5995 5996 return Check_Decls (First (Private_Declarations (Par))); 5997 5998 else 5999 -- No private part, clause not found, return Empty 6000 6001 return Empty; 6002 end if; 6003 end Following_Address_Clause; 6004 6005 ---------------------- 6006 -- Force_Evaluation -- 6007 ---------------------- 6008 6009 procedure Force_Evaluation 6010 (Exp : Node_Id; 6011 Name_Req : Boolean := False; 6012 Related_Id : Entity_Id := Empty; 6013 Is_Low_Bound : Boolean := False; 6014 Is_High_Bound : Boolean := False; 6015 Mode : Force_Evaluation_Mode := Relaxed) 6016 is 6017 begin 6018 Remove_Side_Effects 6019 (Exp => Exp, 6020 Name_Req => Name_Req, 6021 Variable_Ref => True, 6022 Renaming_Req => False, 6023 Related_Id => Related_Id, 6024 Is_Low_Bound => Is_Low_Bound, 6025 Is_High_Bound => Is_High_Bound, 6026 Check_Side_Effects => 6027 Is_Static_Expression (Exp) 6028 or else Mode = Relaxed); 6029 end Force_Evaluation; 6030 6031 --------------------------------- 6032 -- Fully_Qualified_Name_String -- 6033 --------------------------------- 6034 6035 function Fully_Qualified_Name_String 6036 (E : Entity_Id; 6037 Append_NUL : Boolean := True) return String_Id 6038 is 6039 procedure Internal_Full_Qualified_Name (E : Entity_Id); 6040 -- Compute recursively the qualified name without NUL at the end, adding 6041 -- it to the currently started string being generated 6042 6043 ---------------------------------- 6044 -- Internal_Full_Qualified_Name -- 6045 ---------------------------------- 6046 6047 procedure Internal_Full_Qualified_Name (E : Entity_Id) is 6048 Ent : Entity_Id; 6049 6050 begin 6051 -- Deal properly with child units 6052 6053 if Nkind (E) = N_Defining_Program_Unit_Name then 6054 Ent := Defining_Identifier (E); 6055 else 6056 Ent := E; 6057 end if; 6058 6059 -- Compute qualification recursively (only "Standard" has no scope) 6060 6061 if Present (Scope (Scope (Ent))) then 6062 Internal_Full_Qualified_Name (Scope (Ent)); 6063 Store_String_Char (Get_Char_Code ('.')); 6064 end if; 6065 6066 -- Every entity should have a name except some expanded blocks 6067 -- don't bother about those. 6068 6069 if Chars (Ent) = No_Name then 6070 return; 6071 end if; 6072 6073 -- Generates the entity name in upper case 6074 6075 Get_Decoded_Name_String (Chars (Ent)); 6076 Set_All_Upper_Case; 6077 Store_String_Chars (Name_Buffer (1 .. Name_Len)); 6078 return; 6079 end Internal_Full_Qualified_Name; 6080 6081 -- Start of processing for Full_Qualified_Name 6082 6083 begin 6084 Start_String; 6085 Internal_Full_Qualified_Name (E); 6086 6087 if Append_NUL then 6088 Store_String_Char (Get_Char_Code (ASCII.NUL)); 6089 end if; 6090 6091 return End_String; 6092 end Fully_Qualified_Name_String; 6093 6094 ------------------------ 6095 -- Generate_Poll_Call -- 6096 ------------------------ 6097 6098 procedure Generate_Poll_Call (N : Node_Id) is 6099 begin 6100 -- No poll call if polling not active 6101 6102 if not Polling_Required then 6103 return; 6104 6105 -- Otherwise generate require poll call 6106 6107 else 6108 Insert_Before_And_Analyze (N, 6109 Make_Procedure_Call_Statement (Sloc (N), 6110 Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N)))); 6111 end if; 6112 end Generate_Poll_Call; 6113 6114 --------------------------------- 6115 -- Get_Current_Value_Condition -- 6116 --------------------------------- 6117 6118 -- Note: the implementation of this procedure is very closely tied to the 6119 -- implementation of Set_Current_Value_Condition. In the Get procedure, we 6120 -- interpret Current_Value fields set by the Set procedure, so the two 6121 -- procedures need to be closely coordinated. 6122 6123 procedure Get_Current_Value_Condition 6124 (Var : Node_Id; 6125 Op : out Node_Kind; 6126 Val : out Node_Id) 6127 is 6128 Loc : constant Source_Ptr := Sloc (Var); 6129 Ent : constant Entity_Id := Entity (Var); 6130 6131 procedure Process_Current_Value_Condition 6132 (N : Node_Id; 6133 S : Boolean); 6134 -- N is an expression which holds either True (S = True) or False (S = 6135 -- False) in the condition. This procedure digs out the expression and 6136 -- if it refers to Ent, sets Op and Val appropriately. 6137 6138 ------------------------------------- 6139 -- Process_Current_Value_Condition -- 6140 ------------------------------------- 6141 6142 procedure Process_Current_Value_Condition 6143 (N : Node_Id; 6144 S : Boolean) 6145 is 6146 Cond : Node_Id; 6147 Prev_Cond : Node_Id; 6148 Sens : Boolean; 6149 6150 begin 6151 Cond := N; 6152 Sens := S; 6153 6154 loop 6155 Prev_Cond := Cond; 6156 6157 -- Deal with NOT operators, inverting sense 6158 6159 while Nkind (Cond) = N_Op_Not loop 6160 Cond := Right_Opnd (Cond); 6161 Sens := not Sens; 6162 end loop; 6163 6164 -- Deal with conversions, qualifications, and expressions with 6165 -- actions. 6166 6167 while Nkind_In (Cond, 6168 N_Type_Conversion, 6169 N_Qualified_Expression, 6170 N_Expression_With_Actions) 6171 loop 6172 Cond := Expression (Cond); 6173 end loop; 6174 6175 exit when Cond = Prev_Cond; 6176 end loop; 6177 6178 -- Deal with AND THEN and AND cases 6179 6180 if Nkind_In (Cond, N_And_Then, N_Op_And) then 6181 6182 -- Don't ever try to invert a condition that is of the form of an 6183 -- AND or AND THEN (since we are not doing sufficiently general 6184 -- processing to allow this). 6185 6186 if Sens = False then 6187 Op := N_Empty; 6188 Val := Empty; 6189 return; 6190 end if; 6191 6192 -- Recursively process AND and AND THEN branches 6193 6194 Process_Current_Value_Condition (Left_Opnd (Cond), True); 6195 6196 if Op /= N_Empty then 6197 return; 6198 end if; 6199 6200 Process_Current_Value_Condition (Right_Opnd (Cond), True); 6201 return; 6202 6203 -- Case of relational operator 6204 6205 elsif Nkind (Cond) in N_Op_Compare then 6206 Op := Nkind (Cond); 6207 6208 -- Invert sense of test if inverted test 6209 6210 if Sens = False then 6211 case Op is 6212 when N_Op_Eq => Op := N_Op_Ne; 6213 when N_Op_Ne => Op := N_Op_Eq; 6214 when N_Op_Lt => Op := N_Op_Ge; 6215 when N_Op_Gt => Op := N_Op_Le; 6216 when N_Op_Le => Op := N_Op_Gt; 6217 when N_Op_Ge => Op := N_Op_Lt; 6218 when others => raise Program_Error; 6219 end case; 6220 end if; 6221 6222 -- Case of entity op value 6223 6224 if Is_Entity_Name (Left_Opnd (Cond)) 6225 and then Ent = Entity (Left_Opnd (Cond)) 6226 and then Compile_Time_Known_Value (Right_Opnd (Cond)) 6227 then 6228 Val := Right_Opnd (Cond); 6229 6230 -- Case of value op entity 6231 6232 elsif Is_Entity_Name (Right_Opnd (Cond)) 6233 and then Ent = Entity (Right_Opnd (Cond)) 6234 and then Compile_Time_Known_Value (Left_Opnd (Cond)) 6235 then 6236 Val := Left_Opnd (Cond); 6237 6238 -- We are effectively swapping operands 6239 6240 case Op is 6241 when N_Op_Eq => null; 6242 when N_Op_Ne => null; 6243 when N_Op_Lt => Op := N_Op_Gt; 6244 when N_Op_Gt => Op := N_Op_Lt; 6245 when N_Op_Le => Op := N_Op_Ge; 6246 when N_Op_Ge => Op := N_Op_Le; 6247 when others => raise Program_Error; 6248 end case; 6249 6250 else 6251 Op := N_Empty; 6252 end if; 6253 6254 return; 6255 6256 elsif Nkind_In (Cond, 6257 N_Type_Conversion, 6258 N_Qualified_Expression, 6259 N_Expression_With_Actions) 6260 then 6261 Cond := Expression (Cond); 6262 6263 -- Case of Boolean variable reference, return as though the 6264 -- reference had said var = True. 6265 6266 else 6267 if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then 6268 Val := New_Occurrence_Of (Standard_True, Sloc (Cond)); 6269 6270 if Sens = False then 6271 Op := N_Op_Ne; 6272 else 6273 Op := N_Op_Eq; 6274 end if; 6275 end if; 6276 end if; 6277 end Process_Current_Value_Condition; 6278 6279 -- Start of processing for Get_Current_Value_Condition 6280 6281 begin 6282 Op := N_Empty; 6283 Val := Empty; 6284 6285 -- Immediate return, nothing doing, if this is not an object 6286 6287 if Ekind (Ent) not in Object_Kind then 6288 return; 6289 end if; 6290 6291 -- Otherwise examine current value 6292 6293 declare 6294 CV : constant Node_Id := Current_Value (Ent); 6295 Sens : Boolean; 6296 Stm : Node_Id; 6297 6298 begin 6299 -- If statement. Condition is known true in THEN section, known False 6300 -- in any ELSIF or ELSE part, and unknown outside the IF statement. 6301 6302 if Nkind (CV) = N_If_Statement then 6303 6304 -- Before start of IF statement 6305 6306 if Loc < Sloc (CV) then 6307 return; 6308 6309 -- After end of IF statement 6310 6311 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then 6312 return; 6313 end if; 6314 6315 -- At this stage we know that we are within the IF statement, but 6316 -- unfortunately, the tree does not record the SLOC of the ELSE so 6317 -- we cannot use a simple SLOC comparison to distinguish between 6318 -- the then/else statements, so we have to climb the tree. 6319 6320 declare 6321 N : Node_Id; 6322 6323 begin 6324 N := Parent (Var); 6325 while Parent (N) /= CV loop 6326 N := Parent (N); 6327 6328 -- If we fall off the top of the tree, then that's odd, but 6329 -- perhaps it could occur in some error situation, and the 6330 -- safest response is simply to assume that the outcome of 6331 -- the condition is unknown. No point in bombing during an 6332 -- attempt to optimize things. 6333 6334 if No (N) then 6335 return; 6336 end if; 6337 end loop; 6338 6339 -- Now we have N pointing to a node whose parent is the IF 6340 -- statement in question, so now we can tell if we are within 6341 -- the THEN statements. 6342 6343 if Is_List_Member (N) 6344 and then List_Containing (N) = Then_Statements (CV) 6345 then 6346 Sens := True; 6347 6348 -- If the variable reference does not come from source, we 6349 -- cannot reliably tell whether it appears in the else part. 6350 -- In particular, if it appears in generated code for a node 6351 -- that requires finalization, it may be attached to a list 6352 -- that has not been yet inserted into the code. For now, 6353 -- treat it as unknown. 6354 6355 elsif not Comes_From_Source (N) then 6356 return; 6357 6358 -- Otherwise we must be in ELSIF or ELSE part 6359 6360 else 6361 Sens := False; 6362 end if; 6363 end; 6364 6365 -- ELSIF part. Condition is known true within the referenced 6366 -- ELSIF, known False in any subsequent ELSIF or ELSE part, 6367 -- and unknown before the ELSE part or after the IF statement. 6368 6369 elsif Nkind (CV) = N_Elsif_Part then 6370 6371 -- if the Elsif_Part had condition_actions, the elsif has been 6372 -- rewritten as a nested if, and the original elsif_part is 6373 -- detached from the tree, so there is no way to obtain useful 6374 -- information on the current value of the variable. 6375 -- Can this be improved ??? 6376 6377 if No (Parent (CV)) then 6378 return; 6379 end if; 6380 6381 Stm := Parent (CV); 6382 6383 -- If the tree has been otherwise rewritten there is nothing 6384 -- else to be done either. 6385 6386 if Nkind (Stm) /= N_If_Statement then 6387 return; 6388 end if; 6389 6390 -- Before start of ELSIF part 6391 6392 if Loc < Sloc (CV) then 6393 return; 6394 6395 -- After end of IF statement 6396 6397 elsif Loc >= Sloc (Stm) + 6398 Text_Ptr (UI_To_Int (End_Span (Stm))) 6399 then 6400 return; 6401 end if; 6402 6403 -- Again we lack the SLOC of the ELSE, so we need to climb the 6404 -- tree to see if we are within the ELSIF part in question. 6405 6406 declare 6407 N : Node_Id; 6408 6409 begin 6410 N := Parent (Var); 6411 while Parent (N) /= Stm loop 6412 N := Parent (N); 6413 6414 -- If we fall off the top of the tree, then that's odd, but 6415 -- perhaps it could occur in some error situation, and the 6416 -- safest response is simply to assume that the outcome of 6417 -- the condition is unknown. No point in bombing during an 6418 -- attempt to optimize things. 6419 6420 if No (N) then 6421 return; 6422 end if; 6423 end loop; 6424 6425 -- Now we have N pointing to a node whose parent is the IF 6426 -- statement in question, so see if is the ELSIF part we want. 6427 -- the THEN statements. 6428 6429 if N = CV then 6430 Sens := True; 6431 6432 -- Otherwise we must be in subsequent ELSIF or ELSE part 6433 6434 else 6435 Sens := False; 6436 end if; 6437 end; 6438 6439 -- Iteration scheme of while loop. The condition is known to be 6440 -- true within the body of the loop. 6441 6442 elsif Nkind (CV) = N_Iteration_Scheme then 6443 declare 6444 Loop_Stmt : constant Node_Id := Parent (CV); 6445 6446 begin 6447 -- Before start of body of loop 6448 6449 if Loc < Sloc (Loop_Stmt) then 6450 return; 6451 6452 -- After end of LOOP statement 6453 6454 elsif Loc >= Sloc (End_Label (Loop_Stmt)) then 6455 return; 6456 6457 -- We are within the body of the loop 6458 6459 else 6460 Sens := True; 6461 end if; 6462 end; 6463 6464 -- All other cases of Current_Value settings 6465 6466 else 6467 return; 6468 end if; 6469 6470 -- If we fall through here, then we have a reportable condition, Sens 6471 -- is True if the condition is true and False if it needs inverting. 6472 6473 Process_Current_Value_Condition (Condition (CV), Sens); 6474 end; 6475 end Get_Current_Value_Condition; 6476 6477 --------------------- 6478 -- Get_Stream_Size -- 6479 --------------------- 6480 6481 function Get_Stream_Size (E : Entity_Id) return Uint is 6482 begin 6483 -- If we have a Stream_Size clause for this type use it 6484 6485 if Has_Stream_Size_Clause (E) then 6486 return Static_Integer (Expression (Stream_Size_Clause (E))); 6487 6488 -- Otherwise the Stream_Size if the size of the type 6489 6490 else 6491 return Esize (E); 6492 end if; 6493 end Get_Stream_Size; 6494 6495 --------------------------- 6496 -- Has_Access_Constraint -- 6497 --------------------------- 6498 6499 function Has_Access_Constraint (E : Entity_Id) return Boolean is 6500 Disc : Entity_Id; 6501 T : constant Entity_Id := Etype (E); 6502 6503 begin 6504 if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then 6505 Disc := First_Discriminant (T); 6506 while Present (Disc) loop 6507 if Is_Access_Type (Etype (Disc)) then 6508 return True; 6509 end if; 6510 6511 Next_Discriminant (Disc); 6512 end loop; 6513 6514 return False; 6515 else 6516 return False; 6517 end if; 6518 end Has_Access_Constraint; 6519 6520 ----------------------------------------------------- 6521 -- Has_Annotate_Pragma_For_External_Axiomatization -- 6522 ----------------------------------------------------- 6523 6524 function Has_Annotate_Pragma_For_External_Axiomatization 6525 (E : Entity_Id) return Boolean 6526 is 6527 function Is_Annotate_Pragma_For_External_Axiomatization 6528 (N : Node_Id) return Boolean; 6529 -- Returns whether N is 6530 -- pragma Annotate (GNATprove, External_Axiomatization); 6531 6532 ---------------------------------------------------- 6533 -- Is_Annotate_Pragma_For_External_Axiomatization -- 6534 ---------------------------------------------------- 6535 6536 -- The general form of pragma Annotate is 6537 6538 -- pragma Annotate (IDENTIFIER [, IDENTIFIER {, ARG}]); 6539 -- ARG ::= NAME | EXPRESSION 6540 6541 -- The first two arguments are by convention intended to refer to an 6542 -- external tool and a tool-specific function. These arguments are 6543 -- not analyzed. 6544 6545 -- The following is used to annotate a package specification which 6546 -- GNATprove should treat specially, because the axiomatization of 6547 -- this unit is given by the user instead of being automatically 6548 -- generated. 6549 6550 -- pragma Annotate (GNATprove, External_Axiomatization); 6551 6552 function Is_Annotate_Pragma_For_External_Axiomatization 6553 (N : Node_Id) return Boolean 6554 is 6555 Name_GNATprove : constant String := 6556 "gnatprove"; 6557 Name_External_Axiomatization : constant String := 6558 "external_axiomatization"; 6559 -- Special names 6560 6561 begin 6562 if Nkind (N) = N_Pragma 6563 and then Get_Pragma_Id (N) = Pragma_Annotate 6564 and then List_Length (Pragma_Argument_Associations (N)) = 2 6565 then 6566 declare 6567 Arg1 : constant Node_Id := 6568 First (Pragma_Argument_Associations (N)); 6569 Arg2 : constant Node_Id := Next (Arg1); 6570 Nam1 : Name_Id; 6571 Nam2 : Name_Id; 6572 6573 begin 6574 -- Fill in Name_Buffer with Name_GNATprove first, and then with 6575 -- Name_External_Axiomatization so that Name_Find returns the 6576 -- corresponding name. This takes care of all possible casings. 6577 6578 Name_Len := 0; 6579 Add_Str_To_Name_Buffer (Name_GNATprove); 6580 Nam1 := Name_Find; 6581 6582 Name_Len := 0; 6583 Add_Str_To_Name_Buffer (Name_External_Axiomatization); 6584 Nam2 := Name_Find; 6585 6586 return Chars (Get_Pragma_Arg (Arg1)) = Nam1 6587 and then 6588 Chars (Get_Pragma_Arg (Arg2)) = Nam2; 6589 end; 6590 6591 else 6592 return False; 6593 end if; 6594 end Is_Annotate_Pragma_For_External_Axiomatization; 6595 6596 -- Local variables 6597 6598 Decl : Node_Id; 6599 Vis_Decls : List_Id; 6600 N : Node_Id; 6601 6602 -- Start of processing for Has_Annotate_Pragma_For_External_Axiomatization 6603 6604 begin 6605 if Nkind (Parent (E)) = N_Defining_Program_Unit_Name then 6606 Decl := Parent (Parent (E)); 6607 else 6608 Decl := Parent (E); 6609 end if; 6610 6611 Vis_Decls := Visible_Declarations (Decl); 6612 6613 N := First (Vis_Decls); 6614 while Present (N) loop 6615 6616 -- Skip declarations generated by the frontend. Skip all pragmas 6617 -- that are not the desired Annotate pragma. Stop the search on 6618 -- the first non-pragma source declaration. 6619 6620 if Comes_From_Source (N) then 6621 if Nkind (N) = N_Pragma then 6622 if Is_Annotate_Pragma_For_External_Axiomatization (N) then 6623 return True; 6624 end if; 6625 else 6626 return False; 6627 end if; 6628 end if; 6629 6630 Next (N); 6631 end loop; 6632 6633 return False; 6634 end Has_Annotate_Pragma_For_External_Axiomatization; 6635 6636 -------------------- 6637 -- Homonym_Number -- 6638 -------------------- 6639 6640 function Homonym_Number (Subp : Entity_Id) return Nat is 6641 Count : Nat; 6642 Hom : Entity_Id; 6643 6644 begin 6645 Count := 1; 6646 Hom := Homonym (Subp); 6647 while Present (Hom) loop 6648 if Scope (Hom) = Scope (Subp) then 6649 Count := Count + 1; 6650 end if; 6651 6652 Hom := Homonym (Hom); 6653 end loop; 6654 6655 return Count; 6656 end Homonym_Number; 6657 6658 ----------------------------------- 6659 -- In_Library_Level_Package_Body -- 6660 ----------------------------------- 6661 6662 function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is 6663 begin 6664 -- First determine whether the entity appears at the library level, then 6665 -- look at the containing unit. 6666 6667 if Is_Library_Level_Entity (Id) then 6668 declare 6669 Container : constant Node_Id := Cunit (Get_Source_Unit (Id)); 6670 6671 begin 6672 return Nkind (Unit (Container)) = N_Package_Body; 6673 end; 6674 end if; 6675 6676 return False; 6677 end In_Library_Level_Package_Body; 6678 6679 ------------------------------ 6680 -- In_Unconditional_Context -- 6681 ------------------------------ 6682 6683 function In_Unconditional_Context (Node : Node_Id) return Boolean is 6684 P : Node_Id; 6685 6686 begin 6687 P := Node; 6688 while Present (P) loop 6689 case Nkind (P) is 6690 when N_Subprogram_Body => return True; 6691 when N_If_Statement => return False; 6692 when N_Loop_Statement => return False; 6693 when N_Case_Statement => return False; 6694 when others => P := Parent (P); 6695 end case; 6696 end loop; 6697 6698 return False; 6699 end In_Unconditional_Context; 6700 6701 ------------------- 6702 -- Insert_Action -- 6703 ------------------- 6704 6705 procedure Insert_Action 6706 (Assoc_Node : Node_Id; 6707 Ins_Action : Node_Id; 6708 Spec_Expr_OK : Boolean := False) 6709 is 6710 begin 6711 if Present (Ins_Action) then 6712 Insert_Actions 6713 (Assoc_Node => Assoc_Node, 6714 Ins_Actions => New_List (Ins_Action), 6715 Spec_Expr_OK => Spec_Expr_OK); 6716 end if; 6717 end Insert_Action; 6718 6719 -- Version with check(s) suppressed 6720 6721 procedure Insert_Action 6722 (Assoc_Node : Node_Id; 6723 Ins_Action : Node_Id; 6724 Suppress : Check_Id; 6725 Spec_Expr_OK : Boolean := False) 6726 is 6727 begin 6728 Insert_Actions 6729 (Assoc_Node => Assoc_Node, 6730 Ins_Actions => New_List (Ins_Action), 6731 Suppress => Suppress, 6732 Spec_Expr_OK => Spec_Expr_OK); 6733 end Insert_Action; 6734 6735 ------------------------- 6736 -- Insert_Action_After -- 6737 ------------------------- 6738 6739 procedure Insert_Action_After 6740 (Assoc_Node : Node_Id; 6741 Ins_Action : Node_Id) 6742 is 6743 begin 6744 Insert_Actions_After (Assoc_Node, New_List (Ins_Action)); 6745 end Insert_Action_After; 6746 6747 -------------------- 6748 -- Insert_Actions -- 6749 -------------------- 6750 6751 procedure Insert_Actions 6752 (Assoc_Node : Node_Id; 6753 Ins_Actions : List_Id; 6754 Spec_Expr_OK : Boolean := False) 6755 is 6756 N : Node_Id; 6757 P : Node_Id; 6758 6759 Wrapped_Node : Node_Id := Empty; 6760 6761 begin 6762 if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then 6763 return; 6764 end if; 6765 6766 -- Insert the action when the context is "Handling of Default and Per- 6767 -- Object Expressions" only when requested by the caller. 6768 6769 if Spec_Expr_OK then 6770 null; 6771 6772 -- Ignore insert of actions from inside default expression (or other 6773 -- similar "spec expression") in the special spec-expression analyze 6774 -- mode. Any insertions at this point have no relevance, since we are 6775 -- only doing the analyze to freeze the types of any static expressions. 6776 -- See section "Handling of Default and Per-Object Expressions" in the 6777 -- spec of package Sem for further details. 6778 6779 elsif In_Spec_Expression then 6780 return; 6781 end if; 6782 6783 -- If the action derives from stuff inside a record, then the actions 6784 -- are attached to the current scope, to be inserted and analyzed on 6785 -- exit from the scope. The reason for this is that we may also be 6786 -- generating freeze actions at the same time, and they must eventually 6787 -- be elaborated in the correct order. 6788 6789 if Is_Record_Type (Current_Scope) 6790 and then not Is_Frozen (Current_Scope) 6791 then 6792 if No (Scope_Stack.Table 6793 (Scope_Stack.Last).Pending_Freeze_Actions) 6794 then 6795 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions := 6796 Ins_Actions; 6797 else 6798 Append_List 6799 (Ins_Actions, 6800 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions); 6801 end if; 6802 6803 return; 6804 end if; 6805 6806 -- We now intend to climb up the tree to find the right point to 6807 -- insert the actions. We start at Assoc_Node, unless this node is a 6808 -- subexpression in which case we start with its parent. We do this for 6809 -- two reasons. First it speeds things up. Second, if Assoc_Node is 6810 -- itself one of the special nodes like N_And_Then, then we assume that 6811 -- an initial request to insert actions for such a node does not expect 6812 -- the actions to get deposited in the node for later handling when the 6813 -- node is expanded, since clearly the node is being dealt with by the 6814 -- caller. Note that in the subexpression case, N is always the child we 6815 -- came from. 6816 6817 -- N_Raise_xxx_Error is an annoying special case, it is a statement 6818 -- if it has type Standard_Void_Type, and a subexpression otherwise. 6819 -- Procedure calls, and similarly procedure attribute references, are 6820 -- also statements. 6821 6822 if Nkind (Assoc_Node) in N_Subexpr 6823 and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error 6824 or else Etype (Assoc_Node) /= Standard_Void_Type) 6825 and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement 6826 and then (Nkind (Assoc_Node) /= N_Attribute_Reference 6827 or else not Is_Procedure_Attribute_Name 6828 (Attribute_Name (Assoc_Node))) 6829 then 6830 N := Assoc_Node; 6831 P := Parent (Assoc_Node); 6832 6833 -- Non-subexpression case. Note that N is initially Empty in this case 6834 -- (N is only guaranteed Non-Empty in the subexpr case). 6835 6836 else 6837 N := Empty; 6838 P := Assoc_Node; 6839 end if; 6840 6841 -- Capture root of the transient scope 6842 6843 if Scope_Is_Transient then 6844 Wrapped_Node := Node_To_Be_Wrapped; 6845 end if; 6846 6847 loop 6848 pragma Assert (Present (P)); 6849 6850 -- Make sure that inserted actions stay in the transient scope 6851 6852 if Present (Wrapped_Node) and then N = Wrapped_Node then 6853 Store_Before_Actions_In_Scope (Ins_Actions); 6854 return; 6855 end if; 6856 6857 case Nkind (P) is 6858 6859 -- Case of right operand of AND THEN or OR ELSE. Put the actions 6860 -- in the Actions field of the right operand. They will be moved 6861 -- out further when the AND THEN or OR ELSE operator is expanded. 6862 -- Nothing special needs to be done for the left operand since 6863 -- in that case the actions are executed unconditionally. 6864 6865 when N_Short_Circuit => 6866 if N = Right_Opnd (P) then 6867 6868 -- We are now going to either append the actions to the 6869 -- actions field of the short-circuit operation. We will 6870 -- also analyze the actions now. 6871 6872 -- This analysis is really too early, the proper thing would 6873 -- be to just park them there now, and only analyze them if 6874 -- we find we really need them, and to it at the proper 6875 -- final insertion point. However attempting to this proved 6876 -- tricky, so for now we just kill current values before and 6877 -- after the analyze call to make sure we avoid peculiar 6878 -- optimizations from this out of order insertion. 6879 6880 Kill_Current_Values; 6881 6882 -- If P has already been expanded, we can't park new actions 6883 -- on it, so we need to expand them immediately, introducing 6884 -- an Expression_With_Actions. N can't be an expression 6885 -- with actions, or else then the actions would have been 6886 -- inserted at an inner level. 6887 6888 if Analyzed (P) then 6889 pragma Assert (Nkind (N) /= N_Expression_With_Actions); 6890 Rewrite (N, 6891 Make_Expression_With_Actions (Sloc (N), 6892 Actions => Ins_Actions, 6893 Expression => Relocate_Node (N))); 6894 Analyze_And_Resolve (N); 6895 6896 elsif Present (Actions (P)) then 6897 Insert_List_After_And_Analyze 6898 (Last (Actions (P)), Ins_Actions); 6899 else 6900 Set_Actions (P, Ins_Actions); 6901 Analyze_List (Actions (P)); 6902 end if; 6903 6904 Kill_Current_Values; 6905 6906 return; 6907 end if; 6908 6909 -- Then or Else dependent expression of an if expression. Add 6910 -- actions to Then_Actions or Else_Actions field as appropriate. 6911 -- The actions will be moved further out when the if is expanded. 6912 6913 when N_If_Expression => 6914 declare 6915 ThenX : constant Node_Id := Next (First (Expressions (P))); 6916 ElseX : constant Node_Id := Next (ThenX); 6917 6918 begin 6919 -- If the enclosing expression is already analyzed, as 6920 -- is the case for nested elaboration checks, insert the 6921 -- conditional further out. 6922 6923 if Analyzed (P) then 6924 null; 6925 6926 -- Actions belong to the then expression, temporarily place 6927 -- them as Then_Actions of the if expression. They will be 6928 -- moved to the proper place later when the if expression 6929 -- is expanded. 6930 6931 elsif N = ThenX then 6932 if Present (Then_Actions (P)) then 6933 Insert_List_After_And_Analyze 6934 (Last (Then_Actions (P)), Ins_Actions); 6935 else 6936 Set_Then_Actions (P, Ins_Actions); 6937 Analyze_List (Then_Actions (P)); 6938 end if; 6939 6940 return; 6941 6942 -- Actions belong to the else expression, temporarily place 6943 -- them as Else_Actions of the if expression. They will be 6944 -- moved to the proper place later when the if expression 6945 -- is expanded. 6946 6947 elsif N = ElseX then 6948 if Present (Else_Actions (P)) then 6949 Insert_List_After_And_Analyze 6950 (Last (Else_Actions (P)), Ins_Actions); 6951 else 6952 Set_Else_Actions (P, Ins_Actions); 6953 Analyze_List (Else_Actions (P)); 6954 end if; 6955 6956 return; 6957 6958 -- Actions belong to the condition. In this case they are 6959 -- unconditionally executed, and so we can continue the 6960 -- search for the proper insert point. 6961 6962 else 6963 null; 6964 end if; 6965 end; 6966 6967 -- Alternative of case expression, we place the action in the 6968 -- Actions field of the case expression alternative, this will 6969 -- be handled when the case expression is expanded. 6970 6971 when N_Case_Expression_Alternative => 6972 if Present (Actions (P)) then 6973 Insert_List_After_And_Analyze 6974 (Last (Actions (P)), Ins_Actions); 6975 else 6976 Set_Actions (P, Ins_Actions); 6977 Analyze_List (Actions (P)); 6978 end if; 6979 6980 return; 6981 6982 -- Case of appearing within an Expressions_With_Actions node. When 6983 -- the new actions come from the expression of the expression with 6984 -- actions, they must be added to the existing actions. The other 6985 -- alternative is when the new actions are related to one of the 6986 -- existing actions of the expression with actions, and should 6987 -- never reach here: if actions are inserted on a statement 6988 -- within the Actions of an expression with actions, or on some 6989 -- subexpression of such a statement, then the outermost proper 6990 -- insertion point is right before the statement, and we should 6991 -- never climb up as far as the N_Expression_With_Actions itself. 6992 6993 when N_Expression_With_Actions => 6994 if N = Expression (P) then 6995 if Is_Empty_List (Actions (P)) then 6996 Append_List_To (Actions (P), Ins_Actions); 6997 Analyze_List (Actions (P)); 6998 else 6999 Insert_List_After_And_Analyze 7000 (Last (Actions (P)), Ins_Actions); 7001 end if; 7002 7003 return; 7004 7005 else 7006 raise Program_Error; 7007 end if; 7008 7009 -- Case of appearing in the condition of a while expression or 7010 -- elsif. We insert the actions into the Condition_Actions field. 7011 -- They will be moved further out when the while loop or elsif 7012 -- is analyzed. 7013 7014 when N_Elsif_Part 7015 | N_Iteration_Scheme 7016 => 7017 if N = Condition (P) then 7018 if Present (Condition_Actions (P)) then 7019 Insert_List_After_And_Analyze 7020 (Last (Condition_Actions (P)), Ins_Actions); 7021 else 7022 Set_Condition_Actions (P, Ins_Actions); 7023 7024 -- Set the parent of the insert actions explicitly. This 7025 -- is not a syntactic field, but we need the parent field 7026 -- set, in particular so that freeze can understand that 7027 -- it is dealing with condition actions, and properly 7028 -- insert the freezing actions. 7029 7030 Set_Parent (Ins_Actions, P); 7031 Analyze_List (Condition_Actions (P)); 7032 end if; 7033 7034 return; 7035 end if; 7036 7037 -- Statements, declarations, pragmas, representation clauses 7038 7039 when 7040 -- Statements 7041 7042 N_Procedure_Call_Statement 7043 | N_Statement_Other_Than_Procedure_Call 7044 7045 -- Pragmas 7046 7047 | N_Pragma 7048 7049 -- Representation_Clause 7050 7051 | N_At_Clause 7052 | N_Attribute_Definition_Clause 7053 | N_Enumeration_Representation_Clause 7054 | N_Record_Representation_Clause 7055 7056 -- Declarations 7057 7058 | N_Abstract_Subprogram_Declaration 7059 | N_Entry_Body 7060 | N_Exception_Declaration 7061 | N_Exception_Renaming_Declaration 7062 | N_Expression_Function 7063 | N_Formal_Abstract_Subprogram_Declaration 7064 | N_Formal_Concrete_Subprogram_Declaration 7065 | N_Formal_Object_Declaration 7066 | N_Formal_Type_Declaration 7067 | N_Full_Type_Declaration 7068 | N_Function_Instantiation 7069 | N_Generic_Function_Renaming_Declaration 7070 | N_Generic_Package_Declaration 7071 | N_Generic_Package_Renaming_Declaration 7072 | N_Generic_Procedure_Renaming_Declaration 7073 | N_Generic_Subprogram_Declaration 7074 | N_Implicit_Label_Declaration 7075 | N_Incomplete_Type_Declaration 7076 | N_Number_Declaration 7077 | N_Object_Declaration 7078 | N_Object_Renaming_Declaration 7079 | N_Package_Body 7080 | N_Package_Body_Stub 7081 | N_Package_Declaration 7082 | N_Package_Instantiation 7083 | N_Package_Renaming_Declaration 7084 | N_Private_Extension_Declaration 7085 | N_Private_Type_Declaration 7086 | N_Procedure_Instantiation 7087 | N_Protected_Body 7088 | N_Protected_Body_Stub 7089 | N_Single_Task_Declaration 7090 | N_Subprogram_Body 7091 | N_Subprogram_Body_Stub 7092 | N_Subprogram_Declaration 7093 | N_Subprogram_Renaming_Declaration 7094 | N_Subtype_Declaration 7095 | N_Task_Body 7096 | N_Task_Body_Stub 7097 7098 -- Use clauses can appear in lists of declarations 7099 7100 | N_Use_Package_Clause 7101 | N_Use_Type_Clause 7102 7103 -- Freeze entity behaves like a declaration or statement 7104 7105 | N_Freeze_Entity 7106 | N_Freeze_Generic_Entity 7107 => 7108 -- Do not insert here if the item is not a list member (this 7109 -- happens for example with a triggering statement, and the 7110 -- proper approach is to insert before the entire select). 7111 7112 if not Is_List_Member (P) then 7113 null; 7114 7115 -- Do not insert if parent of P is an N_Component_Association 7116 -- node (i.e. we are in the context of an N_Aggregate or 7117 -- N_Extension_Aggregate node. In this case we want to insert 7118 -- before the entire aggregate. 7119 7120 elsif Nkind (Parent (P)) = N_Component_Association then 7121 null; 7122 7123 -- Do not insert if the parent of P is either an N_Variant node 7124 -- or an N_Record_Definition node, meaning in either case that 7125 -- P is a member of a component list, and that therefore the 7126 -- actions should be inserted outside the complete record 7127 -- declaration. 7128 7129 elsif Nkind_In (Parent (P), N_Variant, N_Record_Definition) then 7130 null; 7131 7132 -- Do not insert freeze nodes within the loop generated for 7133 -- an aggregate, because they may be elaborated too late for 7134 -- subsequent use in the back end: within a package spec the 7135 -- loop is part of the elaboration procedure and is only 7136 -- elaborated during the second pass. 7137 7138 -- If the loop comes from source, or the entity is local to the 7139 -- loop itself it must remain within. 7140 7141 elsif Nkind (Parent (P)) = N_Loop_Statement 7142 and then not Comes_From_Source (Parent (P)) 7143 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity 7144 and then 7145 Scope (Entity (First (Ins_Actions))) /= Current_Scope 7146 then 7147 null; 7148 7149 -- Otherwise we can go ahead and do the insertion 7150 7151 elsif P = Wrapped_Node then 7152 Store_Before_Actions_In_Scope (Ins_Actions); 7153 return; 7154 7155 else 7156 Insert_List_Before_And_Analyze (P, Ins_Actions); 7157 return; 7158 end if; 7159 7160 -- the expansion of Task and protected type declarations can 7161 -- create declarations for temporaries which, like other actions 7162 -- are inserted and analyzed before the current declaraation. 7163 -- However, the current scope is the synchronized type, and 7164 -- for unnesting it is critical that the proper scope for these 7165 -- generated entities be the enclosing one. 7166 7167 when N_Task_Type_Declaration 7168 | N_Protected_Type_Declaration => 7169 7170 Push_Scope (Scope (Current_Scope)); 7171 Insert_List_Before_And_Analyze (P, Ins_Actions); 7172 Pop_Scope; 7173 return; 7174 7175 -- A special case, N_Raise_xxx_Error can act either as a statement 7176 -- or a subexpression. We tell the difference by looking at the 7177 -- Etype. It is set to Standard_Void_Type in the statement case. 7178 7179 when N_Raise_xxx_Error => 7180 if Etype (P) = Standard_Void_Type then 7181 if P = Wrapped_Node then 7182 Store_Before_Actions_In_Scope (Ins_Actions); 7183 else 7184 Insert_List_Before_And_Analyze (P, Ins_Actions); 7185 end if; 7186 7187 return; 7188 7189 -- In the subexpression case, keep climbing 7190 7191 else 7192 null; 7193 end if; 7194 7195 -- If a component association appears within a loop created for 7196 -- an array aggregate, attach the actions to the association so 7197 -- they can be subsequently inserted within the loop. For other 7198 -- component associations insert outside of the aggregate. For 7199 -- an association that will generate a loop, its Loop_Actions 7200 -- attribute is already initialized (see exp_aggr.adb). 7201 7202 -- The list of Loop_Actions can in turn generate additional ones, 7203 -- that are inserted before the associated node. If the associated 7204 -- node is outside the aggregate, the new actions are collected 7205 -- at the end of the Loop_Actions, to respect the order in which 7206 -- they are to be elaborated. 7207 7208 when N_Component_Association 7209 | N_Iterated_Component_Association 7210 => 7211 if Nkind (Parent (P)) = N_Aggregate 7212 and then Present (Loop_Actions (P)) 7213 then 7214 if Is_Empty_List (Loop_Actions (P)) then 7215 Set_Loop_Actions (P, Ins_Actions); 7216 Analyze_List (Ins_Actions); 7217 else 7218 declare 7219 Decl : Node_Id; 7220 7221 begin 7222 -- Check whether these actions were generated by a 7223 -- declaration that is part of the Loop_Actions for 7224 -- the component_association. 7225 7226 Decl := Assoc_Node; 7227 while Present (Decl) loop 7228 exit when Parent (Decl) = P 7229 and then Is_List_Member (Decl) 7230 and then 7231 List_Containing (Decl) = Loop_Actions (P); 7232 Decl := Parent (Decl); 7233 end loop; 7234 7235 if Present (Decl) then 7236 Insert_List_Before_And_Analyze 7237 (Decl, Ins_Actions); 7238 else 7239 Insert_List_After_And_Analyze 7240 (Last (Loop_Actions (P)), Ins_Actions); 7241 end if; 7242 end; 7243 end if; 7244 7245 return; 7246 7247 else 7248 null; 7249 end if; 7250 7251 -- Special case: an attribute denoting a procedure call 7252 7253 when N_Attribute_Reference => 7254 if Is_Procedure_Attribute_Name (Attribute_Name (P)) then 7255 if P = Wrapped_Node then 7256 Store_Before_Actions_In_Scope (Ins_Actions); 7257 else 7258 Insert_List_Before_And_Analyze (P, Ins_Actions); 7259 end if; 7260 7261 return; 7262 7263 -- In the subexpression case, keep climbing 7264 7265 else 7266 null; 7267 end if; 7268 7269 -- Special case: a marker 7270 7271 when N_Call_Marker 7272 | N_Variable_Reference_Marker 7273 => 7274 if Is_List_Member (P) then 7275 Insert_List_Before_And_Analyze (P, Ins_Actions); 7276 return; 7277 end if; 7278 7279 -- A contract node should not belong to the tree 7280 7281 when N_Contract => 7282 raise Program_Error; 7283 7284 -- For all other node types, keep climbing tree 7285 7286 when N_Abortable_Part 7287 | N_Accept_Alternative 7288 | N_Access_Definition 7289 | N_Access_Function_Definition 7290 | N_Access_Procedure_Definition 7291 | N_Access_To_Object_Definition 7292 | N_Aggregate 7293 | N_Allocator 7294 | N_Aspect_Specification 7295 | N_Case_Expression 7296 | N_Case_Statement_Alternative 7297 | N_Character_Literal 7298 | N_Compilation_Unit 7299 | N_Compilation_Unit_Aux 7300 | N_Component_Clause 7301 | N_Component_Declaration 7302 | N_Component_Definition 7303 | N_Component_List 7304 | N_Constrained_Array_Definition 7305 | N_Decimal_Fixed_Point_Definition 7306 | N_Defining_Character_Literal 7307 | N_Defining_Identifier 7308 | N_Defining_Operator_Symbol 7309 | N_Defining_Program_Unit_Name 7310 | N_Delay_Alternative 7311 | N_Delta_Aggregate 7312 | N_Delta_Constraint 7313 | N_Derived_Type_Definition 7314 | N_Designator 7315 | N_Digits_Constraint 7316 | N_Discriminant_Association 7317 | N_Discriminant_Specification 7318 | N_Empty 7319 | N_Entry_Body_Formal_Part 7320 | N_Entry_Call_Alternative 7321 | N_Entry_Declaration 7322 | N_Entry_Index_Specification 7323 | N_Enumeration_Type_Definition 7324 | N_Error 7325 | N_Exception_Handler 7326 | N_Expanded_Name 7327 | N_Explicit_Dereference 7328 | N_Extension_Aggregate 7329 | N_Floating_Point_Definition 7330 | N_Formal_Decimal_Fixed_Point_Definition 7331 | N_Formal_Derived_Type_Definition 7332 | N_Formal_Discrete_Type_Definition 7333 | N_Formal_Floating_Point_Definition 7334 | N_Formal_Modular_Type_Definition 7335 | N_Formal_Ordinary_Fixed_Point_Definition 7336 | N_Formal_Package_Declaration 7337 | N_Formal_Private_Type_Definition 7338 | N_Formal_Incomplete_Type_Definition 7339 | N_Formal_Signed_Integer_Type_Definition 7340 | N_Function_Call 7341 | N_Function_Specification 7342 | N_Generic_Association 7343 | N_Handled_Sequence_Of_Statements 7344 | N_Identifier 7345 | N_In 7346 | N_Index_Or_Discriminant_Constraint 7347 | N_Indexed_Component 7348 | N_Integer_Literal 7349 | N_Iterator_Specification 7350 | N_Itype_Reference 7351 | N_Label 7352 | N_Loop_Parameter_Specification 7353 | N_Mod_Clause 7354 | N_Modular_Type_Definition 7355 | N_Not_In 7356 | N_Null 7357 | N_Op_Abs 7358 | N_Op_Add 7359 | N_Op_And 7360 | N_Op_Concat 7361 | N_Op_Divide 7362 | N_Op_Eq 7363 | N_Op_Expon 7364 | N_Op_Ge 7365 | N_Op_Gt 7366 | N_Op_Le 7367 | N_Op_Lt 7368 | N_Op_Minus 7369 | N_Op_Mod 7370 | N_Op_Multiply 7371 | N_Op_Ne 7372 | N_Op_Not 7373 | N_Op_Or 7374 | N_Op_Plus 7375 | N_Op_Rem 7376 | N_Op_Rotate_Left 7377 | N_Op_Rotate_Right 7378 | N_Op_Shift_Left 7379 | N_Op_Shift_Right 7380 | N_Op_Shift_Right_Arithmetic 7381 | N_Op_Subtract 7382 | N_Op_Xor 7383 | N_Operator_Symbol 7384 | N_Ordinary_Fixed_Point_Definition 7385 | N_Others_Choice 7386 | N_Package_Specification 7387 | N_Parameter_Association 7388 | N_Parameter_Specification 7389 | N_Pop_Constraint_Error_Label 7390 | N_Pop_Program_Error_Label 7391 | N_Pop_Storage_Error_Label 7392 | N_Pragma_Argument_Association 7393 | N_Procedure_Specification 7394 | N_Protected_Definition 7395 | N_Push_Constraint_Error_Label 7396 | N_Push_Program_Error_Label 7397 | N_Push_Storage_Error_Label 7398 | N_Qualified_Expression 7399 | N_Quantified_Expression 7400 | N_Raise_Expression 7401 | N_Range 7402 | N_Range_Constraint 7403 | N_Real_Literal 7404 | N_Real_Range_Specification 7405 | N_Record_Definition 7406 | N_Reference 7407 | N_SCIL_Dispatch_Table_Tag_Init 7408 | N_SCIL_Dispatching_Call 7409 | N_SCIL_Membership_Test 7410 | N_Selected_Component 7411 | N_Signed_Integer_Type_Definition 7412 | N_Single_Protected_Declaration 7413 | N_Slice 7414 | N_String_Literal 7415 | N_Subtype_Indication 7416 | N_Subunit 7417 | N_Target_Name 7418 | N_Task_Definition 7419 | N_Terminate_Alternative 7420 | N_Triggering_Alternative 7421 | N_Type_Conversion 7422 | N_Unchecked_Expression 7423 | N_Unchecked_Type_Conversion 7424 | N_Unconstrained_Array_Definition 7425 | N_Unused_At_End 7426 | N_Unused_At_Start 7427 | N_Variant 7428 | N_Variant_Part 7429 | N_Validate_Unchecked_Conversion 7430 | N_With_Clause 7431 => 7432 null; 7433 end case; 7434 7435 -- If we fall through above tests, keep climbing tree 7436 7437 N := P; 7438 7439 if Nkind (Parent (N)) = N_Subunit then 7440 7441 -- This is the proper body corresponding to a stub. Insertion must 7442 -- be done at the point of the stub, which is in the declarative 7443 -- part of the parent unit. 7444 7445 P := Corresponding_Stub (Parent (N)); 7446 7447 else 7448 P := Parent (N); 7449 end if; 7450 end loop; 7451 end Insert_Actions; 7452 7453 -- Version with check(s) suppressed 7454 7455 procedure Insert_Actions 7456 (Assoc_Node : Node_Id; 7457 Ins_Actions : List_Id; 7458 Suppress : Check_Id; 7459 Spec_Expr_OK : Boolean := False) 7460 is 7461 begin 7462 if Suppress = All_Checks then 7463 declare 7464 Sva : constant Suppress_Array := Scope_Suppress.Suppress; 7465 begin 7466 Scope_Suppress.Suppress := (others => True); 7467 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK); 7468 Scope_Suppress.Suppress := Sva; 7469 end; 7470 7471 else 7472 declare 7473 Svg : constant Boolean := Scope_Suppress.Suppress (Suppress); 7474 begin 7475 Scope_Suppress.Suppress (Suppress) := True; 7476 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK); 7477 Scope_Suppress.Suppress (Suppress) := Svg; 7478 end; 7479 end if; 7480 end Insert_Actions; 7481 7482 -------------------------- 7483 -- Insert_Actions_After -- 7484 -------------------------- 7485 7486 procedure Insert_Actions_After 7487 (Assoc_Node : Node_Id; 7488 Ins_Actions : List_Id) 7489 is 7490 begin 7491 if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then 7492 Store_After_Actions_In_Scope (Ins_Actions); 7493 else 7494 Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions); 7495 end if; 7496 end Insert_Actions_After; 7497 7498 ------------------------ 7499 -- Insert_Declaration -- 7500 ------------------------ 7501 7502 procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is 7503 P : Node_Id; 7504 7505 begin 7506 pragma Assert (Nkind (N) in N_Subexpr); 7507 7508 -- Climb until we find a procedure or a package 7509 7510 P := N; 7511 loop 7512 pragma Assert (Present (Parent (P))); 7513 P := Parent (P); 7514 7515 if Is_List_Member (P) then 7516 exit when Nkind_In (Parent (P), N_Package_Specification, 7517 N_Subprogram_Body); 7518 7519 -- Special handling for handled sequence of statements, we must 7520 -- insert in the statements not the exception handlers! 7521 7522 if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then 7523 P := First (Statements (Parent (P))); 7524 exit; 7525 end if; 7526 end if; 7527 end loop; 7528 7529 -- Now do the insertion 7530 7531 Insert_Before (P, Decl); 7532 Analyze (Decl); 7533 end Insert_Declaration; 7534 7535 --------------------------------- 7536 -- Insert_Library_Level_Action -- 7537 --------------------------------- 7538 7539 procedure Insert_Library_Level_Action (N : Node_Id) is 7540 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit)); 7541 7542 begin 7543 Push_Scope (Cunit_Entity (Current_Sem_Unit)); 7544 -- And not Main_Unit as previously. If the main unit is a body, 7545 -- the scope needed to analyze the actions is the entity of the 7546 -- corresponding declaration. 7547 7548 if No (Actions (Aux)) then 7549 Set_Actions (Aux, New_List (N)); 7550 else 7551 Append (N, Actions (Aux)); 7552 end if; 7553 7554 Analyze (N); 7555 Pop_Scope; 7556 end Insert_Library_Level_Action; 7557 7558 ---------------------------------- 7559 -- Insert_Library_Level_Actions -- 7560 ---------------------------------- 7561 7562 procedure Insert_Library_Level_Actions (L : List_Id) is 7563 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit)); 7564 7565 begin 7566 if Is_Non_Empty_List (L) then 7567 Push_Scope (Cunit_Entity (Main_Unit)); 7568 -- ??? should this be Current_Sem_Unit instead of Main_Unit? 7569 7570 if No (Actions (Aux)) then 7571 Set_Actions (Aux, L); 7572 Analyze_List (L); 7573 else 7574 Insert_List_After_And_Analyze (Last (Actions (Aux)), L); 7575 end if; 7576 7577 Pop_Scope; 7578 end if; 7579 end Insert_Library_Level_Actions; 7580 7581 ---------------------- 7582 -- Inside_Init_Proc -- 7583 ---------------------- 7584 7585 function Inside_Init_Proc return Boolean is 7586 Proc : constant Entity_Id := Enclosing_Init_Proc; 7587 7588 begin 7589 return Proc /= Empty; 7590 end Inside_Init_Proc; 7591 7592 ---------------------------- 7593 -- Is_All_Null_Statements -- 7594 ---------------------------- 7595 7596 function Is_All_Null_Statements (L : List_Id) return Boolean is 7597 Stm : Node_Id; 7598 7599 begin 7600 Stm := First (L); 7601 while Present (Stm) loop 7602 if Nkind (Stm) /= N_Null_Statement then 7603 return False; 7604 end if; 7605 7606 Next (Stm); 7607 end loop; 7608 7609 return True; 7610 end Is_All_Null_Statements; 7611 7612 -------------------------------------------------- 7613 -- Is_Displacement_Of_Object_Or_Function_Result -- 7614 -------------------------------------------------- 7615 7616 function Is_Displacement_Of_Object_Or_Function_Result 7617 (Obj_Id : Entity_Id) return Boolean 7618 is 7619 function Is_Controlled_Function_Call (N : Node_Id) return Boolean; 7620 -- Determine whether node N denotes a controlled function call 7621 7622 function Is_Controlled_Indexing (N : Node_Id) return Boolean; 7623 -- Determine whether node N denotes a generalized indexing form which 7624 -- involves a controlled result. 7625 7626 function Is_Displace_Call (N : Node_Id) return Boolean; 7627 -- Determine whether node N denotes a call to Ada.Tags.Displace 7628 7629 function Is_Source_Object (N : Node_Id) return Boolean; 7630 -- Determine whether a particular node denotes a source object 7631 7632 function Strip (N : Node_Id) return Node_Id; 7633 -- Examine arbitrary node N by stripping various indirections and return 7634 -- the "real" node. 7635 7636 --------------------------------- 7637 -- Is_Controlled_Function_Call -- 7638 --------------------------------- 7639 7640 function Is_Controlled_Function_Call (N : Node_Id) return Boolean is 7641 Expr : Node_Id; 7642 7643 begin 7644 -- When a function call appears in Object.Operation format, the 7645 -- original representation has several possible forms depending on 7646 -- the availability and form of actual parameters: 7647 7648 -- Obj.Func N_Selected_Component 7649 -- Obj.Func (Actual) N_Indexed_Component 7650 -- Obj.Func (Formal => Actual) N_Function_Call, whose Name is an 7651 -- N_Selected_Component 7652 7653 Expr := Original_Node (N); 7654 loop 7655 if Nkind (Expr) = N_Function_Call then 7656 Expr := Name (Expr); 7657 7658 -- "Obj.Func (Actual)" case 7659 7660 elsif Nkind (Expr) = N_Indexed_Component then 7661 Expr := Prefix (Expr); 7662 7663 -- "Obj.Func" or "Obj.Func (Formal => Actual) case 7664 7665 elsif Nkind (Expr) = N_Selected_Component then 7666 Expr := Selector_Name (Expr); 7667 7668 else 7669 exit; 7670 end if; 7671 end loop; 7672 7673 return 7674 Nkind (Expr) in N_Has_Entity 7675 and then Present (Entity (Expr)) 7676 and then Ekind (Entity (Expr)) = E_Function 7677 and then Needs_Finalization (Etype (Entity (Expr))); 7678 end Is_Controlled_Function_Call; 7679 7680 ---------------------------- 7681 -- Is_Controlled_Indexing -- 7682 ---------------------------- 7683 7684 function Is_Controlled_Indexing (N : Node_Id) return Boolean is 7685 Expr : constant Node_Id := Original_Node (N); 7686 7687 begin 7688 return 7689 Nkind (Expr) = N_Indexed_Component 7690 and then Present (Generalized_Indexing (Expr)) 7691 and then Needs_Finalization (Etype (Expr)); 7692 end Is_Controlled_Indexing; 7693 7694 ---------------------- 7695 -- Is_Displace_Call -- 7696 ---------------------- 7697 7698 function Is_Displace_Call (N : Node_Id) return Boolean is 7699 Call : constant Node_Id := Strip (N); 7700 7701 begin 7702 return 7703 Present (Call) 7704 and then Nkind (Call) = N_Function_Call 7705 and then Nkind (Name (Call)) in N_Has_Entity 7706 and then Is_RTE (Entity (Name (Call)), RE_Displace); 7707 end Is_Displace_Call; 7708 7709 ---------------------- 7710 -- Is_Source_Object -- 7711 ---------------------- 7712 7713 function Is_Source_Object (N : Node_Id) return Boolean is 7714 Obj : constant Node_Id := Strip (N); 7715 7716 begin 7717 return 7718 Present (Obj) 7719 and then Comes_From_Source (Obj) 7720 and then Nkind (Obj) in N_Has_Entity 7721 and then Is_Object (Entity (Obj)); 7722 end Is_Source_Object; 7723 7724 ----------- 7725 -- Strip -- 7726 ----------- 7727 7728 function Strip (N : Node_Id) return Node_Id is 7729 Result : Node_Id; 7730 7731 begin 7732 Result := N; 7733 loop 7734 if Nkind (Result) = N_Explicit_Dereference then 7735 Result := Prefix (Result); 7736 7737 elsif Nkind_In (Result, N_Type_Conversion, 7738 N_Unchecked_Type_Conversion) 7739 then 7740 Result := Expression (Result); 7741 7742 else 7743 exit; 7744 end if; 7745 end loop; 7746 7747 return Result; 7748 end Strip; 7749 7750 -- Local variables 7751 7752 Obj_Decl : constant Node_Id := Declaration_Node (Obj_Id); 7753 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 7754 Orig_Decl : constant Node_Id := Original_Node (Obj_Decl); 7755 Orig_Expr : Node_Id; 7756 7757 -- Start of processing for Is_Displacement_Of_Object_Or_Function_Result 7758 7759 begin 7760 -- Case 1: 7761 7762 -- Obj : CW_Type := Function_Call (...); 7763 7764 -- is rewritten into: 7765 7766 -- Temp : ... := Function_Call (...)'reference; 7767 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp)); 7768 7769 -- where the return type of the function and the class-wide type require 7770 -- dispatch table pointer displacement. 7771 7772 -- Case 2: 7773 7774 -- Obj : CW_Type := Container (...); 7775 7776 -- is rewritten into: 7777 7778 -- Temp : ... := Function_Call (Container, ...)'reference; 7779 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp)); 7780 7781 -- where the container element type and the class-wide type require 7782 -- dispatch table pointer dispacement. 7783 7784 -- Case 3: 7785 7786 -- Obj : CW_Type := Src_Obj; 7787 7788 -- is rewritten into: 7789 7790 -- Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj)); 7791 7792 -- where the type of the source object and the class-wide type require 7793 -- dispatch table pointer displacement. 7794 7795 if Nkind (Obj_Decl) = N_Object_Renaming_Declaration 7796 and then Is_Class_Wide_Type (Obj_Typ) 7797 and then Is_Displace_Call (Renamed_Object (Obj_Id)) 7798 and then Nkind (Orig_Decl) = N_Object_Declaration 7799 and then Comes_From_Source (Orig_Decl) 7800 then 7801 Orig_Expr := Expression (Orig_Decl); 7802 7803 return 7804 Is_Controlled_Function_Call (Orig_Expr) 7805 or else Is_Controlled_Indexing (Orig_Expr) 7806 or else Is_Source_Object (Orig_Expr); 7807 end if; 7808 7809 return False; 7810 end Is_Displacement_Of_Object_Or_Function_Result; 7811 7812 ------------------------------ 7813 -- Is_Finalizable_Transient -- 7814 ------------------------------ 7815 7816 function Is_Finalizable_Transient 7817 (Decl : Node_Id; 7818 Rel_Node : Node_Id) return Boolean 7819 is 7820 Obj_Id : constant Entity_Id := Defining_Identifier (Decl); 7821 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 7822 7823 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean; 7824 -- Determine whether transient object Trans_Id is initialized either 7825 -- by a function call which returns an access type or simply renames 7826 -- another pointer. 7827 7828 function Initialized_By_Aliased_BIP_Func_Call 7829 (Trans_Id : Entity_Id) return Boolean; 7830 -- Determine whether transient object Trans_Id is initialized by a 7831 -- build-in-place function call where the BIPalloc parameter is of 7832 -- value 1 and BIPaccess is not null. This case creates an aliasing 7833 -- between the returned value and the value denoted by BIPaccess. 7834 7835 function Is_Aliased 7836 (Trans_Id : Entity_Id; 7837 First_Stmt : Node_Id) return Boolean; 7838 -- Determine whether transient object Trans_Id has been renamed or 7839 -- aliased through 'reference in the statement list starting from 7840 -- First_Stmt. 7841 7842 function Is_Allocated (Trans_Id : Entity_Id) return Boolean; 7843 -- Determine whether transient object Trans_Id is allocated on the heap 7844 7845 function Is_Iterated_Container 7846 (Trans_Id : Entity_Id; 7847 First_Stmt : Node_Id) return Boolean; 7848 -- Determine whether transient object Trans_Id denotes a container which 7849 -- is in the process of being iterated in the statement list starting 7850 -- from First_Stmt. 7851 7852 --------------------------- 7853 -- Initialized_By_Access -- 7854 --------------------------- 7855 7856 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is 7857 Expr : constant Node_Id := Expression (Parent (Trans_Id)); 7858 7859 begin 7860 return 7861 Present (Expr) 7862 and then Nkind (Expr) /= N_Reference 7863 and then Is_Access_Type (Etype (Expr)); 7864 end Initialized_By_Access; 7865 7866 ------------------------------------------ 7867 -- Initialized_By_Aliased_BIP_Func_Call -- 7868 ------------------------------------------ 7869 7870 function Initialized_By_Aliased_BIP_Func_Call 7871 (Trans_Id : Entity_Id) return Boolean 7872 is 7873 Call : Node_Id := Expression (Parent (Trans_Id)); 7874 7875 begin 7876 -- Build-in-place calls usually appear in 'reference format 7877 7878 if Nkind (Call) = N_Reference then 7879 Call := Prefix (Call); 7880 end if; 7881 7882 Call := Unqual_Conv (Call); 7883 7884 if Is_Build_In_Place_Function_Call (Call) then 7885 declare 7886 Access_Nam : Name_Id := No_Name; 7887 Access_OK : Boolean := False; 7888 Actual : Node_Id; 7889 Alloc_Nam : Name_Id := No_Name; 7890 Alloc_OK : Boolean := False; 7891 Formal : Node_Id; 7892 Func_Id : Entity_Id; 7893 Param : Node_Id; 7894 7895 begin 7896 -- Examine all parameter associations of the function call 7897 7898 Param := First (Parameter_Associations (Call)); 7899 while Present (Param) loop 7900 if Nkind (Param) = N_Parameter_Association 7901 and then Nkind (Selector_Name (Param)) = N_Identifier 7902 then 7903 Actual := Explicit_Actual_Parameter (Param); 7904 Formal := Selector_Name (Param); 7905 7906 -- Construct the names of formals BIPaccess and BIPalloc 7907 -- using the function name retrieved from an arbitrary 7908 -- formal. 7909 7910 if Access_Nam = No_Name 7911 and then Alloc_Nam = No_Name 7912 and then Present (Entity (Formal)) 7913 then 7914 Func_Id := Scope (Entity (Formal)); 7915 7916 Access_Nam := 7917 New_External_Name (Chars (Func_Id), 7918 BIP_Formal_Suffix (BIP_Object_Access)); 7919 7920 Alloc_Nam := 7921 New_External_Name (Chars (Func_Id), 7922 BIP_Formal_Suffix (BIP_Alloc_Form)); 7923 end if; 7924 7925 -- A match for BIPaccess => Temp has been found 7926 7927 if Chars (Formal) = Access_Nam 7928 and then Nkind (Actual) /= N_Null 7929 then 7930 Access_OK := True; 7931 end if; 7932 7933 -- A match for BIPalloc => 1 has been found 7934 7935 if Chars (Formal) = Alloc_Nam 7936 and then Nkind (Actual) = N_Integer_Literal 7937 and then Intval (Actual) = Uint_1 7938 then 7939 Alloc_OK := True; 7940 end if; 7941 end if; 7942 7943 Next (Param); 7944 end loop; 7945 7946 return Access_OK and Alloc_OK; 7947 end; 7948 end if; 7949 7950 return False; 7951 end Initialized_By_Aliased_BIP_Func_Call; 7952 7953 ---------------- 7954 -- Is_Aliased -- 7955 ---------------- 7956 7957 function Is_Aliased 7958 (Trans_Id : Entity_Id; 7959 First_Stmt : Node_Id) return Boolean 7960 is 7961 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id; 7962 -- Given an object renaming declaration, retrieve the entity of the 7963 -- renamed name. Return Empty if the renamed name is anything other 7964 -- than a variable or a constant. 7965 7966 ------------------------- 7967 -- Find_Renamed_Object -- 7968 ------------------------- 7969 7970 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is 7971 Ren_Obj : Node_Id := Empty; 7972 7973 function Find_Object (N : Node_Id) return Traverse_Result; 7974 -- Try to detect an object which is either a constant or a 7975 -- variable. 7976 7977 ----------------- 7978 -- Find_Object -- 7979 ----------------- 7980 7981 function Find_Object (N : Node_Id) return Traverse_Result is 7982 begin 7983 -- Stop the search once a constant or a variable has been 7984 -- detected. 7985 7986 if Nkind (N) = N_Identifier 7987 and then Present (Entity (N)) 7988 and then Ekind_In (Entity (N), E_Constant, E_Variable) 7989 then 7990 Ren_Obj := Entity (N); 7991 return Abandon; 7992 end if; 7993 7994 return OK; 7995 end Find_Object; 7996 7997 procedure Search is new Traverse_Proc (Find_Object); 7998 7999 -- Local variables 8000 8001 Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl)); 8002 8003 -- Start of processing for Find_Renamed_Object 8004 8005 begin 8006 -- Actions related to dispatching calls may appear as renamings of 8007 -- tags. Do not process this type of renaming because it does not 8008 -- use the actual value of the object. 8009 8010 if not Is_RTE (Typ, RE_Tag_Ptr) then 8011 Search (Name (Ren_Decl)); 8012 end if; 8013 8014 return Ren_Obj; 8015 end Find_Renamed_Object; 8016 8017 -- Local variables 8018 8019 Expr : Node_Id; 8020 Ren_Obj : Entity_Id; 8021 Stmt : Node_Id; 8022 8023 -- Start of processing for Is_Aliased 8024 8025 begin 8026 -- A controlled transient object is not considered aliased when it 8027 -- appears inside an expression_with_actions node even when there are 8028 -- explicit aliases of it: 8029 8030 -- do 8031 -- Trans_Id : Ctrl_Typ ...; -- transient object 8032 -- Alias : ... := Trans_Id; -- object is aliased 8033 -- Val : constant Boolean := 8034 -- ... Alias ...; -- aliasing ends 8035 -- <finalize Trans_Id> -- object safe to finalize 8036 -- in Val end; 8037 8038 -- Expansion ensures that all aliases are encapsulated in the actions 8039 -- list and do not leak to the expression by forcing the evaluation 8040 -- of the expression. 8041 8042 if Nkind (Rel_Node) = N_Expression_With_Actions then 8043 return False; 8044 8045 -- Otherwise examine the statements after the controlled transient 8046 -- object and look for various forms of aliasing. 8047 8048 else 8049 Stmt := First_Stmt; 8050 while Present (Stmt) loop 8051 if Nkind (Stmt) = N_Object_Declaration then 8052 Expr := Expression (Stmt); 8053 8054 -- Aliasing of the form: 8055 -- Obj : ... := Trans_Id'reference; 8056 8057 if Present (Expr) 8058 and then Nkind (Expr) = N_Reference 8059 and then Nkind (Prefix (Expr)) = N_Identifier 8060 and then Entity (Prefix (Expr)) = Trans_Id 8061 then 8062 return True; 8063 end if; 8064 8065 elsif Nkind (Stmt) = N_Object_Renaming_Declaration then 8066 Ren_Obj := Find_Renamed_Object (Stmt); 8067 8068 -- Aliasing of the form: 8069 -- Obj : ... renames ... Trans_Id ...; 8070 8071 if Present (Ren_Obj) and then Ren_Obj = Trans_Id then 8072 return True; 8073 end if; 8074 end if; 8075 8076 Next (Stmt); 8077 end loop; 8078 8079 return False; 8080 end if; 8081 end Is_Aliased; 8082 8083 ------------------ 8084 -- Is_Allocated -- 8085 ------------------ 8086 8087 function Is_Allocated (Trans_Id : Entity_Id) return Boolean is 8088 Expr : constant Node_Id := Expression (Parent (Trans_Id)); 8089 begin 8090 return 8091 Is_Access_Type (Etype (Trans_Id)) 8092 and then Present (Expr) 8093 and then Nkind (Expr) = N_Allocator; 8094 end Is_Allocated; 8095 8096 --------------------------- 8097 -- Is_Iterated_Container -- 8098 --------------------------- 8099 8100 function Is_Iterated_Container 8101 (Trans_Id : Entity_Id; 8102 First_Stmt : Node_Id) return Boolean 8103 is 8104 Aspect : Node_Id; 8105 Call : Node_Id; 8106 Iter : Entity_Id; 8107 Param : Node_Id; 8108 Stmt : Node_Id; 8109 Typ : Entity_Id; 8110 8111 begin 8112 -- It is not possible to iterate over containers in non-Ada 2012 code 8113 8114 if Ada_Version < Ada_2012 then 8115 return False; 8116 end if; 8117 8118 Typ := Etype (Trans_Id); 8119 8120 -- Handle access type created for secondary stack use 8121 8122 if Is_Access_Type (Typ) then 8123 Typ := Designated_Type (Typ); 8124 end if; 8125 8126 -- Look for aspect Default_Iterator. It may be part of a type 8127 -- declaration for a container, or inherited from a base type 8128 -- or parent type. 8129 8130 Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator); 8131 8132 if Present (Aspect) then 8133 Iter := Entity (Aspect); 8134 8135 -- Examine the statements following the container object and 8136 -- look for a call to the default iterate routine where the 8137 -- first parameter is the transient. Such a call appears as: 8138 8139 -- It : Access_To_CW_Iterator := 8140 -- Iterate (Tran_Id.all, ...)'reference; 8141 8142 Stmt := First_Stmt; 8143 while Present (Stmt) loop 8144 8145 -- Detect an object declaration which is initialized by a 8146 -- secondary stack function call. 8147 8148 if Nkind (Stmt) = N_Object_Declaration 8149 and then Present (Expression (Stmt)) 8150 and then Nkind (Expression (Stmt)) = N_Reference 8151 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call 8152 then 8153 Call := Prefix (Expression (Stmt)); 8154 8155 -- The call must invoke the default iterate routine of 8156 -- the container and the transient object must appear as 8157 -- the first actual parameter. Skip any calls whose names 8158 -- are not entities. 8159 8160 if Is_Entity_Name (Name (Call)) 8161 and then Entity (Name (Call)) = Iter 8162 and then Present (Parameter_Associations (Call)) 8163 then 8164 Param := First (Parameter_Associations (Call)); 8165 8166 if Nkind (Param) = N_Explicit_Dereference 8167 and then Entity (Prefix (Param)) = Trans_Id 8168 then 8169 return True; 8170 end if; 8171 end if; 8172 end if; 8173 8174 Next (Stmt); 8175 end loop; 8176 end if; 8177 8178 return False; 8179 end Is_Iterated_Container; 8180 8181 -- Local variables 8182 8183 Desig : Entity_Id := Obj_Typ; 8184 8185 -- Start of processing for Is_Finalizable_Transient 8186 8187 begin 8188 -- Handle access types 8189 8190 if Is_Access_Type (Desig) then 8191 Desig := Available_View (Designated_Type (Desig)); 8192 end if; 8193 8194 return 8195 Ekind_In (Obj_Id, E_Constant, E_Variable) 8196 and then Needs_Finalization (Desig) 8197 and then Requires_Transient_Scope (Desig) 8198 and then Nkind (Rel_Node) /= N_Simple_Return_Statement 8199 8200 -- Do not consider a transient object that was already processed 8201 8202 and then not Is_Finalized_Transient (Obj_Id) 8203 8204 -- Do not consider renamed or 'reference-d transient objects because 8205 -- the act of renaming extends the object's lifetime. 8206 8207 and then not Is_Aliased (Obj_Id, Decl) 8208 8209 -- Do not consider transient objects allocated on the heap since 8210 -- they are attached to a finalization master. 8211 8212 and then not Is_Allocated (Obj_Id) 8213 8214 -- If the transient object is a pointer, check that it is not 8215 -- initialized by a function that returns a pointer or acts as a 8216 -- renaming of another pointer. 8217 8218 and then 8219 (not Is_Access_Type (Obj_Typ) 8220 or else not Initialized_By_Access (Obj_Id)) 8221 8222 -- Do not consider transient objects which act as indirect aliases 8223 -- of build-in-place function results. 8224 8225 and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id) 8226 8227 -- Do not consider conversions of tags to class-wide types 8228 8229 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id) 8230 8231 -- Do not consider iterators because those are treated as normal 8232 -- controlled objects and are processed by the usual finalization 8233 -- machinery. This avoids the double finalization of an iterator. 8234 8235 and then not Is_Iterator (Desig) 8236 8237 -- Do not consider containers in the context of iterator loops. Such 8238 -- transient objects must exist for as long as the loop is around, 8239 -- otherwise any operation carried out by the iterator will fail. 8240 8241 and then not Is_Iterated_Container (Obj_Id, Decl); 8242 end Is_Finalizable_Transient; 8243 8244 --------------------------------- 8245 -- Is_Fully_Repped_Tagged_Type -- 8246 --------------------------------- 8247 8248 function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is 8249 U : constant Entity_Id := Underlying_Type (T); 8250 Comp : Entity_Id; 8251 8252 begin 8253 if No (U) or else not Is_Tagged_Type (U) then 8254 return False; 8255 elsif Has_Discriminants (U) then 8256 return False; 8257 elsif not Has_Specified_Layout (U) then 8258 return False; 8259 end if; 8260 8261 -- Here we have a tagged type, see if it has any unlayed out fields 8262 -- other than a possible tag and parent fields. If so, we return False. 8263 8264 Comp := First_Component (U); 8265 while Present (Comp) loop 8266 if not Is_Tag (Comp) 8267 and then Chars (Comp) /= Name_uParent 8268 and then No (Component_Clause (Comp)) 8269 then 8270 return False; 8271 else 8272 Next_Component (Comp); 8273 end if; 8274 end loop; 8275 8276 -- All components are layed out 8277 8278 return True; 8279 end Is_Fully_Repped_Tagged_Type; 8280 8281 ---------------------------------- 8282 -- Is_Library_Level_Tagged_Type -- 8283 ---------------------------------- 8284 8285 function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is 8286 begin 8287 return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ); 8288 end Is_Library_Level_Tagged_Type; 8289 8290 -------------------------- 8291 -- Is_Non_BIP_Func_Call -- 8292 -------------------------- 8293 8294 function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is 8295 begin 8296 -- The expected call is of the format 8297 -- 8298 -- Func_Call'reference 8299 8300 return 8301 Nkind (Expr) = N_Reference 8302 and then Nkind (Prefix (Expr)) = N_Function_Call 8303 and then not Is_Build_In_Place_Function_Call (Prefix (Expr)); 8304 end Is_Non_BIP_Func_Call; 8305 8306 ---------------------------------- 8307 -- Is_Possibly_Unaligned_Object -- 8308 ---------------------------------- 8309 8310 function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is 8311 T : constant Entity_Id := Etype (N); 8312 8313 begin 8314 -- If renamed object, apply test to underlying object 8315 8316 if Is_Entity_Name (N) 8317 and then Is_Object (Entity (N)) 8318 and then Present (Renamed_Object (Entity (N))) 8319 then 8320 return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N))); 8321 end if; 8322 8323 -- Tagged and controlled types and aliased types are always aligned, as 8324 -- are concurrent types. 8325 8326 if Is_Aliased (T) 8327 or else Has_Controlled_Component (T) 8328 or else Is_Concurrent_Type (T) 8329 or else Is_Tagged_Type (T) 8330 or else Is_Controlled (T) 8331 then 8332 return False; 8333 end if; 8334 8335 -- If this is an element of a packed array, may be unaligned 8336 8337 if Is_Ref_To_Bit_Packed_Array (N) then 8338 return True; 8339 end if; 8340 8341 -- Case of indexed component reference: test whether prefix is unaligned 8342 8343 if Nkind (N) = N_Indexed_Component then 8344 return Is_Possibly_Unaligned_Object (Prefix (N)); 8345 8346 -- Case of selected component reference 8347 8348 elsif Nkind (N) = N_Selected_Component then 8349 declare 8350 P : constant Node_Id := Prefix (N); 8351 C : constant Entity_Id := Entity (Selector_Name (N)); 8352 M : Nat; 8353 S : Nat; 8354 8355 begin 8356 -- If component reference is for an array with non-static bounds, 8357 -- then it is always aligned: we can only process unaligned arrays 8358 -- with static bounds (more precisely compile time known bounds). 8359 8360 if Is_Array_Type (T) 8361 and then not Compile_Time_Known_Bounds (T) 8362 then 8363 return False; 8364 end if; 8365 8366 -- If component is aliased, it is definitely properly aligned 8367 8368 if Is_Aliased (C) then 8369 return False; 8370 end if; 8371 8372 -- If component is for a type implemented as a scalar, and the 8373 -- record is packed, and the component is other than the first 8374 -- component of the record, then the component may be unaligned. 8375 8376 if Is_Packed (Etype (P)) 8377 and then Represented_As_Scalar (Etype (C)) 8378 and then First_Entity (Scope (C)) /= C 8379 then 8380 return True; 8381 end if; 8382 8383 -- Compute maximum possible alignment for T 8384 8385 -- If alignment is known, then that settles things 8386 8387 if Known_Alignment (T) then 8388 M := UI_To_Int (Alignment (T)); 8389 8390 -- If alignment is not known, tentatively set max alignment 8391 8392 else 8393 M := Ttypes.Maximum_Alignment; 8394 8395 -- We can reduce this if the Esize is known since the default 8396 -- alignment will never be more than the smallest power of 2 8397 -- that does not exceed this Esize value. 8398 8399 if Known_Esize (T) then 8400 S := UI_To_Int (Esize (T)); 8401 8402 while (M / 2) >= S loop 8403 M := M / 2; 8404 end loop; 8405 end if; 8406 end if; 8407 8408 -- The following code is historical, it used to be present but it 8409 -- is too cautious, because the front-end does not know the proper 8410 -- default alignments for the target. Also, if the alignment is 8411 -- not known, the front end can't know in any case. If a copy is 8412 -- needed, the back-end will take care of it. This whole section 8413 -- including this comment can be removed later ??? 8414 8415 -- If the component reference is for a record that has a specified 8416 -- alignment, and we either know it is too small, or cannot tell, 8417 -- then the component may be unaligned. 8418 8419 -- What is the following commented out code ??? 8420 8421 -- if Known_Alignment (Etype (P)) 8422 -- and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment 8423 -- and then M > Alignment (Etype (P)) 8424 -- then 8425 -- return True; 8426 -- end if; 8427 8428 -- Case of component clause present which may specify an 8429 -- unaligned position. 8430 8431 if Present (Component_Clause (C)) then 8432 8433 -- Otherwise we can do a test to make sure that the actual 8434 -- start position in the record, and the length, are both 8435 -- consistent with the required alignment. If not, we know 8436 -- that we are unaligned. 8437 8438 declare 8439 Align_In_Bits : constant Nat := M * System_Storage_Unit; 8440 Comp : Entity_Id; 8441 8442 begin 8443 Comp := C; 8444 8445 -- For a component inherited in a record extension, the 8446 -- clause is inherited but position and size are not set. 8447 8448 if Is_Base_Type (Etype (P)) 8449 and then Is_Tagged_Type (Etype (P)) 8450 and then Present (Original_Record_Component (Comp)) 8451 then 8452 Comp := Original_Record_Component (Comp); 8453 end if; 8454 8455 if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0 8456 or else Esize (Comp) mod Align_In_Bits /= 0 8457 then 8458 return True; 8459 end if; 8460 end; 8461 end if; 8462 8463 -- Otherwise, for a component reference, test prefix 8464 8465 return Is_Possibly_Unaligned_Object (P); 8466 end; 8467 8468 -- If not a component reference, must be aligned 8469 8470 else 8471 return False; 8472 end if; 8473 end Is_Possibly_Unaligned_Object; 8474 8475 --------------------------------- 8476 -- Is_Possibly_Unaligned_Slice -- 8477 --------------------------------- 8478 8479 function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is 8480 begin 8481 -- Go to renamed object 8482 8483 if Is_Entity_Name (N) 8484 and then Is_Object (Entity (N)) 8485 and then Present (Renamed_Object (Entity (N))) 8486 then 8487 return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N))); 8488 end if; 8489 8490 -- The reference must be a slice 8491 8492 if Nkind (N) /= N_Slice then 8493 return False; 8494 end if; 8495 8496 -- We only need to worry if the target has strict alignment 8497 8498 if not Target_Strict_Alignment then 8499 return False; 8500 end if; 8501 8502 -- If it is a slice, then look at the array type being sliced 8503 8504 declare 8505 Sarr : constant Node_Id := Prefix (N); 8506 -- Prefix of the slice, i.e. the array being sliced 8507 8508 Styp : constant Entity_Id := Etype (Prefix (N)); 8509 -- Type of the array being sliced 8510 8511 Pref : Node_Id; 8512 Ptyp : Entity_Id; 8513 8514 begin 8515 -- The problems arise if the array object that is being sliced 8516 -- is a component of a record or array, and we cannot guarantee 8517 -- the alignment of the array within its containing object. 8518 8519 -- To investigate this, we look at successive prefixes to see 8520 -- if we have a worrisome indexed or selected component. 8521 8522 Pref := Sarr; 8523 loop 8524 -- Case of array is part of an indexed component reference 8525 8526 if Nkind (Pref) = N_Indexed_Component then 8527 Ptyp := Etype (Prefix (Pref)); 8528 8529 -- The only problematic case is when the array is packed, in 8530 -- which case we really know nothing about the alignment of 8531 -- individual components. 8532 8533 if Is_Bit_Packed_Array (Ptyp) then 8534 return True; 8535 end if; 8536 8537 -- Case of array is part of a selected component reference 8538 8539 elsif Nkind (Pref) = N_Selected_Component then 8540 Ptyp := Etype (Prefix (Pref)); 8541 8542 -- We are definitely in trouble if the record in question 8543 -- has an alignment, and either we know this alignment is 8544 -- inconsistent with the alignment of the slice, or we don't 8545 -- know what the alignment of the slice should be. 8546 8547 if Known_Alignment (Ptyp) 8548 and then (Unknown_Alignment (Styp) 8549 or else Alignment (Styp) > Alignment (Ptyp)) 8550 then 8551 return True; 8552 end if; 8553 8554 -- We are in potential trouble if the record type is packed. 8555 -- We could special case when we know that the array is the 8556 -- first component, but that's not such a simple case ??? 8557 8558 if Is_Packed (Ptyp) then 8559 return True; 8560 end if; 8561 8562 -- We are in trouble if there is a component clause, and 8563 -- either we do not know the alignment of the slice, or 8564 -- the alignment of the slice is inconsistent with the 8565 -- bit position specified by the component clause. 8566 8567 declare 8568 Field : constant Entity_Id := Entity (Selector_Name (Pref)); 8569 begin 8570 if Present (Component_Clause (Field)) 8571 and then 8572 (Unknown_Alignment (Styp) 8573 or else 8574 (Component_Bit_Offset (Field) mod 8575 (System_Storage_Unit * Alignment (Styp))) /= 0) 8576 then 8577 return True; 8578 end if; 8579 end; 8580 8581 -- For cases other than selected or indexed components we know we 8582 -- are OK, since no issues arise over alignment. 8583 8584 else 8585 return False; 8586 end if; 8587 8588 -- We processed an indexed component or selected component 8589 -- reference that looked safe, so keep checking prefixes. 8590 8591 Pref := Prefix (Pref); 8592 end loop; 8593 end; 8594 end Is_Possibly_Unaligned_Slice; 8595 8596 ------------------------------- 8597 -- Is_Related_To_Func_Return -- 8598 ------------------------------- 8599 8600 function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is 8601 Expr : constant Node_Id := Related_Expression (Id); 8602 begin 8603 return 8604 Present (Expr) 8605 and then Nkind (Expr) = N_Explicit_Dereference 8606 and then Nkind (Parent (Expr)) = N_Simple_Return_Statement; 8607 end Is_Related_To_Func_Return; 8608 8609 -------------------------------- 8610 -- Is_Ref_To_Bit_Packed_Array -- 8611 -------------------------------- 8612 8613 function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is 8614 Result : Boolean; 8615 Expr : Node_Id; 8616 8617 begin 8618 if Is_Entity_Name (N) 8619 and then Is_Object (Entity (N)) 8620 and then Present (Renamed_Object (Entity (N))) 8621 then 8622 return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N))); 8623 end if; 8624 8625 if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then 8626 if Is_Bit_Packed_Array (Etype (Prefix (N))) then 8627 Result := True; 8628 else 8629 Result := Is_Ref_To_Bit_Packed_Array (Prefix (N)); 8630 end if; 8631 8632 if Result and then Nkind (N) = N_Indexed_Component then 8633 Expr := First (Expressions (N)); 8634 while Present (Expr) loop 8635 Force_Evaluation (Expr); 8636 Next (Expr); 8637 end loop; 8638 end if; 8639 8640 return Result; 8641 8642 else 8643 return False; 8644 end if; 8645 end Is_Ref_To_Bit_Packed_Array; 8646 8647 -------------------------------- 8648 -- Is_Ref_To_Bit_Packed_Slice -- 8649 -------------------------------- 8650 8651 function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is 8652 begin 8653 if Nkind (N) = N_Type_Conversion then 8654 return Is_Ref_To_Bit_Packed_Slice (Expression (N)); 8655 8656 elsif Is_Entity_Name (N) 8657 and then Is_Object (Entity (N)) 8658 and then Present (Renamed_Object (Entity (N))) 8659 then 8660 return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N))); 8661 8662 elsif Nkind (N) = N_Slice 8663 and then Is_Bit_Packed_Array (Etype (Prefix (N))) 8664 then 8665 return True; 8666 8667 elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then 8668 return Is_Ref_To_Bit_Packed_Slice (Prefix (N)); 8669 8670 else 8671 return False; 8672 end if; 8673 end Is_Ref_To_Bit_Packed_Slice; 8674 8675 ----------------------- 8676 -- Is_Renamed_Object -- 8677 ----------------------- 8678 8679 function Is_Renamed_Object (N : Node_Id) return Boolean is 8680 Pnod : constant Node_Id := Parent (N); 8681 Kind : constant Node_Kind := Nkind (Pnod); 8682 begin 8683 if Kind = N_Object_Renaming_Declaration then 8684 return True; 8685 elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then 8686 return Is_Renamed_Object (Pnod); 8687 else 8688 return False; 8689 end if; 8690 end Is_Renamed_Object; 8691 8692 -------------------------------------- 8693 -- Is_Secondary_Stack_BIP_Func_Call -- 8694 -------------------------------------- 8695 8696 function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is 8697 Alloc_Nam : Name_Id := No_Name; 8698 Actual : Node_Id; 8699 Call : Node_Id := Expr; 8700 Formal : Node_Id; 8701 Param : Node_Id; 8702 8703 begin 8704 -- Build-in-place calls usually appear in 'reference format. Note that 8705 -- the accessibility check machinery may add an extra 'reference due to 8706 -- side effect removal. 8707 8708 while Nkind (Call) = N_Reference loop 8709 Call := Prefix (Call); 8710 end loop; 8711 8712 Call := Unqual_Conv (Call); 8713 8714 if Is_Build_In_Place_Function_Call (Call) then 8715 8716 -- Examine all parameter associations of the function call 8717 8718 Param := First (Parameter_Associations (Call)); 8719 while Present (Param) loop 8720 if Nkind (Param) = N_Parameter_Association then 8721 Formal := Selector_Name (Param); 8722 Actual := Explicit_Actual_Parameter (Param); 8723 8724 -- Construct the name of formal BIPalloc. It is much easier to 8725 -- extract the name of the function using an arbitrary formal's 8726 -- scope rather than the Name field of Call. 8727 8728 if Alloc_Nam = No_Name and then Present (Entity (Formal)) then 8729 Alloc_Nam := 8730 New_External_Name 8731 (Chars (Scope (Entity (Formal))), 8732 BIP_Formal_Suffix (BIP_Alloc_Form)); 8733 end if; 8734 8735 -- A match for BIPalloc => 2 has been found 8736 8737 if Chars (Formal) = Alloc_Nam 8738 and then Nkind (Actual) = N_Integer_Literal 8739 and then Intval (Actual) = Uint_2 8740 then 8741 return True; 8742 end if; 8743 end if; 8744 8745 Next (Param); 8746 end loop; 8747 end if; 8748 8749 return False; 8750 end Is_Secondary_Stack_BIP_Func_Call; 8751 8752 ------------------------------------- 8753 -- Is_Tag_To_Class_Wide_Conversion -- 8754 ------------------------------------- 8755 8756 function Is_Tag_To_Class_Wide_Conversion 8757 (Obj_Id : Entity_Id) return Boolean 8758 is 8759 Expr : constant Node_Id := Expression (Parent (Obj_Id)); 8760 8761 begin 8762 return 8763 Is_Class_Wide_Type (Etype (Obj_Id)) 8764 and then Present (Expr) 8765 and then Nkind (Expr) = N_Unchecked_Type_Conversion 8766 and then Etype (Expression (Expr)) = RTE (RE_Tag); 8767 end Is_Tag_To_Class_Wide_Conversion; 8768 8769 ---------------------------- 8770 -- Is_Untagged_Derivation -- 8771 ---------------------------- 8772 8773 function Is_Untagged_Derivation (T : Entity_Id) return Boolean is 8774 begin 8775 return (not Is_Tagged_Type (T) and then Is_Derived_Type (T)) 8776 or else 8777 (Is_Private_Type (T) and then Present (Full_View (T)) 8778 and then not Is_Tagged_Type (Full_View (T)) 8779 and then Is_Derived_Type (Full_View (T)) 8780 and then Etype (Full_View (T)) /= T); 8781 end Is_Untagged_Derivation; 8782 8783 ------------------------------------ 8784 -- Is_Untagged_Private_Derivation -- 8785 ------------------------------------ 8786 8787 function Is_Untagged_Private_Derivation 8788 (Priv_Typ : Entity_Id; 8789 Full_Typ : Entity_Id) return Boolean 8790 is 8791 begin 8792 return 8793 Present (Priv_Typ) 8794 and then Is_Untagged_Derivation (Priv_Typ) 8795 and then Is_Private_Type (Etype (Priv_Typ)) 8796 and then Present (Full_Typ) 8797 and then Is_Itype (Full_Typ); 8798 end Is_Untagged_Private_Derivation; 8799 8800 ------------------------------ 8801 -- Is_Verifiable_DIC_Pragma -- 8802 ------------------------------ 8803 8804 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is 8805 Args : constant List_Id := Pragma_Argument_Associations (Prag); 8806 8807 begin 8808 -- To qualify as verifiable, a DIC pragma must have a non-null argument 8809 8810 return 8811 Present (Args) 8812 and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null; 8813 end Is_Verifiable_DIC_Pragma; 8814 8815 --------------------------- 8816 -- Is_Volatile_Reference -- 8817 --------------------------- 8818 8819 function Is_Volatile_Reference (N : Node_Id) return Boolean is 8820 begin 8821 -- Only source references are to be treated as volatile, internally 8822 -- generated stuff cannot have volatile external effects. 8823 8824 if not Comes_From_Source (N) then 8825 return False; 8826 8827 -- Never true for reference to a type 8828 8829 elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then 8830 return False; 8831 8832 -- Never true for a compile time known constant 8833 8834 elsif Compile_Time_Known_Value (N) then 8835 return False; 8836 8837 -- True if object reference with volatile type 8838 8839 elsif Is_Volatile_Object (N) then 8840 return True; 8841 8842 -- True if reference to volatile entity 8843 8844 elsif Is_Entity_Name (N) then 8845 return Treat_As_Volatile (Entity (N)); 8846 8847 -- True for slice of volatile array 8848 8849 elsif Nkind (N) = N_Slice then 8850 return Is_Volatile_Reference (Prefix (N)); 8851 8852 -- True if volatile component 8853 8854 elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then 8855 if (Is_Entity_Name (Prefix (N)) 8856 and then Has_Volatile_Components (Entity (Prefix (N)))) 8857 or else (Present (Etype (Prefix (N))) 8858 and then Has_Volatile_Components (Etype (Prefix (N)))) 8859 then 8860 return True; 8861 else 8862 return Is_Volatile_Reference (Prefix (N)); 8863 end if; 8864 8865 -- Otherwise false 8866 8867 else 8868 return False; 8869 end if; 8870 end Is_Volatile_Reference; 8871 8872 -------------------- 8873 -- Kill_Dead_Code -- 8874 -------------------- 8875 8876 procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is 8877 W : Boolean := Warn; 8878 -- Set False if warnings suppressed 8879 8880 begin 8881 if Present (N) then 8882 Remove_Warning_Messages (N); 8883 8884 -- Update the internal structures of the ABE mechanism in case the 8885 -- dead node is an elaboration scenario. 8886 8887 Kill_Elaboration_Scenario (N); 8888 8889 -- Generate warning if appropriate 8890 8891 if W then 8892 8893 -- We suppress the warning if this code is under control of an 8894 -- if statement, whose condition is a simple identifier, and 8895 -- either we are in an instance, or warnings off is set for this 8896 -- identifier. The reason for killing it in the instance case is 8897 -- that it is common and reasonable for code to be deleted in 8898 -- instances for various reasons. 8899 8900 -- Could we use Is_Statically_Unevaluated here??? 8901 8902 if Nkind (Parent (N)) = N_If_Statement then 8903 declare 8904 C : constant Node_Id := Condition (Parent (N)); 8905 begin 8906 if Nkind (C) = N_Identifier 8907 and then 8908 (In_Instance 8909 or else (Present (Entity (C)) 8910 and then Has_Warnings_Off (Entity (C)))) 8911 then 8912 W := False; 8913 end if; 8914 end; 8915 end if; 8916 8917 -- Generate warning if not suppressed 8918 8919 if W then 8920 Error_Msg_F 8921 ("?t?this code can never be executed and has been deleted!", 8922 N); 8923 end if; 8924 end if; 8925 8926 -- Recurse into block statements and bodies to process declarations 8927 -- and statements. 8928 8929 if Nkind (N) = N_Block_Statement 8930 or else Nkind (N) = N_Subprogram_Body 8931 or else Nkind (N) = N_Package_Body 8932 then 8933 Kill_Dead_Code (Declarations (N), False); 8934 Kill_Dead_Code (Statements (Handled_Statement_Sequence (N))); 8935 8936 if Nkind (N) = N_Subprogram_Body then 8937 Set_Is_Eliminated (Defining_Entity (N)); 8938 end if; 8939 8940 elsif Nkind (N) = N_Package_Declaration then 8941 Kill_Dead_Code (Visible_Declarations (Specification (N))); 8942 Kill_Dead_Code (Private_Declarations (Specification (N))); 8943 8944 -- ??? After this point, Delete_Tree has been called on all 8945 -- declarations in Specification (N), so references to entities 8946 -- therein look suspicious. 8947 8948 declare 8949 E : Entity_Id := First_Entity (Defining_Entity (N)); 8950 8951 begin 8952 while Present (E) loop 8953 if Ekind (E) = E_Operator then 8954 Set_Is_Eliminated (E); 8955 end if; 8956 8957 Next_Entity (E); 8958 end loop; 8959 end; 8960 8961 -- Recurse into composite statement to kill individual statements in 8962 -- particular instantiations. 8963 8964 elsif Nkind (N) = N_If_Statement then 8965 Kill_Dead_Code (Then_Statements (N)); 8966 Kill_Dead_Code (Elsif_Parts (N)); 8967 Kill_Dead_Code (Else_Statements (N)); 8968 8969 elsif Nkind (N) = N_Loop_Statement then 8970 Kill_Dead_Code (Statements (N)); 8971 8972 elsif Nkind (N) = N_Case_Statement then 8973 declare 8974 Alt : Node_Id; 8975 begin 8976 Alt := First (Alternatives (N)); 8977 while Present (Alt) loop 8978 Kill_Dead_Code (Statements (Alt)); 8979 Next (Alt); 8980 end loop; 8981 end; 8982 8983 elsif Nkind (N) = N_Case_Statement_Alternative then 8984 Kill_Dead_Code (Statements (N)); 8985 8986 -- Deal with dead instances caused by deleting instantiations 8987 8988 elsif Nkind (N) in N_Generic_Instantiation then 8989 Remove_Dead_Instance (N); 8990 end if; 8991 end if; 8992 end Kill_Dead_Code; 8993 8994 -- Case where argument is a list of nodes to be killed 8995 8996 procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is 8997 N : Node_Id; 8998 W : Boolean; 8999 9000 begin 9001 W := Warn; 9002 9003 if Is_Non_Empty_List (L) then 9004 N := First (L); 9005 while Present (N) loop 9006 Kill_Dead_Code (N, W); 9007 W := False; 9008 Next (N); 9009 end loop; 9010 end if; 9011 end Kill_Dead_Code; 9012 9013 ------------------------ 9014 -- Known_Non_Negative -- 9015 ------------------------ 9016 9017 function Known_Non_Negative (Opnd : Node_Id) return Boolean is 9018 begin 9019 if Is_OK_Static_Expression (Opnd) and then Expr_Value (Opnd) >= 0 then 9020 return True; 9021 9022 else 9023 declare 9024 Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd)); 9025 begin 9026 return 9027 Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0; 9028 end; 9029 end if; 9030 end Known_Non_Negative; 9031 9032 ----------------------------- 9033 -- Make_CW_Equivalent_Type -- 9034 ----------------------------- 9035 9036 -- Create a record type used as an equivalent of any member of the class 9037 -- which takes its size from exp. 9038 9039 -- Generate the following code: 9040 9041 -- type Equiv_T is record 9042 -- _parent : T (List of discriminant constraints taken from Exp); 9043 -- Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8); 9044 -- end Equiv_T; 9045 -- 9046 -- ??? Note that this type does not guarantee same alignment as all 9047 -- derived types 9048 -- 9049 -- Note: for the freezing circuitry, this looks like a record extension, 9050 -- and so we need to make sure that the scalar storage order is the same 9051 -- as that of the parent type. (This does not change anything for the 9052 -- representation of the extension part.) 9053 9054 function Make_CW_Equivalent_Type 9055 (T : Entity_Id; 9056 E : Node_Id) return Entity_Id 9057 is 9058 Loc : constant Source_Ptr := Sloc (E); 9059 Root_Typ : constant Entity_Id := Root_Type (T); 9060 Root_Utyp : constant Entity_Id := Underlying_Type (Root_Typ); 9061 List_Def : constant List_Id := Empty_List; 9062 Comp_List : constant List_Id := New_List; 9063 Equiv_Type : Entity_Id; 9064 Range_Type : Entity_Id; 9065 Str_Type : Entity_Id; 9066 Constr_Root : Entity_Id; 9067 Sizexpr : Node_Id; 9068 9069 begin 9070 -- If the root type is already constrained, there are no discriminants 9071 -- in the expression. 9072 9073 if not Has_Discriminants (Root_Typ) 9074 or else Is_Constrained (Root_Typ) 9075 then 9076 Constr_Root := Root_Typ; 9077 9078 -- At this point in the expansion, non-limited view of the type 9079 -- must be available, otherwise the error will be reported later. 9080 9081 if From_Limited_With (Constr_Root) 9082 and then Present (Non_Limited_View (Constr_Root)) 9083 then 9084 Constr_Root := Non_Limited_View (Constr_Root); 9085 end if; 9086 9087 else 9088 Constr_Root := Make_Temporary (Loc, 'R'); 9089 9090 -- subtype cstr__n is T (List of discr constraints taken from Exp) 9091 9092 Append_To (List_Def, 9093 Make_Subtype_Declaration (Loc, 9094 Defining_Identifier => Constr_Root, 9095 Subtype_Indication => Make_Subtype_From_Expr (E, Root_Typ))); 9096 end if; 9097 9098 -- Generate the range subtype declaration 9099 9100 Range_Type := Make_Temporary (Loc, 'G'); 9101 9102 if not Is_Interface (Root_Typ) then 9103 9104 -- subtype rg__xx is 9105 -- Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit 9106 9107 Sizexpr := 9108 Make_Op_Subtract (Loc, 9109 Left_Opnd => 9110 Make_Attribute_Reference (Loc, 9111 Prefix => 9112 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)), 9113 Attribute_Name => Name_Size), 9114 Right_Opnd => 9115 Make_Attribute_Reference (Loc, 9116 Prefix => New_Occurrence_Of (Constr_Root, Loc), 9117 Attribute_Name => Name_Object_Size)); 9118 else 9119 -- subtype rg__xx is 9120 -- Storage_Offset range 1 .. Expr'size / Storage_Unit 9121 9122 Sizexpr := 9123 Make_Attribute_Reference (Loc, 9124 Prefix => 9125 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)), 9126 Attribute_Name => Name_Size); 9127 end if; 9128 9129 Set_Paren_Count (Sizexpr, 1); 9130 9131 Append_To (List_Def, 9132 Make_Subtype_Declaration (Loc, 9133 Defining_Identifier => Range_Type, 9134 Subtype_Indication => 9135 Make_Subtype_Indication (Loc, 9136 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc), 9137 Constraint => Make_Range_Constraint (Loc, 9138 Range_Expression => 9139 Make_Range (Loc, 9140 Low_Bound => Make_Integer_Literal (Loc, 1), 9141 High_Bound => 9142 Make_Op_Divide (Loc, 9143 Left_Opnd => Sizexpr, 9144 Right_Opnd => Make_Integer_Literal (Loc, 9145 Intval => System_Storage_Unit))))))); 9146 9147 -- subtype str__nn is Storage_Array (rg__x); 9148 9149 Str_Type := Make_Temporary (Loc, 'S'); 9150 Append_To (List_Def, 9151 Make_Subtype_Declaration (Loc, 9152 Defining_Identifier => Str_Type, 9153 Subtype_Indication => 9154 Make_Subtype_Indication (Loc, 9155 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc), 9156 Constraint => 9157 Make_Index_Or_Discriminant_Constraint (Loc, 9158 Constraints => 9159 New_List (New_Occurrence_Of (Range_Type, Loc)))))); 9160 9161 -- type Equiv_T is record 9162 -- [ _parent : Tnn; ] 9163 -- E : Str_Type; 9164 -- end Equiv_T; 9165 9166 Equiv_Type := Make_Temporary (Loc, 'T'); 9167 Set_Ekind (Equiv_Type, E_Record_Type); 9168 Set_Parent_Subtype (Equiv_Type, Constr_Root); 9169 9170 -- Set Is_Class_Wide_Equivalent_Type very early to trigger the special 9171 -- treatment for this type. In particular, even though _parent's type 9172 -- is a controlled type or contains controlled components, we do not 9173 -- want to set Has_Controlled_Component on it to avoid making it gain 9174 -- an unwanted _controller component. 9175 9176 Set_Is_Class_Wide_Equivalent_Type (Equiv_Type); 9177 9178 -- A class-wide equivalent type does not require initialization 9179 9180 Set_Suppress_Initialization (Equiv_Type); 9181 9182 if not Is_Interface (Root_Typ) then 9183 Append_To (Comp_List, 9184 Make_Component_Declaration (Loc, 9185 Defining_Identifier => 9186 Make_Defining_Identifier (Loc, Name_uParent), 9187 Component_Definition => 9188 Make_Component_Definition (Loc, 9189 Aliased_Present => False, 9190 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc)))); 9191 9192 Set_Reverse_Storage_Order 9193 (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp))); 9194 Set_Reverse_Bit_Order 9195 (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp))); 9196 end if; 9197 9198 Append_To (Comp_List, 9199 Make_Component_Declaration (Loc, 9200 Defining_Identifier => Make_Temporary (Loc, 'C'), 9201 Component_Definition => 9202 Make_Component_Definition (Loc, 9203 Aliased_Present => False, 9204 Subtype_Indication => New_Occurrence_Of (Str_Type, Loc)))); 9205 9206 Append_To (List_Def, 9207 Make_Full_Type_Declaration (Loc, 9208 Defining_Identifier => Equiv_Type, 9209 Type_Definition => 9210 Make_Record_Definition (Loc, 9211 Component_List => 9212 Make_Component_List (Loc, 9213 Component_Items => Comp_List, 9214 Variant_Part => Empty)))); 9215 9216 -- Suppress all checks during the analysis of the expanded code to avoid 9217 -- the generation of spurious warnings under ZFP run-time. 9218 9219 Insert_Actions (E, List_Def, Suppress => All_Checks); 9220 return Equiv_Type; 9221 end Make_CW_Equivalent_Type; 9222 9223 ------------------------- 9224 -- Make_Invariant_Call -- 9225 ------------------------- 9226 9227 function Make_Invariant_Call (Expr : Node_Id) return Node_Id is 9228 Loc : constant Source_Ptr := Sloc (Expr); 9229 Typ : constant Entity_Id := Base_Type (Etype (Expr)); 9230 9231 Proc_Id : Entity_Id; 9232 9233 begin 9234 pragma Assert (Has_Invariants (Typ)); 9235 9236 Proc_Id := Invariant_Procedure (Typ); 9237 pragma Assert (Present (Proc_Id)); 9238 9239 return 9240 Make_Procedure_Call_Statement (Loc, 9241 Name => New_Occurrence_Of (Proc_Id, Loc), 9242 Parameter_Associations => New_List (Relocate_Node (Expr))); 9243 end Make_Invariant_Call; 9244 9245 ------------------------ 9246 -- Make_Literal_Range -- 9247 ------------------------ 9248 9249 function Make_Literal_Range 9250 (Loc : Source_Ptr; 9251 Literal_Typ : Entity_Id) return Node_Id 9252 is 9253 Lo : constant Node_Id := 9254 New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ)); 9255 Index : constant Entity_Id := Etype (Lo); 9256 Length_Expr : constant Node_Id := 9257 Make_Op_Subtract (Loc, 9258 Left_Opnd => 9259 Make_Integer_Literal (Loc, 9260 Intval => String_Literal_Length (Literal_Typ)), 9261 Right_Opnd => Make_Integer_Literal (Loc, 1)); 9262 9263 Hi : Node_Id; 9264 9265 begin 9266 Set_Analyzed (Lo, False); 9267 9268 if Is_Integer_Type (Index) then 9269 Hi := 9270 Make_Op_Add (Loc, 9271 Left_Opnd => New_Copy_Tree (Lo), 9272 Right_Opnd => Length_Expr); 9273 else 9274 Hi := 9275 Make_Attribute_Reference (Loc, 9276 Attribute_Name => Name_Val, 9277 Prefix => New_Occurrence_Of (Index, Loc), 9278 Expressions => New_List ( 9279 Make_Op_Add (Loc, 9280 Left_Opnd => 9281 Make_Attribute_Reference (Loc, 9282 Attribute_Name => Name_Pos, 9283 Prefix => New_Occurrence_Of (Index, Loc), 9284 Expressions => New_List (New_Copy_Tree (Lo))), 9285 Right_Opnd => Length_Expr))); 9286 end if; 9287 9288 return 9289 Make_Range (Loc, 9290 Low_Bound => Lo, 9291 High_Bound => Hi); 9292 end Make_Literal_Range; 9293 9294 -------------------------- 9295 -- Make_Non_Empty_Check -- 9296 -------------------------- 9297 9298 function Make_Non_Empty_Check 9299 (Loc : Source_Ptr; 9300 N : Node_Id) return Node_Id 9301 is 9302 begin 9303 return 9304 Make_Op_Ne (Loc, 9305 Left_Opnd => 9306 Make_Attribute_Reference (Loc, 9307 Attribute_Name => Name_Length, 9308 Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)), 9309 Right_Opnd => 9310 Make_Integer_Literal (Loc, 0)); 9311 end Make_Non_Empty_Check; 9312 9313 ------------------------- 9314 -- Make_Predicate_Call -- 9315 ------------------------- 9316 9317 -- WARNING: This routine manages Ghost regions. Return statements must be 9318 -- replaced by gotos which jump to the end of the routine and restore the 9319 -- Ghost mode. 9320 9321 function Make_Predicate_Call 9322 (Typ : Entity_Id; 9323 Expr : Node_Id; 9324 Mem : Boolean := False) return Node_Id 9325 is 9326 Loc : constant Source_Ptr := Sloc (Expr); 9327 9328 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 9329 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 9330 -- Save the Ghost-related attributes to restore on exit 9331 9332 Call : Node_Id; 9333 Func_Id : Entity_Id; 9334 9335 begin 9336 Func_Id := Predicate_Function (Typ); 9337 pragma Assert (Present (Func_Id)); 9338 9339 -- The related type may be subject to pragma Ghost. Set the mode now to 9340 -- ensure that the call is properly marked as Ghost. 9341 9342 Set_Ghost_Mode (Typ); 9343 9344 -- Call special membership version if requested and available 9345 9346 if Mem and then Present (Predicate_Function_M (Typ)) then 9347 Func_Id := Predicate_Function_M (Typ); 9348 end if; 9349 9350 -- Case of calling normal predicate function 9351 9352 -- If the type is tagged, the expression may be class-wide, in which 9353 -- case it has to be converted to its root type, given that the 9354 -- generated predicate function is not dispatching. The conversion is 9355 -- type-safe and does not need validation, which matters when private 9356 -- extensions are involved. 9357 9358 if Is_Tagged_Type (Typ) then 9359 Call := 9360 Make_Function_Call (Loc, 9361 Name => New_Occurrence_Of (Func_Id, Loc), 9362 Parameter_Associations => 9363 New_List (OK_Convert_To (Typ, Relocate_Node (Expr)))); 9364 else 9365 Call := 9366 Make_Function_Call (Loc, 9367 Name => New_Occurrence_Of (Func_Id, Loc), 9368 Parameter_Associations => New_List (Relocate_Node (Expr))); 9369 end if; 9370 9371 Restore_Ghost_Region (Saved_GM, Saved_IGR); 9372 9373 return Call; 9374 end Make_Predicate_Call; 9375 9376 -------------------------- 9377 -- Make_Predicate_Check -- 9378 -------------------------- 9379 9380 function Make_Predicate_Check 9381 (Typ : Entity_Id; 9382 Expr : Node_Id) return Node_Id 9383 is 9384 Loc : constant Source_Ptr := Sloc (Expr); 9385 9386 procedure Add_Failure_Expression (Args : List_Id); 9387 -- Add the failure expression of pragma Predicate_Failure (if any) to 9388 -- list Args. 9389 9390 ---------------------------- 9391 -- Add_Failure_Expression -- 9392 ---------------------------- 9393 9394 procedure Add_Failure_Expression (Args : List_Id) is 9395 function Failure_Expression return Node_Id; 9396 pragma Inline (Failure_Expression); 9397 -- Find aspect or pragma Predicate_Failure that applies to type Typ 9398 -- and return its expression. Return Empty if no such annotation is 9399 -- available. 9400 9401 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean; 9402 pragma Inline (Is_OK_PF_Aspect); 9403 -- Determine whether aspect Asp is a suitable Predicate_Failure 9404 -- aspect that applies to type Typ. 9405 9406 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean; 9407 pragma Inline (Is_OK_PF_Pragma); 9408 -- Determine whether pragma Prag is a suitable Predicate_Failure 9409 -- pragma that applies to type Typ. 9410 9411 procedure Replace_Subtype_Reference (N : Node_Id); 9412 -- Replace the current instance of type Typ denoted by N with 9413 -- expression Expr. 9414 9415 ------------------------ 9416 -- Failure_Expression -- 9417 ------------------------ 9418 9419 function Failure_Expression return Node_Id is 9420 Item : Node_Id; 9421 9422 begin 9423 -- The management of the rep item chain involves "inheritance" of 9424 -- parent type chains. If a parent [sub]type is already subject to 9425 -- pragma Predicate_Failure, then the pragma will also appear in 9426 -- the chain of the child [sub]type, which in turn may possess a 9427 -- pragma of its own. Avoid order-dependent issues by inspecting 9428 -- the rep item chain directly. Note that routine Get_Pragma may 9429 -- return a parent pragma. 9430 9431 Item := First_Rep_Item (Typ); 9432 while Present (Item) loop 9433 9434 -- Predicate_Failure appears as an aspect 9435 9436 if Nkind (Item) = N_Aspect_Specification 9437 and then Is_OK_PF_Aspect (Item) 9438 then 9439 return Expression (Item); 9440 9441 -- Predicate_Failure appears as a pragma 9442 9443 elsif Nkind (Item) = N_Pragma 9444 and then Is_OK_PF_Pragma (Item) 9445 then 9446 return 9447 Get_Pragma_Arg 9448 (Next (First (Pragma_Argument_Associations (Item)))); 9449 end if; 9450 9451 Item := Next_Rep_Item (Item); 9452 end loop; 9453 9454 return Empty; 9455 end Failure_Expression; 9456 9457 --------------------- 9458 -- Is_OK_PF_Aspect -- 9459 --------------------- 9460 9461 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean is 9462 begin 9463 -- To qualify, the aspect must apply to the type subjected to the 9464 -- predicate check. 9465 9466 return 9467 Chars (Identifier (Asp)) = Name_Predicate_Failure 9468 and then Present (Entity (Asp)) 9469 and then Entity (Asp) = Typ; 9470 end Is_OK_PF_Aspect; 9471 9472 --------------------- 9473 -- Is_OK_PF_Pragma -- 9474 --------------------- 9475 9476 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean is 9477 Args : constant List_Id := Pragma_Argument_Associations (Prag); 9478 Typ_Arg : Node_Id; 9479 9480 begin 9481 -- Nothing to do when the pragma does not denote Predicate_Failure 9482 9483 if Pragma_Name (Prag) /= Name_Predicate_Failure then 9484 return False; 9485 9486 -- Nothing to do when the pragma lacks arguments, in which case it 9487 -- is illegal. 9488 9489 elsif No (Args) or else Is_Empty_List (Args) then 9490 return False; 9491 end if; 9492 9493 Typ_Arg := Get_Pragma_Arg (First (Args)); 9494 9495 -- To qualify, the local name argument of the pragma must denote 9496 -- the type subjected to the predicate check. 9497 9498 return 9499 Is_Entity_Name (Typ_Arg) 9500 and then Present (Entity (Typ_Arg)) 9501 and then Entity (Typ_Arg) = Typ; 9502 end Is_OK_PF_Pragma; 9503 9504 -------------------------------- 9505 -- Replace_Subtype_Reference -- 9506 -------------------------------- 9507 9508 procedure Replace_Subtype_Reference (N : Node_Id) is 9509 begin 9510 Rewrite (N, New_Copy_Tree (Expr)); 9511 9512 -- We want to treat the node as if it comes from source, so that 9513 -- ASIS will not ignore it. 9514 9515 Set_Comes_From_Source (N, True); 9516 end Replace_Subtype_Reference; 9517 9518 procedure Replace_Subtype_References is 9519 new Replace_Type_References_Generic (Replace_Subtype_Reference); 9520 9521 -- Local variables 9522 9523 PF_Expr : constant Node_Id := Failure_Expression; 9524 Expr : Node_Id; 9525 9526 -- Start of processing for Add_Failure_Expression 9527 9528 begin 9529 if Present (PF_Expr) then 9530 9531 -- Replace any occurrences of the current instance of the type 9532 -- with the object subjected to the predicate check. 9533 9534 Expr := New_Copy_Tree (PF_Expr); 9535 Replace_Subtype_References (Expr, Typ); 9536 9537 -- The failure expression appears as the third argument of the 9538 -- Check pragma. 9539 9540 Append_To (Args, 9541 Make_Pragma_Argument_Association (Loc, 9542 Expression => Expr)); 9543 end if; 9544 end Add_Failure_Expression; 9545 9546 -- Local variables 9547 9548 Args : List_Id; 9549 Nam : Name_Id; 9550 9551 -- Start of processing for Make_Predicate_Check 9552 9553 begin 9554 -- If predicate checks are suppressed, then return a null statement. For 9555 -- this call, we check only the scope setting. If the caller wants to 9556 -- check a specific entity's setting, they must do it manually. 9557 9558 if Predicate_Checks_Suppressed (Empty) then 9559 return Make_Null_Statement (Loc); 9560 end if; 9561 9562 -- Do not generate a check within an internal subprogram (stream 9563 -- functions and the like, including including predicate functions). 9564 9565 if Within_Internal_Subprogram then 9566 return Make_Null_Statement (Loc); 9567 end if; 9568 9569 -- Compute proper name to use, we need to get this right so that the 9570 -- right set of check policies apply to the Check pragma we are making. 9571 9572 if Has_Dynamic_Predicate_Aspect (Typ) then 9573 Nam := Name_Dynamic_Predicate; 9574 elsif Has_Static_Predicate_Aspect (Typ) then 9575 Nam := Name_Static_Predicate; 9576 else 9577 Nam := Name_Predicate; 9578 end if; 9579 9580 Args := New_List ( 9581 Make_Pragma_Argument_Association (Loc, 9582 Expression => Make_Identifier (Loc, Nam)), 9583 Make_Pragma_Argument_Association (Loc, 9584 Expression => Make_Predicate_Call (Typ, Expr))); 9585 9586 -- If the subtype is subject to pragma Predicate_Failure, add the 9587 -- failure expression as an additional parameter. 9588 9589 Add_Failure_Expression (Args); 9590 9591 return 9592 Make_Pragma (Loc, 9593 Chars => Name_Check, 9594 Pragma_Argument_Associations => Args); 9595 end Make_Predicate_Check; 9596 9597 ---------------------------- 9598 -- Make_Subtype_From_Expr -- 9599 ---------------------------- 9600 9601 -- 1. If Expr is an unconstrained array expression, creates 9602 -- Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n)) 9603 9604 -- 2. If Expr is a unconstrained discriminated type expression, creates 9605 -- Unc_Type(Expr.Discr1, ... , Expr.Discr_n) 9606 9607 -- 3. If Expr is class-wide, creates an implicit class-wide subtype 9608 9609 function Make_Subtype_From_Expr 9610 (E : Node_Id; 9611 Unc_Typ : Entity_Id; 9612 Related_Id : Entity_Id := Empty) return Node_Id 9613 is 9614 List_Constr : constant List_Id := New_List; 9615 Loc : constant Source_Ptr := Sloc (E); 9616 D : Entity_Id; 9617 Full_Exp : Node_Id; 9618 Full_Subtyp : Entity_Id; 9619 High_Bound : Entity_Id; 9620 Index_Typ : Entity_Id; 9621 Low_Bound : Entity_Id; 9622 Priv_Subtyp : Entity_Id; 9623 Utyp : Entity_Id; 9624 9625 begin 9626 if Is_Private_Type (Unc_Typ) 9627 and then Has_Unknown_Discriminants (Unc_Typ) 9628 then 9629 -- The caller requests a unique external name for both the private 9630 -- and the full subtype. 9631 9632 if Present (Related_Id) then 9633 Full_Subtyp := 9634 Make_Defining_Identifier (Loc, 9635 Chars => New_External_Name (Chars (Related_Id), 'C')); 9636 Priv_Subtyp := 9637 Make_Defining_Identifier (Loc, 9638 Chars => New_External_Name (Chars (Related_Id), 'P')); 9639 9640 else 9641 Full_Subtyp := Make_Temporary (Loc, 'C'); 9642 Priv_Subtyp := Make_Temporary (Loc, 'P'); 9643 end if; 9644 9645 -- Prepare the subtype completion. Use the base type to find the 9646 -- underlying type because the type may be a generic actual or an 9647 -- explicit subtype. 9648 9649 Utyp := Underlying_Type (Base_Type (Unc_Typ)); 9650 9651 Full_Exp := 9652 Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E)); 9653 Set_Parent (Full_Exp, Parent (E)); 9654 9655 Insert_Action (E, 9656 Make_Subtype_Declaration (Loc, 9657 Defining_Identifier => Full_Subtyp, 9658 Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp))); 9659 9660 -- Define the dummy private subtype 9661 9662 Set_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ))); 9663 Set_Etype (Priv_Subtyp, Base_Type (Unc_Typ)); 9664 Set_Scope (Priv_Subtyp, Full_Subtyp); 9665 Set_Is_Constrained (Priv_Subtyp); 9666 Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ)); 9667 Set_Is_Itype (Priv_Subtyp); 9668 Set_Associated_Node_For_Itype (Priv_Subtyp, E); 9669 9670 if Is_Tagged_Type (Priv_Subtyp) then 9671 Set_Class_Wide_Type 9672 (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ)); 9673 Set_Direct_Primitive_Operations (Priv_Subtyp, 9674 Direct_Primitive_Operations (Unc_Typ)); 9675 end if; 9676 9677 Set_Full_View (Priv_Subtyp, Full_Subtyp); 9678 9679 return New_Occurrence_Of (Priv_Subtyp, Loc); 9680 9681 elsif Is_Array_Type (Unc_Typ) then 9682 Index_Typ := First_Index (Unc_Typ); 9683 for J in 1 .. Number_Dimensions (Unc_Typ) loop 9684 9685 -- Capture the bounds of each index constraint in case the context 9686 -- is an object declaration of an unconstrained type initialized 9687 -- by a function call: 9688 9689 -- Obj : Unconstr_Typ := Func_Call; 9690 9691 -- This scenario requires secondary scope management and the index 9692 -- constraint cannot depend on the temporary used to capture the 9693 -- result of the function call. 9694 9695 -- SS_Mark; 9696 -- Temp : Unconstr_Typ_Ptr := Func_Call'reference; 9697 -- subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last); 9698 -- Obj : S := Temp.all; 9699 -- SS_Release; -- Temp is gone at this point, bounds of S are 9700 -- -- non existent. 9701 9702 -- Generate: 9703 -- Low_Bound : constant Base_Type (Index_Typ) := E'First (J); 9704 9705 Low_Bound := Make_Temporary (Loc, 'B'); 9706 Insert_Action (E, 9707 Make_Object_Declaration (Loc, 9708 Defining_Identifier => Low_Bound, 9709 Object_Definition => 9710 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc), 9711 Constant_Present => True, 9712 Expression => 9713 Make_Attribute_Reference (Loc, 9714 Prefix => Duplicate_Subexpr_No_Checks (E), 9715 Attribute_Name => Name_First, 9716 Expressions => New_List ( 9717 Make_Integer_Literal (Loc, J))))); 9718 9719 -- Generate: 9720 -- High_Bound : constant Base_Type (Index_Typ) := E'Last (J); 9721 9722 High_Bound := Make_Temporary (Loc, 'B'); 9723 Insert_Action (E, 9724 Make_Object_Declaration (Loc, 9725 Defining_Identifier => High_Bound, 9726 Object_Definition => 9727 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc), 9728 Constant_Present => True, 9729 Expression => 9730 Make_Attribute_Reference (Loc, 9731 Prefix => Duplicate_Subexpr_No_Checks (E), 9732 Attribute_Name => Name_Last, 9733 Expressions => New_List ( 9734 Make_Integer_Literal (Loc, J))))); 9735 9736 Append_To (List_Constr, 9737 Make_Range (Loc, 9738 Low_Bound => New_Occurrence_Of (Low_Bound, Loc), 9739 High_Bound => New_Occurrence_Of (High_Bound, Loc))); 9740 9741 Index_Typ := Next_Index (Index_Typ); 9742 end loop; 9743 9744 elsif Is_Class_Wide_Type (Unc_Typ) then 9745 declare 9746 CW_Subtype : Entity_Id; 9747 EQ_Typ : Entity_Id := Empty; 9748 9749 begin 9750 -- A class-wide equivalent type is not needed on VM targets 9751 -- because the VM back-ends handle the class-wide object 9752 -- initialization itself (and doesn't need or want the 9753 -- additional intermediate type to handle the assignment). 9754 9755 if Expander_Active and then Tagged_Type_Expansion then 9756 9757 -- If this is the class-wide type of a completion that is a 9758 -- record subtype, set the type of the class-wide type to be 9759 -- the full base type, for use in the expanded code for the 9760 -- equivalent type. Should this be done earlier when the 9761 -- completion is analyzed ??? 9762 9763 if Is_Private_Type (Etype (Unc_Typ)) 9764 and then 9765 Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype 9766 then 9767 Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ)))); 9768 end if; 9769 9770 EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E); 9771 end if; 9772 9773 CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E); 9774 Set_Equivalent_Type (CW_Subtype, EQ_Typ); 9775 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ)); 9776 9777 return New_Occurrence_Of (CW_Subtype, Loc); 9778 end; 9779 9780 -- Indefinite record type with discriminants 9781 9782 else 9783 D := First_Discriminant (Unc_Typ); 9784 while Present (D) loop 9785 Append_To (List_Constr, 9786 Make_Selected_Component (Loc, 9787 Prefix => Duplicate_Subexpr_No_Checks (E), 9788 Selector_Name => New_Occurrence_Of (D, Loc))); 9789 9790 Next_Discriminant (D); 9791 end loop; 9792 end if; 9793 9794 return 9795 Make_Subtype_Indication (Loc, 9796 Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc), 9797 Constraint => 9798 Make_Index_Or_Discriminant_Constraint (Loc, 9799 Constraints => List_Constr)); 9800 end Make_Subtype_From_Expr; 9801 9802 --------------- 9803 -- Map_Types -- 9804 --------------- 9805 9806 procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is 9807 9808 -- NOTE: Most of the routines in Map_Types are intentionally unnested to 9809 -- avoid deep indentation of code. 9810 9811 -- NOTE: Routines which deal with discriminant mapping operate on the 9812 -- [underlying/record] full view of various types because those views 9813 -- contain all discriminants and stored constraints. 9814 9815 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id); 9816 -- Subsidiary to Map_Primitives. Find a primitive in the inheritance or 9817 -- overriding chain starting from Prim whose dispatching type is parent 9818 -- type Par_Typ and add a mapping between the result and primitive Prim. 9819 9820 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id; 9821 -- Subsidiary to Map_Primitives. Return the next ancestor primitive in 9822 -- the inheritance or overriding chain of subprogram Subp. Return Empty 9823 -- if no such primitive is available. 9824 9825 function Build_Chain 9826 (Par_Typ : Entity_Id; 9827 Deriv_Typ : Entity_Id) return Elist_Id; 9828 -- Subsidiary to Map_Discriminants. Recreate the derivation chain from 9829 -- parent type Par_Typ leading down towards derived type Deriv_Typ. The 9830 -- list has the form: 9831 -- 9832 -- head tail 9833 -- v v 9834 -- <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ 9835 -- 9836 -- Note that Par_Typ is not part of the resulting derivation chain 9837 9838 function Discriminated_View (Typ : Entity_Id) return Entity_Id; 9839 -- Return the view of type Typ which could potentially contains either 9840 -- the discriminants or stored constraints of the type. 9841 9842 function Find_Discriminant_Value 9843 (Discr : Entity_Id; 9844 Par_Typ : Entity_Id; 9845 Deriv_Typ : Entity_Id; 9846 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id; 9847 -- Subsidiary to Map_Discriminants. Find the value of discriminant Discr 9848 -- in the derivation chain starting from parent type Par_Typ leading to 9849 -- derived type Deriv_Typ. The returned value is one of the following: 9850 -- 9851 -- * An entity which is either a discriminant or a non-discriminant 9852 -- name, and renames/constraints Discr. 9853 -- 9854 -- * An expression which constraints Discr 9855 -- 9856 -- Typ_Elmt is an element of the derivation chain created by routine 9857 -- Build_Chain and denotes the current ancestor being examined. 9858 9859 procedure Map_Discriminants 9860 (Par_Typ : Entity_Id; 9861 Deriv_Typ : Entity_Id); 9862 -- Map each discriminant of type Par_Typ to a meaningful constraint 9863 -- from the point of view of type Deriv_Typ. 9864 9865 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id); 9866 -- Map each primitive of type Par_Typ to a corresponding primitive of 9867 -- type Deriv_Typ. 9868 9869 ------------------- 9870 -- Add_Primitive -- 9871 ------------------- 9872 9873 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is 9874 Par_Prim : Entity_Id; 9875 9876 begin 9877 -- Inspect the inheritance chain through the Alias attribute and the 9878 -- overriding chain through the Overridden_Operation looking for an 9879 -- ancestor primitive with the appropriate dispatching type. 9880 9881 Par_Prim := Prim; 9882 while Present (Par_Prim) loop 9883 exit when Find_Dispatching_Type (Par_Prim) = Par_Typ; 9884 Par_Prim := Ancestor_Primitive (Par_Prim); 9885 end loop; 9886 9887 -- Create a mapping of the form: 9888 9889 -- parent type primitive -> derived type primitive 9890 9891 if Present (Par_Prim) then 9892 Type_Map.Set (Par_Prim, Prim); 9893 end if; 9894 end Add_Primitive; 9895 9896 ------------------------ 9897 -- Ancestor_Primitive -- 9898 ------------------------ 9899 9900 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is 9901 Inher_Prim : constant Entity_Id := Alias (Subp); 9902 Over_Prim : constant Entity_Id := Overridden_Operation (Subp); 9903 9904 begin 9905 -- The current subprogram overrides an ancestor primitive 9906 9907 if Present (Over_Prim) then 9908 return Over_Prim; 9909 9910 -- The current subprogram is an internally generated alias of an 9911 -- inherited ancestor primitive. 9912 9913 elsif Present (Inher_Prim) then 9914 return Inher_Prim; 9915 9916 -- Otherwise the current subprogram is the root of the inheritance or 9917 -- overriding chain. 9918 9919 else 9920 return Empty; 9921 end if; 9922 end Ancestor_Primitive; 9923 9924 ----------------- 9925 -- Build_Chain -- 9926 ----------------- 9927 9928 function Build_Chain 9929 (Par_Typ : Entity_Id; 9930 Deriv_Typ : Entity_Id) return Elist_Id 9931 is 9932 Anc_Typ : Entity_Id; 9933 Chain : Elist_Id; 9934 Curr_Typ : Entity_Id; 9935 9936 begin 9937 Chain := New_Elmt_List; 9938 9939 -- Add the derived type to the derivation chain 9940 9941 Prepend_Elmt (Deriv_Typ, Chain); 9942 9943 -- Examine all ancestors starting from the derived type climbing 9944 -- towards parent type Par_Typ. 9945 9946 Curr_Typ := Deriv_Typ; 9947 loop 9948 -- Handle the case where the current type is a record which 9949 -- derives from a subtype. 9950 9951 -- subtype Sub_Typ is Par_Typ ... 9952 -- type Deriv_Typ is Sub_Typ ... 9953 9954 if Ekind (Curr_Typ) = E_Record_Type 9955 and then Present (Parent_Subtype (Curr_Typ)) 9956 then 9957 Anc_Typ := Parent_Subtype (Curr_Typ); 9958 9959 -- Handle the case where the current type is a record subtype of 9960 -- another subtype. 9961 9962 -- subtype Sub_Typ1 is Par_Typ ... 9963 -- subtype Sub_Typ2 is Sub_Typ1 ... 9964 9965 elsif Ekind (Curr_Typ) = E_Record_Subtype 9966 and then Present (Cloned_Subtype (Curr_Typ)) 9967 then 9968 Anc_Typ := Cloned_Subtype (Curr_Typ); 9969 9970 -- Otherwise use the direct parent type 9971 9972 else 9973 Anc_Typ := Etype (Curr_Typ); 9974 end if; 9975 9976 -- Use the first subtype when dealing with itypes 9977 9978 if Is_Itype (Anc_Typ) then 9979 Anc_Typ := First_Subtype (Anc_Typ); 9980 end if; 9981 9982 -- Work with the view which contains the discriminants and stored 9983 -- constraints. 9984 9985 Anc_Typ := Discriminated_View (Anc_Typ); 9986 9987 -- Stop the climb when either the parent type has been reached or 9988 -- there are no more ancestors left to examine. 9989 9990 exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ; 9991 9992 Prepend_Unique_Elmt (Anc_Typ, Chain); 9993 Curr_Typ := Anc_Typ; 9994 end loop; 9995 9996 return Chain; 9997 end Build_Chain; 9998 9999 ------------------------ 10000 -- Discriminated_View -- 10001 ------------------------ 10002 10003 function Discriminated_View (Typ : Entity_Id) return Entity_Id is 10004 T : Entity_Id; 10005 10006 begin 10007 T := Typ; 10008 10009 -- Use the [underlying] full view when dealing with private types 10010 -- because the view contains all inherited discriminants or stored 10011 -- constraints. 10012 10013 if Is_Private_Type (T) then 10014 if Present (Underlying_Full_View (T)) then 10015 T := Underlying_Full_View (T); 10016 10017 elsif Present (Full_View (T)) then 10018 T := Full_View (T); 10019 end if; 10020 end if; 10021 10022 -- Use the underlying record view when the type is an extenstion of 10023 -- a parent type with unknown discriminants because the view contains 10024 -- all inherited discriminants or stored constraints. 10025 10026 if Ekind (T) = E_Record_Type 10027 and then Present (Underlying_Record_View (T)) 10028 then 10029 T := Underlying_Record_View (T); 10030 end if; 10031 10032 return T; 10033 end Discriminated_View; 10034 10035 ----------------------------- 10036 -- Find_Discriminant_Value -- 10037 ----------------------------- 10038 10039 function Find_Discriminant_Value 10040 (Discr : Entity_Id; 10041 Par_Typ : Entity_Id; 10042 Deriv_Typ : Entity_Id; 10043 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id 10044 is 10045 Discr_Pos : constant Uint := Discriminant_Number (Discr); 10046 Typ : constant Entity_Id := Node (Typ_Elmt); 10047 10048 function Find_Constraint_Value 10049 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id; 10050 -- Given constraint Constr, find what it denotes. This is either: 10051 -- 10052 -- * An entity which is either a discriminant or a name 10053 -- 10054 -- * An expression 10055 10056 --------------------------- 10057 -- Find_Constraint_Value -- 10058 --------------------------- 10059 10060 function Find_Constraint_Value 10061 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id 10062 is 10063 begin 10064 if Nkind (Constr) in N_Entity then 10065 10066 -- The constraint denotes a discriminant of the curren type 10067 -- which renames the ancestor discriminant: 10068 10069 -- vv 10070 -- type Typ (D1 : ...; DN : ...) is 10071 -- new Anc (Discr => D1) with ... 10072 -- ^^ 10073 10074 if Ekind (Constr) = E_Discriminant then 10075 10076 -- The discriminant belongs to derived type Deriv_Typ. This 10077 -- is the final value for the ancestor discriminant as the 10078 -- derivations chain has been fully exhausted. 10079 10080 if Typ = Deriv_Typ then 10081 return Constr; 10082 10083 -- Otherwise the discriminant may be renamed or constrained 10084 -- at a lower level. Continue looking down the derivation 10085 -- chain. 10086 10087 else 10088 return 10089 Find_Discriminant_Value 10090 (Discr => Constr, 10091 Par_Typ => Par_Typ, 10092 Deriv_Typ => Deriv_Typ, 10093 Typ_Elmt => Next_Elmt (Typ_Elmt)); 10094 end if; 10095 10096 -- Otherwise the constraint denotes a reference to some name 10097 -- which results in a Girder discriminant: 10098 10099 -- vvvv 10100 -- Name : ...; 10101 -- type Typ (D1 : ...; DN : ...) is 10102 -- new Anc (Discr => Name) with ... 10103 -- ^^^^ 10104 10105 -- Return the name as this is the proper constraint of the 10106 -- discriminant. 10107 10108 else 10109 return Constr; 10110 end if; 10111 10112 -- The constraint denotes a reference to a name 10113 10114 elsif Is_Entity_Name (Constr) then 10115 return Find_Constraint_Value (Entity (Constr)); 10116 10117 -- Otherwise the current constraint is an expression which yields 10118 -- a Girder discriminant: 10119 10120 -- type Typ (D1 : ...; DN : ...) is 10121 -- new Anc (Discr => <expression>) with ... 10122 -- ^^^^^^^^^^ 10123 10124 -- Return the expression as this is the proper constraint of the 10125 -- discriminant. 10126 10127 else 10128 return Constr; 10129 end if; 10130 end Find_Constraint_Value; 10131 10132 -- Local variables 10133 10134 Constrs : constant Elist_Id := Stored_Constraint (Typ); 10135 10136 Constr_Elmt : Elmt_Id; 10137 Pos : Uint; 10138 Typ_Discr : Entity_Id; 10139 10140 -- Start of processing for Find_Discriminant_Value 10141 10142 begin 10143 -- The algorithm for finding the value of a discriminant works as 10144 -- follows. First, it recreates the derivation chain from Par_Typ 10145 -- to Deriv_Typ as a list: 10146 10147 -- Par_Typ (shown for completeness) 10148 -- v 10149 -- Ancestor_N <-- head of chain 10150 -- v 10151 -- Ancestor_1 10152 -- v 10153 -- Deriv_Typ <-- tail of chain 10154 10155 -- The algorithm then traces the fate of a parent discriminant down 10156 -- the derivation chain. At each derivation level, the discriminant 10157 -- may be either inherited or constrained. 10158 10159 -- 1) Discriminant is inherited: there are two cases, depending on 10160 -- which type is inheriting. 10161 10162 -- 1.1) Deriv_Typ is inheriting: 10163 10164 -- type Ancestor (D_1 : ...) is tagged ... 10165 -- type Deriv_Typ is new Ancestor ... 10166 10167 -- In this case the inherited discriminant is the final value of 10168 -- the parent discriminant because the end of the derivation chain 10169 -- has been reached. 10170 10171 -- 1.2) Some other type is inheriting: 10172 10173 -- type Ancestor_1 (D_1 : ...) is tagged ... 10174 -- type Ancestor_2 is new Ancestor_1 ... 10175 10176 -- In this case the algorithm continues to trace the fate of the 10177 -- inherited discriminant down the derivation chain because it may 10178 -- be further inherited or constrained. 10179 10180 -- 2) Discriminant is constrained: there are three cases, depending 10181 -- on what the constraint is. 10182 10183 -- 2.1) The constraint is another discriminant (aka renaming): 10184 10185 -- type Ancestor_1 (D_1 : ...) is tagged ... 10186 -- type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ... 10187 10188 -- In this case the constraining discriminant becomes the one to 10189 -- track down the derivation chain. The algorithm already knows 10190 -- that D_2 constrains D_1, therefore if the algorithm finds the 10191 -- value of D_2, then this would also be the value for D_1. 10192 10193 -- 2.2) The constraint is a name (aka Girder): 10194 10195 -- Name : ... 10196 -- type Ancestor_1 (D_1 : ...) is tagged ... 10197 -- type Ancestor_2 is new Ancestor_1 (D_1 => Name) ... 10198 10199 -- In this case the name is the final value of D_1 because the 10200 -- discriminant cannot be further constrained. 10201 10202 -- 2.3) The constraint is an expression (aka Girder): 10203 10204 -- type Ancestor_1 (D_1 : ...) is tagged ... 10205 -- type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ... 10206 10207 -- Similar to 2.2, the expression is the final value of D_1 10208 10209 Pos := Uint_1; 10210 10211 -- When a derived type constrains its parent type, all constaints 10212 -- appear in the Stored_Constraint list. Examine the list looking 10213 -- for a positional match. 10214 10215 if Present (Constrs) then 10216 Constr_Elmt := First_Elmt (Constrs); 10217 while Present (Constr_Elmt) loop 10218 10219 -- The position of the current constraint matches that of the 10220 -- ancestor discriminant. 10221 10222 if Pos = Discr_Pos then 10223 return Find_Constraint_Value (Node (Constr_Elmt)); 10224 end if; 10225 10226 Next_Elmt (Constr_Elmt); 10227 Pos := Pos + 1; 10228 end loop; 10229 10230 -- Otherwise the derived type does not constraint its parent type in 10231 -- which case it inherits the parent discriminants. 10232 10233 else 10234 Typ_Discr := First_Discriminant (Typ); 10235 while Present (Typ_Discr) loop 10236 10237 -- The position of the current discriminant matches that of the 10238 -- ancestor discriminant. 10239 10240 if Pos = Discr_Pos then 10241 return Find_Constraint_Value (Typ_Discr); 10242 end if; 10243 10244 Next_Discriminant (Typ_Discr); 10245 Pos := Pos + 1; 10246 end loop; 10247 end if; 10248 10249 -- A discriminant must always have a corresponding value. This is 10250 -- either another discriminant, a name, or an expression. If this 10251 -- point is reached, them most likely the derivation chain employs 10252 -- the wrong views of types. 10253 10254 pragma Assert (False); 10255 10256 return Empty; 10257 end Find_Discriminant_Value; 10258 10259 ----------------------- 10260 -- Map_Discriminants -- 10261 ----------------------- 10262 10263 procedure Map_Discriminants 10264 (Par_Typ : Entity_Id; 10265 Deriv_Typ : Entity_Id) 10266 is 10267 Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ); 10268 10269 Discr : Entity_Id; 10270 Discr_Val : Node_Or_Entity_Id; 10271 10272 begin 10273 -- Examine each discriminant of parent type Par_Typ and find a 10274 -- suitable value for it from the point of view of derived type 10275 -- Deriv_Typ. 10276 10277 if Has_Discriminants (Par_Typ) then 10278 Discr := First_Discriminant (Par_Typ); 10279 while Present (Discr) loop 10280 Discr_Val := 10281 Find_Discriminant_Value 10282 (Discr => Discr, 10283 Par_Typ => Par_Typ, 10284 Deriv_Typ => Deriv_Typ, 10285 Typ_Elmt => First_Elmt (Deriv_Chain)); 10286 10287 -- Create a mapping of the form: 10288 10289 -- parent type discriminant -> value 10290 10291 Type_Map.Set (Discr, Discr_Val); 10292 10293 Next_Discriminant (Discr); 10294 end loop; 10295 end if; 10296 end Map_Discriminants; 10297 10298 -------------------- 10299 -- Map_Primitives -- 10300 -------------------- 10301 10302 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is 10303 Deriv_Prim : Entity_Id; 10304 Par_Prim : Entity_Id; 10305 Par_Prims : Elist_Id; 10306 Prim_Elmt : Elmt_Id; 10307 10308 begin 10309 -- Inspect the primitives of the derived type and determine whether 10310 -- they relate to the primitives of the parent type. If there is a 10311 -- meaningful relation, create a mapping of the form: 10312 10313 -- parent type primitive -> perived type primitive 10314 10315 if Present (Direct_Primitive_Operations (Deriv_Typ)) then 10316 Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ)); 10317 while Present (Prim_Elmt) loop 10318 Deriv_Prim := Node (Prim_Elmt); 10319 10320 if Is_Subprogram (Deriv_Prim) 10321 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ 10322 then 10323 Add_Primitive (Deriv_Prim, Par_Typ); 10324 end if; 10325 10326 Next_Elmt (Prim_Elmt); 10327 end loop; 10328 end if; 10329 10330 -- If the parent operation is an interface operation, the overriding 10331 -- indicator is not present. Instead, we get from the interface 10332 -- operation the primitive of the current type that implements it. 10333 10334 if Is_Interface (Par_Typ) then 10335 Par_Prims := Collect_Primitive_Operations (Par_Typ); 10336 10337 if Present (Par_Prims) then 10338 Prim_Elmt := First_Elmt (Par_Prims); 10339 10340 while Present (Prim_Elmt) loop 10341 Par_Prim := Node (Prim_Elmt); 10342 Deriv_Prim := 10343 Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim); 10344 10345 if Present (Deriv_Prim) then 10346 Type_Map.Set (Par_Prim, Deriv_Prim); 10347 end if; 10348 10349 Next_Elmt (Prim_Elmt); 10350 end loop; 10351 end if; 10352 end if; 10353 end Map_Primitives; 10354 10355 -- Start of processing for Map_Types 10356 10357 begin 10358 -- Nothing to do if there are no types to work with 10359 10360 if No (Parent_Type) or else No (Derived_Type) then 10361 return; 10362 10363 -- Nothing to do if the mapping already exists 10364 10365 elsif Type_Map.Get (Parent_Type) = Derived_Type then 10366 return; 10367 10368 -- Nothing to do if both types are not tagged. Note that untagged types 10369 -- do not have primitive operations and their discriminants are already 10370 -- handled by gigi. 10371 10372 elsif not Is_Tagged_Type (Parent_Type) 10373 or else not Is_Tagged_Type (Derived_Type) 10374 then 10375 return; 10376 end if; 10377 10378 -- Create a mapping of the form 10379 10380 -- parent type -> derived type 10381 10382 -- to prevent any subsequent attempts to produce the same relations 10383 10384 Type_Map.Set (Parent_Type, Derived_Type); 10385 10386 -- Create mappings of the form 10387 10388 -- parent type discriminant -> derived type discriminant 10389 -- <or> 10390 -- parent type discriminant -> constraint 10391 10392 -- Note that mapping of discriminants breaks privacy because it needs to 10393 -- work with those views which contains the discriminants and any stored 10394 -- constraints. 10395 10396 Map_Discriminants 10397 (Par_Typ => Discriminated_View (Parent_Type), 10398 Deriv_Typ => Discriminated_View (Derived_Type)); 10399 10400 -- Create mappings of the form 10401 10402 -- parent type primitive -> derived type primitive 10403 10404 Map_Primitives 10405 (Par_Typ => Parent_Type, 10406 Deriv_Typ => Derived_Type); 10407 end Map_Types; 10408 10409 ---------------------------- 10410 -- Matching_Standard_Type -- 10411 ---------------------------- 10412 10413 function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is 10414 pragma Assert (Is_Scalar_Type (Typ)); 10415 Siz : constant Uint := Esize (Typ); 10416 10417 begin 10418 -- Floating-point cases 10419 10420 if Is_Floating_Point_Type (Typ) then 10421 if Siz <= Esize (Standard_Short_Float) then 10422 return Standard_Short_Float; 10423 elsif Siz <= Esize (Standard_Float) then 10424 return Standard_Float; 10425 elsif Siz <= Esize (Standard_Long_Float) then 10426 return Standard_Long_Float; 10427 elsif Siz <= Esize (Standard_Long_Long_Float) then 10428 return Standard_Long_Long_Float; 10429 else 10430 raise Program_Error; 10431 end if; 10432 10433 -- Integer cases (includes fixed-point types) 10434 10435 -- Unsigned integer cases (includes normal enumeration types) 10436 10437 elsif Is_Unsigned_Type (Typ) then 10438 if Siz <= Esize (Standard_Short_Short_Unsigned) then 10439 return Standard_Short_Short_Unsigned; 10440 elsif Siz <= Esize (Standard_Short_Unsigned) then 10441 return Standard_Short_Unsigned; 10442 elsif Siz <= Esize (Standard_Unsigned) then 10443 return Standard_Unsigned; 10444 elsif Siz <= Esize (Standard_Long_Unsigned) then 10445 return Standard_Long_Unsigned; 10446 elsif Siz <= Esize (Standard_Long_Long_Unsigned) then 10447 return Standard_Long_Long_Unsigned; 10448 else 10449 raise Program_Error; 10450 end if; 10451 10452 -- Signed integer cases 10453 10454 else 10455 if Siz <= Esize (Standard_Short_Short_Integer) then 10456 return Standard_Short_Short_Integer; 10457 elsif Siz <= Esize (Standard_Short_Integer) then 10458 return Standard_Short_Integer; 10459 elsif Siz <= Esize (Standard_Integer) then 10460 return Standard_Integer; 10461 elsif Siz <= Esize (Standard_Long_Integer) then 10462 return Standard_Long_Integer; 10463 elsif Siz <= Esize (Standard_Long_Long_Integer) then 10464 return Standard_Long_Long_Integer; 10465 else 10466 raise Program_Error; 10467 end if; 10468 end if; 10469 end Matching_Standard_Type; 10470 10471 ----------------------------- 10472 -- May_Generate_Large_Temp -- 10473 ----------------------------- 10474 10475 -- At the current time, the only types that we return False for (i.e. where 10476 -- we decide we know they cannot generate large temps) are ones where we 10477 -- know the size is 256 bits or less at compile time, and we are still not 10478 -- doing a thorough job on arrays and records ??? 10479 10480 function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is 10481 begin 10482 if not Size_Known_At_Compile_Time (Typ) then 10483 return False; 10484 10485 elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then 10486 return False; 10487 10488 elsif Is_Array_Type (Typ) 10489 and then Present (Packed_Array_Impl_Type (Typ)) 10490 then 10491 return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ)); 10492 10493 -- We could do more here to find other small types ??? 10494 10495 else 10496 return True; 10497 end if; 10498 end May_Generate_Large_Temp; 10499 10500 -------------------------------------------- 10501 -- Needs_Conditional_Null_Excluding_Check -- 10502 -------------------------------------------- 10503 10504 function Needs_Conditional_Null_Excluding_Check 10505 (Typ : Entity_Id) return Boolean 10506 is 10507 begin 10508 return 10509 Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ)); 10510 end Needs_Conditional_Null_Excluding_Check; 10511 10512 ---------------------------- 10513 -- Needs_Constant_Address -- 10514 ---------------------------- 10515 10516 function Needs_Constant_Address 10517 (Decl : Node_Id; 10518 Typ : Entity_Id) return Boolean 10519 is 10520 begin 10521 -- If we have no initialization of any kind, then we don't need to place 10522 -- any restrictions on the address clause, because the object will be 10523 -- elaborated after the address clause is evaluated. This happens if the 10524 -- declaration has no initial expression, or the type has no implicit 10525 -- initialization, or the object is imported. 10526 10527 -- The same holds for all initialized scalar types and all access types. 10528 -- Packed bit arrays of size up to 64 are represented using a modular 10529 -- type with an initialization (to zero) and can be processed like other 10530 -- initialized scalar types. 10531 10532 -- If the type is controlled, code to attach the object to a 10533 -- finalization chain is generated at the point of declaration, and 10534 -- therefore the elaboration of the object cannot be delayed: the 10535 -- address expression must be a constant. 10536 10537 if No (Expression (Decl)) 10538 and then not Needs_Finalization (Typ) 10539 and then 10540 (not Has_Non_Null_Base_Init_Proc (Typ) 10541 or else Is_Imported (Defining_Identifier (Decl))) 10542 then 10543 return False; 10544 10545 elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ)) 10546 or else Is_Access_Type (Typ) 10547 or else 10548 (Is_Bit_Packed_Array (Typ) 10549 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ))) 10550 then 10551 return False; 10552 10553 else 10554 -- Otherwise, we require the address clause to be constant because 10555 -- the call to the initialization procedure (or the attach code) has 10556 -- to happen at the point of the declaration. 10557 10558 -- Actually the IP call has been moved to the freeze actions anyway, 10559 -- so maybe we can relax this restriction??? 10560 10561 return True; 10562 end if; 10563 end Needs_Constant_Address; 10564 10565 ------------------------ 10566 -- Needs_Finalization -- 10567 ------------------------ 10568 10569 function Needs_Finalization (Typ : Entity_Id) return Boolean is 10570 function Has_Some_Controlled_Component 10571 (Input_Typ : Entity_Id) return Boolean; 10572 -- Determine whether type Input_Typ has at least one controlled 10573 -- component. 10574 10575 ----------------------------------- 10576 -- Has_Some_Controlled_Component -- 10577 ----------------------------------- 10578 10579 function Has_Some_Controlled_Component 10580 (Input_Typ : Entity_Id) return Boolean 10581 is 10582 Comp : Entity_Id; 10583 10584 begin 10585 -- When a type is already frozen and has at least one controlled 10586 -- component, or is manually decorated, it is sufficient to inspect 10587 -- flag Has_Controlled_Component. 10588 10589 if Has_Controlled_Component (Input_Typ) then 10590 return True; 10591 10592 -- Otherwise inspect the internals of the type 10593 10594 elsif not Is_Frozen (Input_Typ) then 10595 if Is_Array_Type (Input_Typ) then 10596 return Needs_Finalization (Component_Type (Input_Typ)); 10597 10598 elsif Is_Record_Type (Input_Typ) then 10599 Comp := First_Component (Input_Typ); 10600 while Present (Comp) loop 10601 if Needs_Finalization (Etype (Comp)) then 10602 return True; 10603 end if; 10604 10605 Next_Component (Comp); 10606 end loop; 10607 end if; 10608 end if; 10609 10610 return False; 10611 end Has_Some_Controlled_Component; 10612 10613 -- Start of processing for Needs_Finalization 10614 10615 begin 10616 -- Certain run-time configurations and targets do not provide support 10617 -- for controlled types. 10618 10619 if Restriction_Active (No_Finalization) then 10620 return False; 10621 10622 -- C++ types are not considered controlled. It is assumed that the non- 10623 -- Ada side will handle their clean up. 10624 10625 elsif Convention (Typ) = Convention_CPP then 10626 return False; 10627 10628 -- Class-wide types are treated as controlled because derivations from 10629 -- the root type may introduce controlled components. 10630 10631 elsif Is_Class_Wide_Type (Typ) then 10632 return True; 10633 10634 -- Concurrent types are controlled as long as their corresponding record 10635 -- is controlled. 10636 10637 elsif Is_Concurrent_Type (Typ) 10638 and then Present (Corresponding_Record_Type (Typ)) 10639 and then Needs_Finalization (Corresponding_Record_Type (Typ)) 10640 then 10641 return True; 10642 10643 -- Otherwise the type is controlled when it is either derived from type 10644 -- [Limited_]Controlled and not subject to aspect Disable_Controlled, or 10645 -- contains at least one controlled component. 10646 10647 else 10648 return 10649 Is_Controlled (Typ) or else Has_Some_Controlled_Component (Typ); 10650 end if; 10651 end Needs_Finalization; 10652 10653 ---------------------------- 10654 -- New_Class_Wide_Subtype -- 10655 ---------------------------- 10656 10657 function New_Class_Wide_Subtype 10658 (CW_Typ : Entity_Id; 10659 N : Node_Id) return Entity_Id 10660 is 10661 Res : constant Entity_Id := Create_Itype (E_Void, N); 10662 10663 -- Capture relevant attributes of the class-wide subtype which must be 10664 -- restored after the copy. 10665 10666 Res_Chars : constant Name_Id := Chars (Res); 10667 Res_Is_CGE : constant Boolean := Is_Checked_Ghost_Entity (Res); 10668 Res_Is_IGE : constant Boolean := Is_Ignored_Ghost_Entity (Res); 10669 Res_Is_IGN : constant Boolean := Is_Ignored_Ghost_Node (Res); 10670 Res_Scope : constant Entity_Id := Scope (Res); 10671 10672 begin 10673 Copy_Node (CW_Typ, Res); 10674 10675 -- Restore the relevant attributes of the class-wide subtype 10676 10677 Set_Chars (Res, Res_Chars); 10678 Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE); 10679 Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE); 10680 Set_Is_Ignored_Ghost_Node (Res, Res_Is_IGN); 10681 Set_Scope (Res, Res_Scope); 10682 10683 -- Decorate the class-wide subtype 10684 10685 Set_Associated_Node_For_Itype (Res, N); 10686 Set_Comes_From_Source (Res, False); 10687 Set_Ekind (Res, E_Class_Wide_Subtype); 10688 Set_Etype (Res, Base_Type (CW_Typ)); 10689 Set_Freeze_Node (Res, Empty); 10690 Set_Is_Frozen (Res, False); 10691 Set_Is_Itype (Res); 10692 Set_Is_Public (Res, False); 10693 Set_Next_Entity (Res, Empty); 10694 Set_Prev_Entity (Res, Empty); 10695 Set_Sloc (Res, Sloc (N)); 10696 10697 Set_Public_Status (Res); 10698 10699 return Res; 10700 end New_Class_Wide_Subtype; 10701 10702 -------------------------------- 10703 -- Non_Limited_Designated_Type -- 10704 --------------------------------- 10705 10706 function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is 10707 Desig : constant Entity_Id := Designated_Type (T); 10708 begin 10709 if Has_Non_Limited_View (Desig) then 10710 return Non_Limited_View (Desig); 10711 else 10712 return Desig; 10713 end if; 10714 end Non_Limited_Designated_Type; 10715 10716 ----------------------------------- 10717 -- OK_To_Do_Constant_Replacement -- 10718 ----------------------------------- 10719 10720 function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is 10721 ES : constant Entity_Id := Scope (E); 10722 CS : Entity_Id; 10723 10724 begin 10725 -- Do not replace statically allocated objects, because they may be 10726 -- modified outside the current scope. 10727 10728 if Is_Statically_Allocated (E) then 10729 return False; 10730 10731 -- Do not replace aliased or volatile objects, since we don't know what 10732 -- else might change the value. 10733 10734 elsif Is_Aliased (E) or else Treat_As_Volatile (E) then 10735 return False; 10736 10737 -- Debug flag -gnatdM disconnects this optimization 10738 10739 elsif Debug_Flag_MM then 10740 return False; 10741 10742 -- Otherwise check scopes 10743 10744 else 10745 CS := Current_Scope; 10746 10747 loop 10748 -- If we are in right scope, replacement is safe 10749 10750 if CS = ES then 10751 return True; 10752 10753 -- Packages do not affect the determination of safety 10754 10755 elsif Ekind (CS) = E_Package then 10756 exit when CS = Standard_Standard; 10757 CS := Scope (CS); 10758 10759 -- Blocks do not affect the determination of safety 10760 10761 elsif Ekind (CS) = E_Block then 10762 CS := Scope (CS); 10763 10764 -- Loops do not affect the determination of safety. Note that we 10765 -- kill all current values on entry to a loop, so we are just 10766 -- talking about processing within a loop here. 10767 10768 elsif Ekind (CS) = E_Loop then 10769 CS := Scope (CS); 10770 10771 -- Otherwise, the reference is dubious, and we cannot be sure that 10772 -- it is safe to do the replacement. 10773 10774 else 10775 exit; 10776 end if; 10777 end loop; 10778 10779 return False; 10780 end if; 10781 end OK_To_Do_Constant_Replacement; 10782 10783 ------------------------------------ 10784 -- Possible_Bit_Aligned_Component -- 10785 ------------------------------------ 10786 10787 function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is 10788 begin 10789 -- Do not process an unanalyzed node because it is not yet decorated and 10790 -- most checks performed below will fail. 10791 10792 if not Analyzed (N) then 10793 return False; 10794 end if; 10795 10796 -- There are never alignment issues in CodePeer mode 10797 10798 if CodePeer_Mode then 10799 return False; 10800 end if; 10801 10802 case Nkind (N) is 10803 10804 -- Case of indexed component 10805 10806 when N_Indexed_Component => 10807 declare 10808 P : constant Node_Id := Prefix (N); 10809 Ptyp : constant Entity_Id := Etype (P); 10810 10811 begin 10812 -- If we know the component size and it is less than 64, then 10813 -- we are definitely OK. The back end always does assignment of 10814 -- misaligned small objects correctly. 10815 10816 if Known_Static_Component_Size (Ptyp) 10817 and then Component_Size (Ptyp) <= 64 10818 then 10819 return False; 10820 10821 -- Otherwise, we need to test the prefix, to see if we are 10822 -- indexing from a possibly unaligned component. 10823 10824 else 10825 return Possible_Bit_Aligned_Component (P); 10826 end if; 10827 end; 10828 10829 -- Case of selected component 10830 10831 when N_Selected_Component => 10832 declare 10833 P : constant Node_Id := Prefix (N); 10834 Comp : constant Entity_Id := Entity (Selector_Name (N)); 10835 10836 begin 10837 -- If there is no component clause, then we are in the clear 10838 -- since the back end will never misalign a large component 10839 -- unless it is forced to do so. In the clear means we need 10840 -- only the recursive test on the prefix. 10841 10842 if Component_May_Be_Bit_Aligned (Comp) then 10843 return True; 10844 else 10845 return Possible_Bit_Aligned_Component (P); 10846 end if; 10847 end; 10848 10849 -- For a slice, test the prefix, if that is possibly misaligned, 10850 -- then for sure the slice is. 10851 10852 when N_Slice => 10853 return Possible_Bit_Aligned_Component (Prefix (N)); 10854 10855 -- For an unchecked conversion, check whether the expression may 10856 -- be bit-aligned. 10857 10858 when N_Unchecked_Type_Conversion => 10859 return Possible_Bit_Aligned_Component (Expression (N)); 10860 10861 -- If we have none of the above, it means that we have fallen off the 10862 -- top testing prefixes recursively, and we now have a stand alone 10863 -- object, where we don't have a problem, unless this is a renaming, 10864 -- in which case we need to look into the renamed object. 10865 10866 when others => 10867 if Is_Entity_Name (N) 10868 and then Present (Renamed_Object (Entity (N))) 10869 then 10870 return 10871 Possible_Bit_Aligned_Component (Renamed_Object (Entity (N))); 10872 else 10873 return False; 10874 end if; 10875 end case; 10876 end Possible_Bit_Aligned_Component; 10877 10878 ----------------------------------------------- 10879 -- Process_Statements_For_Controlled_Objects -- 10880 ----------------------------------------------- 10881 10882 procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is 10883 Loc : constant Source_Ptr := Sloc (N); 10884 10885 function Are_Wrapped (L : List_Id) return Boolean; 10886 -- Determine whether list L contains only one statement which is a block 10887 10888 function Wrap_Statements_In_Block 10889 (L : List_Id; 10890 Scop : Entity_Id := Current_Scope) return Node_Id; 10891 -- Given a list of statements L, wrap it in a block statement and return 10892 -- the generated node. Scop is either the current scope or the scope of 10893 -- the context (if applicable). 10894 10895 ----------------- 10896 -- Are_Wrapped -- 10897 ----------------- 10898 10899 function Are_Wrapped (L : List_Id) return Boolean is 10900 Stmt : constant Node_Id := First (L); 10901 begin 10902 return 10903 Present (Stmt) 10904 and then No (Next (Stmt)) 10905 and then Nkind (Stmt) = N_Block_Statement; 10906 end Are_Wrapped; 10907 10908 ------------------------------ 10909 -- Wrap_Statements_In_Block -- 10910 ------------------------------ 10911 10912 function Wrap_Statements_In_Block 10913 (L : List_Id; 10914 Scop : Entity_Id := Current_Scope) return Node_Id 10915 is 10916 Block_Id : Entity_Id; 10917 Block_Nod : Node_Id; 10918 Iter_Loop : Entity_Id; 10919 10920 begin 10921 Block_Nod := 10922 Make_Block_Statement (Loc, 10923 Declarations => No_List, 10924 Handled_Statement_Sequence => 10925 Make_Handled_Sequence_Of_Statements (Loc, 10926 Statements => L)); 10927 10928 -- Create a label for the block in case the block needs to manage the 10929 -- secondary stack. A label allows for flag Uses_Sec_Stack to be set. 10930 10931 Add_Block_Identifier (Block_Nod, Block_Id); 10932 10933 -- When wrapping the statements of an iterator loop, check whether 10934 -- the loop requires secondary stack management and if so, propagate 10935 -- the appropriate flags to the block. This ensures that the cursor 10936 -- is properly cleaned up at each iteration of the loop. 10937 10938 Iter_Loop := Find_Enclosing_Iterator_Loop (Scop); 10939 10940 if Present (Iter_Loop) then 10941 Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop)); 10942 10943 -- Secondary stack reclamation is suppressed when the associated 10944 -- iterator loop contains a return statement which uses the stack. 10945 10946 Set_Sec_Stack_Needed_For_Return 10947 (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop)); 10948 end if; 10949 10950 return Block_Nod; 10951 end Wrap_Statements_In_Block; 10952 10953 -- Local variables 10954 10955 Block : Node_Id; 10956 10957 -- Start of processing for Process_Statements_For_Controlled_Objects 10958 10959 begin 10960 -- Whenever a non-handled statement list is wrapped in a block, the 10961 -- block must be explicitly analyzed to redecorate all entities in the 10962 -- list and ensure that a finalizer is properly built. 10963 10964 case Nkind (N) is 10965 when N_Conditional_Entry_Call 10966 | N_Elsif_Part 10967 | N_If_Statement 10968 | N_Selective_Accept 10969 => 10970 -- Check the "then statements" for elsif parts and if statements 10971 10972 if Nkind_In (N, N_Elsif_Part, N_If_Statement) 10973 and then not Is_Empty_List (Then_Statements (N)) 10974 and then not Are_Wrapped (Then_Statements (N)) 10975 and then Requires_Cleanup_Actions 10976 (L => Then_Statements (N), 10977 Lib_Level => False, 10978 Nested_Constructs => False) 10979 then 10980 Block := Wrap_Statements_In_Block (Then_Statements (N)); 10981 Set_Then_Statements (N, New_List (Block)); 10982 10983 Analyze (Block); 10984 end if; 10985 10986 -- Check the "else statements" for conditional entry calls, if 10987 -- statements and selective accepts. 10988 10989 if Nkind_In (N, N_Conditional_Entry_Call, 10990 N_If_Statement, 10991 N_Selective_Accept) 10992 and then not Is_Empty_List (Else_Statements (N)) 10993 and then not Are_Wrapped (Else_Statements (N)) 10994 and then Requires_Cleanup_Actions 10995 (L => Else_Statements (N), 10996 Lib_Level => False, 10997 Nested_Constructs => False) 10998 then 10999 Block := Wrap_Statements_In_Block (Else_Statements (N)); 11000 Set_Else_Statements (N, New_List (Block)); 11001 11002 Analyze (Block); 11003 end if; 11004 11005 when N_Abortable_Part 11006 | N_Accept_Alternative 11007 | N_Case_Statement_Alternative 11008 | N_Delay_Alternative 11009 | N_Entry_Call_Alternative 11010 | N_Exception_Handler 11011 | N_Loop_Statement 11012 | N_Triggering_Alternative 11013 => 11014 if not Is_Empty_List (Statements (N)) 11015 and then not Are_Wrapped (Statements (N)) 11016 and then Requires_Cleanup_Actions 11017 (L => Statements (N), 11018 Lib_Level => False, 11019 Nested_Constructs => False) 11020 then 11021 if Nkind (N) = N_Loop_Statement 11022 and then Present (Identifier (N)) 11023 then 11024 Block := 11025 Wrap_Statements_In_Block 11026 (L => Statements (N), 11027 Scop => Entity (Identifier (N))); 11028 else 11029 Block := Wrap_Statements_In_Block (Statements (N)); 11030 end if; 11031 11032 Set_Statements (N, New_List (Block)); 11033 Analyze (Block); 11034 end if; 11035 11036 -- Could be e.g. a loop that was transformed into a block or null 11037 -- statement. Do nothing for terminate alternatives. 11038 11039 when N_Block_Statement 11040 | N_Null_Statement 11041 | N_Terminate_Alternative 11042 => 11043 null; 11044 11045 when others => 11046 raise Program_Error; 11047 end case; 11048 end Process_Statements_For_Controlled_Objects; 11049 11050 ------------------ 11051 -- Power_Of_Two -- 11052 ------------------ 11053 11054 function Power_Of_Two (N : Node_Id) return Nat is 11055 Typ : constant Entity_Id := Etype (N); 11056 pragma Assert (Is_Integer_Type (Typ)); 11057 11058 Siz : constant Nat := UI_To_Int (Esize (Typ)); 11059 Val : Uint; 11060 11061 begin 11062 if not Compile_Time_Known_Value (N) then 11063 return 0; 11064 11065 else 11066 Val := Expr_Value (N); 11067 for J in 1 .. Siz - 1 loop 11068 if Val = Uint_2 ** J then 11069 return J; 11070 end if; 11071 end loop; 11072 11073 return 0; 11074 end if; 11075 end Power_Of_Two; 11076 11077 ---------------------- 11078 -- Remove_Init_Call -- 11079 ---------------------- 11080 11081 function Remove_Init_Call 11082 (Var : Entity_Id; 11083 Rep_Clause : Node_Id) return Node_Id 11084 is 11085 Par : constant Node_Id := Parent (Var); 11086 Typ : constant Entity_Id := Etype (Var); 11087 11088 Init_Proc : Entity_Id; 11089 -- Initialization procedure for Typ 11090 11091 function Find_Init_Call_In_List (From : Node_Id) return Node_Id; 11092 -- Look for init call for Var starting at From and scanning the 11093 -- enclosing list until Rep_Clause or the end of the list is reached. 11094 11095 ---------------------------- 11096 -- Find_Init_Call_In_List -- 11097 ---------------------------- 11098 11099 function Find_Init_Call_In_List (From : Node_Id) return Node_Id is 11100 Init_Call : Node_Id; 11101 11102 begin 11103 Init_Call := From; 11104 while Present (Init_Call) and then Init_Call /= Rep_Clause loop 11105 if Nkind (Init_Call) = N_Procedure_Call_Statement 11106 and then Is_Entity_Name (Name (Init_Call)) 11107 and then Entity (Name (Init_Call)) = Init_Proc 11108 then 11109 return Init_Call; 11110 end if; 11111 11112 Next (Init_Call); 11113 end loop; 11114 11115 return Empty; 11116 end Find_Init_Call_In_List; 11117 11118 Init_Call : Node_Id; 11119 11120 -- Start of processing for Find_Init_Call 11121 11122 begin 11123 if Present (Initialization_Statements (Var)) then 11124 Init_Call := Initialization_Statements (Var); 11125 Set_Initialization_Statements (Var, Empty); 11126 11127 elsif not Has_Non_Null_Base_Init_Proc (Typ) then 11128 11129 -- No init proc for the type, so obviously no call to be found 11130 11131 return Empty; 11132 11133 else 11134 -- We might be able to handle other cases below by just properly 11135 -- setting Initialization_Statements at the point where the init proc 11136 -- call is generated??? 11137 11138 Init_Proc := Base_Init_Proc (Typ); 11139 11140 -- First scan the list containing the declaration of Var 11141 11142 Init_Call := Find_Init_Call_In_List (From => Next (Par)); 11143 11144 -- If not found, also look on Var's freeze actions list, if any, 11145 -- since the init call may have been moved there (case of an address 11146 -- clause applying to Var). 11147 11148 if No (Init_Call) and then Present (Freeze_Node (Var)) then 11149 Init_Call := 11150 Find_Init_Call_In_List (First (Actions (Freeze_Node (Var)))); 11151 end if; 11152 11153 -- If the initialization call has actuals that use the secondary 11154 -- stack, the call may have been wrapped into a temporary block, in 11155 -- which case the block itself has to be removed. 11156 11157 if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then 11158 declare 11159 Blk : constant Node_Id := Next (Par); 11160 begin 11161 if Present 11162 (Find_Init_Call_In_List 11163 (First (Statements (Handled_Statement_Sequence (Blk))))) 11164 then 11165 Init_Call := Blk; 11166 end if; 11167 end; 11168 end if; 11169 end if; 11170 11171 if Present (Init_Call) then 11172 Remove (Init_Call); 11173 end if; 11174 return Init_Call; 11175 end Remove_Init_Call; 11176 11177 ------------------------- 11178 -- Remove_Side_Effects -- 11179 ------------------------- 11180 11181 procedure Remove_Side_Effects 11182 (Exp : Node_Id; 11183 Name_Req : Boolean := False; 11184 Renaming_Req : Boolean := False; 11185 Variable_Ref : Boolean := False; 11186 Related_Id : Entity_Id := Empty; 11187 Is_Low_Bound : Boolean := False; 11188 Is_High_Bound : Boolean := False; 11189 Check_Side_Effects : Boolean := True) 11190 is 11191 function Build_Temporary 11192 (Loc : Source_Ptr; 11193 Id : Character; 11194 Related_Nod : Node_Id := Empty) return Entity_Id; 11195 -- Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod 11196 -- is present (xxx is taken from the Chars field of Related_Nod), 11197 -- otherwise it generates an internal temporary. The created temporary 11198 -- entity is marked as internal. 11199 11200 --------------------- 11201 -- Build_Temporary -- 11202 --------------------- 11203 11204 function Build_Temporary 11205 (Loc : Source_Ptr; 11206 Id : Character; 11207 Related_Nod : Node_Id := Empty) return Entity_Id 11208 is 11209 Temp_Id : Entity_Id; 11210 Temp_Nam : Name_Id; 11211 11212 begin 11213 -- The context requires an external symbol 11214 11215 if Present (Related_Id) then 11216 if Is_Low_Bound then 11217 Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST"); 11218 else pragma Assert (Is_High_Bound); 11219 Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST"); 11220 end if; 11221 11222 Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam); 11223 11224 -- Otherwise generate an internal temporary 11225 11226 else 11227 Temp_Id := Make_Temporary (Loc, Id, Related_Nod); 11228 end if; 11229 11230 Set_Is_Internal (Temp_Id); 11231 11232 return Temp_Id; 11233 end Build_Temporary; 11234 11235 -- Local variables 11236 11237 Loc : constant Source_Ptr := Sloc (Exp); 11238 Exp_Type : constant Entity_Id := Etype (Exp); 11239 Svg_Suppress : constant Suppress_Record := Scope_Suppress; 11240 Def_Id : Entity_Id; 11241 E : Node_Id; 11242 New_Exp : Node_Id; 11243 Ptr_Typ_Decl : Node_Id; 11244 Ref_Type : Entity_Id; 11245 Res : Node_Id; 11246 11247 -- Start of processing for Remove_Side_Effects 11248 11249 begin 11250 -- Handle cases in which there is nothing to do. In GNATprove mode, 11251 -- removal of side effects is useful for the light expansion of 11252 -- renamings. This removal should only occur when not inside a 11253 -- generic and not doing a preanalysis. 11254 11255 if not Expander_Active 11256 and (Inside_A_Generic or not Full_Analysis or not GNATprove_Mode) 11257 then 11258 return; 11259 11260 -- Cannot generate temporaries if the invocation to remove side effects 11261 -- was issued too early and the type of the expression is not resolved 11262 -- (this happens because routines Duplicate_Subexpr_XX implicitly invoke 11263 -- Remove_Side_Effects). 11264 11265 elsif No (Exp_Type) 11266 or else Ekind (Exp_Type) = E_Access_Attribute_Type 11267 then 11268 return; 11269 11270 -- Nothing to do if prior expansion determined that a function call does 11271 -- not require side effect removal. 11272 11273 elsif Nkind (Exp) = N_Function_Call 11274 and then No_Side_Effect_Removal (Exp) 11275 then 11276 return; 11277 11278 -- No action needed for side-effect free expressions 11279 11280 elsif Check_Side_Effects 11281 and then Side_Effect_Free (Exp, Name_Req, Variable_Ref) 11282 then 11283 return; 11284 11285 -- Generating C code we cannot remove side effect of function returning 11286 -- class-wide types since there is no secondary stack (required to use 11287 -- 'reference). 11288 11289 elsif Modify_Tree_For_C 11290 and then Nkind (Exp) = N_Function_Call 11291 and then Is_Class_Wide_Type (Etype (Exp)) 11292 then 11293 return; 11294 end if; 11295 11296 -- The remaining processing is done with all checks suppressed 11297 11298 -- Note: from now on, don't use return statements, instead do a goto 11299 -- Leave, to ensure that we properly restore Scope_Suppress.Suppress. 11300 11301 Scope_Suppress.Suppress := (others => True); 11302 11303 -- If this is an elementary or a small not-by-reference record type, and 11304 -- we need to capture the value, just make a constant; this is cheap and 11305 -- objects of both kinds of types can be bit aligned, so it might not be 11306 -- possible to generate a reference to them. Likewise if this is not a 11307 -- name reference, except for a type conversion, because we would enter 11308 -- an infinite recursion with Checks.Apply_Predicate_Check if the target 11309 -- type has predicates (and type conversions need a specific treatment 11310 -- anyway, see below). Also do it if we have a volatile reference and 11311 -- Name_Req is not set (see comments for Side_Effect_Free). 11312 11313 if (Is_Elementary_Type (Exp_Type) 11314 or else (Is_Record_Type (Exp_Type) 11315 and then Known_Static_RM_Size (Exp_Type) 11316 and then RM_Size (Exp_Type) <= 64 11317 and then not Has_Discriminants (Exp_Type) 11318 and then not Is_By_Reference_Type (Exp_Type))) 11319 and then (Variable_Ref 11320 or else (not Is_Name_Reference (Exp) 11321 and then Nkind (Exp) /= N_Type_Conversion) 11322 or else (not Name_Req 11323 and then Is_Volatile_Reference (Exp))) 11324 then 11325 Def_Id := Build_Temporary (Loc, 'R', Exp); 11326 Set_Etype (Def_Id, Exp_Type); 11327 Res := New_Occurrence_Of (Def_Id, Loc); 11328 11329 -- If the expression is a packed reference, it must be reanalyzed and 11330 -- expanded, depending on context. This is the case for actuals where 11331 -- a constraint check may capture the actual before expansion of the 11332 -- call is complete. 11333 11334 if Nkind (Exp) = N_Indexed_Component 11335 and then Is_Packed (Etype (Prefix (Exp))) 11336 then 11337 Set_Analyzed (Exp, False); 11338 Set_Analyzed (Prefix (Exp), False); 11339 end if; 11340 11341 -- Generate: 11342 -- Rnn : Exp_Type renames Expr; 11343 11344 if Renaming_Req then 11345 E := 11346 Make_Object_Renaming_Declaration (Loc, 11347 Defining_Identifier => Def_Id, 11348 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11349 Name => Relocate_Node (Exp)); 11350 11351 -- Generate: 11352 -- Rnn : constant Exp_Type := Expr; 11353 11354 else 11355 E := 11356 Make_Object_Declaration (Loc, 11357 Defining_Identifier => Def_Id, 11358 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11359 Constant_Present => True, 11360 Expression => Relocate_Node (Exp)); 11361 11362 Set_Assignment_OK (E); 11363 end if; 11364 11365 Insert_Action (Exp, E); 11366 11367 -- If the expression has the form v.all then we can just capture the 11368 -- pointer, and then do an explicit dereference on the result, but 11369 -- this is not right if this is a volatile reference. 11370 11371 elsif Nkind (Exp) = N_Explicit_Dereference 11372 and then not Is_Volatile_Reference (Exp) 11373 then 11374 Def_Id := Build_Temporary (Loc, 'R', Exp); 11375 Res := 11376 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc)); 11377 11378 Insert_Action (Exp, 11379 Make_Object_Declaration (Loc, 11380 Defining_Identifier => Def_Id, 11381 Object_Definition => 11382 New_Occurrence_Of (Etype (Prefix (Exp)), Loc), 11383 Constant_Present => True, 11384 Expression => Relocate_Node (Prefix (Exp)))); 11385 11386 -- Similar processing for an unchecked conversion of an expression of 11387 -- the form v.all, where we want the same kind of treatment. 11388 11389 elsif Nkind (Exp) = N_Unchecked_Type_Conversion 11390 and then Nkind (Expression (Exp)) = N_Explicit_Dereference 11391 then 11392 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref); 11393 goto Leave; 11394 11395 -- If this is a type conversion, leave the type conversion and remove 11396 -- the side effects in the expression. This is important in several 11397 -- circumstances: for change of representations, and also when this is a 11398 -- view conversion to a smaller object, where gigi can end up creating 11399 -- its own temporary of the wrong size. 11400 11401 elsif Nkind (Exp) = N_Type_Conversion then 11402 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref); 11403 11404 -- Generating C code the type conversion of an access to constrained 11405 -- array type into an access to unconstrained array type involves 11406 -- initializing a fat pointer and the expression must be free of 11407 -- side effects to safely compute its bounds. 11408 11409 if Modify_Tree_For_C 11410 and then Is_Access_Type (Etype (Exp)) 11411 and then Is_Array_Type (Designated_Type (Etype (Exp))) 11412 and then not Is_Constrained (Designated_Type (Etype (Exp))) 11413 then 11414 Def_Id := Build_Temporary (Loc, 'R', Exp); 11415 Set_Etype (Def_Id, Exp_Type); 11416 Res := New_Occurrence_Of (Def_Id, Loc); 11417 11418 Insert_Action (Exp, 11419 Make_Object_Declaration (Loc, 11420 Defining_Identifier => Def_Id, 11421 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11422 Constant_Present => True, 11423 Expression => Relocate_Node (Exp))); 11424 else 11425 goto Leave; 11426 end if; 11427 11428 -- If this is an unchecked conversion that Gigi can't handle, make 11429 -- a copy or a use a renaming to capture the value. 11430 11431 elsif Nkind (Exp) = N_Unchecked_Type_Conversion 11432 and then not Safe_Unchecked_Type_Conversion (Exp) 11433 then 11434 if CW_Or_Has_Controlled_Part (Exp_Type) then 11435 11436 -- Use a renaming to capture the expression, rather than create 11437 -- a controlled temporary. 11438 11439 Def_Id := Build_Temporary (Loc, 'R', Exp); 11440 Res := New_Occurrence_Of (Def_Id, Loc); 11441 11442 Insert_Action (Exp, 11443 Make_Object_Renaming_Declaration (Loc, 11444 Defining_Identifier => Def_Id, 11445 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11446 Name => Relocate_Node (Exp))); 11447 11448 else 11449 Def_Id := Build_Temporary (Loc, 'R', Exp); 11450 Set_Etype (Def_Id, Exp_Type); 11451 Res := New_Occurrence_Of (Def_Id, Loc); 11452 11453 E := 11454 Make_Object_Declaration (Loc, 11455 Defining_Identifier => Def_Id, 11456 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11457 Constant_Present => not Is_Variable (Exp), 11458 Expression => Relocate_Node (Exp)); 11459 11460 Set_Assignment_OK (E); 11461 Insert_Action (Exp, E); 11462 end if; 11463 11464 -- For expressions that denote names, we can use a renaming scheme. 11465 -- This is needed for correctness in the case of a volatile object of 11466 -- a non-volatile type because the Make_Reference call of the "default" 11467 -- approach would generate an illegal access value (an access value 11468 -- cannot designate such an object - see Analyze_Reference). 11469 11470 elsif Is_Name_Reference (Exp) 11471 11472 -- We skip using this scheme if we have an object of a volatile 11473 -- type and we do not have Name_Req set true (see comments for 11474 -- Side_Effect_Free). 11475 11476 and then (Name_Req or else not Treat_As_Volatile (Exp_Type)) 11477 then 11478 Def_Id := Build_Temporary (Loc, 'R', Exp); 11479 Res := New_Occurrence_Of (Def_Id, Loc); 11480 11481 Insert_Action (Exp, 11482 Make_Object_Renaming_Declaration (Loc, 11483 Defining_Identifier => Def_Id, 11484 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11485 Name => Relocate_Node (Exp))); 11486 11487 -- If this is a packed reference, or a selected component with 11488 -- a non-standard representation, a reference to the temporary 11489 -- will be replaced by a copy of the original expression (see 11490 -- Exp_Ch2.Expand_Renaming). Otherwise the temporary must be 11491 -- elaborated by gigi, and is of course not to be replaced in-line 11492 -- by the expression it renames, which would defeat the purpose of 11493 -- removing the side effect. 11494 11495 if Nkind_In (Exp, N_Selected_Component, N_Indexed_Component) 11496 and then Has_Non_Standard_Rep (Etype (Prefix (Exp))) 11497 then 11498 null; 11499 else 11500 Set_Is_Renaming_Of_Object (Def_Id, False); 11501 end if; 11502 11503 -- Avoid generating a variable-sized temporary, by generating the 11504 -- reference just for the function call. The transformation could be 11505 -- refined to apply only when the array component is constrained by a 11506 -- discriminant??? 11507 11508 elsif Nkind (Exp) = N_Selected_Component 11509 and then Nkind (Prefix (Exp)) = N_Function_Call 11510 and then Is_Array_Type (Exp_Type) 11511 then 11512 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref); 11513 goto Leave; 11514 11515 -- Otherwise we generate a reference to the expression 11516 11517 else 11518 -- An expression which is in SPARK mode is considered side effect 11519 -- free if the resulting value is captured by a variable or a 11520 -- constant. 11521 11522 if GNATprove_Mode 11523 and then Nkind (Parent (Exp)) = N_Object_Declaration 11524 then 11525 goto Leave; 11526 11527 -- When generating C code we cannot consider side effect free object 11528 -- declarations that have discriminants and are initialized by means 11529 -- of a function call since on this target there is no secondary 11530 -- stack to store the return value and the expander may generate an 11531 -- extra call to the function to compute the discriminant value. In 11532 -- addition, for targets that have secondary stack, the expansion of 11533 -- functions with side effects involves the generation of an access 11534 -- type to capture the return value stored in the secondary stack; 11535 -- by contrast when generating C code such expansion generates an 11536 -- internal object declaration (no access type involved) which must 11537 -- be identified here to avoid entering into a never-ending loop 11538 -- generating internal object declarations. 11539 11540 elsif Modify_Tree_For_C 11541 and then Nkind (Parent (Exp)) = N_Object_Declaration 11542 and then 11543 (Nkind (Exp) /= N_Function_Call 11544 or else not Has_Discriminants (Exp_Type) 11545 or else Is_Internal_Name 11546 (Chars (Defining_Identifier (Parent (Exp))))) 11547 then 11548 goto Leave; 11549 end if; 11550 11551 -- Special processing for function calls that return a limited type. 11552 -- We need to build a declaration that will enable build-in-place 11553 -- expansion of the call. This is not done if the context is already 11554 -- an object declaration, to prevent infinite recursion. 11555 11556 -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have 11557 -- to accommodate functions returning limited objects by reference. 11558 11559 if Ada_Version >= Ada_2005 11560 and then Nkind (Exp) = N_Function_Call 11561 and then Is_Limited_View (Etype (Exp)) 11562 and then Nkind (Parent (Exp)) /= N_Object_Declaration 11563 then 11564 declare 11565 Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp); 11566 Decl : Node_Id; 11567 11568 begin 11569 Decl := 11570 Make_Object_Declaration (Loc, 11571 Defining_Identifier => Obj, 11572 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11573 Expression => Relocate_Node (Exp)); 11574 11575 Insert_Action (Exp, Decl); 11576 Set_Etype (Obj, Exp_Type); 11577 Rewrite (Exp, New_Occurrence_Of (Obj, Loc)); 11578 goto Leave; 11579 end; 11580 end if; 11581 11582 Def_Id := Build_Temporary (Loc, 'R', Exp); 11583 11584 -- The regular expansion of functions with side effects involves the 11585 -- generation of an access type to capture the return value found on 11586 -- the secondary stack. Since SPARK (and why) cannot process access 11587 -- types, use a different approach which ignores the secondary stack 11588 -- and "copies" the returned object. 11589 -- When generating C code, no need for a 'reference since the 11590 -- secondary stack is not supported. 11591 11592 if GNATprove_Mode or Modify_Tree_For_C then 11593 Res := New_Occurrence_Of (Def_Id, Loc); 11594 Ref_Type := Exp_Type; 11595 11596 -- Regular expansion utilizing an access type and 'reference 11597 11598 else 11599 Res := 11600 Make_Explicit_Dereference (Loc, 11601 Prefix => New_Occurrence_Of (Def_Id, Loc)); 11602 11603 -- Generate: 11604 -- type Ann is access all <Exp_Type>; 11605 11606 Ref_Type := Make_Temporary (Loc, 'A'); 11607 11608 Ptr_Typ_Decl := 11609 Make_Full_Type_Declaration (Loc, 11610 Defining_Identifier => Ref_Type, 11611 Type_Definition => 11612 Make_Access_To_Object_Definition (Loc, 11613 All_Present => True, 11614 Subtype_Indication => 11615 New_Occurrence_Of (Exp_Type, Loc))); 11616 11617 Insert_Action (Exp, Ptr_Typ_Decl); 11618 end if; 11619 11620 E := Exp; 11621 if Nkind (E) = N_Explicit_Dereference then 11622 New_Exp := Relocate_Node (Prefix (E)); 11623 11624 else 11625 E := Relocate_Node (E); 11626 11627 -- Do not generate a 'reference in SPARK mode or C generation 11628 -- since the access type is not created in the first place. 11629 11630 if GNATprove_Mode or Modify_Tree_For_C then 11631 New_Exp := E; 11632 11633 -- Otherwise generate reference, marking the value as non-null 11634 -- since we know it cannot be null and we don't want a check. 11635 11636 else 11637 New_Exp := Make_Reference (Loc, E); 11638 Set_Is_Known_Non_Null (Def_Id); 11639 end if; 11640 end if; 11641 11642 if Is_Delayed_Aggregate (E) then 11643 11644 -- The expansion of nested aggregates is delayed until the 11645 -- enclosing aggregate is expanded. As aggregates are often 11646 -- qualified, the predicate applies to qualified expressions as 11647 -- well, indicating that the enclosing aggregate has not been 11648 -- expanded yet. At this point the aggregate is part of a 11649 -- stand-alone declaration, and must be fully expanded. 11650 11651 if Nkind (E) = N_Qualified_Expression then 11652 Set_Expansion_Delayed (Expression (E), False); 11653 Set_Analyzed (Expression (E), False); 11654 else 11655 Set_Expansion_Delayed (E, False); 11656 end if; 11657 11658 Set_Analyzed (E, False); 11659 end if; 11660 11661 -- Generating C code of object declarations that have discriminants 11662 -- and are initialized by means of a function call we propagate the 11663 -- discriminants of the parent type to the internally built object. 11664 -- This is needed to avoid generating an extra call to the called 11665 -- function. 11666 11667 -- For example, if we generate here the following declaration, it 11668 -- will be expanded later adding an extra call to evaluate the value 11669 -- of the discriminant (needed to compute the size of the object). 11670 -- 11671 -- type Rec (D : Integer) is ... 11672 -- Obj : constant Rec := SomeFunc; 11673 11674 if Modify_Tree_For_C 11675 and then Nkind (Parent (Exp)) = N_Object_Declaration 11676 and then Has_Discriminants (Exp_Type) 11677 and then Nkind (Exp) = N_Function_Call 11678 then 11679 Insert_Action (Exp, 11680 Make_Object_Declaration (Loc, 11681 Defining_Identifier => Def_Id, 11682 Object_Definition => New_Copy_Tree 11683 (Object_Definition (Parent (Exp))), 11684 Constant_Present => True, 11685 Expression => New_Exp)); 11686 else 11687 Insert_Action (Exp, 11688 Make_Object_Declaration (Loc, 11689 Defining_Identifier => Def_Id, 11690 Object_Definition => New_Occurrence_Of (Ref_Type, Loc), 11691 Constant_Present => True, 11692 Expression => New_Exp)); 11693 end if; 11694 end if; 11695 11696 -- Preserve the Assignment_OK flag in all copies, since at least one 11697 -- copy may be used in a context where this flag must be set (otherwise 11698 -- why would the flag be set in the first place). 11699 11700 Set_Assignment_OK (Res, Assignment_OK (Exp)); 11701 11702 -- Finally rewrite the original expression and we are done 11703 11704 Rewrite (Exp, Res); 11705 Analyze_And_Resolve (Exp, Exp_Type); 11706 11707 <<Leave>> 11708 Scope_Suppress := Svg_Suppress; 11709 end Remove_Side_Effects; 11710 11711 ------------------------ 11712 -- Replace_References -- 11713 ------------------------ 11714 11715 procedure Replace_References 11716 (Expr : Node_Id; 11717 Par_Typ : Entity_Id; 11718 Deriv_Typ : Entity_Id; 11719 Par_Obj : Entity_Id := Empty; 11720 Deriv_Obj : Entity_Id := Empty) 11721 is 11722 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean; 11723 -- Determine whether node Ref denotes some component of Deriv_Obj 11724 11725 function Replace_Ref (Ref : Node_Id) return Traverse_Result; 11726 -- Substitute a reference to an entity with the corresponding value 11727 -- stored in table Type_Map. 11728 11729 function Type_Of_Formal 11730 (Call : Node_Id; 11731 Actual : Node_Id) return Entity_Id; 11732 -- Find the type of the formal parameter which corresponds to actual 11733 -- parameter Actual in subprogram call Call. 11734 11735 ---------------------- 11736 -- Is_Deriv_Obj_Ref -- 11737 ---------------------- 11738 11739 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is 11740 Par : constant Node_Id := Parent (Ref); 11741 11742 begin 11743 -- Detect the folowing selected component form: 11744 11745 -- Deriv_Obj.(something) 11746 11747 return 11748 Nkind (Par) = N_Selected_Component 11749 and then Is_Entity_Name (Prefix (Par)) 11750 and then Entity (Prefix (Par)) = Deriv_Obj; 11751 end Is_Deriv_Obj_Ref; 11752 11753 ----------------- 11754 -- Replace_Ref -- 11755 ----------------- 11756 11757 function Replace_Ref (Ref : Node_Id) return Traverse_Result is 11758 procedure Remove_Controlling_Arguments (From_Arg : Node_Id); 11759 -- Reset the Controlling_Argument of all function calls that 11760 -- encapsulate node From_Arg. 11761 11762 ---------------------------------- 11763 -- Remove_Controlling_Arguments -- 11764 ---------------------------------- 11765 11766 procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is 11767 Par : Node_Id; 11768 11769 begin 11770 Par := From_Arg; 11771 while Present (Par) loop 11772 if Nkind (Par) = N_Function_Call 11773 and then Present (Controlling_Argument (Par)) 11774 then 11775 Set_Controlling_Argument (Par, Empty); 11776 11777 -- Prevent the search from going too far 11778 11779 elsif Is_Body_Or_Package_Declaration (Par) then 11780 exit; 11781 end if; 11782 11783 Par := Parent (Par); 11784 end loop; 11785 end Remove_Controlling_Arguments; 11786 11787 -- Local variables 11788 11789 Context : constant Node_Id := Parent (Ref); 11790 Loc : constant Source_Ptr := Sloc (Ref); 11791 Ref_Id : Entity_Id; 11792 Result : Traverse_Result; 11793 11794 New_Ref : Node_Id; 11795 -- The new reference which is intended to substitute the old one 11796 11797 Old_Ref : Node_Id; 11798 -- The reference designated for replacement. In certain cases this 11799 -- may be a node other than Ref. 11800 11801 Val : Node_Or_Entity_Id; 11802 -- The corresponding value of Ref from the type map 11803 11804 -- Start of processing for Replace_Ref 11805 11806 begin 11807 -- Assume that the input reference is to be replaced and that the 11808 -- traversal should examine the children of the reference. 11809 11810 Old_Ref := Ref; 11811 Result := OK; 11812 11813 -- The input denotes a meaningful reference 11814 11815 if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then 11816 Ref_Id := Entity (Ref); 11817 Val := Type_Map.Get (Ref_Id); 11818 11819 -- The reference has a corresponding value in the type map, a 11820 -- substitution is possible. 11821 11822 if Present (Val) then 11823 11824 -- The reference denotes a discriminant 11825 11826 if Ekind (Ref_Id) = E_Discriminant then 11827 if Nkind (Val) in N_Entity then 11828 11829 -- The value denotes another discriminant. Replace as 11830 -- follows: 11831 11832 -- _object.Discr -> _object.Val 11833 11834 if Ekind (Val) = E_Discriminant then 11835 New_Ref := New_Occurrence_Of (Val, Loc); 11836 11837 -- Otherwise the value denotes the entity of a name which 11838 -- constraints the discriminant. Replace as follows: 11839 11840 -- _object.Discr -> Val 11841 11842 else 11843 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref)); 11844 11845 New_Ref := New_Occurrence_Of (Val, Loc); 11846 Old_Ref := Parent (Old_Ref); 11847 end if; 11848 11849 -- Otherwise the value denotes an arbitrary expression which 11850 -- constraints the discriminant. Replace as follows: 11851 11852 -- _object.Discr -> Val 11853 11854 else 11855 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref)); 11856 11857 New_Ref := New_Copy_Tree (Val); 11858 Old_Ref := Parent (Old_Ref); 11859 end if; 11860 11861 -- Otherwise the reference denotes a primitive. Replace as 11862 -- follows: 11863 11864 -- Primitive -> Val 11865 11866 else 11867 pragma Assert (Nkind (Val) in N_Entity); 11868 New_Ref := New_Occurrence_Of (Val, Loc); 11869 end if; 11870 11871 -- The reference mentions the _object parameter of the parent 11872 -- type's DIC or type invariant procedure. Replace as follows: 11873 11874 -- _object -> _object 11875 11876 elsif Present (Par_Obj) 11877 and then Present (Deriv_Obj) 11878 and then Ref_Id = Par_Obj 11879 then 11880 New_Ref := New_Occurrence_Of (Deriv_Obj, Loc); 11881 11882 -- The type of the _object parameter is class-wide when the 11883 -- expression comes from an assertion pragma that applies to 11884 -- an abstract parent type or an interface. The class-wide type 11885 -- facilitates the preanalysis of the expression by treating 11886 -- calls to abstract primitives that mention the current 11887 -- instance of the type as dispatching. Once the calls are 11888 -- remapped to invoke overriding or inherited primitives, the 11889 -- calls no longer need to be dispatching. Examine all function 11890 -- calls that encapsulate the _object parameter and reset their 11891 -- Controlling_Argument attribute. 11892 11893 if Is_Class_Wide_Type (Etype (Par_Obj)) 11894 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj))) 11895 then 11896 Remove_Controlling_Arguments (Old_Ref); 11897 end if; 11898 11899 -- The reference to _object acts as an actual parameter in a 11900 -- subprogram call which may be invoking a primitive of the 11901 -- parent type: 11902 11903 -- Primitive (... _object ...); 11904 11905 -- The parent type primitive may not be overridden nor 11906 -- inherited when it is declared after the derived type 11907 -- definition: 11908 11909 -- type Parent is tagged private; 11910 -- type Child is new Parent with private; 11911 -- procedure Primitive (Obj : Parent); 11912 11913 -- In this scenario the _object parameter is converted to the 11914 -- parent type. Due to complications with partial/full views 11915 -- and view swaps, the parent type is taken from the formal 11916 -- parameter of the subprogram being called. 11917 11918 if Nkind_In (Context, N_Function_Call, 11919 N_Procedure_Call_Statement) 11920 and then No (Type_Map.Get (Entity (Name (Context)))) 11921 then 11922 New_Ref := 11923 Convert_To (Type_Of_Formal (Context, Old_Ref), New_Ref); 11924 11925 -- Do not process the generated type conversion because 11926 -- both the parent type and the derived type are in the 11927 -- Type_Map table. This will clobber the type conversion 11928 -- by resetting its subtype mark. 11929 11930 Result := Skip; 11931 end if; 11932 11933 -- Otherwise there is nothing to replace 11934 11935 else 11936 New_Ref := Empty; 11937 end if; 11938 11939 if Present (New_Ref) then 11940 Rewrite (Old_Ref, New_Ref); 11941 11942 -- Update the return type when the context of the reference 11943 -- acts as the name of a function call. Note that the update 11944 -- should not be performed when the reference appears as an 11945 -- actual in the call. 11946 11947 if Nkind (Context) = N_Function_Call 11948 and then Name (Context) = Old_Ref 11949 then 11950 Set_Etype (Context, Etype (Val)); 11951 end if; 11952 end if; 11953 end if; 11954 11955 -- Reanalyze the reference due to potential replacements 11956 11957 if Nkind (Old_Ref) in N_Has_Etype then 11958 Set_Analyzed (Old_Ref, False); 11959 end if; 11960 11961 return Result; 11962 end Replace_Ref; 11963 11964 procedure Replace_Refs is new Traverse_Proc (Replace_Ref); 11965 11966 -------------------- 11967 -- Type_Of_Formal -- 11968 -------------------- 11969 11970 function Type_Of_Formal 11971 (Call : Node_Id; 11972 Actual : Node_Id) return Entity_Id 11973 is 11974 A : Node_Id; 11975 F : Entity_Id; 11976 11977 begin 11978 -- Examine the list of actual and formal parameters in parallel 11979 11980 A := First (Parameter_Associations (Call)); 11981 F := First_Formal (Entity (Name (Call))); 11982 while Present (A) and then Present (F) loop 11983 if A = Actual then 11984 return Etype (F); 11985 end if; 11986 11987 Next (A); 11988 Next_Formal (F); 11989 end loop; 11990 11991 -- The actual parameter must always have a corresponding formal 11992 11993 pragma Assert (False); 11994 11995 return Empty; 11996 end Type_Of_Formal; 11997 11998 -- Start of processing for Replace_References 11999 12000 begin 12001 -- Map the attributes of the parent type to the proper corresponding 12002 -- attributes of the derived type. 12003 12004 Map_Types 12005 (Parent_Type => Par_Typ, 12006 Derived_Type => Deriv_Typ); 12007 12008 -- Inspect the input expression and perform substitutions where 12009 -- necessary. 12010 12011 Replace_Refs (Expr); 12012 end Replace_References; 12013 12014 ----------------------------- 12015 -- Replace_Type_References -- 12016 ----------------------------- 12017 12018 procedure Replace_Type_References 12019 (Expr : Node_Id; 12020 Typ : Entity_Id; 12021 Obj_Id : Entity_Id) 12022 is 12023 procedure Replace_Type_Ref (N : Node_Id); 12024 -- Substitute a single reference of the current instance of type Typ 12025 -- with a reference to Obj_Id. 12026 12027 ---------------------- 12028 -- Replace_Type_Ref -- 12029 ---------------------- 12030 12031 procedure Replace_Type_Ref (N : Node_Id) is 12032 begin 12033 -- Decorate the reference to Typ even though it may be rewritten 12034 -- further down. This is done for two reasons: 12035 12036 -- * ASIS has all necessary semantic information in the original 12037 -- tree. 12038 12039 -- * Routines which examine properties of the Original_Node have 12040 -- some semantic information. 12041 12042 if Nkind (N) = N_Identifier then 12043 Set_Entity (N, Typ); 12044 Set_Etype (N, Typ); 12045 12046 elsif Nkind (N) = N_Selected_Component then 12047 Analyze (Prefix (N)); 12048 Set_Entity (Selector_Name (N), Typ); 12049 Set_Etype (Selector_Name (N), Typ); 12050 end if; 12051 12052 -- Perform the following substitution: 12053 12054 -- Typ --> _object 12055 12056 Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N))); 12057 Set_Comes_From_Source (N, True); 12058 end Replace_Type_Ref; 12059 12060 procedure Replace_Type_Refs is 12061 new Replace_Type_References_Generic (Replace_Type_Ref); 12062 12063 -- Start of processing for Replace_Type_References 12064 12065 begin 12066 Replace_Type_Refs (Expr, Typ); 12067 end Replace_Type_References; 12068 12069 --------------------------- 12070 -- Represented_As_Scalar -- 12071 --------------------------- 12072 12073 function Represented_As_Scalar (T : Entity_Id) return Boolean is 12074 UT : constant Entity_Id := Underlying_Type (T); 12075 begin 12076 return Is_Scalar_Type (UT) 12077 or else (Is_Bit_Packed_Array (UT) 12078 and then Is_Scalar_Type (Packed_Array_Impl_Type (UT))); 12079 end Represented_As_Scalar; 12080 12081 ------------------------------ 12082 -- Requires_Cleanup_Actions -- 12083 ------------------------------ 12084 12085 function Requires_Cleanup_Actions 12086 (N : Node_Id; 12087 Lib_Level : Boolean) return Boolean 12088 is 12089 At_Lib_Level : constant Boolean := 12090 Lib_Level 12091 and then Nkind_In (N, N_Package_Body, 12092 N_Package_Specification); 12093 -- N is at the library level if the top-most context is a package and 12094 -- the path taken to reach N does not inlcude non-package constructs. 12095 12096 begin 12097 case Nkind (N) is 12098 when N_Accept_Statement 12099 | N_Block_Statement 12100 | N_Entry_Body 12101 | N_Package_Body 12102 | N_Protected_Body 12103 | N_Subprogram_Body 12104 | N_Task_Body 12105 => 12106 return 12107 Requires_Cleanup_Actions 12108 (L => Declarations (N), 12109 Lib_Level => At_Lib_Level, 12110 Nested_Constructs => True) 12111 or else 12112 (Present (Handled_Statement_Sequence (N)) 12113 and then 12114 Requires_Cleanup_Actions 12115 (L => 12116 Statements (Handled_Statement_Sequence (N)), 12117 Lib_Level => At_Lib_Level, 12118 Nested_Constructs => True)); 12119 12120 -- Extended return statements are the same as the above, except that 12121 -- there is no Declarations field. We do not want to clean up the 12122 -- Return_Object_Declarations. 12123 12124 when N_Extended_Return_Statement => 12125 return 12126 Present (Handled_Statement_Sequence (N)) 12127 and then Requires_Cleanup_Actions 12128 (L => 12129 Statements (Handled_Statement_Sequence (N)), 12130 Lib_Level => At_Lib_Level, 12131 Nested_Constructs => True); 12132 12133 when N_Package_Specification => 12134 return 12135 Requires_Cleanup_Actions 12136 (L => Visible_Declarations (N), 12137 Lib_Level => At_Lib_Level, 12138 Nested_Constructs => True) 12139 or else 12140 Requires_Cleanup_Actions 12141 (L => Private_Declarations (N), 12142 Lib_Level => At_Lib_Level, 12143 Nested_Constructs => True); 12144 12145 when others => 12146 raise Program_Error; 12147 end case; 12148 end Requires_Cleanup_Actions; 12149 12150 ------------------------------ 12151 -- Requires_Cleanup_Actions -- 12152 ------------------------------ 12153 12154 function Requires_Cleanup_Actions 12155 (L : List_Id; 12156 Lib_Level : Boolean; 12157 Nested_Constructs : Boolean) return Boolean 12158 is 12159 Decl : Node_Id; 12160 Expr : Node_Id; 12161 Obj_Id : Entity_Id; 12162 Obj_Typ : Entity_Id; 12163 Pack_Id : Entity_Id; 12164 Typ : Entity_Id; 12165 12166 begin 12167 if No (L) 12168 or else Is_Empty_List (L) 12169 then 12170 return False; 12171 end if; 12172 12173 Decl := First (L); 12174 while Present (Decl) loop 12175 12176 -- Library-level tagged types 12177 12178 if Nkind (Decl) = N_Full_Type_Declaration then 12179 Typ := Defining_Identifier (Decl); 12180 12181 -- Ignored Ghost types do not need any cleanup actions because 12182 -- they will not appear in the final tree. 12183 12184 if Is_Ignored_Ghost_Entity (Typ) then 12185 null; 12186 12187 elsif Is_Tagged_Type (Typ) 12188 and then Is_Library_Level_Entity (Typ) 12189 and then Convention (Typ) = Convention_Ada 12190 and then Present (Access_Disp_Table (Typ)) 12191 and then RTE_Available (RE_Unregister_Tag) 12192 and then not Is_Abstract_Type (Typ) 12193 and then not No_Run_Time_Mode 12194 then 12195 return True; 12196 end if; 12197 12198 -- Regular object declarations 12199 12200 elsif Nkind (Decl) = N_Object_Declaration then 12201 Obj_Id := Defining_Identifier (Decl); 12202 Obj_Typ := Base_Type (Etype (Obj_Id)); 12203 Expr := Expression (Decl); 12204 12205 -- Bypass any form of processing for objects which have their 12206 -- finalization disabled. This applies only to objects at the 12207 -- library level. 12208 12209 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then 12210 null; 12211 12212 -- Finalization of transient objects are treated separately in 12213 -- order to handle sensitive cases. These include: 12214 12215 -- * Aggregate expansion 12216 -- * If, case, and expression with actions expansion 12217 -- * Transient scopes 12218 12219 -- If one of those contexts has marked the transient object as 12220 -- ignored, do not generate finalization actions for it. 12221 12222 elsif Is_Finalized_Transient (Obj_Id) 12223 or else Is_Ignored_Transient (Obj_Id) 12224 then 12225 null; 12226 12227 -- Ignored Ghost objects do not need any cleanup actions because 12228 -- they will not appear in the final tree. 12229 12230 elsif Is_Ignored_Ghost_Entity (Obj_Id) then 12231 null; 12232 12233 -- The object is of the form: 12234 -- Obj : [constant] Typ [:= Expr]; 12235 -- 12236 -- Do not process tag-to-class-wide conversions because they do 12237 -- not yield an object. Do not process the incomplete view of a 12238 -- deferred constant. Note that an object initialized by means 12239 -- of a build-in-place function call may appear as a deferred 12240 -- constant after expansion activities. These kinds of objects 12241 -- must be finalized. 12242 12243 elsif not Is_Imported (Obj_Id) 12244 and then Needs_Finalization (Obj_Typ) 12245 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id) 12246 and then not (Ekind (Obj_Id) = E_Constant 12247 and then not Has_Completion (Obj_Id) 12248 and then No (BIP_Initialization_Call (Obj_Id))) 12249 then 12250 return True; 12251 12252 -- The object is of the form: 12253 -- Obj : Access_Typ := Non_BIP_Function_Call'reference; 12254 -- 12255 -- Obj : Access_Typ := 12256 -- BIP_Function_Call (BIPalloc => 2, ...)'reference; 12257 12258 elsif Is_Access_Type (Obj_Typ) 12259 and then Needs_Finalization 12260 (Available_View (Designated_Type (Obj_Typ))) 12261 and then Present (Expr) 12262 and then 12263 (Is_Secondary_Stack_BIP_Func_Call (Expr) 12264 or else 12265 (Is_Non_BIP_Func_Call (Expr) 12266 and then not Is_Related_To_Func_Return (Obj_Id))) 12267 then 12268 return True; 12269 12270 -- Processing for "hook" objects generated for transient objects 12271 -- declared inside an Expression_With_Actions. 12272 12273 elsif Is_Access_Type (Obj_Typ) 12274 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12275 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) = 12276 N_Object_Declaration 12277 then 12278 return True; 12279 12280 -- Processing for intermediate results of if expressions where 12281 -- one of the alternatives uses a controlled function call. 12282 12283 elsif Is_Access_Type (Obj_Typ) 12284 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12285 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) = 12286 N_Defining_Identifier 12287 and then Present (Expr) 12288 and then Nkind (Expr) = N_Null 12289 then 12290 return True; 12291 12292 -- Simple protected objects which use type System.Tasking. 12293 -- Protected_Objects.Protection to manage their locks should be 12294 -- treated as controlled since they require manual cleanup. 12295 12296 elsif Ekind (Obj_Id) = E_Variable 12297 and then (Is_Simple_Protected_Type (Obj_Typ) 12298 or else Has_Simple_Protected_Object (Obj_Typ)) 12299 then 12300 return True; 12301 end if; 12302 12303 -- Specific cases of object renamings 12304 12305 elsif Nkind (Decl) = N_Object_Renaming_Declaration then 12306 Obj_Id := Defining_Identifier (Decl); 12307 Obj_Typ := Base_Type (Etype (Obj_Id)); 12308 12309 -- Bypass any form of processing for objects which have their 12310 -- finalization disabled. This applies only to objects at the 12311 -- library level. 12312 12313 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then 12314 null; 12315 12316 -- Ignored Ghost object renamings do not need any cleanup actions 12317 -- because they will not appear in the final tree. 12318 12319 elsif Is_Ignored_Ghost_Entity (Obj_Id) then 12320 null; 12321 12322 -- Return object of a build-in-place function. This case is 12323 -- recognized and marked by the expansion of an extended return 12324 -- statement (see Expand_N_Extended_Return_Statement). 12325 12326 elsif Needs_Finalization (Obj_Typ) 12327 and then Is_Return_Object (Obj_Id) 12328 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12329 then 12330 return True; 12331 12332 -- Detect a case where a source object has been initialized by 12333 -- a controlled function call or another object which was later 12334 -- rewritten as a class-wide conversion of Ada.Tags.Displace. 12335 12336 -- Obj1 : CW_Type := Src_Obj; 12337 -- Obj2 : CW_Type := Function_Call (...); 12338 12339 -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj)); 12340 -- Tmp : ... := Function_Call (...)'reference; 12341 -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp)); 12342 12343 elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then 12344 return True; 12345 end if; 12346 12347 -- Inspect the freeze node of an access-to-controlled type and look 12348 -- for a delayed finalization master. This case arises when the 12349 -- freeze actions are inserted at a later time than the expansion of 12350 -- the context. Since Build_Finalizer is never called on a single 12351 -- construct twice, the master will be ultimately left out and never 12352 -- finalized. This is also needed for freeze actions of designated 12353 -- types themselves, since in some cases the finalization master is 12354 -- associated with a designated type's freeze node rather than that 12355 -- of the access type (see handling for freeze actions in 12356 -- Build_Finalization_Master). 12357 12358 elsif Nkind (Decl) = N_Freeze_Entity 12359 and then Present (Actions (Decl)) 12360 then 12361 Typ := Entity (Decl); 12362 12363 -- Freeze nodes for ignored Ghost types do not need cleanup 12364 -- actions because they will never appear in the final tree. 12365 12366 if Is_Ignored_Ghost_Entity (Typ) then 12367 null; 12368 12369 elsif ((Is_Access_Type (Typ) 12370 and then not Is_Access_Subprogram_Type (Typ) 12371 and then Needs_Finalization 12372 (Available_View (Designated_Type (Typ)))) 12373 or else (Is_Type (Typ) and then Needs_Finalization (Typ))) 12374 and then Requires_Cleanup_Actions 12375 (Actions (Decl), Lib_Level, Nested_Constructs) 12376 then 12377 return True; 12378 end if; 12379 12380 -- Nested package declarations 12381 12382 elsif Nested_Constructs 12383 and then Nkind (Decl) = N_Package_Declaration 12384 then 12385 Pack_Id := Defining_Entity (Decl); 12386 12387 -- Do not inspect an ignored Ghost package because all code found 12388 -- within will not appear in the final tree. 12389 12390 if Is_Ignored_Ghost_Entity (Pack_Id) then 12391 null; 12392 12393 elsif Ekind (Pack_Id) /= E_Generic_Package 12394 and then Requires_Cleanup_Actions 12395 (Specification (Decl), Lib_Level) 12396 then 12397 return True; 12398 end if; 12399 12400 -- Nested package bodies 12401 12402 elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then 12403 12404 -- Do not inspect an ignored Ghost package body because all code 12405 -- found within will not appear in the final tree. 12406 12407 if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then 12408 null; 12409 12410 elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package 12411 and then Requires_Cleanup_Actions (Decl, Lib_Level) 12412 then 12413 return True; 12414 end if; 12415 12416 elsif Nkind (Decl) = N_Block_Statement 12417 and then 12418 12419 -- Handle a rare case caused by a controlled transient object 12420 -- created as part of a record init proc. The variable is wrapped 12421 -- in a block, but the block is not associated with a transient 12422 -- scope. 12423 12424 (Inside_Init_Proc 12425 12426 -- Handle the case where the original context has been wrapped in 12427 -- a block to avoid interference between exception handlers and 12428 -- At_End handlers. Treat the block as transparent and process its 12429 -- contents. 12430 12431 or else Is_Finalization_Wrapper (Decl)) 12432 then 12433 if Requires_Cleanup_Actions (Decl, Lib_Level) then 12434 return True; 12435 end if; 12436 end if; 12437 12438 Next (Decl); 12439 end loop; 12440 12441 return False; 12442 end Requires_Cleanup_Actions; 12443 12444 ------------------------------------ 12445 -- Safe_Unchecked_Type_Conversion -- 12446 ------------------------------------ 12447 12448 -- Note: this function knows quite a bit about the exact requirements of 12449 -- Gigi with respect to unchecked type conversions, and its code must be 12450 -- coordinated with any changes in Gigi in this area. 12451 12452 -- The above requirements should be documented in Sinfo ??? 12453 12454 function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is 12455 Otyp : Entity_Id; 12456 Ityp : Entity_Id; 12457 Oalign : Uint; 12458 Ialign : Uint; 12459 Pexp : constant Node_Id := Parent (Exp); 12460 12461 begin 12462 -- If the expression is the RHS of an assignment or object declaration 12463 -- we are always OK because there will always be a target. 12464 12465 -- Object renaming declarations, (generated for view conversions of 12466 -- actuals in inlined calls), like object declarations, provide an 12467 -- explicit type, and are safe as well. 12468 12469 if (Nkind (Pexp) = N_Assignment_Statement 12470 and then Expression (Pexp) = Exp) 12471 or else Nkind_In (Pexp, N_Object_Declaration, 12472 N_Object_Renaming_Declaration) 12473 then 12474 return True; 12475 12476 -- If the expression is the prefix of an N_Selected_Component we should 12477 -- also be OK because GCC knows to look inside the conversion except if 12478 -- the type is discriminated. We assume that we are OK anyway if the 12479 -- type is not set yet or if it is controlled since we can't afford to 12480 -- introduce a temporary in this case. 12481 12482 elsif Nkind (Pexp) = N_Selected_Component 12483 and then Prefix (Pexp) = Exp 12484 then 12485 if No (Etype (Pexp)) then 12486 return True; 12487 else 12488 return 12489 not Has_Discriminants (Etype (Pexp)) 12490 or else Is_Constrained (Etype (Pexp)); 12491 end if; 12492 end if; 12493 12494 -- Set the output type, this comes from Etype if it is set, otherwise we 12495 -- take it from the subtype mark, which we assume was already fully 12496 -- analyzed. 12497 12498 if Present (Etype (Exp)) then 12499 Otyp := Etype (Exp); 12500 else 12501 Otyp := Entity (Subtype_Mark (Exp)); 12502 end if; 12503 12504 -- The input type always comes from the expression, and we assume this 12505 -- is indeed always analyzed, so we can simply get the Etype. 12506 12507 Ityp := Etype (Expression (Exp)); 12508 12509 -- Initialize alignments to unknown so far 12510 12511 Oalign := No_Uint; 12512 Ialign := No_Uint; 12513 12514 -- Replace a concurrent type by its corresponding record type and each 12515 -- type by its underlying type and do the tests on those. The original 12516 -- type may be a private type whose completion is a concurrent type, so 12517 -- find the underlying type first. 12518 12519 if Present (Underlying_Type (Otyp)) then 12520 Otyp := Underlying_Type (Otyp); 12521 end if; 12522 12523 if Present (Underlying_Type (Ityp)) then 12524 Ityp := Underlying_Type (Ityp); 12525 end if; 12526 12527 if Is_Concurrent_Type (Otyp) then 12528 Otyp := Corresponding_Record_Type (Otyp); 12529 end if; 12530 12531 if Is_Concurrent_Type (Ityp) then 12532 Ityp := Corresponding_Record_Type (Ityp); 12533 end if; 12534 12535 -- If the base types are the same, we know there is no problem since 12536 -- this conversion will be a noop. 12537 12538 if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then 12539 return True; 12540 12541 -- Same if this is an upwards conversion of an untagged type, and there 12542 -- are no constraints involved (could be more general???) 12543 12544 elsif Etype (Ityp) = Otyp 12545 and then not Is_Tagged_Type (Ityp) 12546 and then not Has_Discriminants (Ityp) 12547 and then No (First_Rep_Item (Base_Type (Ityp))) 12548 then 12549 return True; 12550 12551 -- If the expression has an access type (object or subprogram) we assume 12552 -- that the conversion is safe, because the size of the target is safe, 12553 -- even if it is a record (which might be treated as having unknown size 12554 -- at this point). 12555 12556 elsif Is_Access_Type (Ityp) then 12557 return True; 12558 12559 -- If the size of output type is known at compile time, there is never 12560 -- a problem. Note that unconstrained records are considered to be of 12561 -- known size, but we can't consider them that way here, because we are 12562 -- talking about the actual size of the object. 12563 12564 -- We also make sure that in addition to the size being known, we do not 12565 -- have a case which might generate an embarrassingly large temp in 12566 -- stack checking mode. 12567 12568 elsif Size_Known_At_Compile_Time (Otyp) 12569 and then 12570 (not Stack_Checking_Enabled 12571 or else not May_Generate_Large_Temp (Otyp)) 12572 and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp)) 12573 then 12574 return True; 12575 12576 -- If either type is tagged, then we know the alignment is OK so Gigi 12577 -- will be able to use pointer punning. 12578 12579 elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then 12580 return True; 12581 12582 -- If either type is a limited record type, we cannot do a copy, so say 12583 -- safe since there's nothing else we can do. 12584 12585 elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then 12586 return True; 12587 12588 -- Conversions to and from packed array types are always ignored and 12589 -- hence are safe. 12590 12591 elsif Is_Packed_Array_Impl_Type (Otyp) 12592 or else Is_Packed_Array_Impl_Type (Ityp) 12593 then 12594 return True; 12595 end if; 12596 12597 -- The only other cases known to be safe is if the input type's 12598 -- alignment is known to be at least the maximum alignment for the 12599 -- target or if both alignments are known and the output type's 12600 -- alignment is no stricter than the input's. We can use the component 12601 -- type alignment for an array if a type is an unpacked array type. 12602 12603 if Present (Alignment_Clause (Otyp)) then 12604 Oalign := Expr_Value (Expression (Alignment_Clause (Otyp))); 12605 12606 elsif Is_Array_Type (Otyp) 12607 and then Present (Alignment_Clause (Component_Type (Otyp))) 12608 then 12609 Oalign := Expr_Value (Expression (Alignment_Clause 12610 (Component_Type (Otyp)))); 12611 end if; 12612 12613 if Present (Alignment_Clause (Ityp)) then 12614 Ialign := Expr_Value (Expression (Alignment_Clause (Ityp))); 12615 12616 elsif Is_Array_Type (Ityp) 12617 and then Present (Alignment_Clause (Component_Type (Ityp))) 12618 then 12619 Ialign := Expr_Value (Expression (Alignment_Clause 12620 (Component_Type (Ityp)))); 12621 end if; 12622 12623 if Ialign /= No_Uint and then Ialign > Maximum_Alignment then 12624 return True; 12625 12626 elsif Ialign /= No_Uint 12627 and then Oalign /= No_Uint 12628 and then Ialign <= Oalign 12629 then 12630 return True; 12631 12632 -- Otherwise, Gigi cannot handle this and we must make a temporary 12633 12634 else 12635 return False; 12636 end if; 12637 end Safe_Unchecked_Type_Conversion; 12638 12639 --------------------------------- 12640 -- Set_Current_Value_Condition -- 12641 --------------------------------- 12642 12643 -- Note: the implementation of this procedure is very closely tied to the 12644 -- implementation of Get_Current_Value_Condition. Here we set required 12645 -- Current_Value fields, and in Get_Current_Value_Condition, we interpret 12646 -- them, so they must have a consistent view. 12647 12648 procedure Set_Current_Value_Condition (Cnode : Node_Id) is 12649 12650 procedure Set_Entity_Current_Value (N : Node_Id); 12651 -- If N is an entity reference, where the entity is of an appropriate 12652 -- kind, then set the current value of this entity to Cnode, unless 12653 -- there is already a definite value set there. 12654 12655 procedure Set_Expression_Current_Value (N : Node_Id); 12656 -- If N is of an appropriate form, sets an appropriate entry in current 12657 -- value fields of relevant entities. Multiple entities can be affected 12658 -- in the case of an AND or AND THEN. 12659 12660 ------------------------------ 12661 -- Set_Entity_Current_Value -- 12662 ------------------------------ 12663 12664 procedure Set_Entity_Current_Value (N : Node_Id) is 12665 begin 12666 if Is_Entity_Name (N) then 12667 declare 12668 Ent : constant Entity_Id := Entity (N); 12669 12670 begin 12671 -- Don't capture if not safe to do so 12672 12673 if not Safe_To_Capture_Value (N, Ent, Cond => True) then 12674 return; 12675 end if; 12676 12677 -- Here we have a case where the Current_Value field may need 12678 -- to be set. We set it if it is not already set to a compile 12679 -- time expression value. 12680 12681 -- Note that this represents a decision that one condition 12682 -- blots out another previous one. That's certainly right if 12683 -- they occur at the same level. If the second one is nested, 12684 -- then the decision is neither right nor wrong (it would be 12685 -- equally OK to leave the outer one in place, or take the new 12686 -- inner one. Really we should record both, but our data 12687 -- structures are not that elaborate. 12688 12689 if Nkind (Current_Value (Ent)) not in N_Subexpr then 12690 Set_Current_Value (Ent, Cnode); 12691 end if; 12692 end; 12693 end if; 12694 end Set_Entity_Current_Value; 12695 12696 ---------------------------------- 12697 -- Set_Expression_Current_Value -- 12698 ---------------------------------- 12699 12700 procedure Set_Expression_Current_Value (N : Node_Id) is 12701 Cond : Node_Id; 12702 12703 begin 12704 Cond := N; 12705 12706 -- Loop to deal with (ignore for now) any NOT operators present. The 12707 -- presence of NOT operators will be handled properly when we call 12708 -- Get_Current_Value_Condition. 12709 12710 while Nkind (Cond) = N_Op_Not loop 12711 Cond := Right_Opnd (Cond); 12712 end loop; 12713 12714 -- For an AND or AND THEN, recursively process operands 12715 12716 if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then 12717 Set_Expression_Current_Value (Left_Opnd (Cond)); 12718 Set_Expression_Current_Value (Right_Opnd (Cond)); 12719 return; 12720 end if; 12721 12722 -- Check possible relational operator 12723 12724 if Nkind (Cond) in N_Op_Compare then 12725 if Compile_Time_Known_Value (Right_Opnd (Cond)) then 12726 Set_Entity_Current_Value (Left_Opnd (Cond)); 12727 elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then 12728 Set_Entity_Current_Value (Right_Opnd (Cond)); 12729 end if; 12730 12731 elsif Nkind_In (Cond, 12732 N_Type_Conversion, 12733 N_Qualified_Expression, 12734 N_Expression_With_Actions) 12735 then 12736 Set_Expression_Current_Value (Expression (Cond)); 12737 12738 -- Check possible boolean variable reference 12739 12740 else 12741 Set_Entity_Current_Value (Cond); 12742 end if; 12743 end Set_Expression_Current_Value; 12744 12745 -- Start of processing for Set_Current_Value_Condition 12746 12747 begin 12748 Set_Expression_Current_Value (Condition (Cnode)); 12749 end Set_Current_Value_Condition; 12750 12751 -------------------------- 12752 -- Set_Elaboration_Flag -- 12753 -------------------------- 12754 12755 procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is 12756 Loc : constant Source_Ptr := Sloc (N); 12757 Ent : constant Entity_Id := Elaboration_Entity (Spec_Id); 12758 Asn : Node_Id; 12759 12760 begin 12761 if Present (Ent) then 12762 12763 -- Nothing to do if at the compilation unit level, because in this 12764 -- case the flag is set by the binder generated elaboration routine. 12765 12766 if Nkind (Parent (N)) = N_Compilation_Unit then 12767 null; 12768 12769 -- Here we do need to generate an assignment statement 12770 12771 else 12772 Check_Restriction (No_Elaboration_Code, N); 12773 12774 Asn := 12775 Make_Assignment_Statement (Loc, 12776 Name => New_Occurrence_Of (Ent, Loc), 12777 Expression => Make_Integer_Literal (Loc, Uint_1)); 12778 12779 -- Mark the assignment statement as elaboration code. This allows 12780 -- the early call region mechanism (see Sem_Elab) to properly 12781 -- ignore such assignments even though they are non-preelaborable 12782 -- code. 12783 12784 Set_Is_Elaboration_Code (Asn); 12785 12786 if Nkind (Parent (N)) = N_Subunit then 12787 Insert_After (Corresponding_Stub (Parent (N)), Asn); 12788 else 12789 Insert_After (N, Asn); 12790 end if; 12791 12792 Analyze (Asn); 12793 12794 -- Kill current value indication. This is necessary because the 12795 -- tests of this flag are inserted out of sequence and must not 12796 -- pick up bogus indications of the wrong constant value. 12797 12798 Set_Current_Value (Ent, Empty); 12799 12800 -- If the subprogram is in the current declarative part and 12801 -- 'access has been applied to it, generate an elaboration 12802 -- check at the beginning of the declarations of the body. 12803 12804 if Nkind (N) = N_Subprogram_Body 12805 and then Address_Taken (Spec_Id) 12806 and then 12807 Ekind_In (Scope (Spec_Id), E_Block, E_Procedure, E_Function) 12808 then 12809 declare 12810 Loc : constant Source_Ptr := Sloc (N); 12811 Decls : constant List_Id := Declarations (N); 12812 Chk : Node_Id; 12813 12814 begin 12815 -- No need to generate this check if first entry in the 12816 -- declaration list is a raise of Program_Error now. 12817 12818 if Present (Decls) 12819 and then Nkind (First (Decls)) = N_Raise_Program_Error 12820 then 12821 return; 12822 end if; 12823 12824 -- Otherwise generate the check 12825 12826 Chk := 12827 Make_Raise_Program_Error (Loc, 12828 Condition => 12829 Make_Op_Eq (Loc, 12830 Left_Opnd => New_Occurrence_Of (Ent, Loc), 12831 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)), 12832 Reason => PE_Access_Before_Elaboration); 12833 12834 if No (Decls) then 12835 Set_Declarations (N, New_List (Chk)); 12836 else 12837 Prepend (Chk, Decls); 12838 end if; 12839 12840 Analyze (Chk); 12841 end; 12842 end if; 12843 end if; 12844 end if; 12845 end Set_Elaboration_Flag; 12846 12847 ---------------------------- 12848 -- Set_Renamed_Subprogram -- 12849 ---------------------------- 12850 12851 procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is 12852 begin 12853 -- If input node is an identifier, we can just reset it 12854 12855 if Nkind (N) = N_Identifier then 12856 Set_Chars (N, Chars (E)); 12857 Set_Entity (N, E); 12858 12859 -- Otherwise we have to do a rewrite, preserving Comes_From_Source 12860 12861 else 12862 declare 12863 CS : constant Boolean := Comes_From_Source (N); 12864 begin 12865 Rewrite (N, Make_Identifier (Sloc (N), Chars (E))); 12866 Set_Entity (N, E); 12867 Set_Comes_From_Source (N, CS); 12868 Set_Analyzed (N, True); 12869 end; 12870 end if; 12871 end Set_Renamed_Subprogram; 12872 12873 ---------------------- 12874 -- Side_Effect_Free -- 12875 ---------------------- 12876 12877 function Side_Effect_Free 12878 (N : Node_Id; 12879 Name_Req : Boolean := False; 12880 Variable_Ref : Boolean := False) return Boolean 12881 is 12882 Typ : constant Entity_Id := Etype (N); 12883 -- Result type of the expression 12884 12885 function Safe_Prefixed_Reference (N : Node_Id) return Boolean; 12886 -- The argument N is a construct where the Prefix is dereferenced if it 12887 -- is an access type and the result is a variable. The call returns True 12888 -- if the construct is side effect free (not considering side effects in 12889 -- other than the prefix which are to be tested by the caller). 12890 12891 function Within_In_Parameter (N : Node_Id) return Boolean; 12892 -- Determines if N is a subcomponent of a composite in-parameter. If so, 12893 -- N is not side-effect free when the actual is global and modifiable 12894 -- indirectly from within a subprogram, because it may be passed by 12895 -- reference. The front-end must be conservative here and assume that 12896 -- this may happen with any array or record type. On the other hand, we 12897 -- cannot create temporaries for all expressions for which this 12898 -- condition is true, for various reasons that might require clearing up 12899 -- ??? For example, discriminant references that appear out of place, or 12900 -- spurious type errors with class-wide expressions. As a result, we 12901 -- limit the transformation to loop bounds, which is so far the only 12902 -- case that requires it. 12903 12904 ----------------------------- 12905 -- Safe_Prefixed_Reference -- 12906 ----------------------------- 12907 12908 function Safe_Prefixed_Reference (N : Node_Id) return Boolean is 12909 begin 12910 -- If prefix is not side effect free, definitely not safe 12911 12912 if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then 12913 return False; 12914 12915 -- If the prefix is of an access type that is not access-to-constant, 12916 -- then this construct is a variable reference, which means it is to 12917 -- be considered to have side effects if Variable_Ref is set True. 12918 12919 elsif Is_Access_Type (Etype (Prefix (N))) 12920 and then not Is_Access_Constant (Etype (Prefix (N))) 12921 and then Variable_Ref 12922 then 12923 -- Exception is a prefix that is the result of a previous removal 12924 -- of side effects. 12925 12926 return Is_Entity_Name (Prefix (N)) 12927 and then not Comes_From_Source (Prefix (N)) 12928 and then Ekind (Entity (Prefix (N))) = E_Constant 12929 and then Is_Internal_Name (Chars (Entity (Prefix (N)))); 12930 12931 -- If the prefix is an explicit dereference then this construct is a 12932 -- variable reference, which means it is to be considered to have 12933 -- side effects if Variable_Ref is True. 12934 12935 -- We do NOT exclude dereferences of access-to-constant types because 12936 -- we handle them as constant view of variables. 12937 12938 elsif Nkind (Prefix (N)) = N_Explicit_Dereference 12939 and then Variable_Ref 12940 then 12941 return False; 12942 12943 -- Note: The following test is the simplest way of solving a complex 12944 -- problem uncovered by the following test (Side effect on loop bound 12945 -- that is a subcomponent of a global variable: 12946 12947 -- with Text_Io; use Text_Io; 12948 -- procedure Tloop is 12949 -- type X is 12950 -- record 12951 -- V : Natural := 4; 12952 -- S : String (1..5) := (others => 'a'); 12953 -- end record; 12954 -- X1 : X; 12955 12956 -- procedure Modi; 12957 12958 -- generic 12959 -- with procedure Action; 12960 -- procedure Loop_G (Arg : X; Msg : String) 12961 12962 -- procedure Loop_G (Arg : X; Msg : String) is 12963 -- begin 12964 -- Put_Line ("begin loop_g " & Msg & " will loop till: " 12965 -- & Natural'Image (Arg.V)); 12966 -- for Index in 1 .. Arg.V loop 12967 -- Text_Io.Put_Line 12968 -- (Natural'Image (Index) & " " & Arg.S (Index)); 12969 -- if Index > 2 then 12970 -- Modi; 12971 -- end if; 12972 -- end loop; 12973 -- Put_Line ("end loop_g " & Msg); 12974 -- end; 12975 12976 -- procedure Loop1 is new Loop_G (Modi); 12977 -- procedure Modi is 12978 -- begin 12979 -- X1.V := 1; 12980 -- Loop1 (X1, "from modi"); 12981 -- end; 12982 -- 12983 -- begin 12984 -- Loop1 (X1, "initial"); 12985 -- end; 12986 12987 -- The output of the above program should be: 12988 12989 -- begin loop_g initial will loop till: 4 12990 -- 1 a 12991 -- 2 a 12992 -- 3 a 12993 -- begin loop_g from modi will loop till: 1 12994 -- 1 a 12995 -- end loop_g from modi 12996 -- 4 a 12997 -- begin loop_g from modi will loop till: 1 12998 -- 1 a 12999 -- end loop_g from modi 13000 -- end loop_g initial 13001 13002 -- If a loop bound is a subcomponent of a global variable, a 13003 -- modification of that variable within the loop may incorrectly 13004 -- affect the execution of the loop. 13005 13006 elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification 13007 and then Within_In_Parameter (Prefix (N)) 13008 and then Variable_Ref 13009 then 13010 return False; 13011 13012 -- All other cases are side effect free 13013 13014 else 13015 return True; 13016 end if; 13017 end Safe_Prefixed_Reference; 13018 13019 ------------------------- 13020 -- Within_In_Parameter -- 13021 ------------------------- 13022 13023 function Within_In_Parameter (N : Node_Id) return Boolean is 13024 begin 13025 if not Comes_From_Source (N) then 13026 return False; 13027 13028 elsif Is_Entity_Name (N) then 13029 return Ekind (Entity (N)) = E_In_Parameter; 13030 13031 elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then 13032 return Within_In_Parameter (Prefix (N)); 13033 13034 else 13035 return False; 13036 end if; 13037 end Within_In_Parameter; 13038 13039 -- Start of processing for Side_Effect_Free 13040 13041 begin 13042 -- If volatile reference, always consider it to have side effects 13043 13044 if Is_Volatile_Reference (N) then 13045 return False; 13046 end if; 13047 13048 -- Note on checks that could raise Constraint_Error. Strictly, if we 13049 -- take advantage of 11.6, these checks do not count as side effects. 13050 -- However, we would prefer to consider that they are side effects, 13051 -- since the back end CSE does not work very well on expressions which 13052 -- can raise Constraint_Error. On the other hand if we don't consider 13053 -- them to be side effect free, then we get some awkward expansions 13054 -- in -gnato mode, resulting in code insertions at a point where we 13055 -- do not have a clear model for performing the insertions. 13056 13057 -- Special handling for entity names 13058 13059 if Is_Entity_Name (N) then 13060 13061 -- A type reference is always side effect free 13062 13063 if Is_Type (Entity (N)) then 13064 return True; 13065 13066 -- Variables are considered to be a side effect if Variable_Ref 13067 -- is set or if we have a volatile reference and Name_Req is off. 13068 -- If Name_Req is True then we can't help returning a name which 13069 -- effectively allows multiple references in any case. 13070 13071 elsif Is_Variable (N, Use_Original_Node => False) then 13072 return not Variable_Ref 13073 and then (not Is_Volatile_Reference (N) or else Name_Req); 13074 13075 -- Any other entity (e.g. a subtype name) is definitely side 13076 -- effect free. 13077 13078 else 13079 return True; 13080 end if; 13081 13082 -- A value known at compile time is always side effect free 13083 13084 elsif Compile_Time_Known_Value (N) then 13085 return True; 13086 13087 -- A variable renaming is not side-effect free, because the renaming 13088 -- will function like a macro in the front-end in some cases, and an 13089 -- assignment can modify the component designated by N, so we need to 13090 -- create a temporary for it. 13091 13092 -- The guard testing for Entity being present is needed at least in 13093 -- the case of rewritten predicate expressions, and may well also be 13094 -- appropriate elsewhere. Obviously we can't go testing the entity 13095 -- field if it does not exist, so it's reasonable to say that this is 13096 -- not the renaming case if it does not exist. 13097 13098 elsif Is_Entity_Name (Original_Node (N)) 13099 and then Present (Entity (Original_Node (N))) 13100 and then Is_Renaming_Of_Object (Entity (Original_Node (N))) 13101 and then Ekind (Entity (Original_Node (N))) /= E_Constant 13102 then 13103 declare 13104 RO : constant Node_Id := 13105 Renamed_Object (Entity (Original_Node (N))); 13106 13107 begin 13108 -- If the renamed object is an indexed component, or an 13109 -- explicit dereference, then the designated object could 13110 -- be modified by an assignment. 13111 13112 if Nkind_In (RO, N_Indexed_Component, 13113 N_Explicit_Dereference) 13114 then 13115 return False; 13116 13117 -- A selected component must have a safe prefix 13118 13119 elsif Nkind (RO) = N_Selected_Component then 13120 return Safe_Prefixed_Reference (RO); 13121 13122 -- In all other cases, designated object cannot be changed so 13123 -- we are side effect free. 13124 13125 else 13126 return True; 13127 end if; 13128 end; 13129 13130 -- Remove_Side_Effects generates an object renaming declaration to 13131 -- capture the expression of a class-wide expression. In VM targets 13132 -- the frontend performs no expansion for dispatching calls to 13133 -- class- wide types since they are handled by the VM. Hence, we must 13134 -- locate here if this node corresponds to a previous invocation of 13135 -- Remove_Side_Effects to avoid a never ending loop in the frontend. 13136 13137 elsif not Tagged_Type_Expansion 13138 and then not Comes_From_Source (N) 13139 and then Nkind (Parent (N)) = N_Object_Renaming_Declaration 13140 and then Is_Class_Wide_Type (Typ) 13141 then 13142 return True; 13143 13144 -- Generating C the type conversion of an access to constrained array 13145 -- type into an access to unconstrained array type involves initializing 13146 -- a fat pointer and the expression cannot be assumed to be free of side 13147 -- effects since it must referenced several times to compute its bounds. 13148 13149 elsif Modify_Tree_For_C 13150 and then Nkind (N) = N_Type_Conversion 13151 and then Is_Access_Type (Typ) 13152 and then Is_Array_Type (Designated_Type (Typ)) 13153 and then not Is_Constrained (Designated_Type (Typ)) 13154 then 13155 return False; 13156 end if; 13157 13158 -- For other than entity names and compile time known values, 13159 -- check the node kind for special processing. 13160 13161 case Nkind (N) is 13162 13163 -- An attribute reference is side effect free if its expressions 13164 -- are side effect free and its prefix is side effect free or 13165 -- is an entity reference. 13166 13167 -- Is this right? what about x'first where x is a variable??? 13168 13169 when N_Attribute_Reference => 13170 Attribute_Reference : declare 13171 13172 function Side_Effect_Free_Attribute 13173 (Attribute_Name : Name_Id) return Boolean; 13174 -- Returns True if evaluation of the given attribute is 13175 -- considered side-effect free (independent of prefix and 13176 -- arguments). 13177 13178 -------------------------------- 13179 -- Side_Effect_Free_Attribute -- 13180 -------------------------------- 13181 13182 function Side_Effect_Free_Attribute 13183 (Attribute_Name : Name_Id) return Boolean 13184 is 13185 begin 13186 case Attribute_Name is 13187 when Name_Input => 13188 return False; 13189 13190 when Name_Image 13191 | Name_Img 13192 | Name_Wide_Image 13193 | Name_Wide_Wide_Image 13194 => 13195 -- CodePeer doesn't want to see replicated copies of 13196 -- 'Image calls. 13197 13198 return not CodePeer_Mode; 13199 13200 when others => 13201 return True; 13202 end case; 13203 end Side_Effect_Free_Attribute; 13204 13205 -- Start of processing for Attribute_Reference 13206 13207 begin 13208 return 13209 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref) 13210 and then Side_Effect_Free_Attribute (Attribute_Name (N)) 13211 and then (Is_Entity_Name (Prefix (N)) 13212 or else Side_Effect_Free 13213 (Prefix (N), Name_Req, Variable_Ref)); 13214 end Attribute_Reference; 13215 13216 -- A binary operator is side effect free if and both operands are 13217 -- side effect free. For this purpose binary operators include 13218 -- membership tests and short circuit forms. 13219 13220 when N_Binary_Op 13221 | N_Membership_Test 13222 | N_Short_Circuit 13223 => 13224 return Side_Effect_Free (Left_Opnd (N), Name_Req, Variable_Ref) 13225 and then 13226 Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref); 13227 13228 -- An explicit dereference is side effect free only if it is 13229 -- a side effect free prefixed reference. 13230 13231 when N_Explicit_Dereference => 13232 return Safe_Prefixed_Reference (N); 13233 13234 -- An expression with action is side effect free if its expression 13235 -- is side effect free and it has no actions. 13236 13237 when N_Expression_With_Actions => 13238 return 13239 Is_Empty_List (Actions (N)) 13240 and then Side_Effect_Free 13241 (Expression (N), Name_Req, Variable_Ref); 13242 13243 -- A call to _rep_to_pos is side effect free, since we generate 13244 -- this pure function call ourselves. Moreover it is critically 13245 -- important to make this exception, since otherwise we can have 13246 -- discriminants in array components which don't look side effect 13247 -- free in the case of an array whose index type is an enumeration 13248 -- type with an enumeration rep clause. 13249 13250 -- All other function calls are not side effect free 13251 13252 when N_Function_Call => 13253 return 13254 Nkind (Name (N)) = N_Identifier 13255 and then Is_TSS (Name (N), TSS_Rep_To_Pos) 13256 and then Side_Effect_Free 13257 (First (Parameter_Associations (N)), 13258 Name_Req, Variable_Ref); 13259 13260 -- An IF expression is side effect free if it's of a scalar type, and 13261 -- all its components are all side effect free (conditions and then 13262 -- actions and else actions). We restrict to scalar types, since it 13263 -- is annoying to deal with things like (if A then B else C)'First 13264 -- where the type involved is a string type. 13265 13266 when N_If_Expression => 13267 return 13268 Is_Scalar_Type (Typ) 13269 and then Side_Effect_Free 13270 (Expressions (N), Name_Req, Variable_Ref); 13271 13272 -- An indexed component is side effect free if it is a side 13273 -- effect free prefixed reference and all the indexing 13274 -- expressions are side effect free. 13275 13276 when N_Indexed_Component => 13277 return 13278 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref) 13279 and then Safe_Prefixed_Reference (N); 13280 13281 -- A type qualification, type conversion, or unchecked expression is 13282 -- side effect free if the expression is side effect free. 13283 13284 when N_Qualified_Expression 13285 | N_Type_Conversion 13286 | N_Unchecked_Expression 13287 => 13288 return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref); 13289 13290 -- A selected component is side effect free only if it is a side 13291 -- effect free prefixed reference. 13292 13293 when N_Selected_Component => 13294 return Safe_Prefixed_Reference (N); 13295 13296 -- A range is side effect free if the bounds are side effect free 13297 13298 when N_Range => 13299 return Side_Effect_Free (Low_Bound (N), Name_Req, Variable_Ref) 13300 and then 13301 Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref); 13302 13303 -- A slice is side effect free if it is a side effect free 13304 -- prefixed reference and the bounds are side effect free. 13305 13306 when N_Slice => 13307 return 13308 Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref) 13309 and then Safe_Prefixed_Reference (N); 13310 13311 -- A unary operator is side effect free if the operand 13312 -- is side effect free. 13313 13314 when N_Unary_Op => 13315 return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref); 13316 13317 -- An unchecked type conversion is side effect free only if it 13318 -- is safe and its argument is side effect free. 13319 13320 when N_Unchecked_Type_Conversion => 13321 return 13322 Safe_Unchecked_Type_Conversion (N) 13323 and then Side_Effect_Free 13324 (Expression (N), Name_Req, Variable_Ref); 13325 13326 -- A literal is side effect free 13327 13328 when N_Character_Literal 13329 | N_Integer_Literal 13330 | N_Real_Literal 13331 | N_String_Literal 13332 => 13333 return True; 13334 13335 -- We consider that anything else has side effects. This is a bit 13336 -- crude, but we are pretty close for most common cases, and we 13337 -- are certainly correct (i.e. we never return True when the 13338 -- answer should be False). 13339 13340 when others => 13341 return False; 13342 end case; 13343 end Side_Effect_Free; 13344 13345 -- A list is side effect free if all elements of the list are side 13346 -- effect free. 13347 13348 function Side_Effect_Free 13349 (L : List_Id; 13350 Name_Req : Boolean := False; 13351 Variable_Ref : Boolean := False) return Boolean 13352 is 13353 N : Node_Id; 13354 13355 begin 13356 if L = No_List or else L = Error_List then 13357 return True; 13358 13359 else 13360 N := First (L); 13361 while Present (N) loop 13362 if not Side_Effect_Free (N, Name_Req, Variable_Ref) then 13363 return False; 13364 else 13365 Next (N); 13366 end if; 13367 end loop; 13368 13369 return True; 13370 end if; 13371 end Side_Effect_Free; 13372 13373 ---------------------------------- 13374 -- Silly_Boolean_Array_Not_Test -- 13375 ---------------------------------- 13376 13377 -- This procedure implements an odd and silly test. We explicitly check 13378 -- for the case where the 'First of the component type is equal to the 13379 -- 'Last of this component type, and if this is the case, we make sure 13380 -- that constraint error is raised. The reason is that the NOT is bound 13381 -- to cause CE in this case, and we will not otherwise catch it. 13382 13383 -- No such check is required for AND and OR, since for both these cases 13384 -- False op False = False, and True op True = True. For the XOR case, 13385 -- see Silly_Boolean_Array_Xor_Test. 13386 13387 -- Believe it or not, this was reported as a bug. Note that nearly always, 13388 -- the test will evaluate statically to False, so the code will be 13389 -- statically removed, and no extra overhead caused. 13390 13391 procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is 13392 Loc : constant Source_Ptr := Sloc (N); 13393 CT : constant Entity_Id := Component_Type (T); 13394 13395 begin 13396 -- The check we install is 13397 13398 -- constraint_error when 13399 -- component_type'first = component_type'last 13400 -- and then array_type'Length /= 0) 13401 13402 -- We need the last guard because we don't want to raise CE for empty 13403 -- arrays since no out of range values result. (Empty arrays with a 13404 -- component type of True .. True -- very useful -- even the ACATS 13405 -- does not test that marginal case). 13406 13407 Insert_Action (N, 13408 Make_Raise_Constraint_Error (Loc, 13409 Condition => 13410 Make_And_Then (Loc, 13411 Left_Opnd => 13412 Make_Op_Eq (Loc, 13413 Left_Opnd => 13414 Make_Attribute_Reference (Loc, 13415 Prefix => New_Occurrence_Of (CT, Loc), 13416 Attribute_Name => Name_First), 13417 13418 Right_Opnd => 13419 Make_Attribute_Reference (Loc, 13420 Prefix => New_Occurrence_Of (CT, Loc), 13421 Attribute_Name => Name_Last)), 13422 13423 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))), 13424 Reason => CE_Range_Check_Failed)); 13425 end Silly_Boolean_Array_Not_Test; 13426 13427 ---------------------------------- 13428 -- Silly_Boolean_Array_Xor_Test -- 13429 ---------------------------------- 13430 13431 -- This procedure implements an odd and silly test. We explicitly check 13432 -- for the XOR case where the component type is True .. True, since this 13433 -- will raise constraint error. A special check is required since CE 13434 -- will not be generated otherwise (cf Expand_Packed_Not). 13435 13436 -- No such check is required for AND and OR, since for both these cases 13437 -- False op False = False, and True op True = True, and no check is 13438 -- required for the case of False .. False, since False xor False = False. 13439 -- See also Silly_Boolean_Array_Not_Test 13440 13441 procedure Silly_Boolean_Array_Xor_Test 13442 (N : Node_Id; 13443 R : Node_Id; 13444 T : Entity_Id) 13445 is 13446 Loc : constant Source_Ptr := Sloc (N); 13447 CT : constant Entity_Id := Component_Type (T); 13448 13449 begin 13450 -- The check we install is 13451 13452 -- constraint_error when 13453 -- Boolean (component_type'First) 13454 -- and then Boolean (component_type'Last) 13455 -- and then array_type'Length /= 0) 13456 13457 -- We need the last guard because we don't want to raise CE for empty 13458 -- arrays since no out of range values result (Empty arrays with a 13459 -- component type of True .. True -- very useful -- even the ACATS 13460 -- does not test that marginal case). 13461 13462 Insert_Action (N, 13463 Make_Raise_Constraint_Error (Loc, 13464 Condition => 13465 Make_And_Then (Loc, 13466 Left_Opnd => 13467 Make_And_Then (Loc, 13468 Left_Opnd => 13469 Convert_To (Standard_Boolean, 13470 Make_Attribute_Reference (Loc, 13471 Prefix => New_Occurrence_Of (CT, Loc), 13472 Attribute_Name => Name_First)), 13473 13474 Right_Opnd => 13475 Convert_To (Standard_Boolean, 13476 Make_Attribute_Reference (Loc, 13477 Prefix => New_Occurrence_Of (CT, Loc), 13478 Attribute_Name => Name_Last))), 13479 13480 Right_Opnd => Make_Non_Empty_Check (Loc, R)), 13481 Reason => CE_Range_Check_Failed)); 13482 end Silly_Boolean_Array_Xor_Test; 13483 13484 -------------------------- 13485 -- Target_Has_Fixed_Ops -- 13486 -------------------------- 13487 13488 Integer_Sized_Small : Ureal; 13489 -- Set to 2.0 ** -(Integer'Size - 1) the first time that this function is 13490 -- called (we don't want to compute it more than once). 13491 13492 Long_Integer_Sized_Small : Ureal; 13493 -- Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function 13494 -- is called (we don't want to compute it more than once) 13495 13496 First_Time_For_THFO : Boolean := True; 13497 -- Set to False after first call (if Fractional_Fixed_Ops_On_Target) 13498 13499 function Target_Has_Fixed_Ops 13500 (Left_Typ : Entity_Id; 13501 Right_Typ : Entity_Id; 13502 Result_Typ : Entity_Id) return Boolean 13503 is 13504 function Is_Fractional_Type (Typ : Entity_Id) return Boolean; 13505 -- Return True if the given type is a fixed-point type with a small 13506 -- value equal to 2 ** (-(T'Object_Size - 1)) and whose values have 13507 -- an absolute value less than 1.0. This is currently limited to 13508 -- fixed-point types that map to Integer or Long_Integer. 13509 13510 ------------------------ 13511 -- Is_Fractional_Type -- 13512 ------------------------ 13513 13514 function Is_Fractional_Type (Typ : Entity_Id) return Boolean is 13515 begin 13516 if Esize (Typ) = Standard_Integer_Size then 13517 return Small_Value (Typ) = Integer_Sized_Small; 13518 13519 elsif Esize (Typ) = Standard_Long_Integer_Size then 13520 return Small_Value (Typ) = Long_Integer_Sized_Small; 13521 13522 else 13523 return False; 13524 end if; 13525 end Is_Fractional_Type; 13526 13527 -- Start of processing for Target_Has_Fixed_Ops 13528 13529 begin 13530 -- Return False if Fractional_Fixed_Ops_On_Target is false 13531 13532 if not Fractional_Fixed_Ops_On_Target then 13533 return False; 13534 end if; 13535 13536 -- Here the target has Fractional_Fixed_Ops, if first time, compute 13537 -- standard constants used by Is_Fractional_Type. 13538 13539 if First_Time_For_THFO then 13540 First_Time_For_THFO := False; 13541 13542 Integer_Sized_Small := 13543 UR_From_Components 13544 (Num => Uint_1, 13545 Den => UI_From_Int (Standard_Integer_Size - 1), 13546 Rbase => 2); 13547 13548 Long_Integer_Sized_Small := 13549 UR_From_Components 13550 (Num => Uint_1, 13551 Den => UI_From_Int (Standard_Long_Integer_Size - 1), 13552 Rbase => 2); 13553 end if; 13554 13555 -- Return True if target supports fixed-by-fixed multiply/divide for 13556 -- fractional fixed-point types (see Is_Fractional_Type) and the operand 13557 -- and result types are equivalent fractional types. 13558 13559 return Is_Fractional_Type (Base_Type (Left_Typ)) 13560 and then Is_Fractional_Type (Base_Type (Right_Typ)) 13561 and then Is_Fractional_Type (Base_Type (Result_Typ)) 13562 and then Esize (Left_Typ) = Esize (Right_Typ) 13563 and then Esize (Left_Typ) = Esize (Result_Typ); 13564 end Target_Has_Fixed_Ops; 13565 13566 ------------------- 13567 -- Type_Map_Hash -- 13568 ------------------- 13569 13570 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is 13571 begin 13572 return Type_Map_Header (Id mod Type_Map_Size); 13573 end Type_Map_Hash; 13574 13575 ------------------------------------------ 13576 -- Type_May_Have_Bit_Aligned_Components -- 13577 ------------------------------------------ 13578 13579 function Type_May_Have_Bit_Aligned_Components 13580 (Typ : Entity_Id) return Boolean 13581 is 13582 begin 13583 -- Array type, check component type 13584 13585 if Is_Array_Type (Typ) then 13586 return 13587 Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)); 13588 13589 -- Record type, check components 13590 13591 elsif Is_Record_Type (Typ) then 13592 declare 13593 E : Entity_Id; 13594 13595 begin 13596 E := First_Component_Or_Discriminant (Typ); 13597 while Present (E) loop 13598 if Component_May_Be_Bit_Aligned (E) 13599 or else Type_May_Have_Bit_Aligned_Components (Etype (E)) 13600 then 13601 return True; 13602 end if; 13603 13604 Next_Component_Or_Discriminant (E); 13605 end loop; 13606 13607 return False; 13608 end; 13609 13610 -- Type other than array or record is always OK 13611 13612 else 13613 return False; 13614 end if; 13615 end Type_May_Have_Bit_Aligned_Components; 13616 13617 ------------------------------- 13618 -- Update_Primitives_Mapping -- 13619 ------------------------------- 13620 13621 procedure Update_Primitives_Mapping 13622 (Inher_Id : Entity_Id; 13623 Subp_Id : Entity_Id) 13624 is 13625 begin 13626 Map_Types 13627 (Parent_Type => Find_Dispatching_Type (Inher_Id), 13628 Derived_Type => Find_Dispatching_Type (Subp_Id)); 13629 end Update_Primitives_Mapping; 13630 13631 ---------------------------------- 13632 -- Within_Case_Or_If_Expression -- 13633 ---------------------------------- 13634 13635 function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is 13636 Par : Node_Id; 13637 13638 begin 13639 -- Locate an enclosing case or if expression. Note that these constructs 13640 -- can be expanded into Expression_With_Actions, hence the test of the 13641 -- original node. 13642 13643 Par := Parent (N); 13644 while Present (Par) loop 13645 if Nkind_In (Original_Node (Par), N_Case_Expression, 13646 N_If_Expression) 13647 then 13648 return True; 13649 13650 -- Prevent the search from going too far 13651 13652 elsif Is_Body_Or_Package_Declaration (Par) then 13653 return False; 13654 end if; 13655 13656 Par := Parent (Par); 13657 end loop; 13658 13659 return False; 13660 end Within_Case_Or_If_Expression; 13661 13662 -------------------------------- 13663 -- Within_Internal_Subprogram -- 13664 -------------------------------- 13665 13666 function Within_Internal_Subprogram return Boolean is 13667 S : Entity_Id; 13668 13669 begin 13670 S := Current_Scope; 13671 while Present (S) and then not Is_Subprogram (S) loop 13672 S := Scope (S); 13673 end loop; 13674 13675 return Present (S) 13676 and then Get_TSS_Name (S) /= TSS_Null 13677 and then not Is_Predicate_Function (S) 13678 and then not Is_Predicate_Function_M (S); 13679 end Within_Internal_Subprogram; 13680 13681end Exp_Util; 13682