aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2018-10-17 06:18:36 +0200
committerTristan Gingold <tgingold@free.fr>2018-10-21 08:03:37 +0200
commited7ad157dbecc784bb2df44684442e88431db561 (patch)
tree491533354ca2add405e08869f66c1c74622f97d7 /src/vhdl
parent13000af67c96c2a3417fa321daa3fbf50165f54f (diff)
downloadghdl-ed7ad157dbecc784bb2df44684442e88431db561.tar.gz
ghdl-ed7ad157dbecc784bb2df44684442e88431db561.tar.bz2
ghdl-ed7ad157dbecc784bb2df44684442e88431db561.zip
Rework translation of unbounded and complex types.
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/iirs.ads2
-rw-r--r--src/vhdl/sem_assocs.adb19
-rw-r--r--src/vhdl/sem_types.adb36
-rw-r--r--src/vhdl/translate/trans-chap12.adb9
-rw-r--r--src/vhdl/translate/trans-chap14.adb6
-rw-r--r--src/vhdl/translate/trans-chap2.adb46
-rw-r--r--src/vhdl/translate/trans-chap3.adb1426
-rw-r--r--src/vhdl/translate/trans-chap3.ads37
-rw-r--r--src/vhdl/translate/trans-chap4.adb93
-rw-r--r--src/vhdl/translate/trans-chap5.adb34
-rw-r--r--src/vhdl/translate/trans-chap6.adb44
-rw-r--r--src/vhdl/translate/trans-chap7.adb56
-rw-r--r--src/vhdl/translate/trans-chap8.adb5
-rw-r--r--src/vhdl/translate/trans-chap9.adb7
-rw-r--r--src/vhdl/translate/trans-helpers2.adb15
-rw-r--r--src/vhdl/translate/trans-rtis.adb249
-rw-r--r--src/vhdl/translate/trans-rtis.ads4
-rw-r--r--src/vhdl/translate/trans.adb49
-rw-r--r--src/vhdl/translate/trans.ads248
-rw-r--r--src/vhdl/translate/translation.adb35
20 files changed, 1219 insertions, 1201 deletions
diff --git a/src/vhdl/iirs.ads b/src/vhdl/iirs.ads
index fdc34ebcd..b88b35217 100644
--- a/src/vhdl/iirs.ads
+++ b/src/vhdl/iirs.ads
@@ -1798,7 +1798,7 @@ package Iirs is
--
-- Get/Set_Type (Field1)
--
- -- Corresponding element_declaration. FIXME: remove as supersided by
+ -- Corresponding element_declaration. FIXME: remove as superseeded by
-- element_position.
-- Get/Set_Element_Declaration (Field5)
--
diff --git a/src/vhdl/sem_assocs.adb b/src/vhdl/sem_assocs.adb
index 8cc5fbf74..971962288 100644
--- a/src/vhdl/sem_assocs.adb
+++ b/src/vhdl/sem_assocs.adb
@@ -1012,6 +1012,8 @@ package body Sem_Assocs is
if Get_Constraint_State (Atype) /= Fully_Constrained then
-- Some (sub-)elements are unbounded, create a bounded subtype.
declare
+ Inter : constant Iir :=
+ Get_Interface_Of_Formal (Get_Formal (Assoc));
Ntype : Iir;
Nel_List : Iir_Flist;
Nrec_El : Iir;
@@ -1025,6 +1027,12 @@ package body Sem_Assocs is
Set_Resolution_Indication
(Ntype, Get_Resolution_Indication (Atype));
end if;
+ if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration
+ then
+ -- The subtype is used for signals.
+ Set_Has_Signal_Flag (Ntype, True);
+ end if;
+
Nel_List := Create_Iir_Flist (Nbr_El);
Set_Elements_Declaration_List (Ntype, Nel_List);
@@ -1096,7 +1104,7 @@ package body Sem_Assocs is
-- individual association ASSOC: compute bounds, detect missing elements.
procedure Finish_Individual_Association (Assoc : Iir)
is
- Formal : Iir;
+ Inter : Iir;
Atype : Iir;
begin
-- Guard.
@@ -1104,8 +1112,8 @@ package body Sem_Assocs is
return;
end if;
- Formal := Get_Interface_Of_Formal (Get_Formal (Assoc));
- Atype := Get_Type (Formal);
+ Inter := Get_Interface_Of_Formal (Get_Formal (Assoc));
+ Atype := Get_Type (Inter);
Set_Whole_Association_Flag (Assoc, True);
case Get_Kind (Atype) is
@@ -1118,6 +1126,11 @@ package body Sem_Assocs is
Atype := Create_Array_Subtype (Atype, Get_Location (Assoc));
Set_Index_Constraint_Flag (Atype, True);
Set_Constraint_State (Atype, Fully_Constrained);
+ if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration
+ then
+ -- The subtype is used for signals.
+ Set_Has_Signal_Flag (Atype, True);
+ end if;
Set_Actual_Type (Assoc, Atype);
Set_Actual_Type_Definition (Assoc, Atype);
Finish_Individual_Assoc_Array (Assoc, Assoc, 1);
diff --git a/src/vhdl/sem_types.adb b/src/vhdl/sem_types.adb
index 843f549e4..47432e140 100644
--- a/src/vhdl/sem_types.adb
+++ b/src/vhdl/sem_types.adb
@@ -1394,6 +1394,31 @@ package body Sem_Types is
(Def : Iir; Type_Mark : Iir; Resolution : Iir)
return Iir;
+ function Copy_Record_Element_Declaration (El : Iir; Parent : Iir) return Iir
+ is
+ New_El : Iir;
+ begin
+ case Get_Kind (El) is
+ when Iir_Kind_Element_Declaration =>
+ New_El := Create_Iir (Iir_Kind_Element_Declaration);
+ -- As this is a copy, it has no subtype indication.
+ Set_Subtype_Indication (New_El, Null_Iir);
+ when Iir_Kind_Record_Element_Constraint =>
+ New_El := Create_Iir (Iir_Kind_Record_Element_Constraint);
+ Set_Element_Declaration (New_El, Get_Element_Declaration (El));
+ when others =>
+ Error_Kind ("copy_record_element_declaration", El);
+ end case;
+ Location_Copy (New_El, El);
+ Set_Parent (New_El, Parent);
+ Set_Identifier (New_El, Get_Identifier (El));
+ Set_Type (New_El, Get_Type (El));
+ Set_Base_Element_Declaration
+ (New_El, Get_Base_Element_Declaration (El));
+ Set_Element_Position (New_El, Get_Element_Position (El));
+ return New_El;
+ end Copy_Record_Element_Declaration;
+
-- Create a copy of elements_declaration_list of SRC and set it to DST.
procedure Copy_Record_Elements_Declaration_List (Dst : Iir; Src : Iir)
is
@@ -1405,14 +1430,7 @@ package body Sem_Types is
Set_Elements_Declaration_List (Dst, New_El_List);
for I in Flist_First .. Flist_Last (El_List) loop
El := Get_Nth_Element (El_List, I);
- New_El := Create_Iir (Iir_Kind_Element_Declaration);
- Location_Copy (New_El, El);
- Set_Parent (New_El, Dst);
- Set_Identifier (New_El, Get_Identifier (El));
- Set_Type (New_El, Get_Type (El));
- Set_Base_Element_Declaration (New_El,
- Get_Base_Element_Declaration (El));
- Set_Element_Position (New_El, Get_Element_Position (El));
+ New_El := Copy_Record_Element_Declaration (El, Dst);
Set_Nth_Element (New_El_List, I, New_El);
end loop;
end Copy_Record_Elements_Declaration_List;
@@ -2030,7 +2048,7 @@ package body Sem_Types is
if Els (I) = Null_Iir and Res_Els (I) = Null_Iir then
-- No new record element constraints. Copy the element from
-- the type mark.
- El := Tm_El;
+ El := Copy_Record_Element_Declaration (Tm_El, Res);
El_Type := Get_Type (El);
else
if Els (I) = Null_Iir then
diff --git a/src/vhdl/translate/trans-chap12.adb b/src/vhdl/translate/trans-chap12.adb
index cad732752..dfd50856c 100644
--- a/src/vhdl/translate/trans-chap12.adb
+++ b/src/vhdl/translate/trans-chap12.adb
@@ -85,11 +85,9 @@ package body Trans.Chap12 is
(Assoc, New_Lit (New_Unsigned_Literal (Ghdl_Index_Type,
Unsigned_64 (Elab_Nbr_Pkgs))));
New_Association
- (Assoc, New_Lit (New_Global_Address
- (Pkgs_Arr, Rtis.Ghdl_Rti_Arr_Acc)));
+ (Assoc, New_Address (New_Obj (Pkgs_Arr), Rtis.Ghdl_Rti_Arr_Acc));
New_Association
- (Assoc,
- New_Lit (Rtis.New_Rti_Address (Get_Info (Arch).Block_Rti_Const)));
+ (Assoc, Rtis.New_Rti_Address (Get_Info (Arch).Block_Rti_Const));
New_Association
(Assoc, New_Convert_Ov (Arch_Instance, Ghdl_Ptr_Type));
New_Procedure_Call (Assoc);
@@ -98,8 +96,7 @@ package body Trans.Chap12 is
Start_Association (Assoc, Ghdl_Rti_Add_Package);
New_Association
(Assoc,
- New_Lit (Rtis.New_Rti_Address
- (Get_Info (Standard_Package).Package_Rti_Const)));
+ Rtis.New_Rti_Address (Get_Info (Standard_Package).Package_Rti_Const));
New_Procedure_Call (Assoc);
end Call_Elab_Decls;
diff --git a/src/vhdl/translate/trans-chap14.adb b/src/vhdl/translate/trans-chap14.adb
index 2e554d556..b35cc9f81 100644
--- a/src/vhdl/translate/trans-chap14.adb
+++ b/src/vhdl/translate/trans-chap14.adb
@@ -809,8 +809,7 @@ package body Trans.Chap14 is
| Type_Mode_E32
| Type_Mode_P32
| Type_Mode_P64 =>
- New_Association
- (Assoc, New_Lit (Rtis.New_Rti_Address (Pinfo.Type_Rti)));
+ New_Association (Assoc, Rtis.New_Rti_Address (Pinfo.Type_Rti));
when Type_Mode_I32
| Type_Mode_I64
| Type_Mode_F64 =>
@@ -857,8 +856,7 @@ package body Trans.Chap14 is
| Type_Mode_E32
| Type_Mode_P32
| Type_Mode_P64 =>
- New_Association
- (Assoc, New_Lit (Rtis.New_Rti_Address (Pinfo.Type_Rti)));
+ New_Association (Assoc, Rtis.New_Rti_Address (Pinfo.Type_Rti));
when Type_Mode_I32
| Type_Mode_I64
| Type_Mode_F64 =>
diff --git a/src/vhdl/translate/trans-chap2.adb b/src/vhdl/translate/trans-chap2.adb
index 60040ea2e..374879857 100644
--- a/src/vhdl/translate/trans-chap2.adb
+++ b/src/vhdl/translate/trans-chap2.adb
@@ -1024,8 +1024,7 @@ package body Trans.Chap2 is
-- instantiated due to generate statements).
Start_Association (Constr, Ghdl_Rti_Add_Package);
New_Association
- (Constr,
- New_Lit (Rtis.New_Rti_Address (Info.Package_Rti_Const)));
+ (Constr, Rtis.New_Rti_Address (Info.Package_Rti_Const));
New_Procedure_Call (Constr);
end if;
@@ -1160,7 +1159,12 @@ package body Trans.Chap2 is
null;
when Kind_Type_Array
| Kind_Type_Record =>
- null;
+ B.Builder (Mode_Value).Builder_Instance :=
+ Instantiate_Subprg_Instance
+ (Orig.Builder (Mode_Value).Builder_Instance);
+ B.Builder (Mode_Signal).Builder_Instance :=
+ Instantiate_Subprg_Instance
+ (Orig.Builder (Mode_Signal).Builder_Instance);
when Kind_Type_File =>
null;
when Kind_Type_Protected =>
@@ -1187,7 +1191,7 @@ package body Trans.Chap2 is
Res.Range_Var := Instantiate_Var (Src.Range_Var);
when Kind_Type_Array
| Kind_Type_Record =>
- Res.Composite_Bounds := Instantiate_Var (Src.Composite_Bounds);
+ Res.Composite_Layout := Instantiate_Var (Src.Composite_Layout);
when Kind_Type_File =>
null;
when Kind_Type_Protected =>
@@ -1206,45 +1210,13 @@ package body Trans.Chap2 is
Type_Incomplete => Src.Type_Incomplete,
Type_Locally_Constrained =>
Src.Type_Locally_Constrained,
- C => null,
Ortho_Type => Src.Ortho_Type,
Ortho_Ptr_Type => Src.Ortho_Ptr_Type,
B => Src.B,
S => Copy_Info_Subtype (Src.S),
Type_Rti => Src.Type_Rti);
Adjust_Info_Basetype (Dest.B'Unrestricted_Access,
- Src.B'Unrestricted_Access);
- if Src.C /= null then
- Dest.C := new Complex_Type_Arr_Info'
- (Mode_Value =>
- (Mark => False,
- Size_Var => Instantiate_Var
- (Src.C (Mode_Value).Size_Var),
- Builder_Need_Func =>
- Src.C (Mode_Value).Builder_Need_Func,
- Builder_Instance => Instantiate_Subprg_Instance
- (Src.C (Mode_Value).Builder_Instance),
- Builder_Base_Param =>
- Src.C (Mode_Value).Builder_Base_Param,
- Builder_Bound_Param =>
- Src.C (Mode_Value).Builder_Bound_Param,
- Builder_Func =>
- Src.C (Mode_Value).Builder_Func),
- Mode_Signal =>
- (Mark => False,
- Size_Var => Instantiate_Var
- (Src.C (Mode_Signal).Size_Var),
- Builder_Need_Func =>
- Src.C (Mode_Signal).Builder_Need_Func,
- Builder_Instance => Instantiate_Subprg_Instance
- (Src.C (Mode_Signal).Builder_Instance),
- Builder_Base_Param =>
- Src.C (Mode_Signal).Builder_Base_Param,
- Builder_Bound_Param =>
- Src.C (Mode_Signal).Builder_Bound_Param,
- Builder_Func =>
- Src.C (Mode_Signal).Builder_Func));
- end if;
+ Src.B'Unrestricted_Access);
when Kind_Object =>
Dest.all :=
(Kind => Kind_Object,
diff --git a/src/vhdl/translate/trans-chap3.adb b/src/vhdl/translate/trans-chap3.adb
index ced7e1a94..624b95a25 100644
--- a/src/vhdl/translate/trans-chap3.adb
+++ b/src/vhdl/translate/trans-chap3.adb
@@ -32,8 +32,6 @@ with Translation;
package body Trans.Chap3 is
use Trans.Helpers;
- function Unbox_Record (Arr : Mnode) return Mnode;
-
function Create_Static_Type_Definition_Type_Range (Def : Iir)
return O_Cnode;
procedure Elab_Scalar_Type_Range (Def : Iir; Target : O_Lnode);
@@ -43,11 +41,114 @@ package body Trans.Chap3 is
Base : Iir;
Subtype_Info : Type_Info_Acc);
+ function Get_Composite_Type_Layout (Info : Type_Info_Acc) return Mnode
+ is
+ begin
+ case Info.Type_Mode is
+ when Type_Mode_Unbounded =>
+ raise Internal_Error;
+ when Type_Mode_Bounded_Arrays
+ | Type_Mode_Bounded_Records =>
+ return Varv2M (Info.S.Composite_Layout,
+ Info, Mode_Value,
+ Info.B.Layout_Type,
+ Info.B.Layout_Ptr_Type);
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Get_Composite_Type_Layout;
+
+ function Layout_To_Bounds (B : Mnode) return Mnode
+ is
+ Info : constant Type_Info_Acc := Get_Type_Info (B);
+ begin
+ case Info.Type_Mode is
+ when Type_Mode_Arrays =>
+ return Lv2M (New_Selected_Element (M2Lv (B), Info.B.Layout_Bounds),
+ Info, Mode_Value,
+ Info.B.Bounds_Type, Info.B.Bounds_Ptr_Type);
+ when Type_Mode_Records =>
+ return B;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Layout_To_Bounds;
+
+ function Layout_To_Sizes (B : Mnode) return O_Lnode
+ is
+ Info : constant Type_Info_Acc := Get_Type_Info (B);
+ begin
+ return New_Selected_Element (M2Lv (B), Info.B.Layout_Size);
+ end Layout_To_Sizes;
+
+ function Layout_To_Sizes (B : Mnode) return Mnode is
+ begin
+ return Lv2M (Layout_To_Sizes (B), Get_Type_Info (B), Mode_Value,
+ Ghdl_Sizes_Type, Ghdl_Sizes_Ptr);
+ end Layout_To_Sizes;
+
+ function Sizes_To_Size (Sizes : O_Lnode; Kind : Object_Kind_Type)
+ return O_Lnode
+ is
+ Field : O_Fnode;
+ begin
+ case Kind is
+ when Mode_Value =>
+ Field := Ghdl_Sizes_Val;
+ when Mode_Signal =>
+ Field := Ghdl_Sizes_Sig;
+ end case;
+ return New_Selected_Element (Sizes, Field);
+ end Sizes_To_Size;
+
+ function Layout_To_Size (Layout : Mnode; Kind : Object_Kind_Type)
+ return O_Lnode is
+ begin
+ return Sizes_To_Size (M2Lv (Layout_To_Sizes (Layout)), Kind);
+ end Layout_To_Size;
+
+ function Record_Layout_To_Element_Layout (B : Mnode; El : Iir) return Mnode
+ is
+ El_Type : constant Iir := Get_Type (El);
+ El_Info : constant Field_Info_Acc := Get_Info (El);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
+ begin
+ return Lv2M (New_Selected_Element (M2Lv (B),
+ El_Info.Field_Bound),
+ El_Tinfo, Mode_Value,
+ El_Tinfo.B.Layout_Type, El_Tinfo.B.Layout_Ptr_Type);
+ end Record_Layout_To_Element_Layout;
+
+ function Record_Layout_To_Element_Offset
+ (B : Mnode; El : Iir; Kind : Object_Kind_Type) return O_Lnode
+ is
+ El_Info : constant Field_Info_Acc := Get_Info (El);
+ begin
+ return New_Selected_Element (M2Lv (B), El_Info.Field_Node (Kind));
+ end Record_Layout_To_Element_Offset;
+
+ function Array_Bounds_To_Element_Layout (B : Mnode; Atype : Iir)
+ return Mnode
+ is
+ Arr_Tinfo : constant Type_Info_Acc := Get_Info (Atype);
+ El_Type : constant Iir := Get_Element_Subtype (Atype);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
+ begin
+ return Lv2M (New_Selected_Element (M2Lv (B), Arr_Tinfo.B.Bounds_El),
+ El_Tinfo, Mode_Value,
+ El_Tinfo.B.Layout_Type, El_Tinfo.B.Layout_Ptr_Type);
+ end Array_Bounds_To_Element_Layout;
+
+ function Array_Layout_To_Element_Layout (B : Mnode; Arr_Type : Iir)
+ return Mnode is
+ begin
+ return Array_Bounds_To_Element_Layout (Layout_To_Bounds (B), Arr_Type);
+ end Array_Layout_To_Element_Layout;
+
-- Finish a type definition: declare the type, define and declare a
-- pointer to the type.
procedure Finish_Type_Definition
- (Info : Type_Info_Acc; Completion : Boolean := False)
- is
+ (Info : Type_Info_Acc; Completion : Boolean := False) is
begin
-- Declare the type.
if not Completion then
@@ -83,31 +184,6 @@ package body Trans.Chap3 is
end if;
end Finish_Type_Definition;
- procedure Set_Complex_Type (Info : Type_Info_Acc; Need_Builder : Boolean) is
- begin
- pragma Assert (Info.C = null);
- Info.C := new Complex_Type_Arr_Info;
- -- No size variable for unconstrained array type.
- for Mode in Object_Kind_Type loop
- Info.C (Mode).Builder_Need_Func := Need_Builder;
- end loop;
- end Set_Complex_Type;
-
- procedure Copy_Complex_Type (Dest : Type_Info_Acc; Src : Type_Info_Acc) is
- begin
- Dest.C := new Complex_Type_Arr_Info'(Src.C.all);
- end Copy_Complex_Type;
-
- procedure Create_Size_Var (Def : Iir; Info : Type_Info_Acc) is
- begin
- Info.C (Mode_Value).Size_Var := Create_Var
- (Create_Var_Identifier ("SIZE"), Ghdl_Index_Type);
- if Get_Has_Signal_Flag (Def) then
- Info.C (Mode_Signal).Size_Var := Create_Var
- (Create_Var_Identifier ("SIGSIZE"), Ghdl_Index_Type);
- end if;
- end Create_Size_Var;
-
-- A builder set internal fields of object pointed by BASE_PTR, using
-- memory from BASE_PTR and returns a pointer to the next memory byte
-- to be used.
@@ -117,7 +193,6 @@ package body Trans.Chap3 is
is
Interface_List : O_Inter_List;
Ident : O_Ident;
- Ptype : O_Tnode;
begin
case Kind is
when Mode_Value =>
@@ -126,63 +201,27 @@ package body Trans.Chap3 is
Ident := Create_Identifier (Name, "_SIGBUILDER");
end case;
-- FIXME: return the same type as its first parameter ???
- Start_Function_Decl
- (Interface_List, Ident, Global_Storage, Ghdl_Index_Type);
+ Start_Procedure_Decl (Interface_List, Ident, Global_Storage);
Subprgs.Add_Subprg_Instance_Interfaces
- (Interface_List, Info.C (Kind).Builder_Instance);
- case Info.Type_Mode is
- when Type_Mode_Unbounded =>
- Ptype := Info.B.Base_Ptr_Type (Kind);
- when Type_Mode_Complex_Record =>
- Ptype := Info.Ortho_Ptr_Type (Kind);
- when others =>
- raise Internal_Error;
- end case;
+ (Interface_List, Info.B.Builder (Kind).Builder_Instance);
New_Interface_Decl
- (Interface_List, Info.C (Kind).Builder_Base_Param,
- Get_Identifier ("base_ptr"), Ptype);
- -- Add parameter for array bounds.
- if Info.Type_Mode in Type_Mode_Unbounded then
- New_Interface_Decl
- (Interface_List, Info.C (Kind).Builder_Bound_Param,
- Get_Identifier ("bound"), Info.B.Bounds_Ptr_Type);
- end if;
- Finish_Subprogram_Decl (Interface_List, Info.C (Kind).Builder_Func);
+ (Interface_List, Info.B.Builder (Kind).Builder_Layout_Param,
+ Get_Identifier ("layout_ptr"), Info.B.Layout_Ptr_Type);
+ Finish_Subprogram_Decl
+ (Interface_List, Info.B.Builder (Kind).Builder_Proc);
end Create_Builder_Subprogram_Decl;
- function Gen_Call_Type_Builder (Var : Mnode; Var_Type : Iir) return O_Enode
+ procedure Gen_Call_Type_Builder
+ (Layout : Mnode; Var_Type : Iir; Kind : Object_Kind_Type)
is
- Kind : constant Object_Kind_Type := Get_Object_Kind (Var);
Binfo : constant Type_Info_Acc := Get_Info (Get_Base_Type (Var_Type));
Assoc : O_Assoc_List;
begin
- -- Build the field
- Start_Association (Assoc, Binfo.C (Kind).Builder_Func);
+ Start_Association (Assoc, Binfo.B.Builder (Kind).Builder_Proc);
Subprgs.Add_Subprg_Instance_Assoc
- (Assoc, Binfo.C (Kind).Builder_Instance);
-
- -- Note: a fat array can only be at the top of a complex type;
- -- the bounds must have been set.
- New_Association
- (Assoc, M2Addr (Chap3.Get_Composite_Base (Var)));
-
- if Binfo.Type_Mode in Type_Mode_Unbounded then
- New_Association (Assoc, M2Addr (Chap3.Get_Composite_Bounds (Var)));
- end if;
-
- return New_Function_Call (Assoc);
- end Gen_Call_Type_Builder;
-
- procedure Gen_Call_Type_Builder (Var : Mnode; Var_Type : Iir)
- is
- Mem : O_Dnode;
- V : Mnode;
- begin
- Open_Temp;
- V := Stabilize (Var);
- Mem := Create_Temp (Ghdl_Index_Type);
- New_Assign_Stmt (New_Obj (Mem), Gen_Call_Type_Builder (V, Var_Type));
- Close_Temp;
+ (Assoc, Binfo.B.Builder (Kind).Builder_Instance);
+ New_Association (Assoc, M2Addr (Layout));
+ New_Procedure_Call (Assoc);
end Gen_Call_Type_Builder;
------------------
@@ -246,8 +285,10 @@ package body Trans.Chap3 is
Finish_Enum_Type (Constr, Info.Ortho_Type (Mode_Value));
if Nbr <= 256 then
Info.Type_Mode := Type_Mode_E8;
+ Info.B.Align := Align_8;
else
Info.Type_Mode := Type_Mode_E32;
+ Info.B.Align := Align_32;
end if;
-- Enumerations are always in their range.
Info.S.Nocheck_Low := True;
@@ -275,6 +316,7 @@ package body Trans.Chap3 is
Set_Ortho_Expr (True_Lit, True_Node);
Info.S.Nocheck_Low := True;
Info.S.Nocheck_Hi := True;
+ Info.B.Align := Align_8;
Finish_Type_Definition (Info);
end Translate_Bool_Type;
@@ -315,9 +357,11 @@ package body Trans.Chap3 is
when Precision_32 =>
Info.Ortho_Type (Mode_Value) := New_Signed_Type (32);
Info.Type_Mode := Type_Mode_I32;
+ Info.B.Align := Align_32;
when Precision_64 =>
Info.Ortho_Type (Mode_Value) := New_Signed_Type (64);
Info.Type_Mode := Type_Mode_I64;
+ Info.B.Align := Align_64;
end case;
-- Integers are always in their ranges.
Info.S.Nocheck_Low := True;
@@ -336,6 +380,7 @@ package body Trans.Chap3 is
begin
-- FIXME: should check precision
Info.Type_Mode := Type_Mode_F64;
+ Info.B.Align := Align_64;
Info.Ortho_Type (Mode_Value) := New_Float_Type;
-- Reals are always in their ranges.
Info.S.Nocheck_Low := True;
@@ -356,9 +401,11 @@ package body Trans.Chap3 is
when Precision_32 =>
Info.Ortho_Type (Mode_Value) := New_Signed_Type (32);
Info.Type_Mode := Type_Mode_P32;
+ Info.B.Align := Align_32;
when Precision_64 =>
Info.Ortho_Type (Mode_Value) := New_Signed_Type (64);
Info.Type_Mode := Type_Mode_P64;
+ Info.B.Align := Align_64;
end case;
-- Physical types are always in their ranges.
Info.S.Nocheck_Low := True;
@@ -394,6 +441,7 @@ package body Trans.Chap3 is
Info.Ortho_Type (Mode_Value) := Ghdl_File_Index_Type;
Info.Ortho_Ptr_Type (Mode_Value) := Ghdl_File_Index_Ptr_Type;
Info.Type_Mode := Type_Mode_File;
+ Info.B.Align := Align_32;
end Translate_File_Type;
function Get_File_Signature_Length (Def : Iir) return Natural is
@@ -503,6 +551,7 @@ package body Trans.Chap3 is
procedure Create_Unbounded_Type_Fat_Pointer (Info : Type_Info_Acc)
is
Constr : O_Element_List;
+ Bounds_Type : O_Tnode;
begin
for Kind in Object_Kind_Type loop
exit when Info.B.Base_Type (Kind) = O_Tnode_Null;
@@ -511,9 +560,17 @@ package body Trans.Chap3 is
New_Record_Field
(Constr, Info.B.Base_Field (Kind), Wki_Base,
Info.B.Base_Ptr_Type (Kind));
+ case Info.Type_Mode is
+ when Type_Mode_Unbounded_Array =>
+ Bounds_Type := Info.B.Bounds_Ptr_Type;
+ when Type_Mode_Unbounded_Record =>
+ Bounds_Type := Info.B.Layout_Ptr_Type;
+ when others =>
+ raise Internal_Error;
+ end case;
New_Record_Field
(Constr, Info.B.Bounds_Field (Kind), Wki_Bounds,
- Info.B.Bounds_Ptr_Type);
+ Bounds_Type);
Finish_Record_Type (Constr, Info.Ortho_Type (Kind));
end loop;
end Create_Unbounded_Type_Fat_Pointer;
@@ -550,89 +607,129 @@ package body Trans.Chap3 is
New_Type_Decl (Create_Identifier ("BOUNDP"), Info.B.Bounds_Ptr_Type);
end Finish_Unbounded_Type_Bounds;
- function Create_Static_Composite_Subtype_Bounds (Def : Iir) return O_Cnode
+ function Create_Static_Composite_Subtype_Sizes (Def : Iir) return O_Cnode
+ is
+ Info : constant Type_Info_Acc := Get_Info (Def);
+ Sz_List : O_Record_Aggr_List;
+ Sz : O_Cnode;
+ Sz_Res : O_Cnode;
+ begin
+ Start_Record_Aggr (Sz_List, Ghdl_Sizes_Type);
+ New_Record_Aggr_El
+ (Sz_List, New_Sizeof (Info.Ortho_Type (Mode_Value), Ghdl_Index_Type));
+ if Get_Has_Signal_Flag (Def) then
+ Sz := New_Sizeof (Info.Ortho_Type (Mode_Signal), Ghdl_Index_Type);
+ else
+ Sz := Ghdl_Index_0;
+ end if;
+ New_Record_Aggr_El (Sz_List, Sz);
+ Finish_Record_Aggr (Sz_List, Sz_Res);
+ return Sz_Res;
+ end Create_Static_Composite_Subtype_Sizes;
+
+ function Create_Static_Array_Subtype_Bounds (Def : Iir) return O_Cnode
is
- Binfo : constant Type_Info_Acc := Get_Info (Get_Base_Type (Def));
+ Base_Type : constant Iir := Get_Base_Type (Def);
+ Binfo : constant Type_Info_Acc := Get_Info (Base_Type);
+ Indexes_List : constant Iir_Flist := Get_Index_Subtype_List (Def);
+ Index : Iir;
List : O_Record_Aggr_List;
Res : O_Cnode;
begin
Start_Record_Aggr (List, Binfo.B.Bounds_Type);
- case Get_Kind (Def) is
- when Iir_Kind_Array_Subtype_Definition =>
- declare
- Indexes_List : constant Iir_Flist :=
- Get_Index_Subtype_List (Def);
- Index : Iir;
- begin
- for I in Flist_First .. Flist_Last (Indexes_List) loop
- Index := Get_Index_Type (Indexes_List, I);
- New_Record_Aggr_El
- (List, Create_Static_Type_Definition_Type_Range (Index));
- end loop;
- end;
- if Binfo.B.El_Size /= O_Fnode_Null then
- -- For arrays of unbounded type.
- declare
- El_Type : constant Iir := Get_Element_Subtype (Def);
- El_Info : constant Type_Info_Acc := Get_Info (El_Type);
- Sz_List : O_Record_Aggr_List;
- Sz_Res : O_Cnode;
- begin
- New_Record_Aggr_El
- (List, Create_Static_Composite_Subtype_Bounds (El_Type));
-
- Start_Record_Aggr (Sz_List, Ghdl_Sizes_Type);
- New_Record_Aggr_El
- (Sz_List, New_Sizeof (El_Info.Ortho_Type (Mode_Value),
- Ghdl_Index_Type));
- New_Record_Aggr_El
- (Sz_List, New_Sizeof (El_Info.Ortho_Type (Mode_Signal),
- Ghdl_Index_Type));
- Finish_Record_Aggr (Sz_List, Sz_Res);
- New_Record_Aggr_El (List, Sz_Res);
- end;
- end if;
+ for I in Flist_First .. Flist_Last (Indexes_List) loop
+ Index := Get_Index_Type (Indexes_List, I);
+ New_Record_Aggr_El
+ (List, Create_Static_Type_Definition_Type_Range (Index));
+ end loop;
- when Iir_Kind_Record_Subtype_Definition =>
- declare
- El_List : constant Iir_Flist :=
- Get_Elements_Declaration_List (Def);
- El_Blist : constant Iir_Flist :=
- Get_Elements_Declaration_List (Get_Base_Type (Def));
- El : Iir;
- Bel : Iir;
- Bel_Info : Field_Info_Acc;
- begin
- for I in Flist_First .. Flist_Last (El_Blist) loop
- Bel := Get_Nth_Element (El_Blist, I);
- Bel_Info := Get_Info (Bel);
- if Bel_Info.Field_Bound /= O_Fnode_Null then
- El := Get_Nth_Element (El_List, I);
- New_Record_Aggr_El
- (List,
- Create_Static_Composite_Subtype_Bounds
- (Get_Type (El)));
- end if;
- end loop;
- end;
+ if Binfo.B.Bounds_El /= O_Fnode_Null then
+ -- For arrays of unbounded type.
+ New_Record_Aggr_El
+ (List, Create_Static_Composite_Subtype_Layout
+ (Get_Element_Subtype (Def)));
+ end if;
- when others =>
- Error_Kind ("create_static_composite_subtype_bounds", Def);
- end case;
+ Finish_Record_Aggr (List, Res);
+ return Res;
+ end Create_Static_Array_Subtype_Bounds;
+
+ function Create_Static_Record_Subtype_Bounds (Def : Iir) return O_Cnode
+ is
+ Base_Type : constant Iir := Get_Base_Type (Def);
+ Binfo : constant Type_Info_Acc := Get_Info (Base_Type);
+ El_List : constant Iir_Flist := Get_Elements_Declaration_List (Def);
+ El_Blist : constant Iir_Flist :=
+ Get_Elements_Declaration_List (Base_Type);
+ Info : constant Type_Info_Acc := Get_Info (Def);
+ List : O_Record_Aggr_List;
+ Res : O_Cnode;
+ El : Iir;
+ Bel : Iir;
+ Bel_Info : Field_Info_Acc;
+ El_Info : Field_Info_Acc;
+ Off : O_Cnode;
+ begin
+ Start_Record_Aggr (List, Binfo.B.Bounds_Type);
+
+ New_Record_Aggr_El (List, Create_Static_Composite_Subtype_Sizes (Def));
+
+ for I in Flist_First .. Flist_Last (El_Blist) loop
+ Bel := Get_Nth_Element (El_Blist, I);
+ Bel_Info := Get_Info (Bel);
+ if Bel_Info.Field_Bound /= O_Fnode_Null then
+ El := Get_Nth_Element (El_List, I);
+ El_Info := Get_Info (El);
+ for Kind in Mode_Value .. Type_To_Last_Object_Kind (Base_Type)
+ loop
+ if Info.Ortho_Type (Kind) /= O_Tnode_Null then
+ Off := New_Offsetof (Info.Ortho_Type (Kind),
+ El_Info.Field_Node (Kind),
+ Ghdl_Index_Type);
+ else
+ Off := Ghdl_Index_0;
+ end if;
+ New_Record_Aggr_El (List, Off);
+ end loop;
+ New_Record_Aggr_El
+ (List, Create_Static_Composite_Subtype_Layout (Get_Type (El)));
+ end if;
+ end loop;
Finish_Record_Aggr (List, Res);
return Res;
- end Create_Static_Composite_Subtype_Bounds;
+ end Create_Static_Record_Subtype_Bounds;
- procedure Elab_Composite_Subtype_Bounds (Def : Iir; Target : O_Lnode)
+ function Create_Static_Composite_Subtype_Layout (Def : Iir) return O_Cnode
is
- Info : constant Type_Info_Acc := Get_Info (Def);
- Base_Type : constant Iir := Get_Base_Type (Def);
- Targ : Mnode;
+ Info : constant Type_Info_Acc := Get_Info (Def);
+ begin
+ case Info.Type_Mode is
+ when Type_Mode_Static_Record
+ | Type_Mode_Complex_Record =>
+ return Create_Static_Record_Subtype_Bounds (Def);
+ when Type_Mode_Static_Array
+ | Type_Mode_Complex_Array =>
+ declare
+ List : O_Record_Aggr_List;
+ Res : O_Cnode;
+ begin
+ Start_Record_Aggr (List, Info.B.Layout_Type);
+ New_Record_Aggr_El
+ (List, Create_Static_Composite_Subtype_Sizes (Def));
+ New_Record_Aggr_El
+ (List, Create_Static_Array_Subtype_Bounds (Def));
+ Finish_Record_Aggr (List, Res);
+ return Res;
+ end;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Create_Static_Composite_Subtype_Layout;
+
+ procedure Elab_Composite_Subtype_Layout (Def : Iir; Target : Mnode) is
begin
- Targ := Lv2M (Target, null, Mode_Value,
- Info.B.Bounds_Type, Info.B.Bounds_Ptr_Type);
Open_Temp;
case Get_Kind (Def) is
@@ -640,110 +737,101 @@ package body Trans.Chap3 is
declare
Indexes_List : constant Iir_Flist :=
Get_Index_Subtype_List (Def);
- Indexes_Def_List : constant Iir_Flist :=
- Get_Index_Subtype_Definition_List (Base_Type);
+ Targ : Mnode;
Index : Iir;
begin
+ Targ := Layout_To_Bounds (Target);
if Get_Nbr_Elements (Indexes_List) > 1 then
Targ := Stabilize (Targ);
end if;
for I in Flist_First .. Flist_Last (Indexes_List) loop
Index := Get_Index_Type (Indexes_List, I);
- declare
- Index_Type : constant Iir := Get_Base_Type (Index);
- Index_Info : constant Type_Info_Acc :=
- Get_Info (Index_Type);
- Base_Index_Info : constant Index_Info_Acc :=
- Get_Info (Get_Nth_Element (Indexes_Def_List, I));
- D : O_Dnode;
- begin
- Open_Temp;
- D := Create_Temp_Ptr
- (Index_Info.B.Range_Ptr_Type,
- New_Selected_Element (M2Lv (Targ),
- Base_Index_Info.Index_Field));
- Chap7.Translate_Discrete_Range
- (Dp2M (D, Index_Info, Mode_Value,
- Index_Info.B.Range_Type,
- Index_Info.B.Range_Ptr_Type),
- Index);
- Close_Temp;
- end;
+ Open_Temp;
+ Chap7.Translate_Discrete_Range
+ (Bounds_To_Range (Targ, Def, I + 1), Index);
+ Close_Temp;
end loop;
+ -- FIXME: element ?
end;
+ when Iir_Kind_Record_Type_Definition =>
+ null;
+
when Iir_Kind_Record_Subtype_Definition =>
declare
El_List : constant Iir_Flist :=
Get_Elements_Declaration_List (Def);
+ Targ : Mnode;
El : Iir;
- El_Info : Field_Info_Acc;
+ Base_El : Iir;
begin
- Targ := Stabilize (Targ);
+ Targ := Stabilize (Target);
for I in Flist_First .. Flist_Last (El_List) loop
El := Get_Nth_Element (El_List, I);
- El_Info := Get_Info (Get_Base_Element_Declaration (El));
- if El_Info.Field_Bound /= O_Fnode_Null then
- Elab_Composite_Subtype_Bounds
+ Base_El := Get_Base_Element_Declaration (El);
+ if Is_Unbounded_Type (Get_Info (Get_Type (Base_El))) then
+ Elab_Composite_Subtype_Layout
(Get_Type (El),
- New_Selected_Element (M2Lv (Targ),
- El_Info.Field_Bound));
+ Record_Layout_To_Element_Layout (Targ, El));
end if;
end loop;
end;
when others =>
- Error_Kind ("elab_composite_subtype_bounds", Def);
+ Error_Kind ("elab_composite_subtype_layout", Def);
end case;
Close_Temp;
- end Elab_Composite_Subtype_Bounds;
+ end Elab_Composite_Subtype_Layout;
- procedure Elab_Composite_Subtype_Bounds (Def : Iir)
+ procedure Elab_Composite_Subtype_Layout (Def : Iir)
is
Info : constant Type_Info_Acc := Get_Info (Def);
begin
- if not Info.S.Static_Bounds then
- Elab_Composite_Subtype_Bounds
- (Def, Get_Var (Info.S.Composite_Bounds));
+ if Is_Complex_Type (Info) then
+ Elab_Composite_Subtype_Layout (Def, Get_Composite_Type_Layout (Info));
+
+ Gen_Call_Type_Builder
+ (Get_Composite_Type_Layout (Info), Def, Mode_Value);
+ if Get_Has_Signal_Flag (Def) then
+ Gen_Call_Type_Builder
+ (Get_Composite_Type_Layout (Info), Def, Mode_Signal);
+ end if;
end if;
- end Elab_Composite_Subtype_Bounds;
+ end Elab_Composite_Subtype_Layout;
- -- Create a variable containing the bounds for array subtype DEF.
- procedure Create_Composite_Subtype_Bounds_Var
+ -- Create a variable containing the layout for composite subtype DEF.
+ procedure Create_Composite_Subtype_Layout_Var
(Def : Iir; Elab_Now : Boolean)
is
Info : constant Type_Info_Acc := Get_Info (Def);
- Base_Info : Type_Info_Acc;
Val : O_Cnode;
begin
- if Info.S.Composite_Bounds /= Null_Var then
+ if Info.S.Composite_Layout /= Null_Var then
+ -- Already created.
return;
end if;
- Base_Info := Get_Info (Get_Base_Type (Def));
if Are_Bounds_Locally_Static (Def) then
- Info.S.Static_Bounds := True;
if Global_Storage = O_Storage_External then
-- Do not create the value of the type desc, since it
-- is never dereferenced in a static type desc.
Val := O_Cnode_Null;
else
- Val := Create_Static_Composite_Subtype_Bounds (Def);
+ Val := Create_Static_Composite_Subtype_Layout (Def);
end if;
- Info.S.Composite_Bounds := Create_Global_Const
- (Create_Identifier ("STB"),
- Base_Info.B.Bounds_Type, Global_Storage, Val);
+ Info.S.Composite_Layout := Create_Global_Const
+ (Create_Identifier ("STL"),
+ Info.B.Layout_Type, Global_Storage, Val);
else
pragma Assert (Get_Type_Staticness (Def) /= Locally);
- Info.S.Static_Bounds := False;
- Info.S.Composite_Bounds := Create_Var
- (Create_Var_Identifier ("STB"), Base_Info.B.Bounds_Type);
+ Info.S.Composite_Layout := Create_Var
+ (Create_Var_Identifier ("STL"), Info.B.Layout_Type);
if Elab_Now then
- Elab_Composite_Subtype_Bounds (Def);
+ Elab_Composite_Subtype_Layout (Def);
end if;
end if;
- end Create_Composite_Subtype_Bounds_Var;
+ end Create_Composite_Subtype_Layout_Var;
-------------
-- Array --
@@ -793,25 +881,50 @@ package body Trans.Chap3 is
end loop;
if Is_Unbounded_Type (El_Info) then
- -- Bounds and size for element.
- New_Record_Field (Constr, Info.B.El_Bounds,
- Get_Identifier ("el_bound"), El_Info.B.Bounds_Type);
- New_Record_Field (Constr, Info.B.El_Size, Get_Identifier ("el_size"),
- Ghdl_Sizes_Type);
+ -- Add layout for the element.
+ New_Record_Field
+ (Constr, Info.B.Bounds_El,
+ Get_Identifier ("el_layout"), El_Info.B.Layout_Type);
end if;
Finish_Record_Type (Constr, Info.B.Bounds_Type);
Finish_Unbounded_Type_Bounds (Info);
end Translate_Array_Type_Bounds;
+ -- Create the layout type.
+ procedure Create_Array_Type_Layout_Type (Info : Type_Info_Acc)
+ is
+ Constr : O_Element_List;
+ begin
+ Start_Record_Type (Constr);
+ New_Record_Field (Constr, Info.B.Layout_Size,
+ Get_Identifier ("size"), Ghdl_Sizes_Type);
+ New_Record_Field (Constr, Info.B.Layout_Bounds,
+ Get_Identifier ("bounds"), Info.B.Bounds_Type);
+ Finish_Record_Type (Constr, Info.B.Layout_Type);
+
+ New_Type_Decl (Create_Identifier ("LAYOUT"), Info.B.Layout_Type);
+ Info.B.Layout_Ptr_Type := New_Access_Type (Info.B.Layout_Type);
+ New_Type_Decl (Create_Identifier ("LAYOUTP"), Info.B.Layout_Ptr_Type);
+ end Create_Array_Type_Layout_Type;
+
procedure Translate_Array_Type_Base
- (Def : Iir_Array_Type_Definition;
- Info : Type_Info_Acc)
+ (Def : Iir_Array_Type_Definition; Info : Type_Info_Acc)
is
El_Type : constant Iir := Get_Element_Subtype (Def);
El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
begin
- if Is_Complex_Type (El_Tinfo) or else Is_Unbounded_Type (El_Tinfo) then
+ Info.B.Align := El_Tinfo.B.Align;
+ if Is_Static_Type (El_Tinfo) then
+ -- Simple case: the array is really an array.
+ for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
+ Info.B.Base_Type (Kind) :=
+ New_Array_Type (El_Tinfo.Ortho_Type (Kind), Ghdl_Index_Type);
+ end loop;
+
+ -- Declare the types.
+ Finish_Unbounded_Type_Base (Info);
+ else
if El_Tinfo.Type_Mode in Type_Mode_Arrays then
Info.B.Base_Type := El_Tinfo.B.Base_Ptr_Type;
Info.B.Base_Ptr_Type := El_Tinfo.B.Base_Ptr_Type;
@@ -819,20 +932,13 @@ package body Trans.Chap3 is
Info.B.Base_Type := El_Tinfo.Ortho_Ptr_Type;
Info.B.Base_Ptr_Type := El_Tinfo.Ortho_Ptr_Type;
end if;
- else
- for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
- Info.B.Base_Type (Kind) :=
- New_Array_Type (El_Tinfo.Ortho_Type (Kind), Ghdl_Index_Type);
- end loop;
- Finish_Unbounded_Type_Base (Info);
+ pragma Assert (Info.B.Align /= Align_Undef);
end if;
end Translate_Array_Type_Base;
- procedure Translate_Array_Type_Definition
- (Def : Iir_Array_Type_Definition)
+ procedure Translate_Array_Type (Def : Iir_Array_Type_Definition)
is
Info : constant Type_Info_Acc := Get_Info (Def);
- El_Tinfo : Type_Info_Acc;
begin
Info.Type_Mode := Type_Mode_Fat_Array;
Info.B := Ortho_Info_Basetype_Array_Init;
@@ -843,14 +949,10 @@ package body Trans.Chap3 is
Create_Unbounded_Type_Fat_Pointer (Info);
Finish_Type_Definition (Info, False);
- El_Tinfo := Get_Info (Get_Element_Subtype (Def));
- if Is_Complex_Type (El_Tinfo) then
- -- This is a complex type.
- -- No size variable for unconstrained array type.
- Set_Complex_Type (Info, El_Tinfo.C (Mode_Value).Builder_Need_Func);
- end if;
+ Create_Array_Type_Layout_Type (Info);
+
Info.Type_Incomplete := False;
- end Translate_Array_Type_Definition;
+ end Translate_Array_Type;
-- Get the length of DEF, ie the number of elements.
-- If the length is not statically defined, returns -1.
@@ -942,7 +1044,7 @@ package body Trans.Chap3 is
Info.Type_Locally_Constrained := (Len >= 0);
Info.B := Pinfo.B;
Info.S := Pinfo.S;
- if Is_Complex_Type (Pinfo)
+ if Is_Complex_Type (Get_Info (Get_Element_Subtype (Parent_Type)))
or else not Info.Type_Locally_Constrained
then
-- This is a complex type as the size is not known at compile
@@ -950,18 +1052,6 @@ package body Trans.Chap3 is
Info.Type_Mode := Type_Mode_Complex_Array;
Info.Ortho_Type := Pinfo.B.Base_Ptr_Type;
Info.Ortho_Ptr_Type := Pinfo.B.Base_Ptr_Type;
-
- -- If the base type need a builder, so does the subtype.
- if Is_Complex_Type (Pinfo)
- and then Pinfo.C (Mode_Value).Builder_Need_Func
- then
- Copy_Complex_Type (Info, Pinfo);
- else
- Set_Complex_Type (Info, False);
- end if;
-
- -- Type is bounded, but not statically.
- Create_Size_Var (Def, Info);
else
-- Length is known. Create a constrained array.
El_Constrained := Get_Array_Element_Constraint (Def) /= Null_Iir;
@@ -1007,88 +1097,53 @@ package body Trans.Chap3 is
Info.Type_Mode := Type_Mode_Unbounded_Array;
Create_Array_For_Array_Subtype
(Def, Info.B.Base_Type, Info.B.Base_Ptr_Type);
-
- -- If the base type need a builder, so does the subtype.
- if Is_Complex_Type (Pinfo) then
- if Pinfo.C (Mode_Value).Builder_Need_Func then
- Copy_Complex_Type (Info, Pinfo);
- else
- Set_Complex_Type (Info, False);
- end if;
- end if;
end Translate_Array_Subtype_Definition_Constrained_Element;
procedure Create_Array_Type_Builder
(Def : Iir_Array_Type_Definition; Kind : Object_Kind_Type)
is
+ El_Type : constant Iir := Get_Element_Subtype (Def);
+ El_Info : constant Type_Info_Acc := Get_Info (El_Type);
Info : constant Type_Info_Acc := Get_Info (Def);
- Base : constant O_Dnode := Info.C (Kind).Builder_Base_Param;
- Bound : constant O_Dnode := Info.C (Kind).Builder_Bound_Param;
- Var_Off : O_Dnode;
- Var_Mem : O_Dnode;
- Var_Length : O_Dnode;
- El_Type : Iir;
- El_Info : Type_Info_Acc;
- Label : O_Snode;
- begin
- Start_Subprogram_Body (Info.C (Kind).Builder_Func);
- Subprgs.Start_Subprg_Instance_Use (Info.C (Kind).Builder_Instance);
-
- -- Compute length of the array.
- New_Var_Decl (Var_Length, Wki_Length, O_Storage_Local,
- Ghdl_Index_Type);
- New_Var_Decl (Var_Mem, Get_Identifier ("mem"), O_Storage_Local,
- Info.B.Base_Ptr_Type (Kind));
- New_Var_Decl (Var_Off, Get_Identifier ("off"), O_Storage_Local,
- Ghdl_Index_Type);
+ Layout_Param : constant O_Dnode :=
+ Info.B.Builder (Kind).Builder_Layout_Param;
+ Layout : Mnode;
+ El_Size : O_Enode;
+ Size : O_Enode;
+ begin
+ Start_Subprogram_Body (Info.B.Builder (Kind).Builder_Proc);
+ Subprgs.Start_Subprg_Instance_Use
+ (Info.B.Builder (Kind).Builder_Instance);
+ Open_Local_Temp;
- El_Type := Get_Element_Subtype (Def);
- El_Info := Get_Info (El_Type);
+ Layout := Dp2M (Layout_Param, Info, Kind,
+ Info.B.Layout_Type, Info.B.Layout_Ptr_Type);
- New_Assign_Stmt
- (New_Obj (Var_Length),
- New_Dyadic_Op (ON_Mul_Ov,
- New_Value (Get_Var (El_Info.C (Kind).Size_Var)),
- Get_Bounds_Length (Dp2M (Bound, Info,
- Mode_Value,
- Info.B.Bounds_Type,
- Info.B.Bounds_Ptr_Type),
- Def)));
-
- -- Find the innermost non-array element.
- while El_Info.Type_Mode = Type_Mode_Complex_Array loop
- El_Type := Get_Element_Subtype (El_Type);
- El_Info := Get_Info (El_Type);
- end loop;
+ -- Call the builder to layout the element (only for unbounded elements)
+ if Is_Unbounded_Type (El_Info) then
+ Gen_Call_Type_Builder
+ (Array_Layout_To_Element_Layout (Layout, Def), El_Type, Kind);
- -- Set each index of the array.
- Init_Var (Var_Off);
- Start_Loop_Stmt (Label);
- Gen_Exit_When (Label, New_Compare_Op (ON_Eq,
- New_Obj_Value (Var_Off),
- New_Obj_Value (Var_Length),
- Ghdl_Bool_Type));
+ El_Size := New_Value
+ (Layout_To_Size (Array_Layout_To_Element_Layout (Layout, Def),
+ Kind));
+ else
+ El_Size := Get_Subtype_Size (El_Type, Mnode_Null, Kind);
+ end if;
- New_Assign_Stmt
- (New_Obj (Var_Mem),
- New_Unchecked_Address
- (New_Slice (New_Access_Element
- (New_Convert_Ov (New_Obj_Value (Base),
- Char_Ptr_Type)),
- Chararray_Type,
- New_Obj_Value (Var_Off)),
- Info.B.Base_Ptr_Type (Kind)));
+ -- Compute size.
+ Size := New_Dyadic_Op
+ (ON_Mul_Ov,
+ El_Size,
+ Get_Bounds_Length (Layout_To_Bounds (Layout), Def));
- New_Assign_Stmt
- (New_Obj (Var_Off),
- New_Dyadic_Op (ON_Add_Ov,
- New_Obj_Value (Var_Off),
- Gen_Call_Type_Builder (Dp2M (Var_Mem, El_Info, Kind), El_Type)));
- Finish_Loop_Stmt (Label);
+ -- Set size.
+ New_Assign_Stmt (Layout_To_Size (Layout, Kind), Size);
- New_Return_Stmt (New_Obj_Value (Var_Off));
+ Close_Local_Temp;
- Subprgs.Finish_Subprg_Instance_Use (Info.C (Kind).Builder_Instance);
+ Subprgs.Finish_Subprg_Instance_Use
+ (Info.B.Builder (Kind).Builder_Instance);
Finish_Subprogram_Body;
end Create_Array_Type_Builder;
@@ -1097,82 +1152,31 @@ package body Trans.Chap3 is
--------------
-- Get the alignment mask for *ortho* type ATYPE.
- function Get_Type_Alignmask (Atype : O_Tnode) return O_Enode is
+ function Get_Alignmask (Align : Alignment_Type) return O_Enode is
begin
- return New_Dyadic_Op
- (ON_Sub_Ov,
- New_Lit (New_Alignof (Atype, Ghdl_Index_Type)),
- New_Lit (Ghdl_Index_1));
- end Get_Type_Alignmask;
+ return New_Dyadic_Op (ON_Sub_Ov,
+ New_Lit (Align_Val (Align)),
+ New_Lit (Ghdl_Index_1));
+ end Get_Alignmask;
-- Align VALUE (of unsigned type) for type ATYPE.
-- The formulae is: (V + (A - 1)) and not (A - 1), where A is the
-- alignment for ATYPE in bytes.
- function Realign (Value : O_Enode; Atype : O_Tnode) return O_Enode is
+ function Realign (Value : O_Enode; Align : Alignment_Type) return O_Enode is
begin
return New_Dyadic_Op
(ON_And,
- New_Dyadic_Op (ON_Add_Ov, Value, Get_Type_Alignmask (Atype)),
- New_Monadic_Op (ON_Not, Get_Type_Alignmask (Atype)));
+ New_Dyadic_Op (ON_Add_Ov, Value, Get_Alignmask (Align)),
+ New_Monadic_Op (ON_Not, Get_Alignmask (Align)));
end Realign;
function Realign (Value : O_Enode; Atype : Iir) return O_Enode
is
Tinfo : constant Type_Info_Acc := Get_Info (Atype);
- Otype : O_Tnode;
- begin
- if Is_Unbounded_Type (Tinfo) then
- Otype := Tinfo.B.Base_Type (Mode_Value);
- else
- Otype := Tinfo.Ortho_Type (Mode_Value);
- end if;
- return Realign (Value, Otype);
- end Realign;
-
- function Realign (Value : O_Enode; Mask : O_Dnode) return O_Enode is
begin
- return New_Dyadic_Op
- (ON_And,
- New_Dyadic_Op (ON_Add_Ov, Value, New_Obj_Value (Mask)),
- New_Monadic_Op (ON_Not, New_Obj_Value (Mask)));
+ return Realign (Value, Tinfo.B.Align);
end Realign;
- -- Find the innermost non-array element.
- function Get_Innermost_Non_Array_Element (Atype : Iir) return Iir
- is
- Res : Iir := Atype;
- begin
- while Get_Kind (Res) in Iir_Kinds_Array_Type_Definition loop
- Res := Get_Element_Subtype (Res);
- end loop;
- return Res;
- end Get_Innermost_Non_Array_Element;
-
- -- Declare the bounds types for DEF.
- procedure Translate_Record_Type_Bounds
- (Def : Iir_Record_Type_Definition; Info : Type_Info_Acc)
- is
- List : constant Iir_Flist := Get_Elements_Declaration_List (Def);
- El : Iir;
- El_Tinfo : Type_Info_Acc;
- El_Info : Field_Info_Acc;
- Constr : O_Element_List;
- begin
- Start_Record_Type (Constr);
- for I in Flist_First .. Flist_Last (List) loop
- El := Get_Nth_Element (List, I);
- El_Tinfo := Get_Info (Get_Type (El));
- if Is_Unbounded_Type (El_Tinfo) then
- El_Info := Get_Info (El);
- New_Record_Field (Constr, El_Info.Field_Bound,
- Create_Identifier_Without_Prefix (El),
- El_Tinfo.B.Bounds_Type);
- end if;
- end loop;
- Finish_Record_Type (Constr, Info.B.Bounds_Type);
- Finish_Unbounded_Type_Bounds (Info);
- end Translate_Record_Type_Bounds;
-
procedure Translate_Record_Type (Def : Iir_Record_Type_Definition)
is
Info : constant Type_Info_Acc := Get_Info (Def);
@@ -1184,32 +1188,37 @@ package body Trans.Chap3 is
Field_Info : Ortho_Info_Acc;
El_Type : Iir;
El_Tinfo : Type_Info_Acc;
- El_Tnode : O_Tnode;
+ Align : Alignment_Type;
-- True if a size variable will be created since the size of
-- the record is not known at compile-time.
- Need_Size : Boolean;
+ Is_Complex : Boolean;
Mark : Id_Mark_Type;
begin
- Need_Size := False;
-
-- First, translate the anonymous type of the elements.
+ Align := Align_8;
for I in Flist_First .. Flist_Last (List) loop
El := Get_Nth_Element (List, I);
El_Type := Get_Type (El);
- if Get_Info (El_Type) = null then
+ El_Tinfo := Get_Info (El_Type);
+ if El_Tinfo = null then
Push_Identifier_Prefix (Mark, Get_Identifier (El));
Translate_Subtype_Indication (El_Type, True);
Pop_Identifier_Prefix (Mark);
+ El_Tinfo := Get_Info (El_Type);
end if;
- Need_Size := Need_Size or else Is_Complex_Type (Get_Info (El_Type));
Field_Info := Add_Info (El, Kind_Field);
+
+ pragma Assert (El_Tinfo.B.Align /= Align_Undef);
+ Align := Alignment_Type'Max (Align, El_Tinfo.B.Align);
end loop;
+ Info.B.Align := Align;
-- Then create the record type.
Info.S := Ortho_Info_Subtype_Record_Init;
Info.Ortho_Type (Mode_Signal) := O_Tnode_Null;
+ Is_Complex := False;
for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
Start_Record_Type (El_List);
for I in Flist_First .. Flist_Last (List) loop
@@ -1219,31 +1228,65 @@ package body Trans.Chap3 is
if Is_Complex_Type (El_Tinfo)
or else Is_Unbounded_Type (El_Tinfo)
then
- -- Always use an offset for a complex type.
- El_Tnode := Ghdl_Index_Type;
+ Is_Complex := True;
else
- El_Tnode := El_Tinfo.Ortho_Type (Kind);
+ New_Record_Field (El_List, Field_Info.Field_Node (Kind),
+ Create_Identifier_Without_Prefix (El),
+ El_Tinfo.Ortho_Type (Kind));
end if;
- New_Record_Field (El_List, Field_Info.Field_Node (Kind),
- Create_Identifier_Without_Prefix (El),
- El_Tnode);
end loop;
Finish_Record_Type (El_List, Info.B.Base_Type (Kind));
end loop;
+ -- Create the bounds type
+ Info.B.Bounds_Type := O_Tnode_Null;
+ Start_Record_Type (El_List);
+ New_Record_Field (El_List, Info.B.Layout_Size,
+ Get_Identifier ("size"), Ghdl_Sizes_Type);
+ for I in Flist_First .. Flist_Last (List) loop
+ declare
+ El : constant Iir := Get_Nth_Element (List, I);
+ Field_Info : constant Field_Info_Acc := Get_Info (El);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (Get_Type (El));
+ Unbounded_El : constant Boolean := Is_Unbounded_Type (El_Tinfo);
+ Complex_El : constant Boolean := Is_Complex_Type (El_Tinfo);
+ begin
+ if Unbounded_El or Complex_El then
+ -- Offset
+ New_Record_Field
+ (El_List, Field_Info.Field_Node (Mode_Value),
+ Create_Identifier_Without_Prefix (El, "_OFF"),
+ Ghdl_Index_Type);
+ if Get_Has_Signal_Flag (Def) then
+ New_Record_Field
+ (El_List, Field_Info.Field_Node (Mode_Signal),
+ Create_Identifier_Without_Prefix (El, "_SIGOFF"),
+ Ghdl_Index_Type);
+ end if;
+ end if;
+ if Unbounded_El then
+ New_Record_Field
+ (El_List, Field_Info.Field_Bound,
+ Create_Identifier_Without_Prefix (El, "_BND"),
+ El_Tinfo.B.Layout_Type);
+ end if;
+ end;
+ end loop;
+ Finish_Record_Type (El_List, Info.B.Bounds_Type);
+ Finish_Unbounded_Type_Bounds (Info);
+
+ -- For records: layout == bounds.
+ Info.B.Layout_Type := Info.B.Bounds_Type;
+ Info.B.Layout_Ptr_Type := Info.B.Bounds_Ptr_Type;
+
if Is_Unbounded then
Info.Type_Mode := Type_Mode_Unbounded_Record;
Finish_Unbounded_Type_Base (Info);
- Translate_Record_Type_Bounds (Def, Info);
Create_Unbounded_Type_Fat_Pointer (Info);
Finish_Type_Definition (Info);
-
- -- There are internal fields for unbounded records, so the objects
- -- must be built.
- Set_Complex_Type (Info, True);
else
- if Need_Size then
+ if Is_Complex then
Info.Type_Mode := Type_Mode_Complex_Record;
else
Info.Type_Mode := Type_Mode_Static_Record;
@@ -1252,10 +1295,7 @@ package body Trans.Chap3 is
Finish_Type_Definition (Info);
Info.B.Base_Ptr_Type := Info.Ortho_Ptr_Type;
- if Need_Size then
- Set_Complex_Type (Info, True);
- Create_Size_Var (Def, Info);
- end if;
+ Create_Composite_Subtype_Layout_Var (Def, False);
end if;
end Translate_Record_Type;
@@ -1296,23 +1336,23 @@ package body Trans.Chap3 is
for I in Flist_First .. Flist_Last (El_List) loop
El := Get_Nth_Element (El_List, I);
El_Type := Get_Type (El);
- if Is_Fully_Constrained_Type (El) then
- El_Btype := Get_Type (Get_Nth_Element (El_Tm_List, I));
- if not Is_Fully_Constrained_Type (El_Btype) then
- Has_New_Constraints := True;
- if Get_Type_Staticness (El_Type) = Locally then
- Has_Boxed_Elements := True;
- end if;
- Push_Identifier_Prefix (Mark, Get_Identifier (El));
- Translate_Subtype_Definition (El_Type, El_Btype, With_Vars);
- Pop_Identifier_Prefix (Mark);
+ El_Btype := Get_Type (Get_Nth_Element (El_Tm_List, I));
+ if Is_Fully_Constrained_Type (El_Type)
+ and then not Is_Fully_Constrained_Type (El_Btype)
+ then
+ Has_New_Constraints := True;
+ if Get_Type_Staticness (El_Type) = Locally then
+ Has_Boxed_Elements := True;
end if;
+ Push_Identifier_Prefix (Mark, Get_Identifier (El));
+ Translate_Subtype_Definition (El_Type, El_Btype, With_Vars);
+ Pop_Identifier_Prefix (Mark);
end if;
end loop;
-- By default, use the same representation as the base type.
Info.all := Base_Info.all;
- Info.S := Ortho_Info_Subtype_Record_Init;
+ -- Info.S := Ortho_Info_Subtype_Record_Init;
-- However, it is a different subtype which has its own rti.
Info.Type_Rti := O_Dnode_Null;
@@ -1323,6 +1363,15 @@ package body Trans.Chap3 is
-- create objects, so wait until it is completly constrained.
-- The subtype is simply an alias.
-- In both cases, use the same representation as its type mark.
+
+ for I in Flist_First .. Flist_Last (El_Blist) loop
+ B_El := Get_Nth_Element (El_Blist, I);
+ El := Get_Nth_Element (El_List, I);
+ if El /= B_El then
+ Set_Info (El, Get_Info (B_El));
+ end if;
+ end loop;
+
return;
end if;
@@ -1333,9 +1382,6 @@ package body Trans.Chap3 is
Info.Type_Mode := Type_Mode_Complex_Record;
end if;
- -- Base type is complex (unbounded record)
- Copy_Complex_Type (Info, Base_Info);
-
-- Then create the record type, containing the base record and the
-- fields.
if Has_Boxed_Elements then
@@ -1350,7 +1396,7 @@ package body Trans.Chap3 is
-- This element has been locally constrained.
if Is_Unbounded_Type (Get_Info (Get_Type (B_El)))
- and then Get_Type_Staticness (Get_Type(El)) = Locally
+ and then Get_Type_Staticness (Get_Type (El)) = Locally
then
if Kind = Mode_Value then
Field_Info := Add_Info (El, Kind_Field);
@@ -1363,6 +1409,11 @@ package body Trans.Chap3 is
New_Record_Field (Rec, Field_Info.Field_Node (Kind),
Create_Identifier_Without_Prefix (El),
El_Tnode);
+ Field_Info.Field_Bound := Get_Info (B_El).Field_Bound;
+ else
+ if Kind = Mode_Value and then El /= B_El then
+ Set_Info (El, Get_Info (B_El));
+ end if;
end if;
end loop;
Finish_Record_Type (Rec, Info.Ortho_Type (Kind));
@@ -1374,14 +1425,18 @@ package body Trans.Chap3 is
-- time.
Info.Ortho_Type := Base_Info.B.Base_Type;
Info.Ortho_Ptr_Type := Base_Info.B.Base_Ptr_Type;
- end if;
- if Get_Type_Staticness (Def) /= Locally then
- Create_Size_Var (Def, Info);
+ for I in Flist_First .. Flist_Last (El_Blist) loop
+ B_El := Get_Nth_Element (El_Blist, I);
+ El := Get_Nth_Element (El_List, I);
+ if El /= B_El then
+ Set_Info (El, Get_Info (B_El));
+ end if;
+ end loop;
end if;
if With_Vars then
- Create_Composite_Subtype_Bounds_Var (Def, False);
+ Create_Composite_Subtype_Layout_Var (Def, False);
end if;
end Translate_Record_Subtype;
@@ -1389,20 +1444,20 @@ package body Trans.Chap3 is
(Def : Iir_Record_Type_Definition; Kind : Object_Kind_Type)
is
Info : constant Type_Info_Acc := Get_Info (Def);
- Base : constant O_Dnode := Info.C (Kind).Builder_Base_Param;
+ Layout_Param : constant O_Dnode :=
+ Info.B.Builder (Kind).Builder_Layout_Param;
List : constant Iir_Flist := Get_Elements_Declaration_List (Def);
- El : Iir_Element_Declaration;
+ Layout : Mnode;
Off_Var : O_Dnode;
Off_Val : O_Enode;
- El_Off : O_Enode;
- Sub_Bound : Mnode;
- El_Type : Iir;
- Inner_Type : Iir;
- El_Tinfo : Type_Info_Acc;
begin
- Start_Subprogram_Body (Info.C (Kind).Builder_Func);
- Subprgs.Start_Subprg_Instance_Use (Info.C (Kind).Builder_Instance);
+ Start_Subprogram_Body (Info.B.Builder (Kind).Builder_Proc);
+ Subprgs.Start_Subprg_Instance_Use
+ (Info.B.Builder (Kind).Builder_Instance);
+
+ Layout := Dp2M (Layout_Param, Info, Kind,
+ Info.B.Layout_Type, Info.B.Layout_Ptr_Type);
-- Declare OFF, the offset variable
New_Var_Decl (Off_Var, Get_Identifier ("off"), O_Storage_Local,
@@ -1410,93 +1465,58 @@ package body Trans.Chap3 is
-- Reserve memory for the record, ie:
-- OFF = SIZEOF (record).
- -- Align for signals, as the base type may contain a single index.
Off_Val := New_Lit
(New_Sizeof (Info.B.Base_Type (Kind), Ghdl_Index_Type));
- if Kind = Mode_Signal then
- Off_Val := Realign (Off_Val, Ghdl_Signal_Ptr);
- end if;
New_Assign_Stmt (New_Obj (Off_Var), Off_Val);
-- Set memory for each complex element.
for I in Flist_First .. Flist_Last (List) loop
- El := Get_Nth_Element (List, I);
- El_Type := Get_Type (El);
- El_Tinfo := Get_Info (El_Type);
- if Is_Complex_Type (El_Tinfo)
- or else Is_Unbounded_Type (El_Tinfo)
- then
- -- Complex or unbounded type. Field is an offset.
-
- -- Align on the innermost array element (which should be
- -- a record) for Mode_Value. No need to align for signals,
- -- as all non-composite elements are accesses.
- Inner_Type := Get_Innermost_Non_Array_Element (El_Type);
- Off_Val := New_Obj_Value (Off_Var);
- if Kind = Mode_Value then
- Off_Val := Realign (Off_Val, Inner_Type);
+ declare
+ El : constant Iir := Get_Nth_Element (List, I);
+ El_Type : constant Iir := Get_Type (El);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
+ El_Complex : constant Boolean := Is_Complex_Type (El_Tinfo);
+ El_Unbounded : constant Boolean := Is_Unbounded_Type (El_Tinfo);
+ El_Layout : Mnode;
+ El_Size : O_Enode;
+ begin
+ if El_Unbounded then
+ -- Set layout
+ El_Layout := Record_Layout_To_Element_Layout (Layout, El);
+ Gen_Call_Type_Builder (El_Layout, El_Type, Kind);
end if;
- New_Assign_Stmt (New_Obj (Off_Var), Off_Val);
- -- Set the offset.
- New_Assign_Stmt
- (New_Selected_Element (New_Acc_Value (New_Obj (Base)),
- Get_Info (El).Field_Node (Kind)),
- New_Obj_Value (Off_Var));
+ if El_Unbounded or El_Complex then
+ -- Complex or unbounded type. Field is an offset.
- Open_Temp;
-
- if Is_Complex_Type (El_Tinfo)
- and then El_Tinfo.C (Kind).Builder_Need_Func
- then
- -- This type needs a builder, call it.
- declare
- Base2 : Mnode;
- Ptr_Var : O_Dnode;
- begin
- if Is_Unbounded_Type (Info) then
- Base2 := Create_Temp (Info, Kind);
- New_Assign_Stmt
- (M2Lp (Get_Composite_Bounds (Base2)),
- New_Obj_Value (Info.C (Kind).Builder_Bound_Param));
- New_Assign_Stmt
- (M2Lp (Get_Composite_Base (Base2)),
- New_Obj_Value (Info.C (Kind).Builder_Base_Param));
- else
- Base2 := Dp2M (Base, Info, Kind);
- end if;
-
- Ptr_Var := Create_Temp (El_Tinfo.Ortho_Ptr_Type (Kind));
+ -- Align on the innermost array element (which should be
+ -- a record) for Mode_Value. No need to align for signals,
+ -- as all non-composite elements are accesses.
+ Off_Val := New_Obj_Value (Off_Var);
+ if Kind = Mode_Value then
+ Off_Val := Realign (Off_Val, El_Type);
+ end if;
+ New_Assign_Stmt (New_Obj (Off_Var), Off_Val);
- New_Assign_Stmt
- (New_Obj (Ptr_Var),
- M2E (Chap6.Translate_Selected_Element (Base2, El)));
+ -- Set the offset.
+ New_Assign_Stmt
+ (Record_Layout_To_Element_Offset (Layout, El, Kind),
+ New_Obj_Value (Off_Var));
- El_Off := Gen_Call_Type_Builder
- (Dp2M (Ptr_Var, El_Tinfo, Kind), El_Type);
- end;
- else
- if Is_Unbounded_Type (El_Tinfo) then
- Sub_Bound := Bounds_To_Element_Bounds
- (Dp2M (Info.C (Kind).Builder_Bound_Param,
- Info, Mode_Value,
- Info.B.Bounds_Type, Info.B.Bounds_Ptr_Type),
- El);
+ if El_Unbounded then
+ El_Layout := Record_Layout_To_Element_Layout (Layout, El);
+ El_Size := New_Value
+ (Sizes_To_Size (Layout_To_Sizes (El_Layout), Kind));
else
- Sub_Bound := Mnode_Null;
+ El_Size := Get_Subtype_Size (El_Type, El_Layout, Kind);
end if;
- -- Allocate memory.
- El_Off := Get_Subtype_Size (El_Type, Sub_Bound, Kind);
+ New_Assign_Stmt (New_Obj (Off_Var),
+ New_Dyadic_Op (ON_Add_Ov,
+ New_Obj_Value (Off_Var),
+ El_Size));
end if;
-
- New_Assign_Stmt
- (New_Obj (Off_Var),
- New_Dyadic_Op (ON_Add_Ov,
- New_Obj_Value (Off_Var), El_Off));
-
- Close_Temp;
- end if;
+ end;
end loop;
-- Align the size to the object alignment.
@@ -1505,9 +1525,11 @@ package body Trans.Chap3 is
Off_Val := Realign (Off_Val, Def);
end if;
- New_Return_Stmt (Off_Val);
+ -- Set size.
+ New_Assign_Stmt (Layout_To_Size (Layout, Kind), Off_Val);
- Subprgs.Finish_Subprg_Instance_Use (Info.C (Kind).Builder_Instance);
+ Subprgs.Finish_Subprg_Instance_Use
+ (Info.B.Builder (Kind).Builder_Instance);
Finish_Subprogram_Body;
end Create_Record_Type_Builder;
@@ -1555,6 +1577,7 @@ package body Trans.Chap3 is
-- Otherwise, it is a thin pointer.
Def_Info.Type_Mode := Type_Mode_Acc;
end if;
+ Def_Info.B.Align := Align_Ptr;
if D_Info.Kind = Kind_Incomplete_Type then
-- Incomplete access.
@@ -1634,11 +1657,6 @@ package body Trans.Chap3 is
Info.Type_Mode := Type_Mode_Protected;
- -- A protected type is a complex type, as its size is not known
- -- at definition point (will be known at body declaration).
- Info.C := new Complex_Type_Arr_Info;
- Info.C (Mode_Value).Builder_Need_Func := False;
-
-- This is just use to set overload number on subprograms, and to
-- translate interfaces.
Push_Identifier_Prefix
@@ -1904,7 +1922,7 @@ package body Trans.Chap3 is
return Create_Static_Scalar_Type_Range (Def);
when Iir_Kind_Array_Subtype_Definition =>
- return Create_Static_Composite_Subtype_Bounds (Def);
+ return Create_Static_Array_Subtype_Bounds (Def);
when Iir_Kind_Array_Type_Definition =>
return O_Cnode_Null;
@@ -1930,7 +1948,7 @@ package body Trans.Chap3 is
when Iir_Kind_Array_Subtype_Definition =>
if Get_Constraint_State (Def) = Fully_Constrained then
- Elab_Composite_Subtype_Bounds (Def);
+ Elab_Composite_Subtype_Layout (Def);
end if;
when Iir_Kind_Array_Type_Definition =>
@@ -1948,16 +1966,16 @@ package body Trans.Chap3 is
end;
return;
- when Iir_Kind_Record_Subtype_Definition =>
+ when Iir_Kind_Record_Subtype_Definition
+ | Iir_Kind_Record_Type_Definition =>
Info := Get_Info (Def);
- if Info.S.Composite_Bounds /= Null_Var then
- Elab_Composite_Subtype_Bounds (Def);
+ if Info.S.Composite_Layout /= Null_Var then
+ Elab_Composite_Subtype_Layout (Def);
end if;
when Iir_Kind_Access_Type_Definition
| Iir_Kind_Access_Subtype_Definition
| Iir_Kind_File_Type_Definition
- | Iir_Kind_Record_Type_Definition
| Iir_Kind_Protected_Type_Declaration =>
return;
@@ -2111,118 +2129,6 @@ package body Trans.Chap3 is
end if;
end Create_Subtype_Info_From_Type;
- procedure Elab_Type_Definition_Size_Var (Def : Iir);
-
- procedure Elab_Record_Size_Var (Def : Iir; Kind : Object_Kind_Type)
- is
- Info : constant Type_Info_Acc := Get_Info (Def);
- List : constant Iir_Flist := Get_Elements_Declaration_List (Def);
- El : Iir_Element_Declaration;
- El_Type : Iir;
- El_Tinfo : Type_Info_Acc;
- Inner_Type : Iir;
- Res : O_Enode;
- Align_Var : O_Dnode;
- begin
- Open_Temp;
-
- -- Start with the size of the 'base' record, that
- -- contains all non-complex types and an offset for
- -- each complex types.
- Res := New_Lit (New_Sizeof (Info.Ortho_Type (Kind), Ghdl_Index_Type));
-
- -- Start with alignment of the record.
- -- ALIGN = ALIGNOF (record)
- case Kind is
- when Mode_Value =>
- Align_Var := Create_Temp (Ghdl_Index_Type);
- New_Assign_Stmt
- (New_Obj (Align_Var),
- Get_Type_Alignmask (Info.Ortho_Type (Kind)));
- when Mode_Signal =>
- Res := Realign (Res, Ghdl_Signal_Ptr);
- end case;
-
- for I in Flist_First .. Flist_Last (List) loop
- El := Get_Nth_Element (List, I);
- El_Type := Get_Type (El);
- El_Tinfo := Get_Info (El_Type);
- if Get_Type_Staticness (El_Type) /= Locally
- and then
- (Is_Complex_Type (El_Tinfo)
- or else Get_Kind (El) = Iir_Kind_Record_Element_Constraint)
- then
- Inner_Type := Get_Innermost_Non_Array_Element (El_Type);
-
- -- Align (only for Mode_Value) the size,
- -- and add the size of the element.
- if Kind = Mode_Value then
- -- Largest alignment.
- New_Assign_Stmt
- (New_Obj (Align_Var),
- New_Dyadic_Op
- (ON_Or,
- New_Obj_Value (Align_Var),
- Get_Type_Alignmask
- (Get_Ortho_Type (Inner_Type, Mode_Value))));
- Res := Realign (Res, Inner_Type);
- end if;
-
- Res := New_Dyadic_Op
- (ON_Add_Ov,
- Res, New_Value (Get_Var (El_Tinfo.C (Kind).Size_Var)));
- end if;
- end loop;
- if Kind = Mode_Value then
- Res := Realign (Res, Align_Var);
- end if;
- New_Assign_Stmt (Get_Var (Info.C (Kind).Size_Var), Res);
- Close_Temp;
- end Elab_Record_Size_Var;
-
- procedure Elab_Array_Size_Var (Def : Iir; Kind : Object_Kind_Type)
- is
- Info : constant Type_Info_Acc := Get_Info (Def);
- El_Type : constant Iir := Get_Element_Subtype (Def);
- Res : O_Enode;
- begin
- Res := New_Dyadic_Op
- (ON_Mul_Ov,
- Get_Array_Type_Length (Def),
- Chap3.Get_Object_Size (T2M (El_Type, Kind), El_Type));
- New_Assign_Stmt (Get_Var (Info.C (Kind).Size_Var), Res);
- end Elab_Array_Size_Var;
-
- procedure Elab_Type_Definition_Size_Var (Def : Iir)
- is
- Info : constant Type_Info_Acc := Get_Info (Def);
- begin
- if not Is_Complex_Type (Info) then
- return;
- end if;
-
- for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
- if Info.C (Kind).Size_Var /= Null_Var then
- case Info.Type_Mode is
- when Type_Mode_Non_Composite
- | Type_Mode_Unbounded_Array
- | Type_Mode_Unbounded_Record
- | Type_Mode_Unknown
- | Type_Mode_Protected =>
- raise Internal_Error;
- when Type_Mode_Static_Record
- | Type_Mode_Static_Array =>
- -- No need to create a size var, the size is known.
- raise Internal_Error;
- when Type_Mode_Complex_Record =>
- Elab_Record_Size_Var (Def, Kind);
- when Type_Mode_Complex_Array =>
- Elab_Array_Size_Var (Def, Kind);
- end case;
- end if;
- end loop;
- end Elab_Type_Definition_Size_Var;
-
procedure Create_Type_Range_Var (Def : Iir)
is
Info : constant Type_Info_Acc := Get_Info (Def);
@@ -2388,7 +2294,7 @@ package body Trans.Chap3 is
when Iir_Kind_Array_Type_Definition =>
Translate_Array_Element_Definition (Def);
- Translate_Array_Type_Definition (Def);
+ Translate_Array_Type (Def);
when Iir_Kind_Record_Type_Definition =>
Info.B := Ortho_Info_Basetype_Record_Init;
@@ -2480,13 +2386,13 @@ package body Trans.Chap3 is
end if;
when Iir_Kind_Array_Subtype_Definition =>
- -- Handle element subtype.
declare
El_Type : constant Iir := Get_Element_Subtype (Def);
Parent_El_Type : constant Iir :=
Get_Element_Subtype (Parent_Type);
Mark : Id_Mark_Type;
begin
+ -- Handle element subtype.
if El_Type /= Parent_El_Type then
Push_Identifier_Prefix (Mark, "ET");
Translate_Subtype_Definition
@@ -2497,7 +2403,7 @@ package body Trans.Chap3 is
if Get_Constraint_State (Def) = Fully_Constrained then
Translate_Array_Subtype_Definition (Def, Parent_Type);
if With_Vars then
- Create_Composite_Subtype_Bounds_Var (Def, False);
+ Create_Composite_Subtype_Layout_Var (Def, False);
end if;
elsif Is_Fully_Constrained_Type (El_Type)
and then not Is_Fully_Constrained_Type (Parent_El_Type)
@@ -2563,20 +2469,26 @@ package body Trans.Chap3 is
raise Internal_Error;
end case;
+ -- Create builder for arrays and non-static records
Tinfo := Get_Info (Def);
- if not Is_Complex_Type (Tinfo)
- or else Tinfo.C (Mode_Value).Builder_Need_Func = False
- then
- return;
- end if;
+ case Tinfo.Type_Mode is
+ when Type_Mode_Fat_Array
+ | Type_Mode_Unbounded_Record
+ | Type_Mode_Complex_Record =>
+ null;
+ when Type_Mode_Static_Record =>
+ return;
+ when others =>
+ -- Must have been filtered out above.
+ raise Internal_Error;
+ end case;
if Kind in Subprg_Translate_Spec then
-- Declare subprograms.
Id := Get_Identifier (Decl);
- Create_Builder_Subprogram_Decl (Tinfo, Id, Mode_Value);
- if Get_Has_Signal_Flag (Def) then
- Create_Builder_Subprogram_Decl (Tinfo, Id, Mode_Signal);
- end if;
+ for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
+ Create_Builder_Subprogram_Decl (Tinfo, Id, Kind);
+ end loop;
end if;
if Kind in Subprg_Translate_Body then
@@ -2587,15 +2499,13 @@ package body Trans.Chap3 is
-- Define subprograms.
case Get_Kind (Def) is
when Iir_Kind_Array_Type_Definition =>
- Create_Array_Type_Builder (Def, Mode_Value);
- if Get_Has_Signal_Flag (Def) then
- Create_Array_Type_Builder (Def, Mode_Signal);
- end if;
+ for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
+ Create_Array_Type_Builder (Def, Kind);
+ end loop;
when Iir_Kind_Record_Type_Definition =>
- Create_Record_Type_Builder (Def, Mode_Value);
- if Get_Has_Signal_Flag (Def) then
- Create_Record_Type_Builder (Def, Mode_Signal);
- end if;
+ for Kind in Mode_Value .. Type_To_Last_Object_Kind (Def) loop
+ Create_Record_Type_Builder (Def, Kind);
+ end loop;
when others =>
Error_Kind ("translate_type_subprograms", Def);
end case;
@@ -2636,7 +2546,6 @@ package body Trans.Chap3 is
Elab_Type_Definition_Depend (Def);
Elab_Type_Definition_Type_Range (Def);
- Elab_Type_Definition_Size_Var (Def);
end Elab_Type_Definition;
procedure Translate_Subtype_Indication (Def : Iir; With_Vars : Boolean)
@@ -2753,48 +2662,23 @@ package body Trans.Chap3 is
Iinfo.B.Range_Type, Iinfo.B.Range_Ptr_Type);
end Bounds_To_Range;
- function Bounds_To_Element_Bounds (B : Mnode; El : Iir) return Mnode
- is
- El_Type : constant Iir := Get_Type (El);
- El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
- Base_El : constant Iir := Get_Base_Element_Declaration (El);
+ function Record_Bounds_To_Element_Bounds (B : Mnode; El : Iir)
+ return Mnode is
begin
- return Lv2M
- (New_Selected_Element (M2Lv (B),
- Get_Info (Base_El).Field_Bound),
- El_Tinfo, Mode_Value,
- El_Tinfo.B.Bounds_Type, El_Tinfo.B.Bounds_Ptr_Type);
- end Bounds_To_Element_Bounds;
+ return Layout_To_Bounds (Record_Layout_To_Element_Layout (B, El));
+ end Record_Bounds_To_Element_Bounds;
function Array_Bounds_To_Element_Bounds (B : Mnode; Atype : Iir)
- return Mnode
- is
- Arr_Tinfo : constant Type_Info_Acc := Get_Info (Atype);
- El_Type : constant Iir := Get_Element_Subtype (Atype);
- El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
+ return Mnode is
begin
- return Lv2M
- (New_Selected_Element (M2Lv (B), Arr_Tinfo.B.El_Bounds),
- El_Tinfo, Mode_Value,
- El_Tinfo.B.Bounds_Type, El_Tinfo.B.Bounds_Ptr_Type);
+ return Layout_To_Bounds (Array_Bounds_To_Element_Layout (B, Atype));
end Array_Bounds_To_Element_Bounds;
function Array_Bounds_To_Element_Size (B : Mnode; Atype : Iir)
- return O_Lnode
- is
- Arr_Tinfo : constant Type_Info_Acc := Get_Info (Atype);
- Sizes : O_Lnode;
- Field : O_Fnode;
+ return O_Lnode is
begin
- Sizes := New_Selected_Element (M2Lv (B), Arr_Tinfo.B.El_Size);
- case Get_Object_Kind (B) is
- when Mode_Value =>
- Field := Ghdl_Sizes_Val;
- when Mode_Signal =>
- Field := Ghdl_Sizes_Sig;
- end case;
- Sizes := New_Selected_Element (Sizes, Field);
- return Sizes;
+ return Layout_To_Size
+ (Array_Bounds_To_Element_Layout (B, Atype), Get_Object_Kind (B));
end Array_Bounds_To_Element_Size;
function Type_To_Range (Atype : Iir) return Mnode
@@ -2847,51 +2731,35 @@ package body Trans.Chap3 is
Mode_Value);
end Range_To_Right;
- function Get_Array_Type_Bounds (Info : Type_Info_Acc) return Mnode
- is
+ function Get_Composite_Type_Bounds (Atype : Iir) return Mnode is
begin
- case Info.Type_Mode is
- when Type_Mode_Unbounded =>
- raise Internal_Error;
- when Type_Mode_Bounded_Arrays
- | Type_Mode_Bounded_Records =>
- return Varv2M (Info.S.Composite_Bounds,
- Info, Mode_Value,
- Info.B.Bounds_Type,
- Info.B.Bounds_Ptr_Type);
- when others =>
- raise Internal_Error;
- end case;
- end Get_Array_Type_Bounds;
+ return Layout_To_Bounds (Get_Composite_Type_Layout (Get_Info (Atype)));
+ end Get_Composite_Type_Bounds;
- function Get_Array_Type_Bounds (Atype : Iir) return Mnode is
- begin
- return Get_Array_Type_Bounds (Get_Info (Atype));
- end Get_Array_Type_Bounds;
-
- function Get_Composite_Bounds (Arr : Mnode) return Mnode
+ function Get_Composite_Bounds (Obj : Mnode) return Mnode
is
- Info : constant Type_Info_Acc := Get_Type_Info (Arr);
+ Info : constant Type_Info_Acc := Get_Type_Info (Obj);
begin
case Info.Type_Mode is
when Type_Mode_Unbounded_Array
| Type_Mode_Unbounded_Record =>
declare
- Kind : constant Object_Kind_Type := Get_Object_Kind (Arr);
+ Kind : constant Object_Kind_Type := Get_Object_Kind (Obj);
begin
return Lp2M
- (New_Selected_Element (M2Lv (Arr),
+ (New_Selected_Element (M2Lv (Obj),
Info.B.Bounds_Field (Kind)),
Info,
Mode_Value,
Info.B.Bounds_Type,
Info.B.Bounds_Ptr_Type);
end;
- when Type_Mode_Bounded_Arrays
- | Type_Mode_Bounded_Records =>
- return Get_Array_Type_Bounds (Info);
+ when Type_Mode_Bounded_Arrays =>
+ return Layout_To_Bounds (Get_Composite_Type_Layout (Info));
+ when Type_Mode_Bounded_Records =>
+ return Get_Composite_Type_Layout (Info);
when Type_Mode_Bounds_Acc =>
- return Lp2M (M2Lv (Arr), Info, Mode_Value);
+ return Lp2M (M2Lv (Obj), Info, Mode_Value);
when others =>
raise Internal_Error;
end case;
@@ -2942,7 +2810,7 @@ package body Trans.Chap3 is
if Type_Info.Type_Locally_Constrained then
return New_Lit (Get_Thin_Array_Length (Atype));
else
- return Get_Bounds_Length (Get_Array_Type_Bounds (Atype), Atype);
+ return Get_Bounds_Length (Get_Composite_Type_Bounds (Atype), Atype);
end if;
end Get_Array_Type_Length;
@@ -2957,59 +2825,71 @@ package body Trans.Chap3 is
end if;
end Get_Array_Length;
- function Get_Composite_Base (Arr : Mnode) return Mnode
+ -- Get the base part of a dope vector.
+ function Get_Unbounded_Base (Arr : Mnode) return Mnode
is
Info : constant Type_Info_Acc := Get_Type_Info (Arr);
+ Kind : constant Object_Kind_Type := Get_Object_Kind (Arr);
+ begin
+ pragma Assert (Info.Type_Mode in Type_Mode_Unbounded);
+ return Lp2M
+ (New_Selected_Element (M2Lv (Arr), Info.B.Base_Field (Kind)),
+ Info, Kind,
+ Info.B.Base_Type (Kind), Info.B.Base_Ptr_Type (Kind));
+ end Get_Unbounded_Base;
+
+ function Get_Composite_Base (Obj : Mnode) return Mnode
+ is
+ Info : constant Type_Info_Acc := Get_Type_Info (Obj);
begin
case Info.Type_Mode is
when Type_Mode_Unbounded_Array
| Type_Mode_Unbounded_Record =>
- declare
- Kind : constant Object_Kind_Type := Get_Object_Kind (Arr);
- begin
- return Lp2M
- (New_Selected_Element (M2Lv (Arr),
- Info.B.Base_Field (Kind)),
- Info, Kind,
- Info.B.Base_Type (Kind), Info.B.Base_Ptr_Type (Kind));
- end;
- when Type_Mode_Bounded_Arrays =>
- return Arr;
- when Type_Mode_Bounded_Records =>
- return Unbox_Record (Arr);
+ return Get_Unbounded_Base (Obj);
+ when Type_Mode_Bounded_Arrays
+ | Type_Mode_Bounded_Records =>
+ return Obj;
when others =>
raise Internal_Error;
end case;
end Get_Composite_Base;
- function Unbox_Record (Arr : Mnode) return Mnode
+ function Unbox_Record (Obj : Mnode) return Mnode
is
- Info : constant Type_Info_Acc := Get_Type_Info (Arr);
+ Info : constant Type_Info_Acc := Get_Type_Info (Obj);
+ pragma Assert (Info.Type_Mode in Type_Mode_Bounded_Records);
+ Kind : constant Object_Kind_Type := Get_Object_Kind (Obj);
+ Box_Field : constant O_Fnode := Info.S.Box_Field (Kind);
+ begin
+ if Box_Field /= O_Fnode_Null then
+ -- Unbox the record.
+ return Lv2M (New_Selected_Element (M2Lv (Obj), Box_Field),
+ Info, Kind,
+ Info.B.Base_Type (Kind),
+ Info.B.Base_Ptr_Type (Kind));
+ else
+ return Obj;
+ end if;
+ end Unbox_Record;
+
+ function Get_Composite_Unbounded_Base (Obj : Mnode) return Mnode
+ is
+ Info : constant Type_Info_Acc := Get_Type_Info (Obj);
begin
case Info.Type_Mode is
- when Type_Mode_Arrays =>
- return Arr;
- when Type_Mode_Unbounded_Record =>
- return Arr;
+ when Type_Mode_Unbounded_Array
+ | Type_Mode_Unbounded_Record =>
+ return Get_Unbounded_Base (Obj);
+ when Type_Mode_Bounded_Arrays =>
+ -- This works in ortho as an access to unconstrained array is
+ -- also an access to a constrained array.
+ return Obj;
when Type_Mode_Bounded_Records =>
- declare
- Kind : constant Object_Kind_Type := Get_Object_Kind (Arr);
- Box_Field : constant O_Fnode := Info.S.Box_Field (Kind);
- begin
- if Box_Field /= O_Fnode_Null then
- -- Unbox the record.
- return Lv2M (New_Selected_Element (M2Lv (Arr), Box_Field),
- Info, Kind,
- Info.B.Base_Type (Kind),
- Info.B.Base_Ptr_Type (Kind));
- else
- return Arr;
- end if;
- end;
+ return Unbox_Record (Obj);
when others =>
raise Internal_Error;
end case;
- end Unbox_Record;
+ end Get_Composite_Unbounded_Base;
function Create_Maybe_Fat_Array_Element (Arr : Mnode; Arr_Type : Iir)
return Mnode
@@ -3072,13 +2952,12 @@ package body Trans.Chap3 is
return Mnode
is
El_Type : constant Iir := Get_Element_Subtype (Atype);
- El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
Kind : constant Object_Kind_Type := Get_Object_Kind (Base);
begin
return E2M (Reindex_Array
(Base, Atype,
Index,
- New_Value (Get_Var (El_Tinfo.C (Kind).Size_Var))),
+ Get_Subtype_Size (El_Type, Mnode_Null, Kind)),
Res_Info, Kind);
end Reindex_Complex_Array;
@@ -3151,22 +3030,6 @@ package body Trans.Chap3 is
end if;
end Slice_Base;
- procedure Maybe_Call_Type_Builder (Obj : Mnode; Obj_Type : Iir)
- is
- Dinfo : constant Type_Info_Acc :=
- Get_Info (Get_Base_Type (Obj_Type));
- Kind : constant Object_Kind_Type := Get_Object_Kind (Obj);
- begin
- if Is_Complex_Type (Dinfo)
- and then Dinfo.C (Kind).Builder_Need_Func
- then
- Open_Temp;
- -- Build the type.
- Chap3.Gen_Call_Type_Builder (Obj, Obj_Type);
- Close_Temp;
- end if;
- end Maybe_Call_Type_Builder;
-
procedure Allocate_Unbounded_Composite_Base (Alloc_Kind : Allocation_Kind;
Res : Mnode;
Arr_Type : Iir)
@@ -3182,8 +3045,6 @@ package body Trans.Chap3 is
New_Assign_Stmt
(M2Lp (Chap3.Get_Composite_Base (Res)),
Gen_Alloc (Alloc_Kind, Length, Dinfo.B.Base_Ptr_Type (Kind)));
-
- Maybe_Call_Type_Builder (Res, Arr_Type);
end Allocate_Unbounded_Composite_Base;
procedure Allocate_Unbounded_Composite_Bounds
@@ -3207,12 +3068,12 @@ package body Trans.Chap3 is
begin
Chap3.Translate_Subtype_Definition
(Arr_Type, Get_Base_Type (Arr_Type), False);
- Chap3.Create_Composite_Subtype_Bounds_Var (Arr_Type, False);
+ Chap3.Create_Composite_Subtype_Layout_Var (Arr_Type, False);
end Translate_Array_Subtype;
procedure Elab_Array_Subtype (Arr_Type : Iir) is
begin
- Chap3.Elab_Composite_Subtype_Bounds (Arr_Type);
+ Chap3.Elab_Composite_Subtype_Layout (Arr_Type);
end Elab_Array_Subtype;
procedure Create_Array_Subtype (Sub_Type : Iir)
@@ -3226,8 +3087,7 @@ package body Trans.Chap3 is
(Sub_Type, Get_Base_Type (Sub_Type), False);
end if;
-- Force creation of variables.
- Chap3.Create_Composite_Subtype_Bounds_Var (Sub_Type, True);
- Chap3.Elab_Type_Definition_Size_Var (Sub_Type);
+ Chap3.Create_Composite_Subtype_Layout_Var (Sub_Type, True);
Pop_Identifier_Prefix (Mark);
end Create_Array_Subtype;
@@ -3271,66 +3131,30 @@ package body Trans.Chap3 is
Type_Info : constant Type_Info_Acc := Get_Info (Atype);
begin
case Type_Info.Type_Mode is
- when Type_Mode_Complex_Array
- | Type_Mode_Complex_Record =>
- -- The length is pre-computed for a complex bounded type.
- if Type_Info.C (Kind).Size_Var /= Null_Var then
- return New_Value (Get_Var (Type_Info.C (Kind).Size_Var));
- else
- raise Internal_Error;
- end if;
when Type_Mode_Non_Composite
| Type_Mode_Static_Array
| Type_Mode_Static_Record =>
return New_Lit (New_Sizeof (Type_Info.Ortho_Type (Kind),
Ghdl_Index_Type));
+ when Type_Mode_Complex_Array
+ | Type_Mode_Complex_Record =>
+ -- The length is pre-computed for a complex bounded type.
+ return New_Value
+ (Sizes_To_Size
+ (Layout_To_Sizes
+ (Get_Composite_Type_Layout (Type_Info)), Kind));
when Type_Mode_Unbounded_Array =>
declare
El_Type : constant Iir := Get_Element_Subtype (Atype);
El_Sz : O_Enode;
begin
- -- See create_array_size_var.
+ -- FIXME: unbounded elements ?
El_Sz := Get_Subtype_Size (El_Type, Mnode_Null, Kind);
return New_Dyadic_Op
(ON_Mul_Ov, Chap3.Get_Bounds_Length (Bounds, Atype), El_Sz);
end;
when Type_Mode_Unbounded_Record =>
- declare
- El_List : constant Iir_Flist :=
- Get_Elements_Declaration_List (Atype);
- El : Iir;
- El_Type : Iir;
- El_Type_Info : Type_Info_Acc;
- El_Bounds : Mnode;
- Stable_Bounds : Mnode;
- Res : O_Enode;
- begin
- Stable_Bounds := Stabilize (Bounds);
-
- -- Size of base type
- Res := New_Lit (New_Sizeof (Type_Info.B.Base_Type (Kind),
- Ghdl_Index_Type));
- for I in Flist_First .. Flist_Last (El_List) loop
- El := Get_Nth_Element (El_List, I);
- El_Type := Get_Type (El);
- El_Type_Info := Get_Info (El_Type);
- if El_Type_Info.Type_Mode in Type_Mode_Unbounded then
- -- Recurse
- Res := Realign (Res, El_Type);
- El_Bounds := Bounds_To_Element_Bounds (Stable_Bounds, El);
- Res := New_Dyadic_Op
- (ON_Add_Ov,
- Res, Get_Subtype_Size (El_Type, El_Bounds, Kind));
- elsif Is_Complex_Type (El_Type_Info) then
- -- Add supplement
- Res := Realign (Res, El_Type);
- Res := New_Dyadic_Op
- (ON_Add_Ov,
- Res, Get_Subtype_Size (El_Type, Mnode_Null, Kind));
- end if;
- end loop;
- return Res;
- end;
+ return New_Value (Sizes_To_Size (Layout_To_Sizes (Bounds), Kind));
when others =>
raise Internal_Error;
end case;
@@ -3385,8 +3209,6 @@ package body Trans.Chap3 is
Gen_Alloc (Alloc_Kind,
Chap3.Get_Object_Size (T2M (Obj_Type, Kind), Obj_Type),
Tinfo.Ortho_Ptr_Type (Kind)));
-
- Maybe_Call_Type_Builder (Res, Obj_Type);
end if;
end Translate_Object_Allocation;
diff --git a/src/vhdl/translate/trans-chap3.ads b/src/vhdl/translate/trans-chap3.ads
index 9900f48a9..2b9f37e6b 100644
--- a/src/vhdl/translate/trans-chap3.ads
+++ b/src/vhdl/translate/trans-chap3.ads
@@ -43,7 +43,7 @@ package Trans.Chap3 is
procedure Translate_Type_Subprograms
(Decl : Iir; Kind : Subprg_Translate_Kind);
- function Create_Static_Composite_Subtype_Bounds (Def : Iir) return O_Cnode;
+ function Create_Static_Composite_Subtype_Layout (Def : Iir) return O_Cnode;
-- Same as Translate_type_definition only for std.standard.boolean and
-- std.standard.bit.
@@ -116,9 +116,6 @@ package Trans.Chap3 is
-- For a second or third order complex type, INFO.C.BUILDER_NEED_FUNC
-- is set to TRUE.
- -- Call builder for variable pointed VAR of type VAR_TYPE.
- procedure Gen_Call_Type_Builder (Var : Mnode; Var_Type : Iir);
-
-- Functions for fat array.
-- Fat array are array whose size is not known at compilation time.
-- This corresponds to an unconstrained array or a non locally static
@@ -166,11 +163,17 @@ package Trans.Chap3 is
-- Get the number of elements in array ATYPE.
function Get_Array_Type_Length (Atype : Iir) return O_Enode;
- -- Get the base of array or record ARR.
- function Get_Composite_Base (Arr : Mnode) return Mnode;
+ -- Get the base of array or record OBJ. If OBJ is already constrained,
+ -- return it.
+ function Get_Composite_Base (Obj : Mnode) return Mnode;
+
+ -- Get the base of array or record OBJ; but if OBJ is already constrained,
+ -- convert it to the base of an unbounded object (so this unboxes the
+ -- records).
+ function Get_Composite_Unbounded_Base (Obj : Mnode) return Mnode;
-- Get the bounds of composite ARR (an array or an unbounded record).
- function Get_Composite_Bounds (Arr : Mnode) return Mnode;
+ function Get_Composite_Bounds (Obj : Mnode) return Mnode;
-- Get the range ot ATYPE.
function Type_To_Range (Atype : Iir) return Mnode;
@@ -194,16 +197,27 @@ package Trans.Chap3 is
function Get_Array_Range (Arr : Mnode; Atype : Iir; Dim : Positive)
return Mnode;
- -- Get array bounds for type ATYPE.
- function Get_Array_Type_Bounds (Atype : Iir) return Mnode;
+ -- Get array/record bounds for type ATYPE.
+ function Get_Composite_Type_Bounds (Atype : Iir) return Mnode;
-- Return a pointer to the base from bounds_acc ACC.
function Get_Bounds_Acc_Base
(Acc : O_Enode; D_Type : Iir) return O_Enode;
+ -- Return bounds from layout B.
+ function Layout_To_Bounds (B : Mnode) return Mnode;
+
+ -- From a record layout B, return the layout of element EL. EL must be
+ -- an unbounded element.
+ function Record_Layout_To_Element_Layout (B : Mnode; El : Iir) return Mnode;
+
-- From an unbounded record bounds B, get the bounds for (unbounded)
-- element EL.
- function Bounds_To_Element_Bounds (B : Mnode; El : Iir) return Mnode;
+ function Record_Bounds_To_Element_Bounds (B : Mnode; El : Iir) return Mnode;
+
+ -- Return the offset for field EL in record B.
+ function Record_Layout_To_Element_Offset
+ (B : Mnode; El : Iir; Kind : Object_Kind_Type) return O_Lnode;
-- From an unbounded array bounds B, get the bounds for the (unbounded)
-- element.
@@ -246,9 +260,6 @@ package Trans.Chap3 is
-- it may be the result of T2M.
function Get_Object_Size (Obj : Mnode; Obj_Type : Iir) return O_Enode;
- -- If needed call the procedure to build OBJ.
- procedure Maybe_Call_Type_Builder (Obj : Mnode; Obj_Type : Iir);
-
-- Allocate the base of an unbounded composite, whose length is
-- determined from the bounds (already set).
-- RES_PTR is a pointer to the fat pointer (must be a stable variable: it
diff --git a/src/vhdl/translate/trans-chap4.adb b/src/vhdl/translate/trans-chap4.adb
index 47b9f5674..69577161e 100644
--- a/src/vhdl/translate/trans-chap4.adb
+++ b/src/vhdl/translate/trans-chap4.adb
@@ -301,8 +301,6 @@ package body Trans.Chap4 is
is
Type_Info : constant Type_Info_Acc := Get_Type_Info (Var);
Kind : constant Object_Kind_Type := Get_Object_Kind (Var);
- Targ : Mnode;
- Has_Ref : Boolean;
begin
-- Cannot allocate unconstrained object (since size is unknown).
pragma Assert (Type_Info.Type_Mode not in Type_Mode_Unbounded);
@@ -312,34 +310,12 @@ package body Trans.Chap4 is
return;
end if;
- Has_Ref := False;
- Targ := Var;
-
- if not Is_Static_Type (Type_Info) then
- if Type_Info.C (Kind).Builder_Need_Func
- and then not Is_Stable (Var)
- then
- -- Need a stable reference...
- Targ := Create_Temp (Type_Info, Kind);
- Has_Ref := True;
- end if;
-
- -- Allocate variable.
- New_Assign_Stmt (M2Lp (Targ),
- Gen_Alloc (Alloc_Kind,
- Chap3.Get_Object_Size (Var, Obj_Type),
- Type_Info.Ortho_Ptr_Type (Kind)));
- end if;
-
- if Type_Info.C (Kind).Builder_Need_Func then
- -- Build the type.
- Chap3.Gen_Call_Type_Builder (Targ, Obj_Type);
- end if;
-
- if Has_Ref then
- New_Assign_Stmt (M2Lp (Var), M2Addr (Targ));
- Var := Targ;
- end if;
+ -- Allocate variable.
+ New_Assign_Stmt
+ (M2Lp (Var),
+ Gen_Alloc (Alloc_Kind,
+ Chap3.Get_Subtype_Size (Obj_Type, Mnode_Null, Kind),
+ Type_Info.Ortho_Ptr_Type (Kind)));
end Allocate_Complex_Object;
-- Note : OBJ can be a tree.
@@ -535,13 +511,13 @@ package body Trans.Chap4 is
-- Short-cut: don't allocate bounds.
New_Assign_Stmt
(M2Lp (Chap3.Get_Composite_Bounds (Name_Node)),
- M2Addr (Chap3.Get_Array_Type_Bounds (Aggr_Type)));
+ M2Addr (Chap3.Get_Composite_Type_Bounds (Aggr_Type)));
Chap3.Allocate_Unbounded_Composite_Base
(Alloc_Kind, Name_Node, Get_Base_Type (Aggr_Type));
else
Chap3.Translate_Object_Allocation
(Name_Node, Alloc_Kind, Get_Base_Type (Aggr_Type),
- Chap3.Get_Array_Type_Bounds (Aggr_Type));
+ Chap3.Get_Composite_Type_Bounds (Aggr_Type));
end if;
end;
else
@@ -642,23 +618,35 @@ package body Trans.Chap4 is
Obj_Type : constant Iir := Get_Type (Obj);
Type_Info : constant Type_Info_Acc := Get_Info (Obj_Type);
begin
- if Type_Info.Type_Mode in Type_Mode_Unbounded then
- declare
- V : Mnode;
- begin
- Open_Temp;
- V := Chap6.Translate_Name (Obj, Mode_Value);
- Stabilize (V);
- Chap3.Gen_Deallocate
- (New_Value (M2Lp (Chap3.Get_Composite_Bounds (V))));
+ case Type_Mode_Valid (Type_Info.Type_Mode) is
+ when Type_Mode_Unbounded =>
+ declare
+ V : Mnode;
+ begin
+ Open_Temp;
+ V := Chap6.Translate_Name (Obj, Mode_Value);
+ Stabilize (V);
+ Chap3.Gen_Deallocate
+ (New_Value (M2Lp (Chap3.Get_Composite_Bounds (V))));
+ Chap3.Gen_Deallocate
+ (New_Value (M2Lp (Chap3.Get_Composite_Base (V))));
+ Close_Temp;
+ end;
+ when Type_Mode_Complex_Array
+ | Type_Mode_Complex_Record
+ | Type_Mode_Protected =>
Chap3.Gen_Deallocate
- (New_Value (M2Lp (Chap3.Get_Composite_Base (V))));
- Close_Temp;
- end;
- elsif Is_Complex_Type (Type_Info) then
- Chap3.Gen_Deallocate
- (New_Value (M2Lp (Chap6.Translate_Name (Obj, Mode_Value))));
- end if;
+ (New_Value (M2Lp (Chap6.Translate_Name (Obj, Mode_Value))));
+ when Type_Mode_Scalar
+ | Type_Mode_Static_Record
+ | Type_Mode_Static_Array
+ | Type_Mode_Acc
+ | Type_Mode_Bounds_Acc =>
+ null;
+ when Type_Mode_File =>
+ -- FIXME: free file ?
+ null;
+ end case;
end Fini_Object;
function Get_Nbr_Signals (Sig : Mnode; Sig_Type : Iir) return O_Enode
@@ -1152,9 +1140,9 @@ package body Trans.Chap4 is
begin
Start_Association (Assoc, Ghdl_Signal_Name_Rti);
New_Association
- (Assoc, New_Lit (New_Global_Unchecked_Address
- (Get_Info (Base_Decl).Signal_Rti,
- Rtis.Ghdl_Rti_Access)));
+ (Assoc,
+ New_Unchecked_Address (New_Obj (Get_Info (Base_Decl).Signal_Rti),
+ Rtis.Ghdl_Rti_Access));
Rtis.Associate_Rti_Context (Assoc, Parent);
New_Procedure_Call (Assoc);
end;
@@ -3184,7 +3172,8 @@ package body Trans.Chap4 is
Start_Init_Value (C);
Start_Record_Aggr (Constr, Ghdl_Location_Type_Node);
New_Record_Aggr_El
- (Constr, New_Global_Address (Current_Filename_Node, Char_Ptr_Type));
+ (Constr, New_Global_Address (New_Global (Current_Filename_Node),
+ Char_Ptr_Type));
New_Record_Aggr_El (Constr, New_Signed_Literal (Ghdl_I32_Type,
Integer_64 (Line)));
New_Record_Aggr_El (Constr, New_Signed_Literal (Ghdl_I32_Type,
diff --git a/src/vhdl/translate/trans-chap5.adb b/src/vhdl/translate/trans-chap5.adb
index 5f8375760..4c3f0ce20 100644
--- a/src/vhdl/translate/trans-chap5.adb
+++ b/src/vhdl/translate/trans-chap5.adb
@@ -424,7 +424,7 @@ package body Trans.Chap5 is
if Get_Info (Formal_Type).Type_Mode in Type_Mode_Composite then
New_Assign_Stmt
(M2Lp (Chap3.Get_Composite_Base (Formal_Val)),
- M2Addr (Chap3.Get_Composite_Base (Actual_Val)));
+ M2Addr (Chap3.Get_Composite_Unbounded_Base (Actual_Val)));
else
New_Assign_Stmt (M2Lp (Formal_Val), M2Addr (Actual_Val));
end if;
@@ -537,11 +537,11 @@ package body Trans.Chap5 is
begin
if Is_Fully_Constrained_Type (Actual_Type) then
Chap3.Create_Array_Subtype (Actual_Type);
- Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type);
+ Bounds := Chap3.Get_Composite_Type_Bounds (Actual_Type);
Tinfo := Get_Info (Actual_Type);
if Save
and then
- Get_Alloc_Kind_For_Var (Tinfo.S.Composite_Bounds) = Alloc_Stack
+ Get_Alloc_Kind_For_Var (Tinfo.S.Composite_Layout) = Alloc_Stack
then
-- We need a copy.
Bounds_Copy := Alloc_Bounds (Actual_Type, Alloc_System);
@@ -575,7 +575,7 @@ package body Trans.Chap5 is
In_Conv_Type := Get_Type (In_Conv);
if Is_Fully_Constrained_Type (In_Conv_Type) then
-- The 'in' conversion gives the type.
- return Chap3.Get_Array_Type_Bounds (In_Conv_Type);
+ return Chap3.Get_Composite_Type_Bounds (In_Conv_Type);
elsif Get_Kind (In_Conv) = Iir_Kind_Type_Conversion then
-- Convert bounds of the actual.
Can_Convert := True;
@@ -590,7 +590,7 @@ package body Trans.Chap5 is
Param_Type := Get_Type (Get_Interface_Declaration_Chain
(Get_Implementation (Out_Conv)));
if Is_Fully_Constrained_Type (Param_Type) then
- return Chap3.Get_Array_Type_Bounds (Param_Type);
+ return Chap3.Get_Composite_Type_Bounds (Param_Type);
else
pragma Assert (Can_Convert);
null;
@@ -629,35 +629,33 @@ package body Trans.Chap5 is
Get_Type (Get_Default_Value (Port));
begin
Chap3.Create_Array_Subtype (Actual_Type);
- Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type);
+ Bounds := Chap3.Get_Composite_Type_Bounds (Actual_Type);
end;
when Iir_Kind_Association_Element_By_Individual =>
declare
Actual_Type : constant Iir := Get_Actual_Type (Assoc);
begin
Chap3.Create_Array_Subtype (Actual_Type);
- Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type);
+ Bounds := Chap3.Get_Composite_Type_Bounds (Actual_Type);
end;
end case;
Stabilize (Bounds);
for K in Object_Kind_Type loop
Act_Node := Chap6.Translate_Name (Port, K);
- New_Assign_Stmt
- (-- Note: this works only because it is not stabilized, and
- -- therefore the bounds field is returned and not a pointer to
- -- the bounds.
- M2Lp (Chap3.Get_Composite_Bounds (Act_Node)),
- M2Addr (Bounds));
+ -- Note: this works only because it is not stabilized, and
+ -- therefore the bounds field is returned and not a pointer to
+ -- the bounds.
+ New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Bounds (Act_Node)),
+ M2Addr (Bounds));
end loop;
-- Set bounds of init value (if present)
Info := Get_Info (Port);
if Info.Signal_Val /= Null_Var then
- New_Assign_Stmt
- (M2Lp (Chap3.Get_Composite_Bounds
- (Chap6.Get_Port_Init_Value (Port))),
- M2Addr (Bounds));
+ New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Bounds
+ (Chap6.Get_Port_Init_Value (Port))),
+ M2Addr (Bounds));
end if;
Close_Temp;
end Elab_Unconstrained_Port_Bounds;
@@ -824,7 +822,7 @@ package body Trans.Chap5 is
(Formal_Type, Alloc_System, Formal_Node);
else
Chap3.Create_Array_Subtype (Obj_Type);
- Bounds := Chap3.Get_Array_Type_Bounds (Obj_Type);
+ Bounds := Chap3.Get_Composite_Type_Bounds (Obj_Type);
Chap3.Translate_Object_Allocation
(Formal_Node, Alloc_System, Formal_Type, Bounds);
end if;
diff --git a/src/vhdl/translate/trans-chap6.adb b/src/vhdl/translate/trans-chap6.adb
index 08f7de26e..7eb74820a 100644
--- a/src/vhdl/translate/trans-chap6.adb
+++ b/src/vhdl/translate/trans-chap6.adb
@@ -412,7 +412,7 @@ package body Trans.Chap6 is
-- Manually extract range since there is no infos for
-- index subtype.
Range_Ptr := Chap3.Bounds_To_Range
- (Chap3.Get_Array_Type_Bounds (Prefix_Type),
+ (Chap3.Get_Composite_Type_Bounds (Prefix_Type),
Prefix_Type, Dim);
Stabilize (Range_Ptr);
R := Translate_Index_To_Offset
@@ -596,7 +596,7 @@ package body Trans.Chap6 is
-- Save slice bounds.
Slice_Range := Stabilize
- (Chap3.Bounds_To_Range (Chap3.Get_Array_Type_Bounds (Slice_Type),
+ (Chap3.Bounds_To_Range (Chap3.Get_Composite_Type_Bounds (Slice_Type),
Slice_Type, 1));
-- TRUE if the direction of the slice is known.
@@ -834,7 +834,10 @@ package body Trans.Chap6 is
Kind : constant Object_Kind_Type := Get_Object_Kind (Prefix);
El_Info : Field_Info_Acc;
Base_Tinfo : Type_Info_Acc;
- Stable_Prefix, Base, Res, Fat_Res : Mnode;
+ Stable_Prefix : Mnode;
+ Base, Res, Fat_Res : Mnode;
+ Rec_Layout : Mnode;
+ El_Descr : Mnode;
Box_Field : O_Fnode;
B : O_Lnode;
begin
@@ -856,26 +859,26 @@ package body Trans.Chap6 is
Stable_Prefix := Stabilize (Prefix);
-- Result is a fat pointer, create it and set bounds.
+ -- FIXME: layout for record, bounds for array!
Fat_Res := Create_Temp (El_Tinfo, Kind);
- New_Assign_Stmt
- (M2Lp (Chap3.Get_Composite_Bounds (Fat_Res)),
- New_Address
- (New_Selected_Element
- (M2Lv (Chap3.Get_Composite_Bounds (Stable_Prefix)),
- El_Info.Field_Bound),
- El_Tinfo.B.Bounds_Ptr_Type));
+ El_Descr := Chap3.Record_Layout_To_Element_Layout
+ (Chap3.Get_Composite_Bounds (Stable_Prefix), El);
+ case El_Tinfo.Type_Mode is
+ when Type_Mode_Unbounded_Record =>
+ null;
+ when Type_Mode_Unbounded_Array =>
+ El_Descr := Chap3.Layout_To_Bounds (El_Descr);
+ when others =>
+ raise Internal_Error;
+ end case;
+ New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Bounds (Fat_Res)),
+ M2Addr (El_Descr));
else
Stable_Prefix := Prefix;
end if;
- if Get_Type_Info (Stable_Prefix).Type_Mode = Type_Mode_Unbounded_Record
- then
- -- Get the base.
- Base := Chap3.Get_Composite_Base (Stable_Prefix);
- else
- -- Might be a boxed subtype; keep the box to optimize the access.
- Base := Stable_Prefix;
- end if;
+ -- Get the base.
+ Base := Chap3.Get_Composite_Base (Stable_Prefix);
Base_Tinfo := Get_Type_Info (Base);
Box_Field := Base_Tinfo.S.Box_Field (Kind);
@@ -895,6 +898,7 @@ package body Trans.Chap6 is
end if;
-- The element is complex: it's an offset.
+ Rec_Layout := Chap3.Get_Composite_Bounds (Stable_Prefix);
Res := E2M
(New_Unchecked_Address
(New_Slice
@@ -902,8 +906,8 @@ package body Trans.Chap6 is
(New_Unchecked_Address (M2Lv (Base), Char_Ptr_Type)),
Chararray_Type,
New_Value
- (New_Selected_Element (B,
- El_Info.Field_Node (Kind)))),
+ (Chap3.Record_Layout_To_Element_Offset
+ (Rec_Layout, El, Kind))),
El_Tinfo.B.Base_Ptr_Type (Kind)),
El_Tinfo, Kind);
else
diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb
index 614f993f3..e93dce632 100644
--- a/src/vhdl/translate/trans-chap7.adb
+++ b/src/vhdl/translate/trans-chap7.adb
@@ -65,7 +65,7 @@ package body Trans.Chap7 is
Val : Var_Type;
Res : O_Cnode;
List : O_Record_Aggr_List;
- Bound : Var_Type;
+ Layout : Var_Type;
begin
if Res_Type = Expr_Type then
return Expr;
@@ -96,22 +96,24 @@ package body Trans.Chap7 is
Val := Create_Global_Const
(Create_Uniq_Identifier, Expr_Info.Ortho_Type (Mode_Value),
O_Storage_Private, Expr);
- Bound := Expr_Info.S.Composite_Bounds;
- if Bound = Null_Var then
- Bound := Create_Global_Const
- (Create_Uniq_Identifier, Expr_Info.B.Bounds_Type,
+ Layout := Expr_Info.S.Composite_Layout;
+ if Layout = Null_Var then
+ Layout := Create_Global_Const
+ (Create_Uniq_Identifier, Expr_Info.B.Layout_Type,
O_Storage_Private,
- Chap3.Create_Static_Composite_Subtype_Bounds (Expr_Type));
- Expr_Info.S.Composite_Bounds := Bound;
+ Chap3.Create_Static_Composite_Subtype_Layout (Expr_Type));
+ Expr_Info.S.Composite_Layout := Layout;
end if;
Start_Record_Aggr (List, Res_Info.Ortho_Type (Mode_Value));
New_Record_Aggr_El
- (List, New_Global_Address (Get_Var_Label (Val),
- Res_Info.B.Base_Ptr_Type (Mode_Value)));
+ (List, New_Global_Address (New_Global (Get_Var_Label (Val)),
+ Res_Info.B.Base_Ptr_Type (Mode_Value)));
New_Record_Aggr_El
- (List, New_Global_Address (Get_Var_Label (Bound),
- Expr_Info.B.Bounds_Ptr_Type));
+ (List, New_Global_Address (New_Global_Selected_Element
+ (New_Global (Get_Var_Label (Layout)),
+ Expr_Info.B.Layout_Bounds),
+ Expr_Info.B.Bounds_Ptr_Type));
Finish_Record_Aggr (List, Res);
return Res;
@@ -375,12 +377,12 @@ package body Trans.Chap7 is
Start_Record_Aggr (Res_Aggr, Type_Info.Ortho_Type (Mode_Value));
New_Record_Aggr_El
(Res_Aggr,
- New_Global_Address (Get_Var_Label (Val),
- Type_Info.B.Base_Ptr_Type (Mode_Value)));
+ New_Global_Address (New_Global (Get_Var_Label (Val)),
+ Type_Info.B.Base_Ptr_Type (Mode_Value)));
New_Record_Aggr_El
(Res_Aggr,
- New_Global_Address (Get_Var_Label (Bound),
- Type_Info.B.Bounds_Ptr_Type));
+ New_Global_Address (New_Global (Get_Var_Label (Bound)),
+ Type_Info.B.Bounds_Ptr_Type));
Finish_Record_Aggr (Res_Aggr, Res);
Val := Create_Global_Const
@@ -818,7 +820,7 @@ package body Trans.Chap7 is
Atype_El_Type := Get_Type (Atype_El);
if Expr_El_Type /= Atype_El_Type then
Convert_To_Constrained_Check
- (Chap3.Bounds_To_Element_Bounds
+ (Chap3.Record_Bounds_To_Element_Bounds
(Stable_Bounds, Expr_El),
Expr_El_Type, Atype_El_Type, Failure_Label);
end if;
@@ -2626,8 +2628,7 @@ package body Trans.Chap7 is
return Translate_To_String
(Subprg, Res_Type, Expr,
New_Convert_Ov (Left_Tree, Conv),
- New_Lit (Rtis.New_Rti_Address
- (Get_Info (Left_Type).Type_Rti)));
+ Rtis.New_Rti_Address (Get_Info (Left_Type).Type_Rti));
end;
when Iir_Predefined_Floating_To_String =>
return Translate_To_String
@@ -2661,15 +2662,13 @@ package body Trans.Chap7 is
return Translate_To_String
(Subprg, Res_Type, Expr,
New_Convert_Ov (Left_Tree, Conv),
- New_Lit (Rtis.New_Rti_Address
- (Get_Info (Left_Type).Type_Rti)));
+ Rtis.New_Rti_Address (Get_Info (Left_Type).Type_Rti));
end;
when Iir_Predefined_Time_To_String_Unit =>
return Translate_To_String
(Ghdl_Time_To_String_Unit, Res_Type, Expr,
Left_Tree, Right_Tree,
- New_Lit (Rtis.New_Rti_Address
- (Get_Info (Left_Type).Type_Rti)));
+ Rtis.New_Rti_Address (Get_Info (Left_Type).Type_Rti));
when Iir_Predefined_Bit_Vector_To_Ostring =>
return Translate_Bv_To_String
(Ghdl_BV_To_Ostring, Left_Tree, Left_Type, Res_Type, Expr);
@@ -2699,8 +2698,7 @@ package body Trans.Chap7 is
New_Convert_Ov (M2E (Chap3.Get_Composite_Base (Arg)),
Ghdl_Ptr_Type),
Chap3.Get_Array_Length (Arg, Left_Type),
- New_Lit (Rtis.New_Rti_Address
- (Get_Info (El_Type).Type_Rti)));
+ Rtis.New_Rti_Address (Get_Info (El_Type).Type_Rti));
end;
when others =>
@@ -3551,7 +3549,7 @@ package body Trans.Chap7 is
Val_Size := Create_Temp_Init
(Ghdl_Index_Type,
Chap3.Get_Subtype_Size
- (D_Type, Chap3.Get_Array_Type_Bounds (Sub_Type),
+ (D_Type, Chap3.Get_Composite_Type_Bounds (Sub_Type),
Mode_Value));
-- Size of the bounds.
@@ -3569,14 +3567,12 @@ package body Trans.Chap7 is
A_Info.Ortho_Type (Mode_Value)));
-- Copy bounds.
- Gen_Memcpy
- (New_Obj_Value (Ptr),
- M2Addr (Chap3.Get_Array_Type_Bounds (Sub_Type)),
- New_Lit (Bounds_Size));
+ Gen_Memcpy (New_Obj_Value (Ptr),
+ M2Addr (Chap3.Get_Composite_Type_Bounds (Sub_Type)),
+ New_Lit (Bounds_Size));
-- Create a fat pointer to initialize the object.
Res := Bounds_Acc_To_Fat_Pointer (Ptr, A_Type);
- Chap3.Maybe_Call_Type_Builder (Res, D_Type);
Chap4.Init_Object (Res, D_Type);
return New_Obj_Value (Ptr);
diff --git a/src/vhdl/translate/trans-chap8.adb b/src/vhdl/translate/trans-chap8.adb
index 8fc959ab5..318d0142f 100644
--- a/src/vhdl/translate/trans-chap8.adb
+++ b/src/vhdl/translate/trans-chap8.adb
@@ -2713,7 +2713,8 @@ package body Trans.Chap8 is
if Mode = Mode_Value then
if Get_Type_Staticness (Actual_Type) >= Globally then
Chap3.Create_Array_Subtype (Actual_Type);
- Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type);
+ Bounds :=
+ Chap3.Get_Composite_Type_Bounds (Actual_Type);
Chap3.Translate_Object_Allocation
(Param, Alloc, Formal_Type, Bounds);
else
@@ -2877,7 +2878,7 @@ package body Trans.Chap8 is
Stabilize (Saved_Val (Pos));
Chap3.Copy_Bounds
- (Chap3.Bounds_To_Element_Bounds
+ (Chap3.Record_Bounds_To_Element_Bounds
(Chap3.Get_Composite_Bounds
(Params (Last_Individual)),
Get_Selected_Element (Formal)),
diff --git a/src/vhdl/translate/trans-chap9.adb b/src/vhdl/translate/trans-chap9.adb
index 10bd3233f..669f86ee4 100644
--- a/src/vhdl/translate/trans-chap9.adb
+++ b/src/vhdl/translate/trans-chap9.adb
@@ -925,7 +925,7 @@ package body Trans.Chap9 is
(New_Selected_Element (Get_Instance_Ref (Ref_Scope),
Comp_Field),
Rtis.Ghdl_Component_Link_Stmt),
- New_Lit (Rtis.Get_Context_Rti (Stmt)));
+ Rtis.Get_Context_Rti (Stmt));
end Set_Component_Link;
Info : constant Block_Info_Acc := Get_Info (Stmt);
@@ -2523,9 +2523,8 @@ package body Trans.Chap9 is
New_Association
(Assoc, New_Convert_Ov (New_Value (M2Lv (Targ)), Ghdl_Signal_Ptr));
New_Association
- (Assoc,
- New_Lit (New_Global_Unchecked_Address
- (Get_Info (Sig).Signal_Rti, Rtis.Ghdl_Rti_Access)));
+ (Assoc, New_Unchecked_Address (New_Obj (Get_Info (Sig).Signal_Rti),
+ Rtis.Ghdl_Rti_Access));
New_Procedure_Call (Assoc);
end Merge_Signals_Rti_Non_Composite;
diff --git a/src/vhdl/translate/trans-helpers2.adb b/src/vhdl/translate/trans-helpers2.adb
index b0cc37d58..1886ccab5 100644
--- a/src/vhdl/translate/trans-helpers2.adb
+++ b/src/vhdl/translate/trans-helpers2.adb
@@ -108,8 +108,8 @@ package body Trans.Helpers2 is
Unsigned_64 (Str'Length));
Start_Record_Aggr (List, Ghdl_Str_Len_Type_Node);
New_Record_Aggr_El (List, Str_Len);
- New_Record_Aggr_El (List, New_Global_Address (Str_Cst,
- Char_Ptr_Type));
+ New_Record_Aggr_El (List, New_Global_Address (New_Global (Str_Cst),
+ Char_Ptr_Type));
Finish_Record_Aggr (List, Res);
return Res;
end Create_String_Len;
@@ -283,10 +283,11 @@ package body Trans.Helpers2 is
procedure Assoc_Filename_Line (Assoc : in out O_Assoc_List;
Line : Natural) is
begin
- New_Association (Assoc,
- New_Lit (New_Global_Address (Current_Filename_Node,
- Char_Ptr_Type)));
- New_Association (Assoc, New_Lit (New_Signed_Literal
- (Ghdl_I32_Type, Integer_64 (Line))));
+ New_Association
+ (Assoc, New_Address (New_Obj (Current_Filename_Node),
+ Char_Ptr_Type));
+ New_Association
+ (Assoc, New_Lit (New_Signed_Literal (Ghdl_I32_Type,
+ Integer_64 (Line))));
end Assoc_Filename_Line;
end Trans.Helpers2;
diff --git a/src/vhdl/translate/trans-rtis.adb b/src/vhdl/translate/trans-rtis.adb
index 268c4fb9d..0ab7a1bf9 100644
--- a/src/vhdl/translate/trans-rtis.adb
+++ b/src/vhdl/translate/trans-rtis.adb
@@ -110,9 +110,7 @@ package body Trans.Rtis is
Ghdl_Rtin_Subtype_Composite_Common : O_Fnode;
Ghdl_Rtin_Subtype_Composite_Name : O_Fnode;
Ghdl_Rtin_Subtype_Composite_Basetype : O_Fnode;
- Ghdl_Rtin_Subtype_Composite_Bounds : O_Fnode;
- Ghdl_Rtin_Subtype_Composite_Valsize : O_Fnode;
- Ghdl_Rtin_Subtype_Composite_Sigsize : O_Fnode;
+ Ghdl_Rtin_Subtype_Composite_Layout : O_Fnode;
-- Node for a record element.
Ghdl_Rtin_Element : O_Tnode;
@@ -121,6 +119,7 @@ package body Trans.Rtis is
Ghdl_Rtin_Element_Type : O_Fnode;
Ghdl_Rtin_Element_Valoff : O_Fnode;
Ghdl_Rtin_Element_Sigoff : O_Fnode;
+ Ghdl_Rtin_Element_Layout : O_Fnode;
-- Node for a record type.
Ghdl_Rtin_Type_Record : O_Tnode;
@@ -128,8 +127,7 @@ package body Trans.Rtis is
Ghdl_Rtin_Type_Record_Name : O_Fnode;
Ghdl_Rtin_Type_Record_Nbrel : O_Fnode;
Ghdl_Rtin_Type_Record_Elements : O_Fnode;
- --Ghdl_Rtin_Type_Record_Valsize : O_Fnode;
- --Ghdl_Rtin_Type_Record_Sigsize : O_Fnode;
+ Ghdl_Rtin_Type_Record_Layout : O_Fnode;
-- Node for an object.
Ghdl_Rtin_Object : O_Tnode;
@@ -155,6 +153,10 @@ package body Trans.Rtis is
Ghdl_Rtin_Component_Nbr_Child : O_Fnode;
Ghdl_Rtin_Component_Children : O_Fnode;
+ Null_Loc : O_Cnode;
+
+ function Get_Context_Rti (Node : Iir) return O_Dnode;
+
-- Create all the declarations for RTIs.
procedure Rti_Initialize is
begin
@@ -613,12 +615,8 @@ package body Trans.Rtis is
Get_Identifier ("name"), Char_Ptr_Type);
New_Record_Field (Constr, Ghdl_Rtin_Subtype_Composite_Basetype,
Get_Identifier ("basetype"), Ghdl_Rti_Access);
- New_Record_Field (Constr, Ghdl_Rtin_Subtype_Composite_Bounds,
- Get_Identifier ("bounds"), Ghdl_Ptr_Type);
- New_Record_Field (Constr, Ghdl_Rtin_Subtype_Composite_Valsize,
- Get_Identifier ("val_size"), Ghdl_Ptr_Type);
- New_Record_Field (Constr, Ghdl_Rtin_Subtype_Composite_Sigsize,
- Get_Identifier ("sig_size"), Ghdl_Ptr_Type);
+ New_Record_Field (Constr, Ghdl_Rtin_Subtype_Composite_Layout,
+ Get_Identifier ("layout"), Ghdl_Ptr_Type);
Finish_Record_Type (Constr, Ghdl_Rtin_Subtype_Composite);
New_Type_Decl (Get_Identifier ("__ghdl_rtin_subtype_composite"),
Ghdl_Rtin_Subtype_Composite);
@@ -637,6 +635,8 @@ package body Trans.Rtis is
Get_Identifier ("nbrel"), Ghdl_Index_Type);
New_Record_Field (Constr, Ghdl_Rtin_Type_Record_Elements,
Get_Identifier ("elements"), Ghdl_Rti_Arr_Acc);
+ New_Record_Field (Constr, Ghdl_Rtin_Type_Record_Layout,
+ Get_Identifier ("layout"), Ghdl_Ptr_Type);
Finish_Record_Type (Constr, Ghdl_Rtin_Type_Record);
New_Type_Decl (Get_Identifier ("__ghdl_rtin_type_record"),
Ghdl_Rtin_Type_Record);
@@ -657,6 +657,8 @@ package body Trans.Rtis is
Get_Identifier ("val_off"), Ghdl_Index_Type);
New_Record_Field (Constr, Ghdl_Rtin_Element_Sigoff,
Get_Identifier ("sig_off"), Ghdl_Index_Type);
+ New_Record_Field (Constr, Ghdl_Rtin_Element_Layout,
+ Get_Identifier ("layout_off"), Ghdl_Index_Type);
Finish_Record_Type (Constr, Ghdl_Rtin_Element);
New_Type_Decl (Get_Identifier ("__ghdl_rtin_element"),
Ghdl_Rtin_Element);
@@ -722,6 +724,7 @@ package body Trans.Rtis is
Ghdl_Rtin_Component);
end;
+ Null_Loc := New_Null_Access (Ghdl_Ptr_Type);
end Rti_Initialize;
package Rti_Builders is
@@ -891,8 +894,8 @@ package body Trans.Rtis is
for I in Cur_Block.List.Rtis'Range loop
exit when I > Nbr;
New_Array_Aggr_El
- (List, New_Global_Unchecked_Address (Cur_Block.List.Rtis (I),
- Ghdl_Rti_Access));
+ (List, New_Global_Unchecked_Address
+ (New_Global (Cur_Block.List.Rtis (I)), Ghdl_Rti_Access));
end loop;
-- Next chunks.
@@ -902,7 +905,7 @@ package body Trans.Rtis is
for I in L.Rtis'Range loop
exit when I > Nbr;
New_Array_Aggr_El
- (List, New_Global_Unchecked_Address (L.Rtis (I),
+ (List, New_Global_Unchecked_Address (New_Global (L.Rtis (I)),
Ghdl_Rti_Access));
end loop;
L := L.Next;
@@ -997,22 +1000,25 @@ package body Trans.Rtis is
end if;
end Generate_Name;
- function Get_Null_Loc return O_Cnode is
- begin
- return New_Null_Access (Ghdl_Ptr_Type);
- end Get_Null_Loc;
-
- function Var_Acc_To_Loc (Var : Var_Type) return O_Cnode
- is
+ function Var_Acc_To_Loc (Var : Var_Type) return O_Cnode is
begin
if Is_Var_Field (Var) then
return Get_Var_Offset (Var, Ghdl_Ptr_Type);
else
- return New_Global_Unchecked_Address (Get_Var_Label (Var),
+ return New_Global_Unchecked_Address (New_Global (Get_Var_Label (Var)),
Ghdl_Ptr_Type);
end if;
end Var_Acc_To_Loc;
+ function Var_Acc_To_Loc_Maybe (Var : Var_Type) return O_Cnode is
+ begin
+ if Var = Null_Var then
+ return Null_Loc;
+ else
+ return Var_Acc_To_Loc (Var);
+ end if;
+ end Var_Acc_To_Loc_Maybe;
+
-- Generate a name constant for the name of type definition DEF.
-- If DEF is an anonymous subtype, returns O_LNODE_NULL.
-- Use function NEW_NAME_ADDRESS (defined below) to convert the
@@ -1038,13 +1044,19 @@ package body Trans.Rtis is
if Name = O_Dnode_Null then
return New_Null_Access (Char_Ptr_Type);
else
- return New_Global_Unchecked_Address (Name, Char_Ptr_Type);
+ return New_Global_Unchecked_Address (New_Global (Name),
+ Char_Ptr_Type);
end if;
end New_Name_Address;
function New_Rti_Address (Rti : O_Dnode) return O_Cnode is
begin
- return New_Global_Unchecked_Address (Rti, Ghdl_Rti_Access);
+ return New_Global_Unchecked_Address (New_Global (Rti), Ghdl_Rti_Access);
+ end New_Rti_Address;
+
+ function New_Rti_Address (Rti : O_Dnode) return O_Enode is
+ begin
+ return New_Unchecked_Address (New_Obj (Rti), Ghdl_Rti_Access);
end New_Rti_Address;
-- Declare the RTI constant for type definition attached to INFO.
@@ -1109,8 +1121,7 @@ package body Trans.Rtis is
Start_Init_Value (Name_Arr);
Start_Array_Aggr (Arr_Aggr, Name_Arr_Type);
for I in Name_Lits'Range loop
- New_Array_Aggr_El
- (Arr_Aggr, New_Global_Address (Name_Lits (I), Char_Ptr_Type));
+ New_Array_Aggr_El (Arr_Aggr, New_Name_Address (Name_Lits (I)));
end loop;
Finish_Array_Aggr (Arr_Aggr, Val);
Finish_Init_Value (Name_Arr, Val);
@@ -1131,12 +1142,10 @@ package body Trans.Rtis is
Start_Record_Aggr (Rec_Aggr, Ghdl_Rtin_Type_Enum);
New_Record_Aggr_El (Rec_Aggr, Generate_Common_Type (Kind, 0, 0));
New_Record_Aggr_El (Rec_Aggr, New_Name_Address (Name));
+ New_Record_Aggr_El (Rec_Aggr, New_Index_Lit (Unsigned_64 (Nbr_Lit)));
New_Record_Aggr_El
- (Rec_Aggr, New_Unsigned_Literal (Ghdl_Index_Type,
- Unsigned_64 (Nbr_Lit)));
- New_Record_Aggr_El
- (Rec_Aggr,
- New_Global_Address (Name_Arr, Char_Ptr_Array_Ptr_Type));
+ (Rec_Aggr, New_Global_Address (New_Global (Name_Arr),
+ Char_Ptr_Array_Ptr_Type));
Finish_Record_Aggr (Rec_Aggr, Val);
Finish_Init_Value (Info.Type_Rti, Val);
end;
@@ -1210,7 +1219,7 @@ package body Trans.Rtis is
-- Handle non-static units. The only possibility is a unit of
-- std.standard.time.
Val := New_Global_Unchecked_Address
- (Get_Var_Label (Info.Object_Var), Ghdl_Ptr_Type);
+ (New_Global (Get_Var_Label (Info.Object_Var)), Ghdl_Ptr_Type);
else
Val := Chap7.Translate_Numeric_Literal (Unit, Ghdl_I64_Type);
end if;
@@ -1263,12 +1272,9 @@ package body Trans.Rtis is
end case;
New_Record_Aggr_El (List, Generate_Common_Type (Rti_Kind, 0, 0, 0));
New_Record_Aggr_El (List, New_Name_Address (Name));
- New_Record_Aggr_El
- (List,
- New_Unsigned_Literal (Ghdl_Index_Type,
- Unsigned_64 (Nbr_Units)));
- New_Record_Aggr_El
- (List, New_Global_Address (Unit_Arr, Ghdl_Rti_Arr_Acc));
+ New_Record_Aggr_El (List, New_Index_Lit (Unsigned_64 (Nbr_Units)));
+ New_Record_Aggr_El (List, New_Global_Address (New_Global (Unit_Arr),
+ Ghdl_Rti_Arr_Acc));
Finish_Record_Aggr (List, Val);
Finish_Init_Value (Info.Type_Rti, Val);
end Generate_Physical_Type_Definition;
@@ -1499,10 +1505,9 @@ package body Trans.Rtis is
New_Record_Aggr_El (Aggr, New_Name_Address (Name));
New_Record_Aggr_El (Aggr, New_Rti_Address (El_Info.Type_Rti));
New_Record_Aggr_El
- (Aggr,
- New_Unsigned_Literal (Ghdl_Index_Type,
- Unsigned_64 (Get_Nbr_Elements (List))));
- New_Record_Aggr_El (Aggr, New_Global_Address (Arr, Ghdl_Rti_Arr_Acc));
+ (Aggr, New_Index_Lit (Unsigned_64 (Get_Nbr_Elements (List))));
+ New_Record_Aggr_El (Aggr, New_Global_Address (New_Global (Arr),
+ Ghdl_Rti_Arr_Acc));
Finish_Record_Aggr (Aggr, Val);
Finish_Init_Value (Info.Type_Rti, Val);
end Generate_Array_Type_Definition;
@@ -1521,7 +1526,7 @@ package body Trans.Rtis is
Kind : O_Cnode;
Depth : Rti_Depth_Type;
begin
- Bounds := Info.S.Composite_Bounds;
+ Bounds := Info.S.Composite_Layout;
Depth := Get_Depth_From_Var (Bounds);
Info.B.Rti_Max_Depth :=
Rti_Depth_Type'Max (Depth, Base_Info.B.Rti_Max_Depth);
@@ -1555,39 +1560,7 @@ package body Trans.Rtis is
(Kind, Depth, Info.B.Rti_Max_Depth, Type_To_Mode (Atype)));
New_Record_Aggr_El (Aggr, New_Name_Address (Name));
New_Record_Aggr_El (Aggr, New_Rti_Address (Base_Info.Type_Rti));
- if Bounds = Null_Var then
- Val := Get_Null_Loc;
- else
- Val := Var_Acc_To_Loc (Bounds);
- end if;
- New_Record_Aggr_El (Aggr, Val);
- for I in Mode_Value .. Mode_Signal loop
- case Info.Type_Mode is
- when Type_Mode_Static_Array
- | Type_Mode_Static_Record =>
- if Info.Ortho_Type (I) /= O_Tnode_Null then
- Val := New_Sizeof (Info.Ortho_Type (I), Ghdl_Ptr_Type);
- else
- Val := Get_Null_Loc;
- end if;
- when Type_Mode_Complex_Array
- | Type_Mode_Complex_Record =>
- if Info.Ortho_Type (I) /= O_Tnode_Null
- and then Info.C (I).Size_Var /= Null_Var
- then
- Val := Var_Acc_To_Loc (Info.C (I).Size_Var);
- else
- Val := Get_Null_Loc;
- end if;
- when Type_Mode_Unbounded_Array
- | Type_Mode_Unbounded_Record =>
- Val := Get_Null_Loc;
- when others =>
- Error_Kind ("generate_composite_subtype_definition", Atype);
- end case;
- New_Record_Aggr_El (Aggr, Val);
- end loop;
-
+ New_Record_Aggr_El (Aggr, Var_Acc_To_Loc_Maybe (Bounds));
Finish_Record_Aggr (Aggr, Val);
Finish_Init_Value (Info.Type_Rti, Val);
end Generate_Composite_Subtype_Definition;
@@ -1640,12 +1613,14 @@ package body Trans.Rtis is
El := Get_Nth_Element (El_List, I);
declare
El_Type : constant Iir := Get_Type (El);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
Field_Info : constant Field_Info_Acc := Get_Info (El);
Type_Rti : O_Dnode;
El_Name : O_Dnode;
Aggr : O_Record_Aggr_List;
Val : O_Cnode;
El_Const : O_Dnode;
+ Mode : Natural;
Mark : Id_Mark_Type;
begin
Push_Identifier_Prefix (Mark, Get_Identifier (El));
@@ -1655,25 +1630,51 @@ package body Trans.Rtis is
Rti_Depth_Type'Max (Max_Depth,
Get_Info (El_Type).B.Rti_Max_Depth);
+ case El_Tinfo.Type_Mode is
+ when Type_Mode_Unbounded_Array
+ | Type_Mode_Unbounded_Record =>
+ Mode := 2;
+ when Type_Mode_Complex_Record
+ | Type_Mode_Complex_Array =>
+ Mode := 1;
+ when others =>
+ Mode := 0;
+ end case;
El_Name := Generate_Name (El);
New_Const_Decl (El_Const, Create_Identifier ("RTIEL"),
Global_Storage, Ghdl_Rtin_Element);
Start_Init_Value (El_Const);
Start_Record_Aggr (Aggr, Ghdl_Rtin_Element);
- New_Record_Aggr_El (Aggr,
- Generate_Common (Ghdl_Rtik_Element));
+ New_Record_Aggr_El
+ (Aggr, Generate_Common (Ghdl_Rtik_Element, Mode => Mode));
New_Record_Aggr_El (Aggr, New_Name_Address (El_Name));
New_Record_Aggr_El (Aggr, New_Rti_Address (Type_Rti));
for I in Object_Kind_Type loop
if Field_Info.Field_Node (I) /= O_Fnode_Null then
- Val := New_Offsetof (Info.B.Base_Type (I),
- Field_Info.Field_Node (I),
- Ghdl_Index_Type);
+ if Is_Static_Type (El_Tinfo) then
+ Val := New_Offsetof (Info.B.Base_Type (I),
+ Field_Info.Field_Node (I),
+ Ghdl_Index_Type);
+ else
+ Val := New_Offsetof (Info.B.Bounds_Type,
+ Field_Info.Field_Node (I),
+ Ghdl_Index_Type);
+ end if;
else
Val := Ghdl_Index_0;
end if;
New_Record_Aggr_El (Aggr, Val);
end loop;
+
+ if Is_Unbounded_Type (El_Tinfo) then
+ Val := New_Offsetof (Info.B.Bounds_Type,
+ Field_Info.Field_Bound,
+ Ghdl_Index_Type);
+ else
+ Val := Ghdl_Index_0;
+ end if;
+ New_Record_Aggr_El (Aggr, Val);
+
Finish_Record_Aggr (Aggr, Val);
Finish_Init_Value (El_Const, Val);
Add_Rti_Node (El_Const);
@@ -1690,25 +1691,33 @@ package body Trans.Rtis is
Aggr : O_Record_Aggr_List;
Name : O_Dnode;
Rtik : O_Cnode;
+ Depth : Rti_Depth_Type;
+ Layout_Loc : O_Cnode;
begin
Name := Generate_Type_Name (Atype);
Start_Init_Value (Info.Type_Rti);
Start_Record_Aggr (Aggr, Ghdl_Rtin_Type_Record);
+ Depth := 0;
+ Layout_Loc := Null_Loc;
if Get_Constraint_State (Atype) = Fully_Constrained then
Rtik := Ghdl_Rtik_Type_Record;
+ if Info.S.Composite_Layout /= Null_Var then
+ Depth := Get_Depth_From_Var (Info.S.Composite_Layout);
+ Layout_Loc := Var_Acc_To_Loc (Info.S.Composite_Layout);
+ end if;
else
Rtik := Ghdl_Rtik_Type_Unbounded_Record;
end if;
New_Record_Aggr_El
- (Aggr,
- Generate_Common_Type (Rtik, 0, Max_Depth, Type_To_Mode (Atype)));
+ (Aggr, Generate_Common_Type
+ (Rtik, Depth, Max_Depth, Type_To_Mode (Atype)));
New_Record_Aggr_El (Aggr, New_Name_Address (Name));
New_Record_Aggr_El
- (Aggr, New_Unsigned_Literal
- (Ghdl_Index_Type, Unsigned_64 (Get_Nbr_Elements (El_List))));
- New_Record_Aggr_El (Aggr,
- New_Global_Address (El_Arr, Ghdl_Rti_Arr_Acc));
+ (Aggr, New_Index_Lit (Unsigned_64 (Get_Nbr_Elements (El_List))));
+ New_Record_Aggr_El (Aggr, New_Global_Address (New_Global (El_Arr),
+ Ghdl_Rti_Arr_Acc));
+ New_Record_Aggr_El (Aggr, Layout_Loc);
Finish_Record_Aggr (Aggr, Res);
Finish_Init_Value (Info.Type_Rti, Res);
end;
@@ -1993,12 +2002,7 @@ package body Trans.Rtis is
end case;
New_Record_Aggr_El (List, Generate_Common (Comm, Var, Mode));
New_Record_Aggr_El (List, New_Name_Address (Name));
- if Var = Null_Var then
- Val := Get_Null_Loc;
- else
- Val := Var_Acc_To_Loc (Var);
- end if;
- New_Record_Aggr_El (List, Val);
+ New_Record_Aggr_El (List, Var_Acc_To_Loc_Maybe (Var));
Val := New_Rti_Address (Type_Info.Type_Rti);
New_Record_Aggr_El (List, Val);
New_Record_Aggr_El (List, Generate_Linecol (Decl));
@@ -2091,13 +2095,10 @@ package body Trans.Rtis is
Start_Init_Value (Info.Comp_Rti_Const);
Start_Record_Aggr (List, Ghdl_Rtin_Component);
New_Record_Aggr_El (List, Generate_Common (Ghdl_Rtik_Component));
- New_Record_Aggr_El (List,
- New_Global_Address (Name, Char_Ptr_Type));
- New_Record_Aggr_El
- (List, New_Unsigned_Literal (Ghdl_Index_Type,
- Get_Rti_Array_Length));
- New_Record_Aggr_El (List,
- New_Global_Address (Arr, Ghdl_Rti_Arr_Acc));
+ New_Record_Aggr_El (List, New_Name_Address (Name));
+ New_Record_Aggr_El (List, New_Index_Lit (Get_Rti_Array_Length));
+ New_Record_Aggr_El (List, New_Global_Address (New_Global (Arr),
+ Ghdl_Rti_Arr_Acc));
Finish_Record_Aggr (List, Res);
Finish_Init_Value (Info.Comp_Rti_Const, Res);
Pop_Rti_Node (Prev);
@@ -2201,7 +2202,7 @@ package body Trans.Rtis is
Start_Init_Value (Info.Block_Rti_Const);
Start_Record_Aggr (List, Ghdl_Rtin_Instance);
New_Record_Aggr_El (List, Generate_Common (Ghdl_Rtik_Instance));
- New_Record_Aggr_El (List, New_Global_Address (Name, Char_Ptr_Type));
+ New_Record_Aggr_El (List, New_Name_Address (Name));
New_Record_Aggr_El (List, Generate_Linecol (Stmt));
New_Record_Aggr_El
(List, New_Offsetof (Get_Scope_Type
@@ -2495,7 +2496,7 @@ package body Trans.Rtis is
Start_Record_Aggr (List, Ghdl_Rtin_Block);
New_Record_Aggr_El (List, Generate_Common (Rtik));
- New_Record_Aggr_El (List, New_Global_Address (Name, Char_Ptr_Type));
+ New_Record_Aggr_El (List, New_Name_Address (Name));
-- Field Loc: offset in the instance of the entity.
Field_Off := New_Offsetof
@@ -2511,7 +2512,8 @@ package body Trans.Rtis is
-- Fields Nbr_Child and Children.
New_Record_Aggr_El
(List, New_Unsigned_Literal (Ghdl_Index_Type, Get_Rti_Array_Length));
- New_Record_Aggr_El (List, New_Global_Address (Arr, Ghdl_Rti_Arr_Acc));
+ New_Record_Aggr_El (List, New_Global_Address (New_Global (Arr),
+ Ghdl_Rti_Arr_Acc));
Finish_Record_Aggr (List, Res);
Finish_Init_Value (Rti, Res);
@@ -2557,7 +2559,7 @@ package body Trans.Rtis is
Start_Record_Aggr (List, Ghdl_Rtin_Generate);
New_Record_Aggr_El (List, Generate_Common (Ghdl_Rtik_For_Generate));
- New_Record_Aggr_El (List, New_Global_Address (Name, Char_Ptr_Type));
+ New_Record_Aggr_El (List, New_Name_Address (Name));
-- Field Loc: offset in the instance of the entity.
Field_Off := New_Offsetof
@@ -2578,7 +2580,7 @@ package body Trans.Rtis is
Ghdl_Index_Type));
-- Child.
- New_Record_Aggr_El (List, Get_Context_Rti (Bod));
+ New_Record_Aggr_El (List, New_Rti_Address (Get_Context_Rti (Bod)));
Finish_Record_Aggr (List, Res);
@@ -2716,17 +2718,17 @@ package body Trans.Rtis is
Start_Record_Aggr (List, Ghdl_Rtin_Block);
New_Record_Aggr_El (List, Generate_Common (Kind));
- New_Record_Aggr_El (List, New_Global_Address (Name, Char_Ptr_Type));
+ New_Record_Aggr_El (List, New_Name_Address (Name));
-- Field Loc: offset in the instance of the entity.
if Field_Off = O_Cnode_Null then
- Field_Off := Get_Null_Loc;
+ Field_Off := Null_Loc;
end if;
New_Record_Aggr_El (List, Field_Off);
New_Record_Aggr_El (List, Generate_Linecol (Blk));
- -- Field Parent: RTI of the parent.
+ -- Field Parent: RTI of the parent.
if Parent_Rti = O_Dnode_Null then
Res := New_Null_Access (Ghdl_Rti_Access);
else
@@ -2736,14 +2738,14 @@ package body Trans.Rtis is
-- Fields Nbr_Child and Children.
New_Record_Aggr_El (List, New_Index_Lit (Get_Rti_Array_Length));
- New_Record_Aggr_El (List, New_Global_Address (Arr, Ghdl_Rti_Arr_Acc));
+ New_Record_Aggr_El (List, New_Global_Address (New_Global (Arr),
+ Ghdl_Rti_Arr_Acc));
Finish_Record_Aggr (List, Res);
if Rti_Type = Ghdl_Rtin_Block_File then
New_Record_Aggr_El (List_File, Res);
New_Record_Aggr_El (List_File,
- New_Global_Address (Current_Filename_Node,
- Char_Ptr_Type));
+ New_Name_Address (Current_Filename_Node));
Finish_Record_Aggr (List_File, Res);
end if;
@@ -2945,43 +2947,46 @@ package body Trans.Rtis is
Pop_Rti_Node (Prev);
end Generate_Top;
- function Get_Context_Rti (Node : Iir) return O_Cnode
+ function Get_Context_Rti (Node : Iir) return O_Dnode
is
Node_Info : constant Ortho_Info_Acc := Get_Info (Node);
- Rti_Const : O_Dnode;
begin
case Get_Kind (Node) is
when Iir_Kind_Component_Declaration =>
- Rti_Const := Node_Info.Comp_Rti_Const;
+ return Node_Info.Comp_Rti_Const;
when Iir_Kind_Component_Instantiation_Statement =>
- Rti_Const := Node_Info.Block_Rti_Const;
+ return Node_Info.Block_Rti_Const;
when Iir_Kind_Entity_Declaration
| Iir_Kind_Architecture_Body
| Iir_Kind_Block_Statement
| Iir_Kind_Generate_Statement_Body =>
- Rti_Const := Node_Info.Block_Rti_Const;
+ return Node_Info.Block_Rti_Const;
when Iir_Kind_If_Generate_Statement
| Iir_Kind_For_Generate_Statement =>
declare
Bod : constant Iir := Get_Generate_Statement_Body (Node);
Bod_Info : constant Block_Info_Acc := Get_Info (Bod);
begin
- Rti_Const := Bod_Info.Block_Rti_Const;
+ return Bod_Info.Block_Rti_Const;
end;
when Iir_Kind_Package_Declaration
| Iir_Kind_Package_Body =>
- Rti_Const := Node_Info.Package_Rti_Const;
+ return Node_Info.Package_Rti_Const;
when Iir_Kind_Process_Statement
| Iir_Kind_Sensitized_Process_Statement =>
- Rti_Const := Node_Info.Process_Rti_Const;
+ return Node_Info.Process_Rti_Const;
when Iir_Kind_Psl_Assert_Statement
| Iir_Kind_Psl_Cover_Statement
| Iir_Kind_Psl_Endpoint_Declaration =>
- Rti_Const := Node_Info.Psl_Rti_Const;
+ return Node_Info.Psl_Rti_Const;
when others =>
Error_Kind ("get_context_rti", Node);
end case;
- return New_Rti_Address (Rti_Const);
+ end Get_Context_Rti;
+
+ function Get_Context_Rti (Node : Iir) return O_Enode is
+ begin
+ return New_Rti_Address (Get_Context_Rti (Node));
end Get_Context_Rti;
function Get_Context_Addr (Node : Iir) return O_Enode
@@ -3024,7 +3029,7 @@ package body Trans.Rtis is
procedure Associate_Rti_Context (Assoc : in out O_Assoc_List; Node : Iir)
is
begin
- New_Association (Assoc, New_Lit (Get_Context_Rti (Node)));
+ New_Association (Assoc, Get_Context_Rti (Node));
New_Association (Assoc, Get_Context_Addr (Node));
end Associate_Rti_Context;
diff --git a/src/vhdl/translate/trans-rtis.ads b/src/vhdl/translate/trans-rtis.ads
index 73bc514e0..e3c8c188e 100644
--- a/src/vhdl/translate/trans-rtis.ads
+++ b/src/vhdl/translate/trans-rtis.ads
@@ -114,7 +114,7 @@ package Trans.Rtis is
procedure Rti_Initialize;
-- Get address (as Ghdl_Rti_Access) of constant RTI.
- function New_Rti_Address (Rti : O_Dnode) return O_Cnode;
+ function New_Rti_Address (Rti : O_Dnode) return O_Enode;
-- Generate rtis for a library unit.
procedure Generate_Unit (Lib_Unit : Iir);
@@ -139,6 +139,6 @@ package Trans.Rtis is
(Assoc : in out O_Assoc_List; Node : Iir);
procedure Associate_Null_Rti_Context (Assoc : in out O_Assoc_List);
- function Get_Context_Rti (Node : Iir) return O_Cnode;
+ function Get_Context_Rti (Node : Iir) return O_Enode;
function Get_Context_Addr (Node : Iir) return O_Enode;
end Trans.Rtis;
diff --git a/src/vhdl/translate/trans.adb b/src/vhdl/translate/trans.adb
index a2385cbe6..4d6a0a44a 100644
--- a/src/vhdl/translate/trans.adb
+++ b/src/vhdl/translate/trans.adb
@@ -1133,6 +1133,24 @@ package body Trans is
end Instantiate_Var_Scope;
end Chap10;
+ function Align_Val (Algn : Alignment_Type) return O_Cnode is
+ begin
+ case Algn is
+ when Align_Undef =>
+ raise Internal_Error;
+ when Align_8 =>
+ return Ghdl_Index_1;
+ when Align_16 =>
+ return Ghdl_Index_2;
+ when Align_32 =>
+ return Ghdl_Index_4;
+ when Align_Ptr =>
+ return Ghdl_Index_Ptr_Align;
+ when Align_64 =>
+ return Ghdl_Index_8;
+ end case;
+ end Align_Val;
+
function Get_Object_Kind (M : Mnode) return Object_Kind_Type is
begin
return M.M1.K;
@@ -1401,9 +1419,6 @@ package body Trans is
procedure Free_Type_Info (Info : in out Type_Info_Acc) is
begin
- if Info.C /= null then
- Free_Complex_Type_Info (Info.C);
- end if;
Unchecked_Deallocation (Info);
end Free_Type_Info;
@@ -1433,7 +1448,26 @@ package body Trans is
function Is_Complex_Type (Tinfo : Type_Info_Acc) return Boolean is
begin
- return Tinfo.C /= null;
+ case Tinfo.Type_Mode is
+ when Type_Mode_Non_Composite =>
+ return False;
+ when Type_Mode_Static_Record
+ | Type_Mode_Static_Array =>
+ return False;
+ when Type_Mode_Complex_Record
+ | Type_Mode_Complex_Array =>
+ return True;
+ when Type_Mode_Unbounded_Record
+ | Type_Mode_Unbounded_Array =>
+ return False;
+ when Type_Mode_Protected =>
+ -- Considered as a complex type, as its size is known only in
+ -- the body.
+ -- Shouldn't be used.
+ raise Internal_Error;
+ when Type_Mode_Unknown =>
+ return False;
+ end case;
end Is_Complex_Type;
function Is_Static_Type (Tinfo : Type_Info_Acc) return Boolean is
@@ -1480,13 +1514,6 @@ package body Trans is
Clear_Info (I);
else
Info.Mark := True;
- if Info.Kind = Kind_Type and then Info.C /= null then
- if Info.C (Mode_Value).Mark then
- Info.C := null;
- else
- Info.C (Mode_Value).Mark := True;
- end if;
- end if;
end if;
end if;
end loop;
diff --git a/src/vhdl/translate/trans.ads b/src/vhdl/translate/trans.ads
index 8b6888764..960323ee8 100644
--- a/src/vhdl/translate/trans.ads
+++ b/src/vhdl/translate/trans.ads
@@ -68,6 +68,10 @@ package Trans is
Ghdl_Index_Type : O_Tnode;
Ghdl_Index_0 : O_Cnode;
Ghdl_Index_1 : O_Cnode;
+ Ghdl_Index_2 : O_Cnode;
+ Ghdl_Index_4 : O_Cnode;
+ Ghdl_Index_8 : O_Cnode;
+ Ghdl_Index_Ptr_Align : O_Cnode; -- Alignment of a pointer
-- Type for a file (this is in fact a index in a private table).
Ghdl_File_Index_Type : O_Tnode;
@@ -105,6 +109,9 @@ package Trans is
Ghdl_Sizes_Val : O_Fnode;
Ghdl_Sizes_Sig : O_Fnode;
+ -- Access to size.
+ Ghdl_Sizes_Ptr : O_Tnode;
+
-- Comparaison type.
Ghdl_Compare_Type : O_Tnode;
Ghdl_Compare_Lt : O_Cnode;
@@ -750,6 +757,58 @@ package Trans is
type Rti_Depth_Type is new Natural range 0 .. 255;
+ -- Additional info for complex types.
+ type Complex_Type_Info is record
+ -- Parameters for type builders.
+ -- NOTE: this is only set for types (and *not* for subtypes).
+ Builder_Instance : Subprgs.Subprg_Instance_Type;
+ Builder_Layout_Param : O_Dnode;
+ Builder_Proc : O_Dnode := O_Dnode_Null;
+ end record;
+ type Complex_Type_Arr_Info is array (Object_Kind_Type) of Complex_Type_Info;
+
+ -- Alignment of a type.
+ -- This is only for Mode_Value (for Mode_Signal, the alignment is
+ -- Align_Ptr).
+ -- The size of complex types is determined at run-time, and the code to
+ -- compute it is generated by translation. But to know the size, the
+ -- alignment must also be known. It is assumed that allocators (malloc or
+ -- alloca) always return a pointer with the maximum alignment.
+ -- Eg: type cpl_rec is record
+ -- b : boolean;
+ -- v : integer_array (1 to n); -- n is a non-locally constant.
+ -- end record;
+ -- The static part contains only field 'b'. The whole size is of cpl_rec
+ -- is: sizeof (b) + align(v) + n * sizeof(integer) + align(cpl_rec).
+ -- This makes a lot of suppositions about the ABI:
+ -- * elementary types (including doubles) are always naturally aligned
+ -- * fields are aligned as their type
+ -- * records are aligned to their maximum field
+ -- * pointers have the same size
+ -- * finally, pointers are either 32 or 64 bits.
+ -- Note: deviation from the ABI may result in incorrect code as an object
+ -- that is statically constrained may be viewed as a complex/unbounded
+ -- object too.
+ -- Note: These suppositions are true on x86-64, on windows32.
+ -- but not for double on linux-x86!!
+ type Alignment_Type is
+ (
+ -- When alignment is not known.
+ Align_Undef,
+
+ -- For enumerations, integers, physical types.
+ Align_8, Align_16, Align_32,
+
+ -- For an access. We suppose that pointers are either 32 or 64 bits.
+ -- So Align_Ptr >= Align_32 but Align_64 >= Align_Ptr
+ Align_Ptr,
+
+ -- For float64 (floating point types), large integers or large physical
+ -- types.
+ Align_64);
+
+ function Align_Val (Algn : Alignment_Type) return O_Cnode;
+
type Ortho_Info_Basetype_Type
(Kind : Ortho_Info_Type_Kind := Kind_Type_Scalar) is record
-- For all types:
@@ -757,6 +816,8 @@ package Trans is
-- the type itself and every types it depends on.
Rti_Max_Depth : Rti_Depth_Type;
+ Align : Alignment_Type;
+
case Kind is
when Kind_Type_Scalar =>
-- For scalar types:
@@ -779,19 +840,38 @@ package Trans is
Base_Type : O_Tnode_Array;
Base_Ptr_Type : O_Tnode_Array;
-- The dope vector.
+ -- For arrays:
+ -- range of indexes
+ -- layout of element (if element is unbounded)
+ -- For record:
+ -- offsets of complex elements
+ -- layout of unbounded elements
Bounds_Type : O_Tnode;
Bounds_Ptr_Type : O_Tnode;
- -- Only for unbounded arrays: element size and bounds in
- -- the bounds record
- El_Size : O_Fnode;
- El_Bounds : O_Fnode;
+ -- For arrays with unbounded element, the layout field of the
+ -- bounds type.
+ Bounds_El : O_Fnode;
+
+ -- Size + bounds.
+ -- Always created for arrays, created for unbounded and complex
+ -- records.
+ Layout_Type : O_Tnode;
+ Layout_Ptr_Type : O_Tnode;
+
+ -- Size and bounds fields of the layout type.
+ Layout_Size : O_Fnode;
+ Layout_Bounds : O_Fnode;
-- The ortho type is a fat pointer to the base and the bounds.
-- These are the fields of the fat pointer.
Base_Field : O_Fnode_Array;
Bounds_Field : O_Fnode_Array;
+ -- Parameters for type builders.
+ -- NOTE: this is only set for types (and *not* for subtypes).
+ Builder : Complex_Type_Arr_Info;
+
when Kind_Type_File =>
-- Constant containing the signature of the file.
File_Signature : O_Dnode;
@@ -832,11 +912,8 @@ package Trans is
when Kind_Type_Array
| Kind_Type_Record =>
- -- True if the bounds are static.
- Static_Bounds : Boolean;
-
- -- Variable containing the bounds for a constrained type.
- Composite_Bounds : Var_Type;
+ -- Variable containing the layout for a constrained type.
+ Composite_Layout : Var_Type;
-- For a locally constrained record subtype whose base type has
-- unbounded elements: the field containing the base record.
@@ -863,47 +940,61 @@ package Trans is
Ortho_Info_Basetype_Array_Init : constant Ortho_Info_Basetype_Type :=
(Kind => Kind_Type_Array,
Rti_Max_Depth => 0,
+ Align => Align_Undef,
Base_Type => (O_Tnode_Null, O_Tnode_Null),
Base_Ptr_Type => (O_Tnode_Null, O_Tnode_Null),
Bounds_Type => O_Tnode_Null,
Bounds_Ptr_Type => O_Tnode_Null,
- El_Size => O_Fnode_Null,
- El_Bounds => O_Fnode_Null,
+ Bounds_El => O_Fnode_Null,
+ Layout_Type => O_Tnode_Null,
+ Layout_Ptr_Type => O_Tnode_Null,
+ Layout_Size => O_Fnode_Null,
+ Layout_Bounds => O_Fnode_Null,
Base_Field => (O_Fnode_Null, O_Fnode_Null),
- Bounds_Field => (O_Fnode_Null, O_Fnode_Null));
+ Bounds_Field => (O_Fnode_Null, O_Fnode_Null),
+ Builder => (others => (Builder_Instance => Subprgs.Null_Subprg_Instance,
+ Builder_Layout_Param => O_Dnode_Null,
+ Builder_Proc => O_Dnode_Null)));
Ortho_Info_Subtype_Array_Init : constant Ortho_Info_Subtype_Type :=
(Kind => Kind_Type_Array,
- Static_Bounds => False,
- Composite_Bounds => Null_Var,
+ Composite_Layout => Null_Var,
Box_Field => (O_Fnode_Null, O_Fnode_Null));
Ortho_Info_Basetype_Record_Init : constant Ortho_Info_Basetype_Type :=
(Kind => Kind_Type_Record,
Rti_Max_Depth => 0,
+ Align => Align_Undef,
Base_Type => (O_Tnode_Null, O_Tnode_Null),
Base_Ptr_Type => (O_Tnode_Null, O_Tnode_Null),
Bounds_Type => O_Tnode_Null,
Bounds_Ptr_Type => O_Tnode_Null,
- El_Size => O_Fnode_Null,
- El_Bounds => O_Fnode_Null,
+ Bounds_El => O_Fnode_Null,
+ Layout_Type => O_Tnode_Null,
+ Layout_Ptr_Type => O_Tnode_Null,
+ Layout_Size => O_Fnode_Null,
+ Layout_Bounds => O_Fnode_Null,
Base_Field => (O_Fnode_Null, O_Fnode_Null),
- Bounds_Field => (O_Fnode_Null, O_Fnode_Null));
+ Bounds_Field => (O_Fnode_Null, O_Fnode_Null),
+ Builder => (others => (Builder_Instance => Subprgs.Null_Subprg_Instance,
+ Builder_Layout_Param => O_Dnode_Null,
+ Builder_Proc => O_Dnode_Null)));
Ortho_Info_Subtype_Record_Init : constant Ortho_Info_Subtype_Type :=
(Kind => Kind_Type_Record,
- Static_Bounds => False,
- Composite_Bounds => Null_Var,
+ Composite_Layout => Null_Var,
Box_Field => (O_Fnode_Null, O_Fnode_Null));
Ortho_Info_Basetype_File_Init : constant Ortho_Info_Basetype_Type :=
(Kind => Kind_Type_File,
Rti_Max_Depth => 0,
+ Align => Align_Undef,
File_Signature => O_Dnode_Null);
Ortho_Info_Basetype_Prot_Init : constant Ortho_Info_Basetype_Type :=
(Kind => Kind_Type_Protected,
Rti_Max_Depth => 0,
+ Align => Align_Undef,
Prot_Scope => Null_Var_Scope,
Prot_Prev_Scope => null,
Prot_Init_Subprg => O_Dnode_Null,
@@ -1071,6 +1162,88 @@ package Trans is
-- that doesn't suspend is not decomposed by this mechanism).
type State_Type is new Nat32;
+ -- Translation of types.
+ -- (Where you understand that VHDL is more complex than C...)
+ --
+ -- 1) For scalar types (integers, physical types, enumeration, floating
+ -- point types) and pointers, the type is fully known during analysis
+ -- and translation:
+ -- a) for integers and physical types, the size is defined by the range.
+ -- GHDL uses either 32-bit or 64-bit types.
+ -- b) for enumeration, the size is defined by the number of literals.
+ -- GHDL uses either 8-bit or 32-bit types.
+ -- c) for floating-point type, GHDL always uses 64-bit types (Float64).
+ -- d) for access types, GHDL uses pointers. This is slightly more
+ -- complex as sometimes it can be a fat pointer, which is a record
+ -- of two pointers. But in all cases, the size is known.
+ --
+ -- For composite subtypes (arrays and records), there are several cases:
+ --
+ -- 2) Composite types whose sub-elements are statically constrained.
+ -- Eg: subtype byte is bit_vector (7 downto 0);
+ -- Eg: subtype word is std_logic_vector (31 downto 0);
+ -- Eg: type my_bus is record
+ -- req: bit;
+ -- ack: bit;
+ -- data: byte;
+ -- end record;
+ -- This still corresponds to C: sizes and offsets are known during
+ -- translation.
+ -- However, for arrays a bound variable is created. This variable
+ -- contains the bounds of the array (left, right and direction) and the
+ -- length of each bound. This is used both for 'introspection' and for
+ -- conversion to fat pointers.
+ --
+ -- 3) Unbounded types. This is quite usual for parameters.
+ -- Eg: procedure disp_hex (v : std_logic_vector);
+ -- The bounds of an unbounded types are only known during execution, and
+ -- thus must be passed with the argument.
+ -- This is not the same case as an object declared with an unbounded
+ -- type; in that case the bounds are computed during elaboration (or
+ -- dynamic elaboration).
+ -- Eg: constant c : std_logic_vector := xxx;
+ --
+ -- For these unbounded types, the interface is translated as a fat
+ -- pointer, which is a structure containing a base pointer and a bound
+ -- pointer. The base pointer points to the data while the bound pointer
+ -- points to the bounds.
+ --
+ -- In some case, we need to convert from a bounded representation to an
+ -- unbounded representation. This happens while calling a subprogram
+ -- with a bounded object (and corresponds to a subtype conversion in
+ -- VHDL terms). In that case a fat pointer is created, using the object
+ -- as data and the bounds variable as the bounds. The opposite
+ -- conversion can also happen and we just need to check that the bounds
+ -- are matching and to keep only the data part.
+ --
+ -- 4) Complex types. Complex is a word used only by GHDL (not defined by
+ -- VHDL). You need to realize that VHDL types are more powerful than C
+ -- types as you can declare a type whose size is not known by the
+ -- compiler.
+ -- Eg: constant length : natural := call_to_a_complex_function(5);
+ -- subtype my_word is std_logic_vector (1 to length);
+ -- type my_bus is record
+ -- d : my_word;
+ -- req : std_logic_vector;
+ -- end record;
+ -- Clearly, LENGTH is not known during analysis. In many cases it
+ -- could be known during elaboration but this is not enough as such a
+ -- construct could also be used within subprograms using a parameter to
+ -- define a bound.
+ --
+ -- Because the size of these objects is not known during compilation,
+ -- the objects are allocated dynamically (either on the heap or on the
+ -- stack) during (dynamic) elaboration. They also comes with a bound
+ -- variable.
+ --
+ -- For arrays, the bound variable describes the index of the array and
+ -- the bounds of the elements (if the element is unbounded).
+ --
+ -- For records, the bound variable describes the offset and the bounds
+ -- of the non-static elements.
+ --
+
+ -- OLD:
-- Complex types.
--
-- A complex type is not a VHDL notion, but a translation notion.
@@ -1166,30 +1339,6 @@ package Trans is
-- | ... |
-- +--------------+
- -- Additional info for complex types.
- type Complex_Type_Info is record
- -- For a simple memory management: use mark and sweep to free all infos.
- Mark : Boolean := False;
-
- Builder_Need_Func : Boolean := False;
-
- -- Variable containing the size of the type.
- -- This is defined only for types whose size is only known at
- -- running time (and not a compile-time).
- Size_Var : Var_Type := Null_Var;
-
- -- Parameters for type builders.
- -- NOTE: this is only set for types (and *not* for subtypes).
- Builder_Instance : Subprgs.Subprg_Instance_Type;
- Builder_Base_Param : O_Dnode;
- Builder_Bound_Param : O_Dnode;
- Builder_Func : O_Dnode := O_Dnode_Null;
- end record;
- type Complex_Type_Arr_Info is array (Object_Kind_Type) of Complex_Type_Info;
- type Complex_Type_Info_Acc is access Complex_Type_Arr_Info;
- procedure Free_Complex_Type_Info is new Ada.Unchecked_Deallocation
- (Complex_Type_Arr_Info, Complex_Type_Info_Acc);
-
type Assoc_Conv_Info is record
-- The subprogram created to do the conversion.
Subprg : O_Dnode;
@@ -1238,9 +1387,6 @@ package Trans is
-- of its sub-element (ie being a complex type).
Type_Locally_Constrained : Boolean := False;
- -- Additionnal info for complex types.
- C : Complex_Type_Info_Acc := null;
-
-- Ortho node which represents the type.
-- Type -> Ortho type
-- scalar -> scalar
@@ -1275,10 +1421,13 @@ package Trans is
Index_Field : O_Fnode;
when Kind_Field =>
- -- Node for a record element declaration.
+ -- For element whose type is static: field in the record.
+ -- For element whose type is not static: offset field in the
+ -- bounds.
Field_Node : O_Fnode_Array := (O_Fnode_Null, O_Fnode_Null);
- -- The field in the dope vector (for unbounded element).
+ -- The field in the layout record for the layout of the
+ -- element (for unbounded element).
Field_Bound : O_Fnode := O_Fnode_Null;
when Kind_Expr =>
@@ -1709,9 +1858,8 @@ package Trans is
function Is_Composite (Info : Type_Info_Acc) return Boolean;
pragma Inline (Is_Composite);
- -- Type needs to be built.
+ -- Type is bounded but layout and size are known only during elaboration.
function Is_Complex_Type (Tinfo : Type_Info_Acc) return Boolean;
- pragma Inline (Is_Complex_Type);
-- Type size is known at compile-time.
function Is_Static_Type (Tinfo : Type_Info_Acc) return Boolean;
diff --git a/src/vhdl/translate/translation.adb b/src/vhdl/translate/translation.adb
index a7ec6e7da..68dd9a300 100644
--- a/src/vhdl/translate/translation.adb
+++ b/src/vhdl/translate/translation.adb
@@ -33,6 +33,7 @@ with Trans;
with Trans_Decls; use Trans_Decls;
with Trans.Chap1;
with Trans.Chap2;
+with Trans.Chap3;
with Trans.Chap4;
with Trans.Chap7;
with Trans.Chap12;
@@ -423,6 +424,9 @@ package body Translation is
Ghdl_Index_0 := New_Unsigned_Literal (Ghdl_Index_Type, 0);
Ghdl_Index_1 := New_Unsigned_Literal (Ghdl_Index_Type, 1);
+ Ghdl_Index_2 := New_Unsigned_Literal (Ghdl_Index_Type, 2);
+ Ghdl_Index_4 := New_Unsigned_Literal (Ghdl_Index_Type, 4);
+ Ghdl_Index_8 := New_Unsigned_Literal (Ghdl_Index_Type, 8);
Ghdl_I32_Type := New_Signed_Type (32);
New_Type_Decl (Get_Identifier ("__ghdl_i32"), Ghdl_I32_Type);
@@ -453,6 +457,8 @@ package body Translation is
Char_Ptr_Type := New_Access_Type (Chararray_Type);
New_Type_Decl (Get_Identifier ("__ghdl_char_ptr"), Char_Ptr_Type);
+ Ghdl_Index_Ptr_Align := New_Alignof (Char_Ptr_Type, Ghdl_Index_Type);
+
Char_Ptr_Array_Type := New_Array_Type (Char_Ptr_Type, Ghdl_Index_Type);
New_Type_Decl (Get_Identifier ("__ghdl_char_ptr_array"),
Char_Ptr_Array_Type);
@@ -531,6 +537,10 @@ package body Translation is
Ghdl_Sizes_Type);
end;
+ -- __ghdl_sizes_ptr is access __ghdl_sizes_type;
+ Ghdl_Sizes_Ptr := New_Access_Type (Ghdl_Sizes_Type);
+ New_Type_Decl (Get_Identifier ("__ghdl_sizes_ptr"), Ghdl_Sizes_Ptr);
+
-- Create type ghdl_compare_type is (lt, eq, ge);
declare
Constr : O_Enum_List;
@@ -1906,12 +1916,22 @@ package body Translation is
end Post_Initialize;
- procedure Translate_Type_Implicit_Subprograms (Decl : in out Iir)
+ procedure Translate_Type_Implicit_Subprograms
+ (Decl : in out Iir; Main : Boolean)
is
Infos : Chap7.Implicit_Subprogram_Infos;
+ Subprg_Kind : Subprg_Translate_Kind;
begin
- -- Skip type declaration.
pragma Assert (Get_Kind (Decl) in Iir_Kinds_Type_Declaration);
+
+ if Main then
+ Subprg_Kind := Subprg_Translate_Spec_And_Body;
+ else
+ Subprg_Kind := Subprg_Translate_Only_Spec;
+ end if;
+ Chap3.Translate_Type_Subprograms (Decl, Subprg_Kind);
+
+ -- Skip type declaration.
Decl := Get_Chain (Decl);
-- Implicit subprograms are immediately follow the type declaration.
@@ -1988,22 +2008,22 @@ package body Translation is
New_Array_Type (Std_Boolean_Type_Node, Ghdl_Index_Type);
New_Type_Decl (Create_Identifier ("BOOLEAN_ARRAY"),
Std_Boolean_Array_Type);
- Translate_Type_Implicit_Subprograms (Decl);
+ Translate_Type_Implicit_Subprograms (Decl, Main);
-- Second declaration: bit.
pragma Assert (Decl = Bit_Type_Declaration);
Chap4.Translate_Bool_Type_Declaration (Bit_Type_Declaration);
- Translate_Type_Implicit_Subprograms (Decl);
+ Translate_Type_Implicit_Subprograms (Decl, Main);
-- Nothing special for other declarations.
while Decl /= Null_Iir loop
case Get_Kind (Decl) is
when Iir_Kind_Type_Declaration =>
Chap4.Translate_Type_Declaration (Decl);
- Translate_Type_Implicit_Subprograms (Decl);
+ Translate_Type_Implicit_Subprograms (Decl, Main);
when Iir_Kind_Anonymous_Type_Declaration =>
Chap4.Translate_Anonymous_Type_Declaration (Decl);
- Translate_Type_Implicit_Subprograms (Decl);
+ Translate_Type_Implicit_Subprograms (Decl, Main);
when Iir_Kind_Subtype_Declaration =>
Chap4.Translate_Subtype_Declaration (Decl);
Decl := Get_Chain (Decl);
@@ -2078,8 +2098,7 @@ package body Translation is
--Pop_Global_Factory;
end Translate_Standard;
- procedure Finalize
- is
+ procedure Finalize is
begin
Free_Node_Infos;
Free_Old_Temp;