aboutsummaryrefslogtreecommitdiffstats
path: root/translate/translation.adb
diff options
context:
space:
mode:
Diffstat (limited to 'translate/translation.adb')
-rw-r--r--translate/translation.adb336
1 files changed, 215 insertions, 121 deletions
diff --git a/translate/translation.adb b/translate/translation.adb
index 7881530c5..a55314a4a 100644
--- a/translate/translation.adb
+++ b/translate/translation.adb
@@ -1377,8 +1377,15 @@ package body Translation is
function Get_Resolv_Ortho_Decl (Func : Iir) return O_Dnode
is
+ Info : Subprg_Resolv_Info_Acc;
begin
- return Get_Info (Func).Subprg_Resolv.Resolv_Func;
+ Info := Get_Info (Func).Subprg_Resolv;
+ if Info = null then
+ -- Maybe the resolver is not used.
+ return O_Dnode_Null;
+ else
+ return Info.Resolv_Func;
+ end if;
end Get_Resolv_Ortho_Decl;
-- Return true is INFO is a type info for a composite type, ie:
@@ -1987,8 +1994,10 @@ package body Translation is
-- Get the offset in the range pointed by RANGE_PTR of INDEX.
-- This checks INDEX belongs to the range.
+ -- INDEX_TYPE is the subtype of the array index.
function Translate_Index_To_Offset (Range_Ptr : O_Dnode;
Index : O_Enode;
+ Index_Expr : Iir;
Index_Type : Iir;
Loc : Iir)
return O_Enode;
@@ -2249,6 +2258,9 @@ package body Translation is
-- Close the temporary region.
procedure Close_Temp;
+ -- Check there is no temporary region.
+ procedure Check_No_Temp;
+
-- Free all old temp.
-- Used only to free memory.
procedure Free_Old_Temp;
@@ -3099,6 +3111,9 @@ package body Translation is
-- never deallocated.
Old_Level : Temp_Level_Acc := null;
+ -- If set, emit comments for open_temp/close_temp.
+ Flag_Debug_Temp : constant Boolean := False;
+
procedure Open_Temp
is
L : Temp_Level_Acc;
@@ -3119,6 +3134,10 @@ package body Translation is
L.Level := Temp_Level.Level + 1;
end if;
Temp_Level := L;
+ if Flag_Debug_Temp then
+ New_Debug_Comment_Stmt
+ ("Open_Temp level " & Natural'Image (L.Level));
+ end if;
end Open_Temp;
procedure Add_Transient_Type_In_Temp (Atype : Iir)
@@ -3139,6 +3158,11 @@ package body Translation is
-- OPEN_TEMP was not called.
raise Internal_Error;
end if;
+ if Flag_Debug_Temp then
+ New_Debug_Comment_Stmt
+ ("Close_Temp level " & Natural'Image (Temp_Level.Level));
+ end if;
+
if Temp_Level.Stack2_Mark /= O_Dnode_Null then
Start_Association (Constr, Ghdl_Stack2_Release);
New_Association (Constr,
@@ -3171,6 +3195,13 @@ package body Translation is
Old_Level := L;
end Close_Temp;
+ procedure Check_No_Temp is
+ begin
+ if Temp_Level /= null then
+ raise Internal_Error;
+ end if;
+ end Check_No_Temp;
+
procedure Free_Old_Temp
is
procedure Free is new Ada.Unchecked_Deallocation
@@ -4258,8 +4289,7 @@ package body Translation is
Chap7.Translate_Expression
(Get_Nth_Element (Get_Index_List (Spec), 0),
Iter_Type),
- Iter_Type,
- Spec),
+ Scheme, Iter_Type, Spec),
True);
Close_Temp;
end;
@@ -4289,8 +4319,7 @@ package body Translation is
(Range_Ptr,
New_Value (New_Selected_Element
(New_Obj (Slice), Type_Info.T.Range_Left)),
- Iter_Type,
- Spec));
+ Spec, Iter_Type, Spec));
Right := Create_Temp_Init
(Ghdl_Index_Type,
Chap6.Translate_Index_To_Offset
@@ -4298,8 +4327,7 @@ package body Translation is
New_Value (New_Selected_Element
(New_Obj (Slice),
Type_Info.T.Range_Right)),
- Iter_Type,
- Spec));
+ Spec, Iter_Type, Spec));
Index := Create_Temp (Ghdl_Index_Type);
High := Create_Temp (Ghdl_Index_Type);
Start_If_Stmt
@@ -4786,6 +4814,8 @@ package body Translation is
Chap4.Elab_Declaration_Chain (Subprg, Final);
+ pragma Debug (Check_No_Temp);
+
-- If finalization is required, create a dummy loop around the
-- body and convert returns into exit out of this loop.
-- If the subprogram is a function, also create a variable for the
@@ -4838,6 +4868,8 @@ package body Translation is
Finish_Subprogram_Body;
+ pragma Debug (Check_No_Temp);
+
Pop_Identifier_Prefix (Mark);
end Translate_Subprogram_Body;
@@ -5318,7 +5350,7 @@ package body Translation is
Info.C := new Complex_Type_Info;
Info.C.Size_Var (Mode_Value) := Create_Var
(Create_Var_Identifier ("SIZE"), Ghdl_Index_Type);
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
Info.C.Size_Var (Mode_Signal) := Create_Var
(Create_Var_Identifier ("SIGSIZE"), Ghdl_Index_Type);
end if;
@@ -5790,7 +5822,7 @@ package body Translation is
-------------
function Type_To_Last_Object_Kind (Def : Iir) return Object_Kind_Type is
begin
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
return Mode_Signal;
else
return Mode_Value;
@@ -6015,7 +6047,7 @@ package body Translation is
if not Completion then
Create_Array_Fat_Pointer (Info, Mode_Value);
end if;
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
Create_Array_Fat_Pointer (Info, Mode_Signal);
end if;
Finish_Type_Definition (Info, Completion);
@@ -6083,6 +6115,7 @@ package body Translation is
else
-- Length is known. Create a constrained array.
Info.Type_Mode := Type_Mode_Array;
+ Info.Ortho_Type (Mode_Signal) := O_Tnode_Null;
for I in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
case I is
when Mode_Value =>
@@ -6342,6 +6375,7 @@ package body Translation is
El := Get_Chain (El);
end loop;
+ Info.Ortho_Type (Mode_Signal) := O_Tnode_Null;
for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
Start_Record_Type (El_List);
El := Get_Element_Declaration_Chain (Def);
@@ -6355,9 +6389,6 @@ package body Translation is
end loop;
Finish_Record_Type (El_List, Info.Ortho_Type (Kind));
end loop;
- if Get_Signal_Type_Flag (Def) = False then
- Info.Ortho_Type (Mode_Signal) := O_Tnode_Null;
- end if;
Info.Type_Mode := Type_Mode_Record;
Finish_Type_Definition (Info);
@@ -6717,7 +6748,6 @@ package body Translation is
Chap2.Finish_Subprg_Instance_Use (Info.T.Prot_Final_Instance);
Finish_Subprogram_Body;
-
end Translate_Protected_Type_Body_Subprograms;
---------------
@@ -7355,7 +7385,7 @@ package body Translation is
-- Declare subprograms.
Id := Get_Identifier (Decl);
Create_Builder_Subprogram_Decl (Tinfo, Id, Mode_Value);
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
Create_Builder_Subprogram_Decl (Tinfo, Id, Mode_Signal);
end if;
@@ -7367,12 +7397,12 @@ package body Translation is
case Get_Kind (Def) is
when Iir_Kind_Array_Type_Definition =>
Create_Array_Type_Builder (Def, Mode_Value);
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
Create_Array_Type_Builder (Def, Mode_Signal);
end if;
when Iir_Kind_Record_Type_Definition =>
Create_Record_Type_Builder (Def, Mode_Value);
- if Get_Signal_Type_Flag (Def) then
+ if Get_Has_Signal_Flag (Def) then
Create_Record_Type_Builder (Def, Mode_Signal);
end if;
when others =>
@@ -8758,12 +8788,9 @@ package body Translation is
-- FIXME: to be improved ?
-- Only required for transient types.
- -- FIXME: check this (why open/close_temp ?)
- Open_Temp;
Define_Global_Const
(Info.Object_Var,
Chap7.Translate_Static_Expression (Val, Def));
- Close_Temp;
end if;
when others =>
Error_Kind ("create_objet", El);
@@ -10170,40 +10197,6 @@ package body Translation is
end case;
end Translate_Declaration;
- -- Mark FUNC (by adding the subprg_resolv info) iif it can be a
- -- resolution function.
- procedure Check_Resolution_Function (Func : Iir)
- is
- Param : Iir;
- Param_Type : Iir;
- Res_Type : Iir;
- Info : Subprg_Info_Acc;
- begin
- Param := Get_Interface_Declaration_Chain (Func);
-
- -- Return now if the number of parameters is not 1.
- if Param = Null_Iir or else Get_Chain (Param) /= Null_Iir then
- return;
- end if;
- Param_Type := Get_Type (Param);
- case Get_Kind (Param_Type) is
- when Iir_Kind_Array_Type_Definition
- | Iir_Kind_Unconstrained_Array_Subtype_Definition =>
- null;
- when others =>
- return;
- end case;
- Res_Type := Get_Return_Type (Func);
- if Get_Base_Type (Get_Element_Subtype (Param_Type))
- /= Get_Base_Type (Res_Type)
- then
- return;
- end if;
- -- FUNC can be a resolution function.
- Info := Get_Info (Func);
- Info.Subprg_Resolv := new Subprg_Resolv_Info;
- end Check_Resolution_Function;
-
procedure Translate_Resolution_Function (Func : Iir; Block : Iir)
is
-- Type of the resolution function parameter.
@@ -10592,8 +10585,10 @@ package body Translation is
else
Info := Add_Info (El, Kind_Subprg);
Chap2.Translate_Subprogram_Interfaces (El);
- if Get_Kind (El) = Iir_Kind_Function_Declaration then
- Check_Resolution_Function (El);
+ if Get_Kind (El) = Iir_Kind_Function_Declaration
+ and then Get_Resolution_Function_Flag (El)
+ then
+ Info.Subprg_Resolv := new Subprg_Resolv_Info;
end if;
end if;
when Iir_Kind_Function_Body
@@ -12044,8 +12039,34 @@ package body Translation is
Finish_If_Stmt (If_Blk);
end Check_Bound_Error;
+ -- Return TRUE if an array whose index type is RNG_TYPE indexed by
+ -- an expression of type EXPR_TYPE needs a bound check.
+ function Need_Index_Check (Expr_Type : Iir; Rng_Type : Iir)
+ return Boolean
+ is
+ Rng : Iir;
+ begin
+ -- No check if the expression has the type of the index.
+ if Expr_Type = Rng_Type then
+ return False;
+ end if;
+
+ -- No check for 'Range or 'Reverse_Range.
+ Rng := Get_Range_Constraint (Expr_Type);
+ if (Get_Kind (Rng) = Iir_Kind_Range_Array_Attribute
+ or Get_Kind (Rng) = Iir_Kind_Reverse_Range_Array_Attribute)
+ and then Get_Type (Rng) = Rng_Type
+ then
+ return False;
+ end if;
+
+ return True;
+ end Need_Index_Check;
+
+
function Translate_Index_To_Offset (Range_Ptr : O_Dnode;
Index : O_Enode;
+ Index_Expr : Iir;
Index_Type : Iir;
Loc : Iir)
return O_Enode
@@ -12059,7 +12080,7 @@ package body Translation is
Bound_Node : O_Dnode;
Index_Info : Type_Info_Acc;
begin
- Index_Info := Get_Info (Index_Type);
+ Index_Info := Get_Info (Get_Base_Type (Index_Type));
Res := Create_Temp (Ghdl_Index_Type);
@@ -12098,20 +12119,22 @@ package body Translation is
Ghdl_Index_Type));
-- Check bounds.
- Cond1 := New_Compare_Op
- (ON_Lt,
- New_Obj_Value (Off),
- New_Lit (New_Signed_Literal (Index_Info.Ortho_Type (Mode_Value),
- 0)),
- Ghdl_Bool_Type);
-
- Cond2 := New_Compare_Op
- (ON_Ge,
- New_Obj_Value (Res),
- New_Value_Selected_Acc_Value (New_Obj (Range_Ptr),
- Index_Info.T.Range_Length),
- Ghdl_Bool_Type);
- Check_Bound_Error (New_Dyadic_Op (ON_Or, Cond1, Cond2), Loc, 0);
+ if Need_Index_Check (Get_Type (Index_Expr), Index_Type) then
+ Cond1 := New_Compare_Op
+ (ON_Lt,
+ New_Obj_Value (Off),
+ New_Lit (New_Signed_Literal (Index_Info.Ortho_Type (Mode_Value),
+ 0)),
+ Ghdl_Bool_Type);
+
+ Cond2 := New_Compare_Op
+ (ON_Ge,
+ New_Obj_Value (Res),
+ New_Value_Selected_Acc_Value (New_Obj (Range_Ptr),
+ Index_Info.T.Range_Length),
+ Ghdl_Bool_Type);
+ Check_Bound_Error (New_Dyadic_Op (ON_Or, Cond1, Cond2), Loc, 0);
+ end if;
Close_Temp;
@@ -12250,8 +12273,7 @@ package body Translation is
R := Translate_Index_To_Offset
(M2Dp (Range_Ptr),
Chap7.Translate_Expression (Index, Ibasetype),
- Ibasetype,
- Index);
+ Index, Itype, Index);
when Type_Mode_Array =>
-- BASE is a thin array.
R := Translate_Thin_Index_Offset (Itype, Dim, Index);
@@ -12340,11 +12362,11 @@ package body Translation is
Index_Type := Get_Nth_Element
(Get_Index_Subtype_List (Prefix_Type), 0);
+ Kind := Get_Object_Kind (Prefix);
+
-- Evaluate slice bounds.
Chap3.Create_Array_Subtype (Slice_Type, True);
- Kind := Get_Object_Kind (Prefix);
-
Prefix_Info := Get_Info (Prefix_Type);
Slice_Info := Get_Info (Slice_Type);
@@ -12545,7 +12567,6 @@ package body Translation is
end case;
--Finish_If_Stmt (If_Blk);
-
end Translate_Slice_Name;
function Translate_Interface_Name
@@ -13403,7 +13424,8 @@ package body Translation is
Formal_Base := Get_Base_Name (Formal);
case Get_Kind (Formal_Base) is
- when Iir_Kind_Constant_Interface_Declaration =>
+ when Iir_Kind_Constant_Interface_Declaration
+ | Iir_Kind_File_Interface_Declaration =>
return Translate_Expression (Actual, Get_Type (Formal_Base));
when Iir_Kind_Signal_Interface_Declaration =>
return Translate_Implicit_Conv
@@ -15757,34 +15779,93 @@ package body Translation is
end case;
end Translate_Expression;
--- procedure Translate_Range_Expression
--- (Res : O_Lnode; Expr : Iir; Range_Type : Iir)
--- is
--- T_Info : Type_Info_Acc;
--- begin
--- T_Info := Get_Info (Range_Type);
--- Open_Temp;
--- New_Assign_Stmt
--- (New_Selected_Element (Res, T_Info.T.Range_Left),
--- Chap7.Translate_Range_Expression_Left (Expr, Range_Type));
--- New_Assign_Stmt
--- (New_Selected_Element (Res, T_Info.T.Range_Right),
--- Chap7.Translate_Range_Expression_Right (Expr, Range_Type));
--- New_Assign_Stmt (New_Selected_Element (Res, T_Info.T.Range_Dir),
--- Chap7.Translate_Static_Range_Dir (Expr));
--- if T_Info.T.Range_Length /= O_Fnode_Null then
--- Open_Temp;
--- New_Assign_Stmt (New_Selected_Element (Res, T_Info.T.Range_Length),
--- Chap7.Translate_Range_Expression_Length (Expr));
--- Close_Temp;
--- end if;
--- Close_Temp;
--- end Translate_Range_Expression;
+ -- Check if RNG is of the form:
+ -- 1 to T'length
+ -- or T'Length downto 1
+ -- or 0 to T'length - 1
+ -- or T'Length - 1 downto 0
+ -- In either of these cases, return T'Length
+ function Is_Length_Range_Expression (Rng : Iir_Range_Expression)
+ return Iir
+ is
+ -- Pattern of a bound.
+ type Length_Pattern is
+ (
+ Pat_Unknown,
+ Pat_Length,
+ Pat_Length_1, -- Length - 1
+ Pat_1,
+ Pat_0
+ );
+ Length_Attr : Iir := Null_Iir;
+
+ -- Classify the bound.
+ -- Set LENGTH_ATTR is the pattern is Pat_Length.
+ function Get_Length_Pattern (Expr : Iir; Recurse : Boolean)
+ return Length_Pattern
+ is
+ begin
+ case Get_Kind (Expr) is
+ when Iir_Kind_Length_Array_Attribute =>
+ Length_Attr := Expr;
+ return Pat_Length;
+ when Iir_Kind_Integer_Literal =>
+ case Get_Value (Expr) is
+ when 0 =>
+ return Pat_0;
+ when 1 =>
+ return Pat_1;
+ when others =>
+ return Pat_Unknown;
+ end case;
+ when Iir_Kind_Substraction_Operator =>
+ if not Recurse then
+ return Pat_Unknown;
+ end if;
+ if Get_Length_Pattern (Get_Left (Expr), False) = Pat_Length
+ and then
+ Get_Length_Pattern (Get_Right (Expr), False) = Pat_1
+ then
+ return Pat_Length_1;
+ else
+ return Pat_Unknown;
+ end if;
+ when others =>
+ return Pat_Unknown;
+ end case;
+ end Get_Length_Pattern;
+ Left_Pat, Right_Pat : Length_Pattern;
+ begin
+ Left_Pat := Get_Length_Pattern (Get_Left_Limit (Rng), True);
+ if Left_Pat = Pat_Unknown then
+ return Null_Iir;
+ end if;
+ Right_Pat := Get_Length_Pattern (Get_Right_Limit (Rng), True);
+ if Right_Pat = Pat_Unknown then
+ return Null_Iir;
+ end if;
+ case Get_Direction (Rng) is
+ when Iir_To =>
+ if (Left_Pat = Pat_1 and Right_Pat = Pat_Length)
+ or else (Left_Pat = Pat_0 and Right_Pat = Pat_Length_1)
+ then
+ return Length_Attr;
+ end if;
+ when Iir_Downto =>
+ if (Left_Pat = Pat_Length and Right_Pat = Pat_1)
+ or else (Left_Pat = Pat_Length_1 and Right_Pat = Pat_0)
+ then
+ return Length_Attr;
+ end if;
+ end case;
+ return Null_Iir;
+ end Is_Length_Range_Expression;
procedure Translate_Range_Expression_Ptr
(Res_Ptr : O_Dnode; Expr : Iir; Range_Type : Iir)
is
T_Info : Type_Info_Acc;
+ Length_Attr : Iir;
begin
T_Info := Get_Info (Range_Type);
Open_Temp;
@@ -15804,17 +15885,26 @@ package body Translation is
T_Info.T.Range_Length),
New_Lit (Translate_Static_Range_Length (Expr)));
else
- Open_Temp;
- New_Assign_Stmt
- (New_Selected_Acc_Value (New_Obj (Res_Ptr),
- T_Info.T.Range_Length),
- Compute_Range_Length
- (New_Value_Selected_Acc_Value (New_Obj (Res_Ptr),
- T_Info.T.Range_Left),
- New_Value_Selected_Acc_Value (New_Obj (Res_Ptr),
- T_Info.T.Range_Right),
- Get_Direction (Expr)));
- Close_Temp;
+ Length_Attr := Is_Length_Range_Expression (Expr);
+ if Length_Attr = Null_Iir then
+ Open_Temp;
+ New_Assign_Stmt
+ (New_Selected_Acc_Value (New_Obj (Res_Ptr),
+ T_Info.T.Range_Length),
+ Compute_Range_Length
+ (New_Value_Selected_Acc_Value (New_Obj (Res_Ptr),
+ T_Info.T.Range_Left),
+ New_Value_Selected_Acc_Value (New_Obj (Res_Ptr),
+ T_Info.T.Range_Right),
+ Get_Direction (Expr)));
+ Close_Temp;
+ else
+ New_Assign_Stmt
+ (New_Selected_Acc_Value (New_Obj (Res_Ptr),
+ T_Info.T.Range_Length),
+ Chap14.Translate_Length_Array_Attribute
+ (Length_Attr, Null_Iir));
+ end if;
end if;
end if;
Close_Temp;
@@ -24406,20 +24496,24 @@ package body Translation is
New_Record_Aggr_El (Aggr, New_Rti_Address (Base_Info.Type_Rti));
New_Record_Aggr_El (Aggr, Var_Acc_To_Loc (Bounds));
for I in Mode_Value .. Mode_Signal loop
- if I = Mode_Signal and then not Get_Signal_Type_Flag (Atype) then
- Val := Get_Null_Loc;
- else
- case Info.Type_Mode is
- when Type_Mode_Array =>
+ case Info.Type_Mode is
+ when Type_Mode_Array =>
+ if Info.Ortho_Type (I) /= O_Tnode_Null then
Val := New_Union_Aggr (Ghdl_Rti_Loc, Ghdl_Rti_Loc_Offset,
New_Sizeof (Info.Ortho_Type (I),
Ghdl_Index_Type));
- when Type_Mode_Ptr_Array =>
+ else
+ Val := Get_Null_Loc;
+ end if;
+ when Type_Mode_Ptr_Array =>
+ if Info.C.Size_Var (I) /= null then
Val := Var_Acc_To_Loc (Info.C.Size_Var (I));
- when others =>
- Error_Kind ("generate_array_subtype_definition", Atype);
- end case;
- end if;
+ else
+ Val := Get_Null_Loc;
+ end if;
+ when others =>
+ Error_Kind ("generate_array_subtype_definition", Atype);
+ end case;
New_Record_Aggr_El (Aggr, Val);
end loop;