home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / exp_ch3.adb < prev    next >
Text File  |  1996-09-28  |  110KB  |  3,070 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                              E X P _ C H 3                               --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.243 $                            --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
  22. --                                                                          --
  23. ------------------------------------------------------------------------------
  24.  
  25. with Atree;    use Atree;
  26. with Einfo;    use Einfo;
  27. with Elists;   use Elists;
  28. with Exp_Ch4;  use Exp_Ch4;
  29. with Exp_Ch7;  use Exp_Ch7;
  30. with Exp_Ch9;  use Exp_Ch9;
  31. with Exp_Disp; use Exp_Disp;
  32. with Exp_Pakd; use Exp_Pakd;
  33. with Exp_TSS;  use Exp_TSS;
  34. with Exp_Util; use Exp_Util;
  35. with Expander; use Expander;
  36. with Freeze;   use Freeze;
  37. with Nlists;   use Nlists;
  38. with Nmake;    use Nmake;
  39. with Output;   use Output;
  40. with Rtsfind;  use Rtsfind;
  41. with Sem;      use Sem;
  42. with Sem_Ch8;  use Sem_Ch8;
  43. with Sem_Ch13; use Sem_Ch13;
  44. with Sem_Eval; use Sem_Eval;
  45. with Sem_Res;  use Sem_Res;
  46. with Sem_Util; use Sem_Util;
  47. with Sinfo;    use Sinfo;
  48. with Stand;    use Stand;
  49. with Snames;   use Snames;
  50. with Tbuild;   use Tbuild;
  51. with Ttypes;   use Ttypes;
  52. with Uintp;    use Uintp;
  53. with Urealp;   use Urealp;
  54.  
  55. package body Exp_Ch3 is
  56.  
  57.    ------------------------
  58.    --  Local Subprograms --
  59.    ------------------------
  60.  
  61.    procedure Build_Array_Init_Proc (A_Type : Entity_Id);
  62.    --  Build initialization procedure for given array type
  63.  
  64.    function Build_Discriminant_Formals
  65.      (Rec_Id : Entity_Id;
  66.       Use_Dl : Boolean)
  67.       return   List_Id;
  68.    --  This function uses the discriminants of a type to build a list of
  69.    --  formal parameters, used in the following function. If the flag Use_D1
  70.    --  is set, the list is built using the already defined discriminals
  71.    --  of the type. Otherwise new identifiers are created, with the source
  72.    --  names of the discriminants.
  73.  
  74.    procedure Build_Master_Renaming (N : Node_Id; T : Entity_Id);
  75.    --  If the designated type of an access type is a task type or contains
  76.    --  tasks, we make sure that a _Master variable is declared in the current
  77.    --  scope, and then declare a renaming for it:
  78.    --
  79.    --    atypeM : Master_Id renames _Master;
  80.    --
  81.    --  where atyp is the name of the access type. This declaration is
  82.    --  used when an allocator for the access type is expanded.
  83.  
  84.    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id);
  85.    --  Build record initialization procedure. params ???
  86.  
  87.    procedure Build_Variant_Record_Equality (Typ  : Entity_Id);
  88.    --  Create An Equality function for the non-tagged variant record 'Typ'
  89.    --  and attach it to the TSS list
  90.  
  91.    procedure Expand_Tagged_Root (T : Entity_Id);
  92.    --  Add a field _Tag at the beginning of the record. This field carries
  93.    --  the value of the access to the Dispatch table. This procedure is only
  94.    --  called on root (non CPP_Class) types, the _Tag field being inherited
  95.    --  by the descendants.
  96.  
  97.    procedure Expand_Record_Controller (T : Entity_Id);
  98.    --  T must be a record type that Has_Controlled. Add a field _C of type
  99.    --  Record_Controller or Limited_Record_Controller in the record T.
  100.  
  101.    procedure Freeze_Array_Type (N : Node_Id);
  102.    --  Freeze an array type. Deals with building the initialization procedure,
  103.    --  creating the packed array type for a packed array and also with the
  104.    --  creation of the controlling procedures for the controlled case.
  105.  
  106.    procedure Freeze_Enumeration_Type (N : Node_Id);
  107.    --  Freeze enumeration type with non-standard representation. Builds the
  108.    --  array and function needed to convert between enumeration pos and
  109.    --  enumeration representation values. N is the N_Freeze_Entity node.
  110.  
  111.    procedure Freeze_Fixed_Point_Type (N : Node_Id);
  112.    --  Freeze fixed point type. N is the N_Freeze_Entity node.
  113.  
  114.    function Init_Formals (Typ : Entity_Id) return List_Id;
  115.    --  This function builds the list of formals for an initialization routine.
  116.    --  The first formal is always _Init with the given type. For task value
  117.    --  record types and types containing tasks, two additional formals are
  118.    --  added:
  119.    --
  120.    --    _Master : Master_Id
  121.    --    _Chain  : in out Activation_Chain
  122.    --
  123.    --  The caller must append additional entries for discriminants if required.
  124.  
  125.    function In_Runtime (E : Entity_Id) return Boolean;
  126.    --  Check if E is defined in the RTL (in a child of Ada or System).
  127.    --  Used to avoid to bring in the overhead of _Input, _Output for tagged
  128.    --  types
  129.  
  130.    function Make_Eq_Case (Loc  : Source_Ptr; CL : Node_Id) return List_Id;
  131.    --  Building block for variant record equality. Defined to share the
  132.    --  code between the tagged and non-tagged case. Given a Component_List
  133.    --  node CL, it generates a 'if' followed by a 'case' statement that
  134.    --  compares all components of 'X' and 'Y' (that are supposed to be
  135.    --  formals at some upper level)
  136.  
  137.    function Make_Eq_If (Loc  : Source_Ptr; L : List_Id) return Node_Id;
  138.    --  Building block for variant record equality. Defined to share the
  139.    --  code between the tagged and non-tagged case. Given the list of
  140.    --  components (or discriminants) L, it generates a 'if' statement that
  141.    --  compares all components of 'X' and 'Y' (that are supposed to be
  142.    --  formals at some upper level)
  143.  
  144.    function Predef_Spec
  145.      (Loc      : Source_Ptr;
  146.       Tag_Typ  : Entity_Id;
  147.       Name     : Name_Id;
  148.       Profile  : List_Id;
  149.       Ret_Type : Entity_Id := Empty;
  150.       For_Body : Boolean   := False)
  151.       return Node_Id;
  152.    --  Shortcut function that generate the appropriate expansion for a
  153.    --  predefined primitive specified by its name, profile and return
  154.    --  type (Empty means this is a procedure). For_Body controls if
  155.    --  a specification for a declaration or a body is generated.
  156.  
  157.    function Predef_Stream_IO_Spec
  158.      (Loc      : Source_Ptr;
  159.       Tag_Typ  : Entity_Id;
  160.       Name     : Name_Id;
  161.       For_Body : Boolean := False)
  162.       return Node_Id;
  163.    --  Specialized version of Predef_Spec that apply to _read, _write,
  164.    --  _input and _output which have the same kind of spec
  165.  
  166.    function Predef_Deep_Spec
  167.      (Loc      : Source_Ptr;
  168.       Tag_Typ  : Entity_Id;
  169.       Name     : Name_Id;
  170.       For_Body : Boolean := False)
  171.       return Node_Id;
  172.    --  Specialized version of Predef_Spec that apply to _deep_adjust and
  173.    --  _deep_finalize
  174.  
  175.    function Predefined_Primitive_Bodies (Tag_Typ : Entity_Id) return List_Id;
  176.    --  Create the bodies of the predefined primitives that are described in
  177.    --  Predefined_Primitive_Specs
  178.  
  179.    function Predefined_Primitive_Specs (Tag_Typ : Entity_Id) return List_Id;
  180.    --  Create a list with the specs of the predefined primitive operations.
  181.    --  This list contains _Size, _Read, _Write, _Input and _Output for
  182.    --  every tagged types, plus _equality, _assign, _deep_finalize and
  183.    --  _deep_adjust for non limited tagged types.  _Size, _Read, _Write,
  184.    --  _Input and _Output implement the corresponding attributes that need
  185.    --  to be dispatching when their arguments are classwide. _equality and
  186.    --  _assign, implement equality and assignment that also must be
  187.    --  dispatching. _Deep_Finalize and _Deep_Adjust are empty procedures
  188.    --  unless the type contains some controlled components that require
  189.    --  finalization actions
  190.  
  191.    ----------------------------
  192.    --  Build_Array_Init_Proc --
  193.    ----------------------------
  194.  
  195.    procedure Build_Array_Init_Proc (A_Type : Entity_Id) is
  196.       Comp_Type  : constant Entity_Id  := Component_Type (A_Type);
  197.       Loc        : constant Source_Ptr := Sloc (A_Type);
  198.       Index_List : List_Id;
  199.       Proc_Id    : Entity_Id;
  200.       Proc_Body  : Node_Id;
  201.  
  202.       function Init_Component return List_Id;
  203.       --  Create one statement to initialize one array component, designated
  204.       --  by a full set of indices.
  205.  
  206.       function Init_One_Dimension (N : Int) return List_Id;
  207.       --  Create loop to initialize one dimension of the array. The single
  208.       --  statement in the body of the loop initializes the inner dimensions if
  209.       --  any,or else a single component.
  210.  
  211.       --------------------
  212.       -- Init_Component --
  213.       --------------------
  214.  
  215.       function Init_Component return List_Id is
  216.          Comp : Node_Id;
  217.  
  218.       begin
  219.          Comp :=
  220.            Make_Indexed_Component (Loc,
  221.              Prefix => Make_Identifier (Loc, Name_uInit),
  222.              Expressions => Index_List);
  223.  
  224.          if Is_Access_Type (Comp_Type) then
  225.             return New_List (
  226.               Make_Assignment_Statement (Loc,
  227.                 Name => Comp,
  228.                 Expression => Make_Null (Loc)));
  229.  
  230.          elsif Is_Private_Type (Comp_Type)
  231.            and then Is_Access_Type (Underlying_Type (Comp_Type))
  232.          then
  233.             return New_List (
  234.               Make_Assignment_Statement (Loc,
  235.                 Name =>
  236.                   Make_Unchecked_Type_Conversion (Loc,
  237.                     Subtype_Mark =>
  238.                       New_Reference_To (
  239.                         Underlying_Type (Comp_Type), Loc),
  240.                     Expression => Comp),
  241.                 Expression => Make_Null (Loc)));
  242.  
  243.          else
  244.             return Build_Initialization_Call (Loc, Comp, Comp_Type, True);
  245.          end if;
  246.       end Init_Component;
  247.  
  248.       ------------------------
  249.       -- Init_One_Dimension --
  250.       ------------------------
  251.  
  252.       function Init_One_Dimension (N : Int) return List_Id is
  253.          Index : Entity_Id;
  254.  
  255.       begin
  256.          if N > Number_Dimensions (A_Type) then
  257.             return Init_Component;
  258.  
  259.          else
  260.             Index :=
  261.               Make_Defining_Identifier (Loc, New_External_Name ('X', N));
  262.  
  263.             Append (New_Reference_To (Index, Loc), Index_List);
  264.  
  265.             return New_List (
  266.               Make_Loop_Statement (Loc,
  267.                 Identifier => Empty,
  268.                 Iteration_Scheme =>
  269.                   Make_Iteration_Scheme (Loc,
  270.                     Loop_Parameter_Specification =>
  271.                       Make_Loop_Parameter_Specification (Loc,
  272.                         Defining_Identifier => Index,
  273.                         Discrete_Subtype_Definition =>
  274.                           Make_Attribute_Reference (Loc,
  275.                             Prefix => Make_Identifier (Loc, Name_uInit),
  276.                             Attribute_Name  => Name_Range,
  277.                             Expressions => New_List (
  278.                               Make_Integer_Literal (Loc, UI_From_Int (N)))))),
  279.                 Statements => Init_One_Dimension (N + 1)));
  280.          end if;
  281.       end Init_One_Dimension;
  282.  
  283.    --  Start of processing for Build_Array_Init_Proc
  284.  
  285.    begin
  286.       Index_List := New_List;
  287.  
  288.       if Present (Base_Init_Proc (Comp_Type))
  289.         or else Is_Access_Type (Comp_Type)
  290.         or else (Is_Private_Type (Comp_Type)
  291.                   and then Is_Access_Type (Underlying_Type (Comp_Type)))
  292.         or else Has_Tasks (Comp_Type)
  293.       then
  294.          Proc_Id :=
  295.            Make_Defining_Identifier (Loc, Name_uInit_Proc);
  296.  
  297.          Proc_Body :=
  298.            Make_Subprogram_Body (Loc,
  299.              Specification =>
  300.                Make_Procedure_Specification (Loc,
  301.                  Defining_Unit_Name => Proc_Id,
  302.                  Parameter_Specifications => Init_Formals (A_Type)),
  303.              Declarations => New_List,
  304.              Handled_Statement_Sequence =>
  305.                Make_Handled_Sequence_Of_Statements (Loc,
  306.                  Statements => Init_One_Dimension (1)));
  307.  
  308.          Set_Init_Proc (A_Type, Proc_Id);
  309.  
  310.          Set_Ekind          (Proc_Id, E_Procedure);
  311.          Set_Is_Public      (Proc_Id, Is_Public (A_Type));
  312.          Set_Is_Inlined     (Proc_Id);
  313.          Set_Is_Internal    (Proc_Id);
  314.          Set_Has_Completion (Proc_Id);
  315.       end if;
  316.  
  317.    end Build_Array_Init_Proc;
  318.  
  319.    ------------------------------------
  320.    -- Build_Variant_Record_Equality --
  321.    ------------------------------------
  322.  
  323.    --  Generates:
  324.    --
  325.    --    function _Equality (X, Y : T) return Boolean is
  326.    --    begin
  327.    --
  328.    --       --  Compare discriminants
  329.    --
  330.    --       if False or else X.D1 /= Y.D1 or else X.D2 /= Y.D2 then
  331.    --          return False;
  332.    --       end if;
  333.    --
  334.    --       --  Compare components
  335.    --
  336.    --       if False or else X.C1 /= Y.C1 or else X.C2 /= Y.C2 then
  337.    --          return False;
  338.    --       end if;
  339.    --
  340.    --       --  Compare variant part
  341.    --
  342.    --       case X.D1 is
  343.    --          when V1 =>
  344.    --             if False or else X.C2 /= Y.C2 or else X.C3 /= Y.C3 then
  345.    --                return False;
  346.    --             end if;
  347.    --          ...
  348.    --          when Vn =>
  349.    --             if False or else X.Cn /= Y.Cn then
  350.    --                return False;
  351.    --             end if;
  352.    --       end case;
  353.    --       return True;
  354.    --    end _Equality;
  355.  
  356.    procedure Build_Variant_Record_Equality (Typ  : Entity_Id) is
  357.       Loc   : constant Source_Ptr := Sloc (Typ);
  358.       F     : constant Entity_Id := Make_Defining_Identifier (Loc,
  359.                                                               Name_uEquality);
  360.       X     : constant Entity_Id := Make_Defining_Identifier (Loc, Name_X);
  361.       Y     : constant Entity_Id := Make_Defining_Identifier (Loc, Name_Y);
  362.       Def   : constant Node_Id := Parent (Typ);
  363.       Comps : constant Node_Id := Component_List (Type_Definition (Def));
  364.  
  365.       Function_Body : Node_Id;
  366.       Stmts         : List_Id := New_List;
  367.  
  368.    begin
  369.       Function_Body :=
  370.         Make_Subprogram_Body (Loc,
  371.           Specification =>
  372.             Make_Function_Specification (Loc,
  373.               Defining_Unit_Name       => F,
  374.               Parameter_Specifications => New_List (
  375.                 Make_Parameter_Specification (Loc,
  376.                   Defining_Identifier => X,
  377.                   Parameter_Type      => New_Reference_To (Typ, Loc)),
  378.  
  379.                 Make_Parameter_Specification (Loc,
  380.                   Defining_Identifier => Y,
  381.                   Parameter_Type      => New_Reference_To (Typ, Loc))),
  382.  
  383.               Subtype_Mark => New_Reference_To (Standard_Boolean, Loc)),
  384.  
  385.           Declarations               => New_List,
  386.           Handled_Statement_Sequence =>
  387.             Make_Handled_Sequence_Of_Statements (Loc,
  388.               Statements => Stmts));
  389.  
  390.       Append_To (Stmts, Make_Eq_If (Loc, Discriminant_Specifications (Def)));
  391.       Append_List_To (Stmts, Make_Eq_Case (Loc, Comps));
  392.       Append_To (Stmts,
  393.         Make_Return_Statement (Loc, New_Reference_To (Standard_True, Loc)));
  394.  
  395.       Set_TSS (Typ, F);
  396.    end Build_Variant_Record_Equality;
  397.  
  398.    ------------------
  399.    -- Make_Eq_Case --
  400.    ------------------
  401.  
  402.    --  <Make_Eq_if shared components>
  403.    --  case X.D1 is
  404.    --     when V1 => <Make_Eq_Case> on subcomponents
  405.    --     ...
  406.    --     when Vn => <Make_Eq_Case> on subcomponents
  407.    --  end case;
  408.  
  409.    function Make_Eq_Case (Loc  : Source_Ptr; CL : Node_Id) return List_Id is
  410.       Variant  : Node_Id;
  411.       Alt_List : List_Id;
  412.       Result   : List_Id := New_List;
  413.  
  414.    begin
  415.       Append_To (Result, Make_Eq_If (Loc, Component_Items (CL)));
  416.  
  417.       if No (Variant_Part (CL)) then
  418.          return Result;
  419.       end if;
  420.  
  421.       Variant := First (Variants (Variant_Part (CL)));
  422.  
  423.       if No (Variant) then
  424.          return Result;
  425.       end if;
  426.  
  427.       Alt_List := New_List;
  428.  
  429.       while Present (Variant) loop
  430.          Append_To (Alt_List,
  431.            Make_Case_Statement_Alternative (Loc,
  432.              Discrete_Choices => New_List_Copy (Discrete_Choices (Variant)),
  433.              Statements => Make_Eq_Case (Loc, Component_List (Variant))));
  434.  
  435.          Variant := Next (Variant);
  436.       end loop;
  437.  
  438.       Append_To (Result,
  439.         Make_Case_Statement (Loc,
  440.           Expression =>
  441.             Make_Selected_Component (Loc,
  442.               Prefix => Make_Identifier (Loc, Name_X),
  443.               Selector_Name => New_Copy (Name (Variant_Part (CL)))),
  444.           Alternatives => Alt_List));
  445.  
  446.       return Result;
  447.    end Make_Eq_Case;
  448.  
  449.    ----------------
  450.    -- Make_Eq_If --
  451.    ----------------
  452.  
  453.    --  if False
  454.    --    or else X.C1 /= Y.C1
  455.    --    or else X.C2 /= Y.C2
  456.    --    ...
  457.    --  then
  458.    --     return False;
  459.    --  end if;
  460.  
  461.    function Make_Eq_If (Loc  : Source_Ptr; L : List_Id) return Node_Id is
  462.       C     : Node_Id;
  463.       Field : Entity_Id;
  464.       Expr  : Node_Id;
  465.  
  466.    begin
  467.       if No (L) then
  468.          return Make_Null_Statement (Loc);
  469.  
  470.       else
  471.          C := First (L);
  472.  
  473.          if No (C) then
  474.             return Make_Null_Statement (Loc);
  475.          end if;
  476.       end if;
  477.  
  478.       Expr := New_Reference_To (Standard_False, Loc);
  479.  
  480.       while Present (C) loop
  481.  
  482.          if Nkind (C) /= N_Pragma then
  483.             Field := Defining_Identifier (C);
  484.  
  485.             --  Note that in the following, we use Make_Identifier for the
  486.             --  component names. Use of New_Reference_To to identify the
  487.             --  components would be incorrect because the wrong entities
  488.             --  for discriminants could be picked up in the private type case.
  489.  
  490.             Expr :=
  491.               Make_Or_Else (Loc,
  492.                 Left_Opnd  => Expr,
  493.                 Right_Opnd =>
  494.                   Make_Op_Ne (Loc,
  495.                     Left_Opnd =>
  496.                       Make_Selected_Component (Loc,
  497.                         Prefix => Make_Identifier (Loc, Name_X),
  498.                         Selector_Name => Make_Identifier (Loc, Chars (Field))),
  499.  
  500.                     Right_Opnd =>
  501.                       Make_Selected_Component (Loc,
  502.                         Prefix => Make_Identifier (Loc, Name_Y),
  503.                         Selector_Name =>
  504.                           Make_Identifier (Loc, Chars (Field)))));
  505.          end if;
  506.  
  507.          C := Next (C);
  508.       end loop;
  509.  
  510.       return
  511.         Make_If_Statement (Loc,
  512.           Condition       => Expr,
  513.           Then_Statements => New_List (
  514.             Make_Return_Statement (Loc,
  515.               Expression => New_Reference_To (Standard_False, Loc))));
  516.  
  517.    end Make_Eq_If;
  518.  
  519.    --------------------------------
  520.    -- Build_Discriminant_Formals --
  521.    --------------------------------
  522.  
  523.    function Build_Discriminant_Formals
  524.      (Rec_Id : Entity_Id;
  525.       Use_Dl : Boolean)
  526.       return   List_Id
  527.    is
  528.       D               : Entity_Id;
  529.       Formal          : Entity_Id;
  530.       Loc             : constant Source_Ptr := Sloc (Rec_Id);
  531.       Param_Spec_Node : Node_Id;
  532.       Parameter_List  : List_Id := New_List;
  533.  
  534.    begin
  535.       if Has_Discriminants (Rec_Id) then
  536.          D := First_Discriminant (Rec_Id);
  537.  
  538.          while Present (D) loop
  539.             if Use_Dl then
  540.                Formal := Discriminal (D);
  541.             else
  542.                Formal := Make_Defining_Identifier (Loc,  Chars (D));
  543.             end if;
  544.  
  545.             Param_Spec_Node :=
  546.               Make_Parameter_Specification (Loc,
  547.                   Defining_Identifier => Formal,
  548.                 Parameter_Type =>
  549.                   New_Reference_To (Etype (D), Loc));
  550.             Append (Param_Spec_Node, Parameter_List);
  551.             D := Next_Discriminant (D);
  552.          end loop;
  553.       end if;
  554.  
  555.       return Parameter_List;
  556.    end Build_Discriminant_Formals;
  557.  
  558.    --------------------------------
  559.    -- Build_Discr_Checking_Funcs --
  560.    --------------------------------
  561.  
  562.    procedure Build_Discr_Checking_Funcs (N : Node_Id) is
  563.       Rec_Id            : Entity_Id;
  564.       Loc               : Source_Ptr;
  565.       Enclosing_Func_Id : Entity_Id;
  566.       Insertion_Node    : Node_Id := N;
  567.       Sequence          : Nat     := 1;
  568.       Type_Def          : Node_Id;
  569.       V                 : Node_Id;
  570.  
  571.       function Build_Case_Statement
  572.         (Case_Id : Entity_Id;
  573.          Variant : Node_Id)
  574.          return    Node_Id;
  575.       --  TBSL need documentation for this spec
  576.  
  577.       function Build_Function
  578.         (Case_Id : Entity_Id;
  579.          Variant : Node_Id)
  580.          return    Entity_Id;
  581.       --  Build the discriminant checking function for a given variant
  582.  
  583.       procedure Build_Functions (Variant_Part_Node : Node_Id);
  584.       --  Builds the discriminant checking function for each variant of the
  585.       --  given variant part of the record type.
  586.  
  587.       function Build_Case_Statement
  588.         (Case_Id : Entity_Id;
  589.          Variant : Node_Id)
  590.          return    Node_Id
  591.       is
  592.          Actuals_List   : List_Id;
  593.          Alt_List       : List_Id := New_List;
  594.          Case_Node      : Node_Id;
  595.          Case_Alt_Node  : Node_Id;
  596.          Choice         : Node_Id;
  597.          Choice_List    : List_Id;
  598.          D              : Entity_Id;
  599.          Return_Node    : Node_Id;
  600.  
  601.       begin
  602.          --  Build a case statement containing only two alternatives. The
  603.          --  first alternative corresponds exactly to the discrete choices
  604.          --  given on the variant with contains the components that we are
  605.          --  generating the checks for. If the discriminant is one of these
  606.          --  return False. The other alternative consists of the choice
  607.          --  "Others" and will return True indicating the discriminant did
  608.          --  not match.
  609.  
  610.          Case_Node := New_Node (N_Case_Statement, Loc);
  611.  
  612.          --  Replace the discriminant which controls the variant, with the
  613.          --  name of the formal of the checking function.
  614.  
  615.          Set_Expression (Case_Node,
  616.               Make_Identifier (Loc, Chars (Case_Id)));
  617.  
  618.          Choice := First (Discrete_Choices (Variant));
  619.  
  620.          if Nkind (Choice) = N_Others_Choice then
  621.             Choice_List := New_List_Copy (Others_Discrete_Choices (Choice));
  622.          else
  623.             Choice_List := New_List_Copy (Discrete_Choices (Variant));
  624.          end if;
  625.  
  626.          if not Is_Empty_List (Choice_List) then
  627.             Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
  628.             Set_Discrete_Choices (Case_Alt_Node, Choice_List);
  629.  
  630.             --  In case this is a nested variant, we need to return the result
  631.             --  of the discriminant checking function for the immediately
  632.             --  enclosing variant.
  633.  
  634.             if Present (Enclosing_Func_Id) then
  635.                Actuals_List := New_List;
  636.  
  637.                D := First_Discriminant (Rec_Id);
  638.                while Present (D) loop
  639.                   Append (Make_Identifier (Loc, Chars (D)), Actuals_List);
  640.                   D := Next_Discriminant (D);
  641.                end loop;
  642.  
  643.                Return_Node :=
  644.                  Make_Return_Statement (Loc,
  645.                    Expression =>
  646.                      Make_Function_Call (Loc,
  647.                        Name =>
  648.                          New_Reference_To (Enclosing_Func_Id,  Loc),
  649.                        Parameter_Associations =>
  650.                          Actuals_List));
  651.  
  652.             else
  653.                Return_Node :=
  654.                  Make_Return_Statement (Loc,
  655.                    Expression =>
  656.                      New_Reference_To (Standard_False, Loc));
  657.             end if;
  658.  
  659.             Set_Statements (Case_Alt_Node, New_List (Return_Node));
  660.             Append (Case_Alt_Node, Alt_List);
  661.          end if;
  662.  
  663.          Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
  664.          Choice_List := New_List (New_Node (N_Others_Choice, Loc));
  665.          Set_Discrete_Choices (Case_Alt_Node, Choice_List);
  666.  
  667.          Return_Node :=
  668.            Make_Return_Statement (Loc,
  669.              Expression =>
  670.                New_Reference_To (Standard_True, Loc));
  671.  
  672.          Set_Statements (Case_Alt_Node, New_List (Return_Node));
  673.          Append (Case_Alt_Node, Alt_List);
  674.  
  675.          Set_Alternatives (Case_Node, Alt_List);
  676.          return Case_Node;
  677.       end Build_Case_Statement;
  678.  
  679.       function Build_Function
  680.         (Case_Id : Entity_Id;
  681.          Variant : Node_Id)
  682.          return    Entity_Id
  683.       is
  684.          Body_Node           : Node_Id;
  685.          Func_Id             : Entity_Id;
  686.          Parameter_List      : List_Id;
  687.          Spec_Node           : Node_Id;
  688.  
  689.       begin
  690.          Body_Node := New_Node (N_Subprogram_Body, Loc);
  691.          Sequence := Sequence + 1;
  692.  
  693.          Func_Id :=
  694.            Make_Defining_Identifier (Loc,
  695.              Chars => New_External_Name (Chars (Rec_Id), 'D', Sequence));
  696.  
  697.          Spec_Node := New_Node (N_Function_Specification, Loc);
  698.          Set_Defining_Unit_Name (Spec_Node, Func_Id);
  699.  
  700.          Parameter_List := Build_Discriminant_Formals (Rec_Id, False);
  701.  
  702.          Set_Parameter_Specifications (Spec_Node, Parameter_List);
  703.          Set_Subtype_Mark (Spec_Node,
  704.                            New_Reference_To (Standard_Boolean,  Loc));
  705.          Set_Specification (Body_Node, Spec_Node);
  706.          Set_Declarations (Body_Node, New_List);
  707.  
  708.          Set_Handled_Statement_Sequence (Body_Node,
  709.            Make_Handled_Sequence_Of_Statements (Loc,
  710.              Statements => New_List (
  711.                Build_Case_Statement (Case_Id, Variant))));
  712.  
  713.          Set_Ekind       (Func_Id, E_Function);
  714.          Set_Is_Inlined  (Func_Id);
  715.          Set_Is_Pure     (Func_Id);
  716.          Set_Is_Public   (Func_Id, Is_Public (Rec_Id));
  717.          Set_Is_Internal (Func_Id);
  718.  
  719.          Insert_After (Insertion_Node, Body_Node);
  720.          Insertion_Node := Body_Node;
  721.          Analyze (Body_Node);
  722.          return Func_Id;
  723.       end Build_Function;
  724.  
  725.       procedure Build_Functions (Variant_Part_Node : Node_Id) is
  726.          Component_List_Node : Node_Id;
  727.          Decl                : Entity_Id;
  728.          Discr_Name          : Entity_Id;
  729.          Func_Id             : Entity_Id;
  730.          Variant             : Node_Id;
  731.          Saved_Enclosing_Func_Id : Entity_Id;
  732.  
  733.       begin
  734.          --  Build the discriminant checking function for each variant, label
  735.          --  all components of that variant with the function's name.
  736.  
  737.          Discr_Name := Entity (Name (Variant_Part_Node));
  738.          Variant := First (Variants (Variant_Part_Node));
  739.  
  740.          while Present (Variant) loop
  741.             Func_Id := Build_Function (Discr_Name, Variant);
  742.             Component_List_Node := Component_List (Variant);
  743.  
  744.             if not Null_Present (Component_List_Node) then
  745.                Decl := First (Component_Items (Component_List_Node));
  746.                while Present (Decl) loop
  747.                   if Nkind (Decl) /= N_Pragma then
  748.                      Set_Discriminant_Checking_Func
  749.                        (Defining_Identifier (Decl), Func_Id);
  750.                   end if;
  751.  
  752.                   Decl := Next (Decl);
  753.                end loop;
  754.  
  755.                if Present (Variant_Part (Component_List_Node)) then
  756.                   Saved_Enclosing_Func_Id := Enclosing_Func_Id;
  757.                   Enclosing_Func_Id := Func_Id;
  758.                   Build_Functions (Variant_Part (Component_List_Node));
  759.                   Enclosing_Func_Id := Saved_Enclosing_Func_Id;
  760.                end if;
  761.             end if;
  762.  
  763.             Variant := Next (Variant);
  764.          end loop;
  765.       end Build_Functions;
  766.  
  767.    --  Start of processing for Build_Discr_Checking_Funcs
  768.  
  769.    begin
  770.       Type_Def := Type_Definition (N);
  771.  
  772.       pragma Assert (Nkind (Type_Def) = N_Record_Definition
  773.                        or else Nkind (Type_Def) = N_Derived_Type_Definition);
  774.  
  775.       if Nkind (Type_Def) = N_Record_Definition then
  776.          if No (Component_List (Type_Def)) then   -- null record.
  777.             return;
  778.          else
  779.             V := Variant_Part (Component_List (Type_Def));
  780.          end if;
  781.  
  782.       else -- Nkind (Type_Def) = N_Derived_Type_Definition
  783.          if No (Component_List (Record_Extension_Part (Type_Def))) then
  784.             return;
  785.          else
  786.             V := Variant_Part
  787.                    (Component_List (Record_Extension_Part (Type_Def)));
  788.          end if;
  789.       end if;
  790.  
  791.       if Present (V) then
  792.          Loc := Sloc (N);
  793.          Enclosing_Func_Id := Empty;
  794.          Rec_Id := Defining_Identifier (N);
  795.          Build_Functions (V);
  796.       end if;
  797.    end Build_Discr_Checking_Funcs;
  798.  
  799.    ----------------------------
  800.    -- Build_Record_Init_Proc --
  801.    ----------------------------
  802.  
  803.    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id) is
  804.       Loc      : constant Source_Ptr := Sloc (N);
  805.       Proc_Id  : Entity_Id;
  806.       Rec_Type : Entity_Id;
  807.  
  808.       --------------------------------------------------
  809.       -- Local Subprograms for Build_Record_Init_Proc --
  810.       --------------------------------------------------
  811.  
  812.       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id;
  813.       --  Build a assignment statement node which assigns to record
  814.       --  component its default expression if defined. The left hand side
  815.       --  of the assignment is marked Assignment_OK so that initialization
  816.       --  of limited private records works correctly, Return also the
  817.       --  adjustment call for controlled objects
  818.  
  819.       procedure Build_Discriminant_Assignments (Statement_List : List_Id);
  820.       --  If the record has discriminants, adds assignment statements to
  821.       --  statement list to initialize the discriminant values from the
  822.       --  arguments of the initialization procedure.
  823.  
  824.       function Build_Init_Statements (Comp_List : Node_Id) return List_Id;
  825.       --  Build a list representing a sequence of statements which initialize
  826.       --  components of the given component list. This may involve building
  827.       --  case statements for the variant parts.
  828.  
  829.       procedure Build_Init_Procedure;
  830.       --  Build the tree corresponding to the procedure specification and body
  831.       --  of the initialization procedure (by calling all the preceding
  832.       --  auxillary routines), and install it as the _init TSS.
  833.  
  834.       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean;
  835.       --  Determines whether a record initialization procedure needs to be
  836.       --  generated for the given record type.
  837.  
  838.       ----------------------
  839.       -- Build_Assignment --
  840.       ----------------------
  841.  
  842.       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id is
  843.          Lhs : Node_Id;
  844.          Typ : constant Entity_Id := Underlying_Type (Etype (Id));
  845.          Res : List_Id;
  846.  
  847.       begin
  848.          Lhs :=
  849.            Make_Selected_Component (Loc,
  850.              Prefix => Make_Identifier (Loc, Name_uInit),
  851.              Selector_Name => New_Occurrence_Of (Id, Loc));
  852.          Set_Assignment_OK (Lhs);
  853.  
  854.          Res := New_List (
  855.            Make_Assignment_Statement (Loc,
  856.              Name       => Lhs,
  857.              Expression => N));
  858.  
  859.          --  Adjust the tag if tagged
  860.  
  861.          if Is_Tagged_Type (Typ) then
  862.             Append_To (Res,
  863.               Make_Assignment_Statement (Loc,
  864.                 Name =>
  865.                   Make_Selected_Component (Loc,
  866.                     Prefix =>  New_Copy_Tree (Lhs),
  867.                     Selector_Name =>
  868.                       New_Reference_To (Tag_Component (Typ), Loc)),
  869.  
  870.                 Expression =>
  871.                   Make_Unchecked_Type_Conversion (Loc,
  872.                     Subtype_Mark => New_Reference_To (RTE (RE_Tag), Loc),
  873.                     Expression =>
  874.                       New_Reference_To (Access_Disp_Table (Typ), Loc))));
  875.          end if;
  876.  
  877.          --  Adjust the component if controlled
  878.  
  879.          if Controlled_Type (Typ) then
  880.             Append_List_To (Res,
  881.               Make_Adjust_Call (
  882.                Ref         => New_Copy_Tree (Lhs),
  883.                Typ         => Typ,
  884.                Flist_Ref   =>
  885.                  Find_Final_List (Typ, New_Copy_Tree (Lhs)),
  886.                With_Attach => New_Reference_To (Standard_True, Loc)));
  887.          end if;
  888.  
  889.          return Res;
  890.       end Build_Assignment;
  891.  
  892.       ---------------------------
  893.       -- Build_Init_Statements --
  894.       ---------------------------
  895.  
  896.       function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
  897.          Alt_List       : List_Id;
  898.          Statement_List : List_Id;
  899.          Stmts          : List_Id;
  900.  
  901.          Decl     : Node_Id;
  902.          Variant  : Node_Id;
  903.  
  904.          Id  : Entity_Id;
  905.          Typ : Entity_Id;
  906.  
  907.       begin
  908.          if Null_Present (Comp_List) then
  909.             return New_List (Make_Null_Statement (Loc));
  910.          end if;
  911.  
  912.          Statement_List := New_List;
  913.  
  914.          --  Loop through components, skipping pragmas
  915.  
  916.          Decl := First (Component_Items (Comp_List));
  917.          while Present (Decl) loop
  918.             if Nkind (Decl) /= N_Pragma then
  919.                Id := Defining_Identifier (Decl);
  920.                Typ := Etype (Id);
  921.  
  922.                if Present (Expression (Decl)) then
  923.                   Stmts := Build_Assignment (Id, Expression (Decl));
  924.  
  925.                elsif Is_Access_Type (Typ) then
  926.                   Stmts := Build_Assignment (Id, Make_Null (Loc));
  927.  
  928.                elsif Present (Base_Init_Proc (Typ)) then
  929.                   Stmts :=
  930.                     Build_Initialization_Call (Loc,
  931.                       Make_Selected_Component (Loc,
  932.                         Prefix => Make_Identifier (Loc, Name_uInit),
  933.                         Selector_Name => New_Occurrence_Of (Id, Loc)),
  934.                       Typ, True);
  935.  
  936.                --  If the type is private and has no Base_Init_Proc, its full
  937.                --  declaration can be an access type which must be initialized
  938.                --  unless they are Tags or Vtable_Ptr in which case they are
  939.                --  initialized by other means
  940.  
  941.                elsif Is_Private_Type (Typ)
  942.                  and then Is_Access_Type (Underlying_Type (Typ))
  943.                  and then Typ /= RTE (RE_Tag)
  944.                  and then Typ /= RTE (RE_Vtable_Ptr)
  945.  
  946.                then
  947.                   Stmts := New_List (
  948.                     Make_Assignment_Statement (Loc,
  949.                       Name =>
  950.                         Make_Unchecked_Type_Conversion (Loc,
  951.                           Subtype_Mark =>
  952.                             New_Reference_To (
  953.                               Underlying_Type (Typ), Loc),
  954.                           Expression =>
  955.                             Make_Selected_Component (Loc,
  956.                               Prefix => Make_Identifier (Loc, Name_uInit),
  957.                               Selector_Name => New_Occurrence_Of (Id, Loc))),
  958.                       Expression => Make_Null (Loc)));
  959.  
  960.                   Set_Assignment_OK (Name (First (Stmts)));
  961.                else
  962.                   Stmts := No_List;
  963.                end if;
  964.  
  965.                --  Some fields have to be initialized early. The record
  966.                --  Controller is one example.
  967.  
  968.                if Present (Stmts) then
  969.                   if Chars (Id) = Name_uController then
  970.                      Append_List_To (Stmts, Statement_List);
  971.                      Statement_List := Stmts;
  972.                   else
  973.                      Append_List_To (Statement_List, Stmts);
  974.                   end if;
  975.                end if;
  976.             end if;
  977.  
  978.             Decl := Next (Decl);
  979.          end loop;
  980.  
  981.          --  Process the variant part
  982.  
  983.          if Present (Variant_Part (Comp_List)) then
  984.             Alt_List := New_List;
  985.             Variant := First (Variants (Variant_Part (Comp_List)));
  986.  
  987.             while Present (Variant) loop
  988.                Append_To (Alt_List,
  989.                  Make_Case_Statement_Alternative (Loc,
  990.                    Discrete_Choices =>
  991.                      New_List_Copy (Discrete_Choices (Variant)),
  992.                    Statements =>
  993.                      Build_Init_Statements (Component_List (Variant))));
  994.  
  995.                Variant := Next (Variant);
  996.             end loop;
  997.  
  998.             --  The expression of the case statement which is a reference
  999.             --  to one of the discriminants is replaced by the appropriate
  1000.             --  formal parameter of the initialization procedure.
  1001.  
  1002.             Append_To (Statement_List,
  1003.               Make_Case_Statement (Loc,
  1004.                 Expression =>
  1005.                   New_Reference_To (Discriminal (
  1006.                     Entity (Name (Variant_Part (Comp_List)))), Loc),
  1007.                 Alternatives => Alt_List));
  1008.          end if;
  1009.  
  1010.          --  For a task record type, add the task create call and calls
  1011.          --  to bind any interrupt (signal) entries.
  1012.  
  1013.          if Is_Task_Record_Type (Rec_Type) then
  1014.             Append_To (Statement_List, Make_Task_Create_Call (Rec_Type));
  1015.  
  1016.             declare
  1017.                Task_Type : constant Entity_Id :=
  1018.                              Corresponding_Concurrent_Type (Rec_Type);
  1019.                Task_Decl : constant Node_Id := Parent (Task_Type);
  1020.                Task_Def  : constant Node_Id := Task_Definition (Task_Decl);
  1021.                Vis_Decl  : Node_Id;
  1022.                Ent       : Entity_Id;
  1023.  
  1024.             begin
  1025.                if Present (Task_Def) then
  1026.                   Vis_Decl := First (Visible_Declarations (Task_Def));
  1027.                   while Present (Vis_Decl) loop
  1028.                      if Nkind (Vis_Decl) = N_Attribute_Definition_Clause then
  1029.                         if Get_Attribute_Id (Chars (Vis_Decl)) =
  1030.                                                        Attribute_Address
  1031.                         then
  1032.                            Ent := Entity (Name (Vis_Decl));
  1033.  
  1034.                            if Ekind (Ent) = E_Entry then
  1035.                               Append_To (Statement_List,
  1036.                                 Make_Procedure_Call_Statement (Loc,
  1037.                                   Name => New_Reference_To (
  1038.                                     RTE (RE_Bind_Signal_To_Entry), Loc),
  1039.                                   Parameter_Associations => New_List (
  1040.                                     Make_Selected_Component (Loc,
  1041.                                       Prefix =>
  1042.                                         Make_Identifier (Loc, Name_uInit),
  1043.                                       Selector_Name =>
  1044.                                         Make_Identifier (Loc, Name_uTask_Id)),
  1045.                                     Entry_Index_Expression (
  1046.                                       Loc, Ent, Empty, Task_Type),
  1047.                                     Expression (Vis_Decl))));
  1048.                            end if;
  1049.                         end if;
  1050.                      end if;
  1051.  
  1052.                      Vis_Decl := Next (Vis_Decl);
  1053.                   end loop;
  1054.                end if;
  1055.             end;
  1056.  
  1057.          end if;
  1058.  
  1059.          --  For a protected type, add a call to Initialize_Protection.
  1060.  
  1061.          if Is_Protected_Record_Type (Rec_Type) then
  1062.             Append_To (Statement_List,
  1063.               Make_Initialize_Protection_Call (Rec_Type));
  1064.          end if;
  1065.  
  1066.          --  If no initializations when generated for component declarations
  1067.          --  corresponding to this Statement_List, append a null statement
  1068.          --  to the Statement_List to make it a valid Ada tree.
  1069.  
  1070.          if Is_Empty_List (Statement_List) then
  1071.             Append (New_Node (N_Null_Statement, Loc), Statement_List);
  1072.          end if;
  1073.  
  1074.          return Statement_List;
  1075.       end Build_Init_Statements;
  1076.  
  1077.       --------------------------
  1078.       -- Build_Init_Procedure --
  1079.       --------------------------
  1080.  
  1081.       procedure Build_Init_Procedure is
  1082.          Body_Node             : Node_Id;
  1083.          Handled_Stmt_Node     : Node_Id;
  1084.          Parameters            : List_Id;
  1085.          Proc_Spec_Node        : Node_Id;
  1086.          Statement_List        : List_Id;
  1087.          Record_Extension_Node : Node_Id;
  1088.  
  1089.       begin
  1090.          Statement_List := New_List;
  1091.          Body_Node := New_Node (N_Subprogram_Body, Loc);
  1092.  
  1093.          Proc_Id := Make_Defining_Identifier (Loc, Name_uInit_Proc);
  1094.  
  1095.          Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
  1096.          Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
  1097.  
  1098.          Build_Discriminant_Assignments (Statement_List);
  1099.  
  1100.          Parameters := Init_Formals (Rec_Type);
  1101.          Append_List_To (Parameters,
  1102.            Build_Discriminant_Formals (Rec_Type, True));
  1103.          Set_Parameter_Specifications (Proc_Spec_Node, Parameters);
  1104.  
  1105.          Set_Specification (Body_Node, Proc_Spec_Node);
  1106.          Set_Declarations (Body_Node, New_List);
  1107.  
  1108.          if Nkind (Type_Definition (N)) = N_Record_Definition then
  1109.             if not Null_Present (Type_Definition (N)) then
  1110.                Append_List_To (Statement_List,
  1111.                  Build_Init_Statements (
  1112.                    Component_List (Type_Definition (N))));
  1113.             end if;
  1114.  
  1115.          else
  1116.             --  N is a Derived_Type_Definition with a possible non-empty
  1117.             --  extension. The initialization of a type extension consists
  1118.             --  in the initialization of the components in the extension.
  1119.  
  1120.             Record_Extension_Node :=
  1121.               Record_Extension_Part (Type_Definition (N));
  1122.  
  1123.             if not Null_Present (Record_Extension_Node) then
  1124.                declare
  1125.                   Stmts : List_Id :=
  1126.                     Build_Init_Statements (
  1127.                       Component_List (Record_Extension_Node));
  1128.  
  1129.                begin
  1130.                   --  The parent field must be initialized first because
  1131.                   --  the offset of the new discriminants may depend on it
  1132.  
  1133.                   Prepend_To (Statement_List, Remove_Head (Stmts));
  1134.                   Append_List_To (Statement_List, Stmts);
  1135.                end;
  1136.             end if;
  1137.          end if;
  1138.  
  1139.          --  Add here the assignment to instantiate the Tag
  1140.  
  1141.          --  This instantiation is done at the end because the instantiation
  1142.          --  of the _parent field calls the Record_Init_Proc for the parent
  1143.          --  Parent which instantiate the Tag with a wrong value.
  1144.          --  The assignement corresponds to the code:
  1145.  
  1146.          --     _Init._Tag := Typ'Tag;
  1147.  
  1148.          if Is_Tagged_Type (Rec_Type) and then not Is_CPP_Class (Rec_Type) then
  1149.  
  1150.             Append_To (Statement_List,
  1151.               Make_Assignment_Statement (Loc,
  1152.                 Name =>
  1153.                   Make_Selected_Component (Loc,
  1154.                     Prefix => Make_Identifier (Loc, Name_uInit),
  1155.                     Selector_Name =>
  1156.                       New_Reference_To (Tag_Component (Rec_Type), Loc)),
  1157.  
  1158.                 Expression =>
  1159.                   New_Reference_To (Access_Disp_Table (Rec_Type), Loc)));
  1160.          end if;
  1161.  
  1162.          Handled_Stmt_Node := New_Node (N_Handled_Sequence_Of_Statements, Loc);
  1163.          Set_Statements (Handled_Stmt_Node, Statement_List);
  1164.          Set_Exception_Handlers (Handled_Stmt_Node, No_List);
  1165.          Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);
  1166.          Set_Init_Proc (Rec_Type, Proc_Id);
  1167.  
  1168.       end Build_Init_Procedure;
  1169.  
  1170.       ------------------------------------
  1171.       -- Build_Discriminant_Assignments --
  1172.       ------------------------------------
  1173.  
  1174.       procedure Build_Discriminant_Assignments (Statement_List : List_Id) is
  1175.          D : Entity_Id;
  1176.  
  1177.       begin
  1178.          if Has_Discriminants (Rec_Type) then
  1179.             D := First_Discriminant (Rec_Type);
  1180.  
  1181.             while Present (D) loop
  1182.                Append_List_To (Statement_List,
  1183.                  Build_Assignment (D,
  1184.                    New_Reference_To (Discriminal (D), Loc)));
  1185.  
  1186.                D := Next_Discriminant (D);
  1187.             end loop;
  1188.          end if;
  1189.       end Build_Discriminant_Assignments;
  1190.  
  1191.       ------------------------
  1192.       -- Requires_Init_Proc --
  1193.       ------------------------
  1194.  
  1195.       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean is
  1196.          Comp_Decl : Node_Id;
  1197.          Id        : Entity_Id;
  1198.  
  1199.       begin
  1200.          --  An initialization procedure needs to be generated only if at
  1201.          --  least one of the following applies:
  1202.  
  1203.          --  1. Discriminants are present, since they need to be initialized
  1204.          --     with the appropriate discriminant constraint expressions.
  1205.  
  1206.          --  2. The type is a tagged type, since the implicit Tag component
  1207.          --     needs to be initialized with a pointer to the dispatch table.
  1208.  
  1209.          --  3. The type contains tasks
  1210.  
  1211.          --  4. One or more components has an initial value
  1212.  
  1213.          --  5. One or more components is for a type which itself requires
  1214.          --     an initialization procedure.
  1215.  
  1216.          --  6. One or more components is an access type or a private type
  1217.          --     whose full declaration is an access type (which needs to be
  1218.          --     initialized to null).
  1219.  
  1220.          --  7. The type is the record type built for a task type (since at
  1221.          --     the very least, Create_Task must be called)
  1222.  
  1223.          --  8. The type is the record type built for a protected type (since
  1224.          --     Initialize_Protection must be called)
  1225.  
  1226.          if Is_CPP_Class (Rec_Id) then
  1227.             return False;
  1228.  
  1229.          elsif Has_Discriminants (Rec_Id)
  1230.            or else Is_Tagged_Type (Rec_Id)
  1231.            or else Is_Concurrent_Record_Type (Rec_Id)
  1232.            or else Has_Tasks (Rec_Id)
  1233.          then
  1234.             return True;
  1235.          end if;
  1236.  
  1237.          Id := First_Component (Rec_Id);
  1238.  
  1239.          while Present (Id) loop
  1240.             Comp_Decl := Parent (Id);
  1241.  
  1242.             if Present (Expression (Comp_Decl))
  1243.               or else Present (Base_Init_Proc (Etype (Id)))
  1244.               or else Is_Access_Type (Etype (Id))
  1245.               or else
  1246.                 (Is_Private_Type (Etype (Id))
  1247.                   and then Is_Access_Type (Underlying_Type (Etype (Id))))
  1248.             then
  1249.                return True;
  1250.             end if;
  1251.  
  1252.             Id := Next_Component (Id);
  1253.          end loop;
  1254.  
  1255.          return False;
  1256.       end Requires_Init_Proc;
  1257.  
  1258.    --  Start of processing for Build_Record_Init_Proc
  1259.  
  1260.    begin
  1261.       Rec_Type := Defining_Identifier (N);
  1262.  
  1263.       --  This may be full declaration of a private type,  in which case
  1264.       --  the visible entity is a record, and the private entity has been
  1265.       --  exchanged with it in the private part of the current package.
  1266.       --  The initialization procedure is built for the record type, which
  1267.       --  is retrievable from the private entity.
  1268.  
  1269.       if Is_Incomplete_Or_Private_Type (Rec_Type) then
  1270.          Rec_Type := Underlying_Type (Rec_Type);
  1271.       end if;
  1272.  
  1273.       --  Derived types that have no type extension can use the initialization
  1274.       --  procedure of their parent and do not need a procedure of their own.
  1275.       --  This is only correct if there are no representation clauses for the
  1276.       --  type or its parent, and if the parent has in fact been frozen so
  1277.       --  that its initialization procedure exists.
  1278.  
  1279.       if Is_Derived_Type (Rec_Type)
  1280.         and then not Is_Tagged_Type (Rec_Type)
  1281.         and then not Has_Non_Standard_Rep (Rec_Type)
  1282.         and then not Has_Non_Standard_Rep (Root_Type (Rec_Type))
  1283.         and then Present (Base_Init_Proc (Root_Type (Rec_Type)))
  1284.       then
  1285.          Copy_TSS (Base_Init_Proc (Root_Type (Rec_Type)), Rec_Type);
  1286.  
  1287.       --  Otherwise if we need an initialization procedure, then build one,
  1288.       --  mark it as public and inlinable and as having a completion.
  1289.  
  1290.       elsif Requires_Init_Proc (Rec_Type) then
  1291.          Build_Init_Procedure;
  1292.  
  1293.          Set_Ekind          (Proc_Id, E_Procedure);
  1294.          Set_Is_Public      (Proc_Id, Is_Public (Pe));
  1295.          Set_Is_Inlined     (Proc_Id);
  1296.          Set_Is_Internal    (Proc_Id);
  1297.          Set_Has_Completion (Proc_Id);
  1298.       end if;
  1299.    end Build_Record_Init_Proc;
  1300.  
  1301.    ---------------------------
  1302.    -- Expand_Derived_Record --
  1303.    ---------------------------
  1304.  
  1305.    --  Add a field _parent at the beginning of the record extension. This is
  1306.    --  used to implement inheritance. Here are some examples of expansion:
  1307.  
  1308.    --  1. no discriminants
  1309.    --      type T2 is new T1 with null record;
  1310.    --   gives
  1311.    --      type T2 is new T1 with record
  1312.    --        _Parent : T1;
  1313.    --      end record;
  1314.  
  1315.    --  2. renamed discriminants
  1316.    --    type T2 (B, C : Int) is new T1 (A => B) with record
  1317.    --       _Parent : T1 (A => B);
  1318.    --       D : Int;
  1319.    --    end;
  1320.  
  1321.    --  3. inherited discriminants
  1322.    --    type T2 is new T1 with record -- discriminant A inherited
  1323.    --       _Parent : T1 (A);
  1324.    --       D : Int;
  1325.    --    end;
  1326.  
  1327.    procedure Expand_Derived_Record (T : Entity_Id; Def : Node_Id) is
  1328.       Indic        : constant Node_Id    := Subtype_Indication (Def);
  1329.       Loc          : constant Source_Ptr := Sloc (Def);
  1330.       Rec_Ext_Part : Node_Id             := Record_Extension_Part (Def);
  1331.       Comp_List    : Node_Id;
  1332.       Comp_Decl    : Node_Id;
  1333.       Parent_N     : Node_Id;
  1334.       D            : Entity_Id;
  1335.       List_Constr  : constant List_Id    := New_List;
  1336.       New_Indic    : Node_Id;
  1337.  
  1338.    begin
  1339.       --  Expand_Tagged_Extension is called directly from the semantics, so
  1340.       --  we must check to see whether expansion is active before proceeding
  1341.  
  1342.       if not Expander_Active then
  1343.          return;
  1344.       end if;
  1345.  
  1346.       Comp_List := Component_List (Rec_Ext_Part);
  1347.       Parent_N := Make_Defining_Identifier (Loc, Name_uParent);
  1348.  
  1349.       --  If the derived type inherits its discriminants the type of the
  1350.       --  _parent field must be constrained by the inherited discriminants
  1351.  
  1352.       if Has_Discriminants (T)
  1353.         and then Nkind (Indic) /= N_Subtype_Indication
  1354.         and then not Is_Constrained (Entity (Indic))
  1355.       then
  1356.          D := First_Discriminant (T);
  1357.          while (Present (D)) loop
  1358.             Append_To (List_Constr, New_Occurrence_Of (D, Loc));
  1359.             D := Next_Discriminant (D);
  1360.          end loop;
  1361.  
  1362.          New_Indic :=
  1363.            Make_Subtype_Indication (Loc,
  1364.              Subtype_Mark => New_Reference_To (Entity (Indic), Loc),
  1365.              Constraint   =>
  1366.                Make_Index_Or_Discriminant_Constraint (Loc,
  1367.                  Constraints => List_Constr));
  1368.  
  1369.       --  Otherwise the the original subtype_indication is just what is needed
  1370.  
  1371.       else
  1372.          New_Indic := New_Copy (Indic);
  1373.       end if;
  1374.  
  1375.       Comp_Decl :=
  1376.         Make_Component_Declaration (Loc,
  1377.           Defining_Identifier => Parent_N,
  1378.           Subtype_Indication  => New_Indic);
  1379.  
  1380.       if Null_Present (Rec_Ext_Part) then
  1381.          Set_Component_List (Rec_Ext_Part,
  1382.            Make_Component_List (Loc,
  1383.              Component_Items => New_List (Comp_Decl),
  1384.              Variant_Part => Empty,
  1385.              Null_Present => False));
  1386.          Set_Null_Present (Rec_Ext_Part, False);
  1387.  
  1388.       elsif Null_Present (Comp_List)
  1389.         or else Is_Empty_List (Component_Items (Comp_List))
  1390.       then
  1391.          Set_Component_Items (Comp_List, New_List (Comp_Decl));
  1392.          Set_Null_Present (Comp_List, False);
  1393.  
  1394.       else
  1395.          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
  1396.       end if;
  1397.  
  1398.    end Expand_Derived_Record;
  1399.  
  1400.    ------------------------
  1401.    -- Expand_Tagged_Root --
  1402.    ------------------------
  1403.  
  1404.    procedure Expand_Tagged_Root (T : Entity_Id) is
  1405.       Def       : constant Node_Id := Type_Definition (Parent (T));
  1406.       Comp_List : Node_Id;
  1407.       Comp_Decl : Node_Id;
  1408.       Sloc_N    : Source_Ptr;
  1409.  
  1410.    begin
  1411.       if Null_Present (Def) then
  1412.          Set_Component_List (Def,
  1413.            Make_Component_List (Sloc (Def),
  1414.              Component_Items => Empty_List,
  1415.              Variant_Part => Empty,
  1416.              Null_Present => True));
  1417.       end if;
  1418.  
  1419.       Comp_List := Component_List (Def);
  1420.  
  1421.       if Null_Present (Comp_List)
  1422.         or else Is_Empty_List (Component_Items (Comp_List))
  1423.       then
  1424.          Sloc_N := Sloc (Comp_List);
  1425.       else
  1426.          Sloc_N := Sloc (First (Component_Items (Comp_List)));
  1427.       end if;
  1428.  
  1429.       Comp_Decl :=
  1430.         Make_Component_Declaration (Sloc_N,
  1431.           Defining_Identifier => Tag_Component (T),
  1432.           Subtype_Indication  =>
  1433.             New_Reference_To (RTE (RE_Tag), Sloc_N));
  1434.  
  1435.       if Null_Present (Comp_List)
  1436.         or else Is_Empty_List (Component_Items (Comp_List))
  1437.       then
  1438.          Set_Component_Items (Comp_List, New_List (Comp_Decl));
  1439.          Set_Null_Present (Comp_List, False);
  1440.  
  1441.       else
  1442.          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
  1443.       end if;
  1444.  
  1445.       --  We don't Analyze the whole expansion because the tag component has
  1446.       --  already been analyzed previously. Here we just insure that the
  1447.       --  tree is coherent with the semantic decoration
  1448.  
  1449.       Find_Type (Subtype_Indication (Comp_Decl));
  1450.    end Expand_Tagged_Root;
  1451.  
  1452.    ------------------------------
  1453.    -- Expand_Record_Controller --
  1454.    ------------------------------
  1455.  
  1456.    procedure Expand_Record_Controller (T : Entity_Id) is
  1457.       Def             : Node_Id := Type_Definition (Parent (T));
  1458.       Comp_List       : Node_Id;
  1459.       Comp_Decl       : Node_Id;
  1460.       Loc             : Source_Ptr;
  1461.       First_Comp      : Node_Id;
  1462.       Controller_Type : Entity_Id;
  1463.  
  1464.    begin
  1465.       if Nkind (Def) = N_Derived_Type_Definition then
  1466.          Def := Record_Extension_Part (Def);
  1467.       end if;
  1468.  
  1469.       if Null_Present (Def) then
  1470.          Set_Component_List (Def,
  1471.            Make_Component_List (Sloc (Def),
  1472.              Component_Items => Empty_List,
  1473.              Variant_Part => Empty,
  1474.              Null_Present => True));
  1475.       end if;
  1476.  
  1477.       Comp_List := Component_List (Def);
  1478.  
  1479.       if Null_Present (Comp_List)
  1480.         or else Is_Empty_List (Component_Items (Comp_List))
  1481.       then
  1482.          Loc := Sloc (Comp_List);
  1483.       else
  1484.          Loc := Sloc (First (Component_Items (Comp_List)));
  1485.       end if;
  1486.  
  1487.       if Is_Limited_Type (T) then
  1488.          Controller_Type := RTE (RE_Limited_Record_Controller);
  1489.       else
  1490.          Controller_Type := RTE (RE_Record_Controller);
  1491.       end if;
  1492.  
  1493.       Comp_Decl :=
  1494.         Make_Component_Declaration (Loc,
  1495.           Defining_Identifier =>
  1496.             Make_Defining_Identifier (Loc, Name_uController),
  1497.           Subtype_Indication  => New_Reference_To (Controller_Type, Loc));
  1498.  
  1499.       if Null_Present (Comp_List)
  1500.         or else Is_Empty_List (Component_Items (Comp_List))
  1501.       then
  1502.          Set_Component_Items (Comp_List, New_List (Comp_Decl));
  1503.          Set_Null_Present (Comp_List, False);
  1504.  
  1505.       else
  1506.          --  The controller cannot be placed before the _Parent field
  1507.  
  1508.          First_Comp := First (Component_Items (Comp_List));
  1509.  
  1510.          if Chars (Defining_Identifier (First_Comp)) /= Name_uParent
  1511.            and then Chars (Defining_Identifier (First_Comp)) /= Name_uTag
  1512.          then
  1513.             Insert_Before (First_Comp, Comp_Decl);
  1514.          else
  1515.             Insert_After (First_Comp, Comp_Decl);
  1516.          end if;
  1517.       end if;
  1518.  
  1519.       New_Scope (T);
  1520.       Analyze (Comp_Decl);
  1521.       Set_Ekind (Defining_Identifier (Comp_Decl), E_Component);
  1522.       End_Scope;
  1523.    end Expand_Record_Controller;
  1524.  
  1525.    -----------------------
  1526.    -- Freeze_Array_Type --
  1527.    -----------------------
  1528.  
  1529.    procedure Freeze_Array_Type (N : Node_Id) is
  1530.       Loc  : constant Source_Ptr := Sloc (N);
  1531.       Typ  : constant Entity_Id  := Entity (N);
  1532.       Base : constant Entity_Id  := Base_Type (Typ);
  1533.       PAT  : Entity_Id;
  1534.       Decl : Node_Id;
  1535.  
  1536.    begin
  1537.       Set_Is_Packed (Typ, Is_Packed (Base));
  1538.  
  1539.       --  Non-packed case
  1540.  
  1541.       if not Is_Packed (Typ) then
  1542.          if No (Init_Proc (Base)) then
  1543.             Build_Array_Init_Proc (Base);
  1544.          end if;
  1545.  
  1546.          if Typ = Base and then Has_Controlled (Base) then
  1547.             Build_Controlling_Procs (Base);
  1548.          end if;
  1549.  
  1550.       --  Case of packed array, i.e. constrained one dimensional array type
  1551.       --  or subtype for which a pragma Pack is given, and whose component
  1552.       --  type is a scalar type whose size is in the range 1 .. 4. The checks
  1553.       --  on dimensionality and the component type are made in the pragma Pack
  1554.       --  processing in Sem_Prag.
  1555.  
  1556.       --  The processing below constructs an appropriate substitute type that
  1557.       --  is used to represent the packed array, and places the declaration of
  1558.       --  this type as a freeze action for the original array type or subtype.
  1559.  
  1560.       elsif Is_Constrained (Typ) then
  1561.          Expand_Packed_Array_Type (Typ, PAT, Decl);
  1562.          Set_Packed_Array_Type (Typ, PAT);
  1563.          Insert_Before_And_Analyze (N, Decl);
  1564.  
  1565.          --  A size may have been given for the original type, and here is
  1566.          --  where we deal with this. The size belongs to the corresponding
  1567.          --  packed array. Note that for the static case, the size was
  1568.          --  validated when the original size clause was encountered. For
  1569.          --  the dynamic case, Gigi will validate it in the usual manner.
  1570.  
  1571.          if Esize (Typ) /= Uint_0 then
  1572.             Set_Esize (PAT, Esize (Typ));
  1573.             Set_Esize (Typ, Uint_0);
  1574.          end if;
  1575.  
  1576.          --  Finally make sure packed array type gets frozen first
  1577.  
  1578.          Insert_List_Before_And_Analyze (N, Freeze_Entity (PAT, Loc));
  1579.       end if;
  1580.    end Freeze_Array_Type;
  1581.  
  1582.    -----------------------------
  1583.    -- Freeze_Enumeration_Type --
  1584.    -----------------------------
  1585.  
  1586.    procedure Freeze_Enumeration_Type (N : Node_Id) is
  1587.       Loc  : constant Source_Ptr := Sloc (N);
  1588.       Typ  : constant Entity_Id  := Entity (N);
  1589.       Ent  : Entity_Id;
  1590.       Lst  : List_Id;
  1591.       Num  : Nat;
  1592.       Arr  : Entity_Id;
  1593.       Fent : Entity_Id;
  1594.       Func : Entity_Id;
  1595.  
  1596.    begin
  1597.       --  Build list of literal references
  1598.  
  1599.       Lst := New_List;
  1600.       Num := 0;
  1601.  
  1602.       Ent := First_Literal (Typ);
  1603.       while Present (Ent) loop
  1604.          Append_To (Lst, New_Reference_To (Ent, Sloc (Ent)));
  1605.          Num := Num + 1;
  1606.          Ent := Next_Literal (Ent);
  1607.       end loop;
  1608.  
  1609.       --  Now build an array declaration
  1610.  
  1611.       --    typA : array (Natural range 0 .. num - 1) of etype :=
  1612.       --       (v, v, v, v, v, ....)
  1613.  
  1614.       --  where ctype is the corresponding integer type
  1615.  
  1616.       Arr :=
  1617.         Make_Defining_Identifier (Loc,
  1618.           Chars => New_External_Name (Chars (Typ), 'A'));
  1619.  
  1620.       Append_Freeze_Action (Typ,
  1621.         Make_Object_Declaration (Loc,
  1622.           Defining_Identifier => Arr,
  1623.           Constant_Present    => True,
  1624.  
  1625.           Object_Definition   =>
  1626.             Make_Constrained_Array_Definition (Loc,
  1627.               Discrete_Subtype_Definitions => New_List (
  1628.                 Make_Subtype_Indication (Loc,
  1629.                   Subtype_Mark => New_Reference_To (Standard_Natural, Loc),
  1630.                   Constraint =>
  1631.                     Make_Range_Constraint (Loc,
  1632.                       Range_Expression =>
  1633.                         Make_Range (Loc,
  1634.                           Low_Bound  =>
  1635.                             Make_Integer_Literal (Loc,
  1636.                               Intval => Uint_0),
  1637.                           High_Bound =>
  1638.                             Make_Integer_Literal (Loc,
  1639.                               Intval => UI_From_Int (Num - 1)))))),
  1640.  
  1641.               Subtype_Indication => New_Reference_To (Typ, Loc)),
  1642.  
  1643.           Expression =>
  1644.             Make_Aggregate (Loc,
  1645.               Expressions => Lst)));
  1646.  
  1647.       Set_Enum_Pos_To_Rep (Typ, Arr);
  1648.  
  1649.       --  Now we build the function that converts representation values to
  1650.       --  position values. This function has the form:
  1651.  
  1652.       --    function _Rep_To_Pos (A : etype) return Integer is
  1653.       --    begin
  1654.       --       case A is
  1655.       --         when enum-lit => return posval;
  1656.       --         when enum-lit => return posval;
  1657.       --         ...
  1658.       --         when others   => return -1;
  1659.       --       end case;
  1660.       --    end;
  1661.  
  1662.       --  First build list of cases
  1663.  
  1664.       Lst := New_List;
  1665.  
  1666.       Ent := First_Literal (Typ);
  1667.       while Present (Ent) loop
  1668.          Append_To (Lst,
  1669.            Make_Case_Statement_Alternative (Loc,
  1670.              Discrete_Choices => New_List (New_Reference_To (Ent, Loc)),
  1671.              Statements => New_List (
  1672.                Make_Return_Statement (Loc,
  1673.                  Expression =>
  1674.                    Make_Integer_Literal (Loc, Enumeration_Pos (Ent))))));
  1675.  
  1676.          Ent := Next_Literal (Ent);
  1677.       end loop;
  1678.  
  1679.       Append_To (Lst,
  1680.         Make_Case_Statement_Alternative (Loc,
  1681.           Discrete_Choices => New_List (Make_Others_Choice (Loc)),
  1682.           Statements => New_List (
  1683.             Make_Return_Statement (Loc,
  1684.               Expression =>
  1685.                 Make_Integer_Literal (Loc, Uint_Minus_1)))));
  1686.  
  1687.       --  Now we can build the function body
  1688.  
  1689.       Fent :=
  1690.         Make_Defining_Identifier (Loc, Name_uRep_To_Pos);
  1691.  
  1692.       Func :=
  1693.         Make_Subprogram_Body (Loc,
  1694.           Specification =>
  1695.             Make_Function_Specification (Loc,
  1696.               Defining_Unit_Name       => Fent,
  1697.               Parameter_Specifications => New_List (
  1698.                 Make_Parameter_Specification (Loc,
  1699.                   Defining_Identifier =>
  1700.                     Make_Defining_Identifier (Loc, Name_uA),
  1701.                   Parameter_Type => New_Reference_To (Typ, Loc))),
  1702.  
  1703.               Subtype_Mark => New_Reference_To (Standard_Integer, Loc)),
  1704.  
  1705.             Declarations => Empty_List,
  1706.  
  1707.             Handled_Statement_Sequence =>
  1708.               Make_Handled_Sequence_Of_Statements (Loc,
  1709.                 Statements => New_List (
  1710.                   Make_Case_Statement (Loc,
  1711.                     Expression => Make_Identifier (Loc, Name_uA),
  1712.                     Alternatives => Lst))));
  1713.  
  1714.       Set_TSS (Typ, Fent);
  1715.  
  1716.    end Freeze_Enumeration_Type;
  1717.  
  1718.    -----------------------------
  1719.    -- Freeze_Fixed_Point_Type --
  1720.    -----------------------------
  1721.  
  1722.    --  Now that we know the small value, we can set the small values on the
  1723.    --  bounds of the range. We delay this till the freeze-point since we do
  1724.    --  not know the final small value to be used till then.
  1725.  
  1726.    procedure Freeze_Fixed_Point_Type (N : Node_Id) is
  1727.       Typ     : constant Entity_Id  := Entity (N);
  1728.       Rng     : constant Node_Id    := Scalar_Range (Typ);
  1729.       Lo      : constant Node_Id    := Low_Bound (Rng);
  1730.       Hi      : constant Node_Id    := High_Bound (Rng);
  1731.       Loval   : constant Ureal      := Realval (Lo);
  1732.       Hival   : constant Ureal      := Realval (Hi);
  1733.       Btyp    : constant Entity_Id  := Base_Type (Typ);
  1734.       Small   : constant Ureal      := Small_Value (Typ);
  1735.  
  1736.    begin
  1737.       --  See if we can unfudge the bounds without increasing the size
  1738.       --  but be sure to respect the bounds of the base type when we
  1739.       --  do this in the case of a fixed point subtype.
  1740.  
  1741.       if Ekind (Typ) /= E_Ordinary_Fixed_Point_Subtype
  1742.         or else Loval > Realval (Low_Bound (Scalar_Range (Btyp)))
  1743.       then
  1744.          Set_Realval (Lo, Loval - Small);
  1745.  
  1746.          if Minimum_Size (Typ) > Esize (Typ) then
  1747.             Set_Realval (Lo, Loval);
  1748.          end if;
  1749.       end if;
  1750.  
  1751.       if Ekind (Typ) /= E_Ordinary_Fixed_Point_Subtype
  1752.         or else Hival < Realval (High_Bound (Scalar_Range (Btyp)))
  1753.       then
  1754.          Set_Realval (Hi, Hival + Small);
  1755.  
  1756.          if Minimum_Size (Typ) > Esize (Typ) then
  1757.             Set_Realval (Hi, Hival);
  1758.          end if;
  1759.       end if;
  1760.  
  1761.       --  Deal with low bound if not already set
  1762.  
  1763.       if No (Etype (Lo)) then
  1764.          Analyze (Lo);
  1765.  
  1766.          --  Resolve with universal fixed if the base type, and the base
  1767.          --  type if it is a subtype. Note we can't resolve the base type
  1768.          --  with itself, that would be a reference before definition.
  1769.  
  1770.          if Typ = Btyp then
  1771.             Resolve (Lo, Universal_Fixed);
  1772.          else
  1773.             Resolve (Lo, Btyp);
  1774.          end if;
  1775.  
  1776.          --  Set corresponding integer value for bound
  1777.  
  1778.          Set_Corresponding_Integer_Value
  1779.            (Lo, UR_To_Uint (Realval (Lo) / Small));
  1780.       end if;
  1781.  
  1782.       --  Similar processing for high bound
  1783.  
  1784.       if No (Etype (Hi)) then
  1785.          Analyze (Hi);
  1786.  
  1787.          if Typ = Btyp then
  1788.             Resolve (Hi, Universal_Fixed);
  1789.          else
  1790.             Resolve (Hi, Btyp);
  1791.          end if;
  1792.  
  1793.          Set_Corresponding_Integer_Value
  1794.            (Hi, UR_To_Uint (Realval (Hi) / Small));
  1795.       end if;
  1796.    end Freeze_Fixed_Point_Type;
  1797.  
  1798.    -----------------
  1799.    -- Freeze_Type --
  1800.    -----------------
  1801.  
  1802.    --  Full type declarations are expanded at the point at which the type
  1803.    --  is frozen. The formal N is the Freeze_Node for the type. Any statements
  1804.    --  or declarations generated by the freezing (e.g. the procedure generated
  1805.    --  for initialization) are chained in the Acions field list of the freeze
  1806.    --  node using Append_Freeze_Actions.
  1807.  
  1808.    procedure Freeze_Type (N : Node_Id) is
  1809.       Def_Id    : constant Entity_Id := Entity (N);
  1810.       Type_Decl : Node_Id            := Parent (Def_Id);
  1811.  
  1812.    begin
  1813.       --  Freeze processing for record type declaration
  1814.  
  1815.       if Ekind (Def_Id) = E_Record_Type
  1816.         and then not Is_Itype (Def_Id)      --  why this exception???
  1817.       then
  1818.  
  1819.          --  Creation of the Dispatch Table. Note that a Dispatch Table is
  1820.          --  created for regular tagged types as well as for Ada types
  1821.          --  deriving from a C++ Class, but not for tagged types directly
  1822.          --  corresponding to the C++ classes. In the later case we assume
  1823.          --  that the Vtable is created in the C++ side and we just use it.
  1824.  
  1825.          if Is_Tagged_Type (Def_Id) then
  1826.  
  1827.             if Is_CPP_Class (Def_Id) then
  1828.                Set_All_DT_Position (Def_Id);
  1829.                Set_Default_Constructor (Def_Id);
  1830.  
  1831.             else
  1832.                if Underlying_Type (Etype (Def_Id)) = Def_Id then
  1833.                   Expand_Tagged_Root (Def_Id);
  1834.                end if;
  1835.  
  1836.                --  Unfreeze momentarily the type to add the predefined
  1837.                --  primitives operations
  1838.  
  1839.                Set_Is_Frozen (Def_Id, False);
  1840.                Insert_List_Before_And_Analyze (N,
  1841.                  Predefined_Primitive_Specs (Def_Id));
  1842.                Set_Is_Frozen (Def_Id, True);
  1843.                Set_All_DT_Position (Def_Id);
  1844.  
  1845.                Append_Freeze_Actions (Def_Id, Make_DT (Def_Id));
  1846.  
  1847.                --  Make sure that the primitives Initialize, Adjust and
  1848.                --  Finalize are Frozen before other TSS subprograms. We
  1849.                --  don't want them Frozen inside.
  1850.  
  1851.                if Is_Controlled (Def_Id) then
  1852.                   if not Is_Limited_Type (Def_Id) then
  1853.                      Append_Freeze_Actions (Def_Id,
  1854.                        Freeze_Entity
  1855.                          (Find_Prim_Op (Def_Id, Name_Adjust), Sloc (Def_Id)));
  1856.                   end if;
  1857.  
  1858.                   Append_Freeze_Actions (Def_Id,
  1859.                     Freeze_Entity
  1860.                       (Find_Prim_Op (Def_Id, Name_Initialize), Sloc (Def_Id)));
  1861.  
  1862.                   Append_Freeze_Actions (Def_Id,
  1863.                     Freeze_Entity
  1864.                       (Find_Prim_Op (Def_Id, Name_Finalize), Sloc (Def_Id)));
  1865.                end if;
  1866.  
  1867.                Append_Freeze_Actions
  1868.                  (Def_Id, Predefined_Primitive_Bodies (Def_Id));
  1869.             end if;
  1870.  
  1871.          --  In the non-tagged case, an equality function is provided only
  1872.          --  for variant records
  1873.  
  1874.          elsif Has_Discriminants (Def_Id)
  1875.            and then not Is_Limited_Type (Def_Id)
  1876.          then
  1877.             declare
  1878.                Comps : constant Node_Id
  1879.                  := Component_List (Type_Definition (Type_Decl));
  1880.  
  1881.             begin
  1882.                if Present (Comps) and then Present (Variant_Part (Comps)) then
  1883.                   Build_Variant_Record_Equality (Def_Id);
  1884.                end if;
  1885.             end;
  1886.          end if;
  1887.  
  1888.          --  Before building the record initialization procedure, if we are
  1889.          --  dealing with a concurrent record value type, then we must go
  1890.          --  through the discriminants, exchanging discriminals between the
  1891.          --  concurrent type and the concurrent record value type. See the
  1892.          --  section "Handling of Discriminants" in the Einfo spec for details.
  1893.  
  1894.          if Is_Concurrent_Record_Type (Def_Id)
  1895.            and then Has_Discriminants (Def_Id)
  1896.          then
  1897.             declare
  1898.                Ctyp : constant Entity_Id :=
  1899.                         Corresponding_Concurrent_Type (Def_Id);
  1900.                Conc_Discr : Entity_Id;
  1901.                Rec_Discr  : Entity_Id;
  1902.                Temp       : Entity_Id;
  1903.  
  1904.             begin
  1905.                Conc_Discr := First_Discriminant (Ctyp);
  1906.                Rec_Discr  := First_Discriminant (Def_Id);
  1907.  
  1908.                while Present (Conc_Discr) loop
  1909.                   Temp := Discriminal (Conc_Discr);
  1910.                   Set_Discriminal (Conc_Discr, Discriminal (Rec_Discr));
  1911.                   Set_Discriminal (Rec_Discr,  Temp);
  1912.  
  1913.                   Conc_Discr := Next_Discriminant (Conc_Discr);
  1914.                   Rec_Discr  := Next_Discriminant (Rec_Discr);
  1915.                end loop;
  1916.             end;
  1917.          end if;
  1918.  
  1919.          if Has_Controlled (Def_Id) then
  1920.             if No (Controller_Component (Def_Id)) then
  1921.                Expand_Record_Controller (Def_Id);
  1922.             end if;
  1923.  
  1924.             Build_Controlling_Procs (Def_Id);
  1925.          end if;
  1926.  
  1927.          Build_Record_Init_Proc (Type_Decl, Def_Id);
  1928.  
  1929.          --  Build discriminant checking functions if not a derived type (for
  1930.          --  derived types that are not tagged types, we always use the
  1931.          --  discriminant checking functions of the base type).
  1932.  
  1933.          if not Is_Derived_Type (Def_Id)
  1934.            and then not Is_Tagged_Type (Def_Id)
  1935.            and then not Has_Non_Standard_Rep (Def_Id)
  1936.            and then not Has_Non_Standard_Rep (Root_Type (Def_Id))
  1937.          then
  1938.             Build_Discr_Checking_Funcs (Type_Decl);
  1939.          end if;
  1940.  
  1941.       --  Freeze processing for array type declaration
  1942.  
  1943.       elsif Is_Array_Type (Def_Id) then
  1944.          Freeze_Array_Type (N);
  1945.  
  1946.       --  Freeze processing for access type declaration
  1947.  
  1948.       --  For pool-specific access types, find out the pool object used for
  1949.       --  this type, needs actual expansion of it in some cases. Here are the
  1950.       --  different cases :
  1951.  
  1952.       --  1. Rep Clause "for Def_Id'Storage_Size use 0;"
  1953.       --      ---> Storage Pool is 'Empty_Pool_Object'
  1954.  
  1955.       --  2. Rep Clause : for Def_Id'Storage_Size use Expr.
  1956.       --     Expand:
  1957.       --      Def_Id__Pool : Stack_Bounded_Pool (Expr, DT'Size, DT'Alignment);
  1958.  
  1959.       --  3. Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
  1960.       --      ---> Storage Pool is the specified one
  1961.  
  1962.       --  See GNAT Pool packages in the Run-Time for more details
  1963.  
  1964.       elsif Ekind (Def_Id) = E_Access_Type
  1965.         or else Ekind (Def_Id) = E_General_Access_Type
  1966.       then
  1967.          declare
  1968.             Loc         : constant Source_Ptr := Sloc (N);
  1969.             Desig_Type  : constant Entity_Id := Designated_Type (Def_Id);
  1970.             Pool_Object : Entity_Id;
  1971.             Siz_Exp     : Node_Id;
  1972.  
  1973.          begin
  1974.             if Has_Storage_Size_Clause (Def_Id) then
  1975.                Siz_Exp := Expression (Parent (Storage_Size_Variable (Def_Id)));
  1976.             else
  1977.                Siz_Exp := Empty;
  1978.             end if;
  1979.  
  1980.             --  case 1
  1981.  
  1982.             if Has_Storage_Size_Clause (Def_Id)
  1983.               and then Is_OK_Static_Expression (Siz_Exp)
  1984.               and then Expr_Value (Siz_Exp) = 0
  1985.             then
  1986.                Set_Associated_Storage_Pool (Def_Id,
  1987.                  RTE (RE_Empty_Pool_Object));
  1988.  
  1989.             --  case 2
  1990.  
  1991.             elsif Has_Storage_Size_Clause (Def_Id) then
  1992.                declare
  1993.                   DT_Size  : Node_Id;
  1994.                   DT_Align : Node_Id;
  1995.  
  1996.                begin
  1997.                   --  Note: for now ??? we replace DT'Size by the arbitrary
  1998.                   --  value 4096 if DT is unconstrained. This obviously must
  1999.                   --  be fixed later (we need another storage pool type).
  2000.                   --  Similarly, we use Maximum_Alignment for the alignment.
  2001.  
  2002.                   if Is_Array_Type (Desig_Type)
  2003.                     and then not Is_Constrained (Desig_Type)
  2004.                   then
  2005.                      DT_Size :=
  2006.                        Make_Integer_Literal (Loc,
  2007.                          Intval => UI_From_Int (4096));
  2008.  
  2009.                      DT_Align :=
  2010.                        Make_Integer_Literal (Loc,
  2011.                          Intval => UI_From_Int (Maximum_Alignment));
  2012.  
  2013.                   else
  2014.                      DT_Size :=
  2015.                        Make_Attribute_Reference (Loc,
  2016.                          Prefix => New_Reference_To (Desig_Type, Loc),
  2017.                          Attribute_Name => Name_Size);
  2018.  
  2019.                      DT_Align :=
  2020.                        Make_Attribute_Reference (Loc,
  2021.                          Prefix => New_Reference_To (Desig_Type, Loc),
  2022.                          Attribute_Name => Name_Alignment);
  2023.                   end if;
  2024.  
  2025.                   Pool_Object :=
  2026.                     Make_Defining_Identifier (Loc,
  2027.                       Chars => New_External_Name (Chars (Def_Id), 'P'));
  2028.  
  2029.                   Append_Freeze_Action (Def_Id,
  2030.                     Make_Object_Declaration (Loc,
  2031.                       Defining_Identifier => Pool_Object,
  2032.                       Object_Definition =>
  2033.                         Make_Subtype_Indication (Loc,
  2034.                           Subtype_Mark =>
  2035.                             New_Reference_To
  2036.                               (RTE (RE_Stack_Bounded_Pool), Loc),
  2037.  
  2038.                           Constraint =>
  2039.                             Make_Index_Or_Discriminant_Constraint (Loc,
  2040.                               Constraints => New_List (
  2041.  
  2042.                               --  First discriminant is the Pool Size
  2043.  
  2044.                                 New_Reference_To (
  2045.                                   Storage_Size_Variable (Def_Id), Loc),
  2046.  
  2047.                               --  Second discriminant is the element size
  2048.  
  2049.                                 DT_Size,
  2050.  
  2051.                               --  Third discriminant is the alignment
  2052.  
  2053.                                 DT_Align)))));
  2054.  
  2055.                end;
  2056.  
  2057.                Set_Associated_Storage_Pool (Def_Id, Pool_Object);
  2058.  
  2059.             --  case 3
  2060.  
  2061.             elsif Present (Associated_Storage_Pool (Def_Id)) then
  2062.  
  2063.                --  Nothing to do the associated storage pool has been attached
  2064.                --  when analyzing the rep. clause
  2065.  
  2066.                null;
  2067.  
  2068.             end if;
  2069.  
  2070.             --  For access to controlled types (including class-wide types
  2071.             --  and taft amendment types which potentially have controlled
  2072.             --  components), expand the list controller object that will
  2073.             --  store the dynamically allocated objects. Do not do this
  2074.             --  transformation for expander generated access types.
  2075.  
  2076.             if not Comes_From_Source (Def_Id) then
  2077.                null;
  2078.  
  2079.             elsif Controlled_Type (Desig_Type)
  2080.               or else (Is_Incomplete_Or_Private_Type (Desig_Type)
  2081.                 and then No (Full_View (Desig_Type))
  2082.  
  2083.                --  An exception is made for types defined in the run-time
  2084.                --  because Ada.Tags.Tag itself is such a type and cannot
  2085.                --  afford this unnecessary overhead that would generates a
  2086.                --  loop in the expansion scheme...
  2087.  
  2088.                 and then not In_Runtime (Def_Id))
  2089.  
  2090.             then
  2091.                Set_Associated_Final_Chain (Def_Id,
  2092.                  Make_Defining_Identifier (Loc,
  2093.                    New_External_Name (Chars (Def_Id), 'L')));
  2094.  
  2095.                Append_Freeze_Action (Def_Id,
  2096.                  Make_Object_Declaration (Loc,
  2097.                    Defining_Identifier => Associated_Final_Chain (Def_Id),
  2098.                    Object_Definition   =>
  2099.                      New_Reference_To (RTE (RE_List_Controller), Loc)));
  2100.             end if;
  2101.          end;
  2102.  
  2103.       --  Freezing for enumeration types
  2104.  
  2105.       elsif Ekind (Def_Id) = E_Enumeration_Type then
  2106.  
  2107.          --  Always ignore types derived from standard character or standard
  2108.          --  wide character, these types do not permit enum rep clauses.
  2109.          --  Also ignore types derived from standard boolean.
  2110.  
  2111.          if Root_Type (Def_Id) = Standard_Character      or else
  2112.             Root_Type (Def_Id) = Standard_Wide_Character or else
  2113.             Root_Type (Def_Id) = Standard_Boolean
  2114.          then
  2115.             return;
  2116.          end if;
  2117.  
  2118.          --  We only have something to do if we have a non-standard
  2119.          --  representation (i.e. at least one literal whose pos value
  2120.          --  is not the same as its representation)
  2121.  
  2122.          declare
  2123.             E : Entity_Id;
  2124.  
  2125.          begin
  2126.             E := First_Literal (Def_Id);
  2127.             while Present (E) loop
  2128.                if Enumeration_Rep (E) /= Enumeration_Pos (E) then
  2129.                   Freeze_Enumeration_Type (N);
  2130.                   return;
  2131.                end if;
  2132.  
  2133.                E := Next_Literal (E);
  2134.             end loop;
  2135.          end;
  2136.  
  2137.       --  Freezing for fixed-point types
  2138.  
  2139.       elsif Is_Fixed_Point_Type (Def_Id) then
  2140.          Freeze_Fixed_Point_Type (N);
  2141.  
  2142.       --  All other types require no expander action. There are such
  2143.       --  cases (e.g. task types and protected types). In such cases,
  2144.       --  the freeze nodes are there for use by Gigi.
  2145.  
  2146.       end if;
  2147.    end Freeze_Type;
  2148.  
  2149.    ------------------------------------
  2150.    -- Expand_N_Full_Type_Declaration --
  2151.    ------------------------------------
  2152.  
  2153.    procedure Expand_N_Full_Type_Declaration (N : Node_Id) is
  2154.       Def_Id : constant Entity_Id := Defining_Identifier (N);
  2155.  
  2156.    begin
  2157.  
  2158.       if Is_Access_Type (Def_Id) then
  2159.          if Has_Tasks (Designated_Type (Def_Id)) then
  2160.             Build_Master_Entity (Def_Id);
  2161.             Build_Master_Renaming (N, Def_Id);
  2162.          end if;
  2163.  
  2164.       elsif Has_Tasks (Def_Id) then
  2165.          Expand_Previous_Access_Type (N, Def_Id);
  2166.       end if;
  2167.    end Expand_N_Full_Type_Declaration;
  2168.  
  2169.    ---------------------------
  2170.    -- Build_Master_Renaming --
  2171.    ---------------------------
  2172.  
  2173.    procedure Build_Master_Renaming (N : Node_Id; T : Entity_Id) is
  2174.       Loc    : constant Source_Ptr := Sloc (N);
  2175.       M_Id   : Entity_Id;
  2176.       Decl   : Node_Id;
  2177.  
  2178.    begin
  2179.       M_Id :=
  2180.         Make_Defining_Identifier (Loc,
  2181.           New_External_Name (Chars (T), 'M'));
  2182.  
  2183.       Decl :=
  2184.         Make_Object_Renaming_Declaration (Loc,
  2185.           Defining_Identifier => M_Id,
  2186.           Subtype_Mark => New_Reference_To (RTE (RE_Master_Id), Loc),
  2187.           Name => Make_Identifier (Loc, Name_uMaster));
  2188.       Insert_After (N, Decl);
  2189.       Analyze (Decl);
  2190.  
  2191.       Set_Master_Id (T, M_Id);
  2192.  
  2193.    end Build_Master_Renaming;
  2194.  
  2195.    ---------------------------------
  2196.    -- Expand_Previous_Access_Type --
  2197.    ---------------------------------
  2198.  
  2199.    procedure Expand_Previous_Access_Type (N : Node_Id; Def_Id : Entity_Id) is
  2200.       T : Entity_Id := First_Entity (Current_Scope);
  2201.  
  2202.    begin
  2203.       while Present (T) and then T /= Def_Id loop
  2204.          if Is_Access_Type (T)
  2205.             and then Designated_Type (T) = Def_Id
  2206.          then
  2207.             Build_Master_Entity (Def_Id);
  2208.             Build_Master_Renaming (N, T);
  2209.          end if;
  2210.  
  2211.          T := Next_Entity (T);
  2212.       end loop;
  2213.    end Expand_Previous_Access_Type;
  2214.  
  2215.    ---------------------------------
  2216.    -- Expand_N_Object_Declaration --
  2217.    ---------------------------------
  2218.  
  2219.    --  First we do special processing for objects of a tagged type where this
  2220.    --  is the point at which the type is frozen. The creation of the dispatch
  2221.    --  table and the initialization procedure have to be deffered to this
  2222.    --  point, since we reference previously declared primitive subprograms.
  2223.  
  2224.    --  For all types, we call an initialization procedure if there is one
  2225.  
  2226.    procedure Expand_N_Object_Declaration (N : Node_Id) is
  2227.       Def_Id     : constant Entity_Id  := Defining_Identifier (N);
  2228.       Typ        : constant Entity_Id  := Etype (Def_Id);
  2229.       Loc        : constant Source_Ptr := Sloc (N);
  2230.       Expr       : Node_Id := Expression (N);
  2231.       New_Ref    : Node_Id;
  2232.  
  2233.    begin
  2234.       --  Don't do anything for deferred constants. All proper actions will
  2235.       --  be expanded during the redeclaration.
  2236.  
  2237.       if No (Expr) and Constant_Present (N) then
  2238.          return;
  2239.       end if;
  2240.  
  2241.       --  If tasks being declared, make sure we have an activation chain
  2242.       --  defined for the tasks (has no effect if we already have one), and
  2243.       --  also that a Master variable is established and that the appropriate
  2244.       --  enclosing construct is established as a task master.
  2245.  
  2246.       if Has_Tasks (Typ) then
  2247.          Build_Activation_Chain_Entity (N);
  2248.          Build_Master_Entity (Def_Id);
  2249.       end if;
  2250.  
  2251.       if No_Default_Init (N) then
  2252.          null;
  2253.  
  2254.       elsif No (Expr) then
  2255.  
  2256.          --  Expand Initialize call for controlled objects.  One may wonder why
  2257.          --  the Initialize Call is not done in the regular Init procedure
  2258.          --  attached to the record type. That's because the init procedure is
  2259.          --  recursively called on each component, including _Parent, thus the
  2260.          --  Init call for a controlled object would generate not only one
  2261.          --  Initialize call as it is required but one for each ancestor of
  2262.          --  its type.
  2263.  
  2264.          if Controlled_Type (Typ) then
  2265.             Insert_List_After (N,
  2266.               Make_Init_Call (
  2267.                 Ref       => New_Reference_To (Def_Id, Loc),
  2268.                 Typ       => Typ,
  2269.                 Flist_Ref => Find_Final_List (Def_Id)));
  2270.          end if;
  2271.  
  2272.          --  Call type initialization procedure if there is one. We build the
  2273.          --  call and put it immediately after the object declaration, so that
  2274.          --  it will be expanded in the usual manner. Note that this will
  2275.          --  result in proper handling of defaulted discriminants.
  2276.  
  2277.          if Present (Base_Init_Proc (Typ)) then
  2278.             Insert_List_After (N,
  2279.               Build_Initialization_Call (Loc,
  2280.               New_Reference_To (Def_Id, Loc), Typ));
  2281.  
  2282.          elsif Is_Access_Type (Typ) then
  2283.  
  2284.             --  For access types we don't call an init procedure, we directly
  2285.             --  assign a null value in order to leave the code preelaborable
  2286.             --  No_Location is used to mark the null in order to ease its
  2287.             --  removal in case the variable happend to be pragma imported.
  2288.             --  What is this all about ???? (Robert)
  2289.  
  2290.             Set_Expression (N, Make_Null (No_Location));
  2291.             Analyze (Expression (N));
  2292.             Resolve (Expression (N), Typ);
  2293.          end if;
  2294.  
  2295.       else
  2296.  
  2297.          --  if the type is controlled we attach the object to the final list
  2298.          --  and adjust the target after the copy.
  2299.  
  2300.          if Controlled_Type (Typ) then
  2301.             Insert_List_After (N,
  2302.               Make_Adjust_Call (
  2303.                 Ref         => New_Reference_To (Def_Id, Loc),
  2304.                 Typ         => Typ,
  2305.                 Flist_Ref   => Find_Final_List (Def_Id),
  2306.                 With_Attach => New_Reference_To (Standard_True, Loc)));
  2307.          end if;
  2308.  
  2309.          --  For tagged types, when an init value is given, the tag has to be
  2310.          --  re-initialized separately in order to avoid the propagation of a
  2311.          --  wrong tag coming from a view conversion unless the type is class
  2312.          --  wide (in this case the tag comes from the init value).
  2313.  
  2314.          if Is_Tagged_Type (Typ) and then not Is_Class_Wide_Type (Typ) then
  2315.  
  2316.             --  The re-assignment of the tag has to be done even if
  2317.             --  the object is a constant
  2318.  
  2319.             New_Ref :=
  2320.               Make_Selected_Component (Loc,
  2321.                  Prefix => New_Reference_To (Def_Id, Loc),
  2322.                  Selector_Name =>
  2323.                    New_Reference_To (Tag_Component (Typ), Loc));
  2324.  
  2325.             Set_Assignment_OK (New_Ref);
  2326.  
  2327.             Insert_After (N,
  2328.               Make_Assignment_Statement (Loc,
  2329.                 Name => New_Ref,
  2330.                 Expression =>
  2331.                   Make_Unchecked_Type_Conversion (Loc,
  2332.                     Subtype_Mark => New_Reference_To (RTE (RE_Tag), Loc),
  2333.                     Expression =>
  2334.                       New_Reference_To (Access_Disp_Table (Typ), Loc))));
  2335.          end if;
  2336.       end if;
  2337.    end Expand_N_Object_Declaration;
  2338.  
  2339.    -------------------------------
  2340.    -- Build_Initialization_Call --
  2341.    -------------------------------
  2342.  
  2343.    --  References to a discriminant inside the record type declaration
  2344.    --  can appear either in the subtype_indication to constrain a
  2345.    --  record or an array, or as part of a larger expression given for
  2346.    --  the initial value of a component. In both of these cases N appears
  2347.    --  in the record initialization procedure and needs to be replaced by
  2348.    --  the formal parameter of the initialization procedure which
  2349.    --  corresponds to that discriminant.
  2350.  
  2351.    --  In the example below, references to discriminants D1 and D2 in proc_1
  2352.    --  are replaced by references to formals with the same name
  2353.    --  (discriminals)
  2354.  
  2355.    --  A similar replacement is done for calls to any record
  2356.    --  initialization procedure for any components that are themselves
  2357.    --  of a record type.
  2358.  
  2359.    --  type R (D1, D2 : Integer) is record
  2360.    --     X : Integer := F * D1;
  2361.    --     Y : Integer := F * D2;
  2362.    --  end record;
  2363.  
  2364.    --  procedure proc_1 (Out_2 : out R; D1 : Integer; D2 : Integer) is
  2365.    --  begin
  2366.    --     Out_2.D1 := D1;
  2367.    --     Out_2.D2 := D2;
  2368.    --     Out_2.X := F * D1;
  2369.    --     Out_2.Y := F * D2;
  2370.    --  end;
  2371.  
  2372.    function Build_Initialization_Call
  2373.      (Loc          : Source_Ptr;
  2374.       Id_Ref       : Node_Id;
  2375.       Typ          : Entity_Id;
  2376.       In_Init_Proc : Boolean := False)
  2377.       return         List_Id
  2378.    is
  2379.       First_Arg : Node_Id;
  2380.       Args      : List_Id;
  2381.       Discr     : Elmt_Id;
  2382.       Arg       : Node_Id;
  2383.       Proc      : constant Entity_Id := Base_Init_Proc (Typ);
  2384.       Res       : List_Id;
  2385.       Full_Type : Entity_Id := Typ;
  2386.  
  2387.    begin
  2388.       if Is_Private_Type (Typ)
  2389.         and then Present (Full_View (Typ))
  2390.       then
  2391.          Full_Type := Full_View (Typ);
  2392.       end if;
  2393.  
  2394.       --  First argument (_Init) is the object to be initialized.
  2395.  
  2396.       if Is_CPP_Class (Typ) then
  2397.          First_Arg :=
  2398.            Make_Attribute_Reference (Loc,
  2399.              Prefix         => Id_Ref,
  2400.              Attribute_Name => Name_Unrestricted_Access);
  2401.  
  2402.       --  If Typ is derived, the procedure is the initialization procedure for
  2403.       --  the root type. Wrap the argument in an conversion to make it type
  2404.       --  honest. Actually it isn't quite type honest, because there can be
  2405.       --  conflicts of views in the private type case. That is why we set
  2406.       --  Conversion_OK in the conversion node.
  2407.       --  it type-honest.
  2408.  
  2409.       elsif (Is_Record_Type (Typ)
  2410.               or else Is_Private_Type (Typ))
  2411.         and then Etype (First_Formal (Proc)) /= Typ
  2412.       then
  2413.          declare
  2414.             Ftyp : constant Entity_Id := Etype (First_Formal (Proc));
  2415.  
  2416.          begin
  2417.             First_Arg :=
  2418.               Make_Type_Conversion (Loc,
  2419.                 Subtype_Mark => New_Occurrence_Of (Etype (Ftyp), Loc),
  2420.                 Expression   => Id_Ref);
  2421.  
  2422.             Set_Etype (First_Arg, Ftyp);
  2423.             Set_Conversion_OK (First_Arg);
  2424.          end;
  2425.  
  2426.       else
  2427.          First_Arg := Id_Ref;
  2428.       end if;
  2429.  
  2430.       Args := New_List (Convert_Concurrent (First_Arg, Typ));
  2431.  
  2432.       --  In the tasks case, add _Master as the value of the _Master parameter
  2433.       --  and _Chain as the value of the _Chain parameter. At the outer level,
  2434.       --  these will be variables holding the corresponding values obtained
  2435.       --  from GNARL. At inner levels, they will be the parameters passed down
  2436.       --  through the outer routines.
  2437.  
  2438.       if Has_Tasks (Full_Type) then
  2439.          Append_To (Args, Make_Identifier (Loc, Name_uMaster));
  2440.          Append_To (Args, Make_Identifier (Loc, Name_uChain));
  2441.       end if;
  2442.  
  2443.       --  Add discriminant values if discriminants are present
  2444.  
  2445.       if Has_Discriminants (Full_Type) then
  2446.          Discr := First_Elmt (Discriminant_Constraint (Full_Type));
  2447.  
  2448.          if In_Init_Proc then
  2449.  
  2450.             --  Replace any possible references to the discriminant in the
  2451.             --  call to the record initialization procedure with references
  2452.             --  to the appropriate formal parameter.
  2453.  
  2454.             while Present (Discr) loop
  2455.                Arg := Node (Discr);
  2456.  
  2457.                if Nkind (Arg) = N_Identifier
  2458.                   and then Ekind (Entity (Arg)) = E_Discriminant
  2459.                then
  2460.                   Append_To (Args,
  2461.                     New_Reference_To (Discriminal (Entity (Arg)), Loc));
  2462.  
  2463.                --  Case of access discriminants. We replace the reference
  2464.                --  to the type by a reference to the actual object
  2465.  
  2466.                elsif Nkind (Arg) = N_Attribute_Reference
  2467.                  and then Is_Entity_Name (Prefix (Arg))
  2468.                  and then Is_Type (Entity (Prefix (Arg)))
  2469.                then
  2470.                   Append_To (Args,
  2471.                     Make_Attribute_Reference (Loc,
  2472.                       Prefix         => New_Copy (Prefix (Id_Ref)),
  2473.                       Attribute_Name => Name_Unrestricted_Access));
  2474.  
  2475.                else
  2476.                   Append_To (Args, New_Copy (Arg));
  2477.                end if;
  2478.  
  2479.                Discr := Next_Elmt (Discr);
  2480.             end loop;
  2481.  
  2482.          else
  2483.             while Present (Discr) loop
  2484.  
  2485.                if Is_Constrained (Full_Type) then
  2486.                   Append_To (Args, Duplicate_Subexpr (Node (Discr)));
  2487.                else
  2488.  
  2489.                   --  The constraints come from the discriminant default
  2490.                   --  exps, they must be reevaluated, that is why New_Copy
  2491.                   --  is used here
  2492.  
  2493.                   Append_To (Args, New_Copy (Node (Discr)));
  2494.                end if;
  2495.  
  2496.                Discr := Next_Elmt (Discr);
  2497.             end loop;
  2498.          end if;
  2499.       end if;
  2500.  
  2501.       Res := New_List (
  2502.         Make_Procedure_Call_Statement (Loc,
  2503.           Name => New_Occurrence_Of (Proc, Loc),
  2504.           Parameter_Associations => Args));
  2505.  
  2506.       if Controlled_Type (Typ)
  2507.         and then Nkind (Id_Ref) = N_Selected_Component
  2508.         and then Chars (Selector_Name (Id_Ref)) /= Name_uParent
  2509.       then
  2510.          Append_List_To (Res,
  2511.            Make_Init_Call (
  2512.              Ref       => New_Copy_Tree (First_Arg),
  2513.              Typ       => Typ,
  2514.              Flist_Ref =>
  2515.                Find_Final_List (Typ, New_Copy_Tree (First_Arg))));
  2516.       end if;
  2517.  
  2518.       return Res;
  2519.    end Build_Initialization_Call;
  2520.  
  2521.    ----------------
  2522.    -- In_Runtime --
  2523.    ----------------
  2524.  
  2525.    function In_Runtime (E : Entity_Id) return Boolean is
  2526.       S1 : Entity_Id := Scope (E);
  2527.  
  2528.    begin
  2529.       while Scope (S1) /= Standard_Standard loop
  2530.          S1 := Scope (S1);
  2531.       end loop;
  2532.  
  2533.       return Chars (S1) = Name_System or else Chars (S1) = Name_Ada;
  2534.    end In_Runtime;
  2535.  
  2536.    -----------------
  2537.    -- Predef_Spec --
  2538.    -----------------
  2539.  
  2540.    function Predef_Spec
  2541.      (Loc      : Source_Ptr;
  2542.       Tag_Typ  : Entity_Id;
  2543.       Name     : Name_Id;
  2544.       Profile  : List_Id;
  2545.       Ret_Type : Entity_Id := Empty;
  2546.       For_Body : Boolean := False)
  2547.       return     Node_Id
  2548.    is
  2549.       Id   : Entity_Id := Make_Defining_Identifier (Loc, Name);
  2550.       Spec : Node_Id;
  2551.  
  2552.    begin
  2553.       Set_Is_Public (Id, Is_Public (Tag_Typ));
  2554.  
  2555.       --  The internal flag is set to mark these declarations because
  2556.       --  they have specific properties. First they are primitives even
  2557.       --  if they are not defined in the type scope (the freezing point
  2558.       --  is not necessarily in the same scope), furthermore the
  2559.       --  predefined equality can be overridden by a user-defined
  2560.       --  equality, no body will be generated in this case.
  2561.  
  2562.       Set_Is_Internal (Id);
  2563.  
  2564.       if No (Ret_Type) then
  2565.          Spec :=
  2566.            Make_Procedure_Specification (Loc,
  2567.              Defining_Unit_Name       => Id,
  2568.              Parameter_Specifications => Profile);
  2569.       else
  2570.          Spec :=
  2571.            Make_Function_Specification (Loc,
  2572.              Defining_Unit_Name       => Id,
  2573.              Parameter_Specifications => Profile,
  2574.              Subtype_Mark             =>
  2575.                New_Reference_To (Ret_Type, Loc));
  2576.       end if;
  2577.  
  2578.       if For_Body then
  2579.          return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty);
  2580.       else
  2581.          return Make_Subprogram_Declaration (Loc, Spec);
  2582.       end if;
  2583.  
  2584.    end Predef_Spec;
  2585.  
  2586.    ---------------------------
  2587.    -- Predef_Stream_IO_Spec --
  2588.    ---------------------------
  2589.  
  2590.    function Predef_Stream_IO_Spec
  2591.      (Loc      : Source_Ptr;
  2592.       Tag_Typ  : Entity_Id;
  2593.       Name     : Name_Id;
  2594.       For_Body : Boolean    := False)
  2595.       return     Node_Id
  2596.    is
  2597.    begin
  2598.       return Predef_Spec (Loc,
  2599.         Name    => Name,
  2600.         Tag_Typ => Tag_Typ,
  2601.         Profile => New_List (
  2602.           Make_Parameter_Specification (Loc,
  2603.             Defining_Identifier =>  Make_Defining_Identifier (Loc, Name_X),
  2604.             Parameter_Type      =>
  2605.             Make_Access_Definition (Loc,
  2606.                Subtype_Mark => New_Reference_To (
  2607.                  Class_Wide_Type (RTE (RE_Root_Stream_Type)), Loc))),
  2608.  
  2609.           Make_Parameter_Specification (Loc,
  2610.             Defining_Identifier =>  Make_Defining_Identifier (Loc, Name_Y),
  2611.             Out_Present         => True,
  2612.             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2613.  
  2614.         For_Body => For_Body);
  2615.    end Predef_Stream_IO_Spec;
  2616.  
  2617.    ----------------------
  2618.    -- Predef_Deep_Spec --
  2619.    ----------------------
  2620.  
  2621.    function Predef_Deep_Spec
  2622.      (Loc      : Source_Ptr;
  2623.       Tag_Typ  : Entity_Id;
  2624.       Name     : Name_Id;
  2625.       For_Body : Boolean := False)
  2626.       return     Node_Id
  2627.    is
  2628.    begin
  2629.       return Predef_Spec (Loc,
  2630.         Name    => Name,
  2631.         Tag_Typ => Tag_Typ,
  2632.         Profile => New_List (
  2633.           Make_Parameter_Specification (Loc,
  2634.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_L),
  2635.             In_Present          => True,
  2636.             Out_Present         => True,
  2637.             Parameter_Type      =>
  2638.               New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)),
  2639.  
  2640.           Make_Parameter_Specification (Loc,
  2641.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
  2642.             In_Present          => True,
  2643.             Out_Present         => True,
  2644.             Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
  2645.  
  2646.           Make_Parameter_Specification (Loc,
  2647.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_B),
  2648.             Parameter_Type      => New_Reference_To (Standard_Boolean, Loc))),
  2649.  
  2650.         For_Body => For_Body);
  2651.    end Predef_Deep_Spec;
  2652.  
  2653.    --------------------------------
  2654.    -- Predefined_Primitive_Specs --
  2655.    --------------------------------
  2656.  
  2657.    function Predefined_Primitive_Specs
  2658.      (Tag_Typ : Entity_Id)
  2659.       return    List_Id
  2660.    is
  2661.       Loc              : constant Source_Ptr := Sloc (Tag_Typ);
  2662.       Res              : List_Id := New_List;
  2663.       Prim             : Elmt_Id;
  2664.       Eq_Needed        : Boolean;
  2665.  
  2666.    begin
  2667.       --  Spec of _Size
  2668.  
  2669.       Append_To (Res, Predef_Spec (Loc,
  2670.         Tag_Typ => Tag_Typ,
  2671.         Name    => Name_uSize,
  2672.         Profile => New_List (
  2673.           Make_Parameter_Specification (Loc,
  2674.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
  2675.             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2676.  
  2677.         Ret_Type => Standard_Long_Long_Integer));
  2678.  
  2679.       --  Specs for Dispatching stream IO
  2680.  
  2681.       if not In_Runtime (Tag_Typ) then
  2682.          Append_To (Res, Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uRead));
  2683.          Append_To (Res, Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uWrite));
  2684.          Append_To (Res, Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uInput));
  2685.          Append_To (Res, Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uOutput));
  2686.       end if;
  2687.  
  2688.       if not Is_Limited_Type (Tag_Typ) then
  2689.  
  2690.          --  Spec of "=" if expanded if the type is not limited and if a
  2691.          --  user defined "=" was not already declared for the non-full
  2692.          --  view of a private extension
  2693.  
  2694.          Eq_Needed := True;
  2695.          Prim := First_Elmt (Primitive_Operations (Tag_Typ));
  2696.          while Present (Prim) loop
  2697.             if Chars (Node (Prim)) = Name_Op_Eq
  2698.               and then No (Alias (Node (Prim)))
  2699.             then
  2700.                Eq_Needed := False;
  2701.                exit;
  2702.             end if;
  2703.  
  2704.             Prim := Next_Elmt (Prim);
  2705.          end loop;
  2706.  
  2707.          if Eq_Needed then
  2708.             Append_To (Res, Predef_Spec (Loc,
  2709.               Tag_Typ => Tag_Typ,
  2710.               Name    => Name_Op_Eq,
  2711.               Profile => New_List (
  2712.                 Make_Parameter_Specification (Loc,
  2713.                   Defining_Identifier =>
  2714.                     Make_Defining_Identifier (Loc, Name_X),
  2715.                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
  2716.  
  2717.                 Make_Parameter_Specification (Loc,
  2718.                   Defining_Identifier =>
  2719.                     Make_Defining_Identifier (Loc, Name_Y),
  2720.                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2721.  
  2722.               Ret_Type => Standard_Boolean));
  2723.          end if;
  2724.  
  2725.          --  Spec for dispatching assignment
  2726.  
  2727.          Append_To (Res, Predef_Spec (Loc,
  2728.            Tag_Typ => Tag_Typ,
  2729.            Name    => Name_uAssign,
  2730.            Profile => New_List (
  2731.              Make_Parameter_Specification (Loc,
  2732.                Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
  2733.                Out_Present         => True,
  2734.                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
  2735.  
  2736.              Make_Parameter_Specification (Loc,
  2737.                Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
  2738.                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)))));
  2739.       end if;
  2740.  
  2741.       --  Specs for finalization actions that may be required in case a
  2742.       --  future extension contain a controlled element. We generate those
  2743.       --  only for root tagged types where they will get dummy bodies or
  2744.       --  when the type has controlled components and their body must be
  2745.       --  generated. It is also impossible to provide those for tagged
  2746.       --  types defined within s-finimp since it would involve circularity
  2747.       --  problems
  2748.  
  2749.       if In_Finalization_Implementation (Tag_Typ) then
  2750.          null;
  2751.  
  2752.       elsif Etype (Tag_Typ) = Tag_Typ or else Controlled_Type (Tag_Typ) then
  2753.  
  2754.          if not Is_Limited_Type (Tag_Typ) then
  2755.             Append_To (Res,
  2756.               Predef_Deep_Spec (Loc, Tag_Typ, Name_uDeep_Adjust));
  2757.          end if;
  2758.  
  2759.          Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, Name_uDeep_Finalize));
  2760.       end if;
  2761.  
  2762.       return Res;
  2763.    end Predefined_Primitive_Specs;
  2764.  
  2765.    ---------------------------------
  2766.    -- Predefined_Primitive_Bodies --
  2767.    ---------------------------------
  2768.  
  2769.    function Predefined_Primitive_Bodies
  2770.      (Tag_Typ : Entity_Id)
  2771.       return    List_Id
  2772.    is
  2773.       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
  2774.       Decl      : Node_Id;
  2775.       Res       : List_Id := New_List;
  2776.       Prim      : Elmt_Id;
  2777.       Eq_Needed : Boolean := False;
  2778.  
  2779.    begin
  2780.       --  Make sure that predefined primitives operations are frozen
  2781.       --  before their bodies since their body will not freeze anything
  2782.  
  2783.       Prim := First_Elmt (Primitive_Operations (Tag_Typ));
  2784.       while Present (Prim) loop
  2785.          if Is_Internal (Node (Prim)) then
  2786.  
  2787.             Append_List_To (Res, Freeze_Entity (Node (Prim), Loc));
  2788.             if Chars (Node (Prim)) = Name_Op_Eq then
  2789.                Eq_Needed := True;
  2790.             end if;
  2791.          end if;
  2792.  
  2793.          Prim := Next_Elmt (Prim);
  2794.       end loop;
  2795.  
  2796.       --  Body of _Size
  2797.  
  2798.       Decl := Predef_Spec (Loc,
  2799.         Tag_Typ => Tag_Typ,
  2800.         Name    => Name_uSize,
  2801.         Profile => New_List (
  2802.           Make_Parameter_Specification (Loc,
  2803.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
  2804.             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2805.  
  2806.         Ret_Type => Standard_Long_Long_Integer,
  2807.         For_Body => True);
  2808.  
  2809.  
  2810.       Set_Handled_Statement_Sequence (Decl,
  2811.         Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2812.           Make_Return_Statement (Loc,
  2813.             Expression =>
  2814.               Make_Attribute_Reference (Loc,
  2815.                 Prefix => Make_Identifier (Loc, Name_X),
  2816.                 Attribute_Name  => Name_Size)))));
  2817.  
  2818.       Append_To (Res, Decl);
  2819.  
  2820.       --  Bodies for Dispatching stream IO routines
  2821.  
  2822.       if not In_Runtime (Tag_Typ) then
  2823.          Decl := Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uRead, True);
  2824.          Set_Handled_Statement_Sequence (Decl,
  2825.            Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2826.              Make_Null_Statement (Loc))));
  2827.          Append_To (Res, Decl);
  2828.  
  2829.          Decl := Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uWrite, True);
  2830.          Set_Handled_Statement_Sequence (Decl,
  2831.            Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2832.              Make_Null_Statement (Loc))));
  2833.          Append_To (Res, Decl);
  2834.  
  2835.          Decl := Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uInput, True);
  2836.          Set_Handled_Statement_Sequence (Decl,
  2837.            Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2838.              Make_Null_Statement (Loc))));
  2839.          Append_To (Res, Decl);
  2840.  
  2841.          Decl := Predef_Stream_IO_Spec (Loc, Tag_Typ, Name_uOutput, True);
  2842.          Set_Handled_Statement_Sequence (Decl,
  2843.            Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2844.              Make_Null_Statement (Loc))));
  2845.          Append_To (Res, Decl);
  2846.       end if;
  2847.  
  2848.       if not Is_Limited_Type (Tag_Typ) then
  2849.  
  2850.          --  Body for equality
  2851.  
  2852.          if Eq_Needed then
  2853.  
  2854.             Decl := Predef_Spec (Loc,
  2855.               Tag_Typ => Tag_Typ,
  2856.               Name    => Name_Op_Eq,
  2857.               Profile => New_List (
  2858.                 Make_Parameter_Specification (Loc,
  2859.                   Defining_Identifier =>
  2860.                     Make_Defining_Identifier (Loc, Name_X),
  2861.                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
  2862.  
  2863.                 Make_Parameter_Specification (Loc,
  2864.                   Defining_Identifier =>
  2865.                     Make_Defining_Identifier (Loc, Name_Y),
  2866.                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2867.  
  2868.               Ret_Type => Standard_Boolean,
  2869.               For_Body => True);
  2870.  
  2871.             declare
  2872.                Def          : constant Node_Id := Parent (Tag_Typ);
  2873.                Variant_Case : Boolean := Has_Discriminants (Tag_Typ);
  2874.                Comps        : Node_Id := Empty;
  2875.                Typ_Def      : Node_Id := Type_Definition (Def);
  2876.                Stmts        : List_Id := New_List;
  2877.  
  2878.             begin
  2879.                if Variant_Case then
  2880.                   if Nkind (Typ_Def) = N_Derived_Type_Definition then
  2881.                      Typ_Def := Record_Extension_Part (Typ_Def);
  2882.                   end if;
  2883.  
  2884.                   if Present (Typ_Def) then
  2885.                      Comps := Component_List (Typ_Def);
  2886.                   end if;
  2887.  
  2888.                   Variant_Case := Present (Comps)
  2889.                     and then Present (Variant_Part (Comps));
  2890.                end if;
  2891.  
  2892.  
  2893.                if Variant_Case then
  2894.                   Append_To (Stmts,
  2895.                       Make_Eq_If (Loc, Discriminant_Specifications (Def)));
  2896.                   Append_List_To (Stmts, Make_Eq_Case (Loc, Comps));
  2897.                   Append_To (Stmts,
  2898.                     Make_Return_Statement (Loc,
  2899.                       Expression => New_Reference_To (Standard_True, Loc)));
  2900.  
  2901.                else
  2902.                   Append_To (Stmts,
  2903.                     Make_Return_Statement (Loc,
  2904.                       Expression =>
  2905.                         Expand_Record_Equality (Loc,
  2906.                           Typ => Tag_Typ,
  2907.                           Lhs => Make_Identifier (Loc, Name_X),
  2908.                           Rhs => Make_Identifier (Loc, Name_Y))));
  2909.                end if;
  2910.  
  2911.                Set_Handled_Statement_Sequence (Decl,
  2912.                  Make_Handled_Sequence_Of_Statements (Loc, Stmts));
  2913.             end;
  2914.             Append_To (Res, Decl);
  2915.          end if;
  2916.  
  2917.          --  Body for dispatching assignment
  2918.  
  2919.          Decl := Predef_Spec (Loc,
  2920.            Tag_Typ => Tag_Typ,
  2921.            Name    => Name_uAssign,
  2922.            Profile => New_List (
  2923.              Make_Parameter_Specification (Loc,
  2924.                Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
  2925.                Out_Present         => True,
  2926.                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
  2927.  
  2928.              Make_Parameter_Specification (Loc,
  2929.                Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
  2930.                Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
  2931.            For_Body => True);
  2932.  
  2933.          Set_Handled_Statement_Sequence (Decl,
  2934.            Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2935.              Make_Assignment_Statement (Loc,
  2936.                Name       => Make_Identifier (Loc, Name_X),
  2937.                Expression => Make_Identifier (Loc, Name_Y)))));
  2938.  
  2939.          Append_To (Res, Decl);
  2940.       end if;
  2941.  
  2942.       --  Generate dummy bodies for finalization actions of types that have
  2943.       --  no controlled components
  2944.  
  2945.       if In_Finalization_Implementation (Tag_Typ) then
  2946.          null;
  2947.  
  2948.       elsif (Etype (Tag_Typ) = Tag_Typ or else Is_Controlled (Tag_Typ))
  2949.         and then not Has_Controlled (Tag_Typ)
  2950.       then
  2951.  
  2952.          if not Is_Limited_Type (Tag_Typ) then
  2953.             Decl := Predef_Deep_Spec (Loc, Tag_Typ, Name_uDeep_Adjust, True);
  2954.  
  2955.             if Is_Controlled (Tag_Typ) then
  2956.                Set_Handled_Statement_Sequence (Decl,
  2957.                  Make_Handled_Sequence_Of_Statements (Loc,
  2958.                    Make_Adjust_Call (
  2959.                      Ref         => Make_Identifier (Loc, Name_V),
  2960.                      Typ         => Tag_Typ,
  2961.                      Flist_Ref   => Make_Identifier (Loc, Name_L),
  2962.                      With_Attach => Make_Identifier (Loc, Name_B))));
  2963.  
  2964.             else
  2965.                Set_Handled_Statement_Sequence (Decl,
  2966.                  Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2967.                    Make_Null_Statement (Loc))));
  2968.             end if;
  2969.  
  2970.             Append_To (Res, Decl);
  2971.          end if;
  2972.  
  2973.          Decl := Predef_Deep_Spec (Loc, Tag_Typ, Name_uDeep_Finalize, True);
  2974.  
  2975.          if Is_Controlled (Tag_Typ) then
  2976.             Set_Handled_Statement_Sequence (Decl,
  2977.               Make_Handled_Sequence_Of_Statements (Loc,
  2978.                 Make_Final_Call (
  2979.                   Ref         => Make_Identifier (Loc, Name_V),
  2980.                   Typ         => Tag_Typ,
  2981.                   Flist_Ref   => Make_Identifier (Loc, Name_L),
  2982.                   With_Detach => Make_Identifier (Loc, Name_B))));
  2983.  
  2984.          else
  2985.             Set_Handled_Statement_Sequence (Decl,
  2986.               Make_Handled_Sequence_Of_Statements (Loc, New_List (
  2987.                 Make_Null_Statement (Loc))));
  2988.          end if;
  2989.  
  2990.          Append_To (Res, Decl);
  2991.       end if;
  2992.  
  2993.       return Res;
  2994.    end Predefined_Primitive_Bodies;
  2995.  
  2996.    ---------------------------
  2997.    -- Expand_N_Variant_Part --
  2998.    ---------------------------
  2999.  
  3000.    --  If the last variant does not contain the Others choice, replace
  3001.    --  it with an N_Others_Choice node since Gigi always wants an Others.
  3002.    --  Note that we do not bother to call Analyze on the modified variant
  3003.    --  part, since it's only effect would be to compute the contents of
  3004.    --  the Others_Discrete_Choices node laboriously, and of course we
  3005.    --  already know the list of choices that corresponds to the others
  3006.    --  choice (it's the list we are replacing!)
  3007.  
  3008.    procedure Expand_N_Variant_Part (N : Node_Id) is
  3009.       Last_Var    : constant Node_Id := Last (Variants (N));
  3010.       Others_Node : Node_Id;
  3011.  
  3012.    begin
  3013.       if Nkind (First (Discrete_Choices (Last_Var))) /= N_Others_Choice then
  3014.          Others_Node := Make_Others_Choice (Sloc (Last_Var));
  3015.          Set_Others_Discrete_Choices
  3016.            (Others_Node, Discrete_Choices (Last_Var));
  3017.          Set_Discrete_Choices (Last_Var, New_List (Others_Node));
  3018.       end if;
  3019.    end Expand_N_Variant_Part;
  3020.  
  3021.    ------------------
  3022.    -- Init_Formals --
  3023.    ------------------
  3024.  
  3025.    function Init_Formals (Typ : Entity_Id) return List_Id is
  3026.       Loc     : constant Source_Ptr := Sloc (Typ);
  3027.       Formals : List_Id;
  3028.  
  3029.    begin
  3030.       --  First parameter is always _Init : in out typ. Note that we need
  3031.       --  this to be in/out because in the case of the task record value,
  3032.       --  there are default record fields (_Priority and _Size) that may be
  3033.       --  referenced in the generated initialization routine.
  3034.  
  3035.       Formals := New_List (
  3036.         Make_Parameter_Specification (Loc,
  3037.           Defining_Identifier =>
  3038.             Make_Defining_Identifier (Loc, Name_uInit),
  3039.           In_Present  => True,
  3040.           Out_Present => True,
  3041.           Parameter_Type => New_Reference_To (Typ, Loc)));
  3042.  
  3043.       --  For task record value, or type that contains tasks, add two more
  3044.       --  formals, _Master : Master_Id and _Chain : in out Activation_Chain
  3045.       --  We also add these parameters for the task record type case.
  3046.  
  3047.       if Has_Tasks (Typ)
  3048.         or else (Is_Record_Type (Typ) and then Is_Task_Record_Type (Typ))
  3049.       then
  3050.          Append_To (Formals,
  3051.            Make_Parameter_Specification (Loc,
  3052.              Defining_Identifier =>
  3053.                Make_Defining_Identifier (Loc, Name_uMaster),
  3054.              Parameter_Type => New_Reference_To (RTE (RE_Master_Id), Loc)));
  3055.  
  3056.          Append_To (Formals,
  3057.            Make_Parameter_Specification (Loc,
  3058.              Defining_Identifier =>
  3059.                Make_Defining_Identifier (Loc, Name_uChain),
  3060.              In_Present => True,
  3061.              Out_Present => True,
  3062.              Parameter_Type =>
  3063.                New_Reference_To (RTE (RE_Activation_Chain), Loc)));
  3064.       end if;
  3065.  
  3066.       return Formals;
  3067.    end Init_Formals;
  3068.  
  3069. end Exp_Ch3;
  3070.