summaryrefslogtreecommitdiff
path: root/translate/translation.adb
diff options
context:
space:
mode:
Diffstat (limited to 'translate/translation.adb')
-rw-r--r--translate/translation.adb163
1 files changed, 87 insertions, 76 deletions
diff --git a/translate/translation.adb b/translate/translation.adb
index 0d9e8bf..808cd3b 100644
--- a/translate/translation.adb
+++ b/translate/translation.adb
@@ -14028,31 +14028,29 @@ package body Translation is
is
use Name_Table;
- Lit_Type : Iir;
+ Lit_Type : constant Iir := Get_Type (Str);
+ Type_Info : constant Type_Info_Acc := Get_Info (Lit_Type);
Index_Type : Iir;
Bound_Aggr : O_Record_Aggr_List;
Index_Aggr : O_Record_Aggr_List;
Res_Aggr : O_Record_Aggr_List;
Res : O_Cnode;
- Type_Info : Type_Info_Acc;
Index_Type_Info : Type_Info_Acc;
Len : Int32;
Val : Var_Acc;
Bound : Var_Acc;
R : O_Enode;
begin
- Lit_Type := Get_Type (Str);
- Type_Info := Get_Info (Lit_Type);
-
-- Create the string value.
Len := Get_String_Length (Str);
Val := Create_String_Literal_Var (Str);
+ Index_Type :=
+ Get_First_Element (Get_Index_Subtype_List (Lit_Type));
+ Index_Type_Info := Get_Info (Index_Type);
+
if Type_Info.Type_Mode = Type_Mode_Fat_Array then
-- Create the string bound.
- Index_Type :=
- Get_First_Element (Get_Index_Subtype_List (Lit_Type));
- Index_Type_Info := Get_Info (Index_Type);
Start_Record_Aggr (Bound_Aggr, Type_Info.T.Bounds_Type);
Start_Record_Aggr (Index_Aggr, Index_Type_Info.T.Range_Type);
New_Record_Aggr_El
@@ -14093,7 +14091,15 @@ package body Translation is
(Create_Uniq_Identifier, Type_Info.Ortho_Type (Mode_Value),
O_Storage_Private, Res);
elsif Type_Info.Type_Mode = Type_Mode_Array then
- null;
+ -- Type of string literal isn't statically known; check the
+ -- length.
+ Chap6.Check_Bound_Error
+ (New_Compare_Op
+ (ON_Neq,
+ New_Lit (New_Index_Lit (Unsigned_64 (Len))),
+ Chap3.Get_Array_Type_Length (Lit_Type),
+ Ghdl_Bool_Type),
+ Str, 1);
else
raise Internal_Error;
end if;
@@ -15826,35 +15832,39 @@ package body Translation is
Var_Index : O_Dnode;
Targ : Mnode;
- Range_Ptr : Mnode;
Rinfo : Type_Info_Acc;
Bt : Iir;
- function Check_Value
- (Lval : Iir; Lop : ON_Op_Kind; Rval : Iir; Rop : ON_Op_Kind)
- return O_Enode
+ -- Generate code for: (LVAL lop RNG.left) or (RVAL rop RNG.right)
+ function Check_Value (Lval : Iir;
+ Lop : ON_Op_Kind;
+ Rval : Iir;
+ Rop : ON_Op_Kind;
+ Rng : Mnode)
+ return O_Enode
is
L, R : O_Enode;
begin
L := New_Compare_Op
(Lop,
New_Lit (Translate_Static_Expression (Lval, Bt)),
- M2E (Chap3.Range_To_Left (Range_Ptr)),
+ M2E (Chap3.Range_To_Left (Rng)),
Ghdl_Bool_Type);
R := New_Compare_Op
(Rop,
New_Lit (Translate_Static_Expression (Rval, Bt)),
- M2E (Chap3.Range_To_Right (Range_Ptr)),
+ M2E (Chap3.Range_To_Right (Rng)),
Ghdl_Bool_Type);
return New_Dyadic_Op (ON_Or, L, R);
end Check_Value;
+ Range_Ptr : Mnode;
Index_List : Iir_List;
Targ_Index_List : Iir_List;
Subtarg_Type : Iir;
Subaggr_Type : Iir;
L, H : Iir;
- Max : Iir_Int32;
+ Min : Iir_Int32;
Has_Others : Boolean;
Aggr_Info : Iir_Aggregate_Info;
@@ -15882,56 +15892,53 @@ package body Translation is
Bt := Get_Base_Type (Subaggr_Type);
Rinfo := Get_Info (Bt);
- if Get_Type_Staticness (Subaggr_Type) /= Locally then
- -- Aggregate has dynamic bounds.
- if Subaggr_Type /= Subtarg_Type then
- -- And it is not the same as the target.
- -- Must be checked.
-
- Open_Temp;
- declare
- A_Range : O_Dnode;
- Rng_Ptr : O_Dnode;
- begin
- -- Evaluate the range.
- Chap3.Translate_Anonymous_Type_Definition
- (Subaggr_Type, True);
-
- A_Range := Create_Temp (Rinfo.T.Range_Type);
- Rng_Ptr := Create_Temp_Ptr
- (Rinfo.T.Range_Ptr_Type, New_Obj (A_Range));
- Chap7.Translate_Range_Ptr
- (Rng_Ptr,
- Get_Range_Constraint (Subaggr_Type),
- Subaggr_Type);
-
- -- Check range length VS target length.
- Chap6.Check_Bound_Error
- (New_Compare_Op
- (ON_Neq,
- M2E (Chap3.Range_To_Length
- (Dv2M (A_Range,
- Rinfo,
- Mode_Value,
- Rinfo.T.Range_Type,
- Rinfo.T.Range_Ptr_Type))),
- M2E (Chap3.Range_To_Length
- (Chap3.Bounds_To_Range
- (Bounds, Target_Type, I + 1))),
- Ghdl_Bool_Type),
- Aggr, I);
- end;
- Close_Temp;
- end if;
- else
+ if Get_Aggr_Dynamic_Flag (Aggr_Info) then
+ -- Dynamic range, must evaluate it.
+ Open_Temp;
+ declare
+ A_Range : O_Dnode;
+ Rng_Ptr : O_Dnode;
+ begin
+ -- Evaluate the range.
+ Chap3.Translate_Anonymous_Type_Definition
+ (Subaggr_Type, True);
+
+ A_Range := Create_Temp (Rinfo.T.Range_Type);
+ Rng_Ptr := Create_Temp_Ptr
+ (Rinfo.T.Range_Ptr_Type, New_Obj (A_Range));
+ Chap7.Translate_Range_Ptr
+ (Rng_Ptr,
+ Get_Range_Constraint (Subaggr_Type),
+ Subaggr_Type);
+
+ -- Check range length VS target length.
+ Chap6.Check_Bound_Error
+ (New_Compare_Op
+ (ON_Neq,
+ M2E (Chap3.Range_To_Length
+ (Dv2M (A_Range,
+ Rinfo,
+ Mode_Value,
+ Rinfo.T.Range_Type,
+ Rinfo.T.Range_Ptr_Type))),
+ M2E (Chap3.Range_To_Length
+ (Chap3.Bounds_To_Range
+ (Bounds, Target_Type, I + 1))),
+ Ghdl_Bool_Type),
+ Aggr, I);
+ end;
+ Close_Temp;
+ elsif Get_Type_Staticness (Subaggr_Type) /= Locally
+ or else Subaggr_Type /= Subtarg_Type
+ then
-- Note: if the aggregate has no others, then the bounds
-- must be the same, otherwise, aggregate bounds must be
-- inside type bounds.
Has_Others := Get_Aggr_Others_Flag (Aggr_Info);
- Max := Get_Aggr_Max_Length (Aggr_Info);
+ Min := Get_Aggr_Min_Length (Aggr_Info);
L := Get_Aggr_Low_Limit (Aggr_Info);
- if Max > 0 or L /= Null_Iir then
+ if Min > 0 or L /= Null_Iir then
Open_Temp;
-- Pointer to the range.
@@ -15941,6 +15948,9 @@ package body Translation is
H := Get_Aggr_High_Limit (Aggr_Info);
if L /= Null_Iir then
+ -- Check the index range of the aggregrate is equal
+ -- (or within in presence of 'others') the index range
+ -- of the target.
Start_If_Stmt
(If_Blk,
New_Compare_Op (ON_Eq,
@@ -15948,26 +15958,30 @@ package body Translation is
New_Lit (Ghdl_Dir_To_Node),
Ghdl_Bool_Type));
if Has_Others then
- E := Check_Value (L, ON_Lt, H, ON_Gt);
+ E := Check_Value (L, ON_Lt, H, ON_Gt, Range_Ptr);
else
- E := Check_Value (L, ON_Neq, H, ON_Neq);
+ E := Check_Value (L, ON_Neq, H, ON_Neq, Range_Ptr);
end if;
New_Assign_Stmt (New_Obj (Var_Err), E);
New_Else_Stmt (If_Blk);
if Has_Others then
- E := Check_Value (H, ON_Gt, L, ON_Lt);
+ E := Check_Value (H, ON_Gt, L, ON_Lt, Range_Ptr);
else
- E := Check_Value (H, ON_Neq, L, ON_Neq);
+ E := Check_Value (H, ON_Neq, L, ON_Neq, Range_Ptr);
end if;
New_Assign_Stmt (New_Obj (Var_Err), E);
Finish_If_Stmt (If_Blk);
- -- If L and H are greather than the maximum length,
- -- then there is no need to check with max.
- if Iir_Int32 (Eval_Pos (H) - Eval_Pos (L) + 1) >= Max then
- Max := 0;
+ -- If L and H are greather than the minimum length,
+ -- then there is no need to check with min.
+ if Iir_Int32 (Eval_Pos (H) - Eval_Pos (L) + 1) >= Min then
+ Min := 0;
end if;
end if;
- if Max > 0 then
+
+ if Min > 0 then
+ -- Check the number of elements is equal (or less in
+ -- presence of 'others') than the length of the index
+ -- range of the target.
if Has_Others then
Op := ON_Lt;
else
@@ -15977,7 +15991,7 @@ package body Translation is
(Op,
M2E (Chap3.Range_To_Length (Range_Ptr)),
New_Lit (New_Unsigned_Literal (Ghdl_Index_Type,
- Unsigned_64 (Max))),
+ Unsigned_64 (Min))),
Ghdl_Bool_Type);
if L /= Null_Iir then
E := New_Dyadic_Op (ON_Or, E, New_Obj_Value (Var_Err));
@@ -19274,14 +19288,11 @@ package body Translation is
procedure Translate_Variable_Assignment_Statement
(Stmt : Iir_Variable_Assignment_Statement)
is
- Target : Iir;
- Targ_Type : Iir;
- Expr : Iir;
+ Target : constant Iir := Get_Target (Stmt);
+ Targ_Type : constant Iir := Get_Type (Target);
+ Expr : constant Iir := Get_Expression (Stmt);
Targ_Node : Mnode;
begin
- Target := Get_Target (Stmt);
- Targ_Type := Get_Type (Target);
- Expr := Get_Expression (Stmt);
if Get_Kind (Target) = Iir_Kind_Aggregate then
declare
E : O_Enode;