exp_ch13.adb 27.5 KB
Newer Older
Richard Kenner committed
1 2 3 4 5 6 7 8
------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             E X P _ C H 1 3                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
9
--          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
Richard Kenner committed
10 11 12
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- 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- --
Richard Kenner committed
14 15 16 17
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
18 19
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
Richard Kenner committed
20 21
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
22
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
Richard Kenner committed
23 24 25 26
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
27
with Checks;   use Checks;
Richard Kenner committed
28 29 30 31
with Einfo;    use Einfo;
with Exp_Ch3;  use Exp_Ch3;
with Exp_Ch6;  use Exp_Ch6;
with Exp_Imgv; use Exp_Imgv;
32
with Exp_Tss;  use Exp_Tss;
Richard Kenner committed
33
with Exp_Util; use Exp_Util;
Arnaud Charlet committed
34
with Freeze;   use Freeze;
Arnaud Charlet committed
35
with Ghost;    use Ghost;
36
with Namet;    use Namet;
Richard Kenner committed
37 38
with Nlists;   use Nlists;
with Nmake;    use Nmake;
Arnaud Charlet committed
39
with Opt;      use Opt;
Arnaud Charlet committed
40 41
with Restrict; use Restrict;
with Rident;   use Rident;
Richard Kenner committed
42 43
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
Arnaud Charlet committed
44
with Sem_Aux;  use Sem_Aux;
Richard Kenner committed
45 46 47 48 49 50 51 52
with Sem_Ch7;  use Sem_Ch7;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Eval; use Sem_Eval;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Tbuild;   use Tbuild;
with Uintp;    use Uintp;
Arnaud Charlet committed
53
with Validsw;  use Validsw;
Richard Kenner committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

package body Exp_Ch13 is

   ------------------------------------------
   -- Expand_N_Attribute_Definition_Clause --
   ------------------------------------------

   --  Expansion action depends on attribute involved

   procedure Expand_N_Attribute_Definition_Clause (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Exp : constant Node_Id    := Expression (N);
      Ent : Entity_Id;
      V   : Node_Id;

   begin
      Ent := Entity (Name (N));

      if Is_Type (Ent) then
         Ent := Underlying_Type (Ent);
      end if;

      case Get_Attribute_Id (Chars (N)) is

         -------------
         -- Address --
         -------------

         when Attribute_Address =>

84 85 86 87 88 89 90
            --  If there is an initialization which did not come from the
            --  source program, then it is an artifact of our expansion, and we
            --  suppress it. The case we are most concerned about here is the
            --  initialization of a packed array to all false, which seems
            --  inappropriate for variable to which an address clause is
            --  applied. The expression may itself have been rewritten if the
            --  type is packed array, so we need to examine whether the
91 92 93
            --  original node is in the source. An exception though is the case
            --  of an access variable which is default initialized to null, and
            --  such initialization is retained.
94 95

            --  Furthermore, if the initialization is the equivalent aggregate
96 97 98
            --  of the type initialization procedure, it replaces an implicit
            --  call to the init proc, and must be respected. Note that for
            --  packed types we do not build equivalent aggregates.
Richard Kenner committed
99

Arnaud Charlet committed
100 101 102 103 104 105 106 107
            --  Also, if Init_Or_Norm_Scalars applies, then we need to retain
            --  any default initialization for objects of scalar types and
            --  types with scalar components. Normally a composite type will
            --  have an init_proc in the presence of Init_Or_Norm_Scalars,
            --  so when that flag is set we have just have to do a test for
            --  scalar and string types (the predefined string types such as
            --  String and Wide_String don't have an init_proc).

Richard Kenner committed
108 109
            declare
               Decl : constant Node_Id := Declaration_Node (Ent);
110
               Typ  : constant Entity_Id := Etype (Ent);
Arnaud Charlet committed
111

Richard Kenner committed
112 113 114
            begin
               if Nkind (Decl) = N_Object_Declaration
                  and then Present (Expression (Decl))
115
                  and then Nkind (Expression (Decl)) /= N_Null
Richard Kenner committed
116 117 118
                  and then
                   not Comes_From_Source (Original_Node (Expression (Decl)))
               then
119 120 121 122 123
                  if Present (Base_Init_Proc (Typ))
                    and then
                      Present (Static_Initialization (Base_Init_Proc (Typ)))
                  then
                     null;
Arnaud Charlet committed
124 125 126 127 128 129 130

                  elsif Init_Or_Norm_Scalars
                    and then
                      (Is_Scalar_Type (Typ) or else Is_String_Type (Typ))
                  then
                     null;

131 132 133
                  else
                     Set_Expression (Decl, Empty);
                  end if;
Arnaud Charlet committed
134 135 136 137 138 139 140 141 142 143

               --  An object declaration to which an address clause applies
               --  has a delayed freeze, but the address expression itself
               --  must be elaborated at the point it appears. If the object
               --  is controlled, additional checks apply elsewhere.

               elsif Nkind (Decl) = N_Object_Declaration
                 and then not Needs_Constant_Address (Decl, Typ)
               then
                  Remove_Side_Effects (Exp);
Richard Kenner committed
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
               end if;
            end;

         ---------------
         -- Alignment --
         ---------------

         when Attribute_Alignment =>

            --  As required by Gigi, we guarantee that the operand is an
            --  integer literal (this simplifies things in Gigi).

            if Nkind (Exp) /= N_Integer_Literal then
               Rewrite
                 (Exp, Make_Integer_Literal (Loc, Expr_Value (Exp)));
            end if;

Arnaud Charlet committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
            --  A complex case arises if the alignment clause applies to an
            --  unconstrained object initialized with a function call. The
            --  result of the call is placed on the secondary stack, and the
            --  declaration is rewritten as a renaming of a dereference, which
            --  fails expansion. We must introduce a temporary and assign its
            --  value to the existing entity.

            if Nkind (Parent (Ent)) = N_Object_Renaming_Declaration
              and then not Is_Entity_Name (Renamed_Object (Ent))
            then
               declare
                  Loc      : constant Source_Ptr := Sloc (N);
                  Decl     : constant Node_Id    := Parent (Ent);
                  Temp     : constant Entity_Id  := Make_Temporary (Loc, 'T');
                  New_Decl : Node_Id;

               begin
Arnaud Charlet committed
178
                  --  Replace entity with temporary and reanalyze
Arnaud Charlet committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

                  Set_Defining_Identifier (Decl, Temp);
                  Set_Analyzed (Decl, False);
                  Analyze (Decl);

                  --  Introduce new declaration for entity but do not reanalyze
                  --  because entity is already in scope. Type and expression
                  --  are already resolved.

                  New_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Ent,
                      Object_Definition   =>
                        New_Occurrence_Of (Etype (Ent), Loc),
                      Expression          => New_Occurrence_Of (Temp, Loc));

                  Set_Renamed_Object (Ent, Empty);
                  Insert_After (Decl, New_Decl);
                  Set_Analyzed (Decl);
               end;
            end if;

Richard Kenner committed
201 202 203 204 205 206 207 208
         ------------------
         -- Storage_Size --
         ------------------

         when Attribute_Storage_Size =>

            --  If the type is a task type, then assign the value of the
            --  storage size to the Size variable associated with the task.
Arnaud Charlet committed
209 210 211 212 213 214
            --  Insert the assignment right after the declaration of the Size
            --  variable.

            --  Generate:

            --  task_typeZ := expression
Richard Kenner committed
215 216

            if Ekind (Ent) = E_Task_Type then
Arnaud Charlet committed
217 218 219 220 221 222 223
               declare
                  Assign : Node_Id;

               begin
                  Assign :=
                    Make_Assignment_Statement (Loc,
                      Name =>
224
                        New_Occurrence_Of (Storage_Size_Variable (Ent), Loc),
Arnaud Charlet committed
225 226 227
                      Expression =>
                        Convert_To (RTE (RE_Size_Type), Expression (N)));

Arnaud Charlet committed
228 229 230 231 232 233 234 235 236 237 238 239 240
                  --  If the clause is not generated by an aspect, insert
                  --  the assignment here.  Freezing rules ensure that this
                  --  is safe, or clause will have been rejected already.

                  if Is_List_Member (N) then
                     Insert_After (N, Assign);

                  --  Otherwise, insert assignment after task declaration.

                  else
                     Insert_After
                       (Parent (Storage_Size_Variable (Entity (N))), Assign);
                  end if;
Arnaud Charlet committed
241 242 243

                  Analyze (Assign);
               end;
Richard Kenner committed
244 245 246

            --  For Storage_Size for an access type, create a variable to hold
            --  the value of the specified size with name typeV and expand an
247
            --  assignment statement to initialize this value.
Richard Kenner committed
248 249 250

            elsif Is_Access_Type (Ent) then

251 252 253 254 255 256
               --  We don't need the variable for a storage size of zero

               if not No_Pool_Assigned (Ent) then
                  V :=
                    Make_Defining_Identifier (Loc,
                      Chars => New_External_Name (Chars (Ent), 'V'));
Richard Kenner committed
257

258 259 260 261 262 263
                  --  Insert the declaration of the object

                  Insert_Action (N,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => V,
                      Object_Definition  =>
264
                        New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
265 266 267 268 269
                      Expression =>
                        Convert_To (RTE (RE_Storage_Offset), Expression (N))));

                  Set_Storage_Size_Variable (Ent, Entity_Id (V));
               end if;
Richard Kenner committed
270 271 272 273 274 275 276 277 278 279
            end if;

         --  Other attributes require no expansion

         when others =>
            null;

      end case;
   end Expand_N_Attribute_Definition_Clause;

280 281 282 283 284 285
   -----------------------------
   -- Expand_N_Free_Statement --
   -----------------------------

   procedure Expand_N_Free_Statement (N : Node_Id) is
      Expr : constant Node_Id := Expression (N);
Arnaud Charlet committed
286
      Typ  : Entity_Id;
287 288

   begin
Arnaud Charlet committed
289 290 291 292 293
      --  Certain run-time configurations and targets do not provide support
      --  for controlled types.

      if Restriction_Active (No_Finalization) then
         return;
294 295
      end if;

Arnaud Charlet committed
296
      --  Use the base type to perform the check for finalization master
297

Arnaud Charlet committed
298 299
      Typ := Etype (Expr);

300 301 302 303 304 305 306 307 308 309 310 311 312 313
      if Ekind (Typ) = E_Access_Subtype then
         Typ := Etype (Typ);
      end if;

      --  Handle private access types

      if Is_Private_Type (Typ)
        and then Present (Full_View (Typ))
      then
         Typ := Full_View (Typ);
      end if;

      --  Do not create a custom Deallocate when freeing an object with
      --  suppressed finalization. In such cases the object is never attached
Arnaud Charlet committed
314 315
      --  to a master, so it does not need to be detached. Use a regular free
      --  statement instead.
316

Arnaud Charlet committed
317
      if No (Finalization_Master (Typ)) then
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
         return;
      end if;

      --  Use a temporary to store the result of a complex expression. Perform
      --  the following transformation:
      --
      --     Free (Complex_Expression);
      --
      --     Temp : constant Type_Of_Expression := Complex_Expression;
      --     Free (Temp);

      if Nkind (Expr) /= N_Identifier then
         declare
            Expr_Typ : constant Entity_Id  := Etype (Expr);
            Loc      : constant Source_Ptr := Sloc (N);
            New_Expr : Node_Id;
            Temp_Id  : Entity_Id;

         begin
            Temp_Id := Make_Temporary (Loc, 'T');
            Insert_Action (N,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp_Id,
                Object_Definition =>
342
                  New_Occurrence_Of (Expr_Typ, Loc),
343 344 345
                Expression =>
                  Relocate_Node (Expr)));

346
            New_Expr := New_Occurrence_Of (Temp_Id, Loc);
347 348 349 350 351 352 353 354 355 356 357 358 359
            Set_Etype (New_Expr, Expr_Typ);

            Set_Expression (N, New_Expr);
         end;
      end if;

      --  Create a custom Deallocate for a controlled object. This routine
      --  ensures that the hidden list header will be deallocated along with
      --  the actual object.

      Build_Allocate_Deallocate_Proc (N, Is_Allocate => False);
   end Expand_N_Free_Statement;

Richard Kenner committed
360 361 362 363 364
   ----------------------------
   -- Expand_N_Freeze_Entity --
   ----------------------------

   procedure Expand_N_Freeze_Entity (N : Node_Id) is
Arnaud Charlet committed
365 366 367 368 369 370
      E : constant Entity_Id := Entity (N);

      Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;

      Decl           : Node_Id;
      Delete         : Boolean := False;
Richard Kenner committed
371 372 373 374 375
      E_Scope        : Entity_Id;
      In_Other_Scope : Boolean;
      In_Outer_Scope : Boolean;

   begin
Arnaud Charlet committed
376 377 378 379
      --  Ensure that all freezing activities are properly flagged as Ghost

      Set_Ghost_Mode_From_Entity (E);

Arnaud Charlet committed
380 381 382 383 384 385 386 387 388 389 390 391
      --  If there are delayed aspect specifications, we insert them just
      --  before the freeze node. They are already analyzed so we don't need
      --  to reanalyze them (they were analyzed before the type was frozen),
      --  but we want them in the tree for the back end, and so that the
      --  listing from sprint is clearer on where these occur logically.

      if Has_Delayed_Aspects (E) then
         declare
            Aitem : Node_Id;
            Ritem : Node_Id;

         begin
Arnaud Charlet committed
392 393
            --  Look for aspect specs for this entity

Arnaud Charlet committed
394 395
            Ritem := First_Rep_Item (E);
            while Present (Ritem) loop
Arnaud Charlet committed
396 397 398
               if Nkind (Ritem) = N_Aspect_Specification
                 and then Entity (Ritem) = E
               then
Arnaud Charlet committed
399
                  Aitem := Aspect_Rep_Item (Ritem);
Arnaud Charlet committed
400 401 402 403

                  --  Skip this for aspects (e.g. Current_Value) for which
                  --  there is no corresponding pragma or attribute.

404 405 406 407 408 409 410 411
                  if Present (Aitem)

                    --  Also skip if we have a null statement rather than a
                    --  delayed aspect (this happens when we are ignoring rep
                    --  items from use of the -gnatI switch).

                    and then Nkind (Aitem) /= N_Null_Statement
                  then
Arnaud Charlet committed
412 413 414
                     pragma Assert (Is_Delayed_Aspect (Aitem));
                     Insert_Before (N, Aitem);
                  end if;
Arnaud Charlet committed
415 416 417 418 419 420 421
               end if;

               Next_Rep_Item (Ritem);
            end loop;
         end;
      end if;

Arnaud Charlet committed
422 423 424 425 426 427 428
      --  Processing for objects

      if Is_Object (E) then
         if Present (Address_Clause (E)) then
            Apply_Address_Clause_Check (E, N);
         end if;

Arnaud Charlet committed
429
         --  Analyze actions in freeze node, if any
Arnaud Charlet committed
430 431 432 433 434 435 436 437 438 439 440 441 442

         if Present (Actions (N)) then
            declare
               Act : Node_Id;
            begin
               Act := First (Actions (N));
               while Present (Act) loop
                  Analyze (Act);
                  Next (Act);
               end loop;
            end;
         end if;

Arnaud Charlet committed
443 444 445 446
         --  If initialization statements have been captured in a compound
         --  statement, insert them back into the tree now.

         Explode_Initialization_Compound_Statement (E);
Arnaud Charlet committed
447
         Ghost_Mode := Save_Ghost_Mode;
448
         return;
449

450 451
      --  Only other items requiring any front end action are types and
      --  subprograms.
452 453

      elsif not Is_Type (E) and then not Is_Subprogram (E) then
Arnaud Charlet committed
454
         Ghost_Mode := Save_Ghost_Mode;
Richard Kenner committed
455 456 457
         return;
      end if;

458 459
      --  Here E is a type or a subprogram

Richard Kenner committed
460 461
      E_Scope := Scope (E);

462 463 464
      --  This is an error protection against previous errors

      if No (E_Scope) then
Arnaud Charlet committed
465
         Check_Error_Detected;
Arnaud Charlet committed
466
         Ghost_Mode := Save_Ghost_Mode;
467 468 469
         return;
      end if;

Arnaud Charlet committed
470 471 472 473 474 475 476 477 478 479 480
      --  The entity may be a subtype declared for a constrained record
      --  component, in which case the relevant scope is the scope of
      --  the record. This happens for class-wide subtypes created for
      --  a constrained type extension with inherited discriminants.

      if Is_Type (E_Scope)
        and then Ekind (E_Scope) not in Concurrent_Kind
      then
         E_Scope := Scope (E_Scope);
      end if;

481 482 483 484 485 486 487 488 489
      --  Remember that we are processing a freezing entity and its freezing
      --  nodes. This flag (non-zero = set) is used to avoid the need of
      --  climbing through the tree while processing the freezing actions (ie.
      --  to avoid generating spurious warnings or to avoid killing constant
      --  indications while processing the code associated with freezing
      --  actions). We use a counter to deal with nesting.

      Inside_Freezing_Actions := Inside_Freezing_Actions + 1;

490 491 492 493 494
      --  If we are freezing entities defined in protected types, they belong
      --  in the enclosing scope, given that the original type has been
      --  expanded away. The same is true for entities in task types, in
      --  particular the parameter records of entries (Entities in bodies are
      --  all frozen within the body). If we are in the task body, this is a
495 496 497
      --  proper scope. If we are within a subprogram body, the proper scope
      --  is the corresponding spec. This may happen for itypes generated in
      --  the bodies of protected operations.
Richard Kenner committed
498 499 500

      if Ekind (E_Scope) = E_Protected_Type
        or else (Ekind (E_Scope) = E_Task_Type
Arnaud Charlet committed
501
                  and then not Has_Completion (E_Scope))
Richard Kenner committed
502 503
      then
         E_Scope := Scope (E_Scope);
504 505 506

      elsif Ekind (E_Scope) = E_Subprogram_Body then
         E_Scope := Corresponding_Spec (Unit_Declaration_Node (E_Scope));
Richard Kenner committed
507 508
      end if;

Arnaud Charlet committed
509 510
      --  If the scope of the entity is in open scopes, it is the current one
      --  or an enclosing one, including a loop, a block, or a subprogram.
Richard Kenner committed
511

Arnaud Charlet committed
512 513 514 515
      if In_Open_Scopes (E_Scope) then
         In_Other_Scope := False;
         In_Outer_Scope := E_Scope /= Current_Scope;

Arnaud Charlet committed
516 517
      --  Otherwise it is a local package or a different compilation unit

Arnaud Charlet committed
518 519 520 521
      else
         In_Other_Scope := True;
         In_Outer_Scope := False;
      end if;
Richard Kenner committed
522 523 524 525 526 527

      --  If the entity being frozen is defined in a scope that is not
      --  currently on the scope stack, we must establish the proper
      --  visibility before freezing the entity and related subprograms.

      if In_Other_Scope then
528
         Push_Scope (E_Scope);
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554

         --  Finalizers are little odd in terms of freezing. The spec of the
         --  procedure appears in the declarations while the body appears in
         --  the statement part of a single construct. Since the finalizer must
         --  be called by the At_End handler of the construct, the spec is
         --  manually frozen right after its declaration. The only side effect
         --  of this action appears in contexts where the construct is not in
         --  its final resting place. These contexts are:

         --    * Entry bodies - The declarations and statements are moved to
         --      the procedure equivalen of the entry.
         --    * Protected subprograms - The declarations and statements are
         --      moved to the non-protected version of the subprogram.
         --    * Task bodies - The declarations and statements are moved to the
         --      task body procedure.

         --  Visible declarations do not need to be installed in these three
         --  cases since it does not make semantic sense to do so. All entities
         --  referenced by a finalizer are visible and already resolved, plus
         --  the enclosing scope may not have visible declarations at all.

         if Ekind (E) = E_Procedure
           and then Is_Finalizer (E)
           and then
             (Is_Entry (E_Scope)
                or else (Is_Subprogram (E_Scope)
Arnaud Charlet committed
555
                          and then Is_Protected_Type (Scope (E_Scope)))
556 557 558 559 560 561
                or else Is_Task_Type (E_Scope))
         then
            null;
         else
            Install_Visible_Declarations (E_Scope);
         end if;
Richard Kenner committed
562

Samuel Tardieu committed
563 564
         if Is_Package_Or_Generic_Package (E_Scope) or else
            Is_Protected_Type (E_Scope)             or else
Richard Kenner committed
565 566 567 568 569 570 571 572 573 574 575
            Is_Task_Type (E_Scope)
         then
            Install_Private_Declarations (E_Scope);
         end if;

      --  If the entity is in an outer scope, then that scope needs to
      --  temporarily become the current scope so that operations created
      --  during type freezing will be declared in the right scope and
      --  can properly override any corresponding inherited operations.

      elsif In_Outer_Scope then
576
         Push_Scope (E_Scope);
Richard Kenner committed
577 578 579 580 581
      end if;

      --  If type, freeze the type

      if Is_Type (E) then
582
         Delete := Freeze_Type (N);
Richard Kenner committed
583 584 585 586 587 588 589 590 591 592

         --  And for enumeration type, build the enumeration tables

         if Is_Enumeration_Type (E) then
            Build_Enumeration_Image_Tables (E, N);
         end if;

      --  If subprogram, freeze the subprogram

      elsif Is_Subprogram (E) then
Arnaud Charlet committed
593
         Exp_Ch6.Freeze_Subprogram (N);
594 595 596 597 598 599 600 601

         --  Ada 2005 (AI-251): Remove the freezing node associated with the
         --  entities internally used by the frontend to register primitives
         --  covering abstract interfaces. The call to Freeze_Subprogram has
         --  already expanded the code that fills the corresponding entry in
         --  its secondary dispatch table and therefore the code generator
         --  has nothing else to do with this freezing node.

602
         Delete := Present (Interface_Alias (E));
Richard Kenner committed
603 604
      end if;

605 606 607 608 609
      --  Analyze actions generated by freezing. The init_proc contains source
      --  expressions that may raise Constraint_Error, and the assignment
      --  procedure for complex types needs checks on individual component
      --  assignments, but all other freezing actions should be compiled with
      --  all checks off.
Richard Kenner committed
610 611 612 613 614

      if Present (Actions (N)) then
         Decl := First (Actions (N));
         while Present (Decl) loop
            if Nkind (Decl) = N_Subprogram_Body
615 616 617
              and then (Is_Init_Proc (Defining_Entity (Decl))
                          or else
                            Chars (Defining_Entity (Decl)) = Name_uAssign)
Richard Kenner committed
618 619 620 621 622 623 624 625 626 627 628
            then
               Analyze (Decl);

            --  A subprogram body created for a renaming_as_body completes
            --  a previous declaration, which may be in a different scope.
            --  Establish the proper scope before analysis.

            elsif Nkind (Decl) = N_Subprogram_Body
              and then Present (Corresponding_Spec (Decl))
              and then Scope (Corresponding_Spec (Decl)) /= Current_Scope
            then
629
               Push_Scope (Scope (Corresponding_Spec (Decl)));
Richard Kenner committed
630 631 632
               Analyze (Decl, Suppress => All_Checks);
               Pop_Scope;

Arnaud Charlet committed
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
            --  We treat generated equality specially, if validity checks are
            --  enabled, in order to detect components default-initialized
            --  with invalid values.

            elsif Nkind (Decl) = N_Subprogram_Body
              and then Chars (Defining_Entity (Decl)) = Name_Op_Eq
              and then Validity_Checks_On
              and then Initialize_Scalars
            then
               declare
                  Save_Force : constant Boolean := Force_Validity_Checks;
               begin
                  Force_Validity_Checks := True;
                  Analyze (Decl);
                  Force_Validity_Checks := Save_Force;
               end;

Arnaud Charlet committed
650
            --  All other freezing actions
Arnaud Charlet committed
651

Arnaud Charlet committed
652
            else
Richard Kenner committed
653 654 655 656 657 658 659
               Analyze (Decl, Suppress => All_Checks);
            end if;

            Next (Decl);
         end loop;
      end if;

660 661 662 663 664 665 666
      --  If we are to delete this N_Freeze_Entity, do so by rewriting so that
      --  a loop on all nodes being inserted will work propertly.

      if Delete then
         Rewrite (N, Make_Null_Statement (Sloc (N)));
      end if;

667
      --  Pop scope if we installed one for the analysis
668

Richard Kenner committed
669 670 671 672 673 674 675 676 677 678
      if In_Other_Scope then
         if Ekind (Current_Scope) = E_Package then
            End_Package_Scope (E_Scope);
         else
            End_Scope;
         end if;

      elsif In_Outer_Scope then
         Pop_Scope;
      end if;
679 680 681 682 683

      --  Restore previous value of the nesting-level counter that records
      --  whether we are inside a (possibly nested) call to this procedure.

      Inside_Freezing_Actions := Inside_Freezing_Actions - 1;
Arnaud Charlet committed
684
      Ghost_Mode := Save_Ghost_Mode;
Richard Kenner committed
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
   end Expand_N_Freeze_Entity;

   -------------------------------------------
   -- Expand_N_Record_Representation_Clause --
   -------------------------------------------

   --  The only expansion required is for the case of a mod clause present,
   --  which is removed, and translated into an alignment representation
   --  clause inserted immediately after the record rep clause with any
   --  initial pragmas inserted at the start of the component clause list.

   procedure Expand_N_Record_Representation_Clause (N : Node_Id) is
      Loc     : constant Source_Ptr := Sloc (N);
      Rectype : constant Entity_Id  := Entity (Identifier (N));
      Mod_Val : Uint;
      Citems  : List_Id;
      Repitem : Node_Id;
      AtM_Nod : Node_Id;

   begin
Arnaud Charlet committed
705
      if Present (Mod_Clause (N)) and then not Ignore_Rep_Clauses then
Richard Kenner committed
706 707 708 709 710 711 712 713 714 715
         Mod_Val := Expr_Value (Expression (Mod_Clause (N)));
         Citems  := Pragmas_Before (Mod_Clause (N));

         if Present (Citems) then
            Append_List_To (Citems, Component_Clauses (N));
            Set_Component_Clauses (N, Citems);
         end if;

         AtM_Nod :=
           Make_Attribute_Definition_Clause (Loc,
716
             Name       => New_Occurrence_Of (Base_Type (Rectype), Loc),
Richard Kenner committed
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
             Chars      => Name_Alignment,
             Expression => Make_Integer_Literal (Loc, Mod_Val));

         Set_From_At_Mod (AtM_Nod);
         Insert_After (N, AtM_Nod);
         Set_Mod_Clause (N, Empty);
      end if;

      --  If the record representation clause has no components, then
      --  completely remove it.  Note that we also have to remove
      --  ourself from the Rep Item list.

      if Is_Empty_List (Component_Clauses (N)) then
         if First_Rep_Item (Rectype) = N then
            Set_First_Rep_Item (Rectype, Next_Rep_Item (N));
         else
            Repitem := First_Rep_Item (Rectype);
            while Present (Next_Rep_Item (Repitem)) loop
               if Next_Rep_Item (Repitem) = N then
                  Set_Next_Rep_Item (Repitem, Next_Rep_Item (N));
                  exit;
               end if;

               Next_Rep_Item (Repitem);
            end loop;
         end if;

         Rewrite (N,
           Make_Null_Statement (Loc));
      end if;
   end Expand_N_Record_Representation_Clause;

end Exp_Ch13;