1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2006-2008, 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_Util; use Sem_Util;
35 with Stand; use Stand;
36 with Snames; use Snames;
37 with Tbuild; use Tbuild;
39 package body Exp_Atag is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
47 Tag_Node : Node_Id) return Node_Id;
48 -- Build code that displaces the Tag to reference the base of the wrapper
52 -- To_Dispatch_Table_Ptr
53 -- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
55 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id;
56 -- Build code that retrieves the address of the record containing the Type
57 -- Specific Data generated by GNAT.
59 -- Generate: To_Type_Specific_Data_Ptr
60 -- (To_Addr_Ptr (To_Address (Tag) - Typeinfo_Offset).all);
62 ------------------------------------------------
63 -- Build_Common_Dispatching_Select_Statements --
64 ------------------------------------------------
66 procedure Build_Common_Dispatching_Select_Statements
73 -- C := get_prim_op_kind (tag! (<type>VP), S);
75 -- where C is the out parameter capturing the call kind and S is the
76 -- dispatch table slot number.
79 Make_Assignment_Statement (Loc,
81 Make_Identifier (Loc, Name_uC),
83 Make_Function_Call (Loc,
84 Name => New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
85 Parameter_Associations => New_List (
86 Unchecked_Convert_To (RTE (RE_Tag),
87 New_Reference_To (DT_Ptr, Loc)),
88 Make_Identifier (Loc, Name_uS)))));
92 -- if C = POK_Procedure
93 -- or else C = POK_Protected_Procedure
94 -- or else C = POK_Task_Procedure;
99 -- where F is the out parameter capturing the status of a potential
103 Make_If_Statement (Loc,
110 Make_Identifier (Loc, Name_uC),
112 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
118 Make_Identifier (Loc, Name_uC),
120 New_Reference_To (RTE (
121 RE_POK_Protected_Procedure), Loc)),
125 Make_Identifier (Loc, Name_uC),
127 New_Reference_To (RTE (
128 RE_POK_Task_Procedure), Loc)))),
132 Make_Assignment_Statement (Loc,
133 Name => Make_Identifier (Loc, Name_uF),
134 Expression => New_Reference_To (Standard_True, Loc)),
135 Make_Simple_Return_Statement (Loc))));
136 end Build_Common_Dispatching_Select_Statements;
138 -------------------------
139 -- Build_CW_Membership --
140 -------------------------
142 function Build_CW_Membership
144 Obj_Tag_Node : Node_Id;
145 Typ_Tag_Node : Node_Id) return Node_Id
147 function Build_Pos return Node_Id;
148 -- Generate TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
150 function Build_Pos return Node_Id is
153 Make_Op_Subtract (Loc,
155 Make_Selected_Component (Loc,
156 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
158 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
161 Make_Selected_Component (Loc,
162 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
164 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
167 -- Start of processing for Build_CW_Membership
174 Left_Opnd => Build_Pos,
175 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
180 Make_Indexed_Component (Loc,
182 Make_Selected_Component (Loc,
183 Prefix => Build_TSD (Loc, Obj_Tag_Node),
186 (RTE_Record_Component (RE_Tags_Table), Loc)),
188 New_List (Build_Pos)),
190 Right_Opnd => Typ_Tag_Node));
191 end Build_CW_Membership;
199 Tag_Node : Node_Id) return Node_Id is
202 Make_Function_Call (Loc,
203 Name => New_Reference_To (RTE (RE_DT), Loc),
204 Parameter_Associations => New_List (
205 Unchecked_Convert_To (RTE (RE_Tag), Tag_Node)));
208 ----------------------------
209 -- Build_Get_Access_Level --
210 ----------------------------
212 function Build_Get_Access_Level
214 Tag_Node : Node_Id) return Node_Id
218 Make_Selected_Component (Loc,
219 Prefix => Build_TSD (Loc, Tag_Node),
222 (RTE_Record_Component (RE_Access_Level), Loc));
223 end Build_Get_Access_Level;
225 ------------------------------------------
226 -- Build_Get_Predefined_Prim_Op_Address --
227 ------------------------------------------
229 function Build_Get_Predefined_Prim_Op_Address
232 Position : Uint) return Node_Id
235 -- Build code that retrieves the address of the dispatch table
236 -- containing the predefined Ada primitives:
239 -- To_Predef_Prims_Table_Ptr
240 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
243 Make_Indexed_Component (Loc,
245 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
246 Make_Explicit_Dereference (Loc,
247 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
248 Make_Function_Call (Loc,
250 Make_Expanded_Name (Loc,
251 Chars => Name_Op_Subtract,
254 (RTU_Entity (System_Storage_Elements), Loc),
256 Make_Identifier (Loc,
257 Chars => Name_Op_Subtract)),
258 Parameter_Associations => New_List (
259 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
260 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
263 New_List (Make_Integer_Literal (Loc, Position)));
264 end Build_Get_Predefined_Prim_Op_Address;
266 -------------------------
267 -- Build_Inherit_Prims --
268 -------------------------
270 function Build_Inherit_Prims
273 Old_Tag_Node : Node_Id;
274 New_Tag_Node : Node_Id;
275 Num_Prims : Nat) return Node_Id
278 if RTE_Available (RE_DT) then
280 Make_Assignment_Statement (Loc,
284 Make_Selected_Component (Loc,
286 Build_DT (Loc, New_Tag_Node),
289 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
292 Low_Bound => Make_Integer_Literal (Loc, 1),
293 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
298 Make_Selected_Component (Loc,
300 Build_DT (Loc, Old_Tag_Node),
303 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
306 Low_Bound => Make_Integer_Literal (Loc, 1),
307 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
310 Make_Assignment_Statement (Loc,
315 (Node (Last_Elmt (Access_Disp_Table (Typ))),
319 Low_Bound => Make_Integer_Literal (Loc, 1),
320 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
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))));
333 end Build_Inherit_Prims;
335 -------------------------------
336 -- Build_Get_Prim_Op_Address --
337 -------------------------------
339 function Build_Get_Prim_Op_Address
343 Position : Uint) return Node_Id
347 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
349 -- At the end of the Access_Disp_Table list we have the type
350 -- declaration required to convert the tag into a pointer to
351 -- the prims_ptr table (see Freeze_Record_Type).
354 Make_Indexed_Component (Loc,
357 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node),
358 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
359 end Build_Get_Prim_Op_Address;
361 -----------------------------
362 -- Build_Get_Transportable --
363 -----------------------------
365 function Build_Get_Transportable
367 Tag_Node : Node_Id) return Node_Id
371 Make_Selected_Component (Loc,
372 Prefix => Build_TSD (Loc, Tag_Node),
375 (RTE_Record_Component (RE_Transportable), Loc));
376 end Build_Get_Transportable;
378 ------------------------------------
379 -- Build_Inherit_Predefined_Prims --
380 ------------------------------------
382 function Build_Inherit_Predefined_Prims
384 Old_Tag_Node : Node_Id;
385 New_Tag_Node : Node_Id) return Node_Id
389 Make_Assignment_Statement (Loc,
393 Make_Explicit_Dereference (Loc,
394 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
395 Make_Explicit_Dereference (Loc,
396 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
398 Discrete_Range => Make_Range (Loc,
399 Make_Integer_Literal (Loc, Uint_1),
400 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
405 Make_Explicit_Dereference (Loc,
406 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
407 Make_Explicit_Dereference (Loc,
408 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
412 Make_Integer_Literal (Loc, 1),
413 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
414 end Build_Inherit_Predefined_Prims;
416 -------------------------
417 -- Build_Offset_To_Top --
418 -------------------------
420 function Build_Offset_To_Top
422 This_Node : Node_Id) return Node_Id
428 Make_Explicit_Dereference (Loc,
429 Unchecked_Convert_To (RTE (RE_Tag_Ptr), This_Node));
432 Make_Explicit_Dereference (Loc,
433 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
434 Make_Function_Call (Loc,
436 Make_Expanded_Name (Loc,
437 Chars => Name_Op_Subtract,
438 Prefix => New_Reference_To
439 (RTU_Entity (System_Storage_Elements), Loc),
440 Selector_Name => Make_Identifier (Loc,
441 Chars => Name_Op_Subtract)),
442 Parameter_Associations => New_List (
443 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
444 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
446 end Build_Offset_To_Top;
448 ------------------------------------------
449 -- Build_Set_Predefined_Prim_Op_Address --
450 ------------------------------------------
452 function Build_Set_Predefined_Prim_Op_Address
456 Address_Node : Node_Id) return Node_Id
460 Make_Assignment_Statement (Loc,
462 Make_Indexed_Component (Loc,
464 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
465 Make_Explicit_Dereference (Loc,
466 Unchecked_Convert_To (RTE (RE_Addr_Ptr), Tag_Node))),
468 New_List (Make_Integer_Literal (Loc, Position))),
470 Expression => Address_Node);
471 end Build_Set_Predefined_Prim_Op_Address;
473 -------------------------------
474 -- Build_Set_Prim_Op_Address --
475 -------------------------------
477 function Build_Set_Prim_Op_Address
482 Address_Node : Node_Id) return Node_Id
486 Make_Assignment_Statement (Loc,
487 Name => Build_Get_Prim_Op_Address
488 (Loc, Typ, Tag_Node, Position),
489 Expression => Address_Node);
490 end Build_Set_Prim_Op_Address;
492 -----------------------------
493 -- Build_Set_Size_Function --
494 -----------------------------
496 function Build_Set_Size_Function
499 Size_Func : Entity_Id) return Node_Id is
501 pragma Assert (Chars (Size_Func) = Name_uSize
502 and then RTE_Record_Component_Available (RE_Size_Func));
504 Make_Assignment_Statement (Loc,
506 Make_Selected_Component (Loc,
507 Prefix => Build_TSD (Loc, Tag_Node),
510 (RTE_Record_Component (RE_Size_Func), Loc)),
512 Unchecked_Convert_To (RTE (RE_Size_Ptr),
513 Make_Attribute_Reference (Loc,
514 Prefix => New_Reference_To (Size_Func, Loc),
515 Attribute_Name => Name_Unrestricted_Access)));
516 end Build_Set_Size_Function;
518 ------------------------------------
519 -- Build_Set_Static_Offset_To_Top --
520 ------------------------------------
522 function Build_Set_Static_Offset_To_Top
525 Offset_Value : Node_Id) return Node_Id is
528 Make_Assignment_Statement (Loc,
529 Make_Explicit_Dereference (Loc,
530 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
531 Make_Function_Call (Loc,
533 Make_Expanded_Name (Loc,
534 Chars => Name_Op_Subtract,
535 Prefix => New_Reference_To
536 (RTU_Entity (System_Storage_Elements), Loc),
537 Selector_Name => Make_Identifier (Loc,
538 Chars => Name_Op_Subtract)),
539 Parameter_Associations => New_List (
540 Unchecked_Convert_To (RTE (RE_Address), Iface_Tag),
541 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
544 end Build_Set_Static_Offset_To_Top;
550 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
553 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
554 Make_Explicit_Dereference (Loc,
555 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
556 Make_Function_Call (Loc,
558 Make_Expanded_Name (Loc,
559 Chars => Name_Op_Subtract,
562 (RTU_Entity (System_Storage_Elements), Loc),
564 Make_Identifier (Loc,
565 Chars => Name_Op_Subtract)),
567 Parameter_Associations => New_List (
568 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
570 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));