summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_eval.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_eval.adb')
-rw-r--r--gcc/ada/sem_eval.adb164
1 files changed, 73 insertions, 91 deletions
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 0b910a63aac..ba031b13f4c 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -32,6 +32,7 @@ with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
with Eval_Fat; use Eval_Fat;
+with Exp_Util; use Exp_Util;
with Nmake; use Nmake;
with Nlists; use Nlists;
with Opt; use Opt;
@@ -127,14 +128,6 @@ package body Sem_Eval is
-- Local Subprograms --
-----------------------
- function Constant_Array_Ref (Op : Node_Id) return Node_Id;
- -- The caller has checked that Op is an array reference (i.e. that its
- -- node kind is N_Indexed_Component). If the array reference is constant
- -- at compile time, and yields a constant value of a discrete type, then
- -- the expression node for the constant value is returned. otherwise Empty
- -- is returned. This is used by Compile_Time_Known_Value, as well as by
- -- Expr_Value and Expr_Rep_Value.
-
function From_Bits (B : Bits; T : Entity_Id) return Uint;
-- Converts a bit string of length B'Length to a Uint value to be used
-- for a target of type T, which is a modular type. This procedure
@@ -730,7 +723,6 @@ package body Sem_Eval is
function Compile_Time_Known_Value (Op : Node_Id) return Boolean is
K : constant Node_Kind := Nkind (Op);
CV_Ent : CV_Entry renames CV_Cache (Nat (Op) mod CV_Cache_Size);
- Val : Node_Id;
begin
-- Never known at compile time if bad type or raises constraint error
@@ -800,17 +792,6 @@ package body Sem_Eval is
elsif K = N_Attribute_Reference then
return Attribute_Name (Op) = Name_Null_Parameter;
-
- -- A reference to an element of a constant array may be constant.
-
- elsif K = N_Indexed_Component then
- Val := Constant_Array_Ref (Op);
-
- if Present (Val) then
- CV_Ent.N := Op;
- CV_Ent.V := Expr_Value (Val);
- return True;
- end if;
end if;
end if;
@@ -908,58 +889,6 @@ package body Sem_Eval is
end if;
end Compile_Time_Known_Value_Or_Aggr;
- ------------------------
- -- Constant_Array_Ref --
- ------------------------
-
- function Constant_Array_Ref (Op : Node_Id) return Node_Id is
- begin
- if List_Length (Expressions (Op)) = 1
- and then Is_Entity_Name (Prefix (Op))
- and then Ekind (Entity (Prefix (Op))) = E_Constant
- then
- declare
- Arr : constant Node_Id := Constant_Value (Entity (Prefix (Op)));
- Sub : constant Node_Id := First (Expressions (Op));
- Aty : constant Node_Id := Etype (Arr);
-
- Lin : Nat;
- -- Linear one's origin subscript value for array reference
-
- Lbd : Node_Id;
- -- Lower bound of the first array index
-
- Elm : Node_Id;
- -- Value from constant array
-
- begin
- if Ekind (Aty) = E_String_Literal_Subtype then
- Lbd := String_Literal_Low_Bound (Aty);
- else
- Lbd := Type_Low_Bound (Etype (First_Index (Aty)));
- end if;
-
- if Compile_Time_Known_Value (Sub)
- and then Nkind (Arr) = N_Aggregate
- and then Compile_Time_Known_Value (Lbd)
- and then Is_Discrete_Type (Component_Type (Aty))
- then
- Lin := UI_To_Int (Expr_Value (Sub) - Expr_Value (Lbd)) + 1;
-
- if List_Length (Expressions (Arr)) >= Lin then
- Elm := Pick (Expressions (Arr), Lin);
-
- if Compile_Time_Known_Value (Elm) then
- return Elm;
- end if;
- end if;
- end if;
- end;
- end if;
-
- return Empty;
- end Constant_Array_Ref;
-
-----------------
-- Eval_Actual --
-----------------
@@ -1140,7 +1069,6 @@ package body Sem_Eval is
end if;
Set_Is_Static_Expression (N, Stat);
-
end Eval_Arithmetic_Op;
----------------------------
@@ -1344,8 +1272,9 @@ package body Sem_Eval is
-- Eval_Indexed_Component --
----------------------------
- -- Indexed components are never static, so the only required processing
- -- is to perform the check for non-static context on the index values.
+ -- Indexed components are never static, so we need to perform the check
+ -- for non-static context on the index values. Then, we check if the
+ -- value can be obtained at compile time, even though it is non-static.
procedure Eval_Indexed_Component (N : Node_Id) is
Expr : Node_Id;
@@ -1357,6 +1286,74 @@ package body Sem_Eval is
Next (Expr);
end loop;
+ -- See if this is a constant array reference
+
+ if List_Length (Expressions (N)) = 1
+ and then Is_Entity_Name (Prefix (N))
+ and then Ekind (Entity (Prefix (N))) = E_Constant
+ and then Present (Constant_Value (Entity (Prefix (N))))
+ then
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Arr : constant Node_Id := Constant_Value (Entity (Prefix (N)));
+ Sub : constant Node_Id := First (Expressions (N));
+
+ Atyp : Entity_Id;
+ -- Type of array
+
+ Lin : Nat;
+ -- Linear one's origin subscript value for array reference
+
+ Lbd : Node_Id;
+ -- Lower bound of the first array index
+
+ Elm : Node_Id;
+ -- Value from constant array
+
+ begin
+ Atyp := Etype (Arr);
+
+ if Is_Access_Type (Atyp) then
+ Atyp := Designated_Type (Atyp);
+ end if;
+
+ -- If we have an array type (we should have but perhaps there
+ -- are error cases where this is not the case), then see if we
+ -- can do a constant evaluation of the array reference.
+
+ if Is_Array_Type (Atyp) then
+ if Ekind (Atyp) = E_String_Literal_Subtype then
+ Lbd := String_Literal_Low_Bound (Atyp);
+ else
+ Lbd := Type_Low_Bound (Etype (First_Index (Atyp)));
+ end if;
+
+ if Compile_Time_Known_Value (Sub)
+ and then Nkind (Arr) = N_Aggregate
+ and then Compile_Time_Known_Value (Lbd)
+ and then Is_Discrete_Type (Component_Type (Atyp))
+ then
+ Lin := UI_To_Int (Expr_Value (Sub) - Expr_Value (Lbd)) + 1;
+
+ if List_Length (Expressions (Arr)) >= Lin then
+ Elm := Pick (Expressions (Arr), Lin);
+
+ -- If the resulting expression is compile time known,
+ -- then we can rewrite the indexed component with this
+ -- value, being sure to mark the result as non-static.
+ -- We also reset the Sloc, in case this generates an
+ -- error later on (e.g. 136'Access).
+
+ if Compile_Time_Known_Value (Elm) then
+ Rewrite (N, Duplicate_Subexpr_No_Checks (Elm));
+ Set_Is_Static_Expression (N, False);
+ Set_Sloc (N, Loc);
+ end if;
+ end if;
+ end if;
+ end if;
+ end;
+ end if;
end Eval_Indexed_Component;
--------------------------
@@ -2465,7 +2462,6 @@ package body Sem_Eval is
function Expr_Rep_Value (N : Node_Id) return Uint is
Kind : constant Node_Kind := Nkind (N);
Ent : Entity_Id;
- Vexp : Node_Id;
begin
if Is_Entity_Name (N) then
@@ -2506,14 +2502,8 @@ package body Sem_Eval is
then
return Uint_0;
- -- Array reference case
-
- elsif Kind = N_Indexed_Component then
- Vexp := Constant_Array_Ref (N);
- pragma Assert (Present (Vexp));
- return Expr_Rep_Value (Vexp);
-
-- Otherwise must be character literal
+
else
pragma Assert (Kind = N_Character_Literal);
Ent := Entity (N);
@@ -2541,7 +2531,6 @@ package body Sem_Eval is
CV_Ent : CV_Entry renames CV_Cache (Nat (N) mod CV_Cache_Size);
Ent : Entity_Id;
Val : Uint;
- Vexp : Node_Id;
begin
-- If already in cache, then we know it's compile time known and
@@ -2593,13 +2582,6 @@ package body Sem_Eval is
then
Val := Uint_0;
- -- Array reference case
-
- elsif Kind = N_Indexed_Component then
- Vexp := Constant_Array_Ref (N);
- pragma Assert (Present (Vexp));
- Val := Expr_Value (Vexp);
-
-- Otherwise must be character literal
else