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 / sem_eval.adb < prev    next >
Text File  |  1996-09-28  |  68KB  |  2,108 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                             S E M _ E V A L                              --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.158 $                            --
  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 Checks;   use Checks;
  27. with Einfo;    use Einfo;
  28. with Elists;   use Elists;
  29. with Errout;   use Errout;
  30. with Namet;    use Namet;
  31. with Nmake;    use Nmake;
  32. with Nlists;   use Nlists;
  33. with Opt;      use Opt;
  34. with Output;   use Output;
  35. with Sem;      use Sem;
  36. with Sem_Dist; use Sem_Dist;
  37. with Sem_Res;  use Sem_Res;
  38. with Sem_Util; use Sem_Util;
  39. with Sinfo;    use Sinfo;
  40. with Stand;    use Stand;
  41. with Stringt;  use Stringt;
  42. with Tbuild;   use Tbuild;
  43.  
  44. package body Sem_Eval is
  45.  
  46.    -----------------------------------------
  47.    -- Handling of Compile Time Evaluation --
  48.    -----------------------------------------
  49.  
  50.    --  The compile time evaluation of expressions is distributed over several
  51.    --  Eval_xxx procedures. These procedures are called immediatedly after
  52.    --  a subexpression is resolved and is therefore accomplished in a bottom
  53.    --  up fashion. The flags are synthesized using the following approach.
  54.  
  55.    --    Is_Static_Expression is determined by following the detailed rules
  56.    --    in RM 4.9(4-14). This involves testing the Is_Static_Expression
  57.    --    flag of the operands in many cases.
  58.  
  59.    --    Raises_Constraint_Error is set if any of the operands have the flag
  60.    --    set or if an attempt to compute the value of the current expression
  61.    --    results in detection of a runtime constraint error.
  62.  
  63.    --  As described in the spec, the requirement is that Is_Static_Expression
  64.    --  be accurately set, and in addition for nodes for which this flag is set,
  65.    --  Raises_Constraint_Error must also be set. Furthermore a node which has
  66.    --  Is_Static_Expression set, and Raises_Constraint_Error clear, then the
  67.    --  requirement is that the expression value must be precomputed, and the
  68.    --  node is either a literal, or the name of a constant entity whose value
  69.    --  is a static expression.
  70.  
  71.    --  The general approach is as follows. First compute Is_Static_Expression.
  72.    --  If the node is not static, then the flag is left off in the node and
  73.    --  we are all done. Otherwise for a static node, we test if any of the
  74.    --  operands will raise constraint error, and if so, propagate the flag
  75.    --  Raises_Constraint_Error to the result node and we are done (since the
  76.    --  error was already posted at a lower level).
  77.  
  78.    --  For the case of a static node whose operands do not raise constraint
  79.    --  error, we attempt to evaluate the node. If this evaluation succeeds,
  80.    --  then the node is replaced by the result of this computation. If the
  81.    --  evaluation raises constraint error, then Compile_Time_Constraint_Error
  82.    --  is used to rewrite the node to raise the exception and also to post
  83.    --  appropriate error messages.
  84.  
  85.    ----------------
  86.    -- Local Data --
  87.    ----------------
  88.  
  89.    type Bits is array (Nat range <>) of Boolean;
  90.    --  Used to convert unsigned (modular) values for folding logical ops
  91.  
  92.    -----------------------
  93.    -- Local Subprograms --
  94.    -----------------------
  95.  
  96.    function Expression_Is_Foldable
  97.      (N    : Node_Id;
  98.       Op1  : Node_Id)
  99.       return Boolean;
  100.    --  Returns True if operation N whose single operand is Op1 is foldable,
  101.    --  i.e. Op1 has Is_Static_Expression True, and Raises_Constraint_Error
  102.    --  False. In this case the Is_Static_Expression flag on N is set. If
  103.    --  these conditions are not met, then False is returned, and the
  104.    --  Is_Static_Expression and Raises_Constraint_Error flags are set
  105.    --  appropriately in N. If the result is non-static, then a call is
  106.    --  made to Check_Non_Static_Context on the operand. If False is
  107.    --  returned, then all processing is complete, and the caller should
  108.    --  return, since there is nothing else to do.
  109.  
  110.    function Expression_Is_Foldable
  111.      (N    : Node_Id;
  112.       Op1  : Node_Id;
  113.       Op2  : Node_Id)
  114.       return Boolean;
  115.    --  Returns True if operation N, whose two operands are Op1 and Op2,
  116.    --  is foldable, i.e. if both operands have Is_Static_Expression set
  117.    --  and neither has Raises_Constraint_Error set. In this case, the
  118.    --  Is_Static_Expression flag is set on N. In all other cases, False
  119.    --  is returned, and the Is_Static_Expression and Raises_Constraint_Error
  120.    --  flags are set appropriately in N. If the result is non-static, then
  121.    --  calls are made to Check_Non_Static_Context on the operands. If False
  122.    --  is returned, then all processing is complete, and the caller should
  123.    --  return, since there is nothing else to do.
  124.  
  125.    function From_Bits (B : Bits; T : Entity_Id) return Uint;
  126.    --  Converts a bit string of length B'Length to a Uint value to be used
  127.    --  for a target of type T, which is a modular type. This procedure
  128.    --  includes the necessary reduction by the modulus in the case of a
  129.    --  non-binary modulus (for a binary modulus, the bit string is the
  130.    --  right length any way so all is well).
  131.  
  132.    function Get_String_Val (N : Node_Id) return Node_Id;
  133.    --  Given a tree node for a folded string or character value, returns
  134.    --  the corresponding string literal or character literal (one of the
  135.    --  two must be available, or the operand would not have been marked
  136.    --  as folded in the earlier analysis of the operands).
  137.  
  138.    function Test (Cond : Boolean) return Uint;
  139.    pragma Inline (Test);
  140.    --  This function simply returns the appropriate Boolean'Pos value
  141.    --  corresponding to the value of Cond as a universal integer. It is
  142.    --  used for producing the result of the static evaluation of the
  143.    --  logical operators
  144.  
  145.    procedure To_Bits (U : Uint; B : out Bits);
  146.    --  Converts a Uint value to a bit string of length B'Length
  147.  
  148.    ------------------------------
  149.    -- Check_Non_Static_Context --
  150.    ------------------------------
  151.  
  152.    procedure Check_Non_Static_Context (N : Node_Id) is
  153.       T : Entity_Id := Etype (N);
  154.  
  155.    begin
  156.       --  We need the check only for static expressions not raising CE
  157.       --  We can also ignore cases in which the type is Any_Type
  158.  
  159.       if not Is_OK_Static_Expression (N)
  160.         or else Etype (N) = Any_Type
  161.       then
  162.          return;
  163.  
  164.       --  Skip this check for non-scalar expressions
  165.  
  166.       elsif not Is_Scalar_Type (T) then
  167.          return;
  168.  
  169.       --  Check is required
  170.  
  171.       else
  172.          --  Case of outside base range
  173.  
  174.          if Is_Out_Of_Range (N, Base_Type (T)) then
  175.             Compile_Time_Constraint_Error (N, "value not in range of}");
  176.  
  177.          --  Give warning if outside subtype (where one or both of the
  178.          --  bounds of the subtype is static). This warning is omitted
  179.          --  if the expression appears in a range that could be null
  180.          --  (warnings are handled elsewhere for this case).
  181.  
  182.          elsif T /= Base_Type (T)
  183.            and then Is_Out_Of_Range (N, T)
  184.            and then Nkind (Parent (N)) /= N_Range
  185.          then
  186.             Compile_Time_Constraint_Error (N, "value not in range of}?");
  187.          end if;
  188.  
  189.       end if;
  190.    end Check_Non_Static_Context;
  191.  
  192.    -----------------
  193.    -- Eval_Actual --
  194.    -----------------
  195.  
  196.    --  This is only called for actuals of functions that are not predefined
  197.    --  operators (which have already been rewritten as operators at this
  198.    --  stage), so the call can never be folded, and all that needs doing for
  199.    --  the actual is to do the check for a non-static context.
  200.  
  201.    procedure Eval_Actual (N : Node_Id) is
  202.    begin
  203.       Check_Non_Static_Context (N);
  204.    end Eval_Actual;
  205.  
  206.    --------------------
  207.    -- Eval_Aggregate --
  208.    --------------------
  209.  
  210.    procedure Eval_Aggregate (N : Node_Id) is
  211.    begin
  212.       null;          --  ???
  213.    end Eval_Aggregate;
  214.  
  215.    --------------------
  216.    -- Eval_Allocator --
  217.    --------------------
  218.  
  219.    --  Allocators are never static, so all we have to do is to do the
  220.    --  check for a non-static context if an expression is present.
  221.  
  222.    procedure Eval_Allocator (N : Node_Id) is
  223.       Expr : constant Node_Id := Expression (N);
  224.  
  225.    begin
  226.       if Nkind (Expr) = N_Qualified_Expression then
  227.          Check_Non_Static_Context (Expression (Expr));
  228.       end if;
  229.    end Eval_Allocator;
  230.  
  231.    ------------------------
  232.    -- Eval_Arithmetic_Op --
  233.    ------------------------
  234.  
  235.    --  Arithmetic operations are static functions, so the result is static
  236.    --  if both operands are static (RM 4.9(7), 4.9(20)).
  237.  
  238.    procedure Eval_Arithmetic_Op (N : Node_Id) is
  239.       Left  : constant Node_Id   := Left_Opnd (N);
  240.       Right : constant Node_Id   := Right_Opnd (N);
  241.       Ltype : constant Entity_Id := Etype (Left);
  242.       Rtype : constant Entity_Id := Etype (Right);
  243.  
  244.    begin
  245.       --  If not foldable we are done
  246.  
  247.       if not Expression_Is_Foldable (N, Left, Right) then
  248.          return;
  249.       end if;
  250.  
  251.       --  Fold for cases where both operands are of integer type
  252.  
  253.       if Is_Integer_Type (Ltype) and then Is_Integer_Type (Rtype) then
  254.          declare
  255.             Left_Int  : constant Uint := Expr_Value (Left);
  256.             Right_Int : constant Uint := Expr_Value (Right);
  257.             Result    : Uint;
  258.  
  259.          begin
  260.             case Nkind (N) is
  261.  
  262.                when N_Op_Add =>
  263.                   Result := Left_Int + Right_Int;
  264.  
  265.                when N_Op_Subtract =>
  266.                   Result := Left_Int - Right_Int;
  267.  
  268.                when N_Op_Multiply =>
  269.                   Result := Left_Int * Right_Int;
  270.  
  271.                when N_Op_Divide =>
  272.  
  273.                   --  The exception Constraint_Error is raised by integer
  274.                   --  division, rem and mod if the right operand is zero.
  275.  
  276.                   if Right_Int = 0 then
  277.                      Compile_Time_Constraint_Error (N, "division by zero");
  278.                      return;
  279.                   else
  280.                      Result := Left_Int / Right_Int;
  281.                   end if;
  282.  
  283.                when N_Op_Mod =>
  284.  
  285.                   --  The exception Constraint_Error is raised by integer
  286.                   --  division, rem and mod if the right operand is zero.
  287.  
  288.                   if Right_Int = 0 then
  289.                      Compile_Time_Constraint_Error
  290.                        (N, "mod with zero divisor");
  291.                      return;
  292.                   else
  293.                      Result := Left_Int mod Right_Int;
  294.                   end if;
  295.  
  296.                when N_Op_Rem =>
  297.  
  298.                   --  The exception Constraint_Error is raised by integer
  299.                   --  division, rem and mod if the right operand is zero.
  300.  
  301.                   if Right_Int = 0 then
  302.                      Compile_Time_Constraint_Error
  303.                        (N, "rem with zero divisor");
  304.                      return;
  305.                   else
  306.                      Result := Left_Int rem Right_Int;
  307.                   end if;
  308.  
  309.                when others =>
  310.                   pragma Assert (False); null;
  311.             end case;
  312.  
  313.             --  Adjust the result by the modulus if the type is a modular type
  314.  
  315.             if Is_Modular_Integer_Type (Ltype) then
  316.                Result := Result mod Modulus (Ltype);
  317.             end if;
  318.  
  319.             Fold_Uint (N, Result);
  320.          end;
  321.  
  322.       --  Cases where at least one operand is a real. We handle the cases
  323.       --  of both reals, or mixed/real integer cases (the latter happen
  324.       --  only for divide and multiply, and the result is always real).
  325.  
  326.       elsif Is_Real_Type (Ltype) or else Is_Real_Type (Rtype) then
  327.          declare
  328.             Left_Real  : Ureal;
  329.             Right_Real : Ureal;
  330.             Result     : Ureal;
  331.  
  332.          begin
  333.             if Is_Real_Type (Ltype) then
  334.                Left_Real := Expr_Value_R (Left);
  335.             else
  336.                Left_Real := UR_From_Uint (Expr_Value (Left));
  337.             end if;
  338.  
  339.             if Is_Real_Type (Rtype) then
  340.                Right_Real := Expr_Value_R (Right);
  341.             else
  342.                Right_Real := UR_From_Uint (Expr_Value (Right));
  343.             end if;
  344.  
  345.             if Nkind (N) = N_Op_Add then
  346.                Result := Left_Real + Right_Real;
  347.  
  348.             elsif Nkind (N) = N_Op_Subtract then
  349.                Result := Left_Real - Right_Real;
  350.  
  351.             elsif Nkind (N) = N_Op_Multiply then
  352.                Result := Left_Real * Right_Real;
  353.  
  354.             elsif Nkind (N) = N_Op_Divide then
  355.                if UR_Is_Zero (Right_Real) then
  356.                   Compile_Time_Constraint_Error (N, "division by zero");
  357.                   return;
  358.                end if;
  359.  
  360.                Result := Left_Real / Right_Real;
  361.  
  362.             else
  363.                pragma Assert (False); null;
  364.             end if;
  365.  
  366.             Fold_Ureal (N, Result);
  367.          end;
  368.       end if;
  369.  
  370.    end Eval_Arithmetic_Op;
  371.  
  372.    ----------------------------
  373.    -- Eval_Character_Literal --
  374.    ----------------------------
  375.  
  376.    --  Nothing to be done!
  377.  
  378.    procedure Eval_Character_Literal (N : Node_Id) is
  379.    begin
  380.       null;
  381.    end Eval_Character_Literal;
  382.  
  383.    ------------------------
  384.    -- Eval_Concatenation --
  385.    ------------------------
  386.  
  387.    --  Concatenation is a a static functions, so the result is static if
  388.    --  both operands are static (RM 4.9(7), 4.9(21)).
  389.  
  390.    procedure Eval_Concatenation (N : Node_Id) is
  391.       Left  : constant Node_Id := Left_Opnd (N);
  392.       Right : constant Node_Id := Right_Opnd (N);
  393.  
  394.    begin
  395.       --  Concatenation is never static in Ada 83, so if Ada 83
  396.       --  check operand non-static context
  397.  
  398.       if Ada_83
  399.         and then Comes_From_Source (N)
  400.       then
  401.          Check_Non_Static_Context (Left);
  402.          Check_Non_Static_Context (Right);
  403.          return;
  404.       end if;
  405.  
  406.       --  If not foldable we are done
  407.  
  408.       if not Expression_Is_Foldable (N, Left, Right) then
  409.          return;
  410.       end if;
  411.  
  412.       --  Compile time string concatenation. Note that operands that are
  413.       --  aggregates were never marked as static, so we don't attempt
  414.       --  to fold concatenations with such aggregates (see Eval_Aggregate).
  415.       --  Needs some more thought ???
  416.  
  417.       declare
  418.          Left_Str  : constant Node_Id := Get_String_Val (Left);
  419.          Right_Str : constant Node_Id := Get_String_Val (Right);
  420.  
  421.       begin
  422.          --  Establish new string literal, and store left operand. We make
  423.          --  sure to use the special Start_String that takes an operand if
  424.          --  the left operand is a string literal. Since this is optimized
  425.          --  in the case where that is the most recently created string
  426.          --  literal, we ensure efficient time/space behavior for the
  427.          --  case of a concatenation of a series of string literals.
  428.  
  429.          if Nkind (Left_Str) = N_String_Literal then
  430.             Start_String (Strval (Left_Str));
  431.          else
  432.             Start_String;
  433.             Store_String_Char (Char_Literal_Value (Left_Str));
  434.          end if;
  435.  
  436.          --  Now append the characters of the right operand
  437.  
  438.          if Nkind (Right_Str) = N_String_Literal then
  439.             declare
  440.                S : constant String_Id := Strval (Right_Str);
  441.  
  442.             begin
  443.                for J in 1 .. String_Length (S) loop
  444.                   Store_String_Char (Get_String_Char (S, J));
  445.                end loop;
  446.             end;
  447.          else
  448.             Store_String_Char (Char_Literal_Value (Right_Str));
  449.          end if;
  450.  
  451.          Fold_Str (N, End_String);
  452.       end;
  453.    end Eval_Concatenation;
  454.  
  455.    ---------------------------------
  456.    -- Eval_Conditional_Expression --
  457.    ---------------------------------
  458.  
  459.    --  This GNAT internal construct can never be statically folded, so the
  460.    --  only required processing is to do the check for non-static context
  461.    --  for the two expression operands.
  462.  
  463.    procedure Eval_Conditional_Expression (N : Node_Id) is
  464.       Condition : constant Node_Id := First (Expressions (N));
  465.       Then_Expr : constant Node_Id := Next (Condition);
  466.       Else_Expr : constant Node_Id := Next (Then_Expr);
  467.  
  468.    begin
  469.       Check_Non_Static_Context (Then_Expr);
  470.       Check_Non_Static_Context (Else_Expr);
  471.    end Eval_Conditional_Expression;
  472.  
  473.    ----------------------
  474.    -- Eval_Entity_Name --
  475.    ----------------------
  476.  
  477.    --  This procedure is used for identifiers and expanded names other than
  478.    --  named numbers (see Eval_Named_Integer, Eval_Named_Real. These are
  479.    --  static if they denote a static constant (RM 4.9(6)) or if the name
  480.    --  denotes an enumeration literal (RM 4.9(22)).
  481.  
  482.    procedure Eval_Entity_Name (N : Node_Id) is
  483.       Def_Id    : constant Entity_Id := Entity (N);
  484.       Val       : Node_Id;
  485.  
  486.    begin
  487.       --  Enumeration literals are always considered to be constants
  488.       --  and cannot raise constraint error (RM 4.9(22)).
  489.  
  490.       if Ekind (Def_Id) = E_Enumeration_Literal then
  491.          Set_Is_Static_Expression (N);
  492.          return;
  493.  
  494.       --  A name is static if it denotes a static constant (RM 4.9(5)), and
  495.       --  we also copy Raise_Constraint_Error. Notice that even if non-static,
  496.       --  it does not violate 10.2.1(8) here, since this is not a variable.
  497.  
  498.       elsif Ekind (Def_Id) = E_Constant then
  499.          Val := Constant_Value (Def_Id);
  500.  
  501.          if Present (Val) then
  502.             Set_Is_Static_Expression    (N, Is_Static_Expression (Val));
  503.             Set_Raises_Constraint_Error (N, Raises_Constraint_Error (Val));
  504.             return;
  505.          end if;
  506.       end if;
  507.  
  508.       --  Fall through if the name is not static.
  509.  
  510.       --  In the elaboration code of a preelaborated library unit, check
  511.       --  that we do not have the evaluation of a primary that is a name of
  512.       --  an object, unless the name is a static expression (RM 10.2.1(8)).
  513.  
  514.       Validate_Static_Object_Name (N);
  515.  
  516.    end Eval_Entity_Name;
  517.  
  518.    ----------------------------
  519.    -- Eval_Indexed_Component --
  520.    ----------------------------
  521.  
  522.    --  Indexed components are never static, so the only required processing
  523.    --  is to perform the check for non-static context on the index values.
  524.  
  525.    procedure Eval_Indexed_Component (N : Node_Id) is
  526.       Expr : Node_Id;
  527.  
  528.    begin
  529.       Expr := First (Expressions (N));
  530.       while Present (Expr) loop
  531.          Check_Non_Static_Context (Expr);
  532.          Expr := Next (Expr);
  533.       end loop;
  534.  
  535.    end Eval_Indexed_Component;
  536.  
  537.    --------------------------
  538.    -- Eval_Integer_Literal --
  539.    --------------------------
  540.  
  541.    --  Numeric literals are static (RM 4.9(1)), and have already been marked
  542.    --  as static by the analyzer. The reason we did it that early is to allow
  543.    --  the possibility of turning off the Is_Static_Expression flag after
  544.    --  analysis, but before resolution, when integer literals are generated
  545.    --  in the expander that do not correspond to static expressions.
  546.  
  547.    procedure Eval_Integer_Literal (N : Node_Id) is
  548.    begin
  549.       --  If the literal appears in a non-expression context, then it is
  550.       --  certainly appearing in a non-static context, so check it. This
  551.       --  is actually a redundant check, since Check_Non_Static_Context
  552.       --  would check it, but it seems worth while avoiding the call.
  553.  
  554.       if Nkind (Parent (N)) not in N_Subexpr then
  555.          Check_Non_Static_Context (N);
  556.       end if;
  557.    end Eval_Integer_Literal;
  558.  
  559.    ---------------------
  560.    -- Eval_Logical_Op --
  561.    ---------------------
  562.  
  563.    --  Logical operations are static functions, so the result is potentially
  564.    --  static if both operands are potentially static (RM 4.9(7), 4.9(20)).
  565.  
  566.    procedure Eval_Logical_Op (N : Node_Id) is
  567.       Left      : constant Node_Id := Left_Opnd (N);
  568.       Right     : constant Node_Id := Right_Opnd (N);
  569.  
  570.    begin
  571.       --  If not foldable nothing to do
  572.  
  573.       if not Expression_Is_Foldable (N, Left, Right) then
  574.          return;
  575.       end if;
  576.  
  577.       --  Compile time evaluation of logical operation
  578.  
  579.       declare
  580.          Left_Int  : constant Uint := Expr_Value (Left);
  581.          Right_Int : constant Uint := Expr_Value (Right);
  582.  
  583.       begin
  584.          if Is_Modular_Integer_Type (Etype (N)) then
  585.             declare
  586.                Left_Bits  : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
  587.                Right_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
  588.  
  589.             begin
  590.                To_Bits (Left_Int, Left_Bits);
  591.                To_Bits (Right_Int, Right_Bits);
  592.  
  593.                --  Note: should really be able to use array ops instead of
  594.                --  these loops, but they weren't working at the time ???
  595.  
  596.                if Nkind (N) = N_Op_And then
  597.                   for J in Left_Bits'Range loop
  598.                      Left_Bits (J) := Left_Bits (J) and Right_Bits (J);
  599.                   end loop;
  600.  
  601.                elsif Nkind (N) = N_Op_Or then
  602.                   for J in Left_Bits'Range loop
  603.                      Left_Bits (J) := Left_Bits (J) or Right_Bits (J);
  604.                   end loop;
  605.  
  606.                else
  607.                   pragma Assert (Nkind (N) = N_Op_Xor);
  608.  
  609.                   for J in Left_Bits'Range loop
  610.                      Left_Bits (J) := Left_Bits (J) xor Right_Bits (J);
  611.                   end loop;
  612.                end if;
  613.  
  614.                Fold_Uint (N, From_Bits (Left_Bits, Etype (N)));
  615.             end;
  616.  
  617.          else
  618.             pragma Assert (Is_Boolean_Type (Etype (N)));
  619.  
  620.             if Nkind (N) = N_Op_And then
  621.                Fold_Uint (N,
  622.                  Test (Is_True (Left_Int) and then Is_True (Right_Int)));
  623.  
  624.             elsif Nkind (N) = N_Op_Or then
  625.                Fold_Uint (N,
  626.                  Test (Is_True (Left_Int) or else Is_True (Right_Int)));
  627.  
  628.             else
  629.                pragma Assert (Nkind (N) = N_Op_Xor);
  630.                Fold_Uint (N,
  631.                  Test (Is_True (Left_Int) xor Is_True (Right_Int)));
  632.             end if;
  633.          end if;
  634.       end;
  635.    end Eval_Logical_Op;
  636.  
  637.    ------------------------
  638.    -- Eval_Membership_Op --
  639.    ------------------------
  640.  
  641.    --  A membership test is potentially static if the expression is static,
  642.    --  and the range is a potentially static range, or is a subtype mark
  643.    --  denoting a static subtype (RM 4.9(12)).
  644.  
  645.    procedure Eval_Membership_Op (N : Node_Id) is
  646.       Left   : constant Node_Id := Left_Opnd (N);
  647.       Right  : constant Node_Id := Right_Opnd (N);
  648.       Def_Id : Entity_Id;
  649.       Lo     : Uint;
  650.       Hi     : Uint;
  651.  
  652.    begin
  653.       --  Ignore if error in either operand, except to make sure that
  654.       --  Any_Type is properly propagated to avoid junk cascaded errors.
  655.  
  656.       if Etype (Left) = Any_Type
  657.         or else Etype (Right) = Any_Type
  658.       then
  659.          Set_Etype (N, Any_Type);
  660.          return;
  661.       end if;
  662.  
  663.       --  Case of right operand is a subtype name
  664.  
  665.       if Is_Entity_Name (Right) then
  666.          Def_Id := Entity (Right);
  667.  
  668.          if (Is_Scalar_Type (Def_Id) or else Is_String_Type (Def_Id))
  669.            and then Is_OK_Static_Subtype (Def_Id)
  670.          then
  671.             if not Expression_Is_Foldable (N, Left) then
  672.                return;
  673.             end if;
  674.          else
  675.             Check_Non_Static_Context (Left);
  676.             return;
  677.          end if;
  678.  
  679.          --  Here we deal with the bizarre case of a string type
  680.          --  For now, just never fold, we will worry about this later ???
  681.  
  682.          if Is_String_Type (Def_Id) then
  683.             Check_Non_Static_Context (Left);
  684.             return;
  685.          end if;
  686.  
  687.          Lo := Expr_Value (Type_Low_Bound (Def_Id));
  688.          Hi := Expr_Value (Type_High_Bound (Def_Id));
  689.  
  690.       --  Case of right operand is a range
  691.  
  692.       else
  693.          if Is_Static_Range (Right) then
  694.             if not Expression_Is_Foldable (N, Left) then
  695.                return;
  696.  
  697.             --  If one bound of range raises CE, then don't try to fold
  698.  
  699.             elsif not Is_OK_Static_Range (Right) then
  700.                Check_Non_Static_Context (Left);
  701.                return;
  702.             end if;
  703.  
  704.          else
  705.             Check_Non_Static_Context (Left);
  706.             return;
  707.          end if;
  708.  
  709.          --  Here we know range is an OK static range
  710.  
  711.          Lo := Expr_Value (Low_Bound (Right));
  712.          Hi := Expr_Value (High_Bound (Right));
  713.       end if;
  714.  
  715.       --  Fold the membership test. We know we have a static range and Lo
  716.       --  and Hi are set to the values of the end points of this range.
  717.  
  718.       declare
  719.          Left_Int : constant Uint := Expr_Value (Left);
  720.          Result   : Boolean;
  721.  
  722.       begin
  723.          Result := (Lo <= Left_Int and then Left_Int <= Hi);
  724.  
  725.          if Nkind (N) = N_Not_In then
  726.             Result := not Result;
  727.          end if;
  728.  
  729.          Fold_Uint (N, Test (Result));
  730.       end;
  731.    end Eval_Membership_Op;
  732.  
  733.    ------------------------
  734.    -- Eval_Named_Integer --
  735.    ------------------------
  736.  
  737.    procedure Eval_Named_Integer (N : Node_Id) is
  738.    begin
  739.       Fold_Uint (N,
  740.         Expr_Value (Expression (Declaration_Node (Entity (N)))));
  741.    end Eval_Named_Integer;
  742.  
  743.    ---------------------
  744.    -- Eval_Named_Real --
  745.    ---------------------
  746.  
  747.    procedure Eval_Named_Real (N : Node_Id) is
  748.    begin
  749.       Fold_Ureal (N,
  750.         Expr_Value_R (Expression (Declaration_Node (Entity (N)))));
  751.    end Eval_Named_Real;
  752.  
  753.    -------------------
  754.    -- Eval_Op_Expon --
  755.    -------------------
  756.  
  757.    --  Exponentiation is a static functions, so the result is potentially
  758.    --  static if both operands are potentially static (RM 4.9(7), 4.9(20)).
  759.  
  760.    procedure Eval_Op_Expon (N : Node_Id) is
  761.       Left   : constant Node_Id := Left_Opnd (N);
  762.       Right  : constant Node_Id := Right_Opnd (N);
  763.  
  764.    begin
  765.       --  If not foldable, then nothing to do
  766.  
  767.       if not Expression_Is_Foldable (N, Left, Right) then
  768.          return;
  769.       end if;
  770.  
  771.       --  Fold exponentiation operation
  772.  
  773.       declare
  774.          Right_Int : constant Uint := Expr_Value (Right);
  775.  
  776.       begin
  777.          --  Integer case
  778.  
  779.          if Is_Integer_Type (Etype (Left)) then
  780.             declare
  781.                Left_Int : constant Uint := Expr_Value (Left);
  782.                Result   : Uint;
  783.  
  784.             begin
  785.                --  Exponentiation of an integer raises the exception
  786.                --  Constraint_Error for a negative exponent (RM 4.5.6)
  787.  
  788.                if Right_Int < 0 then
  789.                   Compile_Time_Constraint_Error
  790.                     (N, "integer exponent negative");
  791.                   return;
  792.  
  793.                else
  794.                   Result := Left_Int ** Right_Int;
  795.  
  796.                   if Is_Modular_Integer_Type (Etype (N)) then
  797.                      Result := Result mod Modulus (Etype (N));
  798.                   end if;
  799.  
  800.                   Fold_Uint (N, Result);
  801.                end if;
  802.             end;
  803.  
  804.          --  Real case
  805.  
  806.          else
  807.             declare
  808.                Left_Real : constant Ureal := Expr_Value_R (Left);
  809.  
  810.             begin
  811.                --  Cannot have a zero base with a negative exponent
  812.  
  813.                if Right_Int < 0 and then UR_Is_Zero (Left_Real) then
  814.                   Compile_Time_Constraint_Error
  815.                     (N, "zero ** negative integer");
  816.                   return;
  817.                else
  818.                   Fold_Ureal (N, Left_Real ** Right_Int);
  819.                end if;
  820.             end;
  821.          end if;
  822.       end;
  823.  
  824.    end Eval_Op_Expon;
  825.  
  826.    -----------------
  827.    -- Eval_Op_Not --
  828.    -----------------
  829.  
  830.    --  The not operation is a  static functions, so the result is potentially
  831.    --  static if the operand is potentially static (RM 4.9(7), 4.9(20)).
  832.  
  833.    procedure Eval_Op_Not (N : Node_Id) is
  834.       Right : constant Node_Id := Right_Opnd (N);
  835.  
  836.    begin
  837.       --  If not foldable, then nothing to do
  838.  
  839.       if not Expression_Is_Foldable (N, Right) then
  840.          return;
  841.       end if;
  842.  
  843.       --  Fold not operation
  844.  
  845.       declare
  846.          Rint : constant Uint := Expr_Value (Right);
  847.  
  848.       begin
  849.          if Is_Modular_Integer_Type (Etype (N)) then
  850.             declare
  851.                Right_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
  852.  
  853.             begin
  854.                To_Bits (Rint, Right_Bits);
  855.  
  856.                for J in Right_Bits'Range loop
  857.                   Right_Bits (J) := not Right_Bits (J);
  858.                end loop;
  859.  
  860.                Fold_Uint (N, From_Bits (Right_Bits, Etype (N)));
  861.             end;
  862.  
  863.          else
  864.             pragma Assert (Is_Boolean_Type (Etype (N)));
  865.             Fold_Uint (N, Test (not Is_True (Rint)));
  866.          end if;
  867.       end;
  868.    end Eval_Op_Not;
  869.  
  870.    -------------------------------
  871.    -- Eval_Qualified_Expression --
  872.    -------------------------------
  873.  
  874.    --  A qualified expression is potentially static if its subtype mark denotes
  875.    --  a static subtype and its expression is potentially static (RM 4.9 (11)).
  876.  
  877.    procedure Eval_Qualified_Expression (N : Node_Id) is
  878.       Operand     : Node_Id   := Expression (N);
  879.       Target_Type : Entity_Id := Etype (N);
  880.  
  881.    begin
  882.       if Is_Array_Type (Target_Type) and then
  883.         Is_Constrained (Target_Type)
  884.       then
  885.          Apply_Length_Check (Operand, Target_Type);
  886.       end if;
  887.  
  888.       --  Can only fold if target is string or scalar and subtype is static
  889.  
  890.       if (not Is_Scalar_Type (Target_Type)
  891.             and then not Is_String_Type (Target_Type))
  892.         or else not Is_Static_Subtype (Target_Type)
  893.       then
  894.          Check_Non_Static_Context (Operand);
  895.          return;
  896.       end if;
  897.  
  898.       --  Nothing to do if not foldable
  899.  
  900.       if not Expression_Is_Foldable (N, Operand) then
  901.          return;
  902.       end if;
  903.  
  904.       --  Don't try fold if target type has constraint error bounds
  905.  
  906.       if not Is_OK_Static_Subtype (Target_Type) then
  907.          Set_Raises_Constraint_Error (N);
  908.          return;
  909.       end if;
  910.  
  911.       --  Fold the result of qualification
  912.  
  913.       if Is_Discrete_Type (Target_Type) then
  914.          Fold_Uint (N, Expr_Value (Operand));
  915.  
  916.       elsif Is_Real_Type (Target_Type) then
  917.          Fold_Ureal (N, Expr_Value_R (Operand));
  918.  
  919.       else
  920.          Fold_Str (N, Strval (Get_String_Val (Operand)));
  921.       end if;
  922.  
  923.       if Is_Out_Of_Range (N, Etype (N)) then
  924.          Compile_Time_Constraint_Error (N, "value out of range");
  925.       end if;
  926.  
  927.    end Eval_Qualified_Expression;
  928.  
  929.    -----------------------
  930.    -- Eval_Real_Literal --
  931.    -----------------------
  932.  
  933.    --  Numeric literals are static (RM 4.9(1)), and have already been marked
  934.    --  as static by the analyzer. The reason we did it that early is to allow
  935.    --  the possibility of turning off the Is_Static_Expression flag after
  936.    --  analysis, but before resolution, when integer literals are generated
  937.    --  in the expander that do not correspond to static expressions.
  938.  
  939.    procedure Eval_Real_Literal (N : Node_Id) is
  940.    begin
  941.       --  If the literal appears in a non-expression context, then it is
  942.       --  certainly appearing in a non-static context, so check it.
  943.  
  944.       if Nkind (Parent (N)) not in N_Subexpr then
  945.          Check_Non_Static_Context (N);
  946.       end if;
  947.  
  948.    end Eval_Real_Literal;
  949.  
  950.    ------------------------
  951.    -- Eval_Relational_Op --
  952.    ------------------------
  953.  
  954.    --  Relational operations are static functions, so the result is static
  955.    --  if both operands are static (RM 4.9(7), 4.9(20)).
  956.  
  957.    procedure Eval_Relational_Op (N : Node_Id) is
  958.       Left      : constant Node_Id   := Left_Opnd (N);
  959.       Right     : constant Node_Id   := Right_Opnd (N);
  960.       Typ       : constant Entity_Id := Etype (Left);
  961.       Result    : Boolean;
  962.  
  963.    begin
  964.       --  Can only fold if type is scalar (don't fold string ops)
  965.  
  966.       if not Is_Scalar_Type (Typ) then
  967.          Check_Non_Static_Context (Left);
  968.          Check_Non_Static_Context (Right);
  969.          return;
  970.       end if;
  971.  
  972.       --  If not foldable, nothing to do
  973.  
  974.       if not Expression_Is_Foldable (N, Left, Right) then
  975.          return;
  976.       end if;
  977.  
  978.       --  Integer and Enumeration (discrete) type cases
  979.  
  980.       if Is_Discrete_Type (Typ) then
  981.          declare
  982.             Left_Int  : constant Uint := Expr_Value (Left);
  983.             Right_Int : constant Uint := Expr_Value (Right);
  984.  
  985.          begin
  986.             case Nkind (N) is
  987.                when N_Op_Eq => Result := Left_Int =  Right_Int;
  988.                when N_Op_Ne => Result := Left_Int /= Right_Int;
  989.                when N_Op_Lt => Result := Left_Int <  Right_Int;
  990.                when N_Op_Le => Result := Left_Int <= Right_Int;
  991.                when N_Op_Gt => Result := Left_Int >  Right_Int;
  992.                when N_Op_Ge => Result := Left_Int >= Right_Int;
  993.  
  994.                when others => pragma Assert (False); null;
  995.             end case;
  996.  
  997.             Fold_Uint (N, Test (Result));
  998.          end;
  999.  
  1000.       --  Real type case
  1001.  
  1002.       else
  1003.          pragma Assert (Is_Real_Type (Typ));
  1004.  
  1005.          declare
  1006.             Left_Real  : constant Ureal := Expr_Value_R (Left);
  1007.             Right_Real : constant Ureal := Expr_Value_R (Right);
  1008.  
  1009.          begin
  1010.             case Nkind (N) is
  1011.                when N_Op_Eq => Result := (Left_Real =  Right_Real);
  1012.                when N_Op_Ne => Result := (Left_Real /= Right_Real);
  1013.                when N_Op_Lt => Result := (Left_Real <  Right_Real);
  1014.                when N_Op_Le => Result := (Left_Real <= Right_Real);
  1015.                when N_Op_Gt => Result := (Left_Real >  Right_Real);
  1016.                when N_Op_Ge => Result := (Left_Real >= Right_Real);
  1017.  
  1018.                when others => pragma Assert (False); null;
  1019.             end case;
  1020.  
  1021.             Fold_Uint (N, Test (Result));
  1022.          end;
  1023.       end if;
  1024.  
  1025.    end Eval_Relational_Op;
  1026.  
  1027.    ----------------
  1028.    -- Eval_Shift --
  1029.    ----------------
  1030.  
  1031.    --  Shift operations are intrinsic operations that can never be static,
  1032.    --  so the only processing required is to perform the required check for
  1033.    --  a non static context for the two operands.
  1034.  
  1035.    procedure Eval_Shift (N : Node_Id) is
  1036.    begin
  1037.       Check_Non_Static_Context (Left_Opnd (N));
  1038.       Check_Non_Static_Context (Right_Opnd (N));
  1039.    end Eval_Shift;
  1040.  
  1041.    ------------------------
  1042.    -- Eval_Short_Circuit --
  1043.    ------------------------
  1044.  
  1045.    --  A short circuit operation is potentially static if both operands
  1046.    --  are potentially static (RM 4.9 (13))
  1047.  
  1048.    procedure Eval_Short_Circuit (N : Node_Id) is
  1049.       Kind     : constant Node_Kind := Nkind (N);
  1050.       Left     : constant Node_Id   := Left_Opnd (N);
  1051.       Right    : constant Node_Id   := Right_Opnd (N);
  1052.       Left_Int : Uint;
  1053.       Rstat    : constant Boolean   :=
  1054.                    Is_Static_Expression (Left)
  1055.                      and then Is_Static_Expression (Right);
  1056.  
  1057.    begin
  1058.       --  Short circuit operations are never static in Ada 83
  1059.  
  1060.       if Ada_83
  1061.         and then Comes_From_Source (N)
  1062.       then
  1063.          Check_Non_Static_Context (Left);
  1064.          Check_Non_Static_Context (Right);
  1065.          return;
  1066.       end if;
  1067.  
  1068.       --  Now look at the operands, we can't quite use the normal call to
  1069.       --  Expression_Is_Foldable here because short circuit operations are
  1070.       --  a special case, they can still be foldable, even if the right
  1071.       --  operand raises constraint error.
  1072.  
  1073.       --  If either operand is Any_Type, just propagate to result and
  1074.       --  do not try to fold, this prevents cascaded errors.
  1075.  
  1076.       if Etype (Left) = Any_Type or else Etype (Right) = Any_Type then
  1077.          Set_Etype (N, Any_Type);
  1078.          return;
  1079.  
  1080.       --  If left operand raises constraint error, then replace node N with
  1081.       --  the raise constraint error node, and we are obviously not foldable.
  1082.       --  Is_Static_Expression is set from the two operands in the normal way,
  1083.       --  and we check the right operand if it is in a non-static context.
  1084.  
  1085.       elsif Raises_Constraint_Error (Left) then
  1086.          if not Rstat then
  1087.             Check_Non_Static_Context (Right);
  1088.          end if;
  1089.  
  1090.          Rewrite_Substitute_Tree (N, Left);
  1091.          Set_Is_Static_Expression (N, Rstat);
  1092.          return;
  1093.  
  1094.       --  If the result is not static, then we won't in any case fold
  1095.  
  1096.       elsif not Rstat then
  1097.          Check_Non_Static_Context (Left);
  1098.          Check_Non_Static_Context (Right);
  1099.          return;
  1100.       end if;
  1101.  
  1102.       --  Here the result is static, note that, unlike the normal processing
  1103.       --  in Expression_Is_Foldable, we did *not* check above to see if the
  1104.       --  right operand raises constraint error, that's because it is not
  1105.       --  significant if the left operand is decisive.
  1106.  
  1107.       Set_Is_Static_Expression (N);
  1108.  
  1109.       --  It does not matter if the right operand raises constraint error if
  1110.       --  it will not be evaluated. So deal specially with the cases where
  1111.       --  the right operand is not evaluated. Note that we will fold these
  1112.       --  cases even if the right operand is non-static, which is fine, but
  1113.       --  of course in these cases the result is not potentially static.
  1114.  
  1115.       Left_Int := Expr_Value (Left);
  1116.  
  1117.       if (Kind = N_And_Then and then Is_False (Left_Int))
  1118.         or else (Kind = N_Or_Else and Is_True (Left_Int))
  1119.       then
  1120.          Fold_Uint (N, Left_Int);
  1121.          return;
  1122.       end if;
  1123.  
  1124.       --  If first operand not decisive, then it does matter if the right
  1125.       --  operand raises constraint error, since it will be evaluated, so
  1126.       --  we simply replace the node with the right operand. Note that this
  1127.       --  properly propagates Is_Static_Expression and Raises_Constraint_Error
  1128.       --  (both are set to True in Right).
  1129.  
  1130.       if Raises_Constraint_Error (Right) then
  1131.          Rewrite_Substitute_Tree (N, Right);
  1132.          Check_Non_Static_Context (Left);
  1133.          return;
  1134.       end if;
  1135.  
  1136.       --  Otherwise the result depends on the right operand
  1137.  
  1138.       Fold_Uint (N, Expr_Value (Right));
  1139.       return;
  1140.  
  1141.    end Eval_Short_Circuit;
  1142.  
  1143.    ----------------
  1144.    -- Eval_Slice --
  1145.    ----------------
  1146.  
  1147.    --  Slices can never be static, so the only processing required is to
  1148.    --  check for non-static context if an explicit range is given.
  1149.  
  1150.    procedure Eval_Slice (N : Node_Id) is
  1151.       Drange : constant Node_Id := Discrete_Range (N);
  1152.  
  1153.    begin
  1154.       if Nkind (Drange) = N_Range then
  1155.          Check_Non_Static_Context (Low_Bound (Drange));
  1156.          Check_Non_Static_Context (High_Bound (Drange));
  1157.       end if;
  1158.    end Eval_Slice;
  1159.  
  1160.    -------------------------
  1161.    -- Eval_String_Literal --
  1162.    -------------------------
  1163.  
  1164.    --  String literals are static if the subtype is static (RM 4.9(2)), so
  1165.    --  reset the static expression flag (it was set in Analyze_String_Literal)
  1166.    --  if the subtype is non-static.
  1167.  
  1168.    procedure Eval_String_Literal (N : Node_Id) is
  1169.    begin
  1170.       if not Is_Static_Subtype (Component_Type (Etype (N))) then
  1171.          Set_Is_Static_Expression (N, False);
  1172.       end if;
  1173.    end Eval_String_Literal;
  1174.  
  1175.    --------------------------
  1176.    -- Eval_Type_Conversion --
  1177.    --------------------------
  1178.  
  1179.    --  A type conversion is potentially static if its subtype mark is for a
  1180.    --  static scalar subtype, and its operand expression is potentially static
  1181.    --  (RM 4.9 (10))
  1182.  
  1183.    procedure Eval_Type_Conversion (N : Node_Id) is
  1184.       Operand     : constant Node_Id   := Expression (N);
  1185.       Source_Type : constant Entity_Id := Etype (Operand);
  1186.       Target_Type : constant Entity_Id := Etype (N);
  1187.  
  1188.    begin
  1189.       --  Can only fold if type is static and scalar
  1190.  
  1191.       if not Is_Scalar_Type (Target_Type)
  1192.         or else not Is_Static_Subtype (Target_Type)
  1193.       then
  1194.          Check_Non_Static_Context (Operand);
  1195.          return;
  1196.       end if;
  1197.  
  1198.       --  Nothing to do if not foldable
  1199.  
  1200.       if not Expression_Is_Foldable (N, Operand) then
  1201.          return;
  1202.       end if;
  1203.  
  1204.       --  Don't try fold if target type has constraint error bounds
  1205.  
  1206.       if not Is_OK_Static_Subtype (Target_Type) then
  1207.          Set_Raises_Constraint_Error (N);
  1208.          return;
  1209.       end if;
  1210.  
  1211.       --  Fold conversion, case of integer target type
  1212.  
  1213.       if Is_Integer_Type (Target_Type) then
  1214.          declare
  1215.             Result : Uint;
  1216.  
  1217.          begin
  1218.             if Is_Integer_Type (Source_Type) then
  1219.                Result := Expr_Value (Operand);
  1220.             else
  1221.                pragma Assert (Is_Real_Type (Source_Type));
  1222.                Result := UR_To_Uint (Expr_Value_R (Operand));
  1223.             end if;
  1224.  
  1225.             Fold_Uint (N, Result);
  1226.          end;
  1227.  
  1228.       --  Fold conversion, case of real target type
  1229.  
  1230.       elsif Is_Real_Type (Target_Type) then
  1231.          declare
  1232.             Result : Ureal;
  1233.  
  1234.          begin
  1235.             if Is_Real_Type (Source_Type) then
  1236.                Result := Expr_Value_R (Operand);
  1237.             else
  1238.                Result := UR_From_Uint (Expr_Value (Operand));
  1239.             end if;
  1240.  
  1241.             Fold_Ureal (N, Result);
  1242.          end;
  1243.  
  1244.       --  Enumeration types
  1245.  
  1246.       else
  1247.          Fold_Uint (N, Expr_Value (Operand));
  1248.       end if;
  1249.  
  1250.       if Is_Out_Of_Range (N, Etype (N)) then
  1251.          Compile_Time_Constraint_Error (N, "value out of range");
  1252.       end if;
  1253.  
  1254.    end Eval_Type_Conversion;
  1255.  
  1256.    -------------------------------
  1257.    -- Eval_Unchecked_Conversion --
  1258.    -------------------------------
  1259.  
  1260.    --  Unchecked conversions can never be static, so the only required
  1261.    --  processing is to check for a non-static context for the operand.
  1262.  
  1263.    procedure Eval_Unchecked_Conversion (N : Node_Id) is
  1264.    begin
  1265.       Check_Non_Static_Context (Expression (N));
  1266.    end Eval_Unchecked_Conversion;
  1267.  
  1268.    -------------------
  1269.    -- Eval_Unary_Op --
  1270.    -------------------
  1271.  
  1272.    --  Predefined unary operators are static functions (RM 4.9(20)) and thus
  1273.    --  are potentially static if the operand is potentially static (RM 4.9(7))
  1274.  
  1275.    procedure Eval_Unary_Op (N : Node_Id) is
  1276.       Right : constant Node_Id := Right_Opnd (N);
  1277.  
  1278.    begin
  1279.       --  If not foldable, nothing to do
  1280.  
  1281.       if not Expression_Is_Foldable (N, Right) then
  1282.          return;
  1283.       end if;
  1284.  
  1285.       --  Fold for integer case
  1286.  
  1287.       if Is_Integer_Type (Etype (N)) then
  1288.          declare
  1289.             Rint   : constant Uint := Expr_Value (Right);
  1290.             Result : Uint;
  1291.  
  1292.          begin
  1293.             --  In the case of modular unary plus and abs there is no need
  1294.             --  to adjust the result of the operation since if the original
  1295.             --  operand was in bounds the result will be in the bounds of the
  1296.             --  modular type. However, in the case of modular unary minus the
  1297.             --  result may go out of the bounds of the modular type and needs
  1298.             --  adjustment.
  1299.  
  1300.             if Nkind (N) = N_Op_Plus then
  1301.                Result := Rint;
  1302.  
  1303.             elsif Nkind (N) = N_Op_Minus then
  1304.                if Is_Modular_Integer_Type (Etype (N)) then
  1305.                   Result := (-Rint) mod Modulus (Etype (N));
  1306.                else
  1307.                   Result := (-Rint);
  1308.                end if;
  1309.  
  1310.             else
  1311.                pragma Assert (Nkind (N) = N_Op_Abs);
  1312.                Result := abs Rint;
  1313.             end if;
  1314.  
  1315.             Fold_Uint (N, Result);
  1316.          end;
  1317.  
  1318.       --  Fold for real case
  1319.  
  1320.       elsif Is_Real_Type (Etype (N)) then
  1321.          declare
  1322.             Rreal  : constant Ureal := Expr_Value_R (Right);
  1323.             Result : Ureal;
  1324.  
  1325.          begin
  1326.             if Nkind (N) = N_Op_Plus then
  1327.                Result := Rreal;
  1328.  
  1329.             elsif Nkind (N) = N_Op_Minus then
  1330.                Result := UR_Negate (Rreal);
  1331.  
  1332.             else
  1333.                pragma Assert (Nkind (N) = N_Op_Abs);
  1334.                Result := abs Rreal;
  1335.             end if;
  1336.  
  1337.             Fold_Ureal (N, Result);
  1338.          end;
  1339.       end if;
  1340.  
  1341.    end Eval_Unary_Op;
  1342.  
  1343.    ----------------
  1344.    -- Expr_Value --
  1345.    ----------------
  1346.  
  1347.    function Expr_Value (N : Node_Id) return Uint is
  1348.       Kind : constant Node_Kind := Nkind (N);
  1349.       Ent  : Entity_Id;
  1350.  
  1351.    begin
  1352.       if Is_Entity_Name (N) then
  1353.          Ent := Entity (N);
  1354.  
  1355.          --  An enumeration literal that was either in the source or
  1356.          --  created as a result of static evaluation.
  1357.  
  1358.          if Ekind (Ent) = E_Enumeration_Literal then
  1359.             return Enumeration_Pos (Ent);
  1360.  
  1361.          --  A user defined static constant
  1362.  
  1363.          else
  1364.             pragma Assert (Ekind (Ent) = E_Constant);
  1365.             return Expr_Value (Constant_Value (Ent));
  1366.          end if;
  1367.  
  1368.       --  An integer literal that was either in the source or created
  1369.       --  as a result of static evaluation.
  1370.  
  1371.       elsif Kind = N_Integer_Literal then
  1372.          return Intval (N);
  1373.  
  1374.       --  A real literal for a fixed-point type. This must be the fixed-point
  1375.       --  case, either the literal is of a fixed-point type, or it is a bound
  1376.       --  of a fixed-point type, with type universal real. In either case we
  1377.       --  obtain the desired value from Corresponding_Integer_Value.
  1378.  
  1379.       elsif Kind = N_Real_Literal then
  1380.          return Corresponding_Integer_Value (N);
  1381.  
  1382.       else
  1383.          pragma Assert (Kind = N_Character_Literal);
  1384.          Ent := Entity (N);
  1385.  
  1386.          --  Since Character literals of type Standard.Character don't
  1387.          --  have any defining character literals built for them, they
  1388.          --  do not have their Entity set, so just use their Char
  1389.          --  code. Otherwise for user-defined character literals use
  1390.          --  their Pos value as usual.
  1391.  
  1392.          if No (Ent) then
  1393.             return UI_From_Int (Int (Char_Literal_Value (N)));
  1394.          else
  1395.             return Enumeration_Pos (Ent);
  1396.          end if;
  1397.       end if;
  1398.  
  1399.    end Expr_Value;
  1400.  
  1401.    ------------------
  1402.    -- Expr_Value_E --
  1403.    ------------------
  1404.  
  1405.    function Expr_Value_E (N : Node_Id) return Entity_Id is
  1406.       Ent  : constant Entity_Id := Entity (N);
  1407.  
  1408.    begin
  1409.       if Ekind (Ent) = E_Enumeration_Literal then
  1410.          return Ent;
  1411.       else
  1412.          pragma Assert (Ekind (Ent) = E_Constant);
  1413.          return Expr_Value_E (Constant_Value (Ent));
  1414.       end if;
  1415.    end Expr_Value_E;
  1416.  
  1417.    ------------------
  1418.    -- Expr_Value_R --
  1419.    ------------------
  1420.  
  1421.    function Expr_Value_R (N : Node_Id) return Ureal is
  1422.       Kind : constant Node_Kind := Nkind (N);
  1423.       Ent  : Entity_Id;
  1424.  
  1425.    begin
  1426.       if Kind = N_Identifier or else Kind = N_Expanded_Name then
  1427.          Ent := Entity (N);
  1428.          pragma Assert (Ekind (Ent) = E_Constant);
  1429.          return Expr_Value_R (Constant_Value (Ent));
  1430.  
  1431.       else
  1432.          pragma Assert (Kind = N_Real_Literal);
  1433.          return Realval (N);
  1434.       end if;
  1435.    end Expr_Value_R;
  1436.  
  1437.    ------------------
  1438.    -- Expr_Value_S --
  1439.    ------------------
  1440.  
  1441.    function Expr_Value_S (N : Node_Id) return String_Id is
  1442.    begin
  1443.       if Nkind (N) = N_String_Literal then
  1444.          return Strval (N);
  1445.       else
  1446.          pragma Assert (Ekind (Entity (N)) = E_Constant);
  1447.          return Expr_Value_S (Constant_Value (Entity (N)));
  1448.       end if;
  1449.    end Expr_Value_S;
  1450.  
  1451.    ----------------------------
  1452.    -- Expression_Is_Foldable --
  1453.    ----------------------------
  1454.  
  1455.    --  One operand case
  1456.  
  1457.    function Expression_Is_Foldable
  1458.      (N    : Node_Id;
  1459.       Op1  : Node_Id)
  1460.       return Boolean
  1461.    is
  1462.    begin
  1463.       --  If operand is Any_Type, just propagate to result and do not
  1464.       --  try to fold, this prevents cascaded errors.
  1465.  
  1466.       if Etype (Op1) = Any_Type then
  1467.          Set_Etype (N, Any_Type);
  1468.          return False;
  1469.  
  1470.       --  If operand raises constraint error, then replace node N with the
  1471.       --  raise constraint error node, and we are obviously not foldable.
  1472.       --  Note that this replacement inherits the Is_Static_Expression flag
  1473.       --  from the operand.
  1474.  
  1475.       elsif Raises_Constraint_Error (Op1) then
  1476.          Rewrite_Substitute_Tree (N, Op1);
  1477.          return False;
  1478.  
  1479.       --  If the operand is not static, then the result is not static, and
  1480.       --  all we have to do is to check the operand since it is now known
  1481.       --  to appear in a non-static context.
  1482.  
  1483.       elsif not Is_Static_Expression (Op1) then
  1484.          Check_Non_Static_Context (Op1);
  1485.          return False;
  1486.  
  1487.       --  Here we have the case of an operand whose type is OK, which is
  1488.       --  static, and which does not raise constraint error, we can fold.
  1489.  
  1490.       else
  1491.          Set_Is_Static_Expression (N);
  1492.          return True;
  1493.       end if;
  1494.    end Expression_Is_Foldable;
  1495.  
  1496.    --  Two operand case
  1497.  
  1498.    function Expression_Is_Foldable
  1499.      (N    : Node_Id;
  1500.       Op1  : Node_Id;
  1501.       Op2  : Node_Id)
  1502.       return Boolean
  1503.    is
  1504.       Rstat : constant Boolean := Is_Static_Expression (Op1)
  1505.                                     and then Is_Static_Expression (Op2);
  1506.  
  1507.    begin
  1508.       --  If either operand is Any_Type, just propagate to result and
  1509.       --  do not try to fold, this prevents cascaded errors.
  1510.  
  1511.       if Etype (Op1) = Any_Type or else Etype (Op2) = Any_Type then
  1512.          Set_Etype (N, Any_Type);
  1513.          return False;
  1514.  
  1515.       --  If left operand raises constraint error, then replace node N with
  1516.       --  the raise constraint error node, and we are obviously not foldable.
  1517.       --  Is_Static_Expression is set from the two operands in the normal way,
  1518.       --  and we check the right operand if it is in a non-static context.
  1519.  
  1520.       elsif Raises_Constraint_Error (Op1) then
  1521.          if not Rstat then
  1522.             Check_Non_Static_Context (Op2);
  1523.          end if;
  1524.  
  1525.          Rewrite_Substitute_Tree (N, Op1);
  1526.          Set_Is_Static_Expression (N, Rstat);
  1527.          return False;
  1528.  
  1529.       --  Similar processing for the case of the right operand. Note that
  1530.       --  we don't use this routine for the short-circuit case, so we do
  1531.       --  not have to worry about that special case here.
  1532.  
  1533.       elsif Raises_Constraint_Error (Op2) then
  1534.          if not Rstat then
  1535.             Check_Non_Static_Context (Op1);
  1536.          end if;
  1537.  
  1538.          Rewrite_Substitute_Tree (N, Op2);
  1539.          Set_Is_Static_Expression (N, Rstat);
  1540.          return False;
  1541.  
  1542.       --  If result is not-static, then check non-static contexts on operands
  1543.       --  since one of them may be static and the other one may not be static
  1544.  
  1545.       elsif not Rstat then
  1546.          Check_Non_Static_Context (Op1);
  1547.          Check_Non_Static_Context (Op2);
  1548.          return False;
  1549.  
  1550.       --  Else result is static and foldable. Both operands are static,
  1551.       --  and neither raises constraint error, so we can definitely fold.
  1552.  
  1553.       else
  1554.          Set_Is_Static_Expression (N);
  1555.          return True;
  1556.       end if;
  1557.    end Expression_Is_Foldable;
  1558.  
  1559.    --------------
  1560.    -- Fold_Str --
  1561.    --------------
  1562.  
  1563.    procedure Fold_Str (N : Node_Id; Val : String_Id) is
  1564.       Loc      : constant Source_Ptr := Sloc (N);
  1565.       Typ      : constant Entity_Id  := Etype (N);
  1566.  
  1567.    begin
  1568.       Rewrite_Substitute_Tree (N, Make_String_Literal (Loc, Strval => Val));
  1569.       Analyze (N);
  1570.       Resolve (N, Typ);
  1571.    end Fold_Str;
  1572.  
  1573.    ---------------
  1574.    -- Fold_Uint --
  1575.    ---------------
  1576.  
  1577.    procedure Fold_Uint (N : Node_Id; Val : Uint) is
  1578.       Loc : constant Source_Ptr := Sloc (N);
  1579.       Typ : constant Entity_Id  := Etype (N);
  1580.       Lit : Entity_Id;
  1581.       Pos : Int;
  1582.  
  1583.    begin
  1584.       --  For a result of type integer, subsitute an N_Integer_Literal node
  1585.       --  for the result of the compile time evaluation of the expression.
  1586.  
  1587.       if Is_Integer_Type (Etype (N)) then
  1588.          Rewrite_Substitute_Tree (N, Make_Integer_Literal (Loc, Val));
  1589.  
  1590.       --  Otherwise we have an enumeration type, and we substitute either
  1591.       --  an N_Identifier or N_Character_Literal to represent the enumeration
  1592.       --  literal corresponding to the given value, which must always be in
  1593.       --  range, because appropriate tests have already been made for this.
  1594.  
  1595.       elsif Is_Enumeration_Type (Etype (N)) then
  1596.          Pos := UI_To_Int (Val);
  1597.  
  1598.          --  In the case where the literal is either of type Wide_Character
  1599.          --  or Character or of a type derived from them, there needs to be
  1600.          --  some special handling since there is no explicit chain of
  1601.          --  literals to search. Instead, an N_Character_Literal node is
  1602.          --  created with the appropriate Char_Code and Chars fields.
  1603.  
  1604.          if Root_Type (Etype (N)) = Standard_Character
  1605.            or else Root_Type (Etype (N)) = Standard_Wide_Character
  1606.          then
  1607.             Set_Character_Literal_Name (Char_Code (Pos));
  1608.  
  1609.             Rewrite_Substitute_Tree (N,
  1610.               Make_Character_Literal (Loc,
  1611.                 Chars => Name_Find,
  1612.                 Char_Literal_Value => Char_Code (Pos)));
  1613.  
  1614.          --  For all other cases, we have a complete table of literals, and
  1615.          --  we simply iterate through the chain of literal until the one
  1616.          --  with the desired position value is found.
  1617.          --
  1618.  
  1619.          else
  1620.             Lit := First_Literal (Base_Type (Etype (N)));
  1621.             for J in 1 .. Pos loop
  1622.                Lit := Next_Literal (Lit);
  1623.             end loop;
  1624.  
  1625.             Rewrite_Substitute_Tree (N, New_Occurrence_Of (Lit, Loc));
  1626.          end if;
  1627.  
  1628.       --  Anything other than an integer type or enumeration type is wrong
  1629.  
  1630.       else
  1631.          pragma Assert (False); null;
  1632.       end if;
  1633.  
  1634.       --  We now have the literal with the right value, both the actual type
  1635.       --  and the expected type of this literal are taken from the expression
  1636.       --  that was evaluated.
  1637.  
  1638.       Analyze (N);
  1639.       Set_Etype (N, Typ);
  1640.       Resolve (N, Typ);
  1641.    end Fold_Uint;
  1642.  
  1643.    ----------------
  1644.    -- Fold_Ureal --
  1645.    ----------------
  1646.  
  1647.    procedure Fold_Ureal (N : Node_Id; Val : Ureal) is
  1648.       Loc      : constant Source_Ptr := Sloc (N);
  1649.       Typ      : constant Entity_Id  := Etype (N);
  1650.  
  1651.    begin
  1652.       Rewrite_Substitute_Tree (N, Make_Real_Literal (Loc, Realval => Val));
  1653.  
  1654.       --  We now have the literal with the right value, both the actual type
  1655.       --  and the expected type of this literal are taken from the expression
  1656.       --  that was evaluated. Note that for real literals, the distinction
  1657.       --  between actual and expected type is significant, since the check
  1658.       --  for extraneous
  1659.  
  1660.       Analyze (N);
  1661.       Set_Etype (N, Typ);
  1662.       Resolve (N, Typ);
  1663.    end Fold_Ureal;
  1664.  
  1665.    ---------------
  1666.    -- From_Bits --
  1667.    ---------------
  1668.  
  1669.    function From_Bits (B : Bits; T : Entity_Id) return Uint is
  1670.       V : Uint := Uint_0;
  1671.  
  1672.    begin
  1673.       for J in 0 .. B'Last loop
  1674.          if B (J) then
  1675.             V := V + 2 ** J;
  1676.          end if;
  1677.       end loop;
  1678.  
  1679.       if Non_Binary_Modulus (T) then
  1680.          V := V mod Modulus (T);
  1681.       end if;
  1682.  
  1683.       return V;
  1684.    end From_Bits;
  1685.  
  1686.    --------------------
  1687.    -- Get_String_Val --
  1688.    --------------------
  1689.  
  1690.    function Get_String_Val (N : Node_Id) return Node_Id is
  1691.    begin
  1692.       if Nkind (N) = N_String_Literal then
  1693.          return N;
  1694.  
  1695.       elsif Nkind (N) = N_Character_Literal then
  1696.          return N;
  1697.  
  1698.       else
  1699.          pragma Assert (Is_Entity_Name (N));
  1700.          return Get_String_Val (Constant_Value (Entity (N)));
  1701.       end if;
  1702.    end Get_String_Val;
  1703.  
  1704.    -----------------------------
  1705.    -- Is_OK_Static_Expression --
  1706.    -----------------------------
  1707.  
  1708.    function Is_OK_Static_Expression (N : Node_Id) return Boolean is
  1709.    begin
  1710.       return Is_Static_Expression (N)
  1711.         and then not Raises_Constraint_Error (N);
  1712.    end Is_OK_Static_Expression;
  1713.  
  1714.    ------------------------
  1715.    -- Is_OK_Static_Range --
  1716.    ------------------------
  1717.  
  1718.    --  A static range is a range whose bounds are static expressions, or a
  1719.    --  Range_Attribute_Reference equivalent to such a range (RM 4.9(26)).
  1720.    --  We have already converted range attribute references, so we get the
  1721.    --  "or" part of this rule without needing a special test.
  1722.  
  1723.    function Is_OK_Static_Range (N : Node_Id) return Boolean is
  1724.    begin
  1725.       return Is_OK_Static_Expression (Low_Bound (N))
  1726.         and then Is_OK_Static_Expression (High_Bound (N));
  1727.    end Is_OK_Static_Range;
  1728.  
  1729.    --------------------------
  1730.    -- Is_OK_Static_Subtype --
  1731.    --------------------------
  1732.  
  1733.    --  A static subtype is either a scalar base type, other than a generic
  1734.    --  formal type; or a scalar subtype formed by imposing on a static
  1735.    --  subtype either a static range constraint, or a floating or fixed
  1736.    --  point constraint whose range constraint, if any, is static (RM 4.9(26))
  1737.  
  1738.    function Is_OK_Static_Subtype (Typ : Entity_Id) return Boolean is
  1739.       Base_T : constant Entity_Id := Base_Type (Typ);
  1740.  
  1741.    begin
  1742.       if Is_Generic_Type (Base_T)
  1743.         or else not Is_Scalar_Type (Base_T)
  1744.         or else Is_Generic_Actual_Type (Base_T)
  1745.       then
  1746.          return False;
  1747.  
  1748.       elsif Base_T = Typ then
  1749.          return True;
  1750.  
  1751.       else
  1752.          return Is_OK_Static_Subtype (Base_T)
  1753.            and then Is_OK_Static_Expression (Type_Low_Bound (Typ))
  1754.            and then Is_OK_Static_Expression (Type_High_Bound (Typ));
  1755.       end if;
  1756.    end Is_OK_Static_Subtype;
  1757.  
  1758.    ---------------------
  1759.    -- Is_Out_Of_Range --
  1760.    ---------------------
  1761.  
  1762.    function Is_Out_Of_Range (N : Node_Id; Typ : Entity_Id) return Boolean is
  1763.       Val  : Uint;
  1764.       Valr : Ureal;
  1765.  
  1766.    begin
  1767.       --  Universal types have no range limits, so always in range.
  1768.  
  1769.       if Typ = Universal_Integer or else Typ = Universal_Real then
  1770.          return False;
  1771.  
  1772.       --  Never out of range if not scalar type. Don't know if this can
  1773.       --  actually happen, but our spec allows it, so we must check!
  1774.  
  1775.       elsif not Is_Scalar_Type (Typ) then
  1776.          return False;
  1777.  
  1778.       --  Never out of range unless we have an OK static value, since
  1779.       --  otherwise we have no known value to compare against.
  1780.  
  1781.       elsif not Is_OK_Static_Expression (N) then
  1782.          return False;
  1783.  
  1784.       else
  1785.          declare
  1786.             Lo        : constant Node_Id := Type_Low_Bound  (Typ);
  1787.             Hi        : constant Node_Id := Type_High_Bound (Typ);
  1788.             LB_Static : constant Boolean := Is_OK_Static_Expression (Lo);
  1789.             UB_Static : constant Boolean := Is_OK_Static_Expression (Hi);
  1790.  
  1791.          begin
  1792.             --  For floating point types, do check against the bounds
  1793.  
  1794.             if Is_Floating_Point_Type (Typ) then
  1795.                Valr := Expr_Value_R (N);
  1796.  
  1797.                if LB_Static and then Valr < Expr_Value_R (Lo) then
  1798.                   return True;
  1799.  
  1800.                elsif UB_Static and then Expr_Value_R (Hi) < Valr then
  1801.                   return True;
  1802.  
  1803.                else
  1804.                   return False;
  1805.                end if;
  1806.  
  1807.             --  For discrete types, do the check against the integer bounds.
  1808.             --  Also do a check against the integer bounds for fixed-point
  1809.             --  types (in this case we are dealing with the corresponding
  1810.             --  integer value, both for the bounds, and for the value of
  1811.             --  the expression).
  1812.  
  1813.             else
  1814.                Val := Expr_Value (N);
  1815.  
  1816.                if LB_Static and then Val < Expr_Value (Lo) then
  1817.                   return True;
  1818.  
  1819.                elsif UB_Static and then Expr_Value (Hi) < Val then
  1820.                   return True;
  1821.  
  1822.                else
  1823.                   return False;
  1824.                end if;
  1825.             end if;
  1826.          end;
  1827.       end if;
  1828.    end Is_Out_Of_Range;
  1829.  
  1830.    -----------------
  1831.    -- Is_In_Range --
  1832.    -----------------
  1833.  
  1834.    function Is_In_Range (N : Node_Id; Typ : Entity_Id) return Boolean is
  1835.       Val  : Uint;
  1836.       Valr : Ureal;
  1837.  
  1838.    begin
  1839.       --  Universal types have no range limits, so always in range.
  1840.  
  1841.       if Typ = Universal_Integer or else Typ = Universal_Real then
  1842.          return True;
  1843.  
  1844.       --  Never in range if not scalar type. Don't know if this can
  1845.       --  actually happen, but our spec allows it, so we must check!
  1846.  
  1847.       elsif not Is_Scalar_Type (Typ) then
  1848.          return False;
  1849.  
  1850.       --  Never in range unless we have an OK static value, since
  1851.       --  otherwise we have no known value to compare against.
  1852.  
  1853.       elsif not Is_OK_Static_Expression (N) then
  1854.          return False;
  1855.  
  1856.       else
  1857.          declare
  1858.             Lo        : constant Node_Id := Type_Low_Bound  (Typ);
  1859.             Hi        : constant Node_Id := Type_High_Bound (Typ);
  1860.             LB_Static : constant Boolean := Is_OK_Static_Expression (Lo);
  1861.             UB_Static : constant Boolean := Is_OK_Static_Expression (Hi);
  1862.  
  1863.          begin
  1864.             --  For floating point types, do check against the bounds
  1865.  
  1866.             if Is_Floating_Point_Type (Typ) then
  1867.                Valr := Expr_Value_R (N);
  1868.  
  1869.                if LB_Static and then Valr >= Expr_Value_R (Lo) and then
  1870.                    UB_Static and then Valr <= Expr_Value_R (Hi)
  1871.                then
  1872.                   return True;
  1873.                else
  1874.                   return False;
  1875.                end if;
  1876.  
  1877.             --  For discrete types, do the check against the integer bounds.
  1878.             --  Also do a check against the integer bounds for fixed-point
  1879.             --  types (in this case we are dealing with the corresponding
  1880.             --  integer value, both for the bounds, and for the value of
  1881.             --  the expression).
  1882.  
  1883.             else
  1884.                Val := Expr_Value (N);
  1885.  
  1886.                if LB_Static and then Val >= Expr_Value (Lo) and then
  1887.                    UB_Static and then Val <= Expr_Value (Hi)
  1888.                then
  1889.                   return True;
  1890.                else
  1891.                   return False;
  1892.                end if;
  1893.             end if;
  1894.          end;
  1895.       end if;
  1896.    end Is_In_Range;
  1897.  
  1898.    ---------------------
  1899.    -- Is_Static_Range --
  1900.    ---------------------
  1901.  
  1902.    --  A static range is a range whose bounds are static expressions, or a
  1903.    --  Range_Attribute_Reference equivalent to such a range (RM 4.9(26)).
  1904.    --  We have already converted range attribute references, so we get the
  1905.    --  "or" part of this rule without needing a special test.
  1906.  
  1907.    function Is_Static_Range (N : Node_Id) return Boolean is
  1908.    begin
  1909.       return Is_Static_Expression (Low_Bound (N))
  1910.         and then Is_Static_Expression (High_Bound (N));
  1911.    end Is_Static_Range;
  1912.  
  1913.    -----------------------
  1914.    -- Is_Static_Subtype --
  1915.    -----------------------
  1916.  
  1917.    --  A static subtype is either a scalar base type, other than a generic
  1918.    --  formal type; or a scalar subtype formed by imposing on a static
  1919.    --  subtype either a static range constraint, or a floating or fixed
  1920.    --  point constraint whose range constraint, if any, is static. [LRM 4.9]
  1921.  
  1922.    --  Is this definition right???
  1923.  
  1924.    function Is_Static_Subtype (Typ : Entity_Id) return Boolean is
  1925.       Base_T : constant Entity_Id := Base_Type (Typ);
  1926.  
  1927.    begin
  1928.       if Is_Generic_Type (Root_Type (Base_T))
  1929.         or else not Is_Scalar_Type (Base_T)
  1930.         or else Is_Generic_Actual_Type (Base_T)
  1931.       then
  1932.          return False;
  1933.  
  1934.       elsif Base_T = Typ then
  1935.          return True;
  1936.  
  1937.       else
  1938.          return Is_Static_Subtype (Base_T)
  1939.            and then Is_Static_Expression (Type_Low_Bound (Typ))
  1940.            and then Is_Static_Expression (Type_High_Bound (Typ));
  1941.       end if;
  1942.    end Is_Static_Subtype;
  1943.  
  1944.    -------------------------------
  1945.    -- Subtypes_Statically_Match --
  1946.    -------------------------------
  1947.  
  1948.    --  Subtypes statically match if they have statically matching constraints
  1949.    --  (RM 4.9.1(2)). Constraints statically match if there are none, or if
  1950.    --  they are the same identical constraint, or if they are static and the
  1951.    --  values match (RM 4.9.1(1)).
  1952.  
  1953.    function Subtypes_Statically_Match (T1, T2 : Entity_Id) return Boolean is
  1954.    begin
  1955.       --  A type always statically matches itself
  1956.  
  1957.       if T1 = T2 then
  1958.          return True;
  1959.  
  1960.       --  Scalar types
  1961.  
  1962.       elsif Is_Scalar_Type (T1) then
  1963.          declare
  1964.             LB1 : constant Node_Id := Type_Low_Bound  (T1);
  1965.             HB1 : constant Node_Id := Type_High_Bound (T1);
  1966.             LB2 : constant Node_Id := Type_Low_Bound  (T2);
  1967.             HB2 : constant Node_Id := Type_High_Bound (T2);
  1968.  
  1969.          begin
  1970.             --  If the bounds are the same tree node, then match
  1971.  
  1972.             if LB1 = LB2 and then HB1 = HB2 then
  1973.                return True;
  1974.  
  1975.             --  Otherwise bounds must be static and identical value
  1976.  
  1977.             else
  1978.                if not Is_Static_Subtype (T1)
  1979.                  or else not Is_Static_Subtype (T2)
  1980.                then
  1981.                   return False;
  1982.  
  1983.                --  If either type has constraint error bounds, then consider
  1984.                --  that they match to avoid junk cascaded errors here.
  1985.  
  1986.                elsif not Is_OK_Static_Subtype (T1)
  1987.                  or else not Is_OK_Static_Subtype (T2)
  1988.                then
  1989.                   return True;
  1990.  
  1991.                elsif Is_Real_Type (T1) then
  1992.                   return
  1993.                     (Expr_Value_R (LB1) = Expr_Value_R (LB2))
  1994.                       and then
  1995.                     (Expr_Value_R (HB1) = Expr_Value_R (HB2));
  1996.  
  1997.                else
  1998.                   return
  1999.                     Expr_Value (LB1) = Expr_Value (LB2)
  2000.                       and then
  2001.                     Expr_Value (HB1) = Expr_Value (HB2);
  2002.                end if;
  2003.             end if;
  2004.          end;
  2005.  
  2006.       --  Type with discriminants
  2007.  
  2008.       elsif Has_Discriminants (T1) then
  2009.          declare
  2010.             DL1 : constant Elist_Id := Discriminant_Constraint (T1);
  2011.             DL2 : constant Elist_Id := Discriminant_Constraint (T2);
  2012.  
  2013.             DA1 : Elmt_Id := First_Elmt (DL1);
  2014.             DA2 : Elmt_Id := First_Elmt (DL2);
  2015.  
  2016.          begin
  2017.             if DL1 = DL2 then
  2018.                return True;
  2019.             end if;
  2020.  
  2021.  
  2022.             while Present (DA1) loop
  2023.                declare
  2024.                   Expr1 : constant Node_Id := Node (DA1);
  2025.                   Expr2 : constant Node_Id := Node (DA2);
  2026.  
  2027.                begin
  2028.                   if not Is_Static_Expression (Expr1)
  2029.                     or else not Is_Static_Expression (Expr2)
  2030.                   then
  2031.                      return False;
  2032.  
  2033.                   --  If either expression raised a constraint error,
  2034.                   --  consider the expressions as matching, since this
  2035.                   --  helps to prevent cascading errors.
  2036.  
  2037.                   elsif Raises_Constraint_Error (Expr1)
  2038.                     or else Raises_Constraint_Error (Expr2)
  2039.                   then
  2040.                      null;
  2041.  
  2042.                   elsif Expr_Value (Expr1) /= Expr_Value (Expr2) then
  2043.                      return False;
  2044.                   end if;
  2045.                end;
  2046.  
  2047.                DA1 := Next_Elmt (DA1);
  2048.                DA2 := Next_Elmt (DA2);
  2049.             end loop;
  2050.          end;
  2051.  
  2052.          return True;
  2053.  
  2054.       --  Array type
  2055.  
  2056.       elsif Is_Array_Type (T1) then
  2057.          declare
  2058.             Index1 : Node_Id := First_Index (T1);
  2059.             Index2 : Node_Id := First_Index (T2);
  2060.  
  2061.          begin
  2062.             while Present (Index1) loop
  2063.                if not
  2064.                  Subtypes_Statically_Match (Etype (Index1), Etype (Index2))
  2065.                then
  2066.                   return False;
  2067.                end if;
  2068.  
  2069.                Index1 := Next_Index (Index1);
  2070.                Index2 := Next_Index (Index2);
  2071.             end loop;
  2072.  
  2073.             return True;
  2074.          end;
  2075.  
  2076.       --  All other types definitely match
  2077.  
  2078.       else
  2079.          return True;
  2080.       end if;
  2081.    end Subtypes_Statically_Match;
  2082.  
  2083.    ----------
  2084.    -- Test --
  2085.    ----------
  2086.  
  2087.    function Test (Cond : Boolean) return Uint is
  2088.    begin
  2089.       if Cond then
  2090.          return Uint_1;
  2091.       else
  2092.          return Uint_0;
  2093.       end if;
  2094.    end Test;
  2095.  
  2096.    --------------
  2097.    -- To_Bits --
  2098.    --------------
  2099.  
  2100.    procedure To_Bits (U : Uint; B : out Bits) is
  2101.    begin
  2102.       for J in 0 .. B'Last loop
  2103.          B (J) := (U / (2 ** J)) mod 2 /= 0;
  2104.       end loop;
  2105.    end To_Bits;
  2106.  
  2107. end Sem_Eval;
  2108.