1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2006-2007, 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 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Einfo; use Einfo;
28 with Elists; use Elists;
29 with Exp_Util; use Exp_Util;
30 with Nlists; use Nlists;
31 with Nmake; use Nmake;
32 with Rtsfind; use Rtsfind;
33 with Stand; use Stand;
34 with Snames; use Snames;
35 with Tbuild; use Tbuild;
37 package body Exp_Atag is
39 -----------------------
40 -- Local Subprograms --
41 -----------------------
45 Tag_Node : Node_Id) return Node_Id;
46 -- Build code that displaces the Tag to reference the base of the wrapper
50 -- To_Dispatch_Table_Ptr
51 -- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
53 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id;
54 -- Build code that retrieves the address of the record containing the Type
55 -- Specific Data generated by GNAT.
57 -- Generate: To_Type_Specific_Data_Ptr
58 -- (To_Addr_Ptr (To_Address (Tag) - Typeinfo_Offset).all);
60 function Build_Predef_Prims
62 Tag_Node : Node_Id) return Node_Id;
63 -- Build code that retrieves the address of the dispatch table containing
64 -- the predefined Ada primitives:
66 -- Generate: To_Predef_Prims_Table_Ptr
67 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
69 ------------------------------------------------
70 -- Build_Common_Dispatching_Select_Statements --
71 ------------------------------------------------
73 procedure Build_Common_Dispatching_Select_Statements
80 -- C := get_prim_op_kind (tag! (<type>VP), S);
82 -- where C is the out parameter capturing the call kind and S is the
83 -- dispatch table slot number.
86 Make_Assignment_Statement (Loc,
88 Make_Identifier (Loc, Name_uC),
90 Make_Function_Call (Loc,
91 Name => New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
92 Parameter_Associations => New_List (
93 Unchecked_Convert_To (RTE (RE_Tag),
94 New_Reference_To (DT_Ptr, Loc)),
95 Make_Identifier (Loc, Name_uS)))));
99 -- if C = POK_Procedure
100 -- or else C = POK_Protected_Procedure
101 -- or else C = POK_Task_Procedure;
106 -- where F is the out parameter capturing the status of a potential
110 Make_If_Statement (Loc,
117 Make_Identifier (Loc, Name_uC),
119 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
125 Make_Identifier (Loc, Name_uC),
127 New_Reference_To (RTE (
128 RE_POK_Protected_Procedure), Loc)),
132 Make_Identifier (Loc, Name_uC),
134 New_Reference_To (RTE (
135 RE_POK_Task_Procedure), Loc)))),
139 Make_Assignment_Statement (Loc,
140 Name => Make_Identifier (Loc, Name_uF),
141 Expression => New_Reference_To (Standard_True, Loc)),
142 Make_Return_Statement (Loc))));
143 end Build_Common_Dispatching_Select_Statements;
145 -------------------------
146 -- Build_CW_Membership --
147 -------------------------
149 function Build_CW_Membership
151 Obj_Tag_Node : Node_Id;
152 Typ_Tag_Node : Node_Id) return Node_Id
154 function Build_Pos return Node_Id;
155 -- Generate TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
157 function Build_Pos return Node_Id is
160 Make_Op_Subtract (Loc,
162 Make_Selected_Component (Loc,
163 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
165 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
168 Make_Selected_Component (Loc,
169 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
171 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
174 -- Start of processing for Build_CW_Membership
181 Left_Opnd => Build_Pos,
182 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
187 Make_Indexed_Component (Loc,
189 Make_Selected_Component (Loc,
190 Prefix => Build_TSD (Loc, Obj_Tag_Node),
193 (RTE_Record_Component (RE_Tags_Table), Loc)),
195 New_List (Build_Pos)),
197 Right_Opnd => Typ_Tag_Node));
198 end Build_CW_Membership;
206 Tag_Node : Node_Id) return Node_Id is
209 Make_Function_Call (Loc,
210 Name => New_Reference_To (RTE (RE_DT), Loc),
211 Parameter_Associations => New_List (
212 Unchecked_Convert_To (RTE (RE_Tag), Tag_Node)));
215 ----------------------------
216 -- Build_Get_Access_Level --
217 ----------------------------
219 function Build_Get_Access_Level
221 Tag_Node : Node_Id) return Node_Id
225 Make_Selected_Component (Loc,
226 Prefix => Build_TSD (Loc, Tag_Node),
229 (RTE_Record_Component (RE_Access_Level), Loc));
230 end Build_Get_Access_Level;
232 ------------------------------------------
233 -- Build_Get_Predefined_Prim_Op_Address --
234 ------------------------------------------
236 function Build_Get_Predefined_Prim_Op_Address
239 Position : Uint) return Node_Id
243 Make_Indexed_Component (Loc,
245 Build_Predef_Prims (Loc, Tag_Node),
247 New_List (Make_Integer_Literal (Loc, Position)));
248 end Build_Get_Predefined_Prim_Op_Address;
250 -------------------------
251 -- Build_Inherit_Prims --
252 -------------------------
254 function Build_Inherit_Prims
256 Old_Tag_Node : Node_Id;
257 New_Tag_Node : Node_Id;
258 Num_Prims : Nat) return Node_Id
262 Make_Assignment_Statement (Loc,
266 Make_Selected_Component (Loc,
268 Build_DT (Loc, New_Tag_Node),
271 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
274 Low_Bound => Make_Integer_Literal (Loc, 1),
275 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
280 Make_Selected_Component (Loc,
282 Build_DT (Loc, Old_Tag_Node),
285 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
288 Low_Bound => Make_Integer_Literal (Loc, 1),
289 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
290 end Build_Inherit_Prims;
292 -------------------------------
293 -- Build_Get_Prim_Op_Address --
294 -------------------------------
296 function Build_Get_Prim_Op_Address
300 Position : Uint) return Node_Id
304 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
306 -- At the end of the Access_Disp_Table list we have the type
307 -- declaration required to convert the tag into a pointer to
308 -- the prims_ptr table (see Freeze_Record_Type).
311 Make_Indexed_Component (Loc,
314 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node),
315 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
316 end Build_Get_Prim_Op_Address;
318 -----------------------------
319 -- Build_Get_Transportable --
320 -----------------------------
322 function Build_Get_Transportable
324 Tag_Node : Node_Id) return Node_Id
328 Make_Selected_Component (Loc,
329 Prefix => Build_TSD (Loc, Tag_Node),
332 (RTE_Record_Component (RE_Transportable), Loc));
333 end Build_Get_Transportable;
335 ------------------------------------
336 -- Build_Inherit_Predefined_Prims --
337 ------------------------------------
339 function Build_Inherit_Predefined_Prims
341 Old_Tag_Node : Node_Id;
342 New_Tag_Node : Node_Id) return Node_Id
346 Make_Assignment_Statement (Loc,
350 Make_Explicit_Dereference (Loc,
351 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
352 Make_Selected_Component (Loc,
354 Build_DT (Loc, New_Tag_Node),
357 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
358 Discrete_Range => Make_Range (Loc,
359 Make_Integer_Literal (Loc, Uint_1),
360 New_Reference_To (RTE (RE_Default_Prim_Op_Count), Loc))),
365 Make_Explicit_Dereference (Loc,
366 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
367 Make_Selected_Component (Loc,
369 Build_DT (Loc, Old_Tag_Node),
372 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
375 Low_Bound => Make_Integer_Literal (Loc, 1),
377 New_Reference_To (RTE (RE_Default_Prim_Op_Count), Loc))));
378 end Build_Inherit_Predefined_Prims;
380 ------------------------
381 -- Build_Predef_Prims --
382 ------------------------
384 function Build_Predef_Prims
386 Tag_Node : Node_Id) return Node_Id
390 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
391 Make_Explicit_Dereference (Loc,
392 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
393 Make_Function_Call (Loc,
395 Make_Expanded_Name (Loc,
396 Chars => Name_Op_Subtract,
399 (RTU_Entity (System_Storage_Elements), Loc),
401 Make_Identifier (Loc,
402 Chars => Name_Op_Subtract)),
404 Parameter_Associations => New_List (
405 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
406 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
408 end Build_Predef_Prims;
410 ------------------------------------------
411 -- Build_Set_Predefined_Prim_Op_Address --
412 ------------------------------------------
414 function Build_Set_Predefined_Prim_Op_Address
418 Address_Node : Node_Id) return Node_Id
422 Make_Assignment_Statement (Loc,
423 Name => Build_Get_Predefined_Prim_Op_Address (Loc,
425 Expression => Address_Node);
426 end Build_Set_Predefined_Prim_Op_Address;
428 -------------------------------
429 -- Build_Set_Prim_Op_Address --
430 -------------------------------
432 function Build_Set_Prim_Op_Address
437 Address_Node : Node_Id) return Node_Id
441 Make_Assignment_Statement (Loc,
442 Name => Build_Get_Prim_Op_Address
443 (Loc, Typ, Tag_Node, Position),
444 Expression => Address_Node);
445 end Build_Set_Prim_Op_Address;
451 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
454 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
455 Make_Explicit_Dereference (Loc,
456 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
457 Make_Function_Call (Loc,
459 Make_Expanded_Name (Loc,
460 Chars => Name_Op_Subtract,
463 (RTU_Entity (System_Storage_Elements), Loc),
465 Make_Identifier (Loc,
466 Chars => Name_Op_Subtract)),
468 Parameter_Associations => New_List (
469 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
471 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));