aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/a-tags.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/a-tags.adb')
-rw-r--r--gcc/ada/a-tags.adb242
1 files changed, 159 insertions, 83 deletions
diff --git a/gcc/ada/a-tags.adb b/gcc/ada/a-tags.adb
index dddf1bb8835..03221948d34 100644
--- a/gcc/ada/a-tags.adb
+++ b/gcc/ada/a-tags.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2005 Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -32,36 +32,35 @@
------------------------------------------------------------------------------
with Ada.Exceptions;
-
with System.HTable;
-with Unchecked_Conversion;
-
pragma Elaborate_All (System.HTable);
package body Ada.Tags is
-- Structure of the GNAT Dispatch Table
--- +----------------------+
--- | TSD pointer ---|-----> Type Specific Data
--- +----------------------+ +-------------------+
--- | table of | | inheritance depth |
--- : primitive ops : +-------------------+
--- | pointers | | expanded name |
--- +----------------------+ +-------------------+
--- | external tag |
--- +-------------------+
--- | Hash table link |
--- +-------------------+
--- | Remotely Callable |
--- +-------------------+
--- | Rec Ctrler offset |
--- +-------------------+
--- | table of |
--- : ancestor :
--- | tags |
--- +-------------------+
+-- +-----------------------+
+-- | Offset_To_Top |
+-- +-----------------------+
+-- | Typeinfo_Ptr/TSD_Ptr |----> Type Specific Data
+-- Tag ---> +-----------------------+ +-------------------+
+-- | table of | | inheritance depth |
+-- : primitive ops : +-------------------+
+-- | pointers | | expanded name |
+-- +-----------------------+ +-------------------+
+-- | external tag |
+-- +-------------------+
+-- | Hash table link |
+-- +-------------------+
+-- | Remotely Callable |
+-- +-------------------+
+-- | Rec Ctrler offset |
+-- +-------------------+
+-- | table of |
+-- : ancestor :
+-- | tags |
+-- +-------------------+
subtype Cstring is String (Positive);
type Cstring_Ptr is access all Cstring;
@@ -69,12 +68,12 @@ package body Ada.Tags is
type Tag_Table is array (Natural range <>) of Tag;
pragma Suppress_Initialization (Tag_Table);
pragma Suppress (Index_Check, On => Tag_Table);
- -- We suppress index checks because the declared size in the record
- -- below is a dummy size of one (see below).
+ -- We suppress index checks because the declared size in the record below
+ -- is a dummy size of one (see below).
type Wide_Boolean is new Boolean;
- -- This name should probably be changed sometime ??? and indeed
- -- probably this field could simply be of type Standard.Boolean.
+ -- This name should probably be changed sometime ??? and indeed probably
+ -- this field could simply be of type Standard.Boolean.
type Type_Specific_Data is record
Idepth : Natural;
@@ -85,31 +84,48 @@ package body Ada.Tags is
RC_Offset : SSE.Storage_Offset;
Ancestor_Tags : Tag_Table (0 .. 1);
end record;
- -- The size of the Ancestor_Tags array actually depends on the tagged
- -- type to which it applies. We are using the same mechanism as for
- -- the Prims_Ptr array in the Dispatch_Table record. See comments
- -- below for more details.
+ -- The size of the Ancestor_Tags array actually depends on the tagged type
+ -- to which it applies. We are using the same mechanism as for the
+ -- Prims_Ptr array in the Dispatch_Table record. See comments below for
+ -- more details.
type Dispatch_Table is record
- TSD : Type_Specific_Data_Ptr;
- Prims_Ptr : Address_Array (1 .. 1);
+ -- Offset_To_Top : Integer := 0;
+ -- Typeinfo_Ptr : System.Address; -- Currently TSD is also here???
+ Prims_Ptr : Address_Array (Positive);
end record;
- -- The size of the Prims_Ptr array actually depends on the tagged
- -- type to which it applies. For each tagged type, the expander
- -- computes the actual array size, and allocates the Dispatch_Table
- -- record accordingly.
+
+ -- Note on the commented out fields of the Dispatch_Table
+ -- ------------------------------------------------------
+ -- According to the C++ ABI the components Offset_To_Top and Typeinfo_Ptr
+ -- are stored just "before" the dispatch table (that is, the Prims_Ptr
+ -- table), and they are referenced with negative offsets referring to the
+ -- base of the dispatch table. The _Tag (or the VTable_Ptr in C++ termi-
+ -- nology) must point to the base of the virtual table, just after these
+ -- components, to point to the Prims_Ptr table. For this purpose the
+ -- expander generates a Prims_Ptr table that has enough space for these
+ -- additional components, and generates code that displaces the _Tag to
+ -- point after these components.
+ -- -----------------------------------------------------------------------
+
+ -- The size of the Prims_Ptr array actually depends on the tagged type to
+ -- which it applies. For each tagged type, the expander computes the
+ -- actual array size, allocates the Dispatch_Table record accordingly, and
+ -- generates code that displaces the base of the record after the
+ -- Typeinfo_Ptr component. For this reason the first two components have
+ -- been commented in the previous declaration. The access to these
+ -- components is done by means of local functions.
--
- -- To avoid the use of discriminants to define the actual size
- -- of the dispatch table, we used to declare the tag as a pointer
- -- to a record that contains an arbitrary array of addresses, using
- -- Positive as its index. This ensures that there are never range
- -- checks when accessing the dispatch table, but it prevents GDB
- -- from displaying tagged types properly. A better approach is
- -- to declare this record type as holding a small number of addresses,
- -- and to explicitly suppress checks on it.
+ -- To avoid the use of discriminants to define the actual size of the
+ -- dispatch table, we used to declare the tag as a pointer to a record
+ -- that contains an arbitrary array of addresses, using Positive as its
+ -- index. This ensures that there are never range checks when accessing
+ -- the dispatch table, but it prevents GDB from displaying tagged types
+ -- properly. A better approach is to declare this record type as holding a
+ -- small number of addresses, and to explicitly suppress checks on it.
--
- -- Note that in both cases, this type is never allocated, and serves
- -- only to declare the corresponding access type.
+ -- Note that in both cases, this type is never allocated, and serves only
+ -- to declare the corresponding access type.
---------------------------------------------
-- Unchecked Conversions for String Fields --
@@ -121,13 +137,34 @@ package body Ada.Tags is
function To_Address is
new Unchecked_Conversion (Cstring_Ptr, System.Address);
+ -----------------------------------------------------------
+ -- Unchecked Conversions for the component offset_to_top --
+ -----------------------------------------------------------
+
+ type Int_Ptr is access Integer;
+
+ function To_Int_Ptr is
+ new Unchecked_Conversion (System.Address, Int_Ptr);
+
-----------------------
-- Local Subprograms --
-----------------------
function Length (Str : Cstring_Ptr) return Natural;
- -- Length of string represented by the given pointer (treating the
- -- string as a C-style string, which is Nul terminated).
+ -- Length of string represented by the given pointer (treating the string
+ -- as a C-style string, which is Nul terminated).
+
+ function Offset_To_Top (T : Tag) return Integer;
+ -- Returns the current value of the offset_to_top component available in
+ -- the prologue of the dispatch table.
+
+ function Typeinfo_Ptr (T : Tag) return System.Address;
+ -- Returns the current value of the typeinfo_ptr component available in
+ -- the prologue of the dispatch table.
+
+ pragma Unreferenced (Offset_To_Top);
+ pragma Unreferenced (Typeinfo_Ptr);
+ -- These functions will be used for full compatibility with the C++ ABI
-------------------------
-- External_Tag_HTable --
@@ -135,9 +172,9 @@ package body Ada.Tags is
type HTable_Headers is range 1 .. 64;
- -- The following internal package defines the routines used for
- -- the instantiation of a new System.HTable.Static_HTable (see
- -- below). See spec in g-htable.ads for details of usage.
+ -- The following internal package defines the routines used for the
+ -- instantiation of a new System.HTable.Static_HTable (see below). See
+ -- spec in g-htable.ads for details of usage.
package HTable_Subprograms is
procedure Set_HT_Link (T : Tag; Next : Tag);
@@ -195,7 +232,7 @@ package body Ada.Tags is
function Get_HT_Link (T : Tag) return Tag is
begin
- return T.TSD.HT_Link;
+ return TSD (T).HT_Link;
end Get_HT_Link;
----------
@@ -216,7 +253,7 @@ package body Ada.Tags is
procedure Set_HT_Link (T : Tag; Next : Tag) is
begin
- T.TSD.HT_Link := Next;
+ TSD (T).HT_Link := Next;
end Set_HT_Link;
end HTable_Subprograms;
@@ -241,9 +278,9 @@ package body Ada.Tags is
-- = Typ'tag
function CW_Membership (Obj_Tag : Tag; Typ_Tag : Tag) return Boolean is
- Pos : constant Integer := Obj_Tag.TSD.Idepth - Typ_Tag.TSD.Idepth;
+ Pos : constant Integer := TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
begin
- return Pos >= 0 and then Obj_Tag.TSD.Ancestor_Tags (Pos) = Typ_Tag;
+ return Pos >= 0 and then TSD (Obj_Tag).Ancestor_Tags (Pos) = Typ_Tag;
end CW_Membership;
-------------------
@@ -251,7 +288,7 @@ package body Ada.Tags is
-------------------
function Expanded_Name (T : Tag) return String is
- Result : constant Cstring_Ptr := T.TSD.Expanded_Name;
+ Result : constant Cstring_Ptr := TSD (T).Expanded_Name;
begin
return Result (1 .. Length (Result));
end Expanded_Name;
@@ -261,7 +298,7 @@ package body Ada.Tags is
------------------
function External_Tag (T : Tag) return String is
- Result : constant Cstring_Ptr := T.TSD.External_Tag;
+ Result : constant Cstring_Ptr := TSD (T).External_Tag;
begin
return Result (1 .. Length (Result));
end External_Tag;
@@ -272,7 +309,7 @@ package body Ada.Tags is
function Get_Expanded_Name (T : Tag) return System.Address is
begin
- return To_Address (T.TSD.Expanded_Name);
+ return To_Address (TSD (T).Expanded_Name);
end Get_Expanded_Name;
----------------------
@@ -281,7 +318,7 @@ package body Ada.Tags is
function Get_External_Tag (T : Tag) return System.Address is
begin
- return To_Address (T.TSD.External_Tag);
+ return To_Address (TSD (T).External_Tag);
end Get_External_Tag;
---------------------------
@@ -290,7 +327,7 @@ package body Ada.Tags is
function Get_Inheritance_Depth (T : Tag) return Natural is
begin
- return T.TSD.Idepth;
+ return TSD (T).Idepth;
end Get_Inheritance_Depth;
-------------------------
@@ -311,7 +348,7 @@ package body Ada.Tags is
function Get_RC_Offset (T : Tag) return SSE.Storage_Offset is
begin
- return T.TSD.RC_Offset;
+ return TSD (T).RC_Offset;
end Get_RC_Offset;
---------------------------
@@ -320,7 +357,7 @@ package body Ada.Tags is
function Get_Remotely_Callable (T : Tag) return Boolean is
begin
- return T.TSD.Remotely_Callable = True;
+ return TSD (T).Remotely_Callable = True;
end Get_Remotely_Callable;
-------------
@@ -328,8 +365,11 @@ package body Ada.Tags is
-------------
function Get_TSD (T : Tag) return System.Address is
+ use type System.Storage_Elements.Storage_Offset;
+ TSD_Ptr : constant Addr_Ptr :=
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
begin
- return To_Address (T.TSD);
+ return TSD_Ptr.all;
end Get_TSD;
----------------
@@ -353,20 +393,21 @@ package body Ada.Tags is
-----------------
procedure Inherit_TSD (Old_TSD : System.Address; New_Tag : Tag) is
- TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (Old_TSD);
- New_TSD : Type_Specific_Data renames New_Tag.TSD.all;
+ Old_TSD_Ptr : constant Type_Specific_Data_Ptr :=
+ To_Type_Specific_Data_Ptr (Old_TSD);
+ New_TSD_Ptr : constant Type_Specific_Data_Ptr :=
+ TSD (New_Tag);
begin
- if TSD /= null then
- New_TSD.Idepth := TSD.Idepth + 1;
- New_TSD.Ancestor_Tags (1 .. New_TSD.Idepth)
- := TSD.Ancestor_Tags (0 .. TSD.Idepth);
+ if Old_TSD_Ptr /= null then
+ New_TSD_Ptr.Idepth := Old_TSD_Ptr.Idepth + 1;
+ New_TSD_Ptr.Ancestor_Tags (1 .. New_TSD_Ptr.Idepth) :=
+ Old_TSD_Ptr.Ancestor_Tags (0 .. Old_TSD_Ptr.Idepth);
else
- New_TSD.Idepth := 0;
+ New_TSD_Ptr.Idepth := 0;
end if;
- New_TSD.Ancestor_Tags (0) := New_Tag;
+ New_TSD_Ptr.Ancestor_Tags (0) := New_Tag;
end Inherit_TSD;
------------------
@@ -389,7 +430,6 @@ package body Ada.Tags is
declare
Msg1 : constant String := "unknown tagged type: ";
Msg2 : String (1 .. Msg1'Length + External'Length);
-
begin
Msg2 (1 .. Msg1'Length) := Msg1;
Msg2 (Msg1'Length + 1 .. Msg1'Length + External'Length) :=
@@ -430,7 +470,7 @@ package body Ada.Tags is
(Obj : System.Address;
T : Tag) return SSE.Storage_Count
is
- Parent_Tag : constant Tag := T.TSD.Ancestor_Tags (1);
+ Parent_Tag : constant Tag := TSD (T).Ancestor_Tags (1);
-- The tag of the parent type through the dispatch table
F : constant Acc_Size := To_Acc_Size (Parent_Tag.Prims_Ptr (1));
@@ -449,7 +489,7 @@ package body Ada.Tags is
function Parent_Tag (T : Tag) return Tag is
begin
- return T.TSD.Ancestor_Tags (1);
+ return TSD (T).Ancestor_Tags (1);
end Parent_Tag;
------------------
@@ -467,7 +507,7 @@ package body Ada.Tags is
procedure Set_Expanded_Name (T : Tag; Value : System.Address) is
begin
- T.TSD.Expanded_Name := To_Cstring_Ptr (Value);
+ TSD (T).Expanded_Name := To_Cstring_Ptr (Value);
end Set_Expanded_Name;
----------------------
@@ -476,7 +516,7 @@ package body Ada.Tags is
procedure Set_External_Tag (T : Tag; Value : System.Address) is
begin
- T.TSD.External_Tag := To_Cstring_Ptr (Value);
+ TSD (T).External_Tag := To_Cstring_Ptr (Value);
end Set_External_Tag;
---------------------------
@@ -488,7 +528,7 @@ package body Ada.Tags is
Value : Natural)
is
begin
- T.TSD.Idepth := Value;
+ TSD (T).Idepth := Value;
end Set_Inheritance_Depth;
-------------------------
@@ -510,7 +550,7 @@ package body Ada.Tags is
procedure Set_RC_Offset (T : Tag; Value : SSE.Storage_Offset) is
begin
- T.TSD.RC_Offset := Value;
+ TSD (T).RC_Offset := Value;
end Set_RC_Offset;
---------------------------
@@ -520,9 +560,9 @@ package body Ada.Tags is
procedure Set_Remotely_Callable (T : Tag; Value : Boolean) is
begin
if Value then
- T.TSD.Remotely_Callable := True;
+ TSD (T).Remotely_Callable := True;
else
- T.TSD.Remotely_Callable := False;
+ TSD (T).Remotely_Callable := False;
end if;
end Set_Remotely_Callable;
@@ -531,8 +571,44 @@ package body Ada.Tags is
-------------
procedure Set_TSD (T : Tag; Value : System.Address) is
+ use type System.Storage_Elements.Storage_Offset;
+ TSD_Ptr : constant Addr_Ptr :=
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
begin
- T.TSD := To_Type_Specific_Data_Ptr (Value);
+ TSD_Ptr.all := Value;
end Set_TSD;
+ -------------------
+ -- Offset_To_Top --
+ -------------------
+
+ function Offset_To_Top (T : Tag) return Integer is
+ use type System.Storage_Elements.Storage_Offset;
+ TSD_Ptr : constant Int_Ptr :=
+ To_Int_Ptr (To_Address (T) - DT_Prologue_Size);
+ begin
+ return TSD_Ptr.all;
+ end Offset_To_Top;
+
+ ------------------
+ -- Typeinfo_Ptr --
+ ------------------
+
+ function Typeinfo_Ptr (T : Tag) return System.Address is
+ use type System.Storage_Elements.Storage_Offset;
+ TSD_Ptr : constant Addr_Ptr :=
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ begin
+ return TSD_Ptr.all;
+ end Typeinfo_Ptr;
+
+ ---------
+ -- TSD --
+ ---------
+
+ function TSD (T : Tag) return Type_Specific_Data_Ptr is
+ begin
+ return To_Type_Specific_Data_Ptr (Get_TSD (T));
+ end TSD;
+
end Ada.Tags;