1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2006-2009, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree
; use Atree
;
27 with Einfo
; use Einfo
;
28 with Elists
; use Elists
;
29 with Exp_Util
; use Exp_Util
;
30 with Namet
; use Namet
;
31 with Nlists
; use Nlists
;
32 with Nmake
; use Nmake
;
33 with Rtsfind
; use Rtsfind
;
34 with Sinfo
; use Sinfo
;
35 with Sem_Aux
; use Sem_Aux
;
36 with Sem_Util
; use Sem_Util
;
37 with Stand
; use Stand
;
38 with Snames
; use Snames
;
39 with Tbuild
; use Tbuild
;
41 package body Exp_Atag
is
43 -----------------------
44 -- Local Subprograms --
45 -----------------------
49 Tag_Node
: Node_Id
) return Node_Id
;
50 -- Build code that displaces the Tag to reference the base of the wrapper
54 -- To_Dispatch_Table_Ptr
55 -- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
59 Tag_Node_Addr
: Node_Id
) return Node_Id
;
60 -- Build code that retrieves the address of the record containing the Type
61 -- Specific Data generated by GNAT.
63 -- Generate: To_Type_Specific_Data_Ptr
64 -- (To_Addr_Ptr (Tag_Node_Addr - Typeinfo_Offset).all);
66 ------------------------------------------------
67 -- Build_Common_Dispatching_Select_Statements --
68 ------------------------------------------------
70 procedure Build_Common_Dispatching_Select_Statements
77 -- C := get_prim_op_kind (tag! (<type>VP), S);
79 -- where C is the out parameter capturing the call kind and S is the
80 -- dispatch table slot number.
83 Make_Assignment_Statement
(Loc
,
85 Make_Identifier
(Loc
, Name_uC
),
87 Make_Function_Call
(Loc
,
88 Name
=> New_Occurrence_Of
(RTE
(RE_Get_Prim_Op_Kind
), Loc
),
89 Parameter_Associations
=> New_List
(
90 Unchecked_Convert_To
(RTE
(RE_Tag
),
91 New_Reference_To
(DT_Ptr
, Loc
)),
92 Make_Identifier
(Loc
, Name_uS
)))));
96 -- if C = POK_Procedure
97 -- or else C = POK_Protected_Procedure
98 -- or else C = POK_Task_Procedure;
103 -- where F is the out parameter capturing the status of a potential
107 Make_If_Statement
(Loc
,
114 Make_Identifier
(Loc
, Name_uC
),
116 New_Reference_To
(RTE
(RE_POK_Procedure
), Loc
)),
122 Make_Identifier
(Loc
, Name_uC
),
124 New_Reference_To
(RTE
(
125 RE_POK_Protected_Procedure
), Loc
)),
129 Make_Identifier
(Loc
, Name_uC
),
131 New_Reference_To
(RTE
(
132 RE_POK_Task_Procedure
), Loc
)))),
136 Make_Assignment_Statement
(Loc
,
137 Name
=> Make_Identifier
(Loc
, Name_uF
),
138 Expression
=> New_Reference_To
(Standard_True
, Loc
)),
139 Make_Simple_Return_Statement
(Loc
))));
140 end Build_Common_Dispatching_Select_Statements
;
142 -------------------------
143 -- Build_CW_Membership --
144 -------------------------
146 procedure Build_CW_Membership
148 Obj_Tag_Node
: in out Node_Id
;
149 Typ_Tag_Node
: Node_Id
;
150 Related_Nod
: Node_Id
;
151 New_Node
: out Node_Id
)
153 Tag_Addr
: constant Entity_Id
:= Make_Temporary
(Loc
, 'D', Obj_Tag_Node
);
154 Obj_TSD
: constant Entity_Id
:= Make_Temporary
(Loc
, 'D');
155 Typ_TSD
: constant Entity_Id
:= Make_Temporary
(Loc
, 'D');
156 Index
: constant Entity_Id
:= Make_Temporary
(Loc
, 'D');
161 -- Tag_Addr : constant Tag := Address!(Obj_Tag);
162 -- Obj_TSD : constant Type_Specific_Data_Ptr
163 -- := Build_TSD (Tag_Addr);
164 -- Typ_TSD : constant Type_Specific_Data_Ptr
165 -- := Build_TSD (Address!(Typ_Tag));
166 -- Index : constant Integer := Obj_TSD.Idepth - Typ_TSD.Idepth
167 -- Index > 0 and then Obj_TSD.Tags_Table (Index) = Typ'Tag
169 Insert_Action
(Related_Nod
,
170 Make_Object_Declaration
(Loc
,
171 Defining_Identifier
=> Tag_Addr
,
172 Constant_Present
=> True,
173 Object_Definition
=> New_Reference_To
(RTE
(RE_Address
), Loc
),
174 Expression
=> Unchecked_Convert_To
175 (RTE
(RE_Address
), Obj_Tag_Node
)));
177 -- Unchecked_Convert_To relocates Obj_Tag_Node and therefore we must
180 Obj_Tag_Node
:= Expression
(Expression
(Parent
(Tag_Addr
)));
182 Insert_Action
(Related_Nod
,
183 Make_Object_Declaration
(Loc
,
184 Defining_Identifier
=> Obj_TSD
,
185 Constant_Present
=> True,
186 Object_Definition
=> New_Reference_To
187 (RTE
(RE_Type_Specific_Data_Ptr
), Loc
),
188 Expression
=> Build_TSD
(Loc
, New_Reference_To
(Tag_Addr
, Loc
))));
190 Insert_Action
(Related_Nod
,
191 Make_Object_Declaration
(Loc
,
192 Defining_Identifier
=> Typ_TSD
,
193 Constant_Present
=> True,
194 Object_Definition
=> New_Reference_To
195 (RTE
(RE_Type_Specific_Data_Ptr
), Loc
),
196 Expression
=> Build_TSD
(Loc
,
197 Unchecked_Convert_To
(RTE
(RE_Address
),
200 Insert_Action
(Related_Nod
,
201 Make_Object_Declaration
(Loc
,
202 Defining_Identifier
=> Index
,
203 Constant_Present
=> True,
204 Object_Definition
=> New_Occurrence_Of
(Standard_Integer
, Loc
),
206 Make_Op_Subtract
(Loc
,
208 Make_Selected_Component
(Loc
,
209 Prefix
=> New_Reference_To
(Obj_TSD
, Loc
),
212 (RTE_Record_Component
(RE_Idepth
), Loc
)),
215 Make_Selected_Component
(Loc
,
216 Prefix
=> New_Reference_To
(Typ_TSD
, Loc
),
219 (RTE_Record_Component
(RE_Idepth
), Loc
)))));
225 Left_Opnd
=> New_Occurrence_Of
(Index
, Loc
),
226 Right_Opnd
=> Make_Integer_Literal
(Loc
, Uint_0
)),
231 Make_Indexed_Component
(Loc
,
233 Make_Selected_Component
(Loc
,
234 Prefix
=> New_Reference_To
(Obj_TSD
, Loc
),
237 (RTE_Record_Component
(RE_Tags_Table
), Loc
)),
239 New_List
(New_Occurrence_Of
(Index
, Loc
))),
241 Right_Opnd
=> Typ_Tag_Node
));
242 end Build_CW_Membership
;
250 Tag_Node
: Node_Id
) return Node_Id
254 Make_Function_Call
(Loc
,
255 Name
=> New_Reference_To
(RTE
(RE_DT
), Loc
),
256 Parameter_Associations
=> New_List
(
257 Unchecked_Convert_To
(RTE
(RE_Tag
), Tag_Node
)));
260 ----------------------------
261 -- Build_Get_Access_Level --
262 ----------------------------
264 function Build_Get_Access_Level
266 Tag_Node
: Node_Id
) return Node_Id
270 Make_Selected_Component
(Loc
,
273 Unchecked_Convert_To
(RTE
(RE_Address
), Tag_Node
)),
276 (RTE_Record_Component
(RE_Access_Level
), Loc
));
277 end Build_Get_Access_Level
;
279 ------------------------------------------
280 -- Build_Get_Predefined_Prim_Op_Address --
281 ------------------------------------------
283 procedure Build_Get_Predefined_Prim_Op_Address
286 Tag_Node
: in out Node_Id
;
287 New_Node
: out Node_Id
)
292 Ctrl_Tag
:= Unchecked_Convert_To
(RTE
(RE_Address
), Tag_Node
);
294 -- Unchecked_Convert_To relocates the controlling tag node and therefore
295 -- we must update it.
297 Tag_Node
:= Expression
(Ctrl_Tag
);
299 -- Build code that retrieves the address of the dispatch table
300 -- containing the predefined Ada primitives:
303 -- To_Predef_Prims_Table_Ptr
304 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
307 Make_Indexed_Component
(Loc
,
309 Unchecked_Convert_To
(RTE
(RE_Predef_Prims_Table_Ptr
),
310 Make_Explicit_Dereference
(Loc
,
311 Unchecked_Convert_To
(RTE
(RE_Addr_Ptr
),
312 Make_Function_Call
(Loc
,
314 Make_Expanded_Name
(Loc
,
315 Chars
=> Name_Op_Subtract
,
318 (RTU_Entity
(System_Storage_Elements
), Loc
),
320 Make_Identifier
(Loc
,
321 Chars
=> Name_Op_Subtract
)),
322 Parameter_Associations
=> New_List
(
324 New_Reference_To
(RTE
(RE_DT_Predef_Prims_Offset
),
327 New_List
(Make_Integer_Literal
(Loc
, Position
)));
328 end Build_Get_Predefined_Prim_Op_Address
;
330 -------------------------
331 -- Build_Inherit_Prims --
332 -------------------------
334 function Build_Inherit_Prims
337 Old_Tag_Node
: Node_Id
;
338 New_Tag_Node
: Node_Id
;
339 Num_Prims
: Nat
) return Node_Id
342 if RTE_Available
(RE_DT
) then
344 Make_Assignment_Statement
(Loc
,
348 Make_Selected_Component
(Loc
,
350 Build_DT
(Loc
, New_Tag_Node
),
353 (RTE_Record_Component
(RE_Prims_Ptr
), Loc
)),
356 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
357 High_Bound
=> Make_Integer_Literal
(Loc
, Num_Prims
))),
362 Make_Selected_Component
(Loc
,
364 Build_DT
(Loc
, Old_Tag_Node
),
367 (RTE_Record_Component
(RE_Prims_Ptr
), Loc
)),
370 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
371 High_Bound
=> Make_Integer_Literal
(Loc
, Num_Prims
))));
374 Make_Assignment_Statement
(Loc
,
379 (Node
(Last_Elmt
(Access_Disp_Table
(Typ
))),
383 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
384 High_Bound
=> Make_Integer_Literal
(Loc
, Num_Prims
))),
390 (Node
(Last_Elmt
(Access_Disp_Table
(Typ
))),
394 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
395 High_Bound
=> Make_Integer_Literal
(Loc
, Num_Prims
))));
397 end Build_Inherit_Prims
;
399 -------------------------------
400 -- Build_Get_Prim_Op_Address --
401 -------------------------------
403 procedure Build_Get_Prim_Op_Address
407 Tag_Node
: in out Node_Id
;
408 New_Node
: out Node_Id
)
410 New_Prefix
: Node_Id
;
414 (Position
<= DT_Entry_Count
(First_Tag_Component
(Typ
)));
416 -- At the end of the Access_Disp_Table list we have the type
417 -- declaration required to convert the tag into a pointer to
418 -- the prims_ptr table (see Freeze_Record_Type).
422 (Node
(Last_Elmt
(Access_Disp_Table
(Typ
))), Tag_Node
);
424 -- Unchecked_Convert_To relocates the controlling tag node and therefore
425 -- we must update it.
427 Tag_Node
:= Expression
(New_Prefix
);
430 Make_Indexed_Component
(Loc
,
431 Prefix
=> New_Prefix
,
432 Expressions
=> New_List
(Make_Integer_Literal
(Loc
, Position
)));
433 end Build_Get_Prim_Op_Address
;
435 -----------------------------
436 -- Build_Get_Transportable --
437 -----------------------------
439 function Build_Get_Transportable
441 Tag_Node
: Node_Id
) return Node_Id
445 Make_Selected_Component
(Loc
,
448 Unchecked_Convert_To
(RTE
(RE_Address
), Tag_Node
)),
451 (RTE_Record_Component
(RE_Transportable
), Loc
));
452 end Build_Get_Transportable
;
454 ------------------------------------
455 -- Build_Inherit_Predefined_Prims --
456 ------------------------------------
458 function Build_Inherit_Predefined_Prims
460 Old_Tag_Node
: Node_Id
;
461 New_Tag_Node
: Node_Id
) return Node_Id
465 Make_Assignment_Statement
(Loc
,
469 Make_Explicit_Dereference
(Loc
,
470 Unchecked_Convert_To
(RTE
(RE_Predef_Prims_Table_Ptr
),
471 Make_Explicit_Dereference
(Loc
,
472 Unchecked_Convert_To
(RTE
(RE_Addr_Ptr
),
474 Discrete_Range
=> Make_Range
(Loc
,
475 Make_Integer_Literal
(Loc
, Uint_1
),
476 New_Reference_To
(RTE
(RE_Max_Predef_Prims
), Loc
))),
481 Make_Explicit_Dereference
(Loc
,
482 Unchecked_Convert_To
(RTE
(RE_Predef_Prims_Table_Ptr
),
483 Make_Explicit_Dereference
(Loc
,
484 Unchecked_Convert_To
(RTE
(RE_Addr_Ptr
),
488 Make_Integer_Literal
(Loc
, 1),
489 New_Reference_To
(RTE
(RE_Max_Predef_Prims
), Loc
))));
490 end Build_Inherit_Predefined_Prims
;
492 -------------------------
493 -- Build_Offset_To_Top --
494 -------------------------
496 function Build_Offset_To_Top
498 This_Node
: Node_Id
) return Node_Id
504 Make_Explicit_Dereference
(Loc
,
505 Unchecked_Convert_To
(RTE
(RE_Tag_Ptr
), This_Node
));
508 Make_Explicit_Dereference
(Loc
,
509 Unchecked_Convert_To
(RTE
(RE_Offset_To_Top_Ptr
),
510 Make_Function_Call
(Loc
,
512 Make_Expanded_Name
(Loc
,
513 Chars
=> Name_Op_Subtract
,
514 Prefix
=> New_Reference_To
515 (RTU_Entity
(System_Storage_Elements
), Loc
),
516 Selector_Name
=> Make_Identifier
(Loc
,
517 Chars
=> Name_Op_Subtract
)),
518 Parameter_Associations
=> New_List
(
519 Unchecked_Convert_To
(RTE
(RE_Address
), Tag_Node
),
520 New_Reference_To
(RTE
(RE_DT_Offset_To_Top_Offset
),
522 end Build_Offset_To_Top
;
524 ------------------------------------------
525 -- Build_Set_Predefined_Prim_Op_Address --
526 ------------------------------------------
528 function Build_Set_Predefined_Prim_Op_Address
532 Address_Node
: Node_Id
) return Node_Id
536 Make_Assignment_Statement
(Loc
,
538 Make_Indexed_Component
(Loc
,
540 Unchecked_Convert_To
(RTE
(RE_Predef_Prims_Table_Ptr
),
541 Make_Explicit_Dereference
(Loc
,
542 Unchecked_Convert_To
(RTE
(RE_Addr_Ptr
), Tag_Node
))),
544 New_List
(Make_Integer_Literal
(Loc
, Position
))),
546 Expression
=> Address_Node
);
547 end Build_Set_Predefined_Prim_Op_Address
;
549 -------------------------------
550 -- Build_Set_Prim_Op_Address --
551 -------------------------------
553 function Build_Set_Prim_Op_Address
558 Address_Node
: Node_Id
) return Node_Id
560 Ctrl_Tag
: Node_Id
:= Tag_Node
;
564 Build_Get_Prim_Op_Address
(Loc
, Typ
, Position
, Ctrl_Tag
, New_Node
);
567 Make_Assignment_Statement
(Loc
,
569 Expression
=> Address_Node
);
570 end Build_Set_Prim_Op_Address
;
572 -----------------------------
573 -- Build_Set_Size_Function --
574 -----------------------------
576 function Build_Set_Size_Function
579 Size_Func
: Entity_Id
) return Node_Id
is
581 pragma Assert
(Chars
(Size_Func
) = Name_uSize
582 and then RTE_Record_Component_Available
(RE_Size_Func
));
584 Make_Assignment_Statement
(Loc
,
586 Make_Selected_Component
(Loc
,
589 Unchecked_Convert_To
(RTE
(RE_Address
), Tag_Node
)),
592 (RTE_Record_Component
(RE_Size_Func
), Loc
)),
594 Unchecked_Convert_To
(RTE
(RE_Size_Ptr
),
595 Make_Attribute_Reference
(Loc
,
596 Prefix
=> New_Reference_To
(Size_Func
, Loc
),
597 Attribute_Name
=> Name_Unrestricted_Access
)));
598 end Build_Set_Size_Function
;
600 ------------------------------------
601 -- Build_Set_Static_Offset_To_Top --
602 ------------------------------------
604 function Build_Set_Static_Offset_To_Top
607 Offset_Value
: Node_Id
) return Node_Id
is
610 Make_Assignment_Statement
(Loc
,
611 Make_Explicit_Dereference
(Loc
,
612 Unchecked_Convert_To
(RTE
(RE_Offset_To_Top_Ptr
),
613 Make_Function_Call
(Loc
,
615 Make_Expanded_Name
(Loc
,
616 Chars
=> Name_Op_Subtract
,
617 Prefix
=> New_Reference_To
618 (RTU_Entity
(System_Storage_Elements
), Loc
),
619 Selector_Name
=> Make_Identifier
(Loc
,
620 Chars
=> Name_Op_Subtract
)),
621 Parameter_Associations
=> New_List
(
622 Unchecked_Convert_To
(RTE
(RE_Address
), Iface_Tag
),
623 New_Reference_To
(RTE
(RE_DT_Offset_To_Top_Offset
),
626 end Build_Set_Static_Offset_To_Top
;
634 Tag_Node_Addr
: Node_Id
) return Node_Id
is
637 Unchecked_Convert_To
(RTE
(RE_Type_Specific_Data_Ptr
),
638 Make_Explicit_Dereference
(Loc
,
639 Prefix
=> Unchecked_Convert_To
(RTE
(RE_Addr_Ptr
),
640 Make_Function_Call
(Loc
,
642 Make_Expanded_Name
(Loc
,
643 Chars
=> Name_Op_Subtract
,
646 (RTU_Entity
(System_Storage_Elements
), Loc
),
648 Make_Identifier
(Loc
,
649 Chars
=> Name_Op_Subtract
)),
651 Parameter_Associations
=> New_List
(
654 (RTE
(RE_DT_Typeinfo_Ptr_Size
), Loc
))))));