1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
9 -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
36 with System
.Storage_Elements
; use System
.Storage_Elements
;
37 with System
.WCh_Con
; use System
.WCh_Con
;
38 with System
.WCh_StW
; use System
.WCh_StW
;
40 pragma Elaborate_All
(System
.HTable
);
42 package body Ada
.Tags
is
44 -- Structure of the GNAT Primary Dispatch Table
46 -- +----------------------+
48 -- : predefined primitive :
50 -- +----------------------+
52 -- +----------------------+
54 -- +----------------------+
56 -- +----------------------+
57 -- | Typeinfo_Ptr/TSD_Ptr ---> Type Specific Data
58 -- Tag ---> +----------------------+ +-------------------+
59 -- | table of | | inheritance depth |
60 -- : primitive ops : +-------------------+
61 -- | pointers | | access level |
62 -- +----------------------+ +-------------------+
64 -- +-------------------+
66 -- +-------------------+
67 -- | hash table link |
68 -- +-------------------+
69 -- | remotely callable |
70 -- +-------------------+
71 -- | rec ctrler offset |
72 -- +-------------------+
74 -- +-------------------+
75 -- | Ifaces_Table_Ptr --> Interface Data
76 -- +-------------------+ +------------+
77 -- Select Specific Data <---- SSD_Ptr | | table |
78 -- +--------------------+ +-------------------+ : of :
79 -- | table of primitive | | table of | | interfaces |
80 -- : operation : : ancestor : +------------+
82 -- +--------------------+ +-------------------+
86 -- +--------------------+
88 -- Structure of the GNAT Secondary Dispatch Table
90 -- +-----------------------+
92 -- : predefined primitive :
94 -- +-----------------------+
96 -- +-----------------------+
98 -- +-----------------------+
100 -- +-----------------------+
101 -- | OSD_Ptr |---> Object Specific Data
102 -- Tag ---> +-----------------------+ +---------------+
103 -- | table of | | num prim ops |
104 -- : primitive op : +---------------+
105 -- | thunk pointers | | table of |
106 -- +-----------------------+ + primitive |
110 ----------------------------------
111 -- GNAT Dispatch Table Prologue --
112 ----------------------------------
114 -- GNAT's Dispatch Table prologue contains several fields which are hidden
115 -- in order to preserve compatibility with C++. These fields are accessed
116 -- by address calculations performed in the following manner:
118 -- Field : Field_Type :=
119 -- (To_Address (Tag) - Sum_Of_Preceding_Field_Sizes).all;
121 -- The bracketed subtraction shifts the pointer (Tag) from the table of
122 -- primitive operations (or thunks) to the field in question. Since the
123 -- result of the subtraction is an address, dereferencing it will obtain
124 -- the actual value of the field.
126 -- Guidelines for addition of new hidden fields
128 -- Define a Field_Type and Field_Type_Ptr (access to Field_Type) in
129 -- A-Tags.ads for the newly introduced field.
131 -- Defined the size of the new field as a constant Field_Name_Size
133 -- Introduce an Unchecked_Conversion from System.Address to
134 -- Field_Type_Ptr in A-Tags.ads.
136 -- Define the specifications of Get_<Field_Name> and Set_<Field_Name>
139 -- Update the GNAT Dispatch Table structure in a-tags.adb
141 -- Provide bodies to the Get_<Field_Name> and Set_<Field_Name> routines.
142 -- The profile of a Get_<Field_Name> routine should resemble:
144 -- function Get_<Field_Name> (T : Tag; ...) return Field_Type is
145 -- Field : constant System.Address :=
146 -- To_Address (T) - <Sum_Of_Previous_Field_Sizes>;
148 -- pragma Assert (Check_Signature (T, <Applicable_DT>));
149 -- <Additional_Assertions>
151 -- return To_Field_Type_Ptr (Field).all;
152 -- end Get_<Field_Name>;
154 -- The profile of a Set_<Field_Name> routine should resemble:
156 -- procedure Set_<Field_Name> (T : Tag; ..., Value : Field_Type) is
157 -- Field : constant System.Address :=
158 -- To_Address (T) - <Sum_Of_Previous_Field_Sizes>;
160 -- pragma Assert (Check_Signature (T, <Applicable_DT>));
161 -- <Additional_Assertions>
163 -- To_Field_Type_Ptr (Field).all := Value;
164 -- end Set_<Field_Name>;
166 -- NOTE: For each field in the prologue which precedes the newly added
167 -- one, find and update its respective Sum_Of_Previous_Field_Sizes by
168 -- subtractind Field_Name_Size from it. Falure to do so will clobber the
169 -- previous prologue field.
171 K_Typeinfo
: constant SSE
.Storage_Count
:= DT_Typeinfo_Ptr_Size
;
173 K_Offset_To_Top
: constant SSE
.Storage_Count
:=
174 K_Typeinfo
+ DT_Offset_To_Top_Size
;
176 K_Tagged_Kind
: constant SSE
.Storage_Count
:=
177 K_Offset_To_Top
+ DT_Tagged_Kind_Size
;
179 K_Signature
: constant SSE
.Storage_Count
:=
180 K_Tagged_Kind
+ DT_Signature_Size
;
182 subtype Cstring
is String (Positive);
183 type Cstring_Ptr
is access all Cstring
;
185 -- We suppress index checks because the declared size in the record below
186 -- is a dummy size of one (see below).
188 type Tag_Table
is array (Natural range <>) of Tag
;
189 pragma Suppress_Initialization
(Tag_Table
);
190 pragma Suppress
(Index_Check
, On
=> Tag_Table
);
192 -- Declarations for the table of interfaces
194 type Interface_Data_Element
is record
196 Static_Offset_To_Top
: Boolean;
197 Offset_To_Top_Value
: System
.Storage_Elements
.Storage_Offset
;
198 Offset_To_Top_Func
: System
.Address
;
200 -- If some ancestor of the tagged type has discriminants the field
201 -- Static_Offset_To_Top is False and the field Offset_To_Top_Func
202 -- is used to store the address of the function generated by the
203 -- expander which provides this value; otherwise Static_Offset_To_Top
204 -- is True and such value is stored in the Offset_To_Top_Value field.
206 type Interfaces_Array
is
207 array (Natural range <>) of Interface_Data_Element
;
209 type Interface_Data
(Nb_Ifaces
: Positive) is record
210 Table
: Interfaces_Array
(1 .. Nb_Ifaces
);
213 -- Object specific data types
215 type Object_Specific_Data_Array
is array (Positive range <>) of Positive;
217 type Object_Specific_Data
(Nb_Prim
: Positive) is record
218 Num_Prim_Ops
: Natural;
219 -- Number of primitive operations of the dispatch table. This field is
220 -- used by the run-time check routines that are activated when the
221 -- run-time is compiled with assertions enabled.
223 OSD_Table
: Object_Specific_Data_Array
(1 .. Nb_Prim
);
224 -- Table used in secondary DT to reference their counterpart in the
225 -- select specific data (in the TSD of the primary DT). This construct
226 -- is used in the handling of dispatching triggers in select statements.
227 -- Nb_Prim is the number of non-predefined primitive operations.
230 -- Select specific data types
232 type Select_Specific_Data_Element
is record
237 type Select_Specific_Data_Array
is
238 array (Positive range <>) of Select_Specific_Data_Element
;
240 type Select_Specific_Data
(Nb_Prim
: Positive) is record
241 SSD_Table
: Select_Specific_Data_Array
(1 .. Nb_Prim
);
242 -- NOTE: Nb_Prim is the number of non-predefined primitive operations
245 -- Type specific data types
247 type Type_Specific_Data
is record
249 -- Inheritance Depth Level: Used to implement the membership test
250 -- associated with single inheritance of tagged types in constant-time.
251 -- In addition it also indicates the size of the first table stored in
252 -- the Tags_Table component (see comment below).
254 Access_Level
: Natural;
255 -- Accessibility level required to give support to Ada 2005 nested type
256 -- extensions. This feature allows safe nested type extensions by
257 -- shifting the accessibility checks to certain operations, rather than
258 -- being enforced at the type declaration. In particular, by performing
259 -- run-time accessibility checks on class-wide allocators, class-wide
260 -- function return, and class-wide stream I/O, the danger of objects
261 -- outliving their type declaration can be eliminated (Ada 2005: AI-344)
263 Expanded_Name
: Cstring_Ptr
;
264 External_Tag
: Cstring_Ptr
;
266 -- Components used to give support to the Ada.Tags subprograms described
269 Remotely_Callable
: Boolean;
270 -- Used to check ARM E.4 (18)
272 RC_Offset
: SSE
.Storage_Offset
;
273 -- Controller Offset: Used to give support to tagged controlled objects
274 -- (see Get_Deep_Controller at s-finimp)
276 Ifaces_Table_Ptr
: System
.Address
;
277 -- Pointer to the table of interface tags. It is used to implement the
278 -- membership test associated with interfaces and also for backward
279 -- abstract interface type conversions (Ada 2005:AI-251)
281 Num_Prim_Ops
: Natural;
282 -- Number of primitive operations of the dispatch table. This field is
283 -- used for additional run-time checks when the run-time is compiled
284 -- with assertions enabled.
286 SSD_Ptr
: System
.Address
;
287 -- Pointer to a table of records used in dispatching selects. This
288 -- field has a meaningful value for all tagged types that implement
289 -- a limited, protected, synchronized or task interfaces and have
290 -- non-predefined primitive operations.
292 Tags_Table
: Tag_Table
(0 .. 1);
293 -- The size of the Tags_Table array actually depends on the tagged type
294 -- to which it applies. The compiler ensures that has enough space to
295 -- store all the entries of the two tables phisically stored there: the
296 -- "table of ancestor tags" and the "table of interface tags". For this
297 -- purpose we are using the same mechanism as for the Prims_Ptr array in
298 -- the Dispatch_Table record. See comments below on Prims_Ptr for
302 type Dispatch_Table
is record
304 -- According to the C++ ABI the components Offset_To_Top and
305 -- Typeinfo_Ptr are stored just "before" the dispatch table (that is,
306 -- the Prims_Ptr table), and they are referenced with negative offsets
307 -- referring to the base of the dispatch table. The _Tag (or the
308 -- VTable_Ptr in C++ terminology) must point to the base of the virtual
309 -- table, just after these components, to point to the Prims_Ptr table.
310 -- For this purpose the expander generates a Prims_Ptr table that has
311 -- enough space for these additional components, and generates code that
312 -- displaces the _Tag to point after these components.
314 -- Signature : Signature_Kind;
315 -- Tagged_Kind : Tagged_Kind;
316 -- Offset_To_Top : Natural;
317 -- Typeinfo_Ptr : System.Address;
319 Prims_Ptr
: Address_Array
(1 .. 1);
320 -- The size of the Prims_Ptr array actually depends on the tagged type
321 -- to which it applies. For each tagged type, the expander computes the
322 -- actual array size, allocates the Dispatch_Table record accordingly,
323 -- and generates code that displaces the base of the record after the
324 -- Typeinfo_Ptr component. For this reason the first two components have
325 -- been commented in the previous declaration. The access to these
326 -- components is done by means of local functions.
328 -- To avoid the use of discriminants to define the actual size of the
329 -- dispatch table, we used to declare the tag as a pointer to a record
330 -- that contains an arbitrary array of addresses, using Positive as its
331 -- index. This ensures that there are never range checks when accessing
332 -- the dispatch table, but it prevents GDB from displaying tagged types
333 -- properly. A better approach is to declare this record type as holding
334 -- small number of addresses, and to explicitly suppress checks on it.
336 -- Note that in both cases, this type is never allocated, and serves
337 -- only to declare the corresponding access type.
340 type Signature_Type
is
342 Must_Be_Secondary_DT
,
343 Must_Be_Primary_Or_Secondary_DT
,
345 Must_Be_Primary_Or_Interface
);
346 -- Type of signature accepted by primitives in this package that are called
347 -- during the elaboration of tagged types. This type is used by the routine
348 -- Check_Signature that is called only when the run-time is compiled with
349 -- assertions enabled.
351 ---------------------------------------------
352 -- Unchecked Conversions for String Fields --
353 ---------------------------------------------
355 function To_Address
is
356 new Unchecked_Conversion
(Cstring_Ptr
, System
.Address
);
358 function To_Cstring_Ptr
is
359 new Unchecked_Conversion
(System
.Address
, Cstring_Ptr
);
361 ------------------------------------------------
362 -- Unchecked Conversions for other components --
363 ------------------------------------------------
366 is access function (A
: System
.Address
) return Long_Long_Integer;
368 function To_Acc_Size
is new Unchecked_Conversion
(System
.Address
, Acc_Size
);
369 -- The profile of the implicitly defined _size primitive
371 type Offset_To_Top_Function_Ptr
is
372 access function (This
: System
.Address
)
373 return System
.Storage_Elements
.Storage_Offset
;
374 -- Type definition used to call the function that is generated by the
375 -- expander in case of tagged types with discriminants that have secondary
376 -- dispatch tables. This function provides the Offset_To_Top value in this
379 function To_Offset_To_Top_Function_Ptr
is
380 new Unchecked_Conversion
(System
.Address
, Offset_To_Top_Function_Ptr
);
382 type Storage_Offset_Ptr
is access System
.Storage_Elements
.Storage_Offset
;
384 function To_Storage_Offset_Ptr
is
385 new Unchecked_Conversion
(System
.Address
, Storage_Offset_Ptr
);
387 -----------------------
388 -- Local Subprograms --
389 -----------------------
391 function Check_Signature
(T
: Tag
; Kind
: Signature_Type
) return Boolean;
392 -- Check that the signature of T is valid and corresponds with the subset
393 -- specified by the signature Kind.
398 Entry_Count
: Natural) return Boolean;
399 -- Verify that Old_T and New_T have at least Entry_Count entries
401 function Get_Num_Prim_Ops
(T
: Tag
) return Natural;
402 -- Retrieve the number of primitive operations in the dispatch table of T
404 function Is_Primary_DT
(T
: Tag
) return Boolean;
405 pragma Inline_Always
(Is_Primary_DT
);
406 -- Given a tag returns True if it has the signature of a primary dispatch
407 -- table. This is Inline_Always since it is called from other Inline_
408 -- Always subprograms where we want no out of line code to be generated.
410 function Length
(Str
: Cstring_Ptr
) return Natural;
411 -- Length of string represented by the given pointer (treating the string
412 -- as a C-style string, which is Nul terminated).
414 function Typeinfo_Ptr
(T
: Tag
) return System
.Address
;
415 -- Returns the current value of the typeinfo_ptr component available in
416 -- the prologue of the dispatch table.
418 pragma Unreferenced
(Typeinfo_Ptr
);
419 -- These functions will be used for full compatibility with the C++ ABI
421 -------------------------
422 -- External_Tag_HTable --
423 -------------------------
425 type HTable_Headers
is range 1 .. 64;
427 -- The following internal package defines the routines used for the
428 -- instantiation of a new System.HTable.Static_HTable (see below). See
429 -- spec in g-htable.ads for details of usage.
431 package HTable_Subprograms
is
432 procedure Set_HT_Link
(T
: Tag
; Next
: Tag
);
433 function Get_HT_Link
(T
: Tag
) return Tag
;
434 function Hash
(F
: System
.Address
) return HTable_Headers
;
435 function Equal
(A
, B
: System
.Address
) return Boolean;
436 end HTable_Subprograms
;
438 package External_Tag_HTable
is new System
.HTable
.Static_HTable
(
439 Header_Num
=> HTable_Headers
,
440 Element
=> Dispatch_Table
,
443 Set_Next
=> HTable_Subprograms
.Set_HT_Link
,
444 Next
=> HTable_Subprograms
.Get_HT_Link
,
445 Key
=> System
.Address
,
446 Get_Key
=> Get_External_Tag
,
447 Hash
=> HTable_Subprograms
.Hash
,
448 Equal
=> HTable_Subprograms
.Equal
);
450 ------------------------
451 -- HTable_Subprograms --
452 ------------------------
454 -- Bodies of routines for hash table instantiation
456 package body HTable_Subprograms
is
462 function Equal
(A
, B
: System
.Address
) return Boolean is
463 Str1
: constant Cstring_Ptr
:= To_Cstring_Ptr
(A
);
464 Str2
: constant Cstring_Ptr
:= To_Cstring_Ptr
(B
);
468 if Str1
(J
) /= Str2
(J
) then
470 elsif Str1
(J
) = ASCII
.NUL
then
482 function Get_HT_Link
(T
: Tag
) return Tag
is
484 return TSD
(T
).HT_Link
;
491 function Hash
(F
: System
.Address
) return HTable_Headers
is
492 function H
is new System
.HTable
.Hash
(HTable_Headers
);
493 Str
: constant Cstring_Ptr
:= To_Cstring_Ptr
(F
);
494 Res
: constant HTable_Headers
:= H
(Str
(1 .. Length
(Str
)));
503 procedure Set_HT_Link
(T
: Tag
; Next
: Tag
) is
505 TSD
(T
).HT_Link
:= Next
;
508 end HTable_Subprograms
;
510 ---------------------
511 -- Check_Signature --
512 ---------------------
514 function Check_Signature
(T
: Tag
; Kind
: Signature_Type
) return Boolean is
515 Signature
: constant Storage_Offset_Ptr
:=
516 To_Storage_Offset_Ptr
(To_Address
(T
) - K_Signature
);
518 Sig_Values
: constant Signature_Values
:=
519 To_Signature_Values
(Signature
.all);
521 Signature_Id
: Signature_Kind
;
524 if Sig_Values
(1) /= Valid_Signature
then
525 Signature_Id
:= Unknown
;
527 elsif Sig_Values
(2) in Primary_DT
.. Abstract_Interface
then
528 Signature_Id
:= Sig_Values
(2);
531 Signature_Id
:= Unknown
;
536 if Kind
= Must_Be_Secondary_DT
537 or else Kind
= Must_Be_Interface
543 if Kind
= Must_Be_Primary_DT
544 or else Kind
= Must_Be_Interface
549 when Abstract_Interface
=>
550 if Kind
= Must_Be_Primary_DT
551 or else Kind
= Must_Be_Secondary_DT
552 or else Kind
= Must_Be_Primary_Or_Secondary_DT
572 Entry_Count
: Natural) return Boolean
574 Max_Entries_Old
: constant Natural := Get_Num_Prim_Ops
(Old_T
);
575 Max_Entries_New
: constant Natural := Get_Num_Prim_Ops
(New_T
);
578 return Entry_Count
<= Max_Entries_Old
579 and then Entry_Count
<= Max_Entries_New
;
586 -- Canonical implementation of Classwide Membership corresponding to:
590 -- Each dispatch table contains a reference to a table of ancestors (stored
591 -- in the first part of the Tags_Table) and a count of the level of
592 -- inheritance "Idepth".
594 -- Obj is in Typ'Class if Typ'Tag is in the table of ancestors that are
595 -- contained in the dispatch table referenced by Obj'Tag . Knowing the
596 -- level of inheritance of both types, this can be computed in constant
597 -- time by the formula:
599 -- Obj'tag.TSD.Ancestor_Tags (Obj'tag.TSD.Idepth - Typ'tag.TSD.Idepth)
602 function CW_Membership
(Obj_Tag
: Tag
; Typ_Tag
: Tag
) return Boolean is
605 pragma Assert
(Check_Signature
(Obj_Tag
, Must_Be_Primary_DT
));
606 pragma Assert
(Check_Signature
(Typ_Tag
, Must_Be_Primary_DT
));
607 Pos
:= TSD
(Obj_Tag
).Idepth
- TSD
(Typ_Tag
).Idepth
;
608 return Pos
>= 0 and then TSD
(Obj_Tag
).Tags_Table
(Pos
) = Typ_Tag
;
616 (This
: System
.Address
;
617 T
: Tag
) return System
.Address
619 Curr_DT
: constant Tag
:= To_Tag_Ptr
(This
).all;
620 Iface_Table
: Interface_Data_Ptr
;
621 Obj_Base
: System
.Address
;
623 Obj_TSD
: Type_Specific_Data_Ptr
;
627 (Check_Signature
(Curr_DT
, Must_Be_Primary_Or_Secondary_DT
));
629 (Check_Signature
(T
, Must_Be_Interface
));
631 Obj_Base
:= This
- Offset_To_Top
(This
);
632 Obj_DT
:= To_Tag_Ptr
(Obj_Base
).all;
635 (Check_Signature
(Obj_DT
, Must_Be_Primary_DT
));
637 Obj_TSD
:= TSD
(Obj_DT
);
638 Iface_Table
:= To_Interface_Data_Ptr
(Obj_TSD
.Ifaces_Table_Ptr
);
640 if Iface_Table
/= null then
641 for Id
in 1 .. Iface_Table
.Nb_Ifaces
loop
642 if Iface_Table
.Table
(Id
).Iface_Tag
= T
then
644 -- Case of Static value of Offset_To_Top
646 if Iface_Table
.Table
(Id
).Static_Offset_To_Top
then
648 Obj_Base
+ Iface_Table
.Table
(Id
).Offset_To_Top_Value
;
650 -- Otherwise we call the function generated by the expander
651 -- to provide us with this value
656 To_Offset_To_Top_Function_Ptr
657 (Iface_Table
.Table
(Id
).Offset_To_Top_Func
).all
661 Obj_DT
:= To_Tag_Ptr
(Obj_Base
).all;
664 (Check_Signature
(Obj_DT
, Must_Be_Secondary_DT
));
671 -- If the object does not implement the interface we must raise CE
673 raise Constraint_Error
;
680 -- Canonical implementation of Classwide Membership corresponding to:
682 -- Obj in Iface'Class
684 -- Each dispatch table contains a table with the tags of all the
685 -- implemented interfaces.
687 -- Obj is in Iface'Class if Iface'Tag is found in the table of interfaces
688 -- that are contained in the dispatch table referenced by Obj'Tag.
690 function IW_Membership
(This
: System
.Address
; T
: Tag
) return Boolean is
691 Curr_DT
: constant Tag
:= To_Tag_Ptr
(This
).all;
692 Iface_Table
: Interface_Data_Ptr
;
694 Obj_Base
: System
.Address
;
696 Obj_TSD
: Type_Specific_Data_Ptr
;
700 (Check_Signature
(Curr_DT
, Must_Be_Primary_Or_Secondary_DT
));
702 (Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
704 Obj_Base
:= This
- Offset_To_Top
(This
);
705 Obj_DT
:= To_Tag_Ptr
(Obj_Base
).all;
708 (Check_Signature
(Obj_DT
, Must_Be_Primary_DT
));
710 Obj_TSD
:= TSD
(Obj_DT
);
711 Last_Id
:= Obj_TSD
.Idepth
;
713 -- Look for the tag in the table of interfaces
715 Iface_Table
:= To_Interface_Data_Ptr
(Obj_TSD
.Ifaces_Table_Ptr
);
717 if Iface_Table
/= null then
718 for Id
in 1 .. Iface_Table
.Nb_Ifaces
loop
719 if Iface_Table
.Table
(Id
).Iface_Tag
= T
then
725 -- Look for the tag in the ancestor tags table. This is required for:
726 -- Iface_CW in Typ'Class
728 for Id
in 0 .. Last_Id
loop
729 if Obj_TSD
.Tags_Table
(Id
) = T
then
741 function Descendant_Tag
(External
: String; Ancestor
: Tag
) return Tag
is
745 pragma Assert
(Check_Signature
(Ancestor
, Must_Be_Primary_DT
));
746 Int_Tag
:= Internal_Tag
(External
);
747 pragma Assert
(Check_Signature
(Int_Tag
, Must_Be_Primary_DT
));
749 if not Is_Descendant_At_Same_Level
(Int_Tag
, Ancestor
) then
760 function Expanded_Name
(T
: Tag
) return String is
761 Result
: Cstring_Ptr
;
768 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
769 Result
:= TSD
(T
).Expanded_Name
;
770 return Result
(1 .. Length
(Result
));
777 function External_Tag
(T
: Tag
) return String is
778 Result
: Cstring_Ptr
;
785 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
786 Result
:= TSD
(T
).External_Tag
;
788 return Result
(1 .. Length
(Result
));
791 ----------------------
792 -- Get_Access_Level --
793 ----------------------
795 function Get_Access_Level
(T
: Tag
) return Natural is
797 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
798 return TSD
(T
).Access_Level
;
799 end Get_Access_Level
;
801 ---------------------
802 -- Get_Entry_Index --
803 ---------------------
805 function Get_Entry_Index
(T
: Tag
; Position
: Positive) return Positive is
807 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
808 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
809 return SSD
(T
).SSD_Table
(Position
).Index
;
812 ----------------------
813 -- Get_External_Tag --
814 ----------------------
816 function Get_External_Tag
(T
: Tag
) return System
.Address
is
818 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
819 return To_Address
(TSD
(T
).External_Tag
);
820 end Get_External_Tag
;
822 ----------------------
823 -- Get_Num_Prim_Ops --
824 ----------------------
826 function Get_Num_Prim_Ops
(T
: Tag
) return Natural is
828 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
830 if Is_Primary_DT
(T
) then
831 return TSD
(T
).Num_Prim_Ops
;
833 return OSD
(T
).Num_Prim_Ops
;
835 end Get_Num_Prim_Ops
;
837 --------------------------------
838 -- Get_Predef_Prim_Op_Address --
839 --------------------------------
841 function Get_Predefined_Prim_Op_Address
843 Position
: Positive) return System
.Address
845 Prim_Ops_DT
: constant Tag
:= To_Tag
(To_Address
(T
) - DT_Prologue_Size
);
847 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
848 pragma Assert
(Position
<= Default_Prim_Op_Count
);
849 return Prim_Ops_DT
.Prims_Ptr
(Position
);
850 end Get_Predefined_Prim_Op_Address
;
852 -------------------------
853 -- Get_Prim_Op_Address --
854 -------------------------
856 function Get_Prim_Op_Address
858 Position
: Positive) return System
.Address
861 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
862 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
863 return T
.Prims_Ptr
(Position
);
864 end Get_Prim_Op_Address
;
866 ----------------------
867 -- Get_Prim_Op_Kind --
868 ----------------------
870 function Get_Prim_Op_Kind
872 Position
: Positive) return Prim_Op_Kind
875 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
876 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
877 return SSD
(T
).SSD_Table
(Position
).Kind
;
878 end Get_Prim_Op_Kind
;
880 ----------------------
881 -- Get_Offset_Index --
882 ----------------------
884 function Get_Offset_Index
886 Position
: Positive) return Positive
889 pragma Assert
(Check_Signature
(T
, Must_Be_Secondary_DT
));
890 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
891 return OSD
(T
).OSD_Table
(Position
);
892 end Get_Offset_Index
;
898 function Get_RC_Offset
(T
: Tag
) return SSE
.Storage_Offset
is
900 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
901 return TSD
(T
).RC_Offset
;
904 ---------------------------
905 -- Get_Remotely_Callable --
906 ---------------------------
908 function Get_Remotely_Callable
(T
: Tag
) return Boolean is
910 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
911 return TSD
(T
).Remotely_Callable
;
912 end Get_Remotely_Callable
;
914 ---------------------
915 -- Get_Tagged_Kind --
916 ---------------------
918 function Get_Tagged_Kind
(T
: Tag
) return Tagged_Kind
is
919 Tagged_Kind_Ptr
: constant System
.Address
:=
920 To_Address
(T
) - K_Tagged_Kind
;
922 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
923 return To_Tagged_Kind_Ptr
(Tagged_Kind_Ptr
).all;
930 procedure Inherit_DT
(Old_T
: Tag
; New_T
: Tag
; Entry_Count
: Natural) is
931 Old_T_Prim_Ops
: Tag
;
932 New_T_Prim_Ops
: Tag
;
935 pragma Assert
(Check_Signature
(Old_T
, Must_Be_Primary_Or_Secondary_DT
));
936 pragma Assert
(Check_Signature
(New_T
, Must_Be_Primary_Or_Secondary_DT
));
937 pragma Assert
(Check_Size
(Old_T
, New_T
, Entry_Count
));
939 if Old_T
/= null then
940 New_T
.Prims_Ptr
(1 .. Entry_Count
) :=
941 Old_T
.Prims_Ptr
(1 .. Entry_Count
);
942 Old_T_Prim_Ops
:= To_Tag
(To_Address
(Old_T
) - DT_Prologue_Size
);
943 New_T_Prim_Ops
:= To_Tag
(To_Address
(New_T
) - DT_Prologue_Size
);
944 Size
:= Default_Prim_Op_Count
;
945 New_T_Prim_Ops
.Prims_Ptr
(1 .. Size
) :=
946 Old_T_Prim_Ops
.Prims_Ptr
(1 .. Size
);
954 procedure Inherit_TSD
(Old_Tag
: Tag
; New_Tag
: Tag
) is
955 New_TSD_Ptr
: Type_Specific_Data_Ptr
;
956 New_Iface_Table_Ptr
: Interface_Data_Ptr
;
957 Old_TSD_Ptr
: Type_Specific_Data_Ptr
;
958 Old_Iface_Table_Ptr
: Interface_Data_Ptr
;
961 pragma Assert
(Check_Signature
(New_Tag
, Must_Be_Primary_Or_Interface
));
962 New_TSD_Ptr
:= TSD
(New_Tag
);
964 if Old_Tag
/= null then
966 (Check_Signature
(Old_Tag
, Must_Be_Primary_Or_Interface
));
967 Old_TSD_Ptr
:= TSD
(Old_Tag
);
968 New_TSD_Ptr
.Idepth
:= Old_TSD_Ptr
.Idepth
+ 1;
970 -- Copy the "table of ancestor tags" plus the "table of interfaces"
973 New_TSD_Ptr
.Tags_Table
(1 .. New_TSD_Ptr
.Idepth
) :=
974 Old_TSD_Ptr
.Tags_Table
(0 .. Old_TSD_Ptr
.Idepth
);
976 -- Copy the table of interfaces of the parent
978 if not System
."=" (Old_TSD_Ptr
.Ifaces_Table_Ptr
,
981 Old_Iface_Table_Ptr
:=
982 To_Interface_Data_Ptr
(Old_TSD_Ptr
.Ifaces_Table_Ptr
);
983 New_Iface_Table_Ptr
:=
984 To_Interface_Data_Ptr
(New_TSD_Ptr
.Ifaces_Table_Ptr
);
986 New_Iface_Table_Ptr
.Table
(1 .. Old_Iface_Table_Ptr
.Nb_Ifaces
) :=
987 Old_Iface_Table_Ptr
.Table
(1 .. Old_Iface_Table_Ptr
.Nb_Ifaces
);
991 New_TSD_Ptr
.Idepth
:= 0;
994 New_TSD_Ptr
.Tags_Table
(0) := New_Tag
;
1001 function Internal_Tag
(External
: String) return Tag
is
1002 Ext_Copy
: aliased String (External
'First .. External
'Last + 1);
1006 -- Make a copy of the string representing the external tag with
1007 -- a null at the end.
1009 Ext_Copy
(External
'Range) := External
;
1010 Ext_Copy
(Ext_Copy
'Last) := ASCII
.NUL
;
1011 Res
:= External_Tag_HTable
.Get
(Ext_Copy
'Address);
1015 Msg1
: constant String := "unknown tagged type: ";
1016 Msg2
: String (1 .. Msg1
'Length + External
'Length);
1019 Msg2
(1 .. Msg1
'Length) := Msg1
;
1020 Msg2
(Msg1
'Length + 1 .. Msg1
'Length + External
'Length) :=
1022 Ada
.Exceptions
.Raise_Exception
(Tag_Error
'Identity, Msg2
);
1029 ---------------------------------
1030 -- Is_Descendant_At_Same_Level --
1031 ---------------------------------
1033 function Is_Descendant_At_Same_Level
1035 Ancestor
: Tag
) return Boolean
1038 return CW_Membership
(Descendant
, Ancestor
)
1039 and then TSD
(Descendant
).Access_Level
= TSD
(Ancestor
).Access_Level
;
1040 end Is_Descendant_At_Same_Level
;
1046 function Is_Primary_DT
(T
: Tag
) return Boolean is
1047 Signature
: constant Storage_Offset_Ptr
:=
1048 To_Storage_Offset_Ptr
(To_Address
(T
) - K_Signature
);
1049 Sig_Values
: constant Signature_Values
:=
1050 To_Signature_Values
(Signature
.all);
1052 return Sig_Values
(2) = Primary_DT
;
1059 function Length
(Str
: Cstring_Ptr
) return Natural is
1063 while Str
(Len
) /= ASCII
.Nul
loop
1074 function Offset_To_Top
1075 (This
: System
.Address
) return System
.Storage_Elements
.Storage_Offset
1077 Curr_DT
: constant Tag
:= To_Tag_Ptr
(This
).all;
1078 Offset_To_Top
: Storage_Offset_Ptr
;
1080 Offset_To_Top
:= To_Storage_Offset_Ptr
1081 (To_Address
(Curr_DT
) - K_Offset_To_Top
);
1083 if Offset_To_Top
.all = SSE
.Storage_Offset
'Last then
1084 Offset_To_Top
:= To_Storage_Offset_Ptr
(This
+ Tag_Size
);
1087 return Offset_To_Top
.all;
1094 function OSD
(T
: Tag
) return Object_Specific_Data_Ptr
is
1095 OSD_Ptr
: constant Addr_Ptr
:=
1096 To_Addr_Ptr
(To_Address
(T
) - K_Typeinfo
);
1098 pragma Assert
(Check_Signature
(T
, Must_Be_Secondary_DT
));
1099 return To_Object_Specific_Data_Ptr
(OSD_Ptr
.all);
1106 function Parent_Size
1107 (Obj
: System
.Address
;
1108 T
: Tag
) return SSE
.Storage_Count
1111 -- The tag of the parent type through the dispatch table
1114 -- The table of primitive operations of the parent
1117 -- Access to the _size primitive of the parent. We assume that it is
1118 -- always in the first slot of the dispatch table.
1121 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1122 Parent_Tag
:= TSD
(T
).Tags_Table
(1);
1123 Prim_Ops_DT
:= To_Tag
(To_Address
(Parent_Tag
) - DT_Prologue_Size
);
1124 F
:= To_Acc_Size
(Prim_Ops_DT
.Prims_Ptr
(1));
1126 -- Here we compute the size of the _parent field of the object
1128 return SSE
.Storage_Count
(F
.all (Obj
));
1135 function Parent_Tag
(T
: Tag
) return Tag
is
1141 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1143 -- The Parent_Tag of a root-level tagged type is defined to be No_Tag.
1144 -- The first entry in the Ancestors_Tags array will be null for such
1145 -- a type, but it's better to be explicit about returning No_Tag in
1148 if TSD
(T
).Idepth
= 0 then
1151 return TSD
(T
).Tags_Table
(1);
1155 ----------------------------
1156 -- Register_Interface_Tag --
1157 ----------------------------
1159 procedure Register_Interface_Tag
1162 Position
: Positive)
1164 New_T_TSD
: Type_Specific_Data_Ptr
;
1165 Iface_Table
: Interface_Data_Ptr
;
1168 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1169 pragma Assert
(Check_Signature
(Interface_T
, Must_Be_Interface
));
1171 New_T_TSD
:= TSD
(T
);
1172 Iface_Table
:= To_Interface_Data_Ptr
(New_T_TSD
.Ifaces_Table_Ptr
);
1174 pragma Assert
(Position
<= Iface_Table
.Nb_Ifaces
);
1176 Iface_Table
.Table
(Position
).Iface_Tag
:= Interface_T
;
1177 end Register_Interface_Tag
;
1183 procedure Register_Tag
(T
: Tag
) is
1185 External_Tag_HTable
.Set
(T
);
1188 ----------------------
1189 -- Set_Access_Level --
1190 ----------------------
1192 procedure Set_Access_Level
(T
: Tag
; Value
: Natural) is
1194 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1195 TSD
(T
).Access_Level
:= Value
;
1196 end Set_Access_Level
;
1198 ---------------------
1199 -- Set_Entry_Index --
1200 ---------------------
1202 procedure Set_Entry_Index
1204 Position
: Positive;
1208 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1209 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
1210 SSD
(T
).SSD_Table
(Position
).Index
:= Value
;
1211 end Set_Entry_Index
;
1213 -----------------------
1214 -- Set_Expanded_Name --
1215 -----------------------
1217 procedure Set_Expanded_Name
(T
: Tag
; Value
: System
.Address
) is
1220 (Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
1221 TSD
(T
).Expanded_Name
:= To_Cstring_Ptr
(Value
);
1222 end Set_Expanded_Name
;
1224 ----------------------
1225 -- Set_External_Tag --
1226 ----------------------
1228 procedure Set_External_Tag
(T
: Tag
; Value
: System
.Address
) is
1230 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
1231 TSD
(T
).External_Tag
:= To_Cstring_Ptr
(Value
);
1232 end Set_External_Tag
;
1234 -------------------------
1235 -- Set_Interface_Table --
1236 -------------------------
1238 procedure Set_Interface_Table
(T
: Tag
; Value
: System
.Address
) is
1240 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1241 TSD
(T
).Ifaces_Table_Ptr
:= Value
;
1242 end Set_Interface_Table
;
1244 ----------------------
1245 -- Set_Num_Prim_Ops --
1246 ----------------------
1248 procedure Set_Num_Prim_Ops
(T
: Tag
; Value
: Natural) is
1250 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
1252 if Is_Primary_DT
(T
) then
1253 TSD
(T
).Num_Prim_Ops
:= Value
;
1255 OSD
(T
).Num_Prim_Ops
:= Value
;
1257 end Set_Num_Prim_Ops
;
1259 ----------------------
1260 -- Set_Offset_Index --
1261 ----------------------
1263 procedure Set_Offset_Index
1265 Position
: Positive;
1269 pragma Assert
(Check_Signature
(T
, Must_Be_Secondary_DT
));
1270 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
1271 OSD
(T
).OSD_Table
(Position
) := Value
;
1272 end Set_Offset_Index
;
1274 -----------------------
1275 -- Set_Offset_To_Top --
1276 -----------------------
1278 procedure Set_Offset_To_Top
1279 (This
: System
.Address
;
1281 Is_Static
: Boolean;
1282 Offset_Value
: System
.Storage_Elements
.Storage_Offset
;
1283 Offset_Func
: System
.Address
)
1286 Sec_Base
: System
.Address
;
1288 Offset_To_Top
: Storage_Offset_Ptr
;
1289 Iface_Table
: Interface_Data_Ptr
;
1290 Obj_TSD
: Type_Specific_Data_Ptr
;
1292 if System
."=" (This
, System
.Null_Address
) then
1294 (Check_Signature
(Interface_T
, Must_Be_Primary_DT
));
1295 pragma Assert
(Offset_Value
= 0);
1298 To_Storage_Offset_Ptr
(To_Address
(Interface_T
) - K_Offset_To_Top
);
1299 Offset_To_Top
.all := Offset_Value
;
1303 -- "This" points to the primary DT and we must save Offset_Value in the
1304 -- Offset_To_Top field of the corresponding secondary dispatch table.
1306 Prim_DT
:= To_Tag_Ptr
(This
).all;
1309 (Check_Signature
(Prim_DT
, Must_Be_Primary_DT
));
1311 Sec_Base
:= This
+ Offset_Value
;
1312 Sec_DT
:= To_Tag_Ptr
(Sec_Base
).all;
1314 To_Storage_Offset_Ptr
(To_Address
(Sec_DT
) - K_Offset_To_Top
);
1317 (Check_Signature
(Sec_DT
, Must_Be_Secondary_DT
));
1320 Offset_To_Top
.all := Offset_Value
;
1322 Offset_To_Top
.all := SSE
.Storage_Offset
'Last;
1325 -- Save Offset_Value in the table of interfaces of the primary DT. This
1326 -- data will be used by the subprogram "Displace" to give support to
1327 -- backward abstract interface type conversions.
1329 Obj_TSD
:= TSD
(Prim_DT
);
1330 Iface_Table
:= To_Interface_Data_Ptr
(Obj_TSD
.Ifaces_Table_Ptr
);
1332 -- Register the offset in the table of interfaces
1334 if Iface_Table
/= null then
1335 for Id
in 1 .. Iface_Table
.Nb_Ifaces
loop
1336 if Iface_Table
.Table
(Id
).Iface_Tag
= Interface_T
then
1337 Iface_Table
.Table
(Id
).Static_Offset_To_Top
:= Is_Static
;
1340 Iface_Table
.Table
(Id
).Offset_To_Top_Value
:= Offset_Value
;
1342 Iface_Table
.Table
(Id
).Offset_To_Top_Func
:= Offset_Func
;
1350 -- If we arrive here there is some error in the run-time data structure
1352 raise Program_Error
;
1353 end Set_Offset_To_Top
;
1359 procedure Set_OSD
(T
: Tag
; Value
: System
.Address
) is
1360 OSD_Ptr
: constant Addr_Ptr
:=
1361 To_Addr_Ptr
(To_Address
(T
) - K_Typeinfo
);
1363 pragma Assert
(Check_Signature
(T
, Must_Be_Secondary_DT
));
1364 OSD_Ptr
.all := Value
;
1367 ------------------------------------
1368 -- Set_Predefined_Prim_Op_Address --
1369 ------------------------------------
1371 procedure Set_Predefined_Prim_Op_Address
1373 Position
: Positive;
1374 Value
: System
.Address
)
1376 Prim_Ops_DT
: constant Tag
:= To_Tag
(To_Address
(T
) - DT_Prologue_Size
);
1378 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
1379 pragma Assert
(Position
>= 1 and then Position
<= Default_Prim_Op_Count
);
1380 Prim_Ops_DT
.Prims_Ptr
(Position
) := Value
;
1381 end Set_Predefined_Prim_Op_Address
;
1383 -------------------------
1384 -- Set_Prim_Op_Address --
1385 -------------------------
1387 procedure Set_Prim_Op_Address
1389 Position
: Positive;
1390 Value
: System
.Address
)
1393 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
1394 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
1395 T
.Prims_Ptr
(Position
) := Value
;
1396 end Set_Prim_Op_Address
;
1398 ----------------------
1399 -- Set_Prim_Op_Kind --
1400 ----------------------
1402 procedure Set_Prim_Op_Kind
1404 Position
: Positive;
1405 Value
: Prim_Op_Kind
)
1408 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1409 pragma Assert
(Position
<= Get_Num_Prim_Ops
(T
));
1410 SSD
(T
).SSD_Table
(Position
).Kind
:= Value
;
1411 end Set_Prim_Op_Kind
;
1417 procedure Set_RC_Offset
(T
: Tag
; Value
: SSE
.Storage_Offset
) is
1419 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1420 TSD
(T
).RC_Offset
:= Value
;
1423 ---------------------------
1424 -- Set_Remotely_Callable --
1425 ---------------------------
1427 procedure Set_Remotely_Callable
(T
: Tag
; Value
: Boolean) is
1429 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1430 TSD
(T
).Remotely_Callable
:= Value
;
1431 end Set_Remotely_Callable
;
1437 procedure Set_Signature
(T
: Tag
; Value
: Signature_Kind
) is
1438 Signature
: constant System
.Address
:= To_Address
(T
) - K_Signature
;
1439 Sig_Ptr
: constant Signature_Values_Ptr
:=
1440 To_Signature_Values_Ptr
(Signature
);
1442 Sig_Ptr
.all (1) := Valid_Signature
;
1443 Sig_Ptr
.all (2) := Value
;
1450 procedure Set_SSD
(T
: Tag
; Value
: System
.Address
) is
1452 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1453 TSD
(T
).SSD_Ptr
:= Value
;
1456 ---------------------
1457 -- Set_Tagged_Kind --
1458 ---------------------
1460 procedure Set_Tagged_Kind
(T
: Tag
; Value
: Tagged_Kind
) is
1461 Tagged_Kind_Ptr
: constant System
.Address
:=
1462 To_Address
(T
) - K_Tagged_Kind
;
1464 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Secondary_DT
));
1465 To_Tagged_Kind_Ptr
(Tagged_Kind_Ptr
).all := Value
;
1466 end Set_Tagged_Kind
;
1472 procedure Set_TSD
(T
: Tag
; Value
: System
.Address
) is
1475 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
1476 TSD_Ptr
:= To_Addr_Ptr
(To_Address
(T
) - K_Typeinfo
);
1477 TSD_Ptr
.all := Value
;
1484 function SSD
(T
: Tag
) return Select_Specific_Data_Ptr
is
1486 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_DT
));
1487 return To_Select_Specific_Data_Ptr
(TSD
(T
).SSD_Ptr
);
1494 function Typeinfo_Ptr
(T
: Tag
) return System
.Address
is
1495 TSD_Ptr
: constant Addr_Ptr
:=
1496 To_Addr_Ptr
(To_Address
(T
) - K_Typeinfo
);
1505 function TSD
(T
: Tag
) return Type_Specific_Data_Ptr
is
1506 TSD_Ptr
: constant Addr_Ptr
:=
1507 To_Addr_Ptr
(To_Address
(T
) - K_Typeinfo
);
1509 pragma Assert
(Check_Signature
(T
, Must_Be_Primary_Or_Interface
));
1510 return To_Type_Specific_Data_Ptr
(TSD_Ptr
.all);
1513 ------------------------
1514 -- Wide_Expanded_Name --
1515 ------------------------
1517 WC_Encoding
: Character;
1518 pragma Import
(C
, WC_Encoding
, "__gl_wc_encoding");
1519 -- Encoding method for source, as exported by binder
1521 function Wide_Expanded_Name
(T
: Tag
) return Wide_String is
1523 return String_To_Wide_String
1524 (Expanded_Name
(T
), Get_WC_Encoding_Method
(WC_Encoding
));
1525 end Wide_Expanded_Name
;
1527 -----------------------------
1528 -- Wide_Wide_Expanded_Name --
1529 -----------------------------
1531 function Wide_Wide_Expanded_Name
(T
: Tag
) return Wide_Wide_String
is
1533 return String_To_Wide_Wide_String
1534 (Expanded_Name
(T
), Get_WC_Encoding_Method
(WC_Encoding
));
1535 end Wide_Wide_Expanded_Name
;