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_aggr.adb < prev    next >
Text File  |  1996-09-28  |  47KB  |  1,409 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                             E X P _ A G G R                              --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.17 $                              --
  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 Exp_Util; use Exp_Util;
  28. with Exp_Ch3;  use Exp_Ch3;
  29. with Exp_Ch7;  use Exp_Ch7;
  30. with Itypes;   use Itypes;
  31. with Nmake;    use Nmake;
  32. with Nlists;   use Nlists;
  33. with Rtsfind;  use Rtsfind;
  34. with Sem;      use Sem;
  35. with Sem_Ch5;  use Sem_Ch5;
  36. with Sem_Eval; use Sem_Eval;
  37. with Sem_Res;  use Sem_Res;
  38. with Sem_Util; use Sem_Util;
  39. with Sinfo;    use Sinfo;
  40. with Snames;   use Snames;
  41. with Stand;    use Stand;
  42. with Tbuild;   use Tbuild;
  43. with Uintp;    use Uintp;
  44.  
  45. with System.Parameters;
  46.  
  47. package body Exp_Aggr is
  48.  
  49.    -----------------------------------------------------
  50.    -- Subprogram Specs for RECORD AGGREGATE Expansion --
  51.    -----------------------------------------------------
  52.  
  53.    procedure Expand_Record_Aggregate
  54.      (N           : Node_Id;
  55.       Orig_Tag    : Node_Id := Empty;
  56.       Parent_Expr : Node_Id := Empty);
  57.    --  This is the top level procedure for record aggregate expansion.
  58.    --  Expansion for record aggregates needs expand aggregates for tagged
  59.    --  record types. Specifically Expand_Record_Aggregate adds the Tag
  60.    --  field in front of the Component_Association list that was created
  61.    --  during resolution by Resolve_Record_Aggregate.
  62.    --    * N is the record aggregate node.
  63.    --    * Orig_Tag is the value of the Tag that has to be provided for this
  64.    --      specific aggregate. It carries the tag corresponding to the type
  65.    --      of the outermost aggregate during the recursive expansion
  66.    --    * Parent_Expr is the ancestor part of the original extension
  67.    --      aggregate
  68.  
  69.    procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
  70.    --  N is an N_Aggregate of a N_Extension_Aggregate. Typ is the type of
  71.    --  the aggregate. Transodrm the given aggregate into a buch of assignment
  72.    --  component per component
  73.  
  74.    ----------------------------------------------------
  75.    -- Subprogram Specs for ARRAY AGGREGATE Expansion --
  76.    ----------------------------------------------------
  77.  
  78.    procedure Expand_Array_Aggregate (N : Node_Id);
  79.    --  This is the top-level routine to perform array aggregate expansion.
  80.    --
  81.    --    N is the N_Aggregate node to be expanded.
  82.    --
  83.    --  Array aggregate expansion proceeds as follows:
  84.    --
  85.    --  1. If requested we generate code to perform all the array aggregate
  86.    --     bound checks, specifically
  87.    --
  88.    --         (a) Check that the index range defined by aggregate bounds is
  89.    --             compatible with corresponding index subtype.
  90.    --
  91.    --         (b) If an others choice is present check that no aggregate
  92.    --             index is outside the bounds of the index constraint.
  93.    --
  94.    --         (c) For multidimensional arrays make sure that all subaggregates
  95.    --             corresponding to the same dimension have the same bounds.
  96.    --
  97.    --  2. Check if the aggregate can be statically processed. If this is the
  98.    --     case pass it as is to Gigi. Note that a necessary condition for
  99.    --     static processing is that the aggregate be fully positional.
  100.    --
  101.    --  3. If in place aggregate expansion is possible (i.e. no need to create
  102.    --     a temporary) then mark the aggregate as such and return. Otherwise
  103.    --     create a new temporary and generate the appropriate initialization
  104.    --     code.
  105.  
  106.    function Static_Processing_Possible
  107.      (N        : Node_Id;
  108.       Index    : Node_Id;
  109.       Max_Size : Pos := System.Parameters.Max_Static_Aggregate_Size)
  110.       return Boolean;
  111.    --  This function checks if it possible to build a fully positional array
  112.    --  aggregate at compile time. If this is possible True is returned.
  113.    --
  114.    --    N is the N_Aggregate node to be checked.
  115.    --
  116.    --    Index is the index node corresponding to the array sub-aggregate that
  117.    --    we are currently checking.
  118.    --
  119.    --    Max_Size is the maximum size allowed for a static aggregate.
  120.    --
  121.    --  Static processing for the whole array aggregate is possible only if:
  122.    --
  123.    --    1. N is fully positional and its size is no greater than Max_Size;
  124.    --
  125.    --    2. No index type in N is an enumeration type with non-standard
  126.    --       representation.
  127.  
  128.    function Is_Empty (Typ : Entity_Id) return Boolean;
  129.    --  Returns true if constrained array subtype Typ defines an empty array.
  130.  
  131.    function In_Place_Copy_Possible (N : Node_Id; Dim : Pos) return Boolean;
  132.    --  This routine return True if aggregate N can be directly copied into the
  133.    --  target array. For the time being this is allowed only if all of N's
  134.    --  components are static expressions, but can (and should) be extended
  135.    --  for expressions involving names as well, but no function calls or
  136.    --  arrays.
  137.    --
  138.    --    N is an array aggregate or sub-aggregate to be rewritten.
  139.    --
  140.    --    Dim is the number of sub-aggregate dimension we still need to look at.
  141.  
  142.    function Build_Code
  143.      (N       : Node_Id;
  144.       Index   : Node_Id;
  145.       Into    : Entity_Id;
  146.       Indices : List_Id := No_List)
  147.       return List_Id;
  148.    --  This recursive routine returns a list of statements containing the
  149.    --  loops and assignments that are needed for the expansion of the array
  150.    --  aggregate N.
  151.    --
  152.    --    N is the (sub-)aggregate node to be expanded into code.
  153.    --
  154.    --    Index is the index node corresponding to the array sub-aggregate N.
  155.    --
  156.    --    Into is the object into which we are copying the aggregate.
  157.    --
  158.    --    Indices is the current list of expressions used to index the
  159.    --    object we are writing into.
  160.    --
  161.    --  The code that we generate from a one dimensional aggregate is
  162.    --
  163.    --  1. If the sub-aggregate contains discrete choices we
  164.    --     (A) Sort the discrete choices
  165.    --     (B) Otherwise for each discrete choices that specifies a range we
  166.    --         emit a loop. If a range specifies a single value, or we are
  167.    --         dealing with an expression we emit an assignment.
  168.    --     (C) Generate the remaning loops to cover the others choice if any.
  169.    --
  170.    --  2. If the aggregate contains positional elements we
  171.    --     (A) translate the positional elements in a series of assignments.
  172.    --     (B) Generate a final loop to cover the others choice if any.
  173.    --         Note that this final loop has to be a while loop since the case
  174.    --             L : Integer := Integer'Last;
  175.    --             H : Integer := Integer'Last;
  176.    --             A : array (L .. H) := (1, others =>0);
  177.    --         cannot be handled by a for loop. Thus for the following
  178.    --             array (L .. H) := (.. positional elements.., others =>E);
  179.    --         we always generate something like:
  180.    --             I : Index_Type := Index_Of_Last_Positional_Element;
  181.    --             while I < H loop
  182.    --                I := Index_Base'Succ (I)
  183.    --                Tmp (I) := E;
  184.    --             end loop;
  185.  
  186.    function Number_Of_Choices (N : Node_Id) return Nat;
  187.    --  Returns the number of discrete choices (not including the others choice
  188.    --  if present) contained in (sub-)aggregate N.
  189.  
  190.    ------------------------
  191.    -- Expand_N_Aggregate --
  192.    ------------------------
  193.  
  194.    procedure Expand_N_Aggregate (N : Node_Id) is
  195.    begin
  196.       if Is_Record_Type (Etype (N)) then
  197.          Expand_Record_Aggregate (N);
  198.       else
  199.          Expand_Array_Aggregate (N);
  200.       end if;
  201.    end Expand_N_Aggregate;
  202.  
  203.    ----------------------------
  204.    -- Convert_To_Assignments --
  205.    ----------------------------
  206.  
  207.    procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
  208.       Actions : List_Id := New_List;
  209.       Comp    : Node_Id;
  210.       Loc     : constant Source_Ptr := Sloc (N);
  211.       Temp    : constant Entity_Id :=
  212.                   Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  213.       Instr   : Node_Id;
  214.  
  215.    begin
  216.  
  217.       if Is_Controlled (Typ) then
  218.          Establish_Transient_Scope (N);
  219.  
  220.       elsif Has_Controlled (Typ) then
  221.          Unimplemented (N, "aggregate with controlled components");
  222.          return;
  223.       end if;
  224.  
  225.       --  Create the temporary
  226.  
  227.       Instr :=
  228.         Make_Object_Declaration (Loc,
  229.           Defining_Identifier => Temp,
  230.           Object_Definition => New_Occurrence_Of (Typ, Loc));
  231.  
  232.       Set_No_Default_Init (Instr);
  233.       Insert_Action (N, Instr);
  234.  
  235.       --  Deal with the ancestor part of extension aggregates
  236.  
  237.       if Nkind (N) = N_Extension_Aggregate then
  238.          declare
  239.             A : constant Node_Id := Ancestor_Part (N);
  240.  
  241.          begin
  242.  
  243.             --  if the ancestor part is a subtype mark "T", we generate
  244.             --     _init_proc (T(tmp));
  245.  
  246.             if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
  247.                Insert_Actions (N,
  248.                  Build_Initialization_Call (Loc,
  249.                    Id_Ref       =>
  250.                      Make_Type_Conversion (Loc,
  251.                        Subtype_Mark => New_Occurrence_Of (Entity (A), Loc),
  252.                        Expression   => New_Occurrence_Of (Temp, Loc)),
  253.                    Typ          => Entity (A),
  254.                    In_Init_Proc => Chars (Current_Scope) = Name_uInit_Proc));
  255.  
  256.             --  if the ancestor part is an expression "E", we generate
  257.             --     T(tmp) := E;
  258.  
  259.             else
  260.                Instr :=
  261.                  Make_Assignment_Statement (Loc,
  262.                    Name =>
  263.                      Make_Type_Conversion (Loc,
  264.                        Subtype_Mark => New_Occurrence_Of (Etype (A), Loc),
  265.                        Expression   => New_Occurrence_Of (Temp, Loc)),
  266.                    Expression => A);
  267.                Set_Assignment_OK (Name (Instr));
  268.                Insert_Action (N, Instr);
  269.             end if;
  270.          end;
  271.       end if;
  272.  
  273.       --  Attach the temporary to the final list when needed
  274.  
  275.       if Is_Controlled (Typ) then
  276.          Insert_Action (N,
  277.            Make_Attach_Call (
  278.              Obj_Ref   => New_Occurrence_Of (Temp, Loc),
  279.              Flist_Ref => Find_Final_List (Current_Scope)));
  280.       end if;
  281.  
  282.       --  Generate the assignments, component per component
  283.  
  284.       Comp := First (Component_Associations (N));
  285.       while Present (Comp) loop
  286.          Instr :=
  287.            Make_Assignment_Statement (Loc,
  288.              Name =>
  289.                Make_Selected_Component (Loc,
  290.                  Prefix => New_Occurrence_Of (Temp, Loc),
  291.                   Selector_Name =>
  292.                     New_Occurrence_Of
  293.                       (Entity (First (Choices (Comp))), Loc)),
  294.              Expression => Expression (Comp));
  295.  
  296.          Set_Assignment_OK (Name (Instr));
  297.          Insert_Action (N, Instr);
  298.          Comp := Next (Comp);
  299.       end loop;
  300.  
  301.       --  if the type is tagged, the tag needs to be initialized
  302.  
  303.       if Is_Tagged_Type (Typ) then
  304.  
  305.          Instr :=
  306.            Make_Assignment_Statement (Loc,
  307.              Name =>
  308.                Make_Selected_Component (Loc,
  309.                  Prefix => New_Occurrence_Of (Temp, Loc),
  310.                  Selector_Name =>
  311.                    New_Reference_To (Tag_Component (Base_Type (Typ)), Loc)),
  312.  
  313.              Expression =>
  314.                Make_Unchecked_Type_Conversion (Loc,
  315.                  Subtype_Mark => New_Reference_To (RTE (RE_Tag), Loc),
  316.                  Expression =>
  317.                    New_Reference_To (Access_Disp_Table (Base_Type (Typ)),
  318.                      Loc)));
  319.  
  320.          Set_Assignment_OK (Name (Instr));
  321.          Insert_Action (N, Instr);
  322.       end if;
  323.  
  324.       Rewrite_Substitute_Tree (N, New_Occurrence_Of (Temp, Loc));
  325.       Analyze (N);
  326.       Resolve (N, Typ);
  327.    end Convert_To_Assignments;
  328.  
  329.    ----------------------------------
  330.    -- Expand_N_Extension_Aggregate --
  331.    ----------------------------------
  332.  
  333.    --  If the ancestor part is an expression, add a component association for
  334.    --  the parent field. If the type of the ancestor part is not the direct
  335.    --  parent of the expected type,  build recursively the needed ancestors.
  336.    --  If the ancestor part is a subtype_mark, replace aggregate with a decla-
  337.    --  ration for a temporary of the expected type, followed by individual
  338.    --  assignments to the given components.
  339.  
  340.    procedure Expand_N_Extension_Aggregate (N : Node_Id) is
  341.       Loc : constant Source_Ptr := Sloc  (N);
  342.       A   : constant Node_Id    := Ancestor_Part (N);
  343.       Typ : constant Entity_Id  := Etype (N);
  344.  
  345.    begin
  346.       --  Gigi doesn't handle properly temporaries of variable size
  347.       --  so we generate it in the front-end
  348.  
  349.       if not Size_Known_At_Compile_Time (Typ) then
  350.          Convert_To_Assignments (N, Typ);
  351.  
  352.       --  temporaries for controlled aggregates need to be attached to a
  353.       --  final chain in order to be properly finalized, so it has to
  354.       --  be created in the front-end
  355.  
  356.       elsif Is_Controlled (Typ)
  357.         or else Has_Controlled (Base_Type (Typ))
  358.       then
  359.          Convert_To_Assignments (N, Typ);
  360.  
  361.       --  If the ancestor is a subtype mark, an init_proc must be called
  362.       --  on the resulting object which thus has to be materialized in
  363.       --  the front-end
  364.  
  365.       elsif Is_Entity_Name (A) and then Is_Type (Entity (A)) then
  366.          Convert_To_Assignments (N, Typ);
  367.  
  368.  
  369.       --  The extension aggregate is transformed into a record aggregate
  370.       --  of the following form (c1 and c2 are inherited components)
  371.       --   (Exp with c3 => a, c4 => b)
  372.       --      ==> (c1 => Exp.c1, c2 => Exp.c2, c1 => a, c2 => b)
  373.  
  374.       else
  375.          Rewrite_Substitute_Tree (N,
  376.            Make_Aggregate (Loc,
  377.              Component_Associations => Component_Associations (N)));
  378.  
  379.          Set_Etype (N, Typ);
  380.          Expand_Record_Aggregate (N,
  381.            Orig_Tag    => New_Occurrence_Of (Access_Disp_Table (Typ), Loc),
  382.            Parent_Expr => A);
  383.       end if;
  384.    end Expand_N_Extension_Aggregate;
  385.  
  386.    -----------------------------
  387.    -- Expand_Record_Aggregate --
  388.    -----------------------------
  389.  
  390.    procedure Expand_Record_Aggregate
  391.      (N           : Node_Id;
  392.       Orig_Tag    : Node_Id := Empty;
  393.       Parent_Expr : Node_Id := Empty)
  394.    is
  395.       Loc   : constant Source_Ptr := Sloc  (N);
  396.       Comps : constant List_Id    := Component_Associations (N);
  397.  
  398.       Typ       : Entity_Id  := Etype (N);
  399.       Tag_Value : Node_Id;
  400.       Comp      : Entity_Id;
  401.       New_Comp  : Node_Id;
  402.  
  403.    begin
  404.  
  405.       --  Gigi doesn't handle properly temporaries of variable size
  406.       --  so we generate it in the front-end
  407.  
  408.       if not Size_Known_At_Compile_Time (Typ) then
  409.          Convert_To_Assignments (N, Typ);
  410.  
  411.       --  Temporaries for controlled aggregates need to be attached to a
  412.       --  final chain in order to be properly finalized, so it has to
  413.       --  be created in the front-end
  414.  
  415.       elsif Is_Controlled (Typ)
  416.         or else Has_Controlled (Base_Type (Typ))
  417.       then
  418.          Convert_To_Assignments (N, Typ);
  419.  
  420.       --  in all other cases we generate a proper static aggregate that
  421.       --  can be handled by gigi. In the tagged case, the _parent and
  422.       --  _tag component need to be created
  423.  
  424.       elsif Is_Tagged_Type (Typ) then
  425.  
  426.          --  When the current aggregate comes from the expansion of an
  427.          --  extension aggregate, the parent expr is replaced by an
  428.          --  aggregate formed by selected components of this expr
  429.  
  430.          if Present (Parent_Expr)
  431.            and then Is_Empty_List (Comps) then
  432.  
  433.             Comp := First_Entity (Typ);
  434.             while Present (Comp) loop
  435.  
  436.                --  Skip all entities that are not discriminants or components
  437.  
  438.                if Ekind (Comp) not in Object_Kind then
  439.                   null;
  440.  
  441.                --  Skip all expander-generated components
  442.  
  443.                elsif
  444.                  not Comes_From_Source (Original_Record_Component (Comp))
  445.                then
  446.                   null;
  447.  
  448.                else
  449.                   New_Comp :=
  450.                     Make_Selected_Component (Loc,
  451.                       Prefix =>
  452.                         Make_Unchecked_Type_Conversion (Loc,
  453.                           Subtype_Mark => New_Occurrence_Of (Typ, Loc),
  454.                           Expression   =>
  455.                             Duplicate_Subexpr (Parent_Expr, True)),
  456.  
  457.                       Selector_Name => New_Occurrence_Of (Comp, Loc));
  458.  
  459.                   Append_To (Comps,
  460.                     Make_Component_Association (Loc,
  461.                       Choices    => New_List (New_Occurrence_Of (Comp, Loc)),
  462.                       Expression => New_Comp));
  463.  
  464.                   Analyze (New_Comp);
  465.                   Resolve (New_Comp, Etype (Comp));
  466.                end if;
  467.  
  468.                Comp := Next_Entity (Comp);
  469.             end loop;
  470.          end if;
  471.  
  472.  
  473.          --  Compute the value for the Tag now, if the type is a root it
  474.          --  will be included in the aggregatge right away, othewise it will
  475.          --  be propagated to the parent aggregate
  476.  
  477.          if Present (Orig_Tag) then
  478.             Tag_Value := Orig_Tag;
  479.          else
  480.             Tag_Value := New_Occurrence_Of (Access_Disp_Table (Typ), Loc);
  481.          end if;
  482.  
  483.          --  For a derived type, an aggregate for the parent is formed with
  484.          --  all the inherited components
  485.  
  486.          if Is_Derived_Type (Typ) then
  487.             declare
  488.                First_Comp   : Node_Id;
  489.                Parent_Comps : List_Id;
  490.                Parent_Aggr  : Node_Id;
  491.                Parent_Name  : Node_Id;
  492.  
  493.             begin
  494.  
  495.                --  Remove the inherited component association from the
  496.                --  aggregate and store them in the parent aggregate
  497.  
  498.                First_Comp := First (Component_Associations (N));
  499.                Parent_Comps := New_List;
  500.  
  501.                while Present (First_Comp)
  502.                  and then Scope (Entity (First (Choices (First_Comp)))) /= Typ
  503.                loop
  504.                   Comp := First_Comp;
  505.                   First_Comp := Next (First_Comp);
  506.                   Remove (Comp);
  507.                   Append (Comp, Parent_Comps);
  508.                end loop;
  509.  
  510.                Parent_Aggr := Make_Aggregate (Loc,
  511.                  Component_Associations => Parent_Comps);
  512.                Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));
  513.  
  514.                --  Find the _parent component
  515.  
  516.                Comp := First_Component (Typ);
  517.                while Chars (Comp) /= Name_uParent loop
  518.                   Comp := Next_Component (Comp);
  519.                end loop;
  520.  
  521.                Parent_Name := New_Occurrence_Of (Comp, Loc);
  522.  
  523.                --  Insert the parent aggregate
  524.  
  525.                Prepend_To (Component_Associations (N),
  526.                  Make_Component_Association (Loc,
  527.                    Choices    => New_List (Parent_Name),
  528.                    Expression => Parent_Aggr));
  529.  
  530.                --  Expand recursively the parent propagating the right Tag
  531.  
  532.                Expand_Record_Aggregate (Parent_Aggr, Tag_Value, Parent_Expr);
  533.             end;
  534.  
  535.          --  For a root type, the tag component is added
  536.  
  537.          else
  538.             declare
  539.                Tag_Name  : constant Node_Id
  540.                  := New_Occurrence_Of (Tag_Component (Typ), Loc);
  541.                Typ_Tag   : constant Entity_Id := RTE (RE_Tag);
  542.                Conv_Node : constant Node_Id
  543.                  := Make_Unchecked_Type_Conversion (Loc,
  544.                       Subtype_Mark => New_Occurrence_Of (Typ_Tag, Loc),
  545.                       Expression   => Tag_Value);
  546.  
  547.             begin
  548.                Set_Etype (Conv_Node, Typ_Tag);
  549.                Prepend_To (Component_Associations (N),
  550.                  Make_Component_Association (Loc,
  551.                    Choices    => New_List (Tag_Name),
  552.                    Expression => Conv_Node));
  553.             end;
  554.          end if;
  555.       end if;
  556.    end Expand_Record_Aggregate;
  557.  
  558.    ----------------------------
  559.    -- Expand_Array_Aggregate --
  560.    ----------------------------
  561.  
  562.    procedure Expand_Array_Aggregate (N : Node_Id) is
  563.       Loc : constant Source_Ptr := Sloc (N);
  564.       Typ : constant Entity_Id  := Etype (N);
  565.       --  Typ is the correct constrained array subtype of the aggregate.
  566.  
  567.       Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
  568.       --  Number of aggregate index dimensions.
  569.  
  570.       Tmp : Entity_Id;
  571.       --  Holds the temporary aggregate value.
  572.  
  573.       Tmp_Decl : Node_Id;
  574.       --  Holds the declaration of Tmp.
  575.  
  576.       New_Aggr  : Node_Id;
  577.       Aggr_Code : List_Id;
  578.  
  579.    begin
  580.       --  If during semantic analysis it has been determined that aggreagte N
  581.       --  will raise Constraint_Error at run-time, then the aggregate node
  582.       --  has been replaced with an N_Raise_Constraint_Error node and we
  583.       --  should never get here.
  584.  
  585.       pragma Assert (not Raises_Constraint_Error (N));
  586.  
  587.       --  STEP 1.
  588.  
  589.       --  Aggregate consistency checks and bound evaluations should
  590.       --  be performed here.???
  591.  
  592.       --  STEP 2.
  593.  
  594.       --  ??? For now, static processing is never possible for packed array
  595.       --  ??? aggregates, this must be fixed later on
  596.  
  597.       if Static_Processing_Possible (N, First_Index (Typ))
  598.         and then not Is_Packed (Typ)
  599.       then
  600.          return;
  601.       end if;
  602.  
  603.       --  STEP 3.
  604.  
  605.       --  If the aggregate defines an empty array not much to do
  606.  
  607.       if Is_Empty (Typ) then
  608.          null;  --  ??? FOR NOW
  609.  
  610.       --  then look if in place aggregate expansion is possible
  611.  
  612.       elsif In_Place_Copy_Possible (N, Aggr_Dimension) then
  613.          null;   --  ??? FOR NOW
  614.       end if;
  615.  
  616.       --  If we got here then in place aggregate expansion is impossible.
  617.       --  We need to create a temporary.
  618.  
  619.       --  Create the declaration but don't initialize it by default
  620.  
  621.       Tmp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  622.       Tmp_Decl :=
  623.         Make_Object_Declaration
  624.           (Loc,
  625.            Defining_Identifier => Tmp,
  626.            Object_Definition   => New_Occurrence_Of (Typ, Loc),
  627.            No_Default_Init     => True);
  628.  
  629.       Insert_Action (N, Tmp_Decl);
  630.  
  631.       --  Construct and insert the aggregate code. We can safely suppress
  632.       --  index checks because this code is guaranteed not to raise CE
  633.       --  on index checks. However we should *not* suppress all checks.
  634.  
  635.       Aggr_Code := Build_Code (N, First_Index (Typ), Into => Tmp);
  636.       Insert_Actions (N, Aggr_Code, Suppress => All_Checks);
  637.  
  638.       Rewrite_Substitute_Tree (N, New_Reference_To (Tmp, Loc));
  639.  
  640.       Analyze (N);
  641.       Resolve (N, Typ);
  642.    end Expand_Array_Aggregate;
  643.  
  644.    -----------------------
  645.    -- Number_Of_Choices --
  646.    -----------------------
  647.  
  648.    function Number_Of_Choices (N : Node_Id) return Nat is
  649.       Assoc  : Node_Id;
  650.       Choice : Node_Id;
  651.  
  652.       Nb_Choices : Nat := 0;
  653.  
  654.    begin
  655.       if Present (Expressions (N)) then
  656.          return 0;
  657.       end if;
  658.  
  659.       Assoc := First (Component_Associations (N));
  660.       while Present (Assoc) loop
  661.  
  662.          Choice := First (Choices (Assoc));
  663.          while Present (Choice) loop
  664.  
  665.             if Nkind (Choice) /= N_Others_Choice then
  666.                Nb_Choices := Nb_Choices + 1;
  667.             end if;
  668.  
  669.             Choice := Next (Choice);
  670.          end loop;
  671.  
  672.          Assoc := Next (Assoc);
  673.       end loop;
  674.  
  675.       return Nb_Choices;
  676.    end Number_Of_Choices;
  677.  
  678.    --------------------------------
  679.    -- Static_Processing_Possible --
  680.    --------------------------------
  681.  
  682.    function Static_Processing_Possible
  683.      (N        : Node_Id;
  684.       Index    : Node_Id;
  685.       Max_Size : Pos := System.Parameters.Max_Static_Aggregate_Size)
  686.       return Boolean
  687.    is
  688.       Expr      : Node_Id;
  689.       Size      : Pos;
  690.       Index_Typ : constant Entity_Id := Etype (Index);
  691.  
  692.    begin
  693.       --  No static processing if index subtype is enumeration type with holes
  694.       --  ??? temporary expedient to get some of these aggregates correct
  695.  
  696.       if Is_Enumeration_Type (Index_Typ)
  697.         and then Present (Enum_Pos_To_Rep (Base_Type (Index_Typ)))
  698.       then
  699.          return False;
  700.       end if;
  701.  
  702.       --  If component associations no static processing possible
  703.  
  704.       if Present (Component_Associations (N)) then
  705.          return False;
  706.       end if;
  707.  
  708.       --  Count the number of positional expressions
  709.  
  710.       Expr := First (Expressions (N));
  711.  
  712.       while Present (Expr) loop
  713.          Size := Max_Size - 1;
  714.  
  715.          if Size < 0 then
  716.             return False;
  717.  
  718.          elsif Present (Next_Index (Index)) and then
  719.            not Static_Processing_Possible (Expr, Next_Index (Index), Size)
  720.          then
  721.             return False;
  722.          end if;
  723.  
  724.          Expr := Next (Expr);
  725.       end loop;
  726.  
  727.       return True;
  728.    end Static_Processing_Possible;
  729.  
  730.    --------------
  731.    -- Is_Empty --
  732.    --------------
  733.  
  734.    function Is_Empty (Typ : Entity_Id) return Boolean is
  735.    begin
  736.       return False;
  737.    end Is_Empty;
  738.  
  739.    ----------------------------
  740.    -- In_Place_Copy_Possible --
  741.    ----------------------------
  742.  
  743.    function In_Place_Copy_Possible (N : Node_Id; Dim : Pos) return Boolean is
  744.       function Static_Expression_Not_Raising_CE (E : Node_Id) return Boolean;
  745.       --  Returns true if E is a static expression whose evaluation is
  746.       --  guaranteed not to raise a Constraint_Error.
  747.  
  748.       --------------------------------------
  749.       -- Static_Expression_Not_Raising_CE --
  750.       --------------------------------------
  751.  
  752.       function Static_Expression_Not_Raising_CE (E : Node_Id) return Boolean is
  753.          Typ  : constant Entity_Id := Etype (E);
  754.          Low  : Node_Id;
  755.          High : Node_Id;
  756.  
  757.       begin
  758.          if not Is_OK_Static_Expression (E) then
  759.             return False;
  760.  
  761.          else
  762.             Low  := Type_Low_Bound (Typ);
  763.             High := Type_High_Bound (Typ);
  764.  
  765.             if not Is_OK_Static_Expression (Low)
  766.               or else Is_OK_Static_Expression (High)
  767.             then
  768.                return False;
  769.             end if;
  770.          end if;
  771.       end Static_Expression_Not_Raising_CE;
  772.  
  773.       --  Variables local to In_Place_Copy_Possible
  774.  
  775.       Assoc : Node_Id;
  776.       Expr  : Node_Id;
  777.  
  778.    --  Begin of In_Place_Copy_Possible
  779.  
  780.    begin
  781.       --  ??? For now just return
  782.  
  783.       return False;
  784.  
  785.       --  Process positional components
  786.  
  787.       if Present (Expressions (N)) then
  788.          Expr := First (Expressions (N));
  789.  
  790.          while Present (Expr) loop
  791.             if Dim > 1 and then not In_Place_Copy_Possible (Expr, Dim - 1) then
  792.                return False;
  793.  
  794.             elsif not Static_Expression_Not_Raising_CE (Expr) then
  795.                return False;
  796.             end if;
  797.  
  798.             Expr := Next (Expr);
  799.          end loop;
  800.       end if;
  801.  
  802.       --  Process component associations
  803.  
  804.       if Present (Component_Associations (N)) then
  805.          Assoc := First (Component_Associations (N));
  806.          while Present (Assoc) loop
  807.             Expr := Expression (Assoc);
  808.  
  809.             if Dim > 1 and then not In_Place_Copy_Possible (Expr, Dim - 1) then
  810.                return False;
  811.  
  812.             elsif not Static_Expression_Not_Raising_CE (Expr) then
  813.                return False;
  814.             end if;
  815.  
  816.             Assoc := Next (Assoc);
  817.          end loop;
  818.       end if;
  819.  
  820.       return True;
  821.    end In_Place_Copy_Possible;
  822.  
  823.    ----------------
  824.    -- Build_Code --
  825.    ----------------
  826.  
  827.    function Build_Code
  828.      (N       : Node_Id;
  829.       Index   : Node_Id;
  830.       Into    : Entity_Id;
  831.       Indices : List_Id := No_List)
  832.       return List_Id
  833.    is
  834.       Loc          : constant Source_Ptr := Sloc (N);
  835.       Index_Base   : constant Entity_Id  := Base_Type (Etype (Index));
  836.       Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
  837.       Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);
  838.  
  839.       function Add (Val : Int; To : Node_Id) return Node_Id;
  840.       --  Returns an expression where Val is added to expression To,
  841.       --  unless To+Val is provably out of To's base type range.
  842.       --  To must be an already analyzed expression.
  843.  
  844.       function Empty_Range (L, H : Node_Id) return Boolean;
  845.       --  Returns True if the range defined by L .. H is certainly empty.
  846.  
  847.       function Equal (L, H : Node_Id) return Boolean;
  848.       --  Returns True if L = H for sure.
  849.  
  850.       function Index_Base_Name return Node_Id;
  851.       --  Returns a new reference to the index type name.
  852.  
  853.       function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id;
  854.       --  Ind must be a side-effect free expression.
  855.       --  If the input aggregate N to Build_Loop contains no sub-aggregates,
  856.       --  This routine returns the assignment statement
  857.       --
  858.       --     Into (Indices, Ind) := Expr;
  859.       --
  860.       --  Otherwise we call Build_Code recursively.
  861.  
  862.       function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
  863.       --  Nodes L and H must be side-effect free expressions.
  864.       --  If the input aggregate N to Build_Loop contains no sub-aggregates,
  865.       --  This routine returns the for loop statement
  866.       --
  867.       --     for I in Index_Base range L .. H loop
  868.       --        Into (Indices, I) := Expr;
  869.       --     end loop;
  870.       --
  871.       --  Otherwise we call Build_Code recursively.
  872.  
  873.       function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
  874.       --  Nodes L and H must be side-effect free expressions.
  875.       --  If the input aggregate N to Build_Loop contains no sub-aggregates,
  876.       --  This routine returns the while loop statement
  877.       --
  878.       --     I : Index_Base := L;
  879.       --     while I < H loop
  880.       --        I := Index_Base'Succ (I);
  881.       --        Into (Indices, I) := Expr;
  882.       --     end loop;
  883.       --
  884.       --  Otherwise we call Build_Code recursively.
  885.  
  886.       ---------
  887.       -- Add --
  888.       ---------
  889.  
  890.       function Add (Val : Int; To : Node_Id) return Node_Id is
  891.          Expr_Pos : Node_Id;
  892.          Expr     : Node_Id;
  893.          To_Pos   : Node_Id;
  894.  
  895.          U_To  : Uint;
  896.          U_Val : Uint := UI_From_Int (Val);
  897.  
  898.       begin
  899.          if Val = 0 then
  900.             return Duplicate_Subexpr (To);
  901.          end if;
  902.  
  903.          --  First test if we can do constant folding
  904.  
  905.          if Is_OK_Static_Expression (To) then
  906.             U_To := Expr_Value (To) + Val;
  907.  
  908.             --  Determine if our constant is outside the range of the index.
  909.             --  If so return an Empty node. This empty node will be caught
  910.             --  by Empty_Range below.
  911.  
  912.             if Is_OK_Static_Expression (Index_Base_L)
  913.               and then U_To < Expr_Value (Index_Base_L)
  914.             then
  915.                return Empty;
  916.  
  917.             elsif Is_OK_Static_Expression (Index_Base_H)
  918.               and then U_To > Expr_Value (Index_Base_H)
  919.             then
  920.                return Empty;
  921.             end if;
  922.  
  923.             Expr_Pos := Make_Integer_Literal (Loc, U_To);
  924.  
  925.             if not Is_Enumeration_Type (Index_Base) then
  926.                Expr := Expr_Pos;
  927.  
  928.             --  If we are dealing with enumeration return
  929.             --     Index_Base'Val (Expr_Pos)
  930.  
  931.             else
  932.                Expr :=
  933.                  Make_Attribute_Reference
  934.                    (Loc,
  935.                     Prefix         => Index_Base_Name,
  936.                     Attribute_Name => Name_Val,
  937.                     Expressions    => New_List (Expr_Pos));
  938.             end if;
  939.  
  940.             return Expr;
  941.          end if;
  942.  
  943.          --  If we are here no constant folding possible
  944.  
  945.          if not Is_Enumeration_Type (Index_Base) then
  946.             Expr :=
  947.               Make_Op_Add (Loc,
  948.                            Left_Opnd  => Duplicate_Subexpr (To),
  949.                            Right_Opnd => Make_Integer_Literal (Loc, U_Val));
  950.  
  951.          --  If we are dealing with enumeration return
  952.          --    Index_Base'Val (Index_Base'Pos (To) + Val)
  953.  
  954.          else
  955.             To_Pos :=
  956.               Make_Attribute_Reference
  957.                 (Loc,
  958.                  Prefix         => Index_Base_Name,
  959.                  Attribute_Name => Name_Pos,
  960.                  Expressions    => New_List (Duplicate_Subexpr (To)));
  961.  
  962.             Expr_Pos :=
  963.               Make_Op_Add (Loc,
  964.                            Left_Opnd  => To_Pos,
  965.                            Right_Opnd => Make_Integer_Literal (Loc, U_Val));
  966.  
  967.             Expr :=
  968.               Make_Attribute_Reference
  969.                 (Loc,
  970.                  Prefix         => Index_Base_Name,
  971.                  Attribute_Name => Name_Val,
  972.                  Expressions    => New_List (Expr_Pos));
  973.          end if;
  974.  
  975.          return Expr;
  976.       end Add;
  977.  
  978.       -----------------
  979.       -- Empty_Range --
  980.       -----------------
  981.  
  982.       function Empty_Range (L, H : Node_Id) return Boolean is
  983.          Is_Empty : Boolean := False;
  984.          Low      : Node_Id;
  985.          High     : Node_Id;
  986.  
  987.       begin
  988.          --  First check if L or H were already detected as overflowing the
  989.          --  index base range type by function Add above. If this is so Add
  990.          --  returns the empty node.
  991.  
  992.          if No (L) or else No (H) then
  993.             return True;
  994.          end if;
  995.  
  996.          for I in 1 .. 3 loop
  997.             case I is
  998.                --  L > H    range is empty
  999.  
  1000.                when 1 =>
  1001.                   Low  := L;
  1002.                   High := H;
  1003.  
  1004.                --  B_L > H  range must be empty
  1005.  
  1006.                when 2 =>
  1007.                   Low  := Index_Base_L;
  1008.                   High := H;
  1009.  
  1010.                --  L > B_H  range must be empty
  1011.  
  1012.                when 3 =>
  1013.                   Low  := L;
  1014.                   High := Index_Base_H;
  1015.             end case;
  1016.  
  1017.             if Is_OK_Static_Expression (Low)
  1018.               and then Is_OK_Static_Expression (High)
  1019.             then
  1020.                Is_Empty := UI_Gt (Expr_Value (Low), Expr_Value (High));
  1021.             end if;
  1022.  
  1023.             exit when Is_Empty;
  1024.          end loop;
  1025.  
  1026.          return Is_Empty;
  1027.       end Empty_Range;
  1028.  
  1029.       -----------
  1030.       -- Equal --
  1031.       -----------
  1032.  
  1033.       function Equal (L, H : Node_Id) return Boolean is
  1034.       begin
  1035.          if L = H then
  1036.             return True;
  1037.  
  1038.          elsif Is_OK_Static_Expression (L)
  1039.            and then Is_OK_Static_Expression (H)
  1040.          then
  1041.             return UI_Eq (Expr_Value (L), Expr_Value (H));
  1042.          end if;
  1043.  
  1044.          return False;
  1045.       end Equal;
  1046.  
  1047.       ---------------------
  1048.       -- Index_Base_Name --
  1049.       ---------------------
  1050.  
  1051.       function Index_Base_Name return Node_Id is
  1052.       begin
  1053.          return New_Reference_To (Index_Base, Sloc (N));
  1054.       end Index_Base_Name;
  1055.  
  1056.       ----------------
  1057.       -- Gen_Assign --
  1058.       ----------------
  1059.  
  1060.       function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id is
  1061.          A : Node_Id;
  1062.          L : List_Id;
  1063.  
  1064.          New_Indices  : List_Id;
  1065.          Indexed_Comp : Node_Id;
  1066.  
  1067.       begin
  1068.          if No (Indices) then
  1069.             New_Indices := New_List;
  1070.          else
  1071.             New_Indices := New_List_Copy_Tree (Indices);
  1072.          end if;
  1073.  
  1074.          Append_To (New_Indices, Ind);
  1075.  
  1076.          if Present (Next_Index (Index)) then
  1077.             return Build_Code (Expr, Next_Index (Index), Into, New_Indices);
  1078.          end if;
  1079.  
  1080.          --  If we get here then we are at a bottom-level (sub-)aggregate
  1081.  
  1082.          Indexed_Comp :=
  1083.            Make_Indexed_Component (Loc,
  1084.                                    Prefix      => New_Reference_To (Into, Loc),
  1085.                                    Expressions => New_Indices);
  1086.  
  1087.          A := Make_Assignment_Statement (Loc,
  1088.                                          Name       => Indexed_Comp,
  1089.                                          Expression => New_Copy_Tree (Expr));
  1090.          L := New_List;
  1091.          Append_To (L, A);
  1092.          return L;
  1093.       end Gen_Assign;
  1094.  
  1095.       --------------
  1096.       -- Gen_Loop --
  1097.       --------------
  1098.  
  1099.       function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
  1100.          --  The loop built is
  1101.          --     for L_I in Index_Base range L .. H loop
  1102.          --        L_Body;
  1103.          --     end loop;
  1104.  
  1105.          L_I : Node_Id;
  1106.  
  1107.          L_Range : Node_Id;
  1108.          --  L .. H
  1109.  
  1110.          L_Discrete_Subtype_Def : Node_Id;
  1111.          --  Index_Base range L .. H
  1112.  
  1113.          L_Iteration_Scheme : Node_Id;
  1114.          --  L_I in Index_Base range L .. H
  1115.  
  1116.          L_Body : List_Id;
  1117.          --  The statements to execute in the loop
  1118.  
  1119.          S : List_Id := New_List;
  1120.          --  list of statement
  1121.  
  1122.       begin
  1123.          --  If loop bounds define an empty range return the null statement
  1124.  
  1125.          if Empty_Range (L, H) then
  1126.             Append_To (S, Make_Null_Statement (Loc));
  1127.             return S;
  1128.          end if;
  1129.  
  1130.          --  If loop bounds are the same then generate an assignment
  1131.  
  1132.          if Equal (L, H) then
  1133.             return Gen_Assign (New_Copy_Tree (L), Expr);
  1134.          end if;
  1135.  
  1136.          --  construct the loop index L_I
  1137.  
  1138.          L_I := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
  1139.  
  1140.          --  contruct "L .. H"
  1141.  
  1142.          L_Range := Make_Range (Loc, Low_Bound => L, High_Bound => H);
  1143.  
  1144.          --  construct "Index_Base range in  L .. H"
  1145.  
  1146.          L_Discrete_Subtype_Def :=
  1147.            Make_Subtype_Indication
  1148.              (Loc,
  1149.               Subtype_Mark => Index_Base_Name,
  1150.               Constraint   => Make_Range_Constraint (Loc, L_Range));
  1151.  
  1152.          --  construct "for L_I in Index_Base range in  L .. H"
  1153.  
  1154.          L_Iteration_Scheme :=
  1155.            Make_Iteration_Scheme
  1156.              (Loc,
  1157.               Loop_Parameter_Specification =>
  1158.                 Make_Loop_Parameter_Specification
  1159.                   (Loc,
  1160.                    Defining_Identifier         => L_I,
  1161.                    Discrete_Subtype_Definition => L_Discrete_Subtype_Def));
  1162.  
  1163.          --  Construct the statements to execute in the loop body
  1164.  
  1165.          L_Body := Gen_Assign (New_Reference_To (L_I, Loc), Expr);
  1166.  
  1167.          --  construct the final loop
  1168.  
  1169.          Append_To (S, Make_Loop_Statement
  1170.                          (Loc,
  1171.                           Identifier       => Empty,
  1172.                           Iteration_Scheme => L_Iteration_Scheme,
  1173.                           Statements       => L_Body));
  1174.  
  1175.          return S;
  1176.       end Gen_Loop;
  1177.  
  1178.       ---------------
  1179.       -- Gen_While --
  1180.       ---------------
  1181.  
  1182.       function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
  1183.          --  The code built is
  1184.          --     W_I : Index_Base := L;
  1185.          --     while W_I < H loop
  1186.          --        W_I := Index_Base'Succ (W);
  1187.          --        L_Body;
  1188.          --     end loop;
  1189.  
  1190.          W_I : Node_Id;
  1191.  
  1192.          W_Decl : Node_Id;
  1193.          --  W_I : Base_Type := L;
  1194.  
  1195.          W_Iteration_Scheme : Node_Id;
  1196.          --  while W_I < H
  1197.  
  1198.          W_Index_Succ : Node_Id;
  1199.          --  Index_Base'Succ (I)
  1200.  
  1201.          W_Increment  : Node_Id;
  1202.          --  W_I := Index_Base'Succ (W)
  1203.  
  1204.          W_Body : List_Id := New_List;
  1205.          --  The statements to execute in the loop
  1206.  
  1207.          S : List_Id := New_List;
  1208.          --  list of statement
  1209.  
  1210.       begin
  1211.          --  If loop bounds define an empty range or are equal return null
  1212.  
  1213.          if Empty_Range (L, H) or else Equal (L, H) then
  1214.             Append_To (S, Make_Null_Statement (Loc));
  1215.             return S;
  1216.          end if;
  1217.  
  1218.          --  Build the decl of W_I
  1219.  
  1220.          W_I    := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
  1221.          W_Decl :=
  1222.            Make_Object_Declaration
  1223.              (Loc,
  1224.               Defining_Identifier => W_I,
  1225.               Object_Definition   => Index_Base_Name,
  1226.               Expression          => L);
  1227.          --  Theoretically we should do a New_Copy_Tree (L) here, but we know
  1228.          --  that in this particular case L is a fresh Expr generated by
  1229.          --  Add which we are the only ones to use.
  1230.  
  1231.          Append_To (S, W_Decl);
  1232.  
  1233.          --  construct " while W_I < H"
  1234.  
  1235.          W_Iteration_Scheme :=
  1236.            Make_Iteration_Scheme
  1237.              (Loc,
  1238.               Condition => Make_Op_Lt
  1239.                              (Loc,
  1240.                               Left_Opnd  => New_Reference_To (W_I, Loc),
  1241.                               Right_Opnd => New_Copy_Tree (H)));
  1242.  
  1243.          --  Construct the statements to execute in the loop body
  1244.  
  1245.          W_Index_Succ :=
  1246.            Make_Attribute_Reference
  1247.              (Loc,
  1248.               Prefix         => Index_Base_Name,
  1249.               Attribute_Name => Name_Succ,
  1250.               Expressions    => New_List (New_Reference_To (W_I, Loc)));
  1251.  
  1252.          W_Increment  :=
  1253.            Make_Assignment_Statement
  1254.              (Loc,
  1255.               Name       => New_Reference_To (W_I, Loc),
  1256.               Expression => W_Index_Succ);
  1257.  
  1258.          Append_To (W_Body, W_Increment);
  1259.          Append_List_To (W_Body, Gen_Assign (New_Reference_To (W_I, Loc),
  1260.                                              Expr));
  1261.  
  1262.          --  construct the final loop
  1263.  
  1264.          Append_To (S, Make_Loop_Statement
  1265.                          (Loc,
  1266.                           Identifier       => Empty,
  1267.                           Iteration_Scheme => W_Iteration_Scheme,
  1268.                           Statements       => W_Body));
  1269.  
  1270.          return S;
  1271.       end Gen_While;
  1272.  
  1273.       --  Build_Code Variables
  1274.  
  1275.       Assoc  : Node_Id;
  1276.       Choice : Node_Id;
  1277.       Expr   : Node_Id;
  1278.  
  1279.       Others_Expr : Node_Id   := Empty;
  1280.  
  1281.       Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
  1282.       Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
  1283.       --  The aggregate bounds of this specific sub-aggregate.
  1284.       --  Note that if the code generated by Build_Code is executed then these
  1285.       --  bouds are OK. Otherwise a Constraint_Error would have been raised.
  1286.  
  1287.       Aggr_Low  : constant Node_Id := Duplicate_Subexpr (Aggr_L);
  1288.       Aggr_High : constant Node_Id := Duplicate_Subexpr (Aggr_H);
  1289.       --  After Duplicate_Subexpr these are side-effect free.
  1290.  
  1291.       Low  : Node_Id;
  1292.       High : Node_Id;
  1293.  
  1294.       Nb_Choices : Nat := 0;
  1295.       Table      : Case_Table_Type (1 .. Number_Of_Choices (N));
  1296.       --  Used to sort all the different choice values
  1297.  
  1298.       Nb_Elements : Int;
  1299.       --  Number of elements in the positional aggegate
  1300.  
  1301.       New_Code : List_Id := New_List;
  1302.  
  1303.    --  Build_Code begins here
  1304.  
  1305.    begin
  1306.       --  STEP 1: Process component associations
  1307.  
  1308.       if No (Expressions (N)) then
  1309.  
  1310.          --  STEP 1 (A): Sort the discrete choices
  1311.  
  1312.          Assoc := First (Component_Associations (N));
  1313.          while Present (Assoc) loop
  1314.  
  1315.             Choice := First (Choices (Assoc));
  1316.             while Present (Choice) loop
  1317.  
  1318.                if Nkind (Choice) = N_Others_Choice then
  1319.                   Others_Expr := Expression (Assoc);
  1320.                   exit;
  1321.                end if;
  1322.  
  1323.                Get_Index_Bounds (Choice, Low, High);
  1324.  
  1325.                Nb_Choices := Nb_Choices + 1;
  1326.                Table (Nb_Choices) := (Choice_Lo   => Low,
  1327.                                       Choice_Hi   => High,
  1328.                                       Choice_Node => Expression (Assoc));
  1329.  
  1330.                Choice := Next (Choice);
  1331.             end loop;
  1332.  
  1333.             Assoc := Next (Assoc);
  1334.          end loop;
  1335.  
  1336.          --  If there is more than one set of choices these must be static
  1337.          --  and we can therefore sort them. Remeber that Nb_Choices does not
  1338.          --  account for an others choice.
  1339.  
  1340.          if Nb_Choices > 1 then
  1341.             Sort_Case_Table (Table);
  1342.          end if;
  1343.  
  1344.          --  STEP 1 (B):  take care of the whole set of discrete choices.
  1345.  
  1346.          for I in 1 .. Nb_Choices loop
  1347.             Low  := Table (I).Choice_Lo;
  1348.             High := Table (I).Choice_Hi;
  1349.             Expr := Table (I).Choice_Node;
  1350.  
  1351.             Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
  1352.          end loop;
  1353.  
  1354.          --  STEP 1 (D): generate the remaning loops to cover others choice
  1355.  
  1356.          if Present (Others_Expr) then
  1357.             for I in 0 .. Nb_Choices loop
  1358.                if I = 0 then
  1359.                   Low := Aggr_Low;
  1360.                else
  1361.                   Low := Add (1, To => Table (I).Choice_Hi);
  1362.                end if;
  1363.  
  1364.                if I = Nb_Choices then
  1365.                   High := Aggr_High;
  1366.                else
  1367.                   High := Add (-1, To => Table (I + 1).Choice_Lo);
  1368.                end if;
  1369.  
  1370.                Append_List (Gen_Loop (Low, High, Others_Expr), To => New_Code);
  1371.             end loop;
  1372.          end if;
  1373.  
  1374.       --  STEP 2: Process positional components
  1375.  
  1376.       else
  1377.          --  STEP 2 (A): Generate the assignments for each positional element
  1378.          --  Note that here we have to use Aggr_L rather than Aggr_Low because
  1379.          --  Aggr_L is analyzed and Add wants an analyzed expression.
  1380.  
  1381.          Expr        := First (Expressions (N));
  1382.          Nb_Elements := -1;
  1383.  
  1384.          while Present (Expr) loop
  1385.             Nb_Elements := Nb_Elements + 1;
  1386.             Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
  1387.                          To => New_Code);
  1388.             Expr := Next (Expr);
  1389.          end loop;
  1390.  
  1391.          --  STEP 2 (B): Generate final loop if an others choice is present
  1392.          --  Here Nb_Elements gives the offset of the last positional element.
  1393.  
  1394.          if Present (Component_Associations (N)) then
  1395.             Assoc := Last (Component_Associations (N));
  1396.             Expr  := Expression (Assoc);
  1397.  
  1398.             Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
  1399.                                     Aggr_High,
  1400.                                     Expr),
  1401.                          To => New_Code);
  1402.          end if;
  1403.       end if;
  1404.  
  1405.       return New_Code;
  1406.    end Build_Code;
  1407.  
  1408. end Exp_Aggr;
  1409.