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_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 function Build_Get_Predefined_Prim_Op_Address
233 Position : Uint) return Node_Id
236 -- Build code that retrieves the address of the dispatch table
237 -- containing the predefined Ada primitives:
240 -- To_Predef_Prims_Table_Ptr
241 -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all);
244 Make_Indexed_Component (Loc,
246 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
247 Make_Explicit_Dereference (Loc,
248 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
249 Make_Function_Call (Loc,
251 Make_Expanded_Name (Loc,
252 Chars => Name_Op_Subtract,
255 (RTU_Entity (System_Storage_Elements), Loc),
257 Make_Identifier (Loc,
258 Chars => Name_Op_Subtract)),
259 Parameter_Associations => New_List (
260 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
261 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
264 New_List (Make_Integer_Literal (Loc, Position)));
265 end Build_Get_Predefined_Prim_Op_Address;
267 -------------------------
268 -- Build_Inherit_Prims --
269 -------------------------
271 function Build_Inherit_Prims
274 Old_Tag_Node : Node_Id;
275 New_Tag_Node : Node_Id;
276 Num_Prims : Nat) return Node_Id
279 if RTE_Available (RE_DT) then
281 Make_Assignment_Statement (Loc,
285 Make_Selected_Component (Loc,
287 Build_DT (Loc, New_Tag_Node),
290 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
293 Low_Bound => Make_Integer_Literal (Loc, 1),
294 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
299 Make_Selected_Component (Loc,
301 Build_DT (Loc, Old_Tag_Node),
304 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
307 Low_Bound => Make_Integer_Literal (Loc, 1),
308 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
311 Make_Assignment_Statement (Loc,
316 (Node (Last_Elmt (Access_Disp_Table (Typ))),
320 Low_Bound => Make_Integer_Literal (Loc, 1),
321 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
327 (Node (Last_Elmt (Access_Disp_Table (Typ))),
331 Low_Bound => Make_Integer_Literal (Loc, 1),
332 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
334 end Build_Inherit_Prims;
336 -------------------------------
337 -- Build_Get_Prim_Op_Address --
338 -------------------------------
340 function Build_Get_Prim_Op_Address
344 Position : Uint) return Node_Id
348 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
350 -- At the end of the Access_Disp_Table list we have the type
351 -- declaration required to convert the tag into a pointer to
352 -- the prims_ptr table (see Freeze_Record_Type).
355 Make_Indexed_Component (Loc,
358 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node),
359 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
360 end Build_Get_Prim_Op_Address;
362 -----------------------------
363 -- Build_Get_Transportable --
364 -----------------------------
366 function Build_Get_Transportable
368 Tag_Node : Node_Id) return Node_Id
372 Make_Selected_Component (Loc,
373 Prefix => Build_TSD (Loc, Tag_Node),
376 (RTE_Record_Component (RE_Transportable), Loc));
377 end Build_Get_Transportable;
379 ------------------------------------
380 -- Build_Inherit_Predefined_Prims --
381 ------------------------------------
383 function Build_Inherit_Predefined_Prims
385 Old_Tag_Node : Node_Id;
386 New_Tag_Node : Node_Id) return Node_Id
390 Make_Assignment_Statement (Loc,
394 Make_Explicit_Dereference (Loc,
395 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
396 Make_Explicit_Dereference (Loc,
397 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
399 Discrete_Range => Make_Range (Loc,
400 Make_Integer_Literal (Loc, Uint_1),
401 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
406 Make_Explicit_Dereference (Loc,
407 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
408 Make_Explicit_Dereference (Loc,
409 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
413 Make_Integer_Literal (Loc, 1),
414 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
415 end Build_Inherit_Predefined_Prims;
417 -------------------------
418 -- Build_Offset_To_Top --
419 -------------------------
421 function Build_Offset_To_Top
423 This_Node : Node_Id) return Node_Id
429 Make_Explicit_Dereference (Loc,
430 Unchecked_Convert_To (RTE (RE_Tag_Ptr), This_Node));
433 Make_Explicit_Dereference (Loc,
434 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
435 Make_Function_Call (Loc,
437 Make_Expanded_Name (Loc,
438 Chars => Name_Op_Subtract,
439 Prefix => New_Reference_To
440 (RTU_Entity (System_Storage_Elements), Loc),
441 Selector_Name => Make_Identifier (Loc,
442 Chars => Name_Op_Subtract)),
443 Parameter_Associations => New_List (
444 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
445 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
447 end Build_Offset_To_Top;
449 ------------------------------------------
450 -- Build_Set_Predefined_Prim_Op_Address --
451 ------------------------------------------
453 function Build_Set_Predefined_Prim_Op_Address
457 Address_Node : Node_Id) return Node_Id
461 Make_Assignment_Statement (Loc,
463 Make_Indexed_Component (Loc,
465 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
466 Make_Explicit_Dereference (Loc,
467 Unchecked_Convert_To (RTE (RE_Addr_Ptr), Tag_Node))),
469 New_List (Make_Integer_Literal (Loc, Position))),
471 Expression => Address_Node);
472 end Build_Set_Predefined_Prim_Op_Address;
474 -------------------------------
475 -- Build_Set_Prim_Op_Address --
476 -------------------------------
478 function Build_Set_Prim_Op_Address
483 Address_Node : Node_Id) return Node_Id
487 Make_Assignment_Statement (Loc,
488 Name => Build_Get_Prim_Op_Address
489 (Loc, Typ, Tag_Node, Position),
490 Expression => Address_Node);
491 end Build_Set_Prim_Op_Address;
493 -----------------------------
494 -- Build_Set_Size_Function --
495 -----------------------------
497 function Build_Set_Size_Function
500 Size_Func : Entity_Id) return Node_Id is
502 pragma Assert (Chars (Size_Func) = Name_uSize
503 and then RTE_Record_Component_Available (RE_Size_Func));
505 Make_Assignment_Statement (Loc,
507 Make_Selected_Component (Loc,
508 Prefix => Build_TSD (Loc, Tag_Node),
511 (RTE_Record_Component (RE_Size_Func), Loc)),
513 Unchecked_Convert_To (RTE (RE_Size_Ptr),
514 Make_Attribute_Reference (Loc,
515 Prefix => New_Reference_To (Size_Func, Loc),
516 Attribute_Name => Name_Unrestricted_Access)));
517 end Build_Set_Size_Function;
519 ------------------------------------
520 -- Build_Set_Static_Offset_To_Top --
521 ------------------------------------
523 function Build_Set_Static_Offset_To_Top
526 Offset_Value : Node_Id) return Node_Id is
529 Make_Assignment_Statement (Loc,
530 Make_Explicit_Dereference (Loc,
531 Unchecked_Convert_To (RTE (RE_Offset_To_Top_Ptr),
532 Make_Function_Call (Loc,
534 Make_Expanded_Name (Loc,
535 Chars => Name_Op_Subtract,
536 Prefix => New_Reference_To
537 (RTU_Entity (System_Storage_Elements), Loc),
538 Selector_Name => Make_Identifier (Loc,
539 Chars => Name_Op_Subtract)),
540 Parameter_Associations => New_List (
541 Unchecked_Convert_To (RTE (RE_Address), Iface_Tag),
542 New_Reference_To (RTE (RE_DT_Offset_To_Top_Offset),
545 end Build_Set_Static_Offset_To_Top;
551 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
554 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
555 Make_Explicit_Dereference (Loc,
556 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
557 Make_Function_Call (Loc,
559 Make_Expanded_Name (Loc,
560 Chars => Name_Op_Subtract,
563 (RTU_Entity (System_Storage_Elements), Loc),
565 Make_Identifier (Loc,
566 Chars => Name_Op_Subtract)),
568 Parameter_Associations => New_List (
569 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
571 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));