1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                              E X P _ C H 7                               --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1992-2018, 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
26--  This package contains virtually all expansion mechanisms related to
27--    - controlled types
28--    - transient scopes
29
30with Atree;    use Atree;
31with Debug;    use Debug;
32with Einfo;    use Einfo;
33with Elists;   use Elists;
34with Errout;   use Errout;
35with Exp_Ch6;  use Exp_Ch6;
36with Exp_Ch9;  use Exp_Ch9;
37with Exp_Ch11; use Exp_Ch11;
38with Exp_Dbug; use Exp_Dbug;
39with Exp_Dist; use Exp_Dist;
40with Exp_Disp; use Exp_Disp;
41with Exp_Prag; use Exp_Prag;
42with Exp_Tss;  use Exp_Tss;
43with Exp_Util; use Exp_Util;
44with Freeze;   use Freeze;
45with Lib;      use Lib;
46with Nlists;   use Nlists;
47with Nmake;    use Nmake;
48with Opt;      use Opt;
49with Output;   use Output;
50with Restrict; use Restrict;
51with Rident;   use Rident;
52with Rtsfind;  use Rtsfind;
53with Sinfo;    use Sinfo;
54with Sem;      use Sem;
55with Sem_Aux;  use Sem_Aux;
56with Sem_Ch3;  use Sem_Ch3;
57with Sem_Ch7;  use Sem_Ch7;
58with Sem_Ch8;  use Sem_Ch8;
59with Sem_Res;  use Sem_Res;
60with Sem_Util; use Sem_Util;
61with Snames;   use Snames;
62with Stand;    use Stand;
63with Tbuild;   use Tbuild;
64with Ttypes;   use Ttypes;
65with Uintp;    use Uintp;
66
67package body Exp_Ch7 is
68
69   --------------------------------
70   -- Transient Scope Management --
71   --------------------------------
72
73   --  A transient scope is created when temporary objects are created by the
74   --  compiler. These temporary objects are allocated on the secondary stack
75   --  and the transient scope is responsible for finalizing the object when
76   --  appropriate and reclaiming the memory at the right time. The temporary
77   --  objects are generally the objects allocated to store the result of a
78   --  function returning an unconstrained or a tagged value. Expressions
79   --  needing to be wrapped in a transient scope (functions calls returning
80   --  unconstrained or tagged values) may appear in 3 different contexts which
81   --  lead to 3 different kinds of transient scope expansion:
82
83   --   1. In a simple statement (procedure call, assignment, ...). In this
84   --      case the instruction is wrapped into a transient block. See
85   --      Wrap_Transient_Statement for details.
86
87   --   2. In an expression of a control structure (test in a IF statement,
88   --      expression in a CASE statement, ...). See Wrap_Transient_Expression
89   --      for details.
90
91   --   3. In a expression of an object_declaration. No wrapping is possible
92   --      here, so the finalization actions, if any, are done right after the
93   --      declaration and the secondary stack deallocation is done in the
94   --      proper enclosing scope. See Wrap_Transient_Declaration for details.
95
96   --  Note about functions returning tagged types: it has been decided to
97   --  always allocate their result in the secondary stack, even though is not
98   --  absolutely mandatory when the tagged type is constrained because the
99   --  caller knows the size of the returned object and thus could allocate the
100   --  result in the primary stack. An exception to this is when the function
101   --  builds its result in place, as is done for functions with inherently
102   --  limited result types for Ada 2005. In that case, certain callers may
103   --  pass the address of a constrained object as the target object for the
104   --  function result.
105
106   --  By allocating tagged results in the secondary stack a number of
107   --  implementation difficulties are avoided:
108
109   --    - If it is a dispatching function call, the computation of the size of
110   --      the result is possible but complex from the outside.
111
112   --    - If the returned type is controlled, the assignment of the returned
113   --      value to the anonymous object involves an Adjust, and we have no
114   --      easy way to access the anonymous object created by the back end.
115
116   --    - If the returned type is class-wide, this is an unconstrained type
117   --      anyway.
118
119   --  Furthermore, the small loss in efficiency which is the result of this
120   --  decision is not such a big deal because functions returning tagged types
121   --  are not as common in practice compared to functions returning access to
122   --  a tagged type.
123
124   --------------------------------------------------
125   -- Transient Blocks and Finalization Management --
126   --------------------------------------------------
127
128   function Find_Node_To_Be_Wrapped (N : Node_Id) return Node_Id;
129   --  N is a node which may generate a transient scope. Loop over the parent
130   --  pointers of N until we find the appropriate node to wrap. If it returns
131   --  Empty, it means that no transient scope is needed in this context.
132
133   procedure Insert_Actions_In_Scope_Around
134     (N         : Node_Id;
135      Clean     : Boolean;
136      Manage_SS : Boolean);
137   --  Insert the before-actions kept in the scope stack before N, and the
138   --  after-actions after N, which must be a member of a list. If flag Clean
139   --  is set, insert any cleanup actions. If flag Manage_SS is set, insert
140   --  calls to mark and release the secondary stack.
141
142   function Make_Transient_Block
143     (Loc    : Source_Ptr;
144      Action : Node_Id;
145      Par    : Node_Id) return Node_Id;
146   --  Action is a single statement or object declaration. Par is the proper
147   --  parent of the generated block. Create a transient block whose name is
148   --  the current scope and the only handled statement is Action. If Action
149   --  involves controlled objects or secondary stack usage, the corresponding
150   --  cleanup actions are performed at the end of the block.
151
152   procedure Set_Node_To_Be_Wrapped (N : Node_Id);
153   --  Set the field Node_To_Be_Wrapped of the current scope
154
155   --  ??? The entire comment needs to be rewritten
156   --  ??? which entire comment?
157
158   procedure Store_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id);
159   --  Shared processing for Store_xxx_Actions_In_Scope
160
161   -----------------------------
162   -- Finalization Management --
163   -----------------------------
164
165   --  This part describe how Initialization/Adjustment/Finalization procedures
166   --  are generated and called. Two cases must be considered, types that are
167   --  Controlled (Is_Controlled flag set) and composite types that contain
168   --  controlled components (Has_Controlled_Component flag set). In the first
169   --  case the procedures to call are the user-defined primitive operations
170   --  Initialize/Adjust/Finalize. In the second case, GNAT generates
171   --  Deep_Initialize, Deep_Adjust and Deep_Finalize that are in charge
172   --  of calling the former procedures on the controlled components.
173
174   --  For records with Has_Controlled_Component set, a hidden "controller"
175   --  component is inserted. This controller component contains its own
176   --  finalization list on which all controlled components are attached
177   --  creating an indirection on the upper-level Finalization list. This
178   --  technique facilitates the management of objects whose number of
179   --  controlled components changes during execution. This controller
180   --  component is itself controlled and is attached to the upper-level
181   --  finalization chain. Its adjust primitive is in charge of calling adjust
182   --  on the components and adjusting the finalization pointer to match their
183   --  new location (see a-finali.adb).
184
185   --  It is not possible to use a similar technique for arrays that have
186   --  Has_Controlled_Component set. In this case, deep procedures are
187   --  generated that call initialize/adjust/finalize + attachment or
188   --  detachment on the finalization list for all component.
189
190   --  Initialize calls: they are generated for declarations or dynamic
191   --  allocations of Controlled objects with no initial value. They are always
192   --  followed by an attachment to the current Finalization Chain. For the
193   --  dynamic allocation case this the chain attached to the scope of the
194   --  access type definition otherwise, this is the chain of the current
195   --  scope.
196
197   --  Adjust Calls: They are generated on 2 occasions: (1) for declarations
198   --  or dynamic allocations of Controlled objects with an initial value.
199   --  (2) after an assignment. In the first case they are followed by an
200   --  attachment to the final chain, in the second case they are not.
201
202   --  Finalization Calls: They are generated on (1) scope exit, (2)
203   --  assignments, (3) unchecked deallocations. In case (3) they have to
204   --  be detached from the final chain, in case (2) they must not and in
205   --  case (1) this is not important since we are exiting the scope anyway.
206
207   --  Other details:
208
209   --    Type extensions will have a new record controller at each derivation
210   --    level containing controlled components. The record controller for
211   --    the parent/ancestor is attached to the finalization list of the
212   --    extension's record controller (i.e. the parent is like a component
213   --    of the extension).
214
215   --    For types that are both Is_Controlled and Has_Controlled_Components,
216   --    the record controller and the object itself are handled separately.
217   --    It could seem simpler to attach the object at the end of its record
218   --    controller but this would not tackle view conversions properly.
219
220   --    A classwide type can always potentially have controlled components
221   --    but the record controller of the corresponding actual type may not
222   --    be known at compile time so the dispatch table contains a special
223   --    field that allows computation of the offset of the record controller
224   --    dynamically. See s-finimp.Deep_Tag_Attach and a-tags.RC_Offset.
225
226   --  Here is a simple example of the expansion of a controlled block :
227
228   --    declare
229   --       X : Controlled;
230   --       Y : Controlled := Init;
231   --
232   --       type R is record
233   --          C : Controlled;
234   --       end record;
235   --       W : R;
236   --       Z : R := (C => X);
237
238   --    begin
239   --       X := Y;
240   --       W := Z;
241   --    end;
242   --
243   --  is expanded into
244   --
245   --    declare
246   --       _L : System.FI.Finalizable_Ptr;
247
248   --       procedure _Clean is
249   --       begin
250   --          Abort_Defer;
251   --          System.FI.Finalize_List (_L);
252   --          Abort_Undefer;
253   --       end _Clean;
254
255   --       X : Controlled;
256   --       begin
257   --          Abort_Defer;
258   --          Initialize (X);
259   --          Attach_To_Final_List (_L, Finalizable (X), 1);
260   --       at end: Abort_Undefer;
261   --       Y : Controlled := Init;
262   --       Adjust (Y);
263   --       Attach_To_Final_List (_L, Finalizable (Y), 1);
264   --
265   --       type R is record
266   --          C : Controlled;
267   --       end record;
268   --       W : R;
269   --       begin
270   --          Abort_Defer;
271   --          Deep_Initialize (W, _L, 1);
272   --       at end: Abort_Under;
273   --       Z : R := (C => X);
274   --       Deep_Adjust (Z, _L, 1);
275
276   --    begin
277   --       _Assign (X, Y);
278   --       Deep_Finalize (W, False);
279   --       <save W's final pointers>
280   --       W := Z;
281   --       <restore W's final pointers>
282   --       Deep_Adjust (W, _L, 0);
283   --    at end
284   --       _Clean;
285   --    end;
286
287   type Final_Primitives is
288     (Initialize_Case, Adjust_Case, Finalize_Case, Address_Case);
289   --  This enumeration type is defined in order to ease sharing code for
290   --  building finalization procedures for composite types.
291
292   Name_Of      : constant array (Final_Primitives) of Name_Id :=
293                    (Initialize_Case => Name_Initialize,
294                     Adjust_Case     => Name_Adjust,
295                     Finalize_Case   => Name_Finalize,
296                     Address_Case    => Name_Finalize_Address);
297   Deep_Name_Of : constant array (Final_Primitives) of TSS_Name_Type :=
298                    (Initialize_Case => TSS_Deep_Initialize,
299                     Adjust_Case     => TSS_Deep_Adjust,
300                     Finalize_Case   => TSS_Deep_Finalize,
301                     Address_Case    => TSS_Finalize_Address);
302
303   function Allows_Finalization_Master (Typ : Entity_Id) return Boolean;
304   --  Determine whether access type Typ may have a finalization master
305
306   procedure Build_Array_Deep_Procs (Typ : Entity_Id);
307   --  Build the deep Initialize/Adjust/Finalize for a record Typ with
308   --  Has_Controlled_Component set and store them using the TSS mechanism.
309
310   function Build_Cleanup_Statements
311     (N                  : Node_Id;
312      Additional_Cleanup : List_Id) return List_Id;
313   --  Create the cleanup calls for an asynchronous call block, task master,
314   --  protected subprogram body, task allocation block or task body, or
315   --  additional cleanup actions parked on a transient block. If the context
316   --  does not contain the above constructs, the routine returns an empty
317   --  list.
318
319   procedure Build_Finalizer
320     (N           : Node_Id;
321      Clean_Stmts : List_Id;
322      Mark_Id     : Entity_Id;
323      Top_Decls   : List_Id;
324      Defer_Abort : Boolean;
325      Fin_Id      : out Entity_Id);
326   --  N may denote an accept statement, block, entry body, package body,
327   --  package spec, protected body, subprogram body, or a task body. Create
328   --  a procedure which contains finalization calls for all controlled objects
329   --  declared in the declarative or statement region of N. The calls are
330   --  built in reverse order relative to the original declarations. In the
331   --  case of a task body, the routine delays the creation of the finalizer
332   --  until all statements have been moved to the task body procedure.
333   --  Clean_Stmts may contain additional context-dependent code used to abort
334   --  asynchronous calls or complete tasks (see Build_Cleanup_Statements).
335   --  Mark_Id is the secondary stack used in the current context or Empty if
336   --  missing. Top_Decls is the list on which the declaration of the finalizer
337   --  is attached in the non-package case. Defer_Abort indicates that the
338   --  statements passed in perform actions that require abort to be deferred,
339   --  such as for task termination. Fin_Id is the finalizer declaration
340   --  entity.
341
342   procedure Build_Finalizer_Call (N : Node_Id; Fin_Id : Entity_Id);
343   --  N is a construct which contains a handled sequence of statements, Fin_Id
344   --  is the entity of a finalizer. Create an At_End handler which covers the
345   --  statements of N and calls Fin_Id. If the handled statement sequence has
346   --  an exception handler, the statements will be wrapped in a block to avoid
347   --  unwanted interaction with the new At_End handler.
348
349   procedure Build_Record_Deep_Procs (Typ : Entity_Id);
350   --  Build the deep Initialize/Adjust/Finalize for a record Typ with
351   --  Has_Component_Component set and store them using the TSS mechanism.
352
353   procedure Check_Visibly_Controlled
354     (Prim : Final_Primitives;
355      Typ  : Entity_Id;
356      E    : in out Entity_Id;
357      Cref : in out Node_Id);
358   --  The controlled operation declared for a derived type may not be
359   --  overriding, if the controlled operations of the parent type are hidden,
360   --  for example when the parent is a private type whose full view is
361   --  controlled. For other primitive operations we modify the name of the
362   --  operation to indicate that it is not overriding, but this is not
363   --  possible for Initialize, etc. because they have to be retrievable by
364   --  name. Before generating the proper call to one of these operations we
365   --  check whether Typ is known to be controlled at the point of definition.
366   --  If it is not then we must retrieve the hidden operation of the parent
367   --  and use it instead.  This is one case that might be solved more cleanly
368   --  once Overriding pragmas or declarations are in place.
369
370   function Convert_View
371     (Proc : Entity_Id;
372      Arg  : Node_Id;
373      Ind  : Pos := 1) return Node_Id;
374   --  Proc is one of the Initialize/Adjust/Finalize operations, and Arg is the
375   --  argument being passed to it. Ind indicates which formal of procedure
376   --  Proc we are trying to match. This function will, if necessary, generate
377   --  a conversion between the partial and full view of Arg to match the type
378   --  of the formal of Proc, or force a conversion to the class-wide type in
379   --  the case where the operation is abstract.
380
381   function Enclosing_Function (E : Entity_Id) return Entity_Id;
382   --  Given an arbitrary entity, traverse the scope chain looking for the
383   --  first enclosing function. Return Empty if no function was found.
384
385   function Make_Call
386     (Loc       : Source_Ptr;
387      Proc_Id   : Entity_Id;
388      Param     : Node_Id;
389      Skip_Self : Boolean := False) return Node_Id;
390   --  Subsidiary to Make_Adjust_Call and Make_Final_Call. Given the entity of
391   --  routine [Deep_]Adjust or [Deep_]Finalize and an object parameter, create
392   --  an adjust or finalization call. Wnen flag Skip_Self is set, the related
393   --  action has an effect on the components only (if any).
394
395   function Make_Deep_Proc
396     (Prim  : Final_Primitives;
397      Typ   : Entity_Id;
398      Stmts : List_Id) return Node_Id;
399   --  This function generates the tree for Deep_Initialize, Deep_Adjust or
400   --  Deep_Finalize procedures according to the first parameter, these
401   --  procedures operate on the type Typ. The Stmts parameter gives the body
402   --  of the procedure.
403
404   function Make_Deep_Array_Body
405     (Prim : Final_Primitives;
406      Typ  : Entity_Id) return List_Id;
407   --  This function generates the list of statements for implementing
408   --  Deep_Initialize, Deep_Adjust or Deep_Finalize procedures according to
409   --  the first parameter, these procedures operate on the array type Typ.
410
411   function Make_Deep_Record_Body
412     (Prim     : Final_Primitives;
413      Typ      : Entity_Id;
414      Is_Local : Boolean := False) return List_Id;
415   --  This function generates the list of statements for implementing
416   --  Deep_Initialize, Deep_Adjust or Deep_Finalize procedures according to
417   --  the first parameter, these procedures operate on the record type Typ.
418   --  Flag Is_Local is used in conjunction with Deep_Finalize to designate
419   --  whether the inner logic should be dictated by state counters.
420
421   function Make_Finalize_Address_Stmts (Typ : Entity_Id) return List_Id;
422   --  Subsidiary to Make_Finalize_Address_Body, Make_Deep_Array_Body and
423   --  Make_Deep_Record_Body. Generate the following statements:
424   --
425   --    declare
426   --       type Acc_Typ is access all Typ;
427   --       for Acc_Typ'Storage_Size use 0;
428   --    begin
429   --       [Deep_]Finalize (Acc_Typ (V).all);
430   --    end;
431
432   --------------------------------
433   -- Allows_Finalization_Master --
434   --------------------------------
435
436   function Allows_Finalization_Master (Typ : Entity_Id) return Boolean is
437      function In_Deallocation_Instance (E : Entity_Id) return Boolean;
438      --  Determine whether entity E is inside a wrapper package created for
439      --  an instance of Ada.Unchecked_Deallocation.
440
441      ------------------------------
442      -- In_Deallocation_Instance --
443      ------------------------------
444
445      function In_Deallocation_Instance (E : Entity_Id) return Boolean is
446         Pkg : constant Entity_Id := Scope (E);
447         Par : Node_Id := Empty;
448
449      begin
450         if Ekind (Pkg) = E_Package
451           and then Present (Related_Instance (Pkg))
452           and then Ekind (Related_Instance (Pkg)) = E_Procedure
453         then
454            Par := Generic_Parent (Parent (Related_Instance (Pkg)));
455
456            return
457              Present (Par)
458                and then Chars (Par) = Name_Unchecked_Deallocation
459                and then Chars (Scope (Par)) = Name_Ada
460                and then Scope (Scope (Par)) = Standard_Standard;
461         end if;
462
463         return False;
464      end In_Deallocation_Instance;
465
466      --  Local variables
467
468      Desig_Typ : constant Entity_Id := Designated_Type (Typ);
469      Ptr_Typ   : constant Entity_Id :=
470                    Root_Type_Of_Full_View (Base_Type (Typ));
471
472   --  Start of processing for Allows_Finalization_Master
473
474   begin
475      --  Certain run-time configurations and targets do not provide support
476      --  for controlled types and therefore do not need masters.
477
478      if Restriction_Active (No_Finalization) then
479         return False;
480
481      --  Do not consider C and C++ types since it is assumed that the non-Ada
482      --  side will handle their cleanup.
483
484      elsif Convention (Desig_Typ) = Convention_C
485        or else Convention (Desig_Typ) = Convention_CPP
486      then
487         return False;
488
489      --  Do not consider an access type that returns on the secondary stack
490
491      elsif Present (Associated_Storage_Pool (Ptr_Typ))
492        and then Is_RTE (Associated_Storage_Pool (Ptr_Typ), RE_SS_Pool)
493      then
494         return False;
495
496      --  Do not consider an access type that can never allocate an object
497
498      elsif No_Pool_Assigned (Ptr_Typ) then
499         return False;
500
501      --  Do not consider an access type coming from an Unchecked_Deallocation
502      --  instance. Even though the designated type may be controlled, the
503      --  access type will never participate in any allocations.
504
505      elsif In_Deallocation_Instance (Ptr_Typ) then
506         return False;
507
508      --  Do not consider a non-library access type when No_Nested_Finalization
509      --  is in effect since finalization masters are controlled objects and if
510      --  created will violate the restriction.
511
512      elsif Restriction_Active (No_Nested_Finalization)
513        and then not Is_Library_Level_Entity (Ptr_Typ)
514      then
515         return False;
516
517      --  Do not consider an access type subject to pragma No_Heap_Finalization
518      --  because objects allocated through such a type are not to be finalized
519      --  when the access type goes out of scope.
520
521      elsif No_Heap_Finalization (Ptr_Typ) then
522         return False;
523
524      --  Do not create finalization masters in GNATprove mode because this
525      --  causes unwanted extra expansion. A compilation in this mode must
526      --  keep the tree as close as possible to the original sources.
527
528      elsif GNATprove_Mode then
529         return False;
530
531      --  Otherwise the access type may use a finalization master
532
533      else
534         return True;
535      end if;
536   end Allows_Finalization_Master;
537
538   ----------------------------
539   -- Build_Anonymous_Master --
540   ----------------------------
541
542   procedure Build_Anonymous_Master (Ptr_Typ : Entity_Id) is
543      function Create_Anonymous_Master
544        (Desig_Typ : Entity_Id;
545         Unit_Id   : Entity_Id;
546         Unit_Decl : Node_Id) return Entity_Id;
547      --  Create a new anonymous master for access type Ptr_Typ with designated
548      --  type Desig_Typ. The declaration of the master and its initialization
549      --  are inserted in the declarative part of unit Unit_Decl. Unit_Id is
550      --  the entity of Unit_Decl.
551
552      function Current_Anonymous_Master
553        (Desig_Typ : Entity_Id;
554         Unit_Id   : Entity_Id) return Entity_Id;
555      --  Find an anonymous master declared within unit Unit_Id which services
556      --  designated type Desig_Typ. If there is no such master, return Empty.
557
558      -----------------------------
559      -- Create_Anonymous_Master --
560      -----------------------------
561
562      function Create_Anonymous_Master
563        (Desig_Typ : Entity_Id;
564         Unit_Id   : Entity_Id;
565         Unit_Decl : Node_Id) return Entity_Id
566      is
567         Loc : constant Source_Ptr := Sloc (Unit_Id);
568
569         All_FMs   : Elist_Id;
570         Decls     : List_Id;
571         FM_Decl   : Node_Id;
572         FM_Id     : Entity_Id;
573         FM_Init   : Node_Id;
574         Unit_Spec : Node_Id;
575
576      begin
577         --  Generate:
578         --    <FM_Id> : Finalization_Master;
579
580         FM_Id := Make_Temporary (Loc, 'A');
581
582         FM_Decl :=
583           Make_Object_Declaration (Loc,
584             Defining_Identifier => FM_Id,
585             Object_Definition   =>
586               New_Occurrence_Of (RTE (RE_Finalization_Master), Loc));
587
588         --  Generate:
589         --    Set_Base_Pool
590         --      (<FM_Id>, Global_Pool_Object'Unrestricted_Access);
591
592         FM_Init :=
593           Make_Procedure_Call_Statement (Loc,
594             Name                   =>
595               New_Occurrence_Of (RTE (RE_Set_Base_Pool), Loc),
596             Parameter_Associations => New_List (
597               New_Occurrence_Of (FM_Id, Loc),
598               Make_Attribute_Reference (Loc,
599                 Prefix         =>
600                   New_Occurrence_Of (RTE (RE_Global_Pool_Object), Loc),
601                 Attribute_Name => Name_Unrestricted_Access)));
602
603         --  Find the declarative list of the unit
604
605         if Nkind (Unit_Decl) = N_Package_Declaration then
606            Unit_Spec := Specification (Unit_Decl);
607            Decls     := Visible_Declarations (Unit_Spec);
608
609            if No (Decls) then
610               Decls := New_List;
611               Set_Visible_Declarations (Unit_Spec, Decls);
612            end if;
613
614         --  Package body or subprogram case
615
616         --  ??? A subprogram spec or body that acts as a compilation unit may
617         --  contain a formal parameter of an anonymous access-to-controlled
618         --  type initialized by an allocator.
619
620         --    procedure Comp_Unit_Proc (Param : access Ctrl := new Ctrl);
621
622         --  There is no suitable place to create the master as the subprogram
623         --  is not in a declarative list.
624
625         else
626            Decls := Declarations (Unit_Decl);
627
628            if No (Decls) then
629               Decls := New_List;
630               Set_Declarations (Unit_Decl, Decls);
631            end if;
632         end if;
633
634         Prepend_To (Decls, FM_Init);
635         Prepend_To (Decls, FM_Decl);
636
637         --  Use the scope of the unit when analyzing the declaration of the
638         --  master and its initialization actions.
639
640         Push_Scope (Unit_Id);
641         Analyze (FM_Decl);
642         Analyze (FM_Init);
643         Pop_Scope;
644
645         --  Mark the master as servicing this specific designated type
646
647         Set_Anonymous_Designated_Type (FM_Id, Desig_Typ);
648
649         --  Include the anonymous master in the list of existing masters which
650         --  appear in this unit. This effectively creates a mapping between a
651         --  master and a designated type which in turn allows for the reuse of
652         --  masters on a per-unit basis.
653
654         All_FMs := Anonymous_Masters (Unit_Id);
655
656         if No (All_FMs) then
657            All_FMs := New_Elmt_List;
658            Set_Anonymous_Masters (Unit_Id, All_FMs);
659         end if;
660
661         Prepend_Elmt (FM_Id, All_FMs);
662
663         return FM_Id;
664      end Create_Anonymous_Master;
665
666      ------------------------------
667      -- Current_Anonymous_Master --
668      ------------------------------
669
670      function Current_Anonymous_Master
671        (Desig_Typ : Entity_Id;
672         Unit_Id   : Entity_Id) return Entity_Id
673      is
674         All_FMs : constant Elist_Id := Anonymous_Masters (Unit_Id);
675         FM_Elmt : Elmt_Id;
676         FM_Id   : Entity_Id;
677
678      begin
679         --  Inspect the list of anonymous masters declared within the unit
680         --  looking for an existing master which services the same designated
681         --  type.
682
683         if Present (All_FMs) then
684            FM_Elmt := First_Elmt (All_FMs);
685            while Present (FM_Elmt) loop
686               FM_Id := Node (FM_Elmt);
687
688               --  The currect master services the same designated type. As a
689               --  result the master can be reused and associated with another
690               --  anonymous access-to-controlled type.
691
692               if Anonymous_Designated_Type (FM_Id) = Desig_Typ then
693                  return FM_Id;
694               end if;
695
696               Next_Elmt (FM_Elmt);
697            end loop;
698         end if;
699
700         return Empty;
701      end Current_Anonymous_Master;
702
703      --  Local variables
704
705      Desig_Typ : Entity_Id;
706      FM_Id     : Entity_Id;
707      Priv_View : Entity_Id;
708      Unit_Decl : Node_Id;
709      Unit_Id   : Entity_Id;
710
711   --  Start of processing for Build_Anonymous_Master
712
713   begin
714      --  Nothing to do if the circumstances do not allow for a finalization
715      --  master.
716
717      if not Allows_Finalization_Master (Ptr_Typ) then
718         return;
719      end if;
720
721      Unit_Decl := Unit (Cunit (Current_Sem_Unit));
722      Unit_Id   := Unique_Defining_Entity (Unit_Decl);
723
724      --  The compilation unit is a package instantiation. In this case the
725      --  anonymous master is associated with the package spec as both the
726      --  spec and body appear at the same level.
727
728      if Nkind (Unit_Decl) = N_Package_Body
729        and then Nkind (Original_Node (Unit_Decl)) = N_Package_Instantiation
730      then
731         Unit_Id   := Corresponding_Spec (Unit_Decl);
732         Unit_Decl := Unit_Declaration_Node (Unit_Id);
733      end if;
734
735      --  Use the initial declaration of the designated type when it denotes
736      --  the full view of an incomplete or private type. This ensures that
737      --  types with one and two views are treated the same.
738
739      Desig_Typ := Directly_Designated_Type (Ptr_Typ);
740      Priv_View := Incomplete_Or_Partial_View (Desig_Typ);
741
742      if Present (Priv_View) then
743         Desig_Typ := Priv_View;
744      end if;
745
746      --  Determine whether the current semantic unit already has an anonymous
747      --  master which services the designated type.
748
749      FM_Id := Current_Anonymous_Master (Desig_Typ, Unit_Id);
750
751      --  If this is not the case, create a new master
752
753      if No (FM_Id) then
754         FM_Id := Create_Anonymous_Master (Desig_Typ, Unit_Id, Unit_Decl);
755      end if;
756
757      Set_Finalization_Master (Ptr_Typ, FM_Id);
758   end Build_Anonymous_Master;
759
760   ----------------------------
761   -- Build_Array_Deep_Procs --
762   ----------------------------
763
764   procedure Build_Array_Deep_Procs (Typ : Entity_Id) is
765   begin
766      Set_TSS (Typ,
767        Make_Deep_Proc
768          (Prim  => Initialize_Case,
769           Typ   => Typ,
770           Stmts => Make_Deep_Array_Body (Initialize_Case, Typ)));
771
772      if not Is_Limited_View (Typ) then
773         Set_TSS (Typ,
774           Make_Deep_Proc
775             (Prim  => Adjust_Case,
776              Typ   => Typ,
777              Stmts => Make_Deep_Array_Body (Adjust_Case, Typ)));
778      end if;
779
780      --  Do not generate Deep_Finalize and Finalize_Address if finalization is
781      --  suppressed since these routine will not be used.
782
783      if not Restriction_Active (No_Finalization) then
784         Set_TSS (Typ,
785           Make_Deep_Proc
786             (Prim  => Finalize_Case,
787              Typ   => Typ,
788              Stmts => Make_Deep_Array_Body (Finalize_Case, Typ)));
789
790         --  Create TSS primitive Finalize_Address (unless CodePeer_Mode)
791
792         if not CodePeer_Mode then
793            Set_TSS (Typ,
794              Make_Deep_Proc
795                (Prim  => Address_Case,
796                 Typ   => Typ,
797                 Stmts => Make_Deep_Array_Body (Address_Case, Typ)));
798         end if;
799      end if;
800   end Build_Array_Deep_Procs;
801
802   ------------------------------
803   -- Build_Cleanup_Statements --
804   ------------------------------
805
806   function Build_Cleanup_Statements
807     (N                  : Node_Id;
808      Additional_Cleanup : List_Id) return List_Id
809   is
810      Is_Asynchronous_Call : constant Boolean :=
811                               Nkind (N) = N_Block_Statement
812                                 and then Is_Asynchronous_Call_Block (N);
813      Is_Master            : constant Boolean :=
814                               Nkind (N) /= N_Entry_Body
815                                 and then Is_Task_Master (N);
816      Is_Protected_Body    : constant Boolean :=
817                               Nkind (N) = N_Subprogram_Body
818                                 and then Is_Protected_Subprogram_Body (N);
819      Is_Task_Allocation   : constant Boolean :=
820                               Nkind (N) = N_Block_Statement
821                                 and then Is_Task_Allocation_Block (N);
822      Is_Task_Body         : constant Boolean :=
823                               Nkind (Original_Node (N)) = N_Task_Body;
824
825      Loc   : constant Source_Ptr := Sloc (N);
826      Stmts : constant List_Id    := New_List;
827
828   begin
829      if Is_Task_Body then
830         if Restricted_Profile then
831            Append_To (Stmts,
832              Build_Runtime_Call (Loc, RE_Complete_Restricted_Task));
833         else
834            Append_To (Stmts, Build_Runtime_Call (Loc, RE_Complete_Task));
835         end if;
836
837      elsif Is_Master then
838         if Restriction_Active (No_Task_Hierarchy) = False then
839            Append_To (Stmts, Build_Runtime_Call (Loc, RE_Complete_Master));
840         end if;
841
842      --  Add statements to unlock the protected object parameter and to
843      --  undefer abort. If the context is a protected procedure and the object
844      --  has entries, call the entry service routine.
845
846      --  NOTE: The generated code references _object, a parameter to the
847      --  procedure.
848
849      elsif Is_Protected_Body then
850         declare
851            Spec      : constant Node_Id := Parent (Corresponding_Spec (N));
852            Conc_Typ  : Entity_Id;
853            Param     : Node_Id;
854            Param_Typ : Entity_Id;
855
856         begin
857            --  Find the _object parameter representing the protected object
858
859            Param := First (Parameter_Specifications (Spec));
860            loop
861               Param_Typ := Etype (Parameter_Type (Param));
862
863               if Ekind (Param_Typ) = E_Record_Type then
864                  Conc_Typ := Corresponding_Concurrent_Type (Param_Typ);
865               end if;
866
867               exit when No (Param) or else Present (Conc_Typ);
868               Next (Param);
869            end loop;
870
871            pragma Assert (Present (Param));
872
873            --  Historical note: In earlier versions of GNAT, there was code
874            --  at this point to generate stuff to service entry queues. It is
875            --  now abstracted in Build_Protected_Subprogram_Call_Cleanup.
876
877            Build_Protected_Subprogram_Call_Cleanup
878              (Specification (N), Conc_Typ, Loc, Stmts);
879         end;
880
881      --  Add a call to Expunge_Unactivated_Tasks for dynamically allocated
882      --  tasks. Other unactivated tasks are completed by Complete_Task or
883      --  Complete_Master.
884
885      --  NOTE: The generated code references _chain, a local object
886
887      elsif Is_Task_Allocation then
888
889         --  Generate:
890         --     Expunge_Unactivated_Tasks (_chain);
891
892         --  where _chain is the list of tasks created by the allocator but not
893         --  yet activated. This list will be empty unless the block completes
894         --  abnormally.
895
896         Append_To (Stmts,
897           Make_Procedure_Call_Statement (Loc,
898             Name =>
899               New_Occurrence_Of
900                 (RTE (RE_Expunge_Unactivated_Tasks), Loc),
901             Parameter_Associations => New_List (
902               New_Occurrence_Of (Activation_Chain_Entity (N), Loc))));
903
904      --  Attempt to cancel an asynchronous entry call whenever the block which
905      --  contains the abortable part is exited.
906
907      --  NOTE: The generated code references Cnn, a local object
908
909      elsif Is_Asynchronous_Call then
910         declare
911            Cancel_Param : constant Entity_Id :=
912                             Entry_Cancel_Parameter (Entity (Identifier (N)));
913
914         begin
915            --  If it is of type Communication_Block, this must be a protected
916            --  entry call. Generate:
917
918            --    if Enqueued (Cancel_Param) then
919            --       Cancel_Protected_Entry_Call (Cancel_Param);
920            --    end if;
921
922            if Is_RTE (Etype (Cancel_Param), RE_Communication_Block) then
923               Append_To (Stmts,
924                 Make_If_Statement (Loc,
925                   Condition =>
926                     Make_Function_Call (Loc,
927                       Name                   =>
928                         New_Occurrence_Of (RTE (RE_Enqueued), Loc),
929                       Parameter_Associations => New_List (
930                         New_Occurrence_Of (Cancel_Param, Loc))),
931
932                   Then_Statements => New_List (
933                     Make_Procedure_Call_Statement (Loc,
934                       Name =>
935                         New_Occurrence_Of
936                           (RTE (RE_Cancel_Protected_Entry_Call), Loc),
937                         Parameter_Associations => New_List (
938                           New_Occurrence_Of (Cancel_Param, Loc))))));
939
940            --  Asynchronous delay, generate:
941            --    Cancel_Async_Delay (Cancel_Param);
942
943            elsif Is_RTE (Etype (Cancel_Param), RE_Delay_Block) then
944               Append_To (Stmts,
945                 Make_Procedure_Call_Statement (Loc,
946                   Name                   =>
947                     New_Occurrence_Of (RTE (RE_Cancel_Async_Delay), Loc),
948                   Parameter_Associations => New_List (
949                     Make_Attribute_Reference (Loc,
950                       Prefix         =>
951                         New_Occurrence_Of (Cancel_Param, Loc),
952                       Attribute_Name => Name_Unchecked_Access))));
953
954            --  Task entry call, generate:
955            --    Cancel_Task_Entry_Call (Cancel_Param);
956
957            else
958               Append_To (Stmts,
959                 Make_Procedure_Call_Statement (Loc,
960                   Name                   =>
961                     New_Occurrence_Of (RTE (RE_Cancel_Task_Entry_Call), Loc),
962                   Parameter_Associations => New_List (
963                     New_Occurrence_Of (Cancel_Param, Loc))));
964            end if;
965         end;
966      end if;
967
968      Append_List_To (Stmts, Additional_Cleanup);
969      return Stmts;
970   end Build_Cleanup_Statements;
971
972   -----------------------------
973   -- Build_Controlling_Procs --
974   -----------------------------
975
976   procedure Build_Controlling_Procs (Typ : Entity_Id) is
977   begin
978      if Is_Array_Type (Typ) then
979         Build_Array_Deep_Procs (Typ);
980      else pragma Assert (Is_Record_Type (Typ));
981         Build_Record_Deep_Procs (Typ);
982      end if;
983   end Build_Controlling_Procs;
984
985   -----------------------------
986   -- Build_Exception_Handler --
987   -----------------------------
988
989   function Build_Exception_Handler
990     (Data        : Finalization_Exception_Data;
991      For_Library : Boolean := False) return Node_Id
992   is
993      Actuals      : List_Id;
994      Proc_To_Call : Entity_Id;
995      Except       : Node_Id;
996      Stmts        : List_Id;
997
998   begin
999      pragma Assert (Present (Data.Raised_Id));
1000
1001      if Exception_Extra_Info
1002        or else (For_Library and not Restricted_Profile)
1003      then
1004         if Exception_Extra_Info then
1005
1006            --  Generate:
1007
1008            --    Get_Current_Excep.all
1009
1010            Except :=
1011              Make_Function_Call (Data.Loc,
1012                Name =>
1013                  Make_Explicit_Dereference (Data.Loc,
1014                    Prefix =>
1015                      New_Occurrence_Of
1016                        (RTE (RE_Get_Current_Excep), Data.Loc)));
1017
1018         else
1019            --  Generate:
1020
1021            --    null
1022
1023            Except := Make_Null (Data.Loc);
1024         end if;
1025
1026         if For_Library and then not Restricted_Profile then
1027            Proc_To_Call := RTE (RE_Save_Library_Occurrence);
1028            Actuals := New_List (Except);
1029
1030         else
1031            Proc_To_Call := RTE (RE_Save_Occurrence);
1032
1033            --  The dereference occurs only when Exception_Extra_Info is true,
1034            --  and therefore Except is not null.
1035
1036            Actuals :=
1037              New_List (
1038                New_Occurrence_Of (Data.E_Id, Data.Loc),
1039                Make_Explicit_Dereference (Data.Loc, Except));
1040         end if;
1041
1042         --  Generate:
1043
1044         --    when others =>
1045         --       if not Raised_Id then
1046         --          Raised_Id := True;
1047
1048         --          Save_Occurrence (E_Id, Get_Current_Excep.all.all);
1049         --            or
1050         --          Save_Library_Occurrence (Get_Current_Excep.all);
1051         --       end if;
1052
1053         Stmts :=
1054           New_List (
1055             Make_If_Statement (Data.Loc,
1056               Condition       =>
1057                 Make_Op_Not (Data.Loc,
1058                   Right_Opnd => New_Occurrence_Of (Data.Raised_Id, Data.Loc)),
1059
1060               Then_Statements => New_List (
1061                 Make_Assignment_Statement (Data.Loc,
1062                   Name       => New_Occurrence_Of (Data.Raised_Id, Data.Loc),
1063                   Expression => New_Occurrence_Of (Standard_True, Data.Loc)),
1064
1065                 Make_Procedure_Call_Statement (Data.Loc,
1066                   Name                   =>
1067                     New_Occurrence_Of (Proc_To_Call, Data.Loc),
1068                   Parameter_Associations => Actuals))));
1069
1070      else
1071         --  Generate:
1072
1073         --    Raised_Id := True;
1074
1075         Stmts := New_List (
1076           Make_Assignment_Statement (Data.Loc,
1077             Name       => New_Occurrence_Of (Data.Raised_Id, Data.Loc),
1078             Expression => New_Occurrence_Of (Standard_True, Data.Loc)));
1079      end if;
1080
1081      --  Generate:
1082
1083      --    when others =>
1084
1085      return
1086        Make_Exception_Handler (Data.Loc,
1087          Exception_Choices => New_List (Make_Others_Choice (Data.Loc)),
1088          Statements        => Stmts);
1089   end Build_Exception_Handler;
1090
1091   -------------------------------
1092   -- Build_Finalization_Master --
1093   -------------------------------
1094
1095   procedure Build_Finalization_Master
1096     (Typ            : Entity_Id;
1097      For_Lib_Level  : Boolean   := False;
1098      For_Private    : Boolean   := False;
1099      Context_Scope  : Entity_Id := Empty;
1100      Insertion_Node : Node_Id   := Empty)
1101   is
1102      procedure Add_Pending_Access_Type
1103        (Typ     : Entity_Id;
1104         Ptr_Typ : Entity_Id);
1105      --  Add access type Ptr_Typ to the pending access type list for type Typ
1106
1107      -----------------------------
1108      -- Add_Pending_Access_Type --
1109      -----------------------------
1110
1111      procedure Add_Pending_Access_Type
1112        (Typ     : Entity_Id;
1113         Ptr_Typ : Entity_Id)
1114      is
1115         List : Elist_Id;
1116
1117      begin
1118         if Present (Pending_Access_Types (Typ)) then
1119            List := Pending_Access_Types (Typ);
1120         else
1121            List := New_Elmt_List;
1122            Set_Pending_Access_Types (Typ, List);
1123         end if;
1124
1125         Prepend_Elmt (Ptr_Typ, List);
1126      end Add_Pending_Access_Type;
1127
1128      --  Local variables
1129
1130      Desig_Typ : constant Entity_Id := Designated_Type (Typ);
1131
1132      Ptr_Typ : constant Entity_Id := Root_Type_Of_Full_View (Base_Type (Typ));
1133      --  A finalization master created for a named access type is associated
1134      --  with the full view (if applicable) as a consequence of freezing. The
1135      --  full view criteria does not apply to anonymous access types because
1136      --  those cannot have a private and a full view.
1137
1138   --  Start of processing for Build_Finalization_Master
1139
1140   begin
1141      --  Nothing to do if the circumstances do not allow for a finalization
1142      --  master.
1143
1144      if not Allows_Finalization_Master (Typ) then
1145         return;
1146
1147      --  Various machinery such as freezing may have already created a
1148      --  finalization master.
1149
1150      elsif Present (Finalization_Master (Ptr_Typ)) then
1151         return;
1152      end if;
1153
1154      declare
1155         Actions    : constant List_Id    := New_List;
1156         Loc        : constant Source_Ptr := Sloc (Ptr_Typ);
1157         Fin_Mas_Id : Entity_Id;
1158         Pool_Id    : Entity_Id;
1159
1160      begin
1161         --  Source access types use fixed master names since the master is
1162         --  inserted in the same source unit only once. The only exception to
1163         --  this are instances using the same access type as generic actual.
1164
1165         if Comes_From_Source (Ptr_Typ) and then not Inside_A_Generic then
1166            Fin_Mas_Id :=
1167              Make_Defining_Identifier (Loc,
1168                Chars => New_External_Name (Chars (Ptr_Typ), "FM"));
1169
1170         --  Internally generated access types use temporaries as their names
1171         --  due to possible collision with identical names coming from other
1172         --  packages.
1173
1174         else
1175            Fin_Mas_Id := Make_Temporary (Loc, 'F');
1176         end if;
1177
1178         Set_Finalization_Master (Ptr_Typ, Fin_Mas_Id);
1179
1180         --  Generate:
1181         --    <Ptr_Typ>FM : aliased Finalization_Master;
1182
1183         Append_To (Actions,
1184           Make_Object_Declaration (Loc,
1185             Defining_Identifier => Fin_Mas_Id,
1186             Aliased_Present     => True,
1187             Object_Definition   =>
1188               New_Occurrence_Of (RTE (RE_Finalization_Master), Loc)));
1189
1190         --  Set the associated pool and primitive Finalize_Address of the new
1191         --  finalization master.
1192
1193         --  The access type has a user-defined storage pool, use it
1194
1195         if Present (Associated_Storage_Pool (Ptr_Typ)) then
1196            Pool_Id := Associated_Storage_Pool (Ptr_Typ);
1197
1198         --  Otherwise the default choice is the global storage pool
1199
1200         else
1201            Pool_Id := RTE (RE_Global_Pool_Object);
1202            Set_Associated_Storage_Pool (Ptr_Typ, Pool_Id);
1203         end if;
1204
1205         --  Generate:
1206         --    Set_Base_Pool (<Ptr_Typ>FM, Pool_Id'Unchecked_Access);
1207
1208         Append_To (Actions,
1209           Make_Procedure_Call_Statement (Loc,
1210             Name                   =>
1211               New_Occurrence_Of (RTE (RE_Set_Base_Pool), Loc),
1212             Parameter_Associations => New_List (
1213               New_Occurrence_Of (Fin_Mas_Id, Loc),
1214               Make_Attribute_Reference (Loc,
1215                 Prefix         => New_Occurrence_Of (Pool_Id, Loc),
1216                 Attribute_Name => Name_Unrestricted_Access))));
1217
1218         --  Finalize_Address is not generated in CodePeer mode because the
1219         --  body contains address arithmetic. Skip this step.
1220
1221         if CodePeer_Mode then
1222            null;
1223
1224         --  Associate the Finalize_Address primitive of the designated type
1225         --  with the finalization master of the access type. The designated
1226         --  type must be forzen as Finalize_Address is generated when the
1227         --  freeze node is expanded.
1228
1229         elsif Is_Frozen (Desig_Typ)
1230           and then Present (Finalize_Address (Desig_Typ))
1231
1232           --  The finalization master of an anonymous access type may need
1233           --  to be inserted in a specific place in the tree. For instance:
1234
1235           --    type Comp_Typ;
1236
1237           --    <finalization master of "access Comp_Typ">
1238
1239           --    type Rec_Typ is record
1240           --       Comp : access Comp_Typ;
1241           --    end record;
1242
1243           --    <freeze node for Comp_Typ>
1244           --    <freeze node for Rec_Typ>
1245
1246           --  Due to this oddity, the anonymous access type is stored for
1247           --  later processing (see below).
1248
1249           and then Ekind (Ptr_Typ) /= E_Anonymous_Access_Type
1250         then
1251            --  Generate:
1252            --    Set_Finalize_Address
1253            --      (<Ptr_Typ>FM, <Desig_Typ>FD'Unrestricted_Access);
1254
1255            Append_To (Actions,
1256              Make_Set_Finalize_Address_Call
1257                (Loc     => Loc,
1258                 Ptr_Typ => Ptr_Typ));
1259
1260         --  Otherwise the designated type is either anonymous access or a
1261         --  Taft-amendment type and has not been frozen. Store the access
1262         --  type for later processing (see Freeze_Type).
1263
1264         else
1265            Add_Pending_Access_Type (Desig_Typ, Ptr_Typ);
1266         end if;
1267
1268         --  A finalization master created for an access designating a type
1269         --  with private components is inserted before a context-dependent
1270         --  node.
1271
1272         if For_Private then
1273
1274            --  At this point both the scope of the context and the insertion
1275            --  mode must be known.
1276
1277            pragma Assert (Present (Context_Scope));
1278            pragma Assert (Present (Insertion_Node));
1279
1280            Push_Scope (Context_Scope);
1281
1282            --  Treat use clauses as declarations and insert directly in front
1283            --  of them.
1284
1285            if Nkind_In (Insertion_Node, N_Use_Package_Clause,
1286                                         N_Use_Type_Clause)
1287            then
1288               Insert_List_Before_And_Analyze (Insertion_Node, Actions);
1289            else
1290               Insert_Actions (Insertion_Node, Actions);
1291            end if;
1292
1293            Pop_Scope;
1294
1295         --  The finalization master belongs to an access result type related
1296         --  to a build-in-place function call used to initialize a library
1297         --  level object. The master must be inserted in front of the access
1298         --  result type declaration denoted by Insertion_Node.
1299
1300         elsif For_Lib_Level then
1301            pragma Assert (Present (Insertion_Node));
1302            Insert_Actions (Insertion_Node, Actions);
1303
1304         --  Otherwise the finalization master and its initialization become a
1305         --  part of the freeze node.
1306
1307         else
1308            Append_Freeze_Actions (Ptr_Typ, Actions);
1309         end if;
1310      end;
1311   end Build_Finalization_Master;
1312
1313   ---------------------
1314   -- Build_Finalizer --
1315   ---------------------
1316
1317   procedure Build_Finalizer
1318     (N           : Node_Id;
1319      Clean_Stmts : List_Id;
1320      Mark_Id     : Entity_Id;
1321      Top_Decls   : List_Id;
1322      Defer_Abort : Boolean;
1323      Fin_Id      : out Entity_Id)
1324   is
1325      Acts_As_Clean    : constant Boolean :=
1326                           Present (Mark_Id)
1327                             or else
1328                               (Present (Clean_Stmts)
1329                                 and then Is_Non_Empty_List (Clean_Stmts));
1330      Exceptions_OK    : constant Boolean := Exceptions_In_Finalization_OK;
1331      For_Package_Body : constant Boolean := Nkind (N) = N_Package_Body;
1332      For_Package_Spec : constant Boolean := Nkind (N) = N_Package_Declaration;
1333      For_Package      : constant Boolean :=
1334                           For_Package_Body or else For_Package_Spec;
1335      Loc              : constant Source_Ptr := Sloc (N);
1336
1337      --  NOTE: Local variable declarations are conservative and do not create
1338      --  structures right from the start. Entities and lists are created once
1339      --  it has been established that N has at least one controlled object.
1340
1341      Components_Built : Boolean := False;
1342      --  A flag used to avoid double initialization of entities and lists. If
1343      --  the flag is set then the following variables have been initialized:
1344      --    Counter_Id
1345      --    Finalizer_Decls
1346      --    Finalizer_Stmts
1347      --    Jump_Alts
1348
1349      Counter_Id  : Entity_Id := Empty;
1350      Counter_Val : Nat       := 0;
1351      --  Name and value of the state counter
1352
1353      Decls : List_Id := No_List;
1354      --  Declarative region of N (if available). If N is a package declaration
1355      --  Decls denotes the visible declarations.
1356
1357      Finalizer_Data : Finalization_Exception_Data;
1358      --  Data for the exception
1359
1360      Finalizer_Decls : List_Id := No_List;
1361      --  Local variable declarations. This list holds the label declarations
1362      --  of all jump block alternatives as well as the declaration of the
1363      --  local exception occurrence and the raised flag:
1364      --     E : Exception_Occurrence;
1365      --     Raised : Boolean := False;
1366      --     L<counter value> : label;
1367
1368      Finalizer_Insert_Nod : Node_Id := Empty;
1369      --  Insertion point for the finalizer body. Depending on the context
1370      --  (Nkind of N) and the individual grouping of controlled objects, this
1371      --  node may denote a package declaration or body, package instantiation,
1372      --  block statement or a counter update statement.
1373
1374      Finalizer_Stmts : List_Id := No_List;
1375      --  The statement list of the finalizer body. It contains the following:
1376      --
1377      --    Abort_Defer;               --  Added if abort is allowed
1378      --    <call to Prev_At_End>      --  Added if exists
1379      --    <cleanup statements>       --  Added if Acts_As_Clean
1380      --    <jump block>               --  Added if Has_Ctrl_Objs
1381      --    <finalization statements>  --  Added if Has_Ctrl_Objs
1382      --    <stack release>            --  Added if Mark_Id exists
1383      --    Abort_Undefer;             --  Added if abort is allowed
1384
1385      Has_Ctrl_Objs : Boolean := False;
1386      --  A general flag which denotes whether N has at least one controlled
1387      --  object.
1388
1389      Has_Tagged_Types : Boolean := False;
1390      --  A general flag which indicates whether N has at least one library-
1391      --  level tagged type declaration.
1392
1393      HSS : Node_Id := Empty;
1394      --  The sequence of statements of N (if available)
1395
1396      Jump_Alts : List_Id := No_List;
1397      --  Jump block alternatives. Depending on the value of the state counter,
1398      --  the control flow jumps to a sequence of finalization statements. This
1399      --  list contains the following:
1400      --
1401      --     when <counter value> =>
1402      --        goto L<counter value>;
1403
1404      Jump_Block_Insert_Nod : Node_Id := Empty;
1405      --  Specific point in the finalizer statements where the jump block is
1406      --  inserted.
1407
1408      Last_Top_Level_Ctrl_Construct : Node_Id := Empty;
1409      --  The last controlled construct encountered when processing the top
1410      --  level lists of N. This can be a nested package, an instantiation or
1411      --  an object declaration.
1412
1413      Prev_At_End : Entity_Id := Empty;
1414      --  The previous at end procedure of the handled statements block of N
1415
1416      Priv_Decls : List_Id := No_List;
1417      --  The private declarations of N if N is a package declaration
1418
1419      Spec_Id    : Entity_Id := Empty;
1420      Spec_Decls : List_Id   := Top_Decls;
1421      Stmts      : List_Id   := No_List;
1422
1423      Tagged_Type_Stmts : List_Id := No_List;
1424      --  Contains calls to Ada.Tags.Unregister_Tag for all library-level
1425      --  tagged types found in N.
1426
1427      -----------------------
1428      -- Local subprograms --
1429      -----------------------
1430
1431      procedure Build_Components;
1432      --  Create all entites and initialize all lists used in the creation of
1433      --  the finalizer.
1434
1435      procedure Create_Finalizer;
1436      --  Create the spec and body of the finalizer and insert them in the
1437      --  proper place in the tree depending on the context.
1438
1439      procedure Process_Declarations
1440        (Decls      : List_Id;
1441         Preprocess : Boolean := False;
1442         Top_Level  : Boolean := False);
1443      --  Inspect a list of declarations or statements which may contain
1444      --  objects that need finalization. When flag Preprocess is set, the
1445      --  routine will simply count the total number of controlled objects in
1446      --  Decls. Flag Top_Level denotes whether the processing is done for
1447      --  objects in nested package declarations or instances.
1448
1449      procedure Process_Object_Declaration
1450        (Decl         : Node_Id;
1451         Has_No_Init  : Boolean := False;
1452         Is_Protected : Boolean := False);
1453      --  Generate all the machinery associated with the finalization of a
1454      --  single object. Flag Has_No_Init is used to denote certain contexts
1455      --  where Decl does not have initialization call(s). Flag Is_Protected
1456      --  is set when Decl denotes a simple protected object.
1457
1458      procedure Process_Tagged_Type_Declaration (Decl : Node_Id);
1459      --  Generate all the code necessary to unregister the external tag of a
1460      --  tagged type.
1461
1462      ----------------------
1463      -- Build_Components --
1464      ----------------------
1465
1466      procedure Build_Components is
1467         Counter_Decl     : Node_Id;
1468         Counter_Typ      : Entity_Id;
1469         Counter_Typ_Decl : Node_Id;
1470
1471      begin
1472         pragma Assert (Present (Decls));
1473
1474         --  This routine might be invoked several times when dealing with
1475         --  constructs that have two lists (either two declarative regions
1476         --  or declarations and statements). Avoid double initialization.
1477
1478         if Components_Built then
1479            return;
1480         end if;
1481
1482         Components_Built := True;
1483
1484         if Has_Ctrl_Objs then
1485
1486            --  Create entities for the counter, its type, the local exception
1487            --  and the raised flag.
1488
1489            Counter_Id  := Make_Temporary (Loc, 'C');
1490            Counter_Typ := Make_Temporary (Loc, 'T');
1491
1492            Finalizer_Decls := New_List;
1493
1494            Build_Object_Declarations
1495              (Finalizer_Data, Finalizer_Decls, Loc, For_Package);
1496
1497            --  Since the total number of controlled objects is always known,
1498            --  build a subtype of Natural with precise bounds. This allows
1499            --  the backend to optimize the case statement. Generate:
1500            --
1501            --    subtype Tnn is Natural range 0 .. Counter_Val;
1502
1503            Counter_Typ_Decl :=
1504              Make_Subtype_Declaration (Loc,
1505                Defining_Identifier => Counter_Typ,
1506                Subtype_Indication  =>
1507                  Make_Subtype_Indication (Loc,
1508                    Subtype_Mark => New_Occurrence_Of (Standard_Natural, Loc),
1509                    Constraint   =>
1510                      Make_Range_Constraint (Loc,
1511                        Range_Expression =>
1512                          Make_Range (Loc,
1513                            Low_Bound  =>
1514                              Make_Integer_Literal (Loc, Uint_0),
1515                            High_Bound =>
1516                              Make_Integer_Literal (Loc, Counter_Val)))));
1517
1518            --  Generate the declaration of the counter itself:
1519            --
1520            --    Counter : Integer := 0;
1521
1522            Counter_Decl :=
1523              Make_Object_Declaration (Loc,
1524                Defining_Identifier => Counter_Id,
1525                Object_Definition   => New_Occurrence_Of (Counter_Typ, Loc),
1526                Expression          => Make_Integer_Literal (Loc, 0));
1527
1528            --  Set the type of the counter explicitly to prevent errors when
1529            --  examining object declarations later on.
1530
1531            Set_Etype (Counter_Id, Counter_Typ);
1532
1533            --  The counter and its type are inserted before the source
1534            --  declarations of N.
1535
1536            Prepend_To (Decls, Counter_Decl);
1537            Prepend_To (Decls, Counter_Typ_Decl);
1538
1539            --  The counter and its associated type must be manually analyzed
1540            --  since N has already been analyzed. Use the scope of the spec
1541            --  when inserting in a package.
1542
1543            if For_Package then
1544               Push_Scope (Spec_Id);
1545               Analyze (Counter_Typ_Decl);
1546               Analyze (Counter_Decl);
1547               Pop_Scope;
1548
1549            else
1550               Analyze (Counter_Typ_Decl);
1551               Analyze (Counter_Decl);
1552            end if;
1553
1554            Jump_Alts := New_List;
1555         end if;
1556
1557         --  If the context requires additional cleanup, the finalization
1558         --  machinery is added after the cleanup code.
1559
1560         if Acts_As_Clean then
1561            Finalizer_Stmts       := Clean_Stmts;
1562            Jump_Block_Insert_Nod := Last (Finalizer_Stmts);
1563         else
1564            Finalizer_Stmts := New_List;
1565         end if;
1566
1567         if Has_Tagged_Types then
1568            Tagged_Type_Stmts := New_List;
1569         end if;
1570      end Build_Components;
1571
1572      ----------------------
1573      -- Create_Finalizer --
1574      ----------------------
1575
1576      procedure Create_Finalizer is
1577         function New_Finalizer_Name return Name_Id;
1578         --  Create a fully qualified name of a package spec or body finalizer.
1579         --  The generated name is of the form: xx__yy__finalize_[spec|body].
1580
1581         ------------------------
1582         -- New_Finalizer_Name --
1583         ------------------------
1584
1585         function New_Finalizer_Name return Name_Id is
1586            procedure New_Finalizer_Name (Id : Entity_Id);
1587            --  Place "__<name-of-Id>" in the name buffer. If the identifier
1588            --  has a non-standard scope, process the scope first.
1589
1590            ------------------------
1591            -- New_Finalizer_Name --
1592            ------------------------
1593
1594            procedure New_Finalizer_Name (Id : Entity_Id) is
1595            begin
1596               if Scope (Id) = Standard_Standard then
1597                  Get_Name_String (Chars (Id));
1598
1599               else
1600                  New_Finalizer_Name (Scope (Id));
1601                  Add_Str_To_Name_Buffer ("__");
1602                  Add_Str_To_Name_Buffer (Get_Name_String (Chars (Id)));
1603               end if;
1604            end New_Finalizer_Name;
1605
1606         --  Start of processing for New_Finalizer_Name
1607
1608         begin
1609            --  Create the fully qualified name of the enclosing scope
1610
1611            New_Finalizer_Name (Spec_Id);
1612
1613            --  Generate:
1614            --    __finalize_[spec|body]
1615
1616            Add_Str_To_Name_Buffer ("__finalize_");
1617
1618            if For_Package_Spec then
1619               Add_Str_To_Name_Buffer ("spec");
1620            else
1621               Add_Str_To_Name_Buffer ("body");
1622            end if;
1623
1624            return Name_Find;
1625         end New_Finalizer_Name;
1626
1627         --  Local variables
1628
1629         Body_Id    : Entity_Id;
1630         Fin_Body   : Node_Id;
1631         Fin_Spec   : Node_Id;
1632         Jump_Block : Node_Id;
1633         Label      : Node_Id;
1634         Label_Id   : Entity_Id;
1635
1636      --  Start of processing for Create_Finalizer
1637
1638      begin
1639         --  Step 1: Creation of the finalizer name
1640
1641         --  Packages must use a distinct name for their finalizers since the
1642         --  binder will have to generate calls to them by name. The name is
1643         --  of the following form:
1644
1645         --    xx__yy__finalize_[spec|body]
1646
1647         if For_Package then
1648            Fin_Id := Make_Defining_Identifier (Loc, New_Finalizer_Name);
1649            Set_Has_Qualified_Name       (Fin_Id);
1650            Set_Has_Fully_Qualified_Name (Fin_Id);
1651
1652         --  The default name is _finalizer
1653
1654         else
1655            Fin_Id :=
1656              Make_Defining_Identifier (Loc,
1657                Chars => New_External_Name (Name_uFinalizer));
1658
1659            --  The visibility semantics of AT_END handlers force a strange
1660            --  separation of spec and body for stack-related finalizers:
1661
1662            --     declare : Enclosing_Scope
1663            --        procedure _finalizer;
1664            --     begin
1665            --        <controlled objects>
1666            --        procedure _finalizer is
1667            --           ...
1668            --     at end
1669            --        _finalizer;
1670            --     end;
1671
1672            --  Both spec and body are within the same construct and scope, but
1673            --  the body is part of the handled sequence of statements. This
1674            --  placement confuses the elaboration mechanism on targets where
1675            --  AT_END handlers are expanded into "when all others" handlers:
1676
1677            --     exception
1678            --        when all others =>
1679            --           _finalizer;  --  appears to require elab checks
1680            --     at end
1681            --        _finalizer;
1682            --     end;
1683
1684            --  Since the compiler guarantees that the body of a _finalizer is
1685            --  always inserted in the same construct where the AT_END handler
1686            --  resides, there is no need for elaboration checks.
1687
1688            Set_Kill_Elaboration_Checks (Fin_Id);
1689
1690            --  Inlining the finalizer produces a substantial speedup at -O2.
1691            --  It is inlined by default at -O3. Either way, it is called
1692            --  exactly twice (once on the normal path, and once for
1693            --  exceptions/abort), so this won't bloat the code too much.
1694
1695            Set_Is_Inlined  (Fin_Id);
1696         end if;
1697
1698         --  Step 2: Creation of the finalizer specification
1699
1700         --  Generate:
1701         --    procedure Fin_Id;
1702
1703         Fin_Spec :=
1704           Make_Subprogram_Declaration (Loc,
1705             Specification =>
1706               Make_Procedure_Specification (Loc,
1707                 Defining_Unit_Name => Fin_Id));
1708
1709         --  Step 3: Creation of the finalizer body
1710
1711         if Has_Ctrl_Objs then
1712
1713            --  Add L0, the default destination to the jump block
1714
1715            Label_Id := Make_Identifier (Loc, New_External_Name ('L', 0));
1716            Set_Entity (Label_Id,
1717              Make_Defining_Identifier (Loc, Chars (Label_Id)));
1718            Label := Make_Label (Loc, Label_Id);
1719
1720            --  Generate:
1721            --    L0 : label;
1722
1723            Prepend_To (Finalizer_Decls,
1724              Make_Implicit_Label_Declaration (Loc,
1725                Defining_Identifier => Entity (Label_Id),
1726                Label_Construct     => Label));
1727
1728            --  Generate:
1729            --    when others =>
1730            --       goto L0;
1731
1732            Append_To (Jump_Alts,
1733              Make_Case_Statement_Alternative (Loc,
1734                Discrete_Choices => New_List (Make_Others_Choice (Loc)),
1735                Statements       => New_List (
1736                  Make_Goto_Statement (Loc,
1737                    Name => New_Occurrence_Of (Entity (Label_Id), Loc)))));
1738
1739            --  Generate:
1740            --    <<L0>>
1741
1742            Append_To (Finalizer_Stmts, Label);
1743
1744            --  Create the jump block which controls the finalization flow
1745            --  depending on the value of the state counter.
1746
1747            Jump_Block :=
1748              Make_Case_Statement (Loc,
1749                Expression   => Make_Identifier (Loc, Chars (Counter_Id)),
1750                Alternatives => Jump_Alts);
1751
1752            if Acts_As_Clean and then Present (Jump_Block_Insert_Nod) then
1753               Insert_After (Jump_Block_Insert_Nod, Jump_Block);
1754            else
1755               Prepend_To (Finalizer_Stmts, Jump_Block);
1756            end if;
1757         end if;
1758
1759         --  Add the library-level tagged type unregistration machinery before
1760         --  the jump block circuitry. This ensures that external tags will be
1761         --  removed even if a finalization exception occurs at some point.
1762
1763         if Has_Tagged_Types then
1764            Prepend_List_To (Finalizer_Stmts, Tagged_Type_Stmts);
1765         end if;
1766
1767         --  Add a call to the previous At_End handler if it exists. The call
1768         --  must always precede the jump block.
1769
1770         if Present (Prev_At_End) then
1771            Prepend_To (Finalizer_Stmts,
1772              Make_Procedure_Call_Statement (Loc, Prev_At_End));
1773
1774            --  Clear the At_End handler since we have already generated the
1775            --  proper replacement call for it.
1776
1777            Set_At_End_Proc (HSS, Empty);
1778         end if;
1779
1780         --  Release the secondary stack mark
1781
1782         if Present (Mark_Id) then
1783            Append_To (Finalizer_Stmts, Build_SS_Release_Call (Loc, Mark_Id));
1784         end if;
1785
1786         --  Protect the statements with abort defer/undefer. This is only when
1787         --  aborts are allowed and the cleanup statements require deferral or
1788         --  there are controlled objects to be finalized. Note that the abort
1789         --  defer/undefer pair does not require an extra block because each
1790         --  finalization exception is caught in its corresponding finalization
1791         --  block. As a result, the call to Abort_Defer always takes place.
1792
1793         if Abort_Allowed and then (Defer_Abort or Has_Ctrl_Objs) then
1794            Prepend_To (Finalizer_Stmts,
1795              Build_Runtime_Call (Loc, RE_Abort_Defer));
1796
1797            Append_To (Finalizer_Stmts,
1798              Build_Runtime_Call (Loc, RE_Abort_Undefer));
1799         end if;
1800
1801         --  The local exception does not need to be reraised for library-level
1802         --  finalizers. Note that this action must be carried out after object
1803         --  cleanup, secondary stack release, and abort undeferral. Generate:
1804
1805         --    if Raised and then not Abort then
1806         --       Raise_From_Controlled_Operation (E);
1807         --    end if;
1808
1809         if Has_Ctrl_Objs and Exceptions_OK and not For_Package then
1810            Append_To (Finalizer_Stmts,
1811              Build_Raise_Statement (Finalizer_Data));
1812         end if;
1813
1814         --  Generate:
1815         --    procedure Fin_Id is
1816         --       Abort  : constant Boolean := Triggered_By_Abort;
1817         --         <or>
1818         --       Abort  : constant Boolean := False;  --  no abort
1819
1820         --       E      : Exception_Occurrence;  --  All added if flag
1821         --       Raised : Boolean := False;      --  Has_Ctrl_Objs is set
1822         --       L0     : label;
1823         --       ...
1824         --       Lnn    : label;
1825
1826         --    begin
1827         --       Abort_Defer;               --  Added if abort is allowed
1828         --       <call to Prev_At_End>      --  Added if exists
1829         --       <cleanup statements>       --  Added if Acts_As_Clean
1830         --       <jump block>               --  Added if Has_Ctrl_Objs
1831         --       <finalization statements>  --  Added if Has_Ctrl_Objs
1832         --       <stack release>            --  Added if Mark_Id exists
1833         --       Abort_Undefer;             --  Added if abort is allowed
1834         --       <exception propagation>    --  Added if Has_Ctrl_Objs
1835         --    end Fin_Id;
1836
1837         --  Create the body of the finalizer
1838
1839         Body_Id := Make_Defining_Identifier (Loc, Chars (Fin_Id));
1840
1841         if For_Package then
1842            Set_Has_Qualified_Name       (Body_Id);
1843            Set_Has_Fully_Qualified_Name (Body_Id);
1844         end if;
1845
1846         Fin_Body :=
1847           Make_Subprogram_Body (Loc,
1848             Specification              =>
1849               Make_Procedure_Specification (Loc,
1850                 Defining_Unit_Name => Body_Id),
1851             Declarations               => Finalizer_Decls,
1852             Handled_Statement_Sequence =>
1853               Make_Handled_Sequence_Of_Statements (Loc,
1854                 Statements => Finalizer_Stmts));
1855
1856         --  Step 4: Spec and body insertion, analysis
1857
1858         if For_Package then
1859
1860            --  If the package spec has private declarations, the finalizer
1861            --  body must be added to the end of the list in order to have
1862            --  visibility of all private controlled objects.
1863
1864            if For_Package_Spec then
1865               if Present (Priv_Decls) then
1866                  Append_To (Priv_Decls, Fin_Spec);
1867                  Append_To (Priv_Decls, Fin_Body);
1868               else
1869                  Append_To (Decls, Fin_Spec);
1870                  Append_To (Decls, Fin_Body);
1871               end if;
1872
1873            --  For package bodies, both the finalizer spec and body are
1874            --  inserted at the end of the package declarations.
1875
1876            else
1877               Append_To (Decls, Fin_Spec);
1878               Append_To (Decls, Fin_Body);
1879            end if;
1880
1881            --  Push the name of the package
1882
1883            Push_Scope (Spec_Id);
1884            Analyze (Fin_Spec);
1885            Analyze (Fin_Body);
1886            Pop_Scope;
1887
1888         --  Non-package case
1889
1890         else
1891            --  Create the spec for the finalizer. The At_End handler must be
1892            --  able to call the body which resides in a nested structure.
1893
1894            --  Generate:
1895            --    declare
1896            --       procedure Fin_Id;                  --  Spec
1897            --    begin
1898            --       <objects and possibly statements>
1899            --       procedure Fin_Id is ...            --  Body
1900            --       <statements>
1901            --    at end
1902            --       Fin_Id;                            --  At_End handler
1903            --    end;
1904
1905            pragma Assert (Present (Spec_Decls));
1906
1907            Append_To (Spec_Decls, Fin_Spec);
1908            Analyze (Fin_Spec);
1909
1910            --  When the finalizer acts solely as a cleanup routine, the body
1911            --  is inserted right after the spec.
1912
1913            if Acts_As_Clean and not Has_Ctrl_Objs then
1914               Insert_After (Fin_Spec, Fin_Body);
1915
1916            --  In all other cases the body is inserted after either:
1917            --
1918            --    1) The counter update statement of the last controlled object
1919            --    2) The last top level nested controlled package
1920            --    3) The last top level controlled instantiation
1921
1922            else
1923               --  Manually freeze the spec. This is somewhat of a hack because
1924               --  a subprogram is frozen when its body is seen and the freeze
1925               --  node appears right before the body. However, in this case,
1926               --  the spec must be frozen earlier since the At_End handler
1927               --  must be able to call it.
1928               --
1929               --    declare
1930               --       procedure Fin_Id;               --  Spec
1931               --       [Fin_Id]                        --  Freeze node
1932               --    begin
1933               --       ...
1934               --    at end
1935               --       Fin_Id;                         --  At_End handler
1936               --    end;
1937
1938               Ensure_Freeze_Node (Fin_Id);
1939               Insert_After (Fin_Spec, Freeze_Node (Fin_Id));
1940               Set_Is_Frozen (Fin_Id);
1941
1942               --  In the case where the last construct to contain a controlled
1943               --  object is either a nested package, an instantiation or a
1944               --  freeze node, the body must be inserted directly after the
1945               --  construct.
1946
1947               if Nkind_In (Last_Top_Level_Ctrl_Construct,
1948                              N_Freeze_Entity,
1949                              N_Package_Declaration,
1950                              N_Package_Body)
1951               then
1952                  Finalizer_Insert_Nod := Last_Top_Level_Ctrl_Construct;
1953               end if;
1954
1955               Insert_After (Finalizer_Insert_Nod, Fin_Body);
1956            end if;
1957
1958            Analyze (Fin_Body, Suppress => All_Checks);
1959         end if;
1960      end Create_Finalizer;
1961
1962      --------------------------
1963      -- Process_Declarations --
1964      --------------------------
1965
1966      procedure Process_Declarations
1967        (Decls      : List_Id;
1968         Preprocess : Boolean := False;
1969         Top_Level  : Boolean := False)
1970      is
1971         Decl    : Node_Id;
1972         Expr    : Node_Id;
1973         Obj_Id  : Entity_Id;
1974         Obj_Typ : Entity_Id;
1975         Pack_Id : Entity_Id;
1976         Spec    : Node_Id;
1977         Typ     : Entity_Id;
1978
1979         Old_Counter_Val : Nat;
1980         --  This variable is used to determine whether a nested package or
1981         --  instance contains at least one controlled object.
1982
1983         procedure Processing_Actions
1984           (Has_No_Init  : Boolean := False;
1985            Is_Protected : Boolean := False);
1986         --  Depending on the mode of operation of Process_Declarations, either
1987         --  increment the controlled object counter, set the controlled object
1988         --  flag and store the last top level construct or process the current
1989         --  declaration. Flag Has_No_Init is used to propagate scenarios where
1990         --  the current declaration may not have initialization proc(s). Flag
1991         --  Is_Protected should be set when the current declaration denotes a
1992         --  simple protected object.
1993
1994         ------------------------
1995         -- Processing_Actions --
1996         ------------------------
1997
1998         procedure Processing_Actions
1999           (Has_No_Init  : Boolean := False;
2000            Is_Protected : Boolean := False)
2001         is
2002         begin
2003            --  Library-level tagged type
2004
2005            if Nkind (Decl) = N_Full_Type_Declaration then
2006               if Preprocess then
2007                  Has_Tagged_Types := True;
2008
2009                  if Top_Level and then No (Last_Top_Level_Ctrl_Construct) then
2010                     Last_Top_Level_Ctrl_Construct := Decl;
2011                  end if;
2012
2013               else
2014                  Process_Tagged_Type_Declaration (Decl);
2015               end if;
2016
2017            --  Controlled object declaration
2018
2019            else
2020               if Preprocess then
2021                  Counter_Val   := Counter_Val + 1;
2022                  Has_Ctrl_Objs := True;
2023
2024                  if Top_Level and then No (Last_Top_Level_Ctrl_Construct) then
2025                     Last_Top_Level_Ctrl_Construct := Decl;
2026                  end if;
2027
2028               else
2029                  Process_Object_Declaration (Decl, Has_No_Init, Is_Protected);
2030               end if;
2031            end if;
2032         end Processing_Actions;
2033
2034      --  Start of processing for Process_Declarations
2035
2036      begin
2037         if No (Decls) or else Is_Empty_List (Decls) then
2038            return;
2039         end if;
2040
2041         --  Process all declarations in reverse order
2042
2043         Decl := Last_Non_Pragma (Decls);
2044         while Present (Decl) loop
2045
2046            --  Library-level tagged types
2047
2048            if Nkind (Decl) = N_Full_Type_Declaration then
2049               Typ := Defining_Identifier (Decl);
2050
2051               --  Ignored Ghost types do not need any cleanup actions because
2052               --  they will not appear in the final tree.
2053
2054               if Is_Ignored_Ghost_Entity (Typ) then
2055                  null;
2056
2057               elsif Is_Tagged_Type (Typ)
2058                 and then Is_Library_Level_Entity (Typ)
2059                 and then Convention (Typ) = Convention_Ada
2060                 and then Present (Access_Disp_Table (Typ))
2061                 and then RTE_Available (RE_Register_Tag)
2062                 and then not Is_Abstract_Type (Typ)
2063                 and then not No_Run_Time_Mode
2064               then
2065                  Processing_Actions;
2066               end if;
2067
2068            --  Regular object declarations
2069
2070            elsif Nkind (Decl) = N_Object_Declaration then
2071               Obj_Id  := Defining_Identifier (Decl);
2072               Obj_Typ := Base_Type (Etype (Obj_Id));
2073               Expr    := Expression (Decl);
2074
2075               --  Bypass any form of processing for objects which have their
2076               --  finalization disabled. This applies only to objects at the
2077               --  library level.
2078
2079               if For_Package and then Finalize_Storage_Only (Obj_Typ) then
2080                  null;
2081
2082               --  Finalization of transient objects are treated separately in
2083               --  order to handle sensitive cases. These include:
2084
2085               --    * Aggregate expansion
2086               --    * If, case, and expression with actions expansion
2087               --    * Transient scopes
2088
2089               --  If one of those contexts has marked the transient object as
2090               --  ignored, do not generate finalization actions for it.
2091
2092               elsif Is_Finalized_Transient (Obj_Id)
2093                 or else Is_Ignored_Transient (Obj_Id)
2094               then
2095                  null;
2096
2097               --  Ignored Ghost objects do not need any cleanup actions
2098               --  because they will not appear in the final tree.
2099
2100               elsif Is_Ignored_Ghost_Entity (Obj_Id) then
2101                  null;
2102
2103               --  The object is of the form:
2104               --    Obj : [constant] Typ [:= Expr];
2105
2106               --  Do not process tag-to-class-wide conversions because they do
2107               --  not yield an object. Do not process the incomplete view of a
2108               --  deferred constant. Note that an object initialized by means
2109               --  of a build-in-place function call may appear as a deferred
2110               --  constant after expansion activities. These kinds of objects
2111               --  must be finalized.
2112
2113               elsif not Is_Imported (Obj_Id)
2114                 and then Needs_Finalization (Obj_Typ)
2115                 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
2116                 and then not (Ekind (Obj_Id) = E_Constant
2117                                and then not Has_Completion (Obj_Id)
2118                                and then No (BIP_Initialization_Call (Obj_Id)))
2119               then
2120                  Processing_Actions;
2121
2122               --  The object is of the form:
2123               --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
2124
2125               --    Obj : Access_Typ :=
2126               --            BIP_Function_Call (BIPalloc => 2, ...)'reference;
2127
2128               elsif Is_Access_Type (Obj_Typ)
2129                 and then Needs_Finalization
2130                            (Available_View (Designated_Type (Obj_Typ)))
2131                 and then Present (Expr)
2132                 and then
2133                   (Is_Secondary_Stack_BIP_Func_Call (Expr)
2134                     or else
2135                       (Is_Non_BIP_Func_Call (Expr)
2136                         and then not Is_Related_To_Func_Return (Obj_Id)))
2137               then
2138                  Processing_Actions (Has_No_Init => True);
2139
2140               --  Processing for "hook" objects generated for transient
2141               --  objects declared inside an Expression_With_Actions.
2142
2143               elsif Is_Access_Type (Obj_Typ)
2144                 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
2145                 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
2146                                                       N_Object_Declaration
2147               then
2148                  Processing_Actions (Has_No_Init => True);
2149
2150               --  Process intermediate results of an if expression with one
2151               --  of the alternatives using a controlled function call.
2152
2153               elsif Is_Access_Type (Obj_Typ)
2154                 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
2155                 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
2156                                                       N_Defining_Identifier
2157                 and then Present (Expr)
2158                 and then Nkind (Expr) = N_Null
2159               then
2160                  Processing_Actions (Has_No_Init => True);
2161
2162               --  Simple protected objects which use type System.Tasking.
2163               --  Protected_Objects.Protection to manage their locks should
2164               --  be treated as controlled since they require manual cleanup.
2165               --  The only exception is illustrated in the following example:
2166
2167               --     package Pkg is
2168               --        type Ctrl is new Controlled ...
2169               --        procedure Finalize (Obj : in out Ctrl);
2170               --        Lib_Obj : Ctrl;
2171               --     end Pkg;
2172
2173               --     package body Pkg is
2174               --        protected Prot is
2175               --           procedure Do_Something (Obj : in out Ctrl);
2176               --        end Prot;
2177
2178               --        protected body Prot is
2179               --           procedure Do_Something (Obj : in out Ctrl) is ...
2180               --        end Prot;
2181
2182               --        procedure Finalize (Obj : in out Ctrl) is
2183               --        begin
2184               --           Prot.Do_Something (Obj);
2185               --        end Finalize;
2186               --     end Pkg;
2187
2188               --  Since for the most part entities in package bodies depend on
2189               --  those in package specs, Prot's lock should be cleaned up
2190               --  first. The subsequent cleanup of the spec finalizes Lib_Obj.
2191               --  This act however attempts to invoke Do_Something and fails
2192               --  because the lock has disappeared.
2193
2194               elsif Ekind (Obj_Id) = E_Variable
2195                 and then not In_Library_Level_Package_Body (Obj_Id)
2196                 and then (Is_Simple_Protected_Type (Obj_Typ)
2197                            or else Has_Simple_Protected_Object (Obj_Typ))
2198               then
2199                  Processing_Actions (Is_Protected => True);
2200               end if;
2201
2202            --  Specific cases of object renamings
2203
2204            elsif Nkind (Decl) = N_Object_Renaming_Declaration then
2205               Obj_Id  := Defining_Identifier (Decl);
2206               Obj_Typ := Base_Type (Etype (Obj_Id));
2207
2208               --  Bypass any form of processing for objects which have their
2209               --  finalization disabled. This applies only to objects at the
2210               --  library level.
2211
2212               if For_Package and then Finalize_Storage_Only (Obj_Typ) then
2213                  null;
2214
2215               --  Ignored Ghost object renamings do not need any cleanup
2216               --  actions because they will not appear in the final tree.
2217
2218               elsif Is_Ignored_Ghost_Entity (Obj_Id) then
2219                  null;
2220
2221               --  Return object of a build-in-place function. This case is
2222               --  recognized and marked by the expansion of an extended return
2223               --  statement (see Expand_N_Extended_Return_Statement).
2224
2225               elsif Needs_Finalization (Obj_Typ)
2226                 and then Is_Return_Object (Obj_Id)
2227                 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
2228               then
2229                  Processing_Actions (Has_No_Init => True);
2230
2231               --  Detect a case where a source object has been initialized by
2232               --  a controlled function call or another object which was later
2233               --  rewritten as a class-wide conversion of Ada.Tags.Displace.
2234
2235               --     Obj1 : CW_Type := Src_Obj;
2236               --     Obj2 : CW_Type := Function_Call (...);
2237
2238               --     Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
2239               --     Tmp  : ... := Function_Call (...)'reference;
2240               --     Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
2241
2242               elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
2243                  Processing_Actions (Has_No_Init => True);
2244               end if;
2245
2246            --  Inspect the freeze node of an access-to-controlled type and
2247            --  look for a delayed finalization master. This case arises when
2248            --  the freeze actions are inserted at a later time than the
2249            --  expansion of the context. Since Build_Finalizer is never called
2250            --  on a single construct twice, the master will be ultimately
2251            --  left out and never finalized. This is also needed for freeze
2252            --  actions of designated types themselves, since in some cases the
2253            --  finalization master is associated with a designated type's
2254            --  freeze node rather than that of the access type (see handling
2255            --  for freeze actions in Build_Finalization_Master).
2256
2257            elsif Nkind (Decl) = N_Freeze_Entity
2258              and then Present (Actions (Decl))
2259            then
2260               Typ := Entity (Decl);
2261
2262               --  Freeze nodes for ignored Ghost types do not need cleanup
2263               --  actions because they will never appear in the final tree.
2264
2265               if Is_Ignored_Ghost_Entity (Typ) then
2266                  null;
2267
2268               elsif (Is_Access_Type (Typ)
2269                        and then not Is_Access_Subprogram_Type (Typ)
2270                        and then Needs_Finalization
2271                                   (Available_View (Designated_Type (Typ))))
2272                      or else (Is_Type (Typ) and then Needs_Finalization (Typ))
2273               then
2274                  Old_Counter_Val := Counter_Val;
2275
2276                  --  Freeze nodes are considered to be identical to packages
2277                  --  and blocks in terms of nesting. The difference is that
2278                  --  a finalization master created inside the freeze node is
2279                  --  at the same nesting level as the node itself.
2280
2281                  Process_Declarations (Actions (Decl), Preprocess);
2282
2283                  --  The freeze node contains a finalization master
2284
2285                  if Preprocess
2286                    and then Top_Level
2287                    and then No (Last_Top_Level_Ctrl_Construct)
2288                    and then Counter_Val > Old_Counter_Val
2289                  then
2290                     Last_Top_Level_Ctrl_Construct := Decl;
2291                  end if;
2292               end if;
2293
2294            --  Nested package declarations, avoid generics
2295
2296            elsif Nkind (Decl) = N_Package_Declaration then
2297               Pack_Id := Defining_Entity (Decl);
2298               Spec    := Specification   (Decl);
2299
2300               --  Do not inspect an ignored Ghost package because all code
2301               --  found within will not appear in the final tree.
2302
2303               if Is_Ignored_Ghost_Entity (Pack_Id) then
2304                  null;
2305
2306               elsif Ekind (Pack_Id) /= E_Generic_Package then
2307                  Old_Counter_Val := Counter_Val;
2308                  Process_Declarations
2309                    (Private_Declarations (Spec), Preprocess);
2310                  Process_Declarations
2311                    (Visible_Declarations (Spec), Preprocess);
2312
2313                  --  Either the visible or the private declarations contain a
2314                  --  controlled object. The nested package declaration is the
2315                  --  last such construct.
2316
2317                  if Preprocess
2318                    and then Top_Level
2319                    and then No (Last_Top_Level_Ctrl_Construct)
2320                    and then Counter_Val > Old_Counter_Val
2321                  then
2322                     Last_Top_Level_Ctrl_Construct := Decl;
2323                  end if;
2324               end if;
2325
2326            --  Nested package bodies, avoid generics
2327
2328            elsif Nkind (Decl) = N_Package_Body then
2329
2330               --  Do not inspect an ignored Ghost package body because all
2331               --  code found within will not appear in the final tree.
2332
2333               if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
2334                  null;
2335
2336               elsif Ekind (Corresponding_Spec (Decl)) /=
2337                       E_Generic_Package
2338               then
2339                  Old_Counter_Val := Counter_Val;
2340                  Process_Declarations (Declarations (Decl), Preprocess);
2341
2342                  --  The nested package body is the last construct to contain
2343                  --  a controlled object.
2344
2345                  if Preprocess
2346                    and then Top_Level
2347                    and then No (Last_Top_Level_Ctrl_Construct)
2348                    and then Counter_Val > Old_Counter_Val
2349                  then
2350                     Last_Top_Level_Ctrl_Construct := Decl;
2351                  end if;
2352               end if;
2353
2354            --  Handle a rare case caused by a controlled transient object
2355            --  created as part of a record init proc. The variable is wrapped
2356            --  in a block, but the block is not associated with a transient
2357            --  scope.
2358
2359            elsif Nkind (Decl) = N_Block_Statement
2360              and then Inside_Init_Proc
2361            then
2362               Old_Counter_Val := Counter_Val;
2363
2364               if Present (Handled_Statement_Sequence (Decl)) then
2365                  Process_Declarations
2366                    (Statements (Handled_Statement_Sequence (Decl)),
2367                     Preprocess);
2368               end if;
2369
2370               Process_Declarations (Declarations (Decl), Preprocess);
2371
2372               --  Either the declaration or statement list of the block has a
2373               --  controlled object.
2374
2375               if Preprocess
2376                 and then Top_Level
2377                 and then No (Last_Top_Level_Ctrl_Construct)
2378                 and then Counter_Val > Old_Counter_Val
2379               then
2380                  Last_Top_Level_Ctrl_Construct := Decl;
2381               end if;
2382
2383            --  Handle the case where the original context has been wrapped in
2384            --  a block to avoid interference between exception handlers and
2385            --  At_End handlers. Treat the block as transparent and process its
2386            --  contents.
2387
2388            elsif Nkind (Decl) = N_Block_Statement
2389              and then Is_Finalization_Wrapper (Decl)
2390            then
2391               if Present (Handled_Statement_Sequence (Decl)) then
2392                  Process_Declarations
2393                    (Statements (Handled_Statement_Sequence (Decl)),
2394                     Preprocess);
2395               end if;
2396
2397               Process_Declarations (Declarations (Decl), Preprocess);
2398            end if;
2399
2400            Prev_Non_Pragma (Decl);
2401         end loop;
2402      end Process_Declarations;
2403
2404      --------------------------------
2405      -- Process_Object_Declaration --
2406      --------------------------------
2407
2408      procedure Process_Object_Declaration
2409        (Decl         : Node_Id;
2410         Has_No_Init  : Boolean := False;
2411         Is_Protected : Boolean := False)
2412      is
2413         Loc    : constant Source_Ptr := Sloc (Decl);
2414         Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
2415
2416         Init_Typ : Entity_Id;
2417         --  The initialization type of the related object declaration. Note
2418         --  that this is not necessarily the same type as Obj_Typ because of
2419         --  possible type derivations.
2420
2421         Obj_Typ : Entity_Id;
2422         --  The type of the related object declaration
2423
2424         function Build_BIP_Cleanup_Stmts (Func_Id : Entity_Id) return Node_Id;
2425         --  Func_Id denotes a build-in-place function. Generate the following
2426         --  cleanup code:
2427         --
2428         --    if BIPallocfrom > Secondary_Stack'Pos
2429         --      and then BIPfinalizationmaster /= null
2430         --    then
2431         --       declare
2432         --          type Ptr_Typ is access Obj_Typ;
2433         --          for Ptr_Typ'Storage_Pool
2434         --            use Base_Pool (BIPfinalizationmaster);
2435         --       begin
2436         --          Free (Ptr_Typ (Temp));
2437         --       end;
2438         --    end if;
2439         --
2440         --  Obj_Typ is the type of the current object, Temp is the original
2441         --  allocation which Obj_Id renames.
2442
2443         procedure Find_Last_Init
2444           (Last_Init   : out Node_Id;
2445            Body_Insert : out Node_Id);
2446         --  Find the last initialization call related to object declaration
2447         --  Decl. Last_Init denotes the last initialization call which follows
2448         --  Decl. Body_Insert denotes a node where the finalizer body could be
2449         --  potentially inserted after (if blocks are involved).
2450
2451         -----------------------------
2452         -- Build_BIP_Cleanup_Stmts --
2453         -----------------------------
2454
2455         function Build_BIP_Cleanup_Stmts
2456           (Func_Id : Entity_Id) return Node_Id
2457         is
2458            Decls      : constant List_Id := New_List;
2459            Fin_Mas_Id : constant Entity_Id :=
2460                           Build_In_Place_Formal
2461                             (Func_Id, BIP_Finalization_Master);
2462            Func_Typ   : constant Entity_Id := Etype (Func_Id);
2463            Temp_Id    : constant Entity_Id :=
2464                           Entity (Prefix (Name (Parent (Obj_Id))));
2465
2466            Cond      : Node_Id;
2467            Free_Blk  : Node_Id;
2468            Free_Stmt : Node_Id;
2469            Pool_Id   : Entity_Id;
2470            Ptr_Typ   : Entity_Id;
2471
2472         begin
2473            --  Generate:
2474            --    Pool_Id renames Base_Pool (BIPfinalizationmaster.all).all;
2475
2476            Pool_Id := Make_Temporary (Loc, 'P');
2477
2478            Append_To (Decls,
2479              Make_Object_Renaming_Declaration (Loc,
2480                Defining_Identifier => Pool_Id,
2481                Subtype_Mark        =>
2482                  New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc),
2483                Name                =>
2484                  Make_Explicit_Dereference (Loc,
2485                    Prefix =>
2486                      Make_Function_Call (Loc,
2487                        Name                   =>
2488                          New_Occurrence_Of (RTE (RE_Base_Pool), Loc),
2489                        Parameter_Associations => New_List (
2490                          Make_Explicit_Dereference (Loc,
2491                            Prefix =>
2492                              New_Occurrence_Of (Fin_Mas_Id, Loc)))))));
2493
2494            --  Create an access type which uses the storage pool of the
2495            --  caller's finalization master.
2496
2497            --  Generate:
2498            --    type Ptr_Typ is access Func_Typ;
2499
2500            Ptr_Typ := Make_Temporary (Loc, 'P');
2501
2502            Append_To (Decls,
2503              Make_Full_Type_Declaration (Loc,
2504                Defining_Identifier => Ptr_Typ,
2505                Type_Definition     =>
2506                  Make_Access_To_Object_Definition (Loc,
2507                    Subtype_Indication => New_Occurrence_Of (Func_Typ, Loc))));
2508
2509            --  Perform minor decoration in order to set the master and the
2510            --  storage pool attributes.
2511
2512            Set_Ekind (Ptr_Typ, E_Access_Type);
2513            Set_Finalization_Master     (Ptr_Typ, Fin_Mas_Id);
2514            Set_Associated_Storage_Pool (Ptr_Typ, Pool_Id);
2515
2516            --  Create an explicit free statement. Note that the free uses the
2517            --  caller's pool expressed as a renaming.
2518
2519            Free_Stmt :=
2520              Make_Free_Statement (Loc,
2521                Expression =>
2522                  Unchecked_Convert_To (Ptr_Typ,
2523                    New_Occurrence_Of (Temp_Id, Loc)));
2524
2525            Set_Storage_Pool (Free_Stmt, Pool_Id);
2526
2527            --  Create a block to house the dummy type and the instantiation as
2528            --  well as to perform the cleanup the temporary.
2529
2530            --  Generate:
2531            --    declare
2532            --       <Decls>
2533            --    begin
2534            --       Free (Ptr_Typ (Temp_Id));
2535            --    end;
2536
2537            Free_Blk :=
2538              Make_Block_Statement (Loc,
2539                Declarations               => Decls,
2540                Handled_Statement_Sequence =>
2541                  Make_Handled_Sequence_Of_Statements (Loc,
2542                    Statements => New_List (Free_Stmt)));
2543
2544            --  Generate:
2545            --    if BIPfinalizationmaster /= null then
2546
2547            Cond :=
2548              Make_Op_Ne (Loc,
2549                Left_Opnd  => New_Occurrence_Of (Fin_Mas_Id, Loc),
2550                Right_Opnd => Make_Null (Loc));
2551
2552            --  For constrained or tagged results escalate the condition to
2553            --  include the allocation format. Generate:
2554
2555            --    if BIPallocform > Secondary_Stack'Pos
2556            --      and then BIPfinalizationmaster /= null
2557            --    then
2558
2559            if not Is_Constrained (Func_Typ)
2560              or else Is_Tagged_Type (Func_Typ)
2561            then
2562               declare
2563                  Alloc : constant Entity_Id :=
2564                            Build_In_Place_Formal (Func_Id, BIP_Alloc_Form);
2565               begin
2566                  Cond :=
2567                    Make_And_Then (Loc,
2568                      Left_Opnd  =>
2569                        Make_Op_Gt (Loc,
2570                          Left_Opnd  => New_Occurrence_Of (Alloc, Loc),
2571                          Right_Opnd =>
2572                            Make_Integer_Literal (Loc,
2573                              UI_From_Int
2574                                (BIP_Allocation_Form'Pos (Secondary_Stack)))),
2575
2576                      Right_Opnd => Cond);
2577               end;
2578            end if;
2579
2580            --  Generate:
2581            --    if <Cond> then
2582            --       <Free_Blk>
2583            --    end if;
2584
2585            return
2586              Make_If_Statement (Loc,
2587                Condition       => Cond,
2588                Then_Statements => New_List (Free_Blk));
2589         end Build_BIP_Cleanup_Stmts;
2590
2591         --------------------
2592         -- Find_Last_Init --
2593         --------------------
2594
2595         procedure Find_Last_Init
2596           (Last_Init   : out Node_Id;
2597            Body_Insert : out Node_Id)
2598         is
2599            function Find_Last_Init_In_Block (Blk : Node_Id) return Node_Id;
2600            --  Find the last initialization call within the statements of
2601            --  block Blk.
2602
2603            function Is_Init_Call (N : Node_Id) return Boolean;
2604            --  Determine whether node N denotes one of the initialization
2605            --  procedures of types Init_Typ or Obj_Typ.
2606
2607            function Next_Suitable_Statement (Stmt : Node_Id) return Node_Id;
2608            --  Obtain the next statement which follows list member Stmt while
2609            --  ignoring artifacts related to access-before-elaboration checks.
2610
2611            -----------------------------
2612            -- Find_Last_Init_In_Block --
2613            -----------------------------
2614
2615            function Find_Last_Init_In_Block (Blk : Node_Id) return Node_Id is
2616               HSS  : constant Node_Id := Handled_Statement_Sequence (Blk);
2617               Stmt : Node_Id;
2618
2619            begin
2620               --  Examine the individual statements of the block in reverse to
2621               --  locate the last initialization call.
2622
2623               if Present (HSS) and then Present (Statements (HSS)) then
2624                  Stmt := Last (Statements (HSS));
2625                  while Present (Stmt) loop
2626
2627                     --  Peek inside nested blocks in case aborts are allowed
2628
2629                     if Nkind (Stmt) = N_Block_Statement then
2630                        return Find_Last_Init_In_Block (Stmt);
2631
2632                     elsif Is_Init_Call (Stmt) then
2633                        return Stmt;
2634                     end if;
2635
2636                     Prev (Stmt);
2637                  end loop;
2638               end if;
2639
2640               return Empty;
2641            end Find_Last_Init_In_Block;
2642
2643            ------------------
2644            -- Is_Init_Call --
2645            ------------------
2646
2647            function Is_Init_Call (N : Node_Id) return Boolean is
2648               function Is_Init_Proc_Of
2649                 (Subp_Id : Entity_Id;
2650                  Typ     : Entity_Id) return Boolean;
2651               --  Determine whether subprogram Subp_Id is a valid init proc of
2652               --  type Typ.
2653
2654               ---------------------
2655               -- Is_Init_Proc_Of --
2656               ---------------------
2657
2658               function Is_Init_Proc_Of
2659                 (Subp_Id : Entity_Id;
2660                  Typ     : Entity_Id) return Boolean
2661               is
2662                  Deep_Init : Entity_Id := Empty;
2663                  Prim_Init : Entity_Id := Empty;
2664                  Type_Init : Entity_Id := Empty;
2665
2666               begin
2667                  --  Obtain all possible initialization routines of the
2668                  --  related type and try to match the subprogram entity
2669                  --  against one of them.
2670
2671                  --  Deep_Initialize
2672
2673                  Deep_Init := TSS (Typ, TSS_Deep_Initialize);
2674
2675                  --  Primitive Initialize
2676
2677                  if Is_Controlled (Typ) then
2678                     Prim_Init := Find_Optional_Prim_Op (Typ, Name_Initialize);
2679
2680                     if Present (Prim_Init) then
2681                        Prim_Init := Ultimate_Alias (Prim_Init);
2682                     end if;
2683                  end if;
2684
2685                  --  Type initialization routine
2686
2687                  if Has_Non_Null_Base_Init_Proc (Typ) then
2688                     Type_Init := Base_Init_Proc (Typ);
2689                  end if;
2690
2691                  return
2692                    (Present (Deep_Init) and then Subp_Id = Deep_Init)
2693                      or else
2694                    (Present (Prim_Init) and then Subp_Id = Prim_Init)
2695                      or else
2696                    (Present (Type_Init) and then Subp_Id = Type_Init);
2697               end Is_Init_Proc_Of;
2698
2699               --  Local variables
2700
2701               Call_Id : Entity_Id;
2702
2703            --  Start of processing for Is_Init_Call
2704
2705            begin
2706               if Nkind (N) = N_Procedure_Call_Statement
2707                 and then Nkind (Name (N)) = N_Identifier
2708               then
2709                  Call_Id := Entity (Name (N));
2710
2711                  --  Consider both the type of the object declaration and its
2712                  --  related initialization type.
2713
2714                  return
2715                    Is_Init_Proc_Of (Call_Id, Init_Typ)
2716                      or else
2717                    Is_Init_Proc_Of (Call_Id, Obj_Typ);
2718               end if;
2719
2720               return False;
2721            end Is_Init_Call;
2722
2723            -----------------------------
2724            -- Next_Suitable_Statement --
2725            -----------------------------
2726
2727            function Next_Suitable_Statement (Stmt : Node_Id) return Node_Id is
2728               Result : Node_Id;
2729
2730            begin
2731               --  Skip call markers and Program_Error raises installed by the
2732               --  ABE mechanism.
2733
2734               Result := Next (Stmt);
2735               while Present (Result) loop
2736                  if not Nkind_In (Result, N_Call_Marker,
2737                                           N_Raise_Program_Error)
2738                  then
2739                     exit;
2740                  end if;
2741
2742                  Result := Next (Result);
2743               end loop;
2744
2745               return Result;
2746            end Next_Suitable_Statement;
2747
2748            --  Local variables
2749
2750            Call   : Node_Id;
2751            Stmt   : Node_Id;
2752            Stmt_2 : Node_Id;
2753
2754            Deep_Init_Found : Boolean := False;
2755            --  A flag set when a call to [Deep_]Initialize has been found
2756
2757         --  Start of processing for Find_Last_Init
2758
2759         begin
2760            Last_Init   := Decl;
2761            Body_Insert := Empty;
2762
2763            --  Object renamings and objects associated with controlled
2764            --  function results do not require initialization.
2765
2766            if Has_No_Init then
2767               return;
2768            end if;
2769
2770            Stmt := Next_Suitable_Statement (Decl);
2771
2772            --  For an object with suppressed initialization, we check whether
2773            --  there is in fact no initialization expression. If there is not,
2774            --  then this is an object declaration that has been turned into a
2775            --  different object declaration that calls the build-in-place
2776            --  function in a 'Reference attribute, as in "F(...)'Reference".
2777            --  We search for that later object declaration, so that the
2778            --  Inc_Decl will be inserted after the call. Otherwise, if the
2779            --  call raises an exception, we will finalize the (uninitialized)
2780            --  object, which is wrong.
2781
2782            if No_Initialization (Decl) then
2783               if No (Expression (Last_Init)) then
2784                  loop
2785                     Last_Init := Next (Last_Init);
2786                     exit when No (Last_Init);
2787                     exit when Nkind (Last_Init) = N_Object_Declaration
2788                       and then Nkind (Expression (Last_Init)) = N_Reference
2789                       and then Nkind (Prefix (Expression (Last_Init))) =
2790                                  N_Function_Call
2791                       and then Is_Expanded_Build_In_Place_Call
2792                                  (Prefix (Expression (Last_Init)));
2793                  end loop;
2794               end if;
2795
2796               return;
2797
2798            --  In all other cases the initialization calls follow the related
2799            --  object. The general structure of object initialization built by
2800            --  routine Default_Initialize_Object is as follows:
2801
2802            --   [begin                                --  aborts allowed
2803            --       Abort_Defer;]
2804            --       Type_Init_Proc (Obj);
2805            --      [begin]                            --  exceptions allowed
2806            --          Deep_Initialize (Obj);
2807            --      [exception                         --  exceptions allowed
2808            --          when others =>
2809            --             Deep_Finalize (Obj, Self => False);
2810            --             raise;
2811            --       end;]
2812            --   [at end                               --  aborts allowed
2813            --       Abort_Undefer;
2814            --    end;]
2815
2816            --  When aborts are allowed, the initialization calls are housed
2817            --  within a block.
2818
2819            elsif Nkind (Stmt) = N_Block_Statement then
2820               Last_Init   := Find_Last_Init_In_Block (Stmt);
2821               Body_Insert := Stmt;
2822
2823            --  Otherwise the initialization calls follow the related object
2824
2825            else
2826               Stmt_2 := Next_Suitable_Statement (Stmt);
2827
2828               --  Check for an optional call to Deep_Initialize which may
2829               --  appear within a block depending on whether the object has
2830               --  controlled components.
2831
2832               if Present (Stmt_2) then
2833                  if Nkind (Stmt_2) = N_Block_Statement then
2834                     Call := Find_Last_Init_In_Block (Stmt_2);
2835
2836                     if Present (Call) then
2837                        Deep_Init_Found := True;
2838                        Last_Init       := Call;
2839                        Body_Insert     := Stmt_2;
2840                     end if;
2841
2842                  elsif Is_Init_Call (Stmt_2) then
2843                     Deep_Init_Found := True;
2844                     Last_Init       := Stmt_2;
2845                     Body_Insert     := Last_Init;
2846                  end if;
2847               end if;
2848
2849               --  If the object lacks a call to Deep_Initialize, then it must
2850               --  have a call to its related type init proc.
2851
2852               if not Deep_Init_Found and then Is_Init_Call (Stmt) then
2853                  Last_Init   := Stmt;
2854                  Body_Insert := Last_Init;
2855               end if;
2856            end if;
2857         end Find_Last_Init;
2858
2859         --  Local variables
2860
2861         Body_Ins  : Node_Id;
2862         Count_Ins : Node_Id;
2863         Fin_Call  : Node_Id;
2864         Fin_Stmts : List_Id := No_List;
2865         Inc_Decl  : Node_Id;
2866         Label     : Node_Id;
2867         Label_Id  : Entity_Id;
2868         Obj_Ref   : Node_Id;
2869
2870      --  Start of processing for Process_Object_Declaration
2871
2872      begin
2873         --  Handle the object type and the reference to the object
2874
2875         Obj_Ref := New_Occurrence_Of (Obj_Id, Loc);
2876         Obj_Typ := Base_Type (Etype (Obj_Id));
2877
2878         loop
2879            if Is_Access_Type (Obj_Typ) then
2880               Obj_Typ := Directly_Designated_Type (Obj_Typ);
2881               Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);
2882
2883            elsif Is_Concurrent_Type (Obj_Typ)
2884              and then Present (Corresponding_Record_Type (Obj_Typ))
2885            then
2886               Obj_Typ := Corresponding_Record_Type (Obj_Typ);
2887               Obj_Ref := Unchecked_Convert_To (Obj_Typ, Obj_Ref);
2888
2889            elsif Is_Private_Type (Obj_Typ)
2890              and then Present (Full_View (Obj_Typ))
2891            then
2892               Obj_Typ := Full_View (Obj_Typ);
2893               Obj_Ref := Unchecked_Convert_To (Obj_Typ, Obj_Ref);
2894
2895            elsif Obj_Typ /= Base_Type (Obj_Typ) then
2896               Obj_Typ := Base_Type (Obj_Typ);
2897               Obj_Ref := Unchecked_Convert_To (Obj_Typ, Obj_Ref);
2898
2899            else
2900               exit;
2901            end if;
2902         end loop;
2903
2904         Set_Etype (Obj_Ref, Obj_Typ);
2905
2906         --  Handle the initialization type of the object declaration
2907
2908         Init_Typ := Obj_Typ;
2909         loop
2910            if Is_Private_Type (Init_Typ)
2911              and then Present (Full_View (Init_Typ))
2912            then
2913               Init_Typ := Full_View (Init_Typ);
2914
2915            elsif Is_Untagged_Derivation (Init_Typ) then
2916               Init_Typ := Root_Type (Init_Typ);
2917
2918            else
2919               exit;
2920            end if;
2921         end loop;
2922
2923         --  Set a new value for the state counter and insert the statement
2924         --  after the object declaration. Generate:
2925
2926         --    Counter := <value>;
2927
2928         Inc_Decl :=
2929           Make_Assignment_Statement (Loc,
2930             Name       => New_Occurrence_Of (Counter_Id, Loc),
2931             Expression => Make_Integer_Literal (Loc, Counter_Val));
2932
2933         --  Insert the counter after all initialization has been done. The
2934         --  place of insertion depends on the context.
2935
2936         if Ekind_In (Obj_Id, E_Constant, E_Variable) then
2937
2938            --  The object is initialized by a build-in-place function call.
2939            --  The counter insertion point is after the function call.
2940
2941            if Present (BIP_Initialization_Call (Obj_Id)) then
2942               Count_Ins := BIP_Initialization_Call (Obj_Id);
2943               Body_Ins  := Empty;
2944
2945            --  The object is initialized by an aggregate. Insert the counter
2946            --  after the last aggregate assignment.
2947
2948            elsif Present (Last_Aggregate_Assignment (Obj_Id)) then
2949               Count_Ins := Last_Aggregate_Assignment (Obj_Id);
2950               Body_Ins  := Empty;
2951
2952            --  In all other cases the counter is inserted after the last call
2953            --  to either [Deep_]Initialize or the type-specific init proc.
2954
2955            else
2956               Find_Last_Init (Count_Ins, Body_Ins);
2957            end if;
2958
2959         --  In all other cases the counter is inserted after the last call to
2960         --  either [Deep_]Initialize or the type-specific init proc.
2961
2962         else
2963            Find_Last_Init (Count_Ins, Body_Ins);
2964         end if;
2965
2966         --  If the Initialize function is null or trivial, the call will have
2967         --  been replaced with a null statement, in which case place counter
2968         --  declaration after object declaration itself.
2969
2970         if No (Count_Ins) then
2971            Count_Ins := Decl;
2972         end if;
2973
2974         Insert_After (Count_Ins, Inc_Decl);
2975         Analyze (Inc_Decl);
2976
2977         --  If the current declaration is the last in the list, the finalizer
2978         --  body needs to be inserted after the set counter statement for the
2979         --  current object declaration. This is complicated by the fact that
2980         --  the set counter statement may appear in abort deferred block. In
2981         --  that case, the proper insertion place is after the block.
2982
2983         if No (Finalizer_Insert_Nod) then
2984
2985            --  Insertion after an abort deferred block
2986
2987            if Present (Body_Ins) then
2988               Finalizer_Insert_Nod := Body_Ins;
2989            else
2990               Finalizer_Insert_Nod := Inc_Decl;
2991            end if;
2992         end if;
2993
2994         --  Create the associated label with this object, generate:
2995
2996         --    L<counter> : label;
2997
2998         Label_Id :=
2999           Make_Identifier (Loc, New_External_Name ('L', Counter_Val));
3000         Set_Entity
3001           (Label_Id, Make_Defining_Identifier (Loc, Chars (Label_Id)));
3002         Label := Make_Label (Loc, Label_Id);
3003
3004         Prepend_To (Finalizer_Decls,
3005           Make_Implicit_Label_Declaration (Loc,
3006             Defining_Identifier => Entity (Label_Id),
3007             Label_Construct     => Label));
3008
3009         --  Create the associated jump with this object, generate:
3010
3011         --    when <counter> =>
3012         --       goto L<counter>;
3013
3014         Prepend_To (Jump_Alts,
3015           Make_Case_Statement_Alternative (Loc,
3016             Discrete_Choices => New_List (
3017               Make_Integer_Literal (Loc, Counter_Val)),
3018             Statements       => New_List (
3019               Make_Goto_Statement (Loc,
3020                 Name => New_Occurrence_Of (Entity (Label_Id), Loc)))));
3021
3022         --  Insert the jump destination, generate:
3023
3024         --     <<L<counter>>>
3025
3026         Append_To (Finalizer_Stmts, Label);
3027
3028         --  Processing for simple protected objects. Such objects require
3029         --  manual finalization of their lock managers.
3030
3031         if Is_Protected then
3032            if Is_Simple_Protected_Type (Obj_Typ) then
3033               Fin_Call := Cleanup_Protected_Object (Decl, Obj_Ref);
3034
3035               if Present (Fin_Call) then
3036                  Fin_Stmts := New_List (Fin_Call);
3037               end if;
3038
3039            elsif Has_Simple_Protected_Object (Obj_Typ) then
3040               if Is_Record_Type (Obj_Typ) then
3041                  Fin_Stmts := Cleanup_Record (Decl, Obj_Ref, Obj_Typ);
3042               elsif Is_Array_Type (Obj_Typ) then
3043                  Fin_Stmts := Cleanup_Array (Decl, Obj_Ref, Obj_Typ);
3044               end if;
3045            end if;
3046
3047            --  Generate:
3048            --    begin
3049            --       System.Tasking.Protected_Objects.Finalize_Protection
3050            --         (Obj._object);
3051
3052            --    exception
3053            --       when others =>
3054            --          null;
3055            --    end;
3056
3057            if Present (Fin_Stmts) and then Exceptions_OK then
3058               Fin_Stmts := New_List (
3059                 Make_Block_Statement (Loc,
3060                   Handled_Statement_Sequence =>
3061                     Make_Handled_Sequence_Of_Statements (Loc,
3062                       Statements         => Fin_Stmts,
3063
3064                       Exception_Handlers => New_List (
3065                         Make_Exception_Handler (Loc,
3066                           Exception_Choices => New_List (
3067                             Make_Others_Choice (Loc)),
3068
3069                           Statements     => New_List (
3070                             Make_Null_Statement (Loc)))))));
3071            end if;
3072
3073         --  Processing for regular controlled objects
3074
3075         else
3076            --  Generate:
3077            --    begin
3078            --       [Deep_]Finalize (Obj);
3079
3080            --    exception
3081            --       when Id : others =>
3082            --          if not Raised then
3083            --             Raised := True;
3084            --             Save_Occurrence (E, Id);
3085            --          end if;
3086            --    end;
3087
3088            Fin_Call :=
3089              Make_Final_Call (
3090                Obj_Ref => Obj_Ref,
3091                Typ     => Obj_Typ);
3092
3093            --  Guard against a missing [Deep_]Finalize when the object type
3094            --  was not properly frozen.
3095
3096            if No (Fin_Call) then
3097               Fin_Call := Make_Null_Statement (Loc);
3098            end if;
3099
3100            --  For CodePeer, the exception handlers normally generated here
3101            --  generate complex flowgraphs which result in capacity problems.
3102            --  Omitting these handlers for CodePeer is justified as follows:
3103
3104            --    If a handler is dead, then omitting it is surely ok
3105
3106            --    If a handler is live, then CodePeer should flag the
3107            --      potentially-exception-raising construct that causes it
3108            --      to be live. That is what we are interested in, not what
3109            --      happens after the exception is raised.
3110
3111            if Exceptions_OK and not CodePeer_Mode then
3112               Fin_Stmts := New_List (
3113                 Make_Block_Statement (Loc,
3114                   Handled_Statement_Sequence =>
3115                     Make_Handled_Sequence_Of_Statements (Loc,
3116                       Statements => New_List (Fin_Call),
3117
3118                    Exception_Handlers => New_List (
3119                      Build_Exception_Handler
3120                        (Finalizer_Data, For_Package)))));
3121
3122            --  When exception handlers are prohibited, the finalization call
3123            --  appears unprotected. Any exception raised during finalization
3124            --  will bypass the circuitry which ensures the cleanup of all
3125            --  remaining objects.
3126
3127            else
3128               Fin_Stmts := New_List (Fin_Call);
3129            end if;
3130
3131            --  If we are dealing with a return object of a build-in-place
3132            --  function, generate the following cleanup statements:
3133
3134            --    if BIPallocfrom > Secondary_Stack'Pos
3135            --      and then BIPfinalizationmaster /= null
3136            --    then
3137            --       declare
3138            --          type Ptr_Typ is access Obj_Typ;
3139            --          for Ptr_Typ'Storage_Pool use
3140            --                Base_Pool (BIPfinalizationmaster.all).all;
3141            --       begin
3142            --          Free (Ptr_Typ (Temp));
3143            --       end;
3144            --    end if;
3145
3146            --  The generated code effectively detaches the temporary from the
3147            --  caller finalization master and deallocates the object.
3148
3149            if Is_Return_Object (Obj_Id) then
3150               declare
3151                  Func_Id : constant Entity_Id := Enclosing_Function (Obj_Id);
3152               begin
3153                  if Is_Build_In_Place_Function (Func_Id)
3154                    and then Needs_BIP_Finalization_Master (Func_Id)
3155                  then
3156                     Append_To (Fin_Stmts, Build_BIP_Cleanup_Stmts (Func_Id));
3157                  end if;
3158               end;
3159            end if;
3160
3161            if Ekind_In (Obj_Id, E_Constant, E_Variable)
3162              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
3163            then
3164               --  Temporaries created for the purpose of "exporting" a
3165               --  transient object out of an Expression_With_Actions (EWA)
3166               --  need guards. The following illustrates the usage of such
3167               --  temporaries.
3168
3169               --    Access_Typ : access [all] Obj_Typ;
3170               --    Temp       : Access_Typ := null;
3171               --    <Counter>  := ...;
3172
3173               --    do
3174               --       Ctrl_Trans : [access [all]] Obj_Typ := ...;
3175               --       Temp := Access_Typ (Ctrl_Trans);  --  when a pointer
3176               --         <or>
3177               --       Temp := Ctrl_Trans'Unchecked_Access;
3178               --    in ... end;
3179
3180               --  The finalization machinery does not process EWA nodes as
3181               --  this may lead to premature finalization of expressions. Note
3182               --  that Temp is marked as being properly initialized regardless
3183               --  of whether the initialization of Ctrl_Trans succeeded. Since
3184               --  a failed initialization may leave Temp with a value of null,
3185               --  add a guard to handle this case:
3186
3187               --    if Obj /= null then
3188               --       <object finalization statements>
3189               --    end if;
3190
3191               if Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
3192                                                      N_Object_Declaration
3193               then
3194                  Fin_Stmts := New_List (
3195                    Make_If_Statement (Loc,
3196                      Condition       =>
3197                        Make_Op_Ne (Loc,
3198                          Left_Opnd  => New_Occurrence_Of (Obj_Id, Loc),
3199                          Right_Opnd => Make_Null (Loc)),
3200                      Then_Statements => Fin_Stmts));
3201
3202               --  Return objects use a flag to aid in processing their
3203               --  potential finalization when the enclosing function fails
3204               --  to return properly. Generate:
3205
3206               --    if not Flag then
3207               --       <object finalization statements>
3208               --    end if;
3209
3210               else
3211                  Fin_Stmts := New_List (
3212                    Make_If_Statement (Loc,
3213                      Condition     =>
3214                        Make_Op_Not (Loc,
3215                          Right_Opnd =>
3216                            New_Occurrence_Of
3217                              (Status_Flag_Or_Transient_Decl (Obj_Id), Loc)),
3218
3219                    Then_Statements => Fin_Stmts));
3220               end if;
3221            end if;
3222         end if;
3223
3224         Append_List_To (Finalizer_Stmts, Fin_Stmts);
3225
3226         --  Since the declarations are examined in reverse, the state counter
3227         --  must be decremented in order to keep with the true position of
3228         --  objects.
3229
3230         Counter_Val := Counter_Val - 1;
3231      end Process_Object_Declaration;
3232
3233      -------------------------------------
3234      -- Process_Tagged_Type_Declaration --
3235      -------------------------------------
3236
3237      procedure Process_Tagged_Type_Declaration (Decl : Node_Id) is
3238         Typ    : constant Entity_Id := Defining_Identifier (Decl);
3239         DT_Ptr : constant Entity_Id :=
3240                    Node (First_Elmt (Access_Disp_Table (Typ)));
3241      begin
3242         --  Generate:
3243         --    Ada.Tags.Unregister_Tag (<Typ>P);
3244
3245         Append_To (Tagged_Type_Stmts,
3246           Make_Procedure_Call_Statement (Loc,
3247             Name                   =>
3248               New_Occurrence_Of (RTE (RE_Unregister_Tag), Loc),
3249             Parameter_Associations => New_List (
3250               New_Occurrence_Of (DT_Ptr, Loc))));
3251      end Process_Tagged_Type_Declaration;
3252
3253   --  Start of processing for Build_Finalizer
3254
3255   begin
3256      Fin_Id := Empty;
3257
3258      --  Do not perform this expansion in SPARK mode because it is not
3259      --  necessary.
3260
3261      if GNATprove_Mode then
3262         return;
3263      end if;
3264
3265      --  Step 1: Extract all lists which may contain controlled objects or
3266      --  library-level tagged types.
3267
3268      if For_Package_Spec then
3269         Decls      := Visible_Declarations (Specification (N));
3270         Priv_Decls := Private_Declarations (Specification (N));
3271
3272         --  Retrieve the package spec id
3273
3274         Spec_Id := Defining_Unit_Name (Specification (N));
3275
3276         if Nkind (Spec_Id) = N_Defining_Program_Unit_Name then
3277            Spec_Id := Defining_Identifier (Spec_Id);
3278         end if;
3279
3280      --  Accept statement, block, entry body, package body, protected body,
3281      --  subprogram body or task body.
3282
3283      else
3284         Decls := Declarations (N);
3285         HSS   := Handled_Statement_Sequence (N);
3286
3287         if Present (HSS) then
3288            if Present (Statements (HSS)) then
3289               Stmts := Statements (HSS);
3290            end if;
3291
3292            if Present (At_End_Proc (HSS)) then
3293               Prev_At_End := At_End_Proc (HSS);
3294            end if;
3295         end if;
3296
3297         --  Retrieve the package spec id for package bodies
3298
3299         if For_Package_Body then
3300            Spec_Id := Corresponding_Spec (N);
3301         end if;
3302      end if;
3303
3304      --  Do not process nested packages since those are handled by the
3305      --  enclosing scope's finalizer. Do not process non-expanded package
3306      --  instantiations since those will be re-analyzed and re-expanded.
3307
3308      if For_Package
3309        and then
3310          (not Is_Library_Level_Entity (Spec_Id)
3311
3312            --  Nested packages are considered to be library level entities,
3313            --  but do not need to be processed separately. True library level
3314            --  packages have a scope value of 1.
3315
3316            or else Scope_Depth_Value (Spec_Id) /= Uint_1
3317            or else (Is_Generic_Instance (Spec_Id)
3318                      and then Package_Instantiation (Spec_Id) /= N))
3319      then
3320         return;
3321      end if;
3322
3323      --  Step 2: Object [pre]processing
3324
3325      if For_Package then
3326
3327         --  Preprocess the visible declarations now in order to obtain the
3328         --  correct number of controlled object by the time the private
3329         --  declarations are processed.
3330
3331         Process_Declarations (Decls, Preprocess => True, Top_Level => True);
3332
3333         --  From all the possible contexts, only package specifications may
3334         --  have private declarations.
3335
3336         if For_Package_Spec then
3337            Process_Declarations
3338              (Priv_Decls, Preprocess => True, Top_Level => True);
3339         end if;
3340
3341         --  The current context may lack controlled objects, but require some
3342         --  other form of completion (task termination for instance). In such
3343         --  cases, the finalizer must be created and carry the additional
3344         --  statements.
3345
3346         if Acts_As_Clean or Has_Ctrl_Objs or Has_Tagged_Types then
3347            Build_Components;
3348         end if;
3349
3350         --  The preprocessing has determined that the context has controlled
3351         --  objects or library-level tagged types.
3352
3353         if Has_Ctrl_Objs or Has_Tagged_Types then
3354
3355            --  Private declarations are processed first in order to preserve
3356            --  possible dependencies between public and private objects.
3357
3358            if For_Package_Spec then
3359               Process_Declarations (Priv_Decls);
3360            end if;
3361
3362            Process_Declarations (Decls);
3363         end if;
3364
3365      --  Non-package case
3366
3367      else
3368         --  Preprocess both declarations and statements
3369
3370         Process_Declarations (Decls, Preprocess => True, Top_Level => True);
3371         Process_Declarations (Stmts, Preprocess => True, Top_Level => True);
3372
3373         --  At this point it is known that N has controlled objects. Ensure
3374         --  that N has a declarative list since the finalizer spec will be
3375         --  attached to it.
3376
3377         if Has_Ctrl_Objs and then No (Decls) then
3378            Set_Declarations (N, New_List);
3379            Decls      := Declarations (N);
3380            Spec_Decls := Decls;
3381         end if;
3382
3383         --  The current context may lack controlled objects, but require some
3384         --  other form of completion (task termination for instance). In such
3385         --  cases, the finalizer must be created and carry the additional
3386         --  statements.
3387
3388         if Acts_As_Clean or Has_Ctrl_Objs or Has_Tagged_Types then
3389            Build_Components;
3390         end if;
3391
3392         if Has_Ctrl_Objs or Has_Tagged_Types then
3393            Process_Declarations (Stmts);
3394            Process_Declarations (Decls);
3395         end if;
3396      end if;
3397
3398      --  Step 3: Finalizer creation
3399
3400      if Acts_As_Clean or Has_Ctrl_Objs or Has_Tagged_Types then
3401         Create_Finalizer;
3402      end if;
3403   end Build_Finalizer;
3404
3405   --------------------------
3406   -- Build_Finalizer_Call --
3407   --------------------------
3408
3409   procedure Build_Finalizer_Call (N : Node_Id; Fin_Id : Entity_Id) is
3410      Is_Prot_Body : constant Boolean :=
3411                       Nkind (N) = N_Subprogram_Body
3412                         and then Is_Protected_Subprogram_Body (N);
3413      --  Determine whether N denotes the protected version of a subprogram
3414      --  which belongs to a protected type.
3415
3416      Loc : constant Source_Ptr := Sloc (N);
3417      HSS : Node_Id;
3418
3419   begin
3420      --  Do not perform this expansion in SPARK mode because we do not create
3421      --  finalizers in the first place.
3422
3423      if GNATprove_Mode then
3424         return;
3425      end if;
3426
3427      --  The At_End handler should have been assimilated by the finalizer
3428
3429      HSS := Handled_Statement_Sequence (N);
3430      pragma Assert (No (At_End_Proc (HSS)));
3431
3432      --  If the construct to be cleaned up is a protected subprogram body, the
3433      --  finalizer call needs to be associated with the block which wraps the
3434      --  unprotected version of the subprogram. The following illustrates this
3435      --  scenario:
3436
3437      --     procedure Prot_SubpP is
3438      --        procedure finalizer is
3439      --        begin
3440      --           Service_Entries (Prot_Obj);
3441      --           Abort_Undefer;
3442      --        end finalizer;
3443
3444      --     begin
3445      --        . . .
3446      --        begin
3447      --           Prot_SubpN (Prot_Obj);
3448      --        at end
3449      --           finalizer;
3450      --        end;
3451      --     end Prot_SubpP;
3452
3453      if Is_Prot_Body then
3454         HSS := Handled_Statement_Sequence (Last (Statements (HSS)));
3455
3456      --  An At_End handler and regular exception handlers cannot coexist in
3457      --  the same statement sequence. Wrap the original statements in a block.
3458
3459      elsif Present (Exception_Handlers (HSS)) then
3460         declare
3461            End_Lab : constant Node_Id := End_Label (HSS);
3462            Block   : Node_Id;
3463
3464         begin
3465            Block :=
3466              Make_Block_Statement (Loc, Handled_Statement_Sequence => HSS);
3467
3468            Set_Handled_Statement_Sequence (N,
3469              Make_Handled_Sequence_Of_Statements (Loc, New_List (Block)));
3470
3471            HSS := Handled_Statement_Sequence (N);
3472            Set_End_Label (HSS, End_Lab);
3473         end;
3474      end if;
3475
3476      Set_At_End_Proc (HSS, New_Occurrence_Of (Fin_Id, Loc));
3477
3478      Analyze (At_End_Proc (HSS));
3479      Expand_At_End_Handler (HSS, Empty);
3480   end Build_Finalizer_Call;
3481
3482   ---------------------
3483   -- Build_Late_Proc --
3484   ---------------------
3485
3486   procedure Build_Late_Proc (Typ : Entity_Id; Nam : Name_Id) is
3487   begin
3488      for Final_Prim in Name_Of'Range loop
3489         if Name_Of (Final_Prim) = Nam then
3490            Set_TSS (Typ,
3491              Make_Deep_Proc
3492                (Prim  => Final_Prim,
3493                 Typ   => Typ,
3494                 Stmts => Make_Deep_Record_Body (Final_Prim, Typ)));
3495         end if;
3496      end loop;
3497   end Build_Late_Proc;
3498
3499   -------------------------------
3500   -- Build_Object_Declarations --
3501   -------------------------------
3502
3503   procedure Build_Object_Declarations
3504     (Data        : out Finalization_Exception_Data;
3505      Decls       : List_Id;
3506      Loc         : Source_Ptr;
3507      For_Package : Boolean := False)
3508   is
3509      Decl : Node_Id;
3510
3511      Dummy : Entity_Id;
3512      --  This variable captures an unused dummy internal entity, see the
3513      --  comment associated with its use.
3514
3515   begin
3516      pragma Assert (Decls /= No_List);
3517
3518      --  Always set the proper location as it may be needed even when
3519      --  exception propagation is forbidden.
3520
3521      Data.Loc := Loc;
3522
3523      if Restriction_Active (No_Exception_Propagation) then
3524         Data.Abort_Id  := Empty;
3525         Data.E_Id      := Empty;
3526         Data.Raised_Id := Empty;
3527         return;
3528      end if;
3529
3530      Data.Raised_Id := Make_Temporary (Loc, 'R');
3531
3532      --  In certain scenarios, finalization can be triggered by an abort. If
3533      --  the finalization itself fails and raises an exception, the resulting
3534      --  Program_Error must be supressed and replaced by an abort signal. In
3535      --  order to detect this scenario, save the state of entry into the
3536      --  finalization code.
3537
3538      --  This is not needed for library-level finalizers as they are called by
3539      --  the environment task and cannot be aborted.
3540
3541      if not For_Package then
3542         if Abort_Allowed then
3543            Data.Abort_Id := Make_Temporary (Loc, 'A');
3544
3545            --  Generate:
3546            --    Abort_Id : constant Boolean := <A_Expr>;
3547
3548            Append_To (Decls,
3549              Make_Object_Declaration (Loc,
3550                Defining_Identifier => Data.Abort_Id,
3551                Constant_Present    => True,
3552                Object_Definition   =>
3553                  New_Occurrence_Of (Standard_Boolean, Loc),
3554                Expression          =>
3555                  New_Occurrence_Of (RTE (RE_Triggered_By_Abort), Loc)));
3556
3557         --  Abort is not required
3558
3559         else
3560            --  Generate a dummy entity to ensure that the internal symbols are
3561            --  in sync when a unit is compiled with and without aborts.
3562
3563            Dummy := Make_Temporary (Loc, 'A');
3564            Data.Abort_Id := Empty;
3565         end if;
3566
3567      --  Library-level finalizers
3568
3569      else
3570         Data.Abort_Id := Empty;
3571      end if;
3572
3573      if Exception_Extra_Info then
3574         Data.E_Id := Make_Temporary (Loc, 'E');
3575
3576         --  Generate:
3577         --    E_Id : Exception_Occurrence;
3578
3579         Decl :=
3580           Make_Object_Declaration (Loc,
3581             Defining_Identifier => Data.E_Id,
3582             Object_Definition   =>
3583               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc));
3584         Set_No_Initialization (Decl);
3585
3586         Append_To (Decls, Decl);
3587
3588      else
3589         Data.E_Id := Empty;
3590      end if;
3591
3592      --  Generate:
3593      --    Raised_Id : Boolean := False;
3594
3595      Append_To (Decls,
3596        Make_Object_Declaration (Loc,
3597          Defining_Identifier => Data.Raised_Id,
3598          Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
3599          Expression          => New_Occurrence_Of (Standard_False, Loc)));
3600   end Build_Object_Declarations;
3601
3602   ---------------------------
3603   -- Build_Raise_Statement --
3604   ---------------------------
3605
3606   function Build_Raise_Statement
3607     (Data : Finalization_Exception_Data) return Node_Id
3608   is
3609      Stmt : Node_Id;
3610      Expr : Node_Id;
3611
3612   begin
3613      --  Standard run-time use the specialized routine
3614      --  Raise_From_Controlled_Operation.
3615
3616      if Exception_Extra_Info
3617        and then RTE_Available (RE_Raise_From_Controlled_Operation)
3618      then
3619         Stmt :=
3620           Make_Procedure_Call_Statement (Data.Loc,
3621              Name                   =>
3622                New_Occurrence_Of
3623                  (RTE (RE_Raise_From_Controlled_Operation), Data.Loc),
3624              Parameter_Associations =>
3625                New_List (New_Occurrence_Of (Data.E_Id, Data.Loc)));
3626
3627      --  Restricted run-time: exception messages are not supported and hence
3628      --  Raise_From_Controlled_Operation is not supported. Raise Program_Error
3629      --  instead.
3630
3631      else
3632         Stmt :=
3633           Make_Raise_Program_Error (Data.Loc,
3634             Reason => PE_Finalize_Raised_Exception);
3635      end if;
3636
3637      --  Generate:
3638
3639      --    Raised_Id and then not Abort_Id
3640      --      <or>
3641      --    Raised_Id
3642
3643      Expr := New_Occurrence_Of (Data.Raised_Id, Data.Loc);
3644
3645      if Present (Data.Abort_Id) then
3646         Expr := Make_And_Then (Data.Loc,
3647           Left_Opnd  => Expr,
3648           Right_Opnd =>
3649             Make_Op_Not (Data.Loc,
3650               Right_Opnd => New_Occurrence_Of (Data.Abort_Id, Data.Loc)));
3651      end if;
3652
3653      --  Generate:
3654
3655      --    if Raised_Id and then not Abort_Id then
3656      --       Raise_From_Controlled_Operation (E_Id);
3657      --         <or>
3658      --       raise Program_Error;  --  restricted runtime
3659      --    end if;
3660
3661      return
3662        Make_If_Statement (Data.Loc,
3663          Condition       => Expr,
3664          Then_Statements => New_List (Stmt));
3665   end Build_Raise_Statement;
3666
3667   -----------------------------
3668   -- Build_Record_Deep_Procs --
3669   -----------------------------
3670
3671   procedure Build_Record_Deep_Procs (Typ : Entity_Id) is
3672   begin
3673      Set_TSS (Typ,
3674        Make_Deep_Proc
3675          (Prim  => Initialize_Case,
3676           Typ   => Typ,
3677           Stmts => Make_Deep_Record_Body (Initialize_Case, Typ)));
3678
3679      if not Is_Limited_View (Typ) then
3680         Set_TSS (Typ,
3681           Make_Deep_Proc
3682             (Prim  => Adjust_Case,
3683              Typ   => Typ,
3684              Stmts => Make_Deep_Record_Body (Adjust_Case, Typ)));
3685      end if;
3686
3687      --  Do not generate Deep_Finalize and Finalize_Address if finalization is
3688      --  suppressed since these routine will not be used.
3689
3690      if not Restriction_Active (No_Finalization) then
3691         Set_TSS (Typ,
3692           Make_Deep_Proc
3693             (Prim  => Finalize_Case,
3694              Typ   => Typ,
3695              Stmts => Make_Deep_Record_Body (Finalize_Case, Typ)));
3696
3697         --  Create TSS primitive Finalize_Address (unless CodePeer_Mode)
3698
3699         if not CodePeer_Mode then
3700            Set_TSS (Typ,
3701              Make_Deep_Proc
3702                (Prim  => Address_Case,
3703                 Typ   => Typ,
3704                 Stmts => Make_Deep_Record_Body (Address_Case, Typ)));
3705         end if;
3706      end if;
3707   end Build_Record_Deep_Procs;
3708
3709   -------------------
3710   -- Cleanup_Array --
3711   -------------------
3712
3713   function Cleanup_Array
3714     (N    : Node_Id;
3715      Obj  : Node_Id;
3716      Typ  : Entity_Id) return List_Id
3717   is
3718      Loc        : constant Source_Ptr := Sloc (N);
3719      Index_List : constant List_Id := New_List;
3720
3721      function Free_Component return List_Id;
3722      --  Generate the code to finalize the task or protected  subcomponents
3723      --  of a single component of the array.
3724
3725      function Free_One_Dimension (Dim : Int) return List_Id;
3726      --  Generate a loop over one dimension of the array
3727
3728      --------------------
3729      -- Free_Component --
3730      --------------------
3731
3732      function Free_Component return List_Id is
3733         Stmts : List_Id := New_List;
3734         Tsk   : Node_Id;
3735         C_Typ : constant Entity_Id := Component_Type (Typ);
3736
3737      begin
3738         --  Component type is known to contain tasks or protected objects
3739
3740         Tsk :=
3741           Make_Indexed_Component (Loc,
3742             Prefix        => Duplicate_Subexpr_No_Checks (Obj),
3743             Expressions   => Index_List);
3744
3745         Set_Etype (Tsk, C_Typ);
3746
3747         if Is_Task_Type (C_Typ) then
3748            Append_To (Stmts, Cleanup_Task (N, Tsk));
3749
3750         elsif Is_Simple_Protected_Type (C_Typ) then
3751            Append_To (Stmts, Cleanup_Protected_Object (N, Tsk));
3752
3753         elsif Is_Record_Type (C_Typ) then
3754            Stmts := Cleanup_Record (N, Tsk, C_Typ);
3755
3756         elsif Is_Array_Type (C_Typ) then
3757            Stmts := Cleanup_Array (N, Tsk, C_Typ);
3758         end if;
3759
3760         return Stmts;
3761      end Free_Component;
3762
3763      ------------------------
3764      -- Free_One_Dimension --
3765      ------------------------
3766
3767      function Free_One_Dimension (Dim : Int) return List_Id is
3768         Index : Entity_Id;
3769
3770      begin
3771         if Dim > Number_Dimensions (Typ) then
3772            return Free_Component;
3773
3774         --  Here we generate the required loop
3775
3776         else
3777            Index := Make_Temporary (Loc, 'J');
3778            Append (New_Occurrence_Of (Index, Loc), Index_List);
3779
3780            return New_List (
3781              Make_Implicit_Loop_Statement (N,
3782                Identifier       => Empty,
3783                Iteration_Scheme =>
3784                  Make_Iteration_Scheme (Loc,
3785                    Loop_Parameter_Specification =>
3786                      Make_Loop_Parameter_Specification (Loc,
3787                        Defining_Identifier         => Index,
3788                        Discrete_Subtype_Definition =>
3789                          Make_Attribute_Reference (Loc,
3790                            Prefix          => Duplicate_Subexpr (Obj),
3791                            Attribute_Name  => Name_Range,
3792                            Expressions     => New_List (
3793                              Make_Integer_Literal (Loc, Dim))))),
3794                Statements       =>  Free_One_Dimension (Dim + 1)));
3795         end if;
3796      end Free_One_Dimension;
3797
3798   --  Start of processing for Cleanup_Array
3799
3800   begin
3801      return Free_One_Dimension (1);
3802   end Cleanup_Array;
3803
3804   --------------------
3805   -- Cleanup_Record --
3806   --------------------
3807
3808   function Cleanup_Record
3809     (N    : Node_Id;
3810      Obj  : Node_Id;
3811      Typ  : Entity_Id) return List_Id
3812   is
3813      Loc   : constant Source_Ptr := Sloc (N);
3814      Tsk   : Node_Id;
3815      Comp  : Entity_Id;
3816      Stmts : constant List_Id    := New_List;
3817      U_Typ : constant Entity_Id  := Underlying_Type (Typ);
3818
3819   begin
3820      if Has_Discriminants (U_Typ)
3821        and then Nkind (Parent (U_Typ)) = N_Full_Type_Declaration
3822        and then Nkind (Type_Definition (Parent (U_Typ))) = N_Record_Definition
3823        and then
3824          Present
3825            (Variant_Part (Component_List (Type_Definition (Parent (U_Typ)))))
3826      then
3827         --  For now, do not attempt to free a component that may appear in a
3828         --  variant, and instead issue a warning. Doing this "properly" would
3829         --  require building a case statement and would be quite a mess. Note
3830         --  that the RM only requires that free "work" for the case of a task
3831         --  access value, so already we go way beyond this in that we deal
3832         --  with the array case and non-discriminated record cases.
3833
3834         Error_Msg_N
3835           ("task/protected object in variant record will not be freed??", N);
3836         return New_List (Make_Null_Statement (Loc));
3837      end if;
3838
3839      Comp := First_Component (Typ);
3840      while Present (Comp) loop
3841         if Has_Task (Etype (Comp))
3842           or else Has_Simple_Protected_Object (Etype (Comp))
3843         then
3844            Tsk :=
3845              Make_Selected_Component (Loc,
3846                Prefix        => Duplicate_Subexpr_No_Checks (Obj),
3847                Selector_Name => New_Occurrence_Of (Comp, Loc));
3848            Set_Etype (Tsk, Etype (Comp));
3849
3850            if Is_Task_Type (Etype (Comp)) then
3851               Append_To (Stmts, Cleanup_Task (N, Tsk));
3852
3853            elsif Is_Simple_Protected_Type (Etype (Comp)) then
3854               Append_To (Stmts, Cleanup_Protected_Object (N, Tsk));
3855
3856            elsif Is_Record_Type (Etype (Comp)) then
3857
3858               --  Recurse, by generating the prefix of the argument to
3859               --  the eventual cleanup call.
3860
3861               Append_List_To (Stmts, Cleanup_Record (N, Tsk, Etype (Comp)));
3862
3863            elsif Is_Array_Type (Etype (Comp)) then
3864               Append_List_To (Stmts, Cleanup_Array (N, Tsk, Etype (Comp)));
3865            end if;
3866         end if;
3867
3868         Next_Component (Comp);
3869      end loop;
3870
3871      return Stmts;
3872   end Cleanup_Record;
3873
3874   ------------------------------
3875   -- Cleanup_Protected_Object --
3876   ------------------------------
3877
3878   function Cleanup_Protected_Object
3879     (N   : Node_Id;
3880      Ref : Node_Id) return Node_Id
3881   is
3882      Loc : constant Source_Ptr := Sloc (N);
3883
3884   begin
3885      --  For restricted run-time libraries (Ravenscar), tasks are
3886      --  non-terminating, and protected objects can only appear at library
3887      --  level, so we do not want finalization of protected objects.
3888
3889      if Restricted_Profile then
3890         return Empty;
3891
3892      else
3893         return
3894           Make_Procedure_Call_Statement (Loc,
3895             Name                   =>
3896               New_Occurrence_Of (RTE (RE_Finalize_Protection), Loc),
3897             Parameter_Associations => New_List (Concurrent_Ref (Ref)));
3898      end if;
3899   end Cleanup_Protected_Object;
3900
3901   ------------------
3902   -- Cleanup_Task --
3903   ------------------
3904
3905   function Cleanup_Task
3906     (N   : Node_Id;
3907      Ref : Node_Id) return Node_Id
3908   is
3909      Loc  : constant Source_Ptr := Sloc (N);
3910
3911   begin
3912      --  For restricted run-time libraries (Ravenscar), tasks are
3913      --  non-terminating and they can only appear at library level, so we do
3914      --  not want finalization of task objects.
3915
3916      if Restricted_Profile then
3917         return Empty;
3918
3919      else
3920         return
3921           Make_Procedure_Call_Statement (Loc,
3922             Name                   =>
3923               New_Occurrence_Of (RTE (RE_Free_Task), Loc),
3924             Parameter_Associations => New_List (Concurrent_Ref (Ref)));
3925      end if;
3926   end Cleanup_Task;
3927
3928   ------------------------------
3929   -- Check_Visibly_Controlled --
3930   ------------------------------
3931
3932   procedure Check_Visibly_Controlled
3933     (Prim : Final_Primitives;
3934      Typ  : Entity_Id;
3935      E    : in out Entity_Id;
3936      Cref : in out Node_Id)
3937   is
3938      Parent_Type : Entity_Id;
3939      Op          : Entity_Id;
3940
3941   begin
3942      if Is_Derived_Type (Typ)
3943        and then Comes_From_Source (E)
3944        and then not Present (Overridden_Operation (E))
3945      then
3946         --  We know that the explicit operation on the type does not override
3947         --  the inherited operation of the parent, and that the derivation
3948         --  is from a private type that is not visibly controlled.
3949
3950         Parent_Type := Etype (Typ);
3951         Op := Find_Optional_Prim_Op (Parent_Type, Name_Of (Prim));
3952
3953         if Present (Op) then
3954            E := Op;
3955
3956            --  Wrap the object to be initialized into the proper
3957            --  unchecked conversion, to be compatible with the operation
3958            --  to be called.
3959
3960            if Nkind (Cref) = N_Unchecked_Type_Conversion then
3961               Cref := Unchecked_Convert_To (Parent_Type, Expression (Cref));
3962            else
3963               Cref := Unchecked_Convert_To (Parent_Type, Cref);
3964            end if;
3965         end if;
3966      end if;
3967   end Check_Visibly_Controlled;
3968
3969   ------------------
3970   -- Convert_View --
3971   ------------------
3972
3973   function Convert_View
3974     (Proc : Entity_Id;
3975      Arg  : Node_Id;
3976      Ind  : Pos := 1) return Node_Id
3977   is
3978      Fent : Entity_Id := First_Entity (Proc);
3979      Ftyp : Entity_Id;
3980      Atyp : Entity_Id;
3981
3982   begin
3983      for J in 2 .. Ind loop
3984         Next_Entity (Fent);
3985      end loop;
3986
3987      Ftyp := Etype (Fent);
3988
3989      if Nkind_In (Arg, N_Type_Conversion, N_Unchecked_Type_Conversion) then
3990         Atyp := Entity (Subtype_Mark (Arg));
3991      else
3992         Atyp := Etype (Arg);
3993      end if;
3994
3995      if Is_Abstract_Subprogram (Proc) and then Is_Tagged_Type (Ftyp) then
3996         return Unchecked_Convert_To (Class_Wide_Type (Ftyp), Arg);
3997
3998      elsif Ftyp /= Atyp
3999        and then Present (Atyp)
4000        and then (Is_Private_Type (Ftyp) or else Is_Private_Type (Atyp))
4001        and then Base_Type (Underlying_Type (Atyp)) =
4002                 Base_Type (Underlying_Type (Ftyp))
4003      then
4004         return Unchecked_Convert_To (Ftyp, Arg);
4005
4006      --  If the argument is already a conversion, as generated by
4007      --  Make_Init_Call, set the target type to the type of the formal
4008      --  directly, to avoid spurious typing problems.
4009
4010      elsif Nkind_In (Arg, N_Unchecked_Type_Conversion, N_Type_Conversion)
4011        and then not Is_Class_Wide_Type (Atyp)
4012      then
4013         Set_Subtype_Mark (Arg, New_Occurrence_Of (Ftyp, Sloc (Arg)));
4014         Set_Etype (Arg, Ftyp);
4015         return Arg;
4016
4017      --  Otherwise, introduce a conversion when the designated object
4018      --  has a type derived from the formal of the controlled routine.
4019
4020      elsif Is_Private_Type (Ftyp)
4021        and then Present (Atyp)
4022        and then Is_Derived_Type (Underlying_Type (Base_Type (Atyp)))
4023      then
4024         return Unchecked_Convert_To (Ftyp, Arg);
4025
4026      else
4027         return Arg;
4028      end if;
4029   end Convert_View;
4030
4031   -------------------------------
4032   -- CW_Or_Has_Controlled_Part --
4033   -------------------------------
4034
4035   function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean is
4036   begin
4037      return Is_Class_Wide_Type (T) or else Needs_Finalization (T);
4038   end CW_Or_Has_Controlled_Part;
4039
4040   ------------------------
4041   -- Enclosing_Function --
4042   ------------------------
4043
4044   function Enclosing_Function (E : Entity_Id) return Entity_Id is
4045      Func_Id : Entity_Id;
4046
4047   begin
4048      Func_Id := E;
4049      while Present (Func_Id) and then Func_Id /= Standard_Standard loop
4050         if Ekind (Func_Id) = E_Function then
4051            return Func_Id;
4052         end if;
4053
4054         Func_Id := Scope (Func_Id);
4055      end loop;
4056
4057      return Empty;
4058   end Enclosing_Function;
4059
4060   -------------------------------
4061   -- Establish_Transient_Scope --
4062   -------------------------------
4063
4064   --  This procedure is called each time a transient block has to be inserted
4065   --  that is to say for each call to a function with unconstrained or tagged
4066   --  result. It creates a new scope on the scope stack in order to enclose
4067   --  all transient variables generated.
4068
4069   procedure Establish_Transient_Scope
4070     (N                : Node_Id;
4071      Manage_Sec_Stack : Boolean)
4072   is
4073      procedure Create_Transient_Scope (Constr : Node_Id);
4074      --  Place a new scope on the scope stack in order to service construct
4075      --  Constr. The new scope may also manage the secondary stack.
4076
4077      procedure Delegate_Sec_Stack_Management;
4078      --  Move the management of the secondary stack to the nearest enclosing
4079      --  suitable scope.
4080
4081      function Find_Enclosing_Transient_Scope return Entity_Id;
4082      --  Examine the scope stack looking for the nearest enclosing transient
4083      --  scope. Return Empty if no such scope exists.
4084
4085      function Is_OK_Construct (Constr : Node_Id) return Boolean;
4086      --  Determine whether arbitrary node Constr is a suitable construct which
4087      --  requires handling by a transient scope.
4088
4089      function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean;
4090      --  Determine whether arbitrary Id denotes a package or subprogram [body]
4091
4092      ----------------------------
4093      -- Create_Transient_Scope --
4094      ----------------------------
4095
4096      procedure Create_Transient_Scope (Constr : Node_Id) is
4097         Loc : constant Source_Ptr := Sloc (N);
4098
4099         Iter_Loop  : Entity_Id;
4100         Trans_Scop : Entity_Id;
4101
4102      begin
4103         Trans_Scop := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
4104         Set_Etype (Trans_Scop, Standard_Void_Type);
4105
4106         Push_Scope (Trans_Scop);
4107         Set_Node_To_Be_Wrapped (Constr);
4108         Set_Scope_Is_Transient;
4109
4110         --  The transient scope must also manage the secondary stack
4111
4112         if Manage_Sec_Stack then
4113            Set_Uses_Sec_Stack (Trans_Scop);
4114            Check_Restriction (No_Secondary_Stack, N);
4115
4116            --  The expansion of iterator loops generates references to objects
4117            --  in order to extract elements from a container:
4118
4119            --    Ref : Reference_Type_Ptr := Reference (Container, Cursor);
4120            --    Obj : <object type> renames Ref.all.Element.all;
4121
4122            --  These references are controlled and returned on the secondary
4123            --  stack. A new reference is created at each iteration of the loop
4124            --  and as a result it must be finalized and the space occupied by
4125            --  it on the secondary stack reclaimed at the end of the current
4126            --  iteration.
4127
4128            --  When the context that requires a transient scope is a call to
4129            --  routine Reference, the node to be wrapped is the source object:
4130
4131            --    for Obj of Container loop
4132
4133            --  Routine Wrap_Transient_Declaration however does not generate a
4134            --  physical block as wrapping a declaration will kill it too ealy.
4135            --  To handle this peculiar case, mark the related iterator loop as
4136            --  requiring the secondary stack. This signals the finalization
4137            --  machinery to manage the secondary stack (see routine
4138            --  Process_Statements_For_Controlled_Objects).
4139
4140            Iter_Loop := Find_Enclosing_Iterator_Loop (Trans_Scop);
4141
4142            if Present (Iter_Loop) then
4143               Set_Uses_Sec_Stack (Iter_Loop);
4144            end if;
4145         end if;
4146
4147         if Debug_Flag_W then
4148            Write_Str ("    <Transient>");
4149            Write_Eol;
4150         end if;
4151      end Create_Transient_Scope;
4152
4153      -----------------------------------
4154      -- Delegate_Sec_Stack_Management --
4155      -----------------------------------
4156
4157      procedure Delegate_Sec_Stack_Management is
4158         Scop_Id  : Entity_Id;
4159         Scop_Rec : Scope_Stack_Entry;
4160
4161      begin
4162         for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
4163            Scop_Rec := Scope_Stack.Table (Index);
4164            Scop_Id  := Scop_Rec.Entity;
4165
4166            --  Prevent the search from going too far or within the scope space
4167            --  of another unit.
4168
4169            if Scop_Id = Standard_Standard then
4170               return;
4171
4172            --  No transient scope should be encountered during the traversal
4173            --  because Establish_Transient_Scope should have already handled
4174            --  this case.
4175
4176            elsif Scop_Rec.Is_Transient then
4177               pragma Assert (False);
4178               return;
4179
4180            --  The construct which requires secondary stack management is
4181            --  always enclosed by a package or subprogram scope.
4182
4183            elsif Is_Package_Or_Subprogram (Scop_Id) then
4184               Set_Uses_Sec_Stack (Scop_Id);
4185               Check_Restriction (No_Secondary_Stack, N);
4186
4187               return;
4188            end if;
4189         end loop;
4190
4191         --  At this point no suitable scope was found. This should never occur
4192         --  because a construct is always enclosed by a compilation unit which
4193         --  has a scope.
4194
4195         pragma Assert (False);
4196      end Delegate_Sec_Stack_Management;
4197
4198      ------------------------------------
4199      -- Find_Enclosing_Transient_Scope --
4200      ------------------------------------
4201
4202      function Find_Enclosing_Transient_Scope return Entity_Id is
4203         Scop_Id   : Entity_Id;
4204         Scop_Rec  : Scope_Stack_Entry;
4205
4206      begin
4207         for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
4208            Scop_Rec := Scope_Stack.Table (Index);
4209            Scop_Id  := Scop_Rec.Entity;
4210
4211            --  Prevent the search from going too far or within the scope space
4212            --  of another unit.
4213
4214            if Scop_Id = Standard_Standard
4215              or else Is_Package_Or_Subprogram (Scop_Id)
4216            then
4217               exit;
4218
4219            elsif Scop_Rec.Is_Transient then
4220               return Scop_Id;
4221            end if;
4222         end loop;
4223
4224         return Empty;
4225      end Find_Enclosing_Transient_Scope;
4226
4227      ---------------------
4228      -- Is_OK_Construct --
4229      ---------------------
4230
4231      function Is_OK_Construct (Constr : Node_Id) return Boolean is
4232      begin
4233         --  Nothing to do when there is no construct to consider
4234
4235         if No (Constr) then
4236            return False;
4237
4238         --  Nothing to do when the construct is an iteration scheme or an Ada
4239         --  2012 iterator because the expression is one of the bounds, and the
4240         --  expansion will create an explicit declaration for it (see routine
4241         --  Analyze_Iteration_Scheme).
4242
4243         elsif Nkind_In (Constr, N_Iteration_Scheme,
4244                                 N_Iterator_Specification)
4245         then
4246            return False;
4247
4248         --  Nothing to do in formal verification mode when the construct is
4249         --  pragma Check, because the pragma remains unexpanded.
4250
4251         elsif GNATprove_Mode
4252           and then Nkind (Constr) = N_Pragma
4253           and then Get_Pragma_Id (Constr) = Pragma_Check
4254         then
4255            return False;
4256         end if;
4257
4258         return True;
4259      end Is_OK_Construct;
4260
4261      ------------------------------
4262      -- Is_Package_Or_Subprogram --
4263      ------------------------------
4264
4265      function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean is
4266      begin
4267         return Ekind_In (Id, E_Entry,
4268                              E_Entry_Family,
4269                              E_Function,
4270                              E_Package,
4271                              E_Procedure,
4272                              E_Subprogram_Body);
4273      end Is_Package_Or_Subprogram;
4274
4275      --  Local variables
4276
4277      Scop_Id : constant Entity_Id := Find_Enclosing_Transient_Scope;
4278      Constr  : Node_Id;
4279
4280   --  Start of processing for Establish_Transient_Scope
4281
4282   begin
4283      --  Do not create a new transient scope if there is an existing transient
4284      --  scope on the stack.
4285
4286      if Present (Scop_Id) then
4287
4288         --  If the transient scope was requested for purposes of managing the
4289         --  secondary stack, then the existing scope must perform this task.
4290
4291         if Manage_Sec_Stack then
4292            Set_Uses_Sec_Stack (Scop_Id);
4293         end if;
4294
4295         return;
4296      end if;
4297
4298      --  At this point it is known that the scope stack is free of transient
4299      --  scopes. Locate the proper construct which must be serviced by a new
4300      --  transient scope.
4301
4302      Constr := Find_Node_To_Be_Wrapped (N);
4303
4304      if Is_OK_Construct (Constr) then
4305         Create_Transient_Scope (Constr);
4306
4307      --  Otherwise there is no suitable construct which requires handling by
4308      --  a transient scope. If the transient scope was requested for purposes
4309      --  of managing the secondary stack, delegate the work to an enclosing
4310      --  scope.
4311
4312      elsif Manage_Sec_Stack then
4313         Delegate_Sec_Stack_Management;
4314      end if;
4315   end Establish_Transient_Scope;
4316
4317   ----------------------------
4318   -- Expand_Cleanup_Actions --
4319   ----------------------------
4320
4321   procedure Expand_Cleanup_Actions (N : Node_Id) is
4322      pragma Assert (Nkind_In (N, N_Block_Statement,
4323                                  N_Entry_Body,
4324                                  N_Extended_Return_Statement,
4325                                  N_Subprogram_Body,
4326                                  N_Task_Body));
4327
4328      Scop : constant Entity_Id := Current_Scope;
4329
4330      Is_Asynchronous_Call   : constant Boolean :=
4331                                 Nkind (N) = N_Block_Statement
4332                                   and then Is_Asynchronous_Call_Block (N);
4333      Is_Master              : constant Boolean :=
4334                                 Nkind (N) /= N_Extended_Return_Statement
4335                                   and then Nkind (N) /= N_Entry_Body
4336                                   and then Is_Task_Master (N);
4337      Is_Protected_Subp_Body : constant Boolean :=
4338                                 Nkind (N) = N_Subprogram_Body
4339                                   and then Is_Protected_Subprogram_Body (N);
4340      Is_Task_Allocation     : constant Boolean :=
4341                                 Nkind (N) = N_Block_Statement
4342                                   and then Is_Task_Allocation_Block (N);
4343      Is_Task_Body           : constant Boolean :=
4344                                 Nkind (Original_Node (N)) = N_Task_Body;
4345      Needs_Sec_Stack_Mark   : constant Boolean :=
4346                                 Uses_Sec_Stack (Scop)
4347                                   and then
4348                                     not Sec_Stack_Needed_For_Return (Scop);
4349      Needs_Custom_Cleanup   : constant Boolean :=
4350                                 Nkind (N) = N_Block_Statement
4351                                   and then Present (Cleanup_Actions (N));
4352
4353      Actions_Required       : constant Boolean :=
4354                                 Requires_Cleanup_Actions (N, True)
4355                                   or else Is_Asynchronous_Call
4356                                   or else Is_Master
4357                                   or else Is_Protected_Subp_Body
4358                                   or else Is_Task_Allocation
4359                                   or else Is_Task_Body
4360                                   or else Needs_Sec_Stack_Mark
4361                                   or else Needs_Custom_Cleanup;
4362
4363      HSS : Node_Id := Handled_Statement_Sequence (N);
4364      Loc : Source_Ptr;
4365      Cln : List_Id;
4366
4367      procedure Wrap_HSS_In_Block;
4368      --  Move HSS inside a new block along with the original exception
4369      --  handlers. Make the newly generated block the sole statement of HSS.
4370
4371      -----------------------
4372      -- Wrap_HSS_In_Block --
4373      -----------------------
4374
4375      procedure Wrap_HSS_In_Block is
4376         Block    : Node_Id;
4377         Block_Id : Entity_Id;
4378         End_Lab  : Node_Id;
4379
4380      begin
4381         --  Preserve end label to provide proper cross-reference information
4382
4383         End_Lab := End_Label (HSS);
4384         Block :=
4385           Make_Block_Statement (Loc, Handled_Statement_Sequence => HSS);
4386
4387         Block_Id := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
4388         Set_Identifier (Block, New_Occurrence_Of (Block_Id, Loc));
4389         Set_Etype (Block_Id, Standard_Void_Type);
4390         Set_Block_Node (Block_Id, Identifier (Block));
4391
4392         --  Signal the finalization machinery that this particular block
4393         --  contains the original context.
4394
4395         Set_Is_Finalization_Wrapper (Block);
4396
4397         Set_Handled_Statement_Sequence (N,
4398           Make_Handled_Sequence_Of_Statements (Loc, New_List (Block)));
4399         HSS := Handled_Statement_Sequence (N);
4400
4401         Set_First_Real_Statement (HSS, Block);
4402         Set_End_Label (HSS, End_Lab);
4403
4404         --  Comment needed here, see RH for 1.306 ???
4405
4406         if Nkind (N) = N_Subprogram_Body then
4407            Set_Has_Nested_Block_With_Handler (Scop);
4408         end if;
4409      end Wrap_HSS_In_Block;
4410
4411   --  Start of processing for Expand_Cleanup_Actions
4412
4413   begin
4414      --  The current construct does not need any form of servicing
4415
4416      if not Actions_Required then
4417         return;
4418
4419      --  If the current node is a rewritten task body and the descriptors have
4420      --  not been delayed (due to some nested instantiations), do not generate
4421      --  redundant cleanup actions.
4422
4423      elsif Is_Task_Body
4424        and then Nkind (N) = N_Subprogram_Body
4425        and then not Delay_Subprogram_Descriptors (Corresponding_Spec (N))
4426      then
4427         return;
4428      end if;
4429
4430      --  If an extended return statement contains something like
4431      --
4432      --     X := F (...);
4433      --
4434      --  where F is a build-in-place function call returning a controlled
4435      --  type, then a temporary object will be implicitly declared as part
4436      --  of the statement list, and this will need cleanup. In such cases,
4437      --  we transform:
4438      --
4439      --    return Result : T := ... do
4440      --       <statements> -- possibly with handlers
4441      --    end return;
4442      --
4443      --  into:
4444      --
4445      --    return Result : T := ... do
4446      --       declare -- no declarations
4447      --       begin
4448      --          <statements> -- possibly with handlers
4449      --       end; -- no handlers
4450      --    end return;
4451      --
4452      --  So Expand_Cleanup_Actions will end up being called recursively on the
4453      --  block statement.
4454
4455      if Nkind (N) = N_Extended_Return_Statement then
4456         declare
4457            Block : constant Node_Id :=
4458                      Make_Block_Statement (Sloc (N),
4459                        Declarations               => Empty_List,
4460                        Handled_Statement_Sequence =>
4461                          Handled_Statement_Sequence (N));
4462         begin
4463            Set_Handled_Statement_Sequence (N,
4464              Make_Handled_Sequence_Of_Statements (Sloc (N),
4465                Statements => New_List (Block)));
4466
4467            Analyze (Block);
4468         end;
4469
4470         --  Analysis of the block did all the work
4471
4472         return;
4473      end if;
4474
4475      if Needs_Custom_Cleanup then
4476         Cln := Cleanup_Actions (N);
4477      else
4478         Cln := No_List;
4479      end if;
4480
4481      declare
4482         Decls     : List_Id := Declarations (N);
4483         Fin_Id    : Entity_Id;
4484         Mark      : Entity_Id := Empty;
4485         New_Decls : List_Id;
4486         Old_Poll  : Boolean;
4487
4488      begin
4489         --  If we are generating expanded code for debugging purposes, use the
4490         --  Sloc of the point of insertion for the cleanup code. The Sloc will
4491         --  be updated subsequently to reference the proper line in .dg files.
4492         --  If we are not debugging generated code, use No_Location instead,
4493         --  so that no debug information is generated for the cleanup code.
4494         --  This makes the behavior of the NEXT command in GDB monotonic, and
4495         --  makes the placement of breakpoints more accurate.
4496
4497         if Debug_Generated_Code then
4498            Loc := Sloc (Scop);
4499         else
4500            Loc := No_Location;
4501         end if;
4502
4503         --  Set polling off. The finalization and cleanup code is executed
4504         --  with aborts deferred.
4505
4506         Old_Poll := Polling_Required;
4507         Polling_Required := False;
4508
4509         --  A task activation call has already been built for a task
4510         --  allocation block.
4511
4512         if not Is_Task_Allocation then
4513            Build_Task_Activation_Call (N);
4514         end if;
4515
4516         if Is_Master then
4517            Establish_Task_Master (N);
4518         end if;
4519
4520         New_Decls := New_List;
4521
4522         --  If secondary stack is in use, generate:
4523         --
4524         --    Mnn : constant Mark_Id := SS_Mark;
4525
4526         if Needs_Sec_Stack_Mark then
4527            Mark := Make_Temporary (Loc, 'M');
4528
4529            Append_To (New_Decls, Build_SS_Mark_Call (Loc, Mark));
4530            Set_Uses_Sec_Stack (Scop, False);
4531         end if;
4532
4533         --  If exception handlers are present, wrap the sequence of statements
4534         --  in a block since it is not possible to have exception handlers and
4535         --  an At_End handler in the same construct.
4536
4537         if Present (Exception_Handlers (HSS)) then
4538            Wrap_HSS_In_Block;
4539
4540         --  Ensure that the First_Real_Statement field is set
4541
4542         elsif No (First_Real_Statement (HSS)) then
4543            Set_First_Real_Statement (HSS, First (Statements (HSS)));
4544         end if;
4545
4546         --  Do not move the Activation_Chain declaration in the context of
4547         --  task allocation blocks. Task allocation blocks use _chain in their
4548         --  cleanup handlers and gigi complains if it is declared in the
4549         --  sequence of statements of the scope that declares the handler.
4550
4551         if Is_Task_Allocation then
4552            declare
4553               Chain : constant Entity_Id := Activation_Chain_Entity (N);
4554               Decl  : Node_Id;
4555
4556            begin
4557               Decl := First (Decls);
4558               while Nkind (Decl) /= N_Object_Declaration
4559                 or else Defining_Identifier (Decl) /= Chain
4560               loop
4561                  Next (Decl);
4562
4563                  --  A task allocation block should always include a _chain
4564                  --  declaration.
4565
4566                  pragma Assert (Present (Decl));
4567               end loop;
4568
4569               Remove (Decl);
4570               Prepend_To (New_Decls, Decl);
4571            end;
4572         end if;
4573
4574         --  Ensure the presence of a declaration list in order to successfully
4575         --  append all original statements to it.
4576
4577         if No (Decls) then
4578            Set_Declarations (N, New_List);
4579            Decls := Declarations (N);
4580         end if;
4581
4582         --  Move the declarations into the sequence of statements in order to
4583         --  have them protected by the At_End handler. It may seem weird to
4584         --  put declarations in the sequence of statement but in fact nothing
4585         --  forbids that at the tree level.
4586
4587         Append_List_To (Decls, Statements (HSS));
4588         Set_Statements (HSS, Decls);
4589
4590         --  Reset the Sloc of the handled statement sequence to properly
4591         --  reflect the new initial "statement" in the sequence.
4592
4593         Set_Sloc (HSS, Sloc (First (Decls)));
4594
4595         --  The declarations of finalizer spec and auxiliary variables replace
4596         --  the old declarations that have been moved inward.
4597
4598         Set_Declarations (N, New_Decls);
4599         Analyze_Declarations (New_Decls);
4600
4601         --  Generate finalization calls for all controlled objects appearing
4602         --  in the statements of N. Add context specific cleanup for various
4603         --  constructs.
4604
4605         Build_Finalizer
4606           (N           => N,
4607            Clean_Stmts => Build_Cleanup_Statements (N, Cln),
4608            Mark_Id     => Mark,
4609            Top_Decls   => New_Decls,
4610            Defer_Abort => Nkind (Original_Node (N)) = N_Task_Body
4611                             or else Is_Master,
4612            Fin_Id      => Fin_Id);
4613
4614         if Present (Fin_Id) then
4615            Build_Finalizer_Call (N, Fin_Id);
4616         end if;
4617
4618         --  Restore saved polling mode
4619
4620         Polling_Required := Old_Poll;
4621      end;
4622   end Expand_Cleanup_Actions;
4623
4624   ---------------------------
4625   -- Expand_N_Package_Body --
4626   ---------------------------
4627
4628   --  Add call to Activate_Tasks if body is an activator (actual processing
4629   --  is in chapter 9).
4630
4631   --  Generate subprogram descriptor for elaboration routine
4632
4633   --  Encode entity names in package body
4634
4635   procedure Expand_N_Package_Body (N : Node_Id) is
4636      Spec_Id : constant Entity_Id := Corresponding_Spec (N);
4637      Fin_Id  : Entity_Id;
4638
4639   begin
4640      --  This is done only for non-generic packages
4641
4642      if Ekind (Spec_Id) = E_Package then
4643         Push_Scope (Spec_Id);
4644
4645         --  Build dispatch tables of library level tagged types
4646
4647         if Tagged_Type_Expansion
4648           and then Is_Library_Level_Entity (Spec_Id)
4649         then
4650            Build_Static_Dispatch_Tables (N);
4651         end if;
4652
4653         Build_Task_Activation_Call (N);
4654
4655         --  Verify the run-time semantics of pragma Initial_Condition at the
4656         --  end of the body statements.
4657
4658         Expand_Pragma_Initial_Condition (Spec_Id, N);
4659
4660         Pop_Scope;
4661      end if;
4662
4663      Set_Elaboration_Flag (N, Spec_Id);
4664      Set_In_Package_Body (Spec_Id, False);
4665
4666      --  Set to encode entity names in package body before gigi is called
4667
4668      Qualify_Entity_Names (N);
4669
4670      if Ekind (Spec_Id) /= E_Generic_Package then
4671         Build_Finalizer
4672           (N           => N,
4673            Clean_Stmts => No_List,
4674            Mark_Id     => Empty,
4675            Top_Decls   => No_List,
4676            Defer_Abort => False,
4677            Fin_Id      => Fin_Id);
4678
4679         if Present (Fin_Id) then
4680            declare
4681               Body_Ent : Node_Id := Defining_Unit_Name (N);
4682
4683            begin
4684               if Nkind (Body_Ent) = N_Defining_Program_Unit_Name then
4685                  Body_Ent := Defining_Identifier (Body_Ent);
4686               end if;
4687
4688               Set_Finalizer (Body_Ent, Fin_Id);
4689            end;
4690         end if;
4691      end if;
4692   end Expand_N_Package_Body;
4693
4694   ----------------------------------
4695   -- Expand_N_Package_Declaration --
4696   ----------------------------------
4697
4698   --  Add call to Activate_Tasks if there are tasks declared and the package
4699   --  has no body. Note that in Ada 83 this may result in premature activation
4700   --  of some tasks, given that we cannot tell whether a body will eventually
4701   --  appear.
4702
4703   procedure Expand_N_Package_Declaration (N : Node_Id) is
4704      Id     : constant Entity_Id := Defining_Entity (N);
4705      Spec   : constant Node_Id   := Specification (N);
4706      Decls  : List_Id;
4707      Fin_Id : Entity_Id;
4708
4709      No_Body : Boolean := False;
4710      --  True in the case of a package declaration that is a compilation
4711      --  unit and for which no associated body will be compiled in this
4712      --  compilation.
4713
4714   begin
4715      --  Case of a package declaration other than a compilation unit
4716
4717      if Nkind (Parent (N)) /= N_Compilation_Unit then
4718         null;
4719
4720      --  Case of a compilation unit that does not require a body
4721
4722      elsif not Body_Required (Parent (N))
4723        and then not Unit_Requires_Body (Id)
4724      then
4725         No_Body := True;
4726
4727      --  Special case of generating calling stubs for a remote call interface
4728      --  package: even though the package declaration requires one, the body
4729      --  won't be processed in this compilation (so any stubs for RACWs
4730      --  declared in the package must be generated here, along with the spec).
4731
4732      elsif Parent (N) = Cunit (Main_Unit)
4733        and then Is_Remote_Call_Interface (Id)
4734        and then Distribution_Stub_Mode = Generate_Caller_Stub_Body
4735      then
4736         No_Body := True;
4737      end if;
4738
4739      --  For a nested instance, delay processing until freeze point
4740
4741      if Has_Delayed_Freeze (Id)
4742        and then Nkind (Parent (N)) /= N_Compilation_Unit
4743      then
4744         return;
4745      end if;
4746
4747      --  For a package declaration that implies no associated body, generate
4748      --  task activation call and RACW supporting bodies now (since we won't
4749      --  have a specific separate compilation unit for that).
4750
4751      if No_Body then
4752         Push_Scope (Id);
4753
4754         --  Generate RACW subprogram bodies
4755
4756         if Has_RACW (Id) then
4757            Decls := Private_Declarations (Spec);
4758
4759            if No (Decls) then
4760               Decls := Visible_Declarations (Spec);
4761            end if;
4762
4763            if No (Decls) then
4764               Decls := New_List;
4765               Set_Visible_Declarations (Spec, Decls);
4766            end if;
4767
4768            Append_RACW_Bodies (Decls, Id);
4769            Analyze_List (Decls);
4770         end if;
4771
4772         --  Generate task activation call as last step of elaboration
4773
4774         if Present (Activation_Chain_Entity (N)) then
4775            Build_Task_Activation_Call (N);
4776         end if;
4777
4778         --  Verify the run-time semantics of pragma Initial_Condition at the
4779         --  end of the private declarations when the package lacks a body.
4780
4781         Expand_Pragma_Initial_Condition (Id, N);
4782
4783         Pop_Scope;
4784      end if;
4785
4786      --  Build dispatch tables of library level tagged types
4787
4788      if Tagged_Type_Expansion
4789        and then (Is_Compilation_Unit (Id)
4790                   or else (Is_Generic_Instance (Id)
4791                             and then Is_Library_Level_Entity (Id)))
4792      then
4793         Build_Static_Dispatch_Tables (N);
4794      end if;
4795
4796      --  Note: it is not necessary to worry about generating a subprogram
4797      --  descriptor, since the only way to get exception handlers into a
4798      --  package spec is to include instantiations, and that would cause
4799      --  generation of subprogram descriptors to be delayed in any case.
4800
4801      --  Set to encode entity names in package spec before gigi is called
4802
4803      Qualify_Entity_Names (N);
4804
4805      if Ekind (Id) /= E_Generic_Package then
4806         Build_Finalizer
4807           (N           => N,
4808            Clean_Stmts => No_List,
4809            Mark_Id     => Empty,
4810            Top_Decls   => No_List,
4811            Defer_Abort => False,
4812            Fin_Id      => Fin_Id);
4813
4814         Set_Finalizer (Id, Fin_Id);
4815      end if;
4816   end Expand_N_Package_Declaration;
4817
4818   -----------------------------
4819   -- Find_Node_To_Be_Wrapped --
4820   -----------------------------
4821
4822   function Find_Node_To_Be_Wrapped (N : Node_Id) return Node_Id is
4823      Curr : Node_Id;
4824      Prev : Node_Id;
4825
4826   begin
4827      Curr := N;
4828      Prev := Empty;
4829      loop
4830         case Nkind (Curr) is
4831
4832            --  Declarations
4833
4834            --  Declarations act as a boundary for a transient scope even if
4835            --  they are not wrapped, see Wrap_Transient_Declaration.
4836
4837            when N_Object_Declaration
4838               | N_Object_Renaming_Declaration
4839               | N_Subtype_Declaration
4840            =>
4841               return Curr;
4842
4843            --  Statements
4844
4845            --  Statements and statement-like constructs act as a boundary for
4846            --  a transient scope.
4847
4848            when N_Accept_Alternative
4849               | N_Attribute_Definition_Clause
4850               | N_Case_Statement
4851               | N_Case_Statement_Alternative
4852               | N_Code_Statement
4853               | N_Delay_Alternative
4854               | N_Delay_Until_Statement
4855               | N_Delay_Relative_Statement
4856               | N_Discriminant_Association
4857               | N_Elsif_Part
4858               | N_Entry_Body_Formal_Part
4859               | N_Exit_Statement
4860               | N_If_Statement
4861               | N_Iteration_Scheme
4862               | N_Terminate_Alternative
4863            =>
4864               pragma Assert (Present (Prev));
4865               return Prev;
4866
4867            --  Assignment statements are usually wrapped in a transient block
4868            --  except when they are generated as part of controlled aggregate
4869            --  where the wrapping should take place more globally. Note that
4870            --  No_Ctrl_Actions is set also for non-controlled assignments, in
4871            --  order to disable the use of dispatching _assign, thus the test
4872            --  for a controlled type.
4873
4874            when N_Assignment_Statement =>
4875               if No_Ctrl_Actions (Curr)
4876                 and then Needs_Finalization (Etype (Name (Curr)))
4877               then
4878                  return Empty;
4879               else
4880                  return Curr;
4881               end if;
4882
4883            --  An entry of procedure call is usually wrapped except when it
4884            --  acts as the alternative of a conditional or timed entry call.
4885            --  In that case wrap the context of the alternative.
4886
4887            when N_Entry_Call_Statement
4888               | N_Procedure_Call_Statement
4889            =>
4890               if Nkind (Parent (Curr)) = N_Entry_Call_Alternative
4891                 and then Nkind_In (Parent (Parent (Curr)),
4892                                    N_Conditional_Entry_Call,
4893                                    N_Timed_Entry_Call)
4894               then
4895                  return Parent (Parent (Curr));
4896               else
4897                  return Curr;
4898               end if;
4899
4900            when N_Pragma
4901               | N_Raise_Statement
4902            =>
4903               return Curr;
4904
4905            --  A return statement is not wrapped when the associated function
4906            --  would require wrapping.
4907
4908            when N_Simple_Return_Statement =>
4909               if Requires_Transient_Scope (Etype
4910                    (Return_Applies_To (Return_Statement_Entity (Curr))))
4911               then
4912                  return Empty;
4913               else
4914                  return Curr;
4915               end if;
4916
4917            --  Special
4918
4919            when N_Attribute_Reference =>
4920               if Is_Procedure_Attribute_Name (Attribute_Name (Curr)) then
4921                  return Curr;
4922               end if;
4923
4924            --  If the construct is within the iteration scheme of a loop, it
4925            --  requires a declaration followed by an assignment, in order to
4926            --  have a usable statement to wrap.
4927
4928            when N_Loop_Parameter_Specification =>
4929               return Parent (Curr);
4930
4931            --  Termination
4932
4933            --  The following nodes represent "dummy contexts" which do not
4934            --  need to be wrapped.
4935
4936            when N_Component_Declaration
4937               | N_Discriminant_Specification
4938               | N_Parameter_Specification
4939            =>
4940               return Empty;
4941
4942            --  If the traversal leaves a scope without having been able to
4943            --  find a construct to wrap, something is going wrong, but this
4944            --  can happen in error situations that are not detected yet (such
4945            --  as a dynamic string in a pragma Export).
4946
4947            when N_Block_Statement
4948               | N_Entry_Body
4949               | N_Package_Body
4950               | N_Package_Declaration
4951               | N_Protected_Body
4952               | N_Subprogram_Body
4953               | N_Task_Body
4954            =>
4955               return Empty;
4956
4957            --  Default
4958
4959            when others =>
4960               null;
4961         end case;
4962
4963         Prev := Curr;
4964         Curr := Parent (Curr);
4965      end loop;
4966   end Find_Node_To_Be_Wrapped;
4967
4968   ----------------------------------
4969   -- Has_New_Controlled_Component --
4970   ----------------------------------
4971
4972   function Has_New_Controlled_Component (E : Entity_Id) return Boolean is
4973      Comp : Entity_Id;
4974
4975   begin
4976      if not Is_Tagged_Type (E) then
4977         return Has_Controlled_Component (E);
4978      elsif not Is_Derived_Type (E) then
4979         return Has_Controlled_Component (E);
4980      end if;
4981
4982      Comp := First_Component (E);
4983      while Present (Comp) loop
4984         if Chars (Comp) = Name_uParent then
4985            null;
4986
4987         elsif Scope (Original_Record_Component (Comp)) = E
4988           and then Needs_Finalization (Etype (Comp))
4989         then
4990            return True;
4991         end if;
4992
4993         Next_Component (Comp);
4994      end loop;
4995
4996      return False;
4997   end Has_New_Controlled_Component;
4998
4999   ---------------------------------
5000   -- Has_Simple_Protected_Object --
5001   ---------------------------------
5002
5003   function Has_Simple_Protected_Object (T : Entity_Id) return Boolean is
5004   begin
5005      if Has_Task (T) then
5006         return False;
5007
5008      elsif Is_Simple_Protected_Type (T) then
5009         return True;
5010
5011      elsif Is_Array_Type (T) then
5012         return Has_Simple_Protected_Object (Component_Type (T));
5013
5014      elsif Is_Record_Type (T) then
5015         declare
5016            Comp : Entity_Id;
5017
5018         begin
5019            Comp := First_Component (T);
5020            while Present (Comp) loop
5021               if Has_Simple_Protected_Object (Etype (Comp)) then
5022                  return True;
5023               end if;
5024
5025               Next_Component (Comp);
5026            end loop;
5027
5028            return False;
5029         end;
5030
5031      else
5032         return False;
5033      end if;
5034   end Has_Simple_Protected_Object;
5035
5036   ------------------------------------
5037   -- Insert_Actions_In_Scope_Around --
5038   ------------------------------------
5039
5040   procedure Insert_Actions_In_Scope_Around
5041     (N         : Node_Id;
5042      Clean     : Boolean;
5043      Manage_SS : Boolean)
5044   is
5045      Act_Before  : constant List_Id :=
5046        Scope_Stack.Table (Scope_Stack.Last).Actions_To_Be_Wrapped (Before);
5047      Act_After   : constant List_Id :=
5048        Scope_Stack.Table (Scope_Stack.Last).Actions_To_Be_Wrapped (After);
5049      Act_Cleanup : constant List_Id :=
5050        Scope_Stack.Table (Scope_Stack.Last).Actions_To_Be_Wrapped (Cleanup);
5051      --  Note: We used to use renamings of Scope_Stack.Table (Scope_Stack.
5052      --  Last), but this was incorrect as Process_Transients_In_Scope may
5053      --  introduce new scopes and cause a reallocation of Scope_Stack.Table.
5054
5055      procedure Process_Transients_In_Scope
5056        (First_Object : Node_Id;
5057         Last_Object  : Node_Id;
5058         Related_Node : Node_Id);
5059      --  Find all transient objects in the list First_Object .. Last_Object
5060      --  and generate finalization actions for them. Related_Node denotes the
5061      --  node which created all transient objects.
5062
5063      ---------------------------------
5064      -- Process_Transients_In_Scope --
5065      ---------------------------------
5066
5067      procedure Process_Transients_In_Scope
5068        (First_Object : Node_Id;
5069         Last_Object  : Node_Id;
5070         Related_Node : Node_Id)
5071      is
5072         Exceptions_OK : constant Boolean := Exceptions_In_Finalization_OK;
5073
5074         Must_Hook : Boolean := False;
5075         --  Flag denoting whether the context requires transient object
5076         --  export to the outer finalizer.
5077
5078         function Is_Subprogram_Call (N : Node_Id) return Traverse_Result;
5079         --  Determine whether an arbitrary node denotes a subprogram call
5080
5081         procedure Detect_Subprogram_Call is
5082           new Traverse_Proc (Is_Subprogram_Call);
5083
5084         procedure Process_Transient_In_Scope
5085           (Obj_Decl  : Node_Id;
5086            Blk_Data  : Finalization_Exception_Data;
5087            Blk_Stmts : List_Id);
5088         --  Generate finalization actions for a single transient object
5089         --  denoted by object declaration Obj_Decl. Blk_Data is the
5090         --  exception data of the enclosing block. Blk_Stmts denotes the
5091         --  statements of the enclosing block.
5092
5093         ------------------------
5094         -- Is_Subprogram_Call --
5095         ------------------------
5096
5097         function Is_Subprogram_Call (N : Node_Id) return Traverse_Result is
5098         begin
5099            --  A regular procedure or function call
5100
5101            if Nkind (N) in N_Subprogram_Call then
5102               Must_Hook := True;
5103               return Abandon;
5104
5105            --  Special cases
5106
5107            --  Heavy expansion may relocate function calls outside the related
5108            --  node. Inspect the original node to detect the initial placement
5109            --  of the call.
5110
5111            elsif Original_Node (N) /= N then
5112               Detect_Subprogram_Call (Original_Node (N));
5113
5114               if Must_Hook then
5115                  return Abandon;
5116               else
5117                  return OK;
5118               end if;
5119
5120            --  Generalized indexing always involves a function call
5121
5122            elsif Nkind (N) = N_Indexed_Component
5123              and then Present (Generalized_Indexing (N))
5124            then
5125               Must_Hook := True;
5126               return Abandon;
5127
5128            --  Keep searching
5129
5130            else
5131               return OK;
5132            end if;
5133         end Is_Subprogram_Call;
5134
5135         --------------------------------
5136         -- Process_Transient_In_Scope --
5137         --------------------------------
5138
5139         procedure Process_Transient_In_Scope
5140           (Obj_Decl  : Node_Id;
5141            Blk_Data  : Finalization_Exception_Data;
5142            Blk_Stmts : List_Id)
5143         is
5144            Loc         : constant Source_Ptr := Sloc (Obj_Decl);
5145            Obj_Id      : constant Entity_Id  := Defining_Entity (Obj_Decl);
5146            Fin_Call    : Node_Id;
5147            Fin_Stmts   : List_Id;
5148            Hook_Assign : Node_Id;
5149            Hook_Clear  : Node_Id;
5150            Hook_Decl   : Node_Id;
5151            Hook_Insert : Node_Id;
5152            Ptr_Decl    : Node_Id;
5153
5154         begin
5155            --  Mark the transient object as successfully processed to avoid
5156            --  double finalization.
5157
5158            Set_Is_Finalized_Transient (Obj_Id);
5159
5160            --  Construct all the pieces necessary to hook and finalize the
5161            --  transient object.
5162
5163            Build_Transient_Object_Statements
5164              (Obj_Decl    => Obj_Decl,
5165               Fin_Call    => Fin_Call,
5166               Hook_Assign => Hook_Assign,
5167               Hook_Clear  => Hook_Clear,
5168               Hook_Decl   => Hook_Decl,
5169               Ptr_Decl    => Ptr_Decl);
5170
5171            --  The context contains at least one subprogram call which may
5172            --  raise an exception. This scenario employs "hooking" to pass
5173            --  transient objects to the enclosing finalizer in case of an
5174            --  exception.
5175
5176            if Must_Hook then
5177
5178               --  Add the access type which provides a reference to the
5179               --  transient object. Generate:
5180
5181               --    type Ptr_Typ is access all Desig_Typ;
5182
5183               Insert_Action (Obj_Decl, Ptr_Decl);
5184
5185               --  Add the temporary which acts as a hook to the transient
5186               --  object. Generate:
5187
5188               --    Hook : Ptr_Typ := null;
5189
5190               Insert_Action (Obj_Decl, Hook_Decl);
5191
5192               --  When the transient object is initialized by an aggregate,
5193               --  the hook must capture the object after the last aggregate
5194               --  assignment takes place. Only then is the object considered
5195               --  fully initialized. Generate:
5196
5197               --    Hook := Ptr_Typ (Obj_Id);
5198               --      <or>
5199               --    Hook := Obj_Id'Unrestricted_Access;
5200
5201               if Ekind_In (Obj_Id, E_Constant, E_Variable)
5202                 and then Present (Last_Aggregate_Assignment (Obj_Id))
5203               then
5204                  Hook_Insert := Last_Aggregate_Assignment (Obj_Id);
5205
5206               --  Otherwise the hook seizes the related object immediately
5207
5208               else
5209                  Hook_Insert := Obj_Decl;
5210               end if;
5211
5212               Insert_After_And_Analyze (Hook_Insert, Hook_Assign);
5213            end if;
5214
5215            --  When exception propagation is enabled wrap the hook clear
5216            --  statement and the finalization call into a block to catch
5217            --  potential exceptions raised during finalization. Generate:
5218
5219            --    begin
5220            --       [Hook := null;]
5221            --       [Deep_]Finalize (Obj_Ref);
5222
5223            --    exception
5224            --       when others =>
5225            --          if not Raised then
5226            --             Raised := True;
5227            --             Save_Occurrence
5228            --               (Enn, Get_Current_Excep.all.all);
5229            --          end if;
5230            --    end;
5231
5232            if Exceptions_OK then
5233               Fin_Stmts := New_List;
5234
5235               if Must_Hook then
5236                  Append_To (Fin_Stmts, Hook_Clear);
5237               end if;
5238
5239               Append_To (Fin_Stmts, Fin_Call);
5240
5241               Prepend_To (Blk_Stmts,
5242                 Make_Block_Statement (Loc,
5243                   Handled_Statement_Sequence =>
5244                     Make_Handled_Sequence_Of_Statements (Loc,
5245                       Statements         => Fin_Stmts,
5246                       Exception_Handlers => New_List (
5247                         Build_Exception_Handler (Blk_Data)))));
5248
5249            --  Otherwise generate:
5250
5251            --    [Hook := null;]
5252            --    [Deep_]Finalize (Obj_Ref);
5253
5254            --  Note that the statements are inserted in reverse order to
5255            --  achieve the desired final order outlined above.
5256
5257            else
5258               Prepend_To (Blk_Stmts, Fin_Call);
5259
5260               if Must_Hook then
5261                  Prepend_To (Blk_Stmts, Hook_Clear);
5262               end if;
5263            end if;
5264         end Process_Transient_In_Scope;
5265
5266         --  Local variables
5267
5268         Built     : Boolean := False;
5269         Blk_Data  : Finalization_Exception_Data;
5270         Blk_Decl  : Node_Id := Empty;
5271         Blk_Decls : List_Id := No_List;
5272         Blk_Ins   : Node_Id;
5273         Blk_Stmts : List_Id;
5274         Loc       : Source_Ptr;
5275         Obj_Decl  : Node_Id;
5276
5277      --  Start of processing for Process_Transients_In_Scope
5278
5279      begin
5280         --  The expansion performed by this routine is as follows:
5281
5282         --    type Ptr_Typ_1 is access all Ctrl_Trans_Obj_1_Typ;
5283         --    Hook_1 : Ptr_Typ_1 := null;
5284         --    Ctrl_Trans_Obj_1 : ...;
5285         --    Hook_1 := Ctrl_Trans_Obj_1'Unrestricted_Access;
5286         --    . . .
5287         --    type Ptr_Typ_N is access all Ctrl_Trans_Obj_N_Typ;
5288         --    Hook_N : Ptr_Typ_N := null;
5289         --    Ctrl_Trans_Obj_N : ...;
5290         --    Hook_N := Ctrl_Trans_Obj_N'Unrestricted_Access;
5291
5292         --    declare
5293         --       Abrt   : constant Boolean := ...;
5294         --       Ex     : Exception_Occurrence;
5295         --       Raised : Boolean := False;
5296
5297         --    begin
5298         --       Abort_Defer;
5299
5300         --       begin
5301         --          Hook_N := null;
5302         --          [Deep_]Finalize (Ctrl_Trans_Obj_N);
5303
5304         --       exception
5305         --          when others =>
5306         --             if not Raised then
5307         --                Raised := True;
5308         --                Save_Occurrence (Ex, Get_Current_Excep.all.all);
5309         --       end;
5310         --       . . .
5311         --       begin
5312         --          Hook_1 := null;
5313         --          [Deep_]Finalize (Ctrl_Trans_Obj_1);
5314
5315         --       exception
5316         --          when others =>
5317         --             if not Raised then
5318         --                Raised := True;
5319         --                Save_Occurrence (Ex, Get_Current_Excep.all.all);
5320         --       end;
5321
5322         --       Abort_Undefer;
5323
5324         --       if Raised and not Abrt then
5325         --          Raise_From_Controlled_Operation (Ex);
5326         --       end if;
5327         --    end;
5328
5329         --  Recognize a scenario where the transient context is an object
5330         --  declaration initialized by a build-in-place function call:
5331
5332         --    Obj : ... := BIP_Function_Call (Ctrl_Func_Call);
5333
5334         --  The rough expansion of the above is:
5335
5336         --    Temp : ... := Ctrl_Func_Call;
5337         --    Obj  : ...;
5338         --    Res  : ... := BIP_Func_Call (..., Obj, ...);
5339
5340         --  The finalization of any transient object must happen after the
5341         --  build-in-place function call is executed.
5342
5343         if Nkind (N) = N_Object_Declaration
5344           and then Present (BIP_Initialization_Call (Defining_Identifier (N)))
5345         then
5346            Must_Hook := True;
5347            Blk_Ins   := BIP_Initialization_Call (Defining_Identifier (N));
5348
5349         --  Search the context for at least one subprogram call. If found, the
5350         --  machinery exports all transient objects to the enclosing finalizer
5351         --  due to the possibility of abnormal call termination.
5352
5353         else
5354            Detect_Subprogram_Call (N);
5355            Blk_Ins := Last_Object;
5356         end if;
5357
5358         if Clean then
5359            Insert_List_After_And_Analyze (Blk_Ins, Act_Cleanup);
5360         end if;
5361
5362         --  Examine all objects in the list First_Object .. Last_Object
5363
5364         Obj_Decl := First_Object;
5365         while Present (Obj_Decl) loop
5366            if Nkind (Obj_Decl) = N_Object_Declaration
5367              and then Analyzed (Obj_Decl)
5368              and then Is_Finalizable_Transient (Obj_Decl, N)
5369
5370              --  Do not process the node to be wrapped since it will be
5371              --  handled by the enclosing finalizer.
5372
5373              and then Obj_Decl /= Related_Node
5374            then
5375               Loc := Sloc (Obj_Decl);
5376
5377               --  Before generating the cleanup code for the first transient
5378               --  object, create a wrapper block which houses all hook clear
5379               --  statements and finalization calls. This wrapper is needed by
5380               --  the back end.
5381
5382               if not Built then
5383                  Built     := True;
5384                  Blk_Stmts := New_List;
5385
5386                  --  Generate:
5387                  --    Abrt   : constant Boolean := ...;
5388                  --    Ex     : Exception_Occurrence;
5389                  --    Raised : Boolean := False;
5390
5391                  if Exceptions_OK then
5392                     Blk_Decls := New_List;
5393                     Build_Object_Declarations (Blk_Data, Blk_Decls, Loc);
5394                  end if;
5395
5396                  Blk_Decl :=
5397                    Make_Block_Statement (Loc,
5398                      Declarations               => Blk_Decls,
5399                      Handled_Statement_Sequence =>
5400                        Make_Handled_Sequence_Of_Statements (Loc,
5401                          Statements => Blk_Stmts));
5402               end if;
5403
5404               --  Construct all necessary circuitry to hook and finalize a
5405               --  single transient object.
5406
5407               Process_Transient_In_Scope
5408                 (Obj_Decl  => Obj_Decl,
5409                  Blk_Data  => Blk_Data,
5410                  Blk_Stmts => Blk_Stmts);
5411            end if;
5412
5413            --  Terminate the scan after the last object has been processed to
5414            --  avoid touching unrelated code.
5415
5416            if Obj_Decl = Last_Object then
5417               exit;
5418            end if;
5419
5420            Next (Obj_Decl);
5421         end loop;
5422
5423         --  Complete the decoration of the enclosing finalization block and
5424         --  insert it into the tree.
5425
5426         if Present (Blk_Decl) then
5427
5428            --  Note that this Abort_Undefer does not require a extra block or
5429            --  an AT_END handler because each finalization exception is caught
5430            --  in its own corresponding finalization block. As a result, the
5431            --  call to Abort_Defer always takes place.
5432
5433            if Abort_Allowed then
5434               Prepend_To (Blk_Stmts,
5435                 Build_Runtime_Call (Loc, RE_Abort_Defer));
5436
5437               Append_To (Blk_Stmts,
5438                 Build_Runtime_Call (Loc, RE_Abort_Undefer));
5439            end if;
5440
5441            --  Generate:
5442            --    if Raised and then not Abrt then
5443            --       Raise_From_Controlled_Operation (Ex);
5444            --    end if;
5445
5446            if Exceptions_OK then
5447               Append_To (Blk_Stmts, Build_Raise_Statement (Blk_Data));
5448            end if;
5449
5450            Insert_After_And_Analyze (Blk_Ins, Blk_Decl);
5451         end if;
5452      end Process_Transients_In_Scope;
5453
5454      --  Local variables
5455
5456      Loc          : constant Source_Ptr := Sloc (N);
5457      Node_To_Wrap : constant Node_Id    := Node_To_Be_Wrapped;
5458      First_Obj    : Node_Id;
5459      Last_Obj     : Node_Id;
5460      Mark_Id      : Entity_Id;
5461      Target       : Node_Id;
5462
5463   --  Start of processing for Insert_Actions_In_Scope_Around
5464
5465   begin
5466      --  Nothing to do if the scope does not manage the secondary stack or
5467      --  does not contain meaninful actions for insertion.
5468
5469      if not Manage_SS
5470        and then No (Act_Before)
5471        and then No (Act_After)
5472        and then No (Act_Cleanup)
5473      then
5474         return;
5475      end if;
5476
5477      --  If the node to be wrapped is the trigger of an asynchronous select,
5478      --  it is not part of a statement list. The actions must be inserted
5479      --  before the select itself, which is part of some list of statements.
5480      --  Note that the triggering alternative includes the triggering
5481      --  statement and an optional statement list. If the node to be
5482      --  wrapped is part of that list, the normal insertion applies.
5483
5484      if Nkind (Parent (Node_To_Wrap)) = N_Triggering_Alternative
5485        and then not Is_List_Member (Node_To_Wrap)
5486      then
5487         Target := Parent (Parent (Node_To_Wrap));
5488      else
5489         Target := N;
5490      end if;
5491
5492      First_Obj := Target;
5493      Last_Obj  := Target;
5494
5495      --  Add all actions associated with a transient scope into the main tree.
5496      --  There are several scenarios here:
5497
5498      --       +--- Before ----+        +----- After ---+
5499      --    1) First_Obj ....... Target ........ Last_Obj
5500
5501      --    2) First_Obj ....... Target
5502
5503      --    3)                   Target ........ Last_Obj
5504
5505      --  Flag declarations are inserted before the first object
5506
5507      if Present (Act_Before) then
5508         First_Obj := First (Act_Before);
5509         Insert_List_Before (Target, Act_Before);
5510      end if;
5511
5512      --  Finalization calls are inserted after the last object
5513
5514      if Present (Act_After) then
5515         Last_Obj := Last (Act_After);
5516         Insert_List_After (Target, Act_After);
5517      end if;
5518
5519      --  Mark and release the secondary stack when the context warrants it
5520
5521      if Manage_SS then
5522         Mark_Id := Make_Temporary (Loc, 'M');
5523
5524         --  Generate:
5525         --    Mnn : constant Mark_Id := SS_Mark;
5526
5527         Insert_Before_And_Analyze
5528           (First_Obj, Build_SS_Mark_Call (Loc, Mark_Id));
5529
5530         --  Generate:
5531         --    SS_Release (Mnn);
5532
5533         Insert_After_And_Analyze
5534           (Last_Obj, Build_SS_Release_Call (Loc, Mark_Id));
5535      end if;
5536
5537      --  Check for transient objects associated with Target and generate the
5538      --  appropriate finalization actions for them.
5539
5540      Process_Transients_In_Scope
5541        (First_Object => First_Obj,
5542         Last_Object  => Last_Obj,
5543         Related_Node => Target);
5544
5545      --  Reset the action lists
5546
5547      Scope_Stack.Table
5548        (Scope_Stack.Last).Actions_To_Be_Wrapped (Before) := No_List;
5549      Scope_Stack.Table
5550        (Scope_Stack.Last).Actions_To_Be_Wrapped (After)  := No_List;
5551
5552      if Clean then
5553         Scope_Stack.Table
5554           (Scope_Stack.Last).Actions_To_Be_Wrapped (Cleanup) := No_List;
5555      end if;
5556   end Insert_Actions_In_Scope_Around;
5557
5558   ------------------------------
5559   -- Is_Simple_Protected_Type --
5560   ------------------------------
5561
5562   function Is_Simple_Protected_Type (T : Entity_Id) return Boolean is
5563   begin
5564      return
5565        Is_Protected_Type (T)
5566          and then not Uses_Lock_Free (T)
5567          and then not Has_Entries (T)
5568          and then Is_RTE (Find_Protection_Type (T), RE_Protection);
5569   end Is_Simple_Protected_Type;
5570
5571   -----------------------
5572   -- Make_Adjust_Call --
5573   -----------------------
5574
5575   function Make_Adjust_Call
5576     (Obj_Ref   : Node_Id;
5577      Typ       : Entity_Id;
5578      Skip_Self : Boolean := False) return Node_Id
5579   is
5580      Loc    : constant Source_Ptr := Sloc (Obj_Ref);
5581      Adj_Id : Entity_Id := Empty;
5582      Ref    : Node_Id;
5583      Utyp   : Entity_Id;
5584
5585   begin
5586      Ref := Obj_Ref;
5587
5588      --  Recover the proper type which contains Deep_Adjust
5589
5590      if Is_Class_Wide_Type (Typ) then
5591         Utyp := Root_Type (Typ);
5592      else
5593         Utyp := Typ;
5594      end if;
5595
5596      Utyp := Underlying_Type (Base_Type (Utyp));
5597      Set_Assignment_OK (Ref);
5598
5599      --  Deal with untagged derivation of private views
5600
5601      if Present (Utyp) and then Is_Untagged_Derivation (Typ) then
5602         Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
5603         Ref  := Unchecked_Convert_To (Utyp, Ref);
5604         Set_Assignment_OK (Ref);
5605      end if;
5606
5607      --  When dealing with the completion of a private type, use the base
5608      --  type instead.
5609
5610      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
5611         pragma Assert (Is_Private_Type (Typ));
5612
5613         Utyp := Base_Type (Utyp);
5614         Ref  := Unchecked_Convert_To (Utyp, Ref);
5615      end if;
5616
5617      --  The underlying type may not be present due to a missing full view. In
5618      --  this case freezing did not take place and there is no [Deep_]Adjust
5619      --  primitive to call.
5620
5621      if No (Utyp) then
5622         return Empty;
5623
5624      elsif Skip_Self then
5625         if Has_Controlled_Component (Utyp) then
5626            if Is_Tagged_Type (Utyp) then
5627               Adj_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Adjust);
5628            else
5629               Adj_Id := TSS (Utyp, TSS_Deep_Adjust);
5630            end if;
5631         end if;
5632
5633      --  Class-wide types, interfaces and types with controlled components
5634
5635      elsif Is_Class_Wide_Type (Typ)
5636        or else Is_Interface (Typ)
5637        or else Has_Controlled_Component (Utyp)
5638      then
5639         if Is_Tagged_Type (Utyp) then
5640            Adj_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Adjust);
5641         else
5642            Adj_Id := TSS (Utyp, TSS_Deep_Adjust);
5643         end if;
5644
5645      --  Derivations from [Limited_]Controlled
5646
5647      elsif Is_Controlled (Utyp) then
5648         if Has_Controlled_Component (Utyp) then
5649            Adj_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Adjust);
5650         else
5651            Adj_Id := Find_Optional_Prim_Op (Utyp, Name_Of (Adjust_Case));
5652         end if;
5653
5654      --  Tagged types
5655
5656      elsif Is_Tagged_Type (Utyp) then
5657         Adj_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Adjust);
5658
5659      else
5660         raise Program_Error;
5661      end if;
5662
5663      if Present (Adj_Id) then
5664
5665         --  If the object is unanalyzed, set its expected type for use in
5666         --  Convert_View in case an additional conversion is needed.
5667
5668         if No (Etype (Ref))
5669           and then Nkind (Ref) /= N_Unchecked_Type_Conversion
5670         then
5671            Set_Etype (Ref, Typ);
5672         end if;
5673
5674         --  The object reference may need another conversion depending on the
5675         --  type of the formal and that of the actual.
5676
5677         if not Is_Class_Wide_Type (Typ) then
5678            Ref := Convert_View (Adj_Id, Ref);
5679         end if;
5680
5681         return
5682           Make_Call (Loc,
5683             Proc_Id   => Adj_Id,
5684             Param     => Ref,
5685             Skip_Self => Skip_Self);
5686      else
5687         return Empty;
5688      end if;
5689   end Make_Adjust_Call;
5690
5691   ----------------------
5692   -- Make_Detach_Call --
5693   ----------------------
5694
5695   function Make_Detach_Call (Obj_Ref : Node_Id) return Node_Id is
5696      Loc : constant Source_Ptr := Sloc (Obj_Ref);
5697
5698   begin
5699      return
5700        Make_Procedure_Call_Statement (Loc,
5701          Name                   =>
5702            New_Occurrence_Of (RTE (RE_Detach), Loc),
5703          Parameter_Associations => New_List (
5704            Unchecked_Convert_To (RTE (RE_Root_Controlled_Ptr), Obj_Ref)));
5705   end Make_Detach_Call;
5706
5707   ---------------
5708   -- Make_Call --
5709   ---------------
5710
5711   function Make_Call
5712     (Loc       : Source_Ptr;
5713      Proc_Id   : Entity_Id;
5714      Param     : Node_Id;
5715      Skip_Self : Boolean := False) return Node_Id
5716   is
5717      Params : constant List_Id := New_List (Param);
5718
5719   begin
5720      --  Do not apply the controlled action to the object itself by signaling
5721      --  the related routine to avoid self.
5722
5723      if Skip_Self then
5724         Append_To (Params, New_Occurrence_Of (Standard_False, Loc));
5725      end if;
5726
5727      return
5728        Make_Procedure_Call_Statement (Loc,
5729          Name                   => New_Occurrence_Of (Proc_Id, Loc),
5730          Parameter_Associations => Params);
5731   end Make_Call;
5732
5733   --------------------------
5734   -- Make_Deep_Array_Body --
5735   --------------------------
5736
5737   function Make_Deep_Array_Body
5738     (Prim : Final_Primitives;
5739      Typ  : Entity_Id) return List_Id
5740   is
5741      Exceptions_OK : constant Boolean := Exceptions_In_Finalization_OK;
5742
5743      function Build_Adjust_Or_Finalize_Statements
5744        (Typ : Entity_Id) return List_Id;
5745      --  Create the statements necessary to adjust or finalize an array of
5746      --  controlled elements. Generate:
5747      --
5748      --    declare
5749      --       Abort  : constant Boolean := Triggered_By_Abort;
5750      --         <or>
5751      --       Abort  : constant Boolean := False;  --  no abort
5752      --
5753      --       E      : Exception_Occurrence;
5754      --       Raised : Boolean := False;
5755      --
5756      --    begin
5757      --       for J1 in [reverse] Typ'First (1) .. Typ'Last (1) loop
5758      --                 ^--  in the finalization case
5759      --          ...
5760      --          for Jn in [reverse] Typ'First (n) .. Typ'Last (n) loop
5761      --             begin
5762      --                [Deep_]Adjust / Finalize (V (J1, ..., Jn));
5763      --
5764      --             exception
5765      --                when others =>
5766      --                   if not Raised then
5767      --                      Raised := True;
5768      --                      Save_Occurrence (E, Get_Current_Excep.all.all);
5769      --                   end if;
5770      --             end;
5771      --          end loop;
5772      --          ...
5773      --       end loop;
5774      --
5775      --       if Raised and then not Abort then
5776      --          Raise_From_Controlled_Operation (E);
5777      --       end if;
5778      --    end;
5779
5780      function Build_Initialize_Statements (Typ : Entity_Id) return List_Id;
5781      --  Create the statements necessary to initialize an array of controlled
5782      --  elements. Include a mechanism to carry out partial finalization if an
5783      --  exception occurs. Generate:
5784      --
5785      --    declare
5786      --       Counter : Integer := 0;
5787      --
5788      --    begin
5789      --       for J1 in V'Range (1) loop
5790      --          ...
5791      --          for JN in V'Range (N) loop
5792      --             begin
5793      --                [Deep_]Initialize (V (J1, ..., JN));
5794      --
5795      --                Counter := Counter + 1;
5796      --
5797      --             exception
5798      --                when others =>
5799      --                   declare
5800      --                      Abort  : constant Boolean := Triggered_By_Abort;
5801      --                        <or>
5802      --                      Abort  : constant Boolean := False; --  no abort
5803      --                      E      : Exception_Occurrence;
5804      --                      Raised : Boolean := False;
5805
5806      --                   begin
5807      --                      Counter :=
5808      --                        V'Length (1) *
5809      --                        V'Length (2) *
5810      --                        ...
5811      --                        V'Length (N) - Counter;
5812
5813      --                      for F1 in reverse V'Range (1) loop
5814      --                         ...
5815      --                         for FN in reverse V'Range (N) loop
5816      --                            if Counter > 0 then
5817      --                               Counter := Counter - 1;
5818      --                            else
5819      --                               begin
5820      --                                  [Deep_]Finalize (V (F1, ..., FN));
5821
5822      --                               exception
5823      --                                  when others =>
5824      --                                     if not Raised then
5825      --                                        Raised := True;
5826      --                                        Save_Occurrence (E,
5827      --                                          Get_Current_Excep.all.all);
5828      --                                     end if;
5829      --                               end;
5830      --                            end if;
5831      --                         end loop;
5832      --                         ...
5833      --                      end loop;
5834      --                   end;
5835      --
5836      --                   if Raised and then not Abort then
5837      --                      Raise_From_Controlled_Operation (E);
5838      --                   end if;
5839      --
5840      --                   raise;
5841      --             end;
5842      --          end loop;
5843      --       end loop;
5844      --    end;
5845
5846      function New_References_To
5847        (L   : List_Id;
5848         Loc : Source_Ptr) return List_Id;
5849      --  Given a list of defining identifiers, return a list of references to
5850      --  the original identifiers, in the same order as they appear.
5851
5852      -----------------------------------------
5853      -- Build_Adjust_Or_Finalize_Statements --
5854      -----------------------------------------
5855
5856      function Build_Adjust_Or_Finalize_Statements
5857        (Typ : Entity_Id) return List_Id
5858      is
5859         Comp_Typ   : constant Entity_Id  := Component_Type (Typ);
5860         Index_List : constant List_Id    := New_List;
5861         Loc        : constant Source_Ptr := Sloc (Typ);
5862         Num_Dims   : constant Int        := Number_Dimensions (Typ);
5863
5864         procedure Build_Indexes;
5865         --  Generate the indexes used in the dimension loops
5866
5867         -------------------
5868         -- Build_Indexes --
5869         -------------------
5870
5871         procedure Build_Indexes is
5872         begin
5873            --  Generate the following identifiers:
5874            --    Jnn  -  for initialization
5875
5876            for Dim in 1 .. Num_Dims loop
5877               Append_To (Index_List,
5878                 Make_Defining_Identifier (Loc, New_External_Name ('J', Dim)));
5879            end loop;
5880         end Build_Indexes;
5881
5882         --  Local variables
5883
5884         Final_Decls : List_Id := No_List;
5885         Final_Data  : Finalization_Exception_Data;
5886         Block       : Node_Id;
5887         Call        : Node_Id;
5888         Comp_Ref    : Node_Id;
5889         Core_Loop   : Node_Id;
5890         Dim         : Int;
5891         J           : Entity_Id;
5892         Loop_Id     : Entity_Id;
5893         Stmts       : List_Id;
5894
5895      --  Start of processing for Build_Adjust_Or_Finalize_Statements
5896
5897      begin
5898         Final_Decls := New_List;
5899
5900         Build_Indexes;
5901         Build_Object_Declarations (Final_Data, Final_Decls, Loc);
5902
5903         Comp_Ref :=
5904           Make_Indexed_Component (Loc,
5905             Prefix      => Make_Identifier (Loc, Name_V),
5906             Expressions => New_References_To (Index_List, Loc));
5907         Set_Etype (Comp_Ref, Comp_Typ);
5908
5909         --  Generate:
5910         --    [Deep_]Adjust (V (J1, ..., JN))
5911
5912         if Prim = Adjust_Case then
5913            Call := Make_Adjust_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
5914
5915         --  Generate:
5916         --    [Deep_]Finalize (V (J1, ..., JN))
5917
5918         else pragma Assert (Prim = Finalize_Case);
5919            Call := Make_Final_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
5920         end if;
5921
5922         if Present (Call) then
5923
5924            --  Generate the block which houses the adjust or finalize call:
5925
5926            --    begin
5927            --       <adjust or finalize call>
5928
5929            --    exception
5930            --       when others =>
5931            --          if not Raised then
5932            --             Raised := True;
5933            --             Save_Occurrence (E, Get_Current_Excep.all.all);
5934            --          end if;
5935            --    end;
5936
5937            if Exceptions_OK then
5938               Core_Loop :=
5939                 Make_Block_Statement (Loc,
5940                   Handled_Statement_Sequence =>
5941                     Make_Handled_Sequence_Of_Statements (Loc,
5942                       Statements         => New_List (Call),
5943                       Exception_Handlers => New_List (
5944                         Build_Exception_Handler (Final_Data))));
5945            else
5946               Core_Loop := Call;
5947            end if;
5948
5949            --  Generate the dimension loops starting from the innermost one
5950
5951            --    for Jnn in [reverse] V'Range (Dim) loop
5952            --       <core loop>
5953            --    end loop;
5954
5955            J := Last (Index_List);
5956            Dim := Num_Dims;
5957            while Present (J) and then Dim > 0 loop
5958               Loop_Id := J;
5959               Prev (J);
5960               Remove (Loop_Id);
5961
5962               Core_Loop :=
5963                 Make_Loop_Statement (Loc,
5964                   Iteration_Scheme =>
5965                     Make_Iteration_Scheme (Loc,
5966                       Loop_Parameter_Specification =>
5967                         Make_Loop_Parameter_Specification (Loc,
5968                           Defining_Identifier         => Loop_Id,
5969                           Discrete_Subtype_Definition =>
5970                             Make_Attribute_Reference (Loc,
5971                               Prefix         => Make_Identifier (Loc, Name_V),
5972                               Attribute_Name => Name_Range,
5973                               Expressions    => New_List (
5974                                 Make_Integer_Literal (Loc, Dim))),
5975
5976                           Reverse_Present             =>
5977                             Prim = Finalize_Case)),
5978
5979                   Statements       => New_List (Core_Loop),
5980                   End_Label        => Empty);
5981
5982               Dim := Dim - 1;
5983            end loop;
5984
5985            --  Generate the block which contains the core loop, declarations
5986            --  of the abort flag, the exception occurrence, the raised flag
5987            --  and the conditional raise:
5988
5989            --    declare
5990            --       Abort  : constant Boolean := Triggered_By_Abort;
5991            --         <or>
5992            --       Abort  : constant Boolean := False;  --  no abort
5993
5994            --       E      : Exception_Occurrence;
5995            --       Raised : Boolean := False;
5996
5997            --    begin
5998            --       <core loop>
5999
6000            --       if Raised and then not Abort then
6001            --          Raise_From_Controlled_Operation (E);
6002            --       end if;
6003            --    end;
6004
6005            Stmts := New_List (Core_Loop);
6006
6007            if Exceptions_OK then
6008               Append_To (Stmts, Build_Raise_Statement (Final_Data));
6009            end if;
6010
6011            Block :=
6012              Make_Block_Statement (Loc,
6013                Declarations               => Final_Decls,
6014                Handled_Statement_Sequence =>
6015                  Make_Handled_Sequence_Of_Statements (Loc,
6016                    Statements => Stmts));
6017
6018         --  Otherwise previous errors or a missing full view may prevent the
6019         --  proper freezing of the component type. If this is the case, there
6020         --  is no [Deep_]Adjust or [Deep_]Finalize primitive to call.
6021
6022         else
6023            Block := Make_Null_Statement (Loc);
6024         end if;
6025
6026         return New_List (Block);
6027      end Build_Adjust_Or_Finalize_Statements;
6028
6029      ---------------------------------
6030      -- Build_Initialize_Statements --
6031      ---------------------------------
6032
6033      function Build_Initialize_Statements (Typ : Entity_Id) return List_Id is
6034         Comp_Typ   : constant Entity_Id  := Component_Type (Typ);
6035         Final_List : constant List_Id    := New_List;
6036         Index_List : constant List_Id    := New_List;
6037         Loc        : constant Source_Ptr := Sloc (Typ);
6038         Num_Dims   : constant Int        := Number_Dimensions (Typ);
6039
6040         function Build_Assignment (Counter_Id : Entity_Id) return Node_Id;
6041         --  Generate the following assignment:
6042         --    Counter := V'Length (1) *
6043         --               ...
6044         --               V'Length (N) - Counter;
6045         --
6046         --  Counter_Id denotes the entity of the counter.
6047
6048         function Build_Finalization_Call return Node_Id;
6049         --  Generate a deep finalization call for an array element
6050
6051         procedure Build_Indexes;
6052         --  Generate the initialization and finalization indexes used in the
6053         --  dimension loops.
6054
6055         function Build_Initialization_Call return Node_Id;
6056         --  Generate a deep initialization call for an array element
6057
6058         ----------------------
6059         -- Build_Assignment --
6060         ----------------------
6061
6062         function Build_Assignment (Counter_Id : Entity_Id) return Node_Id is
6063            Dim  : Int;
6064            Expr : Node_Id;
6065
6066         begin
6067            --  Start from the first dimension and generate:
6068            --    V'Length (1)
6069
6070            Dim := 1;
6071            Expr :=
6072              Make_Attribute_Reference (Loc,
6073                Prefix         => Make_Identifier (Loc, Name_V),
6074                Attribute_Name => Name_Length,
6075                Expressions    => New_List (Make_Integer_Literal (Loc, Dim)));
6076
6077            --  Process the rest of the dimensions, generate:
6078            --    Expr * V'Length (N)
6079
6080            Dim := Dim + 1;
6081            while Dim <= Num_Dims loop
6082               Expr :=
6083                 Make_Op_Multiply (Loc,
6084                   Left_Opnd  => Expr,
6085                   Right_Opnd =>
6086                     Make_Attribute_Reference (Loc,
6087                       Prefix         => Make_Identifier (Loc, Name_V),
6088                       Attribute_Name => Name_Length,
6089                       Expressions    => New_List (
6090                         Make_Integer_Literal (Loc, Dim))));
6091
6092               Dim := Dim + 1;
6093            end loop;
6094
6095            --  Generate:
6096            --    Counter := Expr - Counter;
6097
6098            return
6099              Make_Assignment_Statement (Loc,
6100                Name       => New_Occurrence_Of (Counter_Id, Loc),
6101                Expression =>
6102                  Make_Op_Subtract (Loc,
6103                    Left_Opnd  => Expr,
6104                    Right_Opnd => New_Occurrence_Of (Counter_Id, Loc)));
6105         end Build_Assignment;
6106
6107         -----------------------------
6108         -- Build_Finalization_Call --
6109         -----------------------------
6110
6111         function Build_Finalization_Call return Node_Id is
6112            Comp_Ref : constant Node_Id :=
6113                         Make_Indexed_Component (Loc,
6114                           Prefix      => Make_Identifier (Loc, Name_V),
6115                           Expressions => New_References_To (Final_List, Loc));
6116
6117         begin
6118            Set_Etype (Comp_Ref, Comp_Typ);
6119
6120            --  Generate:
6121            --    [Deep_]Finalize (V);
6122
6123            return Make_Final_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
6124         end Build_Finalization_Call;
6125
6126         -------------------
6127         -- Build_Indexes --
6128         -------------------
6129
6130         procedure Build_Indexes is
6131         begin
6132            --  Generate the following identifiers:
6133            --    Jnn  -  for initialization
6134            --    Fnn  -  for finalization
6135
6136            for Dim in 1 .. Num_Dims loop
6137               Append_To (Index_List,
6138                 Make_Defining_Identifier (Loc, New_External_Name ('J', Dim)));
6139
6140               Append_To (Final_List,
6141                 Make_Defining_Identifier (Loc, New_External_Name ('F', Dim)));
6142            end loop;
6143         end Build_Indexes;
6144
6145         -------------------------------
6146         -- Build_Initialization_Call --
6147         -------------------------------
6148
6149         function Build_Initialization_Call return Node_Id is
6150            Comp_Ref : constant Node_Id :=
6151                         Make_Indexed_Component (Loc,
6152                           Prefix      => Make_Identifier (Loc, Name_V),
6153                           Expressions => New_References_To (Index_List, Loc));
6154
6155         begin
6156            Set_Etype (Comp_Ref, Comp_Typ);
6157
6158            --  Generate:
6159            --    [Deep_]Initialize (V (J1, ..., JN));
6160
6161            return Make_Init_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
6162         end Build_Initialization_Call;
6163
6164         --  Local variables
6165
6166         Counter_Id  : Entity_Id;
6167         Dim         : Int;
6168         F           : Node_Id;
6169         Fin_Stmt    : Node_Id;
6170         Final_Block : Node_Id;
6171         Final_Data  : Finalization_Exception_Data;
6172         Final_Decls : List_Id := No_List;
6173         Final_Loop  : Node_Id;
6174         Init_Block  : Node_Id;
6175         Init_Call   : Node_Id;
6176         Init_Loop   : Node_Id;
6177         J           : Node_Id;
6178         Loop_Id     : Node_Id;
6179         Stmts       : List_Id;
6180
6181      --  Start of processing for Build_Initialize_Statements
6182
6183      begin
6184         Counter_Id  := Make_Temporary (Loc, 'C');
6185         Final_Decls := New_List;
6186
6187         Build_Indexes;
6188         Build_Object_Declarations (Final_Data, Final_Decls, Loc);
6189
6190         --  Generate the block which houses the finalization call, the index
6191         --  guard and the handler which triggers Program_Error later on.
6192
6193         --    if Counter > 0 then
6194         --       Counter := Counter - 1;
6195         --    else
6196         --       begin
6197         --          [Deep_]Finalize (V (F1, ..., FN));
6198         --       exception
6199         --          when others =>
6200         --             if not Raised then
6201         --                Raised := True;
6202         --                Save_Occurrence (E, Get_Current_Excep.all.all);
6203         --             end if;
6204         --       end;
6205         --    end if;
6206
6207         Fin_Stmt := Build_Finalization_Call;
6208
6209         if Present (Fin_Stmt) then
6210            if Exceptions_OK then
6211               Fin_Stmt :=
6212                 Make_Block_Statement (Loc,
6213                   Handled_Statement_Sequence =>
6214                     Make_Handled_Sequence_Of_Statements (Loc,
6215                       Statements         => New_List (Fin_Stmt),
6216                       Exception_Handlers => New_List (
6217                         Build_Exception_Handler (Final_Data))));
6218            end if;
6219
6220            --  This is the core of the loop, the dimension iterators are added
6221            --  one by one in reverse.
6222
6223            Final_Loop :=
6224              Make_If_Statement (Loc,
6225                Condition =>
6226                  Make_Op_Gt (Loc,
6227                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
6228                    Right_Opnd => Make_Integer_Literal (Loc, 0)),
6229
6230                Then_Statements => New_List (
6231                  Make_Assignment_Statement (Loc,
6232                    Name       => New_Occurrence_Of (Counter_Id, Loc),
6233                    Expression =>
6234                      Make_Op_Subtract (Loc,
6235                        Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
6236                        Right_Opnd => Make_Integer_Literal (Loc, 1)))),
6237
6238                Else_Statements => New_List (Fin_Stmt));
6239
6240            --  Generate all finalization loops starting from the innermost
6241            --  dimension.
6242
6243            --    for Fnn in reverse V'Range (Dim) loop
6244            --       <final loop>
6245            --    end loop;
6246
6247            F := Last (Final_List);
6248            Dim := Num_Dims;
6249            while Present (F) and then Dim > 0 loop
6250               Loop_Id := F;
6251               Prev (F);
6252               Remove (Loop_Id);
6253
6254               Final_Loop :=
6255                 Make_Loop_Statement (Loc,
6256                   Iteration_Scheme =>
6257                     Make_Iteration_Scheme (Loc,
6258                       Loop_Parameter_Specification =>
6259                         Make_Loop_Parameter_Specification (Loc,
6260                           Defining_Identifier         => Loop_Id,
6261                           Discrete_Subtype_Definition =>
6262                             Make_Attribute_Reference (Loc,
6263                               Prefix         => Make_Identifier (Loc, Name_V),
6264                               Attribute_Name => Name_Range,
6265                               Expressions    => New_List (
6266                                 Make_Integer_Literal (Loc, Dim))),
6267
6268                           Reverse_Present             => True)),
6269
6270                   Statements       => New_List (Final_Loop),
6271                   End_Label        => Empty);
6272
6273               Dim := Dim - 1;
6274            end loop;
6275
6276            --  Generate the block which contains the finalization loops, the
6277            --  declarations of the abort flag, the exception occurrence, the
6278            --  raised flag and the conditional raise.
6279
6280            --    declare
6281            --       Abort  : constant Boolean := Triggered_By_Abort;
6282            --         <or>
6283            --       Abort  : constant Boolean := False;  --  no abort
6284
6285            --       E      : Exception_Occurrence;
6286            --       Raised : Boolean := False;
6287
6288            --    begin
6289            --       Counter :=
6290            --         V'Length (1) *
6291            --         ...
6292            --         V'Length (N) - Counter;
6293
6294            --       <final loop>
6295
6296            --       if Raised and then not Abort then
6297            --          Raise_From_Controlled_Operation (E);
6298            --       end if;
6299
6300            --       raise;
6301            --    end;
6302
6303            Stmts := New_List (Build_Assignment (Counter_Id), Final_Loop);
6304
6305            if Exceptions_OK then
6306               Append_To (Stmts, Build_Raise_Statement (Final_Data));
6307               Append_To (Stmts, Make_Raise_Statement (Loc));
6308            end if;
6309
6310            Final_Block :=
6311              Make_Block_Statement (Loc,
6312                Declarations               => Final_Decls,
6313                Handled_Statement_Sequence =>
6314                  Make_Handled_Sequence_Of_Statements (Loc,
6315                    Statements => Stmts));
6316
6317         --  Otherwise previous errors or a missing full view may prevent the
6318         --  proper freezing of the component type. If this is the case, there
6319         --  is no [Deep_]Finalize primitive to call.
6320
6321         else
6322            Final_Block := Make_Null_Statement (Loc);
6323         end if;
6324
6325         --  Generate the block which contains the initialization call and
6326         --  the partial finalization code.
6327
6328         --    begin
6329         --       [Deep_]Initialize (V (J1, ..., JN));
6330
6331         --       Counter := Counter + 1;
6332
6333         --    exception
6334         --       when others =>
6335         --          <finalization code>
6336         --    end;
6337
6338         Init_Call := Build_Initialization_Call;
6339
6340         --  Only create finalization block if there is a non-trivial
6341         --  call to initialization.
6342
6343         if Present (Init_Call)
6344           and then Nkind (Init_Call) /= N_Null_Statement
6345         then
6346            Init_Loop :=
6347              Make_Block_Statement (Loc,
6348                Handled_Statement_Sequence =>
6349                  Make_Handled_Sequence_Of_Statements (Loc,
6350                    Statements         => New_List (Init_Call),
6351                    Exception_Handlers => New_List (
6352                      Make_Exception_Handler (Loc,
6353                        Exception_Choices => New_List (
6354                          Make_Others_Choice (Loc)),
6355                        Statements        => New_List (Final_Block)))));
6356
6357            Append_To (Statements (Handled_Statement_Sequence (Init_Loop)),
6358              Make_Assignment_Statement (Loc,
6359                Name       => New_Occurrence_Of (Counter_Id, Loc),
6360                Expression =>
6361                  Make_Op_Add (Loc,
6362                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
6363                    Right_Opnd => Make_Integer_Literal (Loc, 1))));
6364
6365            --  Generate all initialization loops starting from the innermost
6366            --  dimension.
6367
6368            --    for Jnn in V'Range (Dim) loop
6369            --       <init loop>
6370            --    end loop;
6371
6372            J := Last (Index_List);
6373            Dim := Num_Dims;
6374            while Present (J) and then Dim > 0 loop
6375               Loop_Id := J;
6376               Prev (J);
6377               Remove (Loop_Id);
6378
6379               Init_Loop :=
6380                 Make_Loop_Statement (Loc,
6381                   Iteration_Scheme =>
6382                     Make_Iteration_Scheme (Loc,
6383                       Loop_Parameter_Specification =>
6384                         Make_Loop_Parameter_Specification (Loc,
6385                           Defining_Identifier => Loop_Id,
6386                           Discrete_Subtype_Definition =>
6387                             Make_Attribute_Reference (Loc,
6388                               Prefix         => Make_Identifier (Loc, Name_V),
6389                               Attribute_Name => Name_Range,
6390                               Expressions    => New_List (
6391                                 Make_Integer_Literal (Loc, Dim))))),
6392
6393                   Statements => New_List (Init_Loop),
6394                   End_Label => Empty);
6395
6396               Dim := Dim - 1;
6397            end loop;
6398
6399            --  Generate the block which contains the counter variable and the
6400            --  initialization loops.
6401
6402            --    declare
6403            --       Counter : Integer := 0;
6404            --    begin
6405            --       <init loop>
6406            --    end;
6407
6408            Init_Block :=
6409              Make_Block_Statement (Loc,
6410               Declarations               => New_List (
6411                 Make_Object_Declaration (Loc,
6412                   Defining_Identifier => Counter_Id,
6413                   Object_Definition   =>
6414                     New_Occurrence_Of (Standard_Integer, Loc),
6415                   Expression          => Make_Integer_Literal (Loc, 0))),
6416
6417               Handled_Statement_Sequence =>
6418                 Make_Handled_Sequence_Of_Statements (Loc,
6419                   Statements => New_List (Init_Loop)));
6420
6421         --  Otherwise previous errors or a missing full view may prevent the
6422         --  proper freezing of the component type. If this is the case, there
6423         --  is no [Deep_]Initialize primitive to call.
6424
6425         else
6426            Init_Block := Make_Null_Statement (Loc);
6427         end if;
6428
6429         return New_List (Init_Block);
6430      end Build_Initialize_Statements;
6431
6432      -----------------------
6433      -- New_References_To --
6434      -----------------------
6435
6436      function New_References_To
6437        (L   : List_Id;
6438         Loc : Source_Ptr) return List_Id
6439      is
6440         Refs : constant List_Id := New_List;
6441         Id   : Node_Id;
6442
6443      begin
6444         Id := First (L);
6445         while Present (Id) loop
6446            Append_To (Refs, New_Occurrence_Of (Id, Loc));
6447            Next (Id);
6448         end loop;
6449
6450         return Refs;
6451      end New_References_To;
6452
6453   --  Start of processing for Make_Deep_Array_Body
6454
6455   begin
6456      case Prim is
6457         when Address_Case =>
6458            return Make_Finalize_Address_Stmts (Typ);
6459
6460         when Adjust_Case
6461            | Finalize_Case
6462         =>
6463            return Build_Adjust_Or_Finalize_Statements (Typ);
6464
6465         when Initialize_Case =>
6466            return Build_Initialize_Statements (Typ);
6467      end case;
6468   end Make_Deep_Array_Body;
6469
6470   --------------------
6471   -- Make_Deep_Proc --
6472   --------------------
6473
6474   function Make_Deep_Proc
6475     (Prim  : Final_Primitives;
6476      Typ   : Entity_Id;
6477      Stmts : List_Id) return Entity_Id
6478   is
6479      Loc     : constant Source_Ptr := Sloc (Typ);
6480      Formals : List_Id;
6481      Proc_Id : Entity_Id;
6482
6483   begin
6484      --  Create the object formal, generate:
6485      --    V : System.Address
6486
6487      if Prim = Address_Case then
6488         Formals := New_List (
6489           Make_Parameter_Specification (Loc,
6490             Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
6491             Parameter_Type      =>
6492               New_Occurrence_Of (RTE (RE_Address), Loc)));
6493
6494      --  Default case
6495
6496      else
6497         --  V : in out Typ
6498
6499         Formals := New_List (
6500           Make_Parameter_Specification (Loc,
6501             Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
6502             In_Present          => True,
6503             Out_Present         => True,
6504             Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
6505
6506         --  F : Boolean := True
6507
6508         if Prim = Adjust_Case
6509           or else Prim = Finalize_Case
6510         then
6511            Append_To (Formals,
6512              Make_Parameter_Specification (Loc,
6513                Defining_Identifier => Make_Defining_Identifier (Loc, Name_F),
6514                Parameter_Type      =>
6515                  New_Occurrence_Of (Standard_Boolean, Loc),
6516                Expression          =>
6517                  New_Occurrence_Of (Standard_True, Loc)));
6518         end if;
6519      end if;
6520
6521      Proc_Id :=
6522        Make_Defining_Identifier (Loc,
6523          Chars => Make_TSS_Name (Typ, Deep_Name_Of (Prim)));
6524
6525      --  Generate:
6526      --    procedure Deep_Initialize / Adjust / Finalize (V : in out <typ>) is
6527      --    begin
6528      --       <stmts>
6529      --    exception                --  Finalize and Adjust cases only
6530      --       raise Program_Error;
6531      --    end Deep_Initialize / Adjust / Finalize;
6532
6533      --       or
6534
6535      --    procedure Finalize_Address (V : System.Address) is
6536      --    begin
6537      --       <stmts>
6538      --    end Finalize_Address;
6539
6540      Discard_Node (
6541        Make_Subprogram_Body (Loc,
6542          Specification =>
6543            Make_Procedure_Specification (Loc,
6544              Defining_Unit_Name       => Proc_Id,
6545              Parameter_Specifications => Formals),
6546
6547          Declarations => Empty_List,
6548
6549          Handled_Statement_Sequence =>
6550            Make_Handled_Sequence_Of_Statements (Loc, Statements => Stmts)));
6551
6552      --  If there are no calls to component initialization, indicate that
6553      --  the procedure is trivial, so prevent calls to it.
6554
6555      if Is_Empty_List (Stmts)
6556        or else Nkind (First (Stmts)) = N_Null_Statement
6557      then
6558         Set_Is_Trivial_Subprogram (Proc_Id);
6559      end if;
6560
6561      return Proc_Id;
6562   end Make_Deep_Proc;
6563
6564   ---------------------------
6565   -- Make_Deep_Record_Body --
6566   ---------------------------
6567
6568   function Make_Deep_Record_Body
6569     (Prim     : Final_Primitives;
6570      Typ      : Entity_Id;
6571      Is_Local : Boolean := False) return List_Id
6572   is
6573      Exceptions_OK : constant Boolean := Exceptions_In_Finalization_OK;
6574
6575      function Build_Adjust_Statements (Typ : Entity_Id) return List_Id;
6576      --  Build the statements necessary to adjust a record type. The type may
6577      --  have discriminants and contain variant parts. Generate:
6578      --
6579      --    begin
6580      --       begin
6581      --          [Deep_]Adjust (V.Comp_1);
6582      --       exception
6583      --          when Id : others =>
6584      --             if not Raised then
6585      --                Raised := True;
6586      --                Save_Occurrence (E, Get_Current_Excep.all.all);
6587      --             end if;
6588      --       end;
6589      --       .  .  .
6590      --       begin
6591      --          [Deep_]Adjust (V.Comp_N);
6592      --       exception
6593      --          when Id : others =>
6594      --             if not Raised then
6595      --                Raised := True;
6596      --                Save_Occurrence (E, Get_Current_Excep.all.all);
6597      --             end if;
6598      --       end;
6599      --
6600      --       begin
6601      --          Deep_Adjust (V._parent, False);  --  If applicable
6602      --       exception
6603      --          when Id : others =>
6604      --             if not Raised then
6605      --                Raised := True;
6606      --                Save_Occurrence (E, Get_Current_Excep.all.all);
6607      --             end if;
6608      --       end;
6609      --
6610      --       if F then
6611      --          begin
6612      --             Adjust (V);  --  If applicable
6613      --          exception
6614      --             when others =>
6615      --                if not Raised then
6616      --                   Raised := True;
6617      --                   Save_Occurrence (E, Get_Current_Excep.all.all);
6618      --                end if;
6619      --          end;
6620      --       end if;
6621      --
6622      --       if Raised and then not Abort then
6623      --          Raise_From_Controlled_Operation (E);
6624      --       end if;
6625      --    end;
6626
6627      function Build_Finalize_Statements (Typ : Entity_Id) return List_Id;
6628      --  Build the statements necessary to finalize a record type. The type
6629      --  may have discriminants and contain variant parts. Generate:
6630      --
6631      --    declare
6632      --       Abort  : constant Boolean := Triggered_By_Abort;
6633      --         <or>
6634      --       Abort  : constant Boolean := False;  --  no abort
6635      --       E      : Exception_Occurrence;
6636      --       Raised : Boolean := False;
6637      --
6638      --    begin
6639      --       if F then
6640      --          begin
6641      --             Finalize (V);  --  If applicable
6642      --          exception
6643      --             when others =>
6644      --                if not Raised then
6645      --                   Raised := True;
6646      --                   Save_Occurrence (E, Get_Current_Excep.all.all);
6647      --                end if;
6648      --          end;
6649      --       end if;
6650      --
6651      --       case Variant_1 is
6652      --          when Value_1 =>
6653      --             case State_Counter_N =>  --  If Is_Local is enabled
6654      --                when N =>                 .
6655      --                   goto LN;               .
6656      --                ...                       .
6657      --                when 1 =>                 .
6658      --                   goto L1;               .
6659      --                when others =>            .
6660      --                   goto L0;               .
6661      --             end case;                    .
6662      --
6663      --             <<LN>>                   --  If Is_Local is enabled
6664      --             begin
6665      --                [Deep_]Finalize (V.Comp_N);
6666      --             exception
6667      --                when others =>
6668      --                   if not Raised then
6669      --                      Raised := True;
6670      --                      Save_Occurrence (E, Get_Current_Excep.all.all);
6671      --                   end if;
6672      --             end;
6673      --             .  .  .
6674      --             <<L1>>
6675      --             begin
6676      --                [Deep_]Finalize (V.Comp_1);
6677      --             exception
6678      --                when others =>
6679      --                   if not Raised then
6680      --                      Raised := True;
6681      --                      Save_Occurrence (E, Get_Current_Excep.all.all);
6682      --                   end if;
6683      --             end;
6684      --             <<L0>>
6685      --       end case;
6686      --
6687      --       case State_Counter_1 =>  --  If Is_Local is enabled
6688      --          when M =>                 .
6689      --             goto LM;               .
6690      --       ...
6691      --
6692      --       begin
6693      --          Deep_Finalize (V._parent, False);  --  If applicable
6694      --       exception
6695      --          when Id : others =>
6696      --             if not Raised then
6697      --                Raised := True;
6698      --                Save_Occurrence (E, Get_Current_Excep.all.all);
6699      --             end if;
6700      --       end;
6701      --
6702      --       if Raised and then not Abort then
6703      --          Raise_From_Controlled_Operation (E);
6704      --       end if;
6705      --    end;
6706
6707      function Parent_Field_Type (Typ : Entity_Id) return Entity_Id;
6708      --  Given a derived tagged type Typ, traverse all components, find field
6709      --  _parent and return its type.
6710
6711      procedure Preprocess_Components
6712        (Comps     : Node_Id;
6713         Num_Comps : out Nat;
6714         Has_POC   : out Boolean);
6715      --  Examine all components in component list Comps, count all controlled
6716      --  components and determine whether at least one of them is per-object
6717      --  constrained. Component _parent is always skipped.
6718
6719      -----------------------------
6720      -- Build_Adjust_Statements --
6721      -----------------------------
6722
6723      function Build_Adjust_Statements (Typ : Entity_Id) return List_Id is
6724         Loc     : constant Source_Ptr := Sloc (Typ);
6725         Typ_Def : constant Node_Id    := Type_Definition (Parent (Typ));
6726
6727         Finalizer_Data : Finalization_Exception_Data;
6728
6729         function Process_Component_List_For_Adjust
6730           (Comps : Node_Id) return List_Id;
6731         --  Build all necessary adjust statements for a single component list
6732
6733         ---------------------------------------
6734         -- Process_Component_List_For_Adjust --
6735         ---------------------------------------
6736
6737         function Process_Component_List_For_Adjust
6738           (Comps : Node_Id) return List_Id
6739         is
6740            Stmts : constant List_Id := New_List;
6741
6742            procedure Process_Component_For_Adjust (Decl : Node_Id);
6743            --  Process the declaration of a single controlled component
6744
6745            ----------------------------------
6746            -- Process_Component_For_Adjust --
6747            ----------------------------------
6748
6749            procedure Process_Component_For_Adjust (Decl : Node_Id) is
6750               Id  : constant Entity_Id := Defining_Identifier (Decl);
6751               Typ : constant Entity_Id := Etype (Id);
6752
6753               Adj_Call : Node_Id;
6754
6755            begin
6756               --    begin
6757               --       [Deep_]Adjust (V.Id);
6758
6759               --    exception
6760               --       when others =>
6761               --          if not Raised then
6762               --             Raised := True;
6763               --             Save_Occurrence (E, Get_Current_Excep.all.all);
6764               --          end if;
6765               --    end;
6766
6767               Adj_Call :=
6768                 Make_Adjust_Call (
6769                   Obj_Ref =>
6770                     Make_Selected_Component (Loc,
6771                       Prefix        => Make_Identifier (Loc, Name_V),
6772                       Selector_Name => Make_Identifier (Loc, Chars (Id))),
6773                   Typ     => Typ);
6774
6775               --  Guard against a missing [Deep_]Adjust when the component
6776               --  type was not properly frozen.
6777
6778               if Present (Adj_Call) then
6779                  if Exceptions_OK then
6780                     Adj_Call :=
6781                       Make_Block_Statement (Loc,
6782                         Handled_Statement_Sequence =>
6783                           Make_Handled_Sequence_Of_Statements (Loc,
6784                             Statements         => New_List (Adj_Call),
6785                             Exception_Handlers => New_List (
6786                               Build_Exception_Handler (Finalizer_Data))));
6787                  end if;
6788
6789                  Append_To (Stmts, Adj_Call);
6790               end if;
6791            end Process_Component_For_Adjust;
6792
6793            --  Local variables
6794
6795            Decl      : Node_Id;
6796            Decl_Id   : Entity_Id;
6797            Decl_Typ  : Entity_Id;
6798            Has_POC   : Boolean;
6799            Num_Comps : Nat;
6800            Var_Case  : Node_Id;
6801
6802         --  Start of processing for Process_Component_List_For_Adjust
6803
6804         begin
6805            --  Perform an initial check, determine the number of controlled
6806            --  components in the current list and whether at least one of them
6807            --  is per-object constrained.
6808
6809            Preprocess_Components (Comps, Num_Comps, Has_POC);
6810
6811            --  The processing in this routine is done in the following order:
6812            --    1) Regular components
6813            --    2) Per-object constrained components
6814            --    3) Variant parts
6815
6816            if Num_Comps > 0 then
6817
6818               --  Process all regular components in order of declarations
6819
6820               Decl := First_Non_Pragma (Component_Items (Comps));
6821               while Present (Decl) loop
6822                  Decl_Id  := Defining_Identifier (Decl);
6823                  Decl_Typ := Etype (Decl_Id);
6824
6825                  --  Skip _parent as well as per-object constrained components
6826
6827                  if Chars (Decl_Id) /= Name_uParent
6828                    and then Needs_Finalization (Decl_Typ)
6829                  then
6830                     if Has_Access_Constraint (Decl_Id)
6831                       and then No (Expression (Decl))
6832                     then
6833                        null;
6834                     else
6835                        Process_Component_For_Adjust (Decl);
6836                     end if;
6837                  end if;
6838
6839                  Next_Non_Pragma (Decl);
6840               end loop;
6841
6842               --  Process all per-object constrained components in order of
6843               --  declarations.
6844
6845               if Has_POC then
6846                  Decl := First_Non_Pragma (Component_Items (Comps));
6847                  while Present (Decl) loop
6848                     Decl_Id  := Defining_Identifier (Decl);
6849                     Decl_Typ := Etype (Decl_Id);
6850
6851                     --  Skip _parent
6852
6853                     if Chars (Decl_Id) /= Name_uParent
6854                       and then Needs_Finalization (Decl_Typ)
6855                       and then Has_Access_Constraint (Decl_Id)
6856                       and then No (Expression (Decl))
6857                     then
6858                        Process_Component_For_Adjust (Decl);
6859                     end if;
6860
6861                     Next_Non_Pragma (Decl);
6862                  end loop;
6863               end if;
6864            end if;
6865
6866            --  Process all variants, if any
6867
6868            Var_Case := Empty;
6869            if Present (Variant_Part (Comps)) then
6870               declare
6871                  Var_Alts : constant List_Id := New_List;
6872                  Var      : Node_Id;
6873
6874               begin
6875                  Var := First_Non_Pragma (Variants (Variant_Part (Comps)));
6876                  while Present (Var) loop
6877
6878                     --  Generate:
6879                     --     when <discrete choices> =>
6880                     --        <adjust statements>
6881
6882                     Append_To (Var_Alts,
6883                       Make_Case_Statement_Alternative (Loc,
6884                         Discrete_Choices =>
6885                           New_Copy_List (Discrete_Choices (Var)),
6886                         Statements       =>
6887                           Process_Component_List_For_Adjust (
6888                             Component_List (Var))));
6889
6890                     Next_Non_Pragma (Var);
6891                  end loop;
6892
6893                  --  Generate:
6894                  --     case V.<discriminant> is
6895                  --        when <discrete choices 1> =>
6896                  --           <adjust statements 1>
6897                  --        ...
6898                  --        when <discrete choices N> =>
6899                  --           <adjust statements N>
6900                  --     end case;
6901
6902                  Var_Case :=
6903                    Make_Case_Statement (Loc,
6904                      Expression =>
6905                        Make_Selected_Component (Loc,
6906                          Prefix        => Make_Identifier (Loc, Name_V),
6907                          Selector_Name =>
6908                            Make_Identifier (Loc,
6909                              Chars => Chars (Name (Variant_Part (Comps))))),
6910                      Alternatives => Var_Alts);
6911               end;
6912            end if;
6913
6914            --  Add the variant case statement to the list of statements
6915
6916            if Present (Var_Case) then
6917               Append_To (Stmts, Var_Case);
6918            end if;
6919
6920            --  If the component list did not have any controlled components
6921            --  nor variants, return null.
6922
6923            if Is_Empty_List (Stmts) then
6924               Append_To (Stmts, Make_Null_Statement (Loc));
6925            end if;
6926
6927            return Stmts;
6928         end Process_Component_List_For_Adjust;
6929
6930         --  Local variables
6931
6932         Bod_Stmts       : List_Id := No_List;
6933         Finalizer_Decls : List_Id := No_List;
6934         Rec_Def         : Node_Id;
6935
6936      --  Start of processing for Build_Adjust_Statements
6937
6938      begin
6939         Finalizer_Decls := New_List;
6940         Build_Object_Declarations (Finalizer_Data, Finalizer_Decls, Loc);
6941
6942         if Nkind (Typ_Def) = N_Derived_Type_Definition then
6943            Rec_Def := Record_Extension_Part (Typ_Def);
6944         else
6945            Rec_Def := Typ_Def;
6946         end if;
6947
6948         --  Create an adjust sequence for all record components
6949
6950         if Present (Component_List (Rec_Def)) then
6951            Bod_Stmts :=
6952              Process_Component_List_For_Adjust (Component_List (Rec_Def));
6953         end if;
6954
6955         --  A derived record type must adjust all inherited components. This
6956         --  action poses the following problem:
6957
6958         --    procedure Deep_Adjust (Obj : in out Parent_Typ) is
6959         --    begin
6960         --       Adjust (Obj);
6961         --       ...
6962
6963         --    procedure Deep_Adjust (Obj : in out Derived_Typ) is
6964         --    begin
6965         --       Deep_Adjust (Obj._parent);
6966         --       ...
6967         --       Adjust (Obj);
6968         --       ...
6969
6970         --  Adjusting the derived type will invoke Adjust of the parent and
6971         --  then that of the derived type. This is undesirable because both
6972         --  routines may modify shared components. Only the Adjust of the
6973         --  derived type should be invoked.
6974
6975         --  To prevent this double adjustment of shared components,
6976         --  Deep_Adjust uses a flag to control the invocation of Adjust:
6977
6978         --    procedure Deep_Adjust
6979         --      (Obj  : in out Some_Type;
6980         --       Flag : Boolean := True)
6981         --    is
6982         --    begin
6983         --       if Flag then
6984         --          Adjust (Obj);
6985         --       end if;
6986         --       ...
6987
6988         --  When Deep_Adjust is invokes for field _parent, a value of False is
6989         --  provided for the flag:
6990
6991         --    Deep_Adjust (Obj._parent, False);
6992
6993         if Is_Tagged_Type (Typ) and then Is_Derived_Type (Typ) then
6994            declare
6995               Par_Typ  : constant Entity_Id := Parent_Field_Type (Typ);
6996               Adj_Stmt : Node_Id;
6997               Call     : Node_Id;
6998
6999            begin
7000               if Needs_Finalization (Par_Typ) then
7001                  Call :=
7002                    Make_Adjust_Call
7003                      (Obj_Ref   =>
7004                         Make_Selected_Component (Loc,
7005                           Prefix        => Make_Identifier (Loc, Name_V),
7006                           Selector_Name =>
7007                             Make_Identifier (Loc, Name_uParent)),
7008                       Typ       => Par_Typ,
7009                       Skip_Self => True);
7010
7011                  --  Generate:
7012                  --    begin
7013                  --       Deep_Adjust (V._parent, False);
7014
7015                  --    exception
7016                  --       when Id : others =>
7017                  --          if not Raised then
7018                  --             Raised := True;
7019                  --             Save_Occurrence (E,
7020                  --               Get_Current_Excep.all.all);
7021                  --          end if;
7022                  --    end;
7023
7024                  if Present (Call) then
7025                     Adj_Stmt := Call;
7026
7027                     if Exceptions_OK then
7028                        Adj_Stmt :=
7029                          Make_Block_Statement (Loc,
7030                            Handled_Statement_Sequence =>
7031                              Make_Handled_Sequence_Of_Statements (Loc,
7032                                Statements         => New_List (Adj_Stmt),
7033                                Exception_Handlers => New_List (
7034                                  Build_Exception_Handler (Finalizer_Data))));
7035                     end if;
7036
7037                     Prepend_To (Bod_Stmts, Adj_Stmt);
7038                  end if;
7039               end if;
7040            end;
7041         end if;
7042
7043         --  Adjust the object. This action must be performed last after all
7044         --  components have been adjusted.
7045
7046         if Is_Controlled (Typ) then
7047            declare
7048               Adj_Stmt : Node_Id;
7049               Proc     : Entity_Id;
7050
7051            begin
7052               Proc := Find_Optional_Prim_Op (Typ, Name_Adjust);
7053
7054               --  Generate:
7055               --    if F then
7056               --       begin
7057               --          Adjust (V);
7058
7059               --       exception
7060               --          when others =>
7061               --             if not Raised then
7062               --                Raised := True;
7063               --                Save_Occurrence (E,
7064               --                  Get_Current_Excep.all.all);
7065               --             end if;
7066               --       end;
7067               --    end if;
7068
7069               if Present (Proc) then
7070                  Adj_Stmt :=
7071                    Make_Procedure_Call_Statement (Loc,
7072                      Name                   => New_Occurrence_Of (Proc, Loc),
7073                      Parameter_Associations => New_List (
7074                        Make_Identifier (Loc, Name_V)));
7075
7076                  if Exceptions_OK then
7077                     Adj_Stmt :=
7078                       Make_Block_Statement (Loc,
7079                         Handled_Statement_Sequence =>
7080                           Make_Handled_Sequence_Of_Statements (Loc,
7081                             Statements         => New_List (Adj_Stmt),
7082                             Exception_Handlers => New_List (
7083                               Build_Exception_Handler
7084                                 (Finalizer_Data))));
7085                  end if;
7086
7087                  Append_To (Bod_Stmts,
7088                    Make_If_Statement (Loc,
7089                      Condition       => Make_Identifier (Loc, Name_F),
7090                      Then_Statements => New_List (Adj_Stmt)));
7091               end if;
7092            end;
7093         end if;
7094
7095         --  At this point either all adjustment statements have been generated
7096         --  or the type is not controlled.
7097
7098         if Is_Empty_List (Bod_Stmts) then
7099            Append_To (Bod_Stmts, Make_Null_Statement (Loc));
7100
7101            return Bod_Stmts;
7102
7103         --  Generate:
7104         --    declare
7105         --       Abort  : constant Boolean := Triggered_By_Abort;
7106         --         <or>
7107         --       Abort  : constant Boolean := False;  --  no abort
7108
7109         --       E      : Exception_Occurrence;
7110         --       Raised : Boolean := False;
7111
7112         --    begin
7113         --       <adjust statements>
7114
7115         --       if Raised and then not Abort then
7116         --          Raise_From_Controlled_Operation (E);
7117         --       end if;
7118         --    end;
7119
7120         else
7121            if Exceptions_OK then
7122               Append_To (Bod_Stmts, Build_Raise_Statement (Finalizer_Data));
7123            end if;
7124
7125            return
7126              New_List (
7127                Make_Block_Statement (Loc,
7128                  Declarations               =>
7129                    Finalizer_Decls,
7130                  Handled_Statement_Sequence =>
7131                    Make_Handled_Sequence_Of_Statements (Loc, Bod_Stmts)));
7132         end if;
7133      end Build_Adjust_Statements;
7134
7135      -------------------------------
7136      -- Build_Finalize_Statements --
7137      -------------------------------
7138
7139      function Build_Finalize_Statements (Typ : Entity_Id) return List_Id is
7140         Loc     : constant Source_Ptr := Sloc (Typ);
7141         Typ_Def : constant Node_Id    := Type_Definition (Parent (Typ));
7142
7143         Counter        : Int := 0;
7144         Finalizer_Data : Finalization_Exception_Data;
7145
7146         function Process_Component_List_For_Finalize
7147           (Comps : Node_Id) return List_Id;
7148         --  Build all necessary finalization statements for a single component
7149         --  list. The statements may include a jump circuitry if flag Is_Local
7150         --  is enabled.
7151
7152         -----------------------------------------
7153         -- Process_Component_List_For_Finalize --
7154         -----------------------------------------
7155
7156         function Process_Component_List_For_Finalize
7157           (Comps : Node_Id) return List_Id
7158         is
7159            procedure Process_Component_For_Finalize
7160              (Decl      : Node_Id;
7161               Alts      : List_Id;
7162               Decls     : List_Id;
7163               Stmts     : List_Id;
7164               Num_Comps : in out Nat);
7165            --  Process the declaration of a single controlled component. If
7166            --  flag Is_Local is enabled, create the corresponding label and
7167            --  jump circuitry. Alts is the list of case alternatives, Decls
7168            --  is the top level declaration list where labels are declared
7169            --  and Stmts is the list of finalization actions. Num_Comps
7170            --  denotes the current number of components needing finalization.
7171
7172            ------------------------------------
7173            -- Process_Component_For_Finalize --
7174            ------------------------------------
7175
7176            procedure Process_Component_For_Finalize
7177              (Decl      : Node_Id;
7178               Alts      : List_Id;
7179               Decls     : List_Id;
7180               Stmts     : List_Id;
7181               Num_Comps : in out Nat)
7182            is
7183               Id       : constant Entity_Id := Defining_Identifier (Decl);
7184               Typ      : constant Entity_Id := Etype (Id);
7185               Fin_Call : Node_Id;
7186
7187            begin
7188               if Is_Local then
7189                  declare
7190                     Label    : Node_Id;
7191                     Label_Id : Entity_Id;
7192
7193                  begin
7194                     --  Generate:
7195                     --    LN : label;
7196
7197                     Label_Id :=
7198                       Make_Identifier (Loc,
7199                         Chars => New_External_Name ('L', Num_Comps));
7200                     Set_Entity (Label_Id,
7201                       Make_Defining_Identifier (Loc, Chars (Label_Id)));
7202                     Label := Make_Label (Loc, Label_Id);
7203
7204                     Append_To (Decls,
7205                       Make_Implicit_Label_Declaration (Loc,
7206                         Defining_Identifier => Entity (Label_Id),
7207                         Label_Construct     => Label));
7208
7209                     --  Generate:
7210                     --    when N =>
7211                     --      goto LN;
7212
7213                     Append_To (Alts,
7214                       Make_Case_Statement_Alternative (Loc,
7215                         Discrete_Choices => New_List (
7216                           Make_Integer_Literal (Loc, Num_Comps)),
7217
7218                         Statements => New_List (
7219                           Make_Goto_Statement (Loc,
7220                             Name =>
7221                               New_Occurrence_Of (Entity (Label_Id), Loc)))));
7222
7223                     --  Generate:
7224                     --    <<LN>>
7225
7226                     Append_To (Stmts, Label);
7227
7228                     --  Decrease the number of components to be processed.
7229                     --  This action yields a new Label_Id in future calls.
7230
7231                     Num_Comps := Num_Comps - 1;
7232                  end;
7233               end if;
7234
7235               --  Generate:
7236               --    [Deep_]Finalize (V.Id);  --  No_Exception_Propagation
7237
7238               --    begin                    --  Exception handlers allowed
7239               --       [Deep_]Finalize (V.Id);
7240               --    exception
7241               --       when others =>
7242               --          if not Raised then
7243               --             Raised := True;
7244               --             Save_Occurrence (E,
7245               --               Get_Current_Excep.all.all);
7246               --          end if;
7247               --    end;
7248
7249               Fin_Call :=
7250                 Make_Final_Call
7251                   (Obj_Ref =>
7252                      Make_Selected_Component (Loc,
7253                        Prefix        => Make_Identifier (Loc, Name_V),
7254                        Selector_Name => Make_Identifier (Loc, Chars (Id))),
7255                    Typ     => Typ);
7256
7257               --  Guard against a missing [Deep_]Finalize when the component
7258               --  type was not properly frozen.
7259
7260               if Present (Fin_Call) then
7261                  if Exceptions_OK then
7262                     Fin_Call :=
7263                       Make_Block_Statement (Loc,
7264                         Handled_Statement_Sequence =>
7265                           Make_Handled_Sequence_Of_Statements (Loc,
7266                             Statements         => New_List (Fin_Call),
7267                             Exception_Handlers => New_List (
7268                               Build_Exception_Handler (Finalizer_Data))));
7269                  end if;
7270
7271                  Append_To (Stmts, Fin_Call);
7272               end if;
7273            end Process_Component_For_Finalize;
7274
7275            --  Local variables
7276
7277            Alts       : List_Id;
7278            Counter_Id : Entity_Id := Empty;
7279            Decl       : Node_Id;
7280            Decl_Id    : Entity_Id;
7281            Decl_Typ   : Entity_Id;
7282            Decls      : List_Id;
7283            Has_POC    : Boolean;
7284            Jump_Block : Node_Id;
7285            Label      : Node_Id;
7286            Label_Id   : Entity_Id;
7287            Num_Comps  : Nat;
7288            Stmts      : List_Id;
7289            Var_Case   : Node_Id;
7290
7291         --  Start of processing for Process_Component_List_For_Finalize
7292
7293         begin
7294            --  Perform an initial check, look for controlled and per-object
7295            --  constrained components.
7296
7297            Preprocess_Components (Comps, Num_Comps, Has_POC);
7298
7299            --  Create a state counter to service the current component list.
7300            --  This step is performed before the variants are inspected in
7301            --  order to generate the same state counter names as those from
7302            --  Build_Initialize_Statements.
7303
7304            if Num_Comps > 0 and then Is_Local then
7305               Counter := Counter + 1;
7306
7307               Counter_Id :=
7308                 Make_Defining_Identifier (Loc,
7309                   Chars => New_External_Name ('C', Counter));
7310            end if;
7311
7312            --  Process the component in the following order:
7313            --    1) Variants
7314            --    2) Per-object constrained components
7315            --    3) Regular components
7316
7317            --  Start with the variant parts
7318
7319            Var_Case := Empty;
7320            if Present (Variant_Part (Comps)) then
7321               declare
7322                  Var_Alts : constant List_Id := New_List;
7323                  Var      : Node_Id;
7324
7325               begin
7326                  Var := First_Non_Pragma (Variants (Variant_Part (Comps)));
7327                  while Present (Var) loop
7328
7329                     --  Generate:
7330                     --     when <discrete choices> =>
7331                     --        <finalize statements>
7332
7333                     Append_To (Var_Alts,
7334                       Make_Case_Statement_Alternative (Loc,
7335                         Discrete_Choices =>
7336                           New_Copy_List (Discrete_Choices (Var)),
7337                         Statements =>
7338                           Process_Component_List_For_Finalize (
7339                             Component_List (Var))));
7340
7341                     Next_Non_Pragma (Var);
7342                  end loop;
7343
7344                  --  Generate:
7345                  --     case V.<discriminant> is
7346                  --        when <discrete choices 1> =>
7347                  --           <finalize statements 1>
7348                  --        ...
7349                  --        when <discrete choices N> =>
7350                  --           <finalize statements N>
7351                  --     end case;
7352
7353                  Var_Case :=
7354                    Make_Case_Statement (Loc,
7355                      Expression =>
7356                        Make_Selected_Component (Loc,
7357                          Prefix        => Make_Identifier (Loc, Name_V),
7358                          Selector_Name =>
7359                            Make_Identifier (Loc,
7360                              Chars => Chars (Name (Variant_Part (Comps))))),
7361                      Alternatives => Var_Alts);
7362               end;
7363            end if;
7364
7365            --  The current component list does not have a single controlled
7366            --  component, however it may contain variants. Return the case
7367            --  statement for the variants or nothing.
7368
7369            if Num_Comps = 0 then
7370               if Present (Var_Case) then
7371                  return New_List (Var_Case);
7372               else
7373                  return New_List (Make_Null_Statement (Loc));
7374               end if;
7375            end if;
7376
7377            --  Prepare all lists
7378
7379            Alts  := New_List;
7380            Decls := New_List;
7381            Stmts := New_List;
7382
7383            --  Process all per-object constrained components in reverse order
7384
7385            if Has_POC then
7386               Decl := Last_Non_Pragma (Component_Items (Comps));
7387               while Present (Decl) loop
7388                  Decl_Id  := Defining_Identifier (Decl);
7389                  Decl_Typ := Etype (Decl_Id);
7390
7391                  --  Skip _parent
7392
7393                  if Chars (Decl_Id) /= Name_uParent
7394                    and then Needs_Finalization (Decl_Typ)
7395                    and then Has_Access_Constraint (Decl_Id)
7396                    and then No (Expression (Decl))
7397                  then
7398                     Process_Component_For_Finalize
7399                       (Decl, Alts, Decls, Stmts, Num_Comps);
7400                  end if;
7401
7402                  Prev_Non_Pragma (Decl);
7403               end loop;
7404            end if;
7405
7406            --  Process the rest of the components in reverse order
7407
7408            Decl := Last_Non_Pragma (Component_Items (Comps));
7409            while Present (Decl) loop
7410               Decl_Id  := Defining_Identifier (Decl);
7411               Decl_Typ := Etype (Decl_Id);
7412
7413               --  Skip _parent
7414
7415               if Chars (Decl_Id) /= Name_uParent
7416                 and then Needs_Finalization (Decl_Typ)
7417               then
7418                  --  Skip per-object constrained components since they were
7419                  --  handled in the above step.
7420
7421                  if Has_Access_Constraint (Decl_Id)
7422                    and then No (Expression (Decl))
7423                  then
7424                     null;
7425                  else
7426                     Process_Component_For_Finalize
7427                       (Decl, Alts, Decls, Stmts, Num_Comps);
7428                  end if;
7429               end if;
7430
7431               Prev_Non_Pragma (Decl);
7432            end loop;
7433
7434            --  Generate:
7435            --    declare
7436            --       LN : label;        --  If Is_Local is enabled
7437            --       ...                    .
7438            --       L0 : label;            .
7439
7440            --    begin                     .
7441            --       case CounterX is       .
7442            --          when N =>           .
7443            --             goto LN;         .
7444            --          ...                 .
7445            --          when 1 =>           .
7446            --             goto L1;         .
7447            --          when others =>      .
7448            --             goto L0;         .
7449            --       end case;              .
7450
7451            --       <<LN>>             --  If Is_Local is enabled
7452            --          begin
7453            --             [Deep_]Finalize (V.CompY);
7454            --          exception
7455            --             when Id : others =>
7456            --                if not Raised then
7457            --                   Raised := True;
7458            --                   Save_Occurrence (E,
7459            --                     Get_Current_Excep.all.all);
7460            --                end if;
7461            --          end;
7462            --       ...
7463            --       <<L0>>  --  If Is_Local is enabled
7464            --    end;
7465
7466            if Is_Local then
7467
7468               --  Add the declaration of default jump location L0, its
7469               --  corresponding alternative and its place in the statements.
7470
7471               Label_Id := Make_Identifier (Loc, New_External_Name ('L', 0));
7472               Set_Entity (Label_Id,
7473                 Make_Defining_Identifier (Loc, Chars (Label_Id)));
7474               Label := Make_Label (Loc, Label_Id);
7475
7476               Append_To (Decls,          --  declaration
7477                 Make_Implicit_Label_Declaration (Loc,
7478                   Defining_Identifier => Entity (Label_Id),
7479                   Label_Construct     => Label));
7480
7481               Append_To (Alts,           --  alternative
7482                 Make_Case_Statement_Alternative (Loc,
7483                   Discrete_Choices => New_List (
7484                     Make_Others_Choice (Loc)),
7485
7486                   Statements => New_List (
7487                     Make_Goto_Statement (Loc,
7488                       Name => New_Occurrence_Of (Entity (Label_Id), Loc)))));
7489
7490               Append_To (Stmts, Label);  --  statement
7491
7492               --  Create the jump block
7493
7494               Prepend_To (Stmts,
7495                 Make_Case_Statement (Loc,
7496                   Expression   => Make_Identifier (Loc, Chars (Counter_Id)),
7497                   Alternatives => Alts));
7498            end if;
7499
7500            Jump_Block :=
7501              Make_Block_Statement (Loc,
7502                Declarations               => Decls,
7503                Handled_Statement_Sequence =>
7504                  Make_Handled_Sequence_Of_Statements (Loc, Stmts));
7505
7506            if Present (Var_Case) then
7507               return New_List (Var_Case, Jump_Block);
7508            else
7509               return New_List (Jump_Block);
7510            end if;
7511         end Process_Component_List_For_Finalize;
7512
7513         --  Local variables
7514
7515         Bod_Stmts       : List_Id := No_List;
7516         Finalizer_Decls : List_Id := No_List;
7517         Rec_Def         : Node_Id;
7518
7519      --  Start of processing for Build_Finalize_Statements
7520
7521      begin
7522         Finalizer_Decls := New_List;
7523         Build_Object_Declarations (Finalizer_Data, Finalizer_Decls, Loc);
7524
7525         if Nkind (Typ_Def) = N_Derived_Type_Definition then
7526            Rec_Def := Record_Extension_Part (Typ_Def);
7527         else
7528            Rec_Def := Typ_Def;
7529         end if;
7530
7531         --  Create a finalization sequence for all record components
7532
7533         if Present (Component_List (Rec_Def)) then
7534            Bod_Stmts :=
7535              Process_Component_List_For_Finalize (Component_List (Rec_Def));
7536         end if;
7537
7538         --  A derived record type must finalize all inherited components. This
7539         --  action poses the following problem:
7540
7541         --    procedure Deep_Finalize (Obj : in out Parent_Typ) is
7542         --    begin
7543         --       Finalize (Obj);
7544         --       ...
7545
7546         --    procedure Deep_Finalize (Obj : in out Derived_Typ) is
7547         --    begin
7548         --       Deep_Finalize (Obj._parent);
7549         --       ...
7550         --       Finalize (Obj);
7551         --       ...
7552
7553         --  Finalizing the derived type will invoke Finalize of the parent and
7554         --  then that of the derived type. This is undesirable because both
7555         --  routines may modify shared components. Only the Finalize of the
7556         --  derived type should be invoked.
7557
7558         --  To prevent this double adjustment of shared components,
7559         --  Deep_Finalize uses a flag to control the invocation of Finalize:
7560
7561         --    procedure Deep_Finalize
7562         --      (Obj  : in out Some_Type;
7563         --       Flag : Boolean := True)
7564         --    is
7565         --    begin
7566         --       if Flag then
7567         --          Finalize (Obj);
7568         --       end if;
7569         --       ...
7570
7571         --  When Deep_Finalize is invoked for field _parent, a value of False
7572         --  is provided for the flag:
7573
7574         --    Deep_Finalize (Obj._parent, False);
7575
7576         if Is_Tagged_Type (Typ) and then Is_Derived_Type (Typ) then
7577            declare
7578               Par_Typ  : constant Entity_Id := Parent_Field_Type (Typ);
7579               Call     : Node_Id;
7580               Fin_Stmt : Node_Id;
7581
7582            begin
7583               if Needs_Finalization (Par_Typ) then
7584                  Call :=
7585                    Make_Final_Call
7586                      (Obj_Ref   =>
7587                         Make_Selected_Component (Loc,
7588                           Prefix        => Make_Identifier (Loc, Name_V),
7589                           Selector_Name =>
7590                             Make_Identifier (Loc, Name_uParent)),
7591                       Typ       => Par_Typ,
7592                       Skip_Self => True);
7593
7594                  --  Generate:
7595                  --    begin
7596                  --       Deep_Finalize (V._parent, False);
7597
7598                  --    exception
7599                  --       when Id : others =>
7600                  --          if not Raised then
7601                  --             Raised := True;
7602                  --             Save_Occurrence (E,
7603                  --               Get_Current_Excep.all.all);
7604                  --          end if;
7605                  --    end;
7606
7607                  if Present (Call) then
7608                     Fin_Stmt := Call;
7609
7610                     if Exceptions_OK then
7611                        Fin_Stmt :=
7612                          Make_Block_Statement (Loc,
7613                            Handled_Statement_Sequence =>
7614                              Make_Handled_Sequence_Of_Statements (Loc,
7615                                Statements         => New_List (Fin_Stmt),
7616                                Exception_Handlers => New_List (
7617                                  Build_Exception_Handler
7618                                    (Finalizer_Data))));
7619                     end if;
7620
7621                     Append_To (Bod_Stmts, Fin_Stmt);
7622                  end if;
7623               end if;
7624            end;
7625         end if;
7626
7627         --  Finalize the object. This action must be performed first before
7628         --  all components have been finalized.
7629
7630         if Is_Controlled (Typ) and then not Is_Local then
7631            declare
7632               Fin_Stmt : Node_Id;
7633               Proc     : Entity_Id;
7634
7635            begin
7636               Proc := Find_Optional_Prim_Op (Typ, Name_Finalize);
7637
7638               --  Generate:
7639               --    if F then
7640               --       begin
7641               --          Finalize (V);
7642
7643               --       exception
7644               --          when others =>
7645               --             if not Raised then
7646               --                Raised := True;
7647               --                Save_Occurrence (E,
7648               --                  Get_Current_Excep.all.all);
7649               --             end if;
7650               --       end;
7651               --    end if;
7652
7653               if Present (Proc) then
7654                  Fin_Stmt :=
7655                    Make_Procedure_Call_Statement (Loc,
7656                      Name                   => New_Occurrence_Of (Proc, Loc),
7657                      Parameter_Associations => New_List (
7658                        Make_Identifier (Loc, Name_V)));
7659
7660                  if Exceptions_OK then
7661                     Fin_Stmt :=
7662                       Make_Block_Statement (Loc,
7663                         Handled_Statement_Sequence =>
7664                           Make_Handled_Sequence_Of_Statements (Loc,
7665                             Statements         => New_List (Fin_Stmt),
7666                             Exception_Handlers => New_List (
7667                               Build_Exception_Handler
7668                                 (Finalizer_Data))));
7669                  end if;
7670
7671                  Prepend_To (Bod_Stmts,
7672                    Make_If_Statement (Loc,
7673                      Condition       => Make_Identifier (Loc, Name_F),
7674                      Then_Statements => New_List (Fin_Stmt)));
7675               end if;
7676            end;
7677         end if;
7678
7679         --  At this point either all finalization statements have been
7680         --  generated or the type is not controlled.
7681
7682         if No (Bod_Stmts) then
7683            return New_List (Make_Null_Statement (Loc));
7684
7685         --  Generate:
7686         --    declare
7687         --       Abort  : constant Boolean := Triggered_By_Abort;
7688         --         <or>
7689         --       Abort  : constant Boolean := False;  --  no abort
7690
7691         --       E      : Exception_Occurrence;
7692         --       Raised : Boolean := False;
7693
7694         --    begin
7695         --       <finalize statements>
7696
7697         --       if Raised and then not Abort then
7698         --          Raise_From_Controlled_Operation (E);
7699         --       end if;
7700         --    end;
7701
7702         else
7703            if Exceptions_OK then
7704               Append_To (Bod_Stmts, Build_Raise_Statement (Finalizer_Data));
7705            end if;
7706
7707            return
7708              New_List (
7709                Make_Block_Statement (Loc,
7710                  Declarations               =>
7711                    Finalizer_Decls,
7712                  Handled_Statement_Sequence =>
7713                    Make_Handled_Sequence_Of_Statements (Loc, Bod_Stmts)));
7714         end if;
7715      end Build_Finalize_Statements;
7716
7717      -----------------------
7718      -- Parent_Field_Type --
7719      -----------------------
7720
7721      function Parent_Field_Type (Typ : Entity_Id) return Entity_Id is
7722         Field : Entity_Id;
7723
7724      begin
7725         Field := First_Entity (Typ);
7726         while Present (Field) loop
7727            if Chars (Field) = Name_uParent then
7728               return Etype (Field);
7729            end if;
7730
7731            Next_Entity (Field);
7732         end loop;
7733
7734         --  A derived tagged type should always have a parent field
7735
7736         raise Program_Error;
7737      end Parent_Field_Type;
7738
7739      ---------------------------
7740      -- Preprocess_Components --
7741      ---------------------------
7742
7743      procedure Preprocess_Components
7744        (Comps     : Node_Id;
7745         Num_Comps : out Nat;
7746         Has_POC   : out Boolean)
7747      is
7748         Decl : Node_Id;
7749         Id   : Entity_Id;
7750         Typ  : Entity_Id;
7751
7752      begin
7753         Num_Comps := 0;
7754         Has_POC   := False;
7755
7756         Decl := First_Non_Pragma (Component_Items (Comps));
7757         while Present (Decl) loop
7758            Id  := Defining_Identifier (Decl);
7759            Typ := Etype (Id);
7760
7761            --  Skip field _parent
7762
7763            if Chars (Id) /= Name_uParent
7764              and then Needs_Finalization (Typ)
7765            then
7766               Num_Comps := Num_Comps + 1;
7767
7768               if Has_Access_Constraint (Id)
7769                 and then No (Expression (Decl))
7770               then
7771                  Has_POC := True;
7772               end if;
7773            end if;
7774
7775            Next_Non_Pragma (Decl);
7776         end loop;
7777      end Preprocess_Components;
7778
7779   --  Start of processing for Make_Deep_Record_Body
7780
7781   begin
7782      case Prim is
7783         when Address_Case =>
7784            return Make_Finalize_Address_Stmts (Typ);
7785
7786         when Adjust_Case =>
7787            return Build_Adjust_Statements (Typ);
7788
7789         when Finalize_Case =>
7790            return Build_Finalize_Statements (Typ);
7791
7792         when Initialize_Case =>
7793            declare
7794               Loc : constant Source_Ptr := Sloc (Typ);
7795
7796            begin
7797               if Is_Controlled (Typ) then
7798                  return New_List (
7799                    Make_Procedure_Call_Statement (Loc,
7800                      Name                   =>
7801                        New_Occurrence_Of
7802                          (Find_Prim_Op (Typ, Name_Of (Prim)), Loc),
7803                      Parameter_Associations => New_List (
7804                        Make_Identifier (Loc, Name_V))));
7805               else
7806                  return Empty_List;
7807               end if;
7808            end;
7809      end case;
7810   end Make_Deep_Record_Body;
7811
7812   ----------------------
7813   -- Make_Final_Call --
7814   ----------------------
7815
7816   function Make_Final_Call
7817     (Obj_Ref   : Node_Id;
7818      Typ       : Entity_Id;
7819      Skip_Self : Boolean := False) return Node_Id
7820   is
7821      Loc    : constant Source_Ptr := Sloc (Obj_Ref);
7822      Atyp   : Entity_Id;
7823      Fin_Id : Entity_Id := Empty;
7824      Ref    : Node_Id;
7825      Utyp   : Entity_Id;
7826
7827   begin
7828      Ref := Obj_Ref;
7829
7830      --  Recover the proper type which contains [Deep_]Finalize
7831
7832      if Is_Class_Wide_Type (Typ) then
7833         Utyp := Root_Type (Typ);
7834         Atyp := Utyp;
7835
7836      elsif Is_Concurrent_Type (Typ) then
7837         Utyp := Corresponding_Record_Type (Typ);
7838         Atyp := Empty;
7839         Ref  := Convert_Concurrent (Ref, Typ);
7840
7841      elsif Is_Private_Type (Typ)
7842        and then Present (Full_View (Typ))
7843        and then Is_Concurrent_Type (Full_View (Typ))
7844      then
7845         Utyp := Corresponding_Record_Type (Full_View (Typ));
7846         Atyp := Typ;
7847         Ref  := Convert_Concurrent (Ref, Full_View (Typ));
7848
7849      else
7850         Utyp := Typ;
7851         Atyp := Typ;
7852      end if;
7853
7854      Utyp := Underlying_Type (Base_Type (Utyp));
7855      Set_Assignment_OK (Ref);
7856
7857      --  Deal with untagged derivation of private views. If the parent type
7858      --  is a protected type, Deep_Finalize is found on the corresponding
7859      --  record of the ancestor.
7860
7861      if Is_Untagged_Derivation (Typ) then
7862         if Is_Protected_Type (Typ) then
7863            Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ)));
7864         else
7865            Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
7866
7867            if Is_Protected_Type (Utyp) then
7868               Utyp := Corresponding_Record_Type (Utyp);
7869            end if;
7870         end if;
7871
7872         Ref := Unchecked_Convert_To (Utyp, Ref);
7873         Set_Assignment_OK (Ref);
7874      end if;
7875
7876      --  Deal with derived private types which do not inherit primitives from
7877      --  their parents. In this case, [Deep_]Finalize can be found in the full
7878      --  view of the parent type.
7879
7880      if Present (Utyp)
7881        and then Is_Tagged_Type (Utyp)
7882        and then Is_Derived_Type (Utyp)
7883        and then Is_Empty_Elmt_List (Primitive_Operations (Utyp))
7884        and then Is_Private_Type (Etype (Utyp))
7885        and then Present (Full_View (Etype (Utyp)))
7886      then
7887         Utyp := Full_View (Etype (Utyp));
7888         Ref  := Unchecked_Convert_To (Utyp, Ref);
7889         Set_Assignment_OK (Ref);
7890      end if;
7891
7892      --  When dealing with the completion of a private type, use the base type
7893      --  instead.
7894
7895      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
7896         pragma Assert (Present (Atyp) and then Is_Private_Type (Atyp));
7897
7898         Utyp := Base_Type (Utyp);
7899         Ref  := Unchecked_Convert_To (Utyp, Ref);
7900         Set_Assignment_OK (Ref);
7901      end if;
7902
7903      --  The underlying type may not be present due to a missing full view. In
7904      --  this case freezing did not take place and there is no [Deep_]Finalize
7905      --  primitive to call.
7906
7907      if No (Utyp) then
7908         return Empty;
7909
7910      elsif Skip_Self then
7911         if Has_Controlled_Component (Utyp) then
7912            if Is_Tagged_Type (Utyp) then
7913               Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize);
7914            else
7915               Fin_Id := TSS (Utyp, TSS_Deep_Finalize);
7916            end if;
7917         end if;
7918
7919      --  Class-wide types, interfaces and types with controlled components
7920
7921      elsif Is_Class_Wide_Type (Typ)
7922        or else Is_Interface (Typ)
7923        or else Has_Controlled_Component (Utyp)
7924      then
7925         if Is_Tagged_Type (Utyp) then
7926            Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize);
7927         else
7928            Fin_Id := TSS (Utyp, TSS_Deep_Finalize);
7929         end if;
7930
7931      --  Derivations from [Limited_]Controlled
7932
7933      elsif Is_Controlled (Utyp) then
7934         if Has_Controlled_Component (Utyp) then
7935            Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize);
7936         else
7937            Fin_Id := Find_Optional_Prim_Op (Utyp, Name_Of (Finalize_Case));
7938         end if;
7939
7940      --  Tagged types
7941
7942      elsif Is_Tagged_Type (Utyp) then
7943         Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize);
7944
7945      else
7946         raise Program_Error;
7947      end if;
7948
7949      if Present (Fin_Id) then
7950
7951         --  When finalizing a class-wide object, do not convert to the root
7952         --  type in order to produce a dispatching call.
7953
7954         if Is_Class_Wide_Type (Typ) then
7955            null;
7956
7957         --  Ensure that a finalization routine is at least decorated in order
7958         --  to inspect the object parameter.
7959
7960         elsif Analyzed (Fin_Id)
7961           or else Ekind (Fin_Id) = E_Procedure
7962         then
7963            --  In certain cases, such as the creation of Stream_Read, the
7964            --  visible entity of the type is its full view. Since Stream_Read
7965            --  will have to create an object of type Typ, the local object
7966            --  will be finalzed by the scope finalizer generated later on. The
7967            --  object parameter of Deep_Finalize will always use the private
7968            --  view of the type. To avoid such a clash between a private and a
7969            --  full view, perform an unchecked conversion of the object
7970            --  reference to the private view.
7971
7972            declare
7973               Formal_Typ : constant Entity_Id :=
7974                              Etype (First_Formal (Fin_Id));
7975            begin
7976               if Is_Private_Type (Formal_Typ)
7977                 and then Present (Full_View (Formal_Typ))
7978                 and then Full_View (Formal_Typ) = Utyp
7979               then
7980                  Ref := Unchecked_Convert_To (Formal_Typ, Ref);
7981               end if;
7982            end;
7983
7984            Ref := Convert_View (Fin_Id, Ref);
7985         end if;
7986
7987         return
7988           Make_Call (Loc,
7989             Proc_Id   => Fin_Id,
7990             Param     => Ref,
7991             Skip_Self => Skip_Self);
7992      else
7993         return Empty;
7994      end if;
7995   end Make_Final_Call;
7996
7997   --------------------------------
7998   -- Make_Finalize_Address_Body --
7999   --------------------------------
8000
8001   procedure Make_Finalize_Address_Body (Typ : Entity_Id) is
8002      Is_Task : constant Boolean :=
8003                  Ekind (Typ) = E_Record_Type
8004                    and then Is_Concurrent_Record_Type (Typ)
8005                    and then Ekind (Corresponding_Concurrent_Type (Typ)) =
8006                                                                 E_Task_Type;
8007      Loc     : constant Source_Ptr := Sloc (Typ);
8008      Proc_Id : Entity_Id;
8009      Stmts   : List_Id;
8010
8011   begin
8012      --  The corresponding records of task types are not controlled by design.
8013      --  For the sake of completeness, create an empty Finalize_Address to be
8014      --  used in task class-wide allocations.
8015
8016      if Is_Task then
8017         null;
8018
8019      --  Nothing to do if the type is not controlled or it already has a
8020      --  TSS entry for Finalize_Address. Skip class-wide subtypes which do not
8021      --  come from source. These are usually generated for completeness and
8022      --  do not need the Finalize_Address primitive.
8023
8024      elsif not Needs_Finalization (Typ)
8025        or else Present (TSS (Typ, TSS_Finalize_Address))
8026        or else
8027          (Is_Class_Wide_Type (Typ)
8028            and then Ekind (Root_Type (Typ)) = E_Record_Subtype
8029            and then not Comes_From_Source (Root_Type (Typ)))
8030      then
8031         return;
8032      end if;
8033
8034      --  Do not generate Finalize_Address routine for CodePeer
8035
8036      if CodePeer_Mode then
8037         return;
8038      end if;
8039
8040      Proc_Id :=
8041        Make_Defining_Identifier (Loc,
8042          Make_TSS_Name (Typ, TSS_Finalize_Address));
8043
8044      --  Generate:
8045
8046      --    procedure <Typ>FD (V : System.Address) is
8047      --    begin
8048      --       null;                            --  for tasks
8049
8050      --       declare                          --  for all other types
8051      --          type Pnn is access all Typ;
8052      --          for Pnn'Storage_Size use 0;
8053      --       begin
8054      --          [Deep_]Finalize (Pnn (V).all);
8055      --       end;
8056      --    end TypFD;
8057
8058      if Is_Task then
8059         Stmts := New_List (Make_Null_Statement (Loc));
8060      else
8061         Stmts := Make_Finalize_Address_Stmts (Typ);
8062      end if;
8063
8064      Discard_Node (
8065        Make_Subprogram_Body (Loc,
8066          Specification =>
8067            Make_Procedure_Specification (Loc,
8068              Defining_Unit_Name => Proc_Id,
8069
8070              Parameter_Specifications => New_List (
8071                Make_Parameter_Specification (Loc,
8072                  Defining_Identifier =>
8073                    Make_Defining_Identifier (Loc, Name_V),
8074                  Parameter_Type =>
8075                    New_Occurrence_Of (RTE (RE_Address), Loc)))),
8076
8077          Declarations => No_List,
8078
8079          Handled_Statement_Sequence =>
8080            Make_Handled_Sequence_Of_Statements (Loc,
8081              Statements => Stmts)));
8082
8083      Set_TSS (Typ, Proc_Id);
8084   end Make_Finalize_Address_Body;
8085
8086   ---------------------------------
8087   -- Make_Finalize_Address_Stmts --
8088   ---------------------------------
8089
8090   function Make_Finalize_Address_Stmts (Typ : Entity_Id) return List_Id is
8091      Loc : constant Source_Ptr := Sloc (Typ);
8092
8093      Decls     : List_Id;
8094      Desig_Typ : Entity_Id;
8095      Fin_Block : Node_Id;
8096      Fin_Call  : Node_Id;
8097      Obj_Expr  : Node_Id;
8098      Ptr_Typ   : Entity_Id;
8099
8100   begin
8101      if Is_Array_Type (Typ) then
8102         if Is_Constrained (First_Subtype (Typ)) then
8103            Desig_Typ := First_Subtype (Typ);
8104         else
8105            Desig_Typ := Base_Type (Typ);
8106         end if;
8107
8108      --  Class-wide types of constrained root types
8109
8110      elsif Is_Class_Wide_Type (Typ)
8111        and then Has_Discriminants (Root_Type (Typ))
8112        and then not
8113          Is_Empty_Elmt_List (Discriminant_Constraint (Root_Type (Typ)))
8114      then
8115         declare
8116            Parent_Typ : Entity_Id;
8117
8118         begin
8119            --  Climb the parent type chain looking for a non-constrained type
8120
8121            Parent_Typ := Root_Type (Typ);
8122            while Parent_Typ /= Etype (Parent_Typ)
8123              and then Has_Discriminants (Parent_Typ)
8124              and then not
8125                Is_Empty_Elmt_List (Discriminant_Constraint (Parent_Typ))
8126            loop
8127               Parent_Typ := Etype (Parent_Typ);
8128            end loop;
8129
8130            --  Handle views created for tagged types with unknown
8131            --  discriminants.
8132
8133            if Is_Underlying_Record_View (Parent_Typ) then
8134               Parent_Typ := Underlying_Record_View (Parent_Typ);
8135            end if;
8136
8137            Desig_Typ := Class_Wide_Type (Underlying_Type (Parent_Typ));
8138         end;
8139
8140      --  General case
8141
8142      else
8143         Desig_Typ := Typ;
8144      end if;
8145
8146      --  Generate:
8147      --    type Ptr_Typ is access all Typ;
8148      --    for Ptr_Typ'Storage_Size use 0;
8149
8150      Ptr_Typ := Make_Temporary (Loc, 'P');
8151
8152      Decls := New_List (
8153        Make_Full_Type_Declaration (Loc,
8154          Defining_Identifier => Ptr_Typ,
8155          Type_Definition     =>
8156            Make_Access_To_Object_Definition (Loc,
8157              All_Present        => True,
8158              Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc))),
8159
8160        Make_Attribute_Definition_Clause (Loc,
8161          Name       => New_Occurrence_Of (Ptr_Typ, Loc),
8162          Chars      => Name_Storage_Size,
8163          Expression => Make_Integer_Literal (Loc, 0)));
8164
8165      Obj_Expr := Make_Identifier (Loc, Name_V);
8166
8167      --  Unconstrained arrays require special processing in order to retrieve
8168      --  the elements. To achieve this, we have to skip the dope vector which
8169      --  lays in front of the elements and then use a thin pointer to perform
8170      --  the address-to-access conversion.
8171
8172      if Is_Array_Type (Typ)
8173        and then not Is_Constrained (First_Subtype (Typ))
8174      then
8175         declare
8176            Dope_Id : Entity_Id;
8177
8178         begin
8179            --  Ensure that Ptr_Typ a thin pointer, generate:
8180            --    for Ptr_Typ'Size use System.Address'Size;
8181
8182            Append_To (Decls,
8183              Make_Attribute_Definition_Clause (Loc,
8184                Name       => New_Occurrence_Of (Ptr_Typ, Loc),
8185                Chars      => Name_Size,
8186                Expression =>
8187                  Make_Integer_Literal (Loc, System_Address_Size)));
8188
8189            --  Generate:
8190            --    Dnn : constant Storage_Offset :=
8191            --            Desig_Typ'Descriptor_Size / Storage_Unit;
8192
8193            Dope_Id := Make_Temporary (Loc, 'D');
8194
8195            Append_To (Decls,
8196              Make_Object_Declaration (Loc,
8197                Defining_Identifier => Dope_Id,
8198                Constant_Present    => True,
8199                Object_Definition   =>
8200                  New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
8201                Expression          =>
8202                  Make_Op_Divide (Loc,
8203                    Left_Opnd  =>
8204                      Make_Attribute_Reference (Loc,
8205                        Prefix         => New_Occurrence_Of (Desig_Typ, Loc),
8206                        Attribute_Name => Name_Descriptor_Size),
8207                    Right_Opnd =>
8208                      Make_Integer_Literal (Loc, System_Storage_Unit))));
8209
8210            --  Shift the address from the start of the dope vector to the
8211            --  start of the elements:
8212            --
8213            --    V + Dnn
8214            --
8215            --  Note that this is done through a wrapper routine since RTSfind
8216            --  cannot retrieve operations with string names of the form "+".
8217
8218            Obj_Expr :=
8219              Make_Function_Call (Loc,
8220                Name                   =>
8221                  New_Occurrence_Of (RTE (RE_Add_Offset_To_Address), Loc),
8222                Parameter_Associations => New_List (
8223                  Obj_Expr,
8224                  New_Occurrence_Of (Dope_Id, Loc)));
8225         end;
8226      end if;
8227
8228      Fin_Call :=
8229        Make_Final_Call (
8230          Obj_Ref =>
8231            Make_Explicit_Dereference (Loc,
8232              Prefix => Unchecked_Convert_To (Ptr_Typ, Obj_Expr)),
8233          Typ     => Desig_Typ);
8234
8235      if Present (Fin_Call) then
8236         Fin_Block :=
8237           Make_Block_Statement (Loc,
8238             Declarations               => Decls,
8239             Handled_Statement_Sequence =>
8240               Make_Handled_Sequence_Of_Statements (Loc,
8241                 Statements => New_List (Fin_Call)));
8242
8243      --  Otherwise previous errors or a missing full view may prevent the
8244      --  proper freezing of the designated type. If this is the case, there
8245      --  is no [Deep_]Finalize primitive to call.
8246
8247      else
8248         Fin_Block := Make_Null_Statement (Loc);
8249      end if;
8250
8251      return New_List (Fin_Block);
8252   end Make_Finalize_Address_Stmts;
8253
8254   -------------------------------------
8255   -- Make_Handler_For_Ctrl_Operation --
8256   -------------------------------------
8257
8258   --  Generate:
8259
8260   --    when E : others =>
8261   --      Raise_From_Controlled_Operation (E);
8262
8263   --  or:
8264
8265   --    when others =>
8266   --      raise Program_Error [finalize raised exception];
8267
8268   --  depending on whether Raise_From_Controlled_Operation is available
8269
8270   function Make_Handler_For_Ctrl_Operation
8271     (Loc : Source_Ptr) return Node_Id
8272   is
8273      E_Occ : Entity_Id;
8274      --  Choice parameter (for the first case above)
8275
8276      Raise_Node : Node_Id;
8277      --  Procedure call or raise statement
8278
8279   begin
8280      --  Standard run-time: add choice parameter E and pass it to
8281      --  Raise_From_Controlled_Operation so that the original exception
8282      --  name and message can be recorded in the exception message for
8283      --  Program_Error.
8284
8285      if RTE_Available (RE_Raise_From_Controlled_Operation) then
8286         E_Occ := Make_Defining_Identifier (Loc, Name_E);
8287         Raise_Node :=
8288           Make_Procedure_Call_Statement (Loc,
8289             Name                   =>
8290               New_Occurrence_Of
8291                 (RTE (RE_Raise_From_Controlled_Operation), Loc),
8292             Parameter_Associations => New_List (
8293               New_Occurrence_Of (E_Occ, Loc)));
8294
8295      --  Restricted run-time: exception messages are not supported
8296
8297      else
8298         E_Occ := Empty;
8299         Raise_Node :=
8300           Make_Raise_Program_Error (Loc,
8301             Reason => PE_Finalize_Raised_Exception);
8302      end if;
8303
8304      return
8305        Make_Implicit_Exception_Handler (Loc,
8306          Exception_Choices => New_List (Make_Others_Choice (Loc)),
8307          Choice_Parameter  => E_Occ,
8308          Statements        => New_List (Raise_Node));
8309   end Make_Handler_For_Ctrl_Operation;
8310
8311   --------------------
8312   -- Make_Init_Call --
8313   --------------------
8314
8315   function Make_Init_Call
8316     (Obj_Ref : Node_Id;
8317      Typ     : Entity_Id) return Node_Id
8318   is
8319      Loc     : constant Source_Ptr := Sloc (Obj_Ref);
8320      Is_Conc : Boolean;
8321      Proc    : Entity_Id;
8322      Ref     : Node_Id;
8323      Utyp    : Entity_Id;
8324
8325   begin
8326      Ref := Obj_Ref;
8327
8328      --  Deal with the type and object reference. Depending on the context, an
8329      --  object reference may need several conversions.
8330
8331      if Is_Concurrent_Type (Typ) then
8332         Is_Conc := True;
8333         Utyp    := Corresponding_Record_Type (Typ);
8334         Ref     := Convert_Concurrent (Ref, Typ);
8335
8336      elsif Is_Private_Type (Typ)
8337        and then Present (Full_View (Typ))
8338        and then Is_Concurrent_Type (Underlying_Type (Typ))
8339      then
8340         Is_Conc := True;
8341         Utyp    := Corresponding_Record_Type (Underlying_Type (Typ));
8342         Ref     := Convert_Concurrent (Ref, Underlying_Type (Typ));
8343
8344      else
8345         Is_Conc := False;
8346         Utyp    := Typ;
8347      end if;
8348
8349      Utyp := Underlying_Type (Base_Type (Utyp));
8350      Set_Assignment_OK (Ref);
8351
8352      --  Deal with untagged derivation of private views
8353
8354      if Is_Untagged_Derivation (Typ) and then not Is_Conc then
8355         Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
8356         Ref  := Unchecked_Convert_To (Utyp, Ref);
8357
8358         --  The following is to prevent problems with UC see 1.156 RH ???
8359
8360         Set_Assignment_OK (Ref);
8361      end if;
8362
8363      --  If the underlying_type is a subtype, then we are dealing with the
8364      --  completion of a private type. We need to access the base type and
8365      --  generate a conversion to it.
8366
8367      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
8368         pragma Assert (Is_Private_Type (Typ));
8369         Utyp := Base_Type (Utyp);
8370         Ref  := Unchecked_Convert_To (Utyp, Ref);
8371      end if;
8372
8373      --  The underlying type may not be present due to a missing full view.
8374      --  In this case freezing did not take place and there is no suitable
8375      --  [Deep_]Initialize primitive to call.
8376
8377      if No (Utyp) then
8378         return Empty;
8379      end if;
8380
8381      --  Select the appropriate version of initialize
8382
8383      if Has_Controlled_Component (Utyp) then
8384         Proc := TSS (Utyp, Deep_Name_Of (Initialize_Case));
8385      else
8386         Proc := Find_Prim_Op (Utyp, Name_Of (Initialize_Case));
8387         Check_Visibly_Controlled (Initialize_Case, Typ, Proc, Ref);
8388      end if;
8389
8390      --  If initialization procedure for an array of controlled objects is
8391      --  trivial, do not generate a useless call to it.
8392
8393      if (Is_Array_Type (Utyp) and then Is_Trivial_Subprogram (Proc))
8394        or else
8395          (not Comes_From_Source (Proc)
8396            and then Present (Alias (Proc))
8397            and then Is_Trivial_Subprogram (Alias (Proc)))
8398      then
8399         return Make_Null_Statement (Loc);
8400      end if;
8401
8402      --  The object reference may need another conversion depending on the
8403      --  type of the formal and that of the actual.
8404
8405      Ref := Convert_View (Proc, Ref);
8406
8407      --  Generate:
8408      --    [Deep_]Initialize (Ref);
8409
8410      return
8411        Make_Procedure_Call_Statement (Loc,
8412          Name                   => New_Occurrence_Of (Proc, Loc),
8413          Parameter_Associations => New_List (Ref));
8414   end Make_Init_Call;
8415
8416   ------------------------------
8417   -- Make_Local_Deep_Finalize --
8418   ------------------------------
8419
8420   function Make_Local_Deep_Finalize
8421     (Typ : Entity_Id;
8422      Nam : Entity_Id) return Node_Id
8423   is
8424      Loc : constant Source_Ptr := Sloc (Typ);
8425      Formals : List_Id;
8426
8427   begin
8428      Formals := New_List (
8429
8430         --  V : in out Typ
8431
8432        Make_Parameter_Specification (Loc,
8433          Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
8434          In_Present          => True,
8435          Out_Present         => True,
8436          Parameter_Type      => New_Occurrence_Of (Typ, Loc)),
8437
8438         --  F : Boolean := True
8439
8440        Make_Parameter_Specification (Loc,
8441          Defining_Identifier => Make_Defining_Identifier (Loc, Name_F),
8442          Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
8443          Expression          => New_Occurrence_Of (Standard_True, Loc)));
8444
8445      --  Add the necessary number of counters to represent the initialization
8446      --  state of an object.
8447
8448      return
8449        Make_Subprogram_Body (Loc,
8450          Specification =>
8451            Make_Procedure_Specification (Loc,
8452              Defining_Unit_Name       => Nam,
8453              Parameter_Specifications => Formals),
8454
8455          Declarations => No_List,
8456
8457          Handled_Statement_Sequence =>
8458            Make_Handled_Sequence_Of_Statements (Loc,
8459              Statements => Make_Deep_Record_Body (Finalize_Case, Typ, True)));
8460   end Make_Local_Deep_Finalize;
8461
8462   ------------------------------------
8463   -- Make_Set_Finalize_Address_Call --
8464   ------------------------------------
8465
8466   function Make_Set_Finalize_Address_Call
8467     (Loc     : Source_Ptr;
8468      Ptr_Typ : Entity_Id) return Node_Id
8469   is
8470      --  It is possible for Ptr_Typ to be a partial view, if the access type
8471      --  is a full view declared in the private part of a nested package, and
8472      --  the finalization actions take place when completing analysis of the
8473      --  enclosing unit. For this reason use Underlying_Type twice below.
8474
8475      Desig_Typ : constant Entity_Id :=
8476                    Available_View
8477                      (Designated_Type (Underlying_Type (Ptr_Typ)));
8478      Fin_Addr  : constant Entity_Id := Finalize_Address (Desig_Typ);
8479      Fin_Mas   : constant Entity_Id :=
8480                    Finalization_Master (Underlying_Type (Ptr_Typ));
8481
8482   begin
8483      --  Both the finalization master and primitive Finalize_Address must be
8484      --  available.
8485
8486      pragma Assert (Present (Fin_Addr) and Present (Fin_Mas));
8487
8488      --  Generate:
8489      --    Set_Finalize_Address
8490      --      (<Ptr_Typ>FM, <Desig_Typ>FD'Unrestricted_Access);
8491
8492      return
8493        Make_Procedure_Call_Statement (Loc,
8494          Name                   =>
8495            New_Occurrence_Of (RTE (RE_Set_Finalize_Address), Loc),
8496          Parameter_Associations => New_List (
8497            New_Occurrence_Of (Fin_Mas, Loc),
8498
8499            Make_Attribute_Reference (Loc,
8500              Prefix         => New_Occurrence_Of (Fin_Addr, Loc),
8501              Attribute_Name => Name_Unrestricted_Access)));
8502   end Make_Set_Finalize_Address_Call;
8503
8504   --------------------------
8505   -- Make_Transient_Block --
8506   --------------------------
8507
8508   function Make_Transient_Block
8509     (Loc    : Source_Ptr;
8510      Action : Node_Id;
8511      Par    : Node_Id) return Node_Id
8512   is
8513      function Manages_Sec_Stack (Id : Entity_Id) return Boolean;
8514      --  Determine whether scoping entity Id manages the secondary stack
8515
8516      -----------------------
8517      -- Manages_Sec_Stack --
8518      -----------------------
8519
8520      function Manages_Sec_Stack (Id : Entity_Id) return Boolean is
8521      begin
8522         case Ekind (Id) is
8523
8524            --  An exception handler with a choice parameter utilizes a dummy
8525            --  block to provide a declarative region. Such a block should not
8526            --  be considered because it never manifests in the tree and can
8527            --  never release the secondary stack.
8528
8529            when E_Block =>
8530               return
8531                 Uses_Sec_Stack (Id) and then not Is_Exception_Handler (Id);
8532
8533            when E_Entry
8534               | E_Entry_Family
8535               | E_Function
8536               | E_Procedure
8537            =>
8538               return Uses_Sec_Stack (Id);
8539
8540            when others =>
8541               return False;
8542         end case;
8543      end Manages_Sec_Stack;
8544
8545      --  Local variables
8546
8547      Decls    : constant List_Id   := New_List;
8548      Instrs   : constant List_Id   := New_List (Action);
8549      Trans_Id : constant Entity_Id := Current_Scope;
8550
8551      Block  : Node_Id;
8552      Insert : Node_Id;
8553      Scop   : Entity_Id;
8554
8555   --  Start of processing for Make_Transient_Block
8556
8557   begin
8558      --  Even though the transient block is tasked with managing the secondary
8559      --  stack, the block may forgo this functionality depending on how the
8560      --  secondary stack is managed by enclosing scopes.
8561
8562      if Manages_Sec_Stack (Trans_Id) then
8563
8564         --  Determine whether an enclosing scope already manages the secondary
8565         --  stack.
8566
8567         Scop := Scope (Trans_Id);
8568         while Present (Scop) loop
8569
8570            --  It should not be possible to reach Standard without hitting one
8571            --  of the other cases first unless Standard was manually pushed.
8572
8573            if Scop = Standard_Standard then
8574               exit;
8575
8576            --  The transient block is within a function which returns on the
8577            --  secondary stack. Take a conservative approach and assume that
8578            --  the value on the secondary stack is part of the result. Note
8579            --  that it is not possible to detect this dependency without flow
8580            --  analysis which the compiler does not have. Letting the object
8581            --  live longer than the transient block will not leak any memory
8582            --  because the caller will reclaim the total storage used by the
8583            --  function.
8584
8585            elsif Ekind (Scop) = E_Function
8586              and then Sec_Stack_Needed_For_Return (Scop)
8587            then
8588               Set_Uses_Sec_Stack (Trans_Id, False);
8589               exit;
8590
8591            --  The transient block must manage the secondary stack when the
8592            --  block appears within a loop in order to reclaim the memory at
8593            --  each iteration.
8594
8595            elsif Ekind (Scop) = E_Loop then
8596               exit;
8597
8598            --  The transient block does not need to manage the secondary stack
8599            --  when there is an enclosing construct which already does that.
8600            --  This optimization saves on SS_Mark and SS_Release calls but may
8601            --  allow objects to live a little longer than required.
8602
8603            --  The transient block must manage the secondary stack when switch
8604            --  -gnatd.s (strict management) is in effect.
8605
8606            elsif Manages_Sec_Stack (Scop) and then not Debug_Flag_Dot_S then
8607               Set_Uses_Sec_Stack (Trans_Id, False);
8608               exit;
8609
8610            --  Prevent the search from going too far because transient blocks
8611            --  are bounded by packages and subprogram scopes.
8612
8613            elsif Ekind_In (Scop, E_Entry,
8614                                  E_Entry_Family,
8615                                  E_Function,
8616                                  E_Package,
8617                                  E_Procedure,
8618                                  E_Subprogram_Body)
8619            then
8620               exit;
8621            end if;
8622
8623            Scop := Scope (Scop);
8624         end loop;
8625      end if;
8626
8627      --  Create the transient block. Set the parent now since the block itself
8628      --  is not part of the tree. The current scope is the E_Block entity that
8629      --  has been pushed by Establish_Transient_Scope.
8630
8631      pragma Assert (Ekind (Trans_Id) = E_Block);
8632
8633      Block :=
8634        Make_Block_Statement (Loc,
8635          Identifier                 => New_Occurrence_Of (Trans_Id, Loc),
8636          Declarations               => Decls,
8637          Handled_Statement_Sequence =>
8638            Make_Handled_Sequence_Of_Statements (Loc, Statements => Instrs),
8639          Has_Created_Identifier     => True);
8640      Set_Parent (Block, Par);
8641
8642      --  Insert actions stuck in the transient scopes as well as all freezing
8643      --  nodes needed by those actions. Do not insert cleanup actions here,
8644      --  they will be transferred to the newly created block.
8645
8646      Insert_Actions_In_Scope_Around
8647        (Action, Clean => False, Manage_SS => False);
8648
8649      Insert := Prev (Action);
8650
8651      if Present (Insert) then
8652         Freeze_All (First_Entity (Trans_Id), Insert);
8653      end if;
8654
8655      --  Transfer cleanup actions to the newly created block
8656
8657      declare
8658         Cleanup_Actions : List_Id
8659           renames Scope_Stack.Table (Scope_Stack.Last).
8660                     Actions_To_Be_Wrapped (Cleanup);
8661      begin
8662         Set_Cleanup_Actions (Block, Cleanup_Actions);
8663         Cleanup_Actions := No_List;
8664      end;
8665
8666      --  When the transient scope was established, we pushed the entry for the
8667      --  transient scope onto the scope stack, so that the scope was active
8668      --  for the installation of finalizable entities etc. Now we must remove
8669      --  this entry, since we have constructed a proper block.
8670
8671      Pop_Scope;
8672
8673      return Block;
8674   end Make_Transient_Block;
8675
8676   ------------------------
8677   -- Node_To_Be_Wrapped --
8678   ------------------------
8679
8680   function Node_To_Be_Wrapped return Node_Id is
8681   begin
8682      return Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped;
8683   end Node_To_Be_Wrapped;
8684
8685   ----------------------------
8686   -- Set_Node_To_Be_Wrapped --
8687   ----------------------------
8688
8689   procedure Set_Node_To_Be_Wrapped (N : Node_Id) is
8690   begin
8691      Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped := N;
8692   end Set_Node_To_Be_Wrapped;
8693
8694   ----------------------------
8695   -- Store_Actions_In_Scope --
8696   ----------------------------
8697
8698   procedure Store_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id) is
8699      SE      : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
8700      Actions : List_Id renames SE.Actions_To_Be_Wrapped (AK);
8701
8702   begin
8703      if No (Actions) then
8704         Actions := L;
8705
8706         if Is_List_Member (SE.Node_To_Be_Wrapped) then
8707            Set_Parent (L, Parent (SE.Node_To_Be_Wrapped));
8708         else
8709            Set_Parent (L, SE.Node_To_Be_Wrapped);
8710         end if;
8711
8712         Analyze_List (L);
8713
8714      elsif AK = Before then
8715         Insert_List_After_And_Analyze (Last (Actions), L);
8716
8717      else
8718         Insert_List_Before_And_Analyze (First (Actions), L);
8719      end if;
8720   end Store_Actions_In_Scope;
8721
8722   ----------------------------------
8723   -- Store_After_Actions_In_Scope --
8724   ----------------------------------
8725
8726   procedure Store_After_Actions_In_Scope (L : List_Id) is
8727   begin
8728      Store_Actions_In_Scope (After, L);
8729   end Store_After_Actions_In_Scope;
8730
8731   -----------------------------------
8732   -- Store_Before_Actions_In_Scope --
8733   -----------------------------------
8734
8735   procedure Store_Before_Actions_In_Scope (L : List_Id) is
8736   begin
8737      Store_Actions_In_Scope (Before, L);
8738   end Store_Before_Actions_In_Scope;
8739
8740   -----------------------------------
8741   -- Store_Cleanup_Actions_In_Scope --
8742   -----------------------------------
8743
8744   procedure Store_Cleanup_Actions_In_Scope (L : List_Id) is
8745   begin
8746      Store_Actions_In_Scope (Cleanup, L);
8747   end Store_Cleanup_Actions_In_Scope;
8748
8749   --------------------------------
8750   -- Wrap_Transient_Declaration --
8751   --------------------------------
8752
8753   --  If a transient scope has been established during the processing of the
8754   --  Expression of an Object_Declaration, it is not possible to wrap the
8755   --  declaration into a transient block as usual case, otherwise the object
8756   --  would be itself declared in the wrong scope. Therefore, all entities (if
8757   --  any) defined in the transient block are moved to the proper enclosing
8758   --  scope. Furthermore, if they are controlled variables they are finalized
8759   --  right after the declaration. The finalization list of the transient
8760   --  scope is defined as a renaming of the enclosing one so during their
8761   --  initialization they will be attached to the proper finalization list.
8762   --  For instance, the following declaration :
8763
8764   --        X : Typ := F (G (A), G (B));
8765
8766   --  (where G(A) and G(B) return controlled values, expanded as _v1 and _v2)
8767   --  is expanded into :
8768
8769   --    X : Typ := [ complex Expression-Action ];
8770   --    [Deep_]Finalize (_v1);
8771   --    [Deep_]Finalize (_v2);
8772
8773   procedure Wrap_Transient_Declaration (N : Node_Id) is
8774      Curr_S : Entity_Id;
8775      Encl_S : Entity_Id;
8776
8777   begin
8778      Curr_S := Current_Scope;
8779      Encl_S := Scope (Curr_S);
8780
8781      --  Insert all actions including cleanup generated while analyzing or
8782      --  expanding the transient context back into the tree. Manage the
8783      --  secondary stack when the object declaration appears in a library
8784      --  level package [body].
8785
8786      Insert_Actions_In_Scope_Around
8787        (N         => N,
8788         Clean     => True,
8789         Manage_SS =>
8790           Uses_Sec_Stack (Curr_S)
8791             and then Nkind (N) = N_Object_Declaration
8792             and then Ekind_In (Encl_S, E_Package, E_Package_Body)
8793             and then Is_Library_Level_Entity (Encl_S));
8794      Pop_Scope;
8795
8796      --  Relocate local entities declared within the transient scope to the
8797      --  enclosing scope. This action sets their Is_Public flag accordingly.
8798
8799      Transfer_Entities (Curr_S, Encl_S);
8800
8801      --  Mark the enclosing dynamic scope to ensure that the secondary stack
8802      --  is properly released upon exiting the said scope.
8803
8804      if Uses_Sec_Stack (Curr_S) then
8805         Curr_S := Enclosing_Dynamic_Scope (Curr_S);
8806
8807         --  Do not mark a function that returns on the secondary stack as the
8808         --  reclamation is done by the caller.
8809
8810         if Ekind (Curr_S) = E_Function
8811           and then Requires_Transient_Scope (Etype (Curr_S))
8812         then
8813            null;
8814
8815         --  Otherwise mark the enclosing dynamic scope
8816
8817         else
8818            Set_Uses_Sec_Stack (Curr_S);
8819            Check_Restriction (No_Secondary_Stack, N);
8820         end if;
8821      end if;
8822   end Wrap_Transient_Declaration;
8823
8824   -------------------------------
8825   -- Wrap_Transient_Expression --
8826   -------------------------------
8827
8828   procedure Wrap_Transient_Expression (N : Node_Id) is
8829      Loc  : constant Source_Ptr := Sloc (N);
8830      Expr : Node_Id             := Relocate_Node (N);
8831      Temp : constant Entity_Id  := Make_Temporary (Loc, 'E', N);
8832      Typ  : constant Entity_Id  := Etype (N);
8833
8834   begin
8835      --  Generate:
8836
8837      --    Temp : Typ;
8838      --    declare
8839      --       M : constant Mark_Id := SS_Mark;
8840      --       procedure Finalizer is ...  (See Build_Finalizer)
8841
8842      --    begin
8843      --       Temp := <Expr>;                           --  general case
8844      --       Temp := (if <Expr> then True else False); --  boolean case
8845
8846      --    at end
8847      --       Finalizer;
8848      --    end;
8849
8850      --  A special case is made for Boolean expressions so that the back end
8851      --  knows to generate a conditional branch instruction, if running with
8852      --  -fpreserve-control-flow. This ensures that a control-flow change
8853      --  signaling the decision outcome occurs before the cleanup actions.
8854
8855      if Opt.Suppress_Control_Flow_Optimizations
8856        and then Is_Boolean_Type (Typ)
8857      then
8858         Expr :=
8859           Make_If_Expression (Loc,
8860             Expressions => New_List (
8861               Expr,
8862               New_Occurrence_Of (Standard_True, Loc),
8863               New_Occurrence_Of (Standard_False, Loc)));
8864      end if;
8865
8866      Insert_Actions (N, New_List (
8867        Make_Object_Declaration (Loc,
8868          Defining_Identifier => Temp,
8869          Object_Definition   => New_Occurrence_Of (Typ, Loc)),
8870
8871        Make_Transient_Block (Loc,
8872          Action =>
8873            Make_Assignment_Statement (Loc,
8874              Name       => New_Occurrence_Of (Temp, Loc),
8875              Expression => Expr),
8876          Par    => Parent (N))));
8877
8878      Rewrite (N, New_Occurrence_Of (Temp, Loc));
8879      Analyze_And_Resolve (N, Typ);
8880   end Wrap_Transient_Expression;
8881
8882   ------------------------------
8883   -- Wrap_Transient_Statement --
8884   ------------------------------
8885
8886   procedure Wrap_Transient_Statement (N : Node_Id) is
8887      Loc      : constant Source_Ptr := Sloc (N);
8888      New_Stmt : constant Node_Id    := Relocate_Node (N);
8889
8890   begin
8891      --  Generate:
8892      --    declare
8893      --       M : constant Mark_Id := SS_Mark;
8894      --       procedure Finalizer is ...  (See Build_Finalizer)
8895      --
8896      --    begin
8897      --       <New_Stmt>;
8898      --
8899      --    at end
8900      --       Finalizer;
8901      --    end;
8902
8903      Rewrite (N,
8904        Make_Transient_Block (Loc,
8905          Action => New_Stmt,
8906          Par    => Parent (N)));
8907
8908      --  With the scope stack back to normal, we can call analyze on the
8909      --  resulting block. At this point, the transient scope is being
8910      --  treated like a perfectly normal scope, so there is nothing
8911      --  special about it.
8912
8913      --  Note: Wrap_Transient_Statement is called with the node already
8914      --  analyzed (i.e. Analyzed (N) is True). This is important, since
8915      --  otherwise we would get a recursive processing of the node when
8916      --  we do this Analyze call.
8917
8918      Analyze (N);
8919   end Wrap_Transient_Statement;
8920
8921end Exp_Ch7;
8922