aboutsummaryrefslogtreecommitdiffstats
path: root/src/ortho/mcode
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-07-24 18:31:11 +0200
committerTristan Gingold <tgingold@free.fr>2020-07-25 11:28:49 +0200
commit04cd83fb46bee1e7a7b37be95bee73449af9c8b8 (patch)
tree3fe35d0bc6d4b1be8d81ad44df685057c221d2dc /src/ortho/mcode
parent4033dd795927a4953879bdc92d395788893a5468 (diff)
downloadghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.tar.gz
ghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.tar.bz2
ghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.zip
ortho: add unbounded records, rework array subtypes.
Diffstat (limited to 'src/ortho/mcode')
-rw-r--r--src/ortho/mcode/ortho_code-consts.adb43
-rw-r--r--src/ortho/mcode/ortho_code-consts.ads4
-rw-r--r--src/ortho/mcode/ortho_code-disps.adb10
-rw-r--r--src/ortho/mcode/ortho_code-dwarf.adb50
-rw-r--r--src/ortho/mcode/ortho_code-exprs.adb19
-rw-r--r--src/ortho/mcode/ortho_code-types.adb257
-rw-r--r--src/ortho/mcode/ortho_code-types.ads54
-rw-r--r--src/ortho/mcode/ortho_code-x86-emits.adb13
-rw-r--r--src/ortho/mcode/ortho_mcode.adb44
-rw-r--r--src/ortho/mcode/ortho_mcode.ads40
-rw-r--r--src/ortho/mcode/ortho_mcode.private.ads15
11 files changed, 408 insertions, 141 deletions
diff --git a/src/ortho/mcode/ortho_code-consts.adb b/src/ortho/mcode/ortho_code-consts.adb
index dcb9c13be..c83b98459 100644
--- a/src/ortho/mcode/ortho_code-consts.adb
+++ b/src/ortho/mcode/ortho_code-consts.adb
@@ -507,11 +507,11 @@ package body Ortho_Code.Consts is
return To_Cnode_Union (Cnodes.Table (Cst + 1)).El;
end Get_Const_Union_Value;
+ function To_Cnode_Common is new Ada.Unchecked_Conversion
+ (Source => Cnode_Sizeof, Target => Cnode_Common);
+
function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode
is
- function To_Cnode_Common is new Ada.Unchecked_Conversion
- (Source => Cnode_Sizeof, Target => Cnode_Common);
-
Res : O_Cnode;
begin
if Debug.Flag_Debug_Hli then
@@ -527,6 +527,24 @@ package body Ortho_Code.Consts is
end if;
end New_Sizeof;
+ function New_Record_Sizeof
+ (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode
+ is
+ Res : O_Cnode;
+ begin
+ if Debug.Flag_Debug_Hli then
+ Cnodes.Append (Cnode_Common'(Kind => OC_Record_Sizeof,
+ Lit_Type => Rtype));
+ Res := Cnodes.Last;
+ Cnodes.Append (To_Cnode_Common (Cnode_Sizeof'(Atype => Atype,
+ Pad => 0)));
+ return Res;
+ else
+ return New_Unsigned_Literal
+ (Rtype, Unsigned_64 (Get_Type_Record_Size (Atype)));
+ end if;
+ end New_Record_Sizeof;
+
function Get_Sizeof_Type (Cst : O_Cnode) return O_Tnode
is
function To_Cnode_Sizeof is new Ada.Unchecked_Conversion
@@ -645,8 +663,8 @@ package body Ortho_Code.Consts is
begin
case Get_Const_Kind (Cst) is
when OC_Signed
- | OC_Unsigned
- | OC_Float =>
+ | OC_Unsigned
+ | OC_Float =>
H := Get_Const_High (Cst);
L := Get_Const_Low (Cst);
when OC_Null =>
@@ -656,13 +674,14 @@ package body Ortho_Code.Consts is
H := 0;
L := To_Cnode_Enum (Cnodes.Table (Cst + 1)).Val;
when OC_Array
- | OC_Record
- | OC_Union
- | OC_Sizeof
- | OC_Alignof
- | OC_Address
- | OC_Subprg_Address
- | OC_Zero =>
+ | OC_Record
+ | OC_Union
+ | OC_Sizeof
+ | OC_Record_Sizeof
+ | OC_Alignof
+ | OC_Address
+ | OC_Subprg_Address
+ | OC_Zero =>
raise Syntax_Error;
end case;
end Get_Const_Bytes;
diff --git a/src/ortho/mcode/ortho_code-consts.ads b/src/ortho/mcode/ortho_code-consts.ads
index f49dbb315..05ff4389e 100644
--- a/src/ortho/mcode/ortho_code-consts.ads
+++ b/src/ortho/mcode/ortho_code-consts.ads
@@ -22,7 +22,7 @@ package Ortho_Code.Consts is
OC_Zero,
OC_Array, OC_Record, OC_Union,
OC_Subprg_Address, OC_Address,
- OC_Sizeof, OC_Alignof);
+ OC_Sizeof, OC_Record_Sizeof, OC_Alignof);
type OG_Kind is (OG_Decl, OG_Record_Ref);
@@ -140,6 +140,8 @@ package Ortho_Code.Consts is
-- unsigned type RTYPE
-- ATYPE cannot be an unconstrained array type.
function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode;
+ function New_Record_Sizeof
+ (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode;
-- Returns the alignment in bytes for ATYPE. The result is a literal of
-- unsgined type RTYPE.
diff --git a/src/ortho/mcode/ortho_code-disps.adb b/src/ortho/mcode/ortho_code-disps.adb
index 45507a52e..8195f675d 100644
--- a/src/ortho/mcode/ortho_code-disps.adb
+++ b/src/ortho/mcode/ortho_code-disps.adb
@@ -400,10 +400,20 @@ package body Ortho_Code.Disps is
Put ("[");
Put_Trim (Uns32'Image (Get_Type_Subarray_Length (Atype)));
Put ("]");
+ Put (" ");
+ Put ("of");
+ Put (" ");
+ Disp_Type (Get_Type_Subarray_Element (Atype));
when OT_Record =>
Put_Line ("record");
Disp_Fields (1, Atype);
Put ("end record");
+ when OT_Subrecord =>
+ Put_Line ("subrecord");
+ Disp_Type (Get_Type_Subrecord_Base (Atype));
+ Put ("(");
+ Disp_Fields (1, Atype);
+ Put (")");
when OT_Union =>
Put_Line ("union");
Disp_Fields (1, Atype);
diff --git a/src/ortho/mcode/ortho_code-dwarf.adb b/src/ortho/mcode/ortho_code-dwarf.adb
index 0275b870f..31acadd0f 100644
--- a/src/ortho/mcode/ortho_code-dwarf.adb
+++ b/src/ortho/mcode/ortho_code-dwarf.adb
@@ -674,10 +674,9 @@ package body Ortho_Code.Dwarf is
end if;
end Emit_Access_Type;
- procedure Emit_Ucarray_Type (Atype : O_Tnode; Decl : O_Dnode)
+ procedure Emit_Array_Type
+ (Decl : O_Dnode; El_Type : O_Tnode; Idx_Type : O_Tnode)
is
- use Ortho_Code.Types;
-
procedure Finish_Gen_Abbrev is
begin
Gen_Abbrev_Tuple (DW_AT_Type, DW_FORM_Ref4);
@@ -701,7 +700,7 @@ package body Ortho_Code.Dwarf is
Gen_Info_Header (Abbrev_Ucarray_Name);
Emit_Decl_Ident (Decl);
end if;
- Emit_Type_Ref (Get_Type_Ucarray_Element (Atype));
+ Emit_Type_Ref (El_Type);
if Abbrev_Uc_Subrange = 0 then
Generate_Abbrev (Abbrev_Uc_Subrange);
@@ -712,9 +711,18 @@ package body Ortho_Code.Dwarf is
end if;
Gen_Info_Header (Abbrev_Uc_Subrange);
- Emit_Type_Ref (Get_Type_Ucarray_Index (Atype));
+ Emit_Type_Ref (Idx_Type);
Gen_Uleb128 (0);
+ end Emit_Array_Type;
+
+ procedure Emit_Ucarray_Type (Atype : O_Tnode; Decl : O_Dnode)
+ is
+ use Ortho_Code.Types;
+ begin
+ Emit_Array_Type (Decl,
+ Get_Type_Ucarray_Element (Atype),
+ Get_Type_Ucarray_Index (Atype));
end Emit_Ucarray_Type;
procedure Emit_Subarray_Type (Atype : O_Tnode; Decl : O_Dnode)
@@ -747,9 +755,8 @@ package body Ortho_Code.Dwarf is
Emit_Decl_Ident (Decl);
end if;
- Base := Get_Type_Subarray_Base (Atype);
- Emit_Type_Ref (Get_Type_Ucarray_Element (Base));
+ Emit_Type_Ref (Get_Type_Subarray_Element (Atype));
Gen_Uleb128 (Unsigned_32 (Get_Type_Size (Atype)));
if Abbrev_Subrange = 0 then
@@ -763,6 +770,7 @@ package body Ortho_Code.Dwarf is
end if;
Gen_Info_Header (Abbrev_Subrange);
+ Base := Get_Type_Subarray_Base (Atype);
Emit_Type_Ref (Get_Type_Ucarray_Index (Base));
Gen_8 (0);
Gen_Uleb128 (Unsigned_32 (Get_Type_Subarray_Length (Atype)));
@@ -777,6 +785,7 @@ package body Ortho_Code.Dwarf is
F : O_Fnode;
Loc_Pc : Pc_Type;
Sibling_Pc : Pc_Type;
+ Sz : Uns32;
begin
if Abbrev_Member = 0 then
Generate_Abbrev (Abbrev_Member);
@@ -792,7 +801,12 @@ package body Ortho_Code.Dwarf is
Set_Current_Section (Info_Sect);
Sibling_Pc := Gen_Info_Sibling;
Emit_Decl_Ident_If_Set (Decl);
- Gen_Uleb128 (Unsigned_32 (Get_Type_Size (Atype)));
+ if Get_Type_Sized (Atype) then
+ Sz := Get_Type_Size (Atype);
+ else
+ Sz := Get_Type_Record_Size (Atype);
+ end if;
+ Gen_Uleb128 (Unsigned_32 (Sz));
Nbr := Get_Type_Record_Nbr_Fields (Atype);
F := Get_Type_Record_Fields (Atype);
@@ -975,10 +989,10 @@ package body Ortho_Code.Dwarf is
-- First step: emit inner types (if any).
case Kind is
when OT_Signed
- | OT_Unsigned
- | OT_Float
- | OT_Boolean
- | OT_Enum =>
+ | OT_Unsigned
+ | OT_Float
+ | OT_Boolean
+ | OT_Enum =>
null;
when OT_Access =>
null;
@@ -988,7 +1002,8 @@ package body Ortho_Code.Dwarf is
when OT_Subarray =>
Emit_Type (Get_Type_Subarray_Base (Atype));
when OT_Record
- | OT_Union =>
+ | OT_Subrecord
+ | OT_Union =>
declare
Nbr : Uns32;
F : O_Fnode;
@@ -1013,8 +1028,8 @@ package body Ortho_Code.Dwarf is
-- Second step: emit info.
case Kind is
when OT_Signed
- | OT_Unsigned
- | OT_Float =>
+ | OT_Unsigned
+ | OT_Float =>
Emit_Base_Type (Atype, Decl);
-- base types.
when OT_Access =>
@@ -1023,12 +1038,13 @@ package body Ortho_Code.Dwarf is
Emit_Ucarray_Type (Atype, Decl);
when OT_Subarray =>
Emit_Subarray_Type (Atype, Decl);
- when OT_Record =>
+ when OT_Record
+ | OT_Subrecord =>
Emit_Record_Type (Atype, Decl);
when OT_Union =>
Emit_Union_Type (Atype, Decl);
when OT_Enum
- | OT_Boolean =>
+ | OT_Boolean =>
Emit_Enum_Type (Atype, Decl);
when OT_Complete =>
null;
diff --git a/src/ortho/mcode/ortho_code-exprs.adb b/src/ortho/mcode/ortho_code-exprs.adb
index e580082c7..619f124a6 100644
--- a/src/ortho/mcode/ortho_code-exprs.adb
+++ b/src/ortho/mcode/ortho_code-exprs.adb
@@ -708,10 +708,10 @@ package body Ortho_Code.Exprs is
else
case Get_Const_Kind (Lit) is
when OC_Signed
- | OC_Unsigned
- | OC_Float
- | OC_Null
- | OC_Lit =>
+ | OC_Unsigned
+ | OC_Float
+ | OC_Null
+ | OC_Lit =>
declare
H, L : Uns32;
begin
@@ -726,11 +726,12 @@ package body Ortho_Code.Exprs is
return New_Enode (OE_Addrd, L_Type,
O_Enode (Get_Const_Decl (Lit)), O_Enode_Null);
when OC_Array
- | OC_Record
- | OC_Union
- | OC_Sizeof
- | OC_Alignof
- | OC_Zero =>
+ | OC_Record
+ | OC_Record_Sizeof
+ | OC_Union
+ | OC_Sizeof
+ | OC_Alignof
+ | OC_Zero =>
raise Syntax_Error;
end case;
end if;
diff --git a/src/ortho/mcode/ortho_code-types.adb b/src/ortho/mcode/ortho_code-types.adb
index 177c1ec99..5cd17f0d1 100644
--- a/src/ortho/mcode/ortho_code-types.adb
+++ b/src/ortho/mcode/ortho_code-types.adb
@@ -32,8 +32,9 @@ package body Ortho_Code.Types is
Mode : Mode_Type; -- 4 bits.
Align : Small_Natural; -- 2 bits.
Deferred : Boolean; -- 1 bit (True if the type was incomplete at first)
+ Sized : Boolean; -- 1 bit (True if the type has a size, is constrained)
Flag1 : Boolean;
- Pad0 : Bool_Array (0 .. 19);
+ Pad0 : Bool_Array (0 .. 18);
Size : Uns32;
end record;
pragma Pack (Tnode_Common);
@@ -49,7 +50,7 @@ package body Ortho_Code.Types is
Index_Type : O_Tnode;
end record;
- type Tnode_Subarray is record
+ type Tnode_Subarray_2 is record
Base_Type : O_Tnode;
Length : Uns32;
end record;
@@ -59,6 +60,11 @@ package body Ortho_Code.Types is
Nbr_Fields : Uns32;
end record;
+ type Tnode_Subrecord_2 is record
+ Base_Type : O_Tnode;
+ Pad : Uns32;
+ end record;
+
type Tnode_Enum is record
Lits : O_Cnode;
Nbr_Lits : Uns32;
@@ -94,12 +100,28 @@ package body Ortho_Code.Types is
return Tnodes.Table (Atype).Kind;
end Get_Type_Kind;
+ function Get_Type_Sized (Atype : O_Tnode) return Boolean is
+ begin
+ return Tnodes.Table (Atype).Sized;
+ end Get_Type_Sized;
+
+ procedure Set_Type_Sized (Atype : O_Tnode; Sized : Boolean) is
+ begin
+ Tnodes.Table (Atype).Sized := Sized;
+ end Set_Type_Sized;
+
function Get_Type_Size (Atype : O_Tnode) return Uns32 is
begin
- pragma Assert (Get_Type_Kind (Atype) /= OT_Ucarray);
+ pragma Assert (Get_Type_Sized (Atype));
return Tnodes.Table (Atype).Size;
end Get_Type_Size;
+ function Get_Type_Record_Size (Atype : O_Tnode) return Uns32 is
+ begin
+ pragma Assert (Get_Type_Kind (Atype) = OT_Record);
+ return Tnodes.Table (Atype).Size;
+ end Get_Type_Record_Size;
+
function Get_Type_Align (Atype : O_Tnode) return Small_Natural is
begin
return Tnodes.Table (Atype).Align;
@@ -154,20 +176,26 @@ package body Ortho_Code.Types is
end Get_Type_Ucarray_Element;
- function To_Tnode_Subarray is new Ada.Unchecked_Conversion
- (Source => Tnode_Common, Target => Tnode_Subarray);
+ function To_Tnode_Subarray_2 is new Ada.Unchecked_Conversion
+ (Source => Tnode_Common, Target => Tnode_Subarray_2);
function Get_Type_Subarray_Base (Atype : O_Tnode) return O_Tnode is
begin
- return To_Tnode_Subarray (Tnodes.Table (Atype + 1)).Base_Type;
+ return To_Tnode_Subarray_2 (Tnodes.Table (Atype + 2)).Base_Type;
end Get_Type_Subarray_Base;
function Get_Type_Subarray_Length (Atype : O_Tnode) return Uns32 is
begin
- return To_Tnode_Subarray (Tnodes.Table (Atype + 1)).Length;
+ return To_Tnode_Subarray_2 (Tnodes.Table (Atype + 2)).Length;
end Get_Type_Subarray_Length;
+ function Get_Type_Subarray_Element (Atype : O_Tnode) return O_Tnode is
+ begin
+ return To_Tnode_Array (Tnodes.Table (Atype + 1)).Element_Type;
+ end Get_Type_Subarray_Element;
+
+
function To_Tnode_Record is new Ada.Unchecked_Conversion
(Source => Tnode_Common, Target => Tnode_Record);
@@ -181,6 +209,14 @@ package body Ortho_Code.Types is
return To_Tnode_Record (Tnodes.Table (Atype + 1)).Nbr_Fields;
end Get_Type_Record_Nbr_Fields;
+ function To_Tnode_Subrecord_2 is new Ada.Unchecked_Conversion
+ (Source => Tnode_Common, Target => Tnode_Subrecord_2);
+
+ function Get_Type_Subrecord_Base (Atype : O_Tnode) return O_Tnode is
+ begin
+ return To_Tnode_Subrecord_2 (Tnodes.Table (Atype + 2)).Base_Type;
+ end Get_Type_Subrecord_Base;
+
function To_Tnode_Enum is new Ada.Unchecked_Conversion
(Source => Tnode_Common, Target => Tnode_Enum);
@@ -271,6 +307,7 @@ package body Ortho_Code.Types is
Mode => Mode,
Align => Mode_Align (Mode),
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => Sz));
@@ -302,6 +339,7 @@ package body Ortho_Code.Types is
Mode => Mode,
Align => Mode_Align (Mode),
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => Sz));
@@ -314,6 +352,7 @@ package body Ortho_Code.Types is
Mode => Mode_F64,
Align => Mode_Align (Mode_F64),
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => 8));
@@ -348,6 +387,7 @@ package body Ortho_Code.Types is
Mode => Mode,
Align => Mode_Align (Mode),
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => Sz));
@@ -393,6 +433,7 @@ package body Ortho_Code.Types is
Mode => Mode_B2,
Align => 0,
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => 1));
@@ -415,6 +456,7 @@ package body Ortho_Code.Types is
Mode => Mode_Blk,
Align => Get_Type_Align (El_Type),
Deferred => False,
+ Sized => False,
Flag1 => False,
Pad0 => (others => False),
Size => 0));
@@ -425,27 +467,32 @@ package body Ortho_Code.Types is
end New_Array_Type;
function To_Tnode_Common is new Ada.Unchecked_Conversion
- (Source => Tnode_Subarray, Target => Tnode_Common);
+ (Source => Tnode_Subarray_2, Target => Tnode_Common);
- function New_Constrained_Array_Type (Atype : O_Tnode; Length : Uns32)
- return O_Tnode
+ function New_Array_Subtype
+ (Atype : O_Tnode; El_Type : O_Tnode; Length : Uns32) return O_Tnode
is
Res : O_Tnode;
Size : Uns32;
begin
- Size := Get_Type_Size (Get_Type_Array_Element (Atype));
+ Size := Get_Type_Size (El_Type);
Tnodes.Append (Tnode_Common'(Kind => OT_Subarray,
Mode => Mode_Blk,
Align => Get_Type_Align (Atype),
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => Size * Length));
Res := Tnodes.Last;
- Tnodes.Append (To_Tnode_Common (Tnode_Subarray'(Base_Type => Atype,
- Length => Length)));
+ Tnodes.Append (To_Tnode_Common
+ (Tnode_Array'(Element_Type => El_Type,
+ Index_Type => O_Tnode_Null)));
+ Tnodes.Append (To_Tnode_Common
+ (Tnode_Subarray_2'(Base_Type => Atype,
+ Length => Length)));
return Res;
- end New_Constrained_Array_Type;
+ end New_Array_Subtype;
procedure Create_Completer (Atype : O_Tnode) is
begin
@@ -453,6 +500,7 @@ package body Ortho_Code.Types is
Mode => Mode_Nil,
Align => 0,
Deferred => False,
+ Sized => False,
Flag1 => False,
Pad0 => (others => False),
Size => To_Uns32 (Int32 (Atype))));
@@ -476,6 +524,7 @@ package body Ortho_Code.Types is
Mode => Mode_Ptr,
Align => Mode_Align (Mode_Ptr),
Deferred => Dtype = O_Tnode_Null,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => Sz));
@@ -502,6 +551,9 @@ package body Ortho_Code.Types is
function To_Tnode_Common is new Ada.Unchecked_Conversion
(Source => Tnode_Record, Target => Tnode_Common);
+ function To_Tnode_Common is new Ada.Unchecked_Conversion
+ (Source => Tnode_Subrecord_2, Target => Tnode_Common);
+
function Create_Record_Type (Deferred : Boolean) return O_Tnode
is
Res : O_Tnode;
@@ -510,6 +562,7 @@ package body Ortho_Code.Types is
Mode => Mode_Blk,
Align => 0,
Deferred => Deferred,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => 0));
@@ -519,17 +572,6 @@ package body Ortho_Code.Types is
return Res;
end Create_Record_Type;
- procedure Start_Record_Type (Elements : out O_Element_List)
- is
- begin
- Elements := (Res => Create_Record_Type (False),
- First_Field => O_Fnode_Null,
- Last_Field => O_Fnode_Null,
- Off => 0,
- Align => 0,
- Nbr => 0);
- end Start_Record_Type;
-
procedure New_Uncomplete_Record_Type (Res : out O_Tnode) is
begin
Res := Create_Record_Type (True);
@@ -544,7 +586,8 @@ package body Ortho_Code.Types is
Last_Field => O_Fnode_Null,
Off => 0,
Align => 0,
- Nbr => 0);
+ Nbr => 0,
+ Base_Field => O_Fnode_Null);
end Start_Uncomplete_Record_Type;
function Get_Mode_Size (Mode : Mode_Type) return Uns32 is
@@ -590,12 +633,10 @@ package body Ortho_Code.Types is
return (Off + Msk) and (not Msk);
end Do_Align;
- procedure New_Record_Field
- (Elements : in out O_Element_List;
- El : out O_Fnode;
- Ident : O_Ident;
- Etype : O_Tnode)
- is
+ procedure Append_Field (Elements : in out O_Element_List;
+ El : out O_Fnode;
+ Ident : O_Ident;
+ Etype : O_Tnode) is
begin
Elements.Off := Do_Align (Elements.Off, Etype);
@@ -605,7 +646,11 @@ package body Ortho_Code.Types is
Offset => Elements.Off,
Next => O_Fnode_Null));
El := Fnodes.Last;
- Elements.Off := Elements.Off + Get_Type_Size (Etype);
+ if Get_Type_Sized (Etype) then
+ Elements.Off := Elements.Off + Get_Type_Size (Etype);
+ else
+ Set_Type_Sized (Elements.Res, False);
+ end if;
if Get_Type_Align (Etype) > Elements.Align then
Elements.Align := Get_Type_Align (Etype);
end if;
@@ -615,12 +660,35 @@ package body Ortho_Code.Types is
Elements.First_Field := Fnodes.Last;
end if;
Elements.Last_Field := Fnodes.Last;
+ end Append_Field;
+
+ procedure Start_Record_Type (Elements : out O_Element_List) is
+ begin
+ Elements := (Res => Create_Record_Type (False),
+ First_Field => O_Fnode_Null,
+ Last_Field => O_Fnode_Null,
+ Off => 0,
+ Align => 0,
+ Nbr => 0,
+ Base_Field => O_Fnode_Null);
+ end Start_Record_Type;
+
+ procedure New_Record_Field (Elements : in out O_Element_List;
+ El : out O_Fnode;
+ Ident : O_Ident;
+ Etype : O_Tnode) is
+ begin
+ if Get_Type_Sized (Etype) then
+ -- Cannot append bounded elements after unbounded onces.
+ pragma Assert (Get_Type_Sized (Elements.Res));
+ null;
+ end if;
+
+ Append_Field (Elements, El, Ident, Etype);
Elements.Nbr := Elements.Nbr + 1;
end New_Record_Field;
- procedure Finish_Record_Type
- (Elements : in out O_Element_List; Res : out O_Tnode)
- is
+ procedure Finish_Record (Elements : O_Element_List) is
begin
Tnodes.Table (Elements.Res).Align := Elements.Align;
Tnodes.Table (Elements.Res).Size := Do_Align (Elements.Off,
@@ -628,6 +696,12 @@ package body Ortho_Code.Types is
Tnodes.Table (Elements.Res + 1) := To_Tnode_Common
(Tnode_Record'(Fields => Elements.First_Field,
Nbr_Fields => Elements.Nbr));
+ end Finish_Record;
+
+ procedure Finish_Record_Type
+ (Elements : in out O_Element_List; Res : out O_Tnode) is
+ begin
+ Finish_Record (Elements);
Res := Elements.Res;
if Flag_Type_Completer
and then Tnodes.Table (Elements.Res).Deferred
@@ -636,6 +710,71 @@ package body Ortho_Code.Types is
end if;
end Finish_Record_Type;
+ procedure Start_Record_Subtype
+ (Rtype : O_Tnode; Elements : out O_Element_List)
+ is
+ Res : O_Tnode;
+ Nbr : Uns32;
+ begin
+ pragma Assert (Get_Type_Kind (Rtype) = OT_Record);
+ Nbr := Get_Type_Record_Nbr_Fields (Rtype);
+
+ Tnodes.Append (Tnode_Common'(Kind => OT_Subrecord,
+ Mode => Mode_Blk,
+ Align => 0,
+ Deferred => False,
+ Sized => True,
+ Flag1 => False,
+ Pad0 => (others => False),
+ Size => 0));
+ Res := Tnodes.Last;
+ Tnodes.Append (To_Tnode_Common (Tnode_Record'(Fields => O_Fnode_Null,
+ Nbr_Fields => Nbr)));
+ Tnodes.Append (To_Tnode_Common (Tnode_Subrecord_2'(Base_Type => Rtype,
+ Pad => 0)));
+ Elements := (Res => Res,
+ First_Field => O_Fnode_Null,
+ Last_Field => O_Fnode_Null,
+ Off => 0,
+ Align => 0,
+ Nbr => Nbr,
+ Base_Field => Get_Type_Record_Fields (Rtype));
+ end Start_Record_Subtype;
+
+ procedure New_Subrecord_Field
+ (Elements : in out O_Element_List; El : out O_Fnode; Etype : O_Tnode)
+ is
+ Base_Type : O_Tnode;
+ begin
+ pragma Assert (Elements.Nbr > 0);
+ Elements.Nbr := Elements.Nbr - 1;
+
+ Base_Type := Get_Field_Type (Elements.Base_Field);
+ if Get_Type_Sized (Base_Type) then
+ -- For bounded elements, the type must be the same.
+ pragma Assert (Etype = Base_Type);
+ null;
+ else
+ -- For unbounded elements, those from the subtype must be bounded.
+ pragma Assert (Get_Base_Type (Etype) = Base_Type);
+ pragma Assert (Get_Type_Sized (Etype));
+ null;
+ end if;
+
+ Append_Field (Elements,
+ El, Get_Field_Ident (Elements.Base_Field), Etype);
+ Elements.Base_Field := Get_Field_Chain (Elements.Base_Field);
+ end New_Subrecord_Field;
+
+ procedure Finish_Record_Subtype
+ (Elements : in out O_Element_List; Res : out O_Tnode) is
+ begin
+ Elements.Nbr := Get_Type_Record_Nbr_Fields (Elements.Res);
+ Finish_Record (Elements);
+ Res := Elements.Res;
+ end Finish_Record_Subtype;
+
+
procedure Start_Union_Type (Elements : out O_Element_List)
is
begin
@@ -643,6 +782,7 @@ package body Ortho_Code.Types is
Mode => Mode_Blk,
Align => 0,
Deferred => False,
+ Sized => True,
Flag1 => False,
Pad0 => (others => False),
Size => 0));
@@ -651,7 +791,8 @@ package body Ortho_Code.Types is
Last_Field => O_Fnode_Null,
Off => 0,
Align => 0,
- Nbr => 0);
+ Nbr => 0,
+ Base_Field => O_Fnode_Null);
Tnodes.Append (To_Tnode_Common (Tnode_Record'(Fields => O_Fnode_Null,
Nbr_Fields => 0)));
end Start_Union_Type;
@@ -679,22 +820,19 @@ package body Ortho_Code.Types is
Finish_Record_Type (Elements, Res);
end Finish_Union_Type;
- function Get_Type_Array_Element (Atype : O_Tnode) return O_Tnode
- is
- Base : O_Tnode;
+ function Get_Type_Array_Element (Atype : O_Tnode) return O_Tnode is
begin
case Get_Type_Kind (Atype) is
when OT_Ucarray =>
- Base := Atype;
+ return Get_Type_Ucarray_Element (Atype);
when OT_Subarray =>
- Base := Get_Type_Subarray_Base (Atype);
+ return Get_Type_Subarray_Element (Atype);
when others =>
raise Program_Error;
end case;
- return Get_Type_Ucarray_Element (Base);
end Get_Type_Array_Element;
- procedure Debug_Type (Atype : O_Tnode)
+ procedure Dump_Tnode (Atype : O_Tnode)
is
use Ortho_Code.Debug.Int32_IO;
use Ada.Text_IO;
@@ -733,13 +871,15 @@ package body Ortho_Code.Types is
Put (Int32 (Get_Type_Subarray_Base (Atype)));
Put (", length: ");
Put (To_Int32 (Get_Type_Subarray_Length (Atype)));
+ Put (", el_type: ");
+ Put (Int32 (Get_Type_Subarray_Element (Atype)));
New_Line;
when others =>
null;
end case;
- end Debug_Type;
+ end Dump_Tnode;
- procedure Debug_Field (Field : O_Fnode)
+ procedure Dump_Fnode (Field : O_Fnode)
is
use Ortho_Code.Debug.Int32_IO;
use Ada.Text_IO;
@@ -755,7 +895,7 @@ package body Ortho_Code.Types is
Put (", Chain=");
Put (Int32 (Get_Field_Chain (Field)), 0);
New_Line;
- end Debug_Field;
+ end Dump_Fnode;
function Get_Type_Limit return O_Tnode is
begin
@@ -766,28 +906,31 @@ package body Ortho_Code.Types is
begin
case Tnodes.Table (Atype).Kind is
when OT_Unsigned
- | OT_Signed
- | OT_Float =>
+ | OT_Signed
+ | OT_Float =>
return Atype + 1;
when OT_Boolean
- | OT_Enum
- | OT_Ucarray
- | OT_Subarray
- | OT_Access
- | OT_Record
- | OT_Union =>
+ | OT_Enum
+ | OT_Ucarray
+ | OT_Access
+ | OT_Record
+ | OT_Union =>
return Atype + 2;
+ when OT_Subarray
+ | OT_Subrecord =>
+ return Atype + 3;
when OT_Complete =>
return Atype + 1;
end case;
end Get_Type_Next;
- function Get_Base_Type (Atype : O_Tnode) return O_Tnode
- is
+ function Get_Base_Type (Atype : O_Tnode) return O_Tnode is
begin
case Get_Type_Kind (Atype) is
when OT_Subarray =>
return Get_Type_Subarray_Base (Atype);
+ when OT_Subrecord =>
+ return Get_Type_Subrecord_Base (Atype);
when others =>
return Atype;
end case;
diff --git a/src/ortho/mcode/ortho_code-types.ads b/src/ortho/mcode/ortho_code-types.ads
index a9d15b60a..1fd336ebd 100644
--- a/src/ortho/mcode/ortho_code-types.ads
+++ b/src/ortho/mcode/ortho_code-types.ads
@@ -17,8 +17,10 @@
-- 02111-1307, USA.
package Ortho_Code.Types is
type OT_Kind is (OT_Unsigned, OT_Signed, OT_Boolean, OT_Enum, OT_Float,
- OT_Ucarray, OT_Subarray, OT_Access,
- OT_Record, OT_Union,
+ OT_Ucarray, OT_Subarray,
+ OT_Access,
+ OT_Record, OT_Subrecord,
+ OT_Union,
-- Type completion. Mark the completion of a type.
-- Optionnal.
@@ -32,6 +34,9 @@ package Ortho_Code.Types is
-- Number of bytes of type ATYPE.
function Get_Type_Size (Atype : O_Tnode) return Uns32;
+ -- True if ATYPE is bounded (and therefore its size is valid).
+ function Get_Type_Sized (Atype : O_Tnode) return Boolean;
+
-- Same as Get_Type_Size but for modes.
-- Returns 0 in case of error.
function Get_Mode_Size (Mode : Mode_Type) return Uns32;
@@ -75,12 +80,21 @@ package Ortho_Code.Types is
-- Get number of element for array type ATYPE.
function Get_Type_Subarray_Length (Atype : O_Tnode) return Uns32;
+ -- Get the element type of subarray type ATYPE.
+ function Get_Type_Subarray_Element (Atype : O_Tnode) return O_Tnode;
+
+ -- Get the size of the bounded part of ATYPE.
+ function Get_Type_Record_Size (Atype : O_Tnode) return Uns32;
+
-- Get the first field of record/union ATYPE.
function Get_Type_Record_Fields (Atype : O_Tnode) return O_Fnode;
-- Get the number of fields of record/union ATYPE.
function Get_Type_Record_Nbr_Fields (Atype : O_Tnode) return Uns32;
+ -- Get the base type of subrecord ATYPE.
+ function Get_Type_Subrecord_Base (Atype : O_Tnode) return O_Tnode;
+
-- Get the first literal of enum type ATYPE.
function Get_Type_Enum_Lits (Atype : O_Tnode) return O_Cnode;
@@ -148,11 +162,11 @@ package Ortho_Code.Types is
-- Build an array type.
-- The array is not constrained and unidimensional.
function New_Array_Type (El_Type : O_Tnode; Index_Type : O_Tnode)
- return O_Tnode;
+ return O_Tnode;
-- Build a constrained array type.
- function New_Constrained_Array_Type (Atype : O_Tnode; Length : Uns32)
- return O_Tnode;
+ function New_Array_Subtype
+ (Atype : O_Tnode; El_Type : O_Tnode; Length : Uns32) return O_Tnode;
-- Return the base type of ATYPE: for a subarray this is the uc array,
-- otherwise this is the type.
@@ -172,6 +186,14 @@ package Ortho_Code.Types is
procedure Finish_Record_Type
(Elements : in out O_Element_List; Res : out O_Tnode);
+ -- Record subtype.
+ procedure Start_Record_Subtype
+ (Rtype : O_Tnode; Elements : out O_Element_List);
+ procedure New_Subrecord_Field
+ (Elements : in out O_Element_List; El : out O_Fnode; Etype : O_Tnode);
+ procedure Finish_Record_Subtype
+ (Elements : in out O_Element_List; Res : out O_Tnode);
+
-- Build an uncomplete record type:
-- First call NEW_UNCOMPLETE_RECORD_TYPE, which returns a record type.
-- This type can be declared or used to define access types on it.
@@ -214,23 +236,25 @@ package Ortho_Code.Types is
procedure Mark (M : out Mark_Type);
procedure Release (M : Mark_Type);
- procedure Debug_Type (Atype : O_Tnode);
- procedure Debug_Field (Field : O_Fnode);
+ procedure Dump_Tnode (Atype : O_Tnode);
+ procedure Dump_Fnode (Field : O_Fnode);
private
type O_Enum_List is record
- Res : O_Tnode;
+ Res : O_Tnode;
First : O_Cnode;
- Last : O_Cnode;
- Nbr : Uns32;
+ Last : O_Cnode;
+ Nbr : Uns32;
end record;
type O_Element_List is record
- Res : O_Tnode;
- Nbr : Uns32;
- Off : Uns32;
- Align : Small_Natural;
+ Res : O_Tnode;
+ Nbr : Uns32;
+ Off : Uns32;
+ Align : Small_Natural;
First_Field : O_Fnode;
- Last_Field : O_Fnode;
+ Last_Field : O_Fnode;
+ -- For subrecords
+ Base_Field : O_Fnode;
end record;
type Mark_Type is record
diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb
index 91db6b54d..f55793eec 100644
--- a/src/ortho/mcode/ortho_code-x86-emits.adb
+++ b/src/ortho/mcode/ortho_code-x86-emits.adb
@@ -3163,10 +3163,10 @@ package body Ortho_Code.X86.Emits is
begin
case Get_Const_Kind (Val) is
when OC_Signed
- | OC_Unsigned
- | OC_Float
- | OC_Null
- | OC_Lit =>
+ | OC_Unsigned
+ | OC_Float
+ | OC_Null
+ | OC_Lit =>
Get_Const_Bytes (Val, H, L);
case Get_Type_Mode (Get_Const_Type (Val)) is
when Mode_U8
@@ -3216,8 +3216,9 @@ package body Ortho_Code.X86.Emits is
Gen_8 (0);
end loop;
when OC_Sizeof
- | OC_Alignof
- | OC_Union =>
+ | OC_Record_Sizeof
+ | OC_Alignof
+ | OC_Union =>
raise Program_Error;
end case;
end Emit_Const;
diff --git a/src/ortho/mcode/ortho_mcode.adb b/src/ortho/mcode/ortho_mcode.adb
index cd7131d73..235bb0e47 100644
--- a/src/ortho/mcode/ortho_mcode.adb
+++ b/src/ortho/mcode/ortho_mcode.adb
@@ -60,6 +60,31 @@ package body Ortho_Mcode is
Ortho_Code.O_Tnode (Res));
end Finish_Record_Type;
+ procedure Start_Record_Subtype
+ (Rtype : O_Tnode; Elements : out O_Element_Sublist) is
+ begin
+ Ortho_Code.Types.Start_Record_Subtype
+ (Ortho_Code.O_Tnode (Rtype),
+ Ortho_Code.Types.O_Element_List (Elements));
+ end Start_Record_Subtype;
+
+ procedure New_Subrecord_Field
+ (Elements : in out O_Element_Sublist; El : out O_Fnode; Etype : O_Tnode)
+ is
+ begin
+ Ortho_Code.Types.New_Subrecord_Field
+ (Ortho_Code.Types.O_Element_List (Elements),
+ Ortho_Code.O_Fnode (El), Ortho_Code.O_Tnode (Etype));
+ end New_Subrecord_Field;
+
+ procedure Finish_Record_Subtype
+ (Elements : in out O_Element_Sublist; Res : out O_Tnode) is
+ begin
+ Ortho_Code.Types.Finish_Record_Subtype
+ (Ortho_Code.Types.O_Element_List (Elements),
+ Ortho_Code.O_Tnode (Res));
+ end Finish_Record_Subtype;
+
procedure New_Uncomplete_Record_Type (Res : out O_Tnode) is
begin
Ortho_Code.Types.New_Uncomplete_Record_Type (Ortho_Code.O_Tnode (Res));
@@ -127,8 +152,8 @@ package body Ortho_Mcode is
Ortho_Code.O_Tnode (Index_Type)));
end New_Array_Type;
- function New_Constrained_Array_Type (Atype : O_Tnode; Length : O_Cnode)
- return O_Tnode
+ function New_Array_Subtype
+ (Atype : O_Tnode; El_Type : O_Tnode; Length : O_Cnode) return O_Tnode
is
Len : constant Ortho_Code.O_Cnode := Ortho_Code.O_Cnode (Length);
L_Type : Ortho_Code.O_Tnode;
@@ -137,9 +162,10 @@ package body Ortho_Mcode is
if Get_Type_Kind (L_Type) /= OT_Unsigned then
raise Syntax_Error;
end if;
- return O_Tnode (New_Constrained_Array_Type
- (Ortho_Code.O_Tnode (Atype), Get_Const_U32 (Len)));
- end New_Constrained_Array_Type;
+ return O_Tnode (New_Array_Subtype (Ortho_Code.O_Tnode (Atype),
+ Ortho_Code.O_Tnode (El_Type),
+ Get_Const_U32 (Len)));
+ end New_Array_Subtype;
function New_Unsigned_Type (Size : Natural) return O_Tnode is
begin
@@ -325,6 +351,14 @@ package body Ortho_Mcode is
Ortho_Code.O_Tnode (Rtype)));
end New_Sizeof;
+ function New_Record_Sizeof
+ (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode is
+ begin
+ return O_Cnode
+ (Ortho_Code.Consts.New_Record_Sizeof (Ortho_Code.O_Tnode (Atype),
+ Ortho_Code.O_Tnode (Rtype)));
+ end New_Record_Sizeof;
+
function New_Alignof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode is
begin
return O_Cnode
diff --git a/src/ortho/mcode/ortho_mcode.ads b/src/ortho/mcode/ortho_mcode.ads
index ef24372e3..1e3aa6a44 100644
--- a/src/ortho/mcode/ortho_mcode.ads
+++ b/src/ortho/mcode/ortho_mcode.ads
@@ -64,8 +64,8 @@ package Ortho_Mcode is
-- Build a record type.
procedure Start_Record_Type (Elements : out O_Element_List);
- -- Add a field in the record; not constrained array are prohibited, since
- -- its size is unlimited.
+ -- Add a field in the record. Unconstrained fields must be at the end,
+ -- and cannot be followed by a constrained one.
procedure New_Record_Field
(Elements : in out O_Element_List;
El : out O_Fnode;
@@ -74,6 +74,17 @@ package Ortho_Mcode is
procedure Finish_Record_Type
(Elements : in out O_Element_List; Res : out O_Tnode);
+ type O_Element_Sublist is limited private;
+
+ -- Build a record subtype.
+ -- Re-declare only unconstrained fields with a subtype of them.
+ procedure Start_Record_Subtype
+ (Rtype : O_Tnode; Elements : out O_Element_Sublist);
+ procedure New_Subrecord_Field
+ (Elements : in out O_Element_Sublist; El : out O_Fnode; Etype : O_Tnode);
+ procedure Finish_Record_Subtype
+ (Elements : in out O_Element_Sublist; Res : out O_Tnode);
+
-- Build an uncomplete record type:
-- First call NEW_UNCOMPLETE_RECORD_TYPE, which returns a record type.
-- This type can be declared or used to define access types on it.
@@ -105,8 +116,8 @@ package Ortho_Mcode is
return O_Tnode;
-- Build a constrained array type.
- function New_Constrained_Array_Type (Atype : O_Tnode; Length : O_Cnode)
- return O_Tnode;
+ function New_Array_Subtype
+ (Atype : O_Tnode; El_Type : O_Tnode; Length : O_Cnode) return O_Tnode;
-- Build a scalar type; size may be 8, 16, 32 or 64.
function New_Unsigned_Type (Size : Natural) return O_Tnode;
@@ -179,9 +190,13 @@ package Ortho_Mcode is
-- Returns the size in bytes of ATYPE. The result is a literal of
-- unsigned type RTYPE
- -- ATYPE cannot be an unconstrained array type.
+ -- ATYPE cannot be an unconstrained type.
function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode;
+ -- Get the size of the bounded part of a record.
+ function New_Record_Sizeof
+ (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode;
+
-- Returns the alignment in bytes for ATYPE. The result is a literal of
-- unsgined type RTYPE.
function New_Alignof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode;
@@ -498,14 +513,15 @@ private
O_Snode_Null : constant O_Snode := O_Snode (Ortho_Code.Exprs.O_Snode_Null);
O_Tnode_Null : constant O_Tnode := O_Tnode (Ortho_Code.O_Tnode_Null);
- type O_Element_List is new Ortho_Code.Types.O_Element_List;
- type O_Enum_List is new Ortho_Code.Types.O_Enum_List;
- type O_Inter_List is new Ortho_Code.Decls.O_Inter_List;
+ type O_Element_List is new Ortho_Code.Types.O_Element_List;
+ type O_Element_Sublist is new Ortho_Code.Types.O_Element_List;
+ type O_Enum_List is new Ortho_Code.Types.O_Enum_List;
+ type O_Inter_List is new Ortho_Code.Decls.O_Inter_List;
type O_Record_Aggr_List is new Ortho_Code.Consts.O_Record_Aggr_List;
- type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List;
- type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List;
- type O_If_Block is new Ortho_Code.Exprs.O_If_Block;
- type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block;
+ type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List;
+ type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List;
+ type O_If_Block is new Ortho_Code.Exprs.O_If_Block;
+ type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block;
pragma Inline (New_Lit);
pragma Inline (New_Dyadic_Op);
diff --git a/src/ortho/mcode/ortho_mcode.private.ads b/src/ortho/mcode/ortho_mcode.private.ads
index a78a1a170..def9b7a72 100644
--- a/src/ortho/mcode/ortho_mcode.private.ads
+++ b/src/ortho/mcode/ortho_mcode.private.ads
@@ -52,14 +52,15 @@ private
O_Snode_Null : constant O_Snode := O_Snode (Ortho_Code.Exprs.O_Snode_Null);
O_Tnode_Null : constant O_Tnode := O_Tnode (Ortho_Code.O_Tnode_Null);
- type O_Element_List is new Ortho_Code.Types.O_Element_List;
- type O_Enum_List is new Ortho_Code.Types.O_Enum_List;
- type O_Inter_List is new Ortho_Code.Decls.O_Inter_List;
+ type O_Element_List is new Ortho_Code.Types.O_Element_List;
+ type O_Element_Sublist is new Ortho_Code.Types.O_Element_List;
+ type O_Enum_List is new Ortho_Code.Types.O_Enum_List;
+ type O_Inter_List is new Ortho_Code.Decls.O_Inter_List;
type O_Record_Aggr_List is new Ortho_Code.Consts.O_Record_Aggr_List;
- type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List;
- type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List;
- type O_If_Block is new Ortho_Code.Exprs.O_If_Block;
- type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block;
+ type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List;
+ type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List;
+ type O_If_Block is new Ortho_Code.Exprs.O_If_Block;
+ type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block;
pragma Inline (New_Lit);
pragma Inline (New_Dyadic_Op);