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))))));