Dummy_Object : Entity_Id := Empty;
-- Extra nonexistent object of type Typ internally used to compute the
-- offset to the components that reference secondary dispatch tables.
- -- Used to statically allocate secondary dispatch tables.
+ -- Used to compute the offset of components located at fixed position.
procedure Check_Premature_Freezing
(Subp : Entity_Id;
Prefix => New_Occurrence_Of (Predef_Prims, Loc),
Attribute_Name => Name_Address));
- -- If the location of the component that references this secondary
- -- dispatch table is variable then we have not declared the internal
- -- dummy object; the value of Offset_To_Top will be set by the init
- -- subprogram.
+ -- Interface component located at variable offset; the value of
+ -- Offset_To_Top will be set by the init subprogram.
- if No (Dummy_Object) then
+ if No (Dummy_Object)
+ or else Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
+ then
Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
+ -- Interface component located at fixed offset
+
else
Append_To (DT_Aggr_List,
Make_Op_Minus (Loc,
Make_Object_Declaration (Loc,
Defining_Identifier => Iface_DT,
Aliased_Present => True,
- Constant_Present => Present (Dummy_Object),
+ Constant_Present => Building_Static_Secondary_DT (Typ),
Object_Definition =>
Make_Subtype_Indication (Loc,
end;
end if;
- if Building_Static_Secondary_DT (Typ) then
+ if not Is_Interface (Typ) and then Has_Interfaces (Typ) then
declare
Cannot_Have_Null_Disc : Boolean := False;
+ Dummy_Object_Typ : constant Entity_Id := Typ;
Name_Dummy_Object : constant Name_Id :=
New_External_Name (Tname,
'P', Suffix_Index => -1);
Set_Is_Internal (Dummy_Object);
- if not Has_Discriminants (Typ) then
+ if not Has_Discriminants (Dummy_Object_Typ) then
Append_To (Result,
Make_Object_Declaration (Loc,
Defining_Identifier => Dummy_Object,
Constant_Present => True,
- Object_Definition => New_Occurrence_Of (Typ, Loc)));
+ Object_Definition => New_Occurrence_Of
+ (Dummy_Object_Typ, Loc)));
else
declare
Constr_List : constant List_Id := New_List;
Discrim : Node_Id;
begin
- Discrim := First_Discriminant (Typ);
+ Discrim := First_Discriminant (Dummy_Object_Typ);
while Present (Discrim) loop
if Is_Discrete_Type (Etype (Discrim)) then
Append_To (Constr_List,
Constant_Present => True,
Object_Definition =>
Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Occurrence_Of (Typ, Loc),
+ Subtype_Mark =>
+ New_Occurrence_Of (Dummy_Object_Typ, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => Constr_List))));
declare
TSD_Ifaces_List : constant List_Id := New_List;
Elmt : Elmt_Id;
- Ifaces_List : Elist_Id := No_Elist;
- Ifaces_Comp_List : Elist_Id := No_Elist;
- Ifaces_Tag_List : Elist_Id;
Offset_To_Top : Node_Id;
Sec_DT_Tag : Node_Id;
+ Dummy_Object_Ifaces_List : Elist_Id := No_Elist;
+ Dummy_Object_Ifaces_Comp_List : Elist_Id := No_Elist;
+ Dummy_Object_Ifaces_Tag_List : Elist_Id := No_Elist;
+ -- Interfaces information of the dummy object
+
begin
-- Collect interfaces information if we need to compute the
-- offset to the top using the dummy object.
if Present (Dummy_Object) then
Collect_Interfaces_Info (Typ,
- Ifaces_List, Ifaces_Comp_List, Ifaces_Tag_List);
+ Ifaces_List => Dummy_Object_Ifaces_List,
+ Components_List => Dummy_Object_Ifaces_Comp_List,
+ Tags_List => Dummy_Object_Ifaces_Tag_List);
end if;
AI := First_Elmt (Typ_Ifaces);
(Node (Next_Elmt (Next_Elmt (Elmt))), Loc);
end if;
- -- For static dispatch tables compute Offset_To_Top using
- -- the dummy object.
+ -- Use the dummy object to compute Offset_To_Top of
+ -- components located at fixed position.
if Present (Dummy_Object) then
declare
Iface_Elmt : Elmt_Id;
begin
- Iface_Elmt := First_Elmt (Ifaces_List);
- Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
+ Iface_Elmt :=
+ First_Elmt (Dummy_Object_Ifaces_List);
+ Iface_Comp_Elmt :=
+ First_Elmt (Dummy_Object_Ifaces_Comp_List);
while Present (Iface_Elmt) loop
if Node (Iface_Elmt) = Iface then
pragma Assert (Present (Iface_Comp));
- Offset_To_Top :=
- Make_Op_Minus (Loc,
- Make_Attribute_Reference (Loc,
- Prefix =>
- Make_Selected_Component (Loc,
- Prefix =>
- New_Occurrence_Of (Dummy_Object, Loc),
- Selector_Name =>
- New_Occurrence_Of (Iface_Comp, Loc)),
- Attribute_Name => Name_Position));
+ if not
+ Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
+ then
+ Offset_To_Top :=
+ Make_Op_Minus (Loc,
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ Make_Selected_Component (Loc,
+ Prefix =>
+ New_Occurrence_Of (Dummy_Object, Loc),
+ Selector_Name =>
+ New_Occurrence_Of (Iface_Comp, Loc)),
+ Attribute_Name => Name_Position));
+ else
+ Offset_To_Top := Make_Integer_Literal (Loc, 0);
+ end if;
end;
else
Offset_To_Top := Make_Integer_Literal (Loc, 0);
Make_Object_Declaration (Loc,
Defining_Identifier => ITable,
Aliased_Present => True,
- Constant_Present => Present (Dummy_Object),
+ Constant_Present => Building_Static_Secondary_DT (Typ),
Object_Definition =>
Make_Subtype_Indication (Loc,
Subtype_Mark =>