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 Sem_Util; use Sem_Util;
34 with Stand; use Stand;
35 with Snames; use Snames;
36 with Tbuild; use Tbuild;
38 package body Exp_Atag is
40 -----------------------
41 -- Local Subprograms --
42 -----------------------
46 Tag_Node : Node_Id) return Node_Id;
47 -- Build code that displaces the Tag to reference the base of the wrapper
51 -- To_Dispatch_Table_Ptr
52 -- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
54 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id;
55 -- Build code that retrieves the address of the record containing the Type
56 -- Specific Data generated by GNAT.
58 -- Generate: To_Type_Specific_Data_Ptr
59 -- (To_Addr_Ptr (To_Address (Tag) - Typeinfo_Offset).all);
61 function Build_Predef_Prims
63 Tag_Node : Node_Id) return Node_Id;
64 -- Build code that retrieves the address of the dispatch table containing
65 -- the predefined Ada primitives:
67 -- Generate: To_Predef_Prims_Table_Ptr
68 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
70 ------------------------------------------------
71 -- Build_Common_Dispatching_Select_Statements --
72 ------------------------------------------------
74 procedure Build_Common_Dispatching_Select_Statements
81 -- C := get_prim_op_kind (tag! (<type>VP), S);
83 -- where C is the out parameter capturing the call kind and S is the
84 -- dispatch table slot number.
87 Make_Assignment_Statement (Loc,
89 Make_Identifier (Loc, Name_uC),
91 Make_Function_Call (Loc,
92 Name => New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
93 Parameter_Associations => New_List (
94 Unchecked_Convert_To (RTE (RE_Tag),
95 New_Reference_To (DT_Ptr, Loc)),
96 Make_Identifier (Loc, Name_uS)))));
100 -- if C = POK_Procedure
101 -- or else C = POK_Protected_Procedure
102 -- or else C = POK_Task_Procedure;
107 -- where F is the out parameter capturing the status of a potential
111 Make_If_Statement (Loc,
118 Make_Identifier (Loc, Name_uC),
120 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
126 Make_Identifier (Loc, Name_uC),
128 New_Reference_To (RTE (
129 RE_POK_Protected_Procedure), Loc)),
133 Make_Identifier (Loc, Name_uC),
135 New_Reference_To (RTE (
136 RE_POK_Task_Procedure), Loc)))),
140 Make_Assignment_Statement (Loc,
141 Name => Make_Identifier (Loc, Name_uF),
142 Expression => New_Reference_To (Standard_True, Loc)),
143 Make_Simple_Return_Statement (Loc))));
144 end Build_Common_Dispatching_Select_Statements;
146 -------------------------
147 -- Build_CW_Membership --
148 -------------------------
150 function Build_CW_Membership
152 Obj_Tag_Node : Node_Id;
153 Typ_Tag_Node : Node_Id) return Node_Id
155 function Build_Pos return Node_Id;
156 -- Generate TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
158 function Build_Pos return Node_Id is
161 Make_Op_Subtract (Loc,
163 Make_Selected_Component (Loc,
164 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
166 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
169 Make_Selected_Component (Loc,
170 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
172 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
175 -- Start of processing for Build_CW_Membership
182 Left_Opnd => Build_Pos,
183 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
188 Make_Indexed_Component (Loc,
190 Make_Selected_Component (Loc,
191 Prefix => Build_TSD (Loc, Obj_Tag_Node),
194 (RTE_Record_Component (RE_Tags_Table), Loc)),
196 New_List (Build_Pos)),
198 Right_Opnd => Typ_Tag_Node));
199 end Build_CW_Membership;
207 Tag_Node : Node_Id) return Node_Id is
210 Make_Function_Call (Loc,
211 Name => New_Reference_To (RTE (RE_DT), Loc),
212 Parameter_Associations => New_List (
213 Unchecked_Convert_To (RTE (RE_Tag), Tag_Node)));
216 ----------------------------
217 -- Build_Get_Access_Level --
218 ----------------------------
220 function Build_Get_Access_Level
222 Tag_Node : Node_Id) return Node_Id
226 Make_Selected_Component (Loc,
227 Prefix => Build_TSD (Loc, Tag_Node),
230 (RTE_Record_Component (RE_Access_Level), Loc));
231 end Build_Get_Access_Level;
233 ------------------------------------------
234 -- Build_Get_Predefined_Prim_Op_Address --
235 ------------------------------------------
237 function Build_Get_Predefined_Prim_Op_Address
240 Position : Uint) return Node_Id
244 Make_Indexed_Component (Loc,
246 Build_Predef_Prims (Loc, Tag_Node),
248 New_List (Make_Integer_Literal (Loc, Position)));
249 end Build_Get_Predefined_Prim_Op_Address;
251 -------------------------
252 -- Build_Inherit_Prims --
253 -------------------------
255 function Build_Inherit_Prims
258 Old_Tag_Node : Node_Id;
259 New_Tag_Node : Node_Id;
260 Num_Prims : Nat) return Node_Id
263 if RTE_Available (RE_DT) then
265 Make_Assignment_Statement (Loc,
269 Make_Selected_Component (Loc,
271 Build_DT (Loc, New_Tag_Node),
274 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
277 Low_Bound => Make_Integer_Literal (Loc, 1),
278 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
283 Make_Selected_Component (Loc,
285 Build_DT (Loc, Old_Tag_Node),
288 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
291 Low_Bound => Make_Integer_Literal (Loc, 1),
292 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
295 Make_Assignment_Statement (Loc,
300 (Node (Last_Elmt (Access_Disp_Table (Typ))),
304 Low_Bound => Make_Integer_Literal (Loc, 1),
305 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
311 (Node (Last_Elmt (Access_Disp_Table (Typ))),
315 Low_Bound => Make_Integer_Literal (Loc, 1),
316 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
318 end Build_Inherit_Prims;
320 -------------------------------
321 -- Build_Get_Prim_Op_Address --
322 -------------------------------
324 function Build_Get_Prim_Op_Address
328 Position : Uint) return Node_Id
332 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
334 -- At the end of the Access_Disp_Table list we have the type
335 -- declaration required to convert the tag into a pointer to
336 -- the prims_ptr table (see Freeze_Record_Type).
339 Make_Indexed_Component (Loc,
342 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node),
343 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
344 end Build_Get_Prim_Op_Address;
346 -----------------------------
347 -- Build_Get_Transportable --
348 -----------------------------
350 function Build_Get_Transportable
352 Tag_Node : Node_Id) return Node_Id
356 Make_Selected_Component (Loc,
357 Prefix => Build_TSD (Loc, Tag_Node),
360 (RTE_Record_Component (RE_Transportable), Loc));
361 end Build_Get_Transportable;
363 ------------------------------------
364 -- Build_Inherit_Predefined_Prims --
365 ------------------------------------
367 function Build_Inherit_Predefined_Prims
369 Old_Tag_Node : Node_Id;
370 New_Tag_Node : Node_Id) return Node_Id
373 if RTE_Available (RE_DT) then
375 Make_Assignment_Statement (Loc,
379 Make_Explicit_Dereference (Loc,
380 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
381 Make_Selected_Component (Loc,
383 Build_DT (Loc, New_Tag_Node),
386 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
387 Discrete_Range => Make_Range (Loc,
388 Make_Integer_Literal (Loc, Uint_1),
389 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
394 Make_Explicit_Dereference (Loc,
395 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
396 Make_Selected_Component (Loc,
398 Build_DT (Loc, Old_Tag_Node),
401 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
405 Low_Bound => Make_Integer_Literal (Loc, 1),
407 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
410 Make_Assignment_Statement (Loc,
414 Make_Explicit_Dereference (Loc,
415 Build_Predef_Prims (Loc, New_Tag_Node)),
416 Discrete_Range => Make_Range (Loc,
417 Make_Integer_Literal (Loc, Uint_1),
418 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
423 Make_Explicit_Dereference (Loc,
424 Build_Predef_Prims (Loc, Old_Tag_Node)),
427 Low_Bound => Make_Integer_Literal (Loc, 1),
429 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
431 end Build_Inherit_Predefined_Prims;
433 ------------------------
434 -- Build_Predef_Prims --
435 ------------------------
437 function Build_Predef_Prims
439 Tag_Node : Node_Id) return Node_Id
443 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
444 Make_Explicit_Dereference (Loc,
445 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
446 Make_Function_Call (Loc,
448 Make_Expanded_Name (Loc,
449 Chars => Name_Op_Subtract,
452 (RTU_Entity (System_Storage_Elements), Loc),
454 Make_Identifier (Loc,
455 Chars => Name_Op_Subtract)),
457 Parameter_Associations => New_List (
458 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
459 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
461 end Build_Predef_Prims;
463 ------------------------------------------
464 -- Build_Set_Predefined_Prim_Op_Address --
465 ------------------------------------------
467 function Build_Set_Predefined_Prim_Op_Address
471 Address_Node : Node_Id) return Node_Id
475 Make_Assignment_Statement (Loc,
476 Name => Build_Get_Predefined_Prim_Op_Address (Loc,
478 Expression => Address_Node);
479 end Build_Set_Predefined_Prim_Op_Address;
481 -------------------------------
482 -- Build_Set_Prim_Op_Address --
483 -------------------------------
485 function Build_Set_Prim_Op_Address
490 Address_Node : Node_Id) return Node_Id
494 Make_Assignment_Statement (Loc,
495 Name => Build_Get_Prim_Op_Address
496 (Loc, Typ, Tag_Node, Position),
497 Expression => Address_Node);
498 end Build_Set_Prim_Op_Address;
504 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
507 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
508 Make_Explicit_Dereference (Loc,
509 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
510 Make_Function_Call (Loc,
512 Make_Expanded_Name (Loc,
513 Chars => Name_Op_Subtract,
516 (RTU_Entity (System_Storage_Elements), Loc),
518 Make_Identifier (Loc,
519 Chars => Name_Op_Subtract)),
521 Parameter_Associations => New_List (
522 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
524 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));