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 Einfo; use Einfo;
27 with Elists; use Elists;
28 with Exp_Util; use Exp_Util;
29 with Namet; use Namet;
30 with Nlists; use Nlists;
31 with Nmake; use Nmake;
32 with Rtsfind; use Rtsfind;
33 with Sinfo; use Sinfo;
34 with Sem_Aux; use Sem_Aux;
35 with Sem_Util; use Sem_Util;
36 with Stand; use Stand;
37 with Snames; use Snames;
38 with Tbuild; use Tbuild;
40 package body Exp_Atag is
42 -----------------------
43 -- Local Subprograms --
44 -----------------------
48 Tag_Node : Node_Id) return Node_Id;
49 -- Build code that displaces the Tag to reference the base of the wrapper
53 -- To_Dispatch_Table_Ptr
54 -- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
56 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id;
57 -- Build code that retrieves the address of the record containing the Type
58 -- Specific Data generated by GNAT.
60 -- Generate: To_Type_Specific_Data_Ptr
61 -- (To_Addr_Ptr (To_Address (Tag) - Typeinfo_Offset).all);
63 ------------------------------------------------
64 -- Build_Common_Dispatching_Select_Statements --
65 ------------------------------------------------
67 procedure Build_Common_Dispatching_Select_Statements
74 -- C := get_prim_op_kind (tag! (<type>VP), S);
76 -- where C is the out parameter capturing the call kind and S is the
77 -- dispatch table slot number.
80 Make_Assignment_Statement (Loc,
82 Make_Identifier (Loc, Name_uC),
84 Make_Function_Call (Loc,
85 Name => New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
86 Parameter_Associations => New_List (
87 Unchecked_Convert_To (RTE (RE_Tag),
88 New_Reference_To (DT_Ptr, Loc)),
89 Make_Identifier (Loc, Name_uS)))));
93 -- if C = POK_Procedure
94 -- or else C = POK_Protected_Procedure
95 -- or else C = POK_Task_Procedure;
100 -- where F is the out parameter capturing the status of a potential
104 Make_If_Statement (Loc,
111 Make_Identifier (Loc, Name_uC),
113 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
119 Make_Identifier (Loc, Name_uC),
121 New_Reference_To (RTE (
122 RE_POK_Protected_Procedure), Loc)),
126 Make_Identifier (Loc, Name_uC),
128 New_Reference_To (RTE (
129 RE_POK_Task_Procedure), Loc)))),
133 Make_Assignment_Statement (Loc,
134 Name => Make_Identifier (Loc, Name_uF),
135 Expression => New_Reference_To (Standard_True, Loc)),
136 Make_Simple_Return_Statement (Loc))));
137 end Build_Common_Dispatching_Select_Statements;
139 -------------------------
140 -- Build_CW_Membership --
141 -------------------------
143 function Build_CW_Membership
145 Obj_Tag_Node : Node_Id;
146 Typ_Tag_Node : Node_Id) return Node_Id
148 function Build_Pos return Node_Id;
149 -- Generate TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
151 function Build_Pos return Node_Id is
154 Make_Op_Subtract (Loc,
156 Make_Selected_Component (Loc,
157 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
159 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
162 Make_Selected_Component (Loc,
163 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
165 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
168 -- Start of processing for Build_CW_Membership
175 Left_Opnd => Build_Pos,
176 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
181 Make_Indexed_Component (Loc,
183 Make_Selected_Component (Loc,
184 Prefix => Build_TSD (Loc, Obj_Tag_Node),
187 (RTE_Record_Component (RE_Tags_Table), Loc)),
189 New_List (Build_Pos)),
191 Right_Opnd => Typ_Tag_Node));
192 end Build_CW_Membership;
200 Tag_Node : Node_Id) return Node_Id is
203 Make_Function_Call (Loc,
204 Name => New_Reference_To (RTE (RE_DT), Loc),
205 Parameter_Associations => New_List (
206 Unchecked_Convert_To (RTE (RE_Tag), Tag_Node)));
209 ----------------------------
210 -- Build_Get_Access_Level --
211 ----------------------------
213 function Build_Get_Access_Level
215 Tag_Node : Node_Id) return Node_Id
219 Make_Selected_Component (Loc,
220 Prefix => Build_TSD (Loc, Tag_Node),
223 (RTE_Record_Component (RE_Access_Level), Loc));
224 end Build_Get_Access_Level;
226 ------------------------------------------
227 -- Build_Get_Predefined_Prim_Op_Address --
228 ------------------------------------------
230 procedure Build_Get_Predefined_Prim_Op_Address
233 Tag_Node : in out Node_Id;
234 New_Node : out Node_Id)
239 Ctrl_Tag := Unchecked_Convert_To (RTE (RE_Address), Tag_Node);
241 -- Unchecked_Convert_To relocates the controlling tag node and therefore
242 -- we must update it.
244 Tag_Node := Expression (Ctrl_Tag);
246 -- Build code that retrieves the address of the dispatch table
247 -- containing the predefined Ada primitives:
250 -- To_Predef_Prims_Table_Ptr
251 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
254 Make_Indexed_Component (Loc,
256 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
257 Make_Explicit_Dereference (Loc,
258 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
259 Make_Function_Call (Loc,
261 Make_Expanded_Name (Loc,
262 Chars => Name_Op_Subtract,
265 (RTU_Entity (System_Storage_Elements), Loc),
267 Make_Identifier (Loc,
268 Chars => Name_Op_Subtract)),
269 Parameter_Associations => New_List (
271 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
274 New_List (Make_Integer_Literal (Loc, Position)));
275 end Build_Get_Predefined_Prim_Op_Address;
277 -------------------------
278 -- Build_Inherit_Prims --
279 -------------------------
281 function Build_Inherit_Prims
284 Old_Tag_Node : Node_Id;
285 New_Tag_Node : Node_Id;
286 Num_Prims : Nat) return Node_Id
289 if RTE_Available (RE_DT) then
291 Make_Assignment_Statement (Loc,
295 Make_Selected_Component (Loc,
297 Build_DT (Loc, New_Tag_Node),
300 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
303 Low_Bound => Make_Integer_Literal (Loc, 1),
304 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
309 Make_Selected_Component (Loc,
311 Build_DT (Loc, Old_Tag_Node),
314 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
317 Low_Bound => Make_Integer_Literal (Loc, 1),
318 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
321 Make_Assignment_Statement (Loc,
326 (Node (Last_Elmt (Access_Disp_Table (Typ))),
330 Low_Bound => Make_Integer_Literal (Loc, 1),
331 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
337 (Node (Last_Elmt (Access_Disp_Table (Typ))),
341 Low_Bound => Make_Integer_Literal (Loc, 1),
342 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
344 end Build_Inherit_Prims;
346 -------------------------------
347 -- Build_Get_Prim_Op_Address --
348 -------------------------------
350 procedure Build_Get_Prim_Op_Address
354 Tag_Node : in out Node_Id;
355 New_Node : out Node_Id)
357 New_Prefix : Node_Id;
361 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
363 -- At the end of the Access_Disp_Table list we have the type
364 -- declaration required to convert the tag into a pointer to
365 -- the prims_ptr table (see Freeze_Record_Type).
369 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node);
371 -- Unchecked_Convert_To relocates the controlling tag node and therefore
372 -- we must update it.
374 Tag_Node := Expression (New_Prefix);
377 Make_Indexed_Component (Loc,
378 Prefix => New_Prefix,
379 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
380 end Build_Get_Prim_Op_Address;
382 -----------------------------
383 -- Build_Get_Transportable --
384 -----------------------------
386 function Build_Get_Transportable
388 Tag_Node : Node_Id) return Node_Id
392 Make_Selected_Component (Loc,
393 Prefix => Build_TSD (Loc, Tag_Node),
396 (RTE_Record_Component (RE_Transportable), Loc));
397 end Build_Get_Transportable;
399 ------------------------------------
400 -- Build_Inherit_Predefined_Prims --
401 ------------------------------------
403 function Build_Inherit_Predefined_Prims
405 Old_Tag_Node : Node_Id;
406 New_Tag_Node : Node_Id) return Node_Id
410 Make_Assignment_Statement (Loc,
414 Make_Explicit_Dereference (Loc,
415 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
416 Make_Explicit_Dereference (Loc,
417 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
419 Discrete_Range => Make_Range (Loc,
420 Make_Integer_Literal (Loc, Uint_1),
421 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
426 Make_Explicit_Dereference (Loc,
427 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
428 Make_Explicit_Dereference (Loc,
429 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
433 Make_Integer_Literal (Loc, 1),
434 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
435 end Build_Inherit_Predefined_Prims;
437 -------------------------
438 -- Build_Offset_To_Top --
439 -------------------------
441 function Build_Offset_To_Top
443 This_Node : Node_Id) return Node_Id
449 Make_Explicit_Dereference (Loc,
450 Unchecked_Convert_To (RTE (RE_Tag_Ptr), This_Node));
453 Make_Explicit_Dereference (Loc,
454 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
455 Make_Function_Call (Loc,
457 Make_Expanded_Name (Loc,
458 Chars => Name_Op_Subtract,
459 Prefix => New_Reference_To
460 (RTU_Entity (System_Storage_Elements), Loc),
461 Selector_Name => Make_Identifier (Loc,
462 Chars => Name_Op_Subtract)),
463 Parameter_Associations => New_List (
464 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
465 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
467 end Build_Offset_To_Top;
469 ------------------------------------------
470 -- Build_Set_Predefined_Prim_Op_Address --
471 ------------------------------------------
473 function Build_Set_Predefined_Prim_Op_Address
477 Address_Node : Node_Id) return Node_Id
481 Make_Assignment_Statement (Loc,
483 Make_Indexed_Component (Loc,
485 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
486 Make_Explicit_Dereference (Loc,
487 Unchecked_Convert_To (RTE (RE_Addr_Ptr), Tag_Node))),
489 New_List (Make_Integer_Literal (Loc, Position))),
491 Expression => Address_Node);
492 end Build_Set_Predefined_Prim_Op_Address;
494 -------------------------------
495 -- Build_Set_Prim_Op_Address --
496 -------------------------------
498 function Build_Set_Prim_Op_Address
503 Address_Node : Node_Id) return Node_Id
505 Ctrl_Tag : Node_Id := Tag_Node;
509 Build_Get_Prim_Op_Address (Loc, Typ, Position, Ctrl_Tag, New_Node);
512 Make_Assignment_Statement (Loc,
514 Expression => Address_Node);
515 end Build_Set_Prim_Op_Address;
517 -----------------------------
518 -- Build_Set_Size_Function --
519 -----------------------------
521 function Build_Set_Size_Function
524 Size_Func : Entity_Id) return Node_Id is
526 pragma Assert (Chars (Size_Func) = Name_uSize
527 and then RTE_Record_Component_Available (RE_Size_Func));
529 Make_Assignment_Statement (Loc,
531 Make_Selected_Component (Loc,
532 Prefix => Build_TSD (Loc, Tag_Node),
535 (RTE_Record_Component (RE_Size_Func), Loc)),
537 Unchecked_Convert_To (RTE (RE_Size_Ptr),
538 Make_Attribute_Reference (Loc,
539 Prefix => New_Reference_To (Size_Func, Loc),
540 Attribute_Name => Name_Unrestricted_Access)));
541 end Build_Set_Size_Function;
543 ------------------------------------
544 -- Build_Set_Static_Offset_To_Top --
545 ------------------------------------
547 function Build_Set_Static_Offset_To_Top
550 Offset_Value : Node_Id) return Node_Id is
553 Make_Assignment_Statement (Loc,
554 Make_Explicit_Dereference (Loc,
555 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
556 Make_Function_Call (Loc,
558 Make_Expanded_Name (Loc,
559 Chars => Name_Op_Subtract,
560 Prefix => New_Reference_To
561 (RTU_Entity (System_Storage_Elements), Loc),
562 Selector_Name => Make_Identifier (Loc,
563 Chars => Name_Op_Subtract)),
564 Parameter_Associations => New_List (
565 Unchecked_Convert_To (RTE (RE_Address), Iface_Tag),
566 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
569 end Build_Set_Static_Offset_To_Top;
575 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
578 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
579 Make_Explicit_Dereference (Loc,
580 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
581 Make_Function_Call (Loc,
583 Make_Expanded_Name (Loc,
584 Chars => Name_Op_Subtract,
587 (RTU_Entity (System_Storage_Elements), Loc),
589 Make_Identifier (Loc,
590 Chars => Name_Op_Subtract)),
592 Parameter_Associations => New_List (
593 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
595 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));