Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / ada / exp_atag.adb
blob670ddf8b868fc93adc91abd4dedec4b4fb66bbdc
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ A T A G --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2006-2007, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Einfo; use Einfo;
27 with Elists; use Elists;
28 with Exp_Util; use Exp_Util;
29 with Nlists; use Nlists;
30 with Nmake; use Nmake;
31 with Rtsfind; use Rtsfind;
32 with Sem_Util; use Sem_Util;
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 -----------------------
43 function Build_DT
44 (Loc : Source_Ptr;
45 Tag_Node : Node_Id) return Node_Id;
46 -- Build code that displaces the Tag to reference the base of the wrapper
47 -- record
49 -- Generates:
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
61 (Loc : Source_Ptr;
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
74 (Loc : Source_Ptr;
75 DT_Ptr : Entity_Id;
76 Stmts : List_Id)
78 begin
79 -- Generate:
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.
85 Append_To (Stmts,
86 Make_Assignment_Statement (Loc,
87 Name =>
88 Make_Identifier (Loc, Name_uC),
89 Expression =>
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)))));
97 -- Generate:
99 -- if C = POK_Procedure
100 -- or else C = POK_Protected_Procedure
101 -- or else C = POK_Task_Procedure;
102 -- then
103 -- F := True;
104 -- return;
106 -- where F is the out parameter capturing the status of a potential
107 -- entry call.
109 Append_To (Stmts,
110 Make_If_Statement (Loc,
112 Condition =>
113 Make_Or_Else (Loc,
114 Left_Opnd =>
115 Make_Op_Eq (Loc,
116 Left_Opnd =>
117 Make_Identifier (Loc, Name_uC),
118 Right_Opnd =>
119 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
120 Right_Opnd =>
121 Make_Or_Else (Loc,
122 Left_Opnd =>
123 Make_Op_Eq (Loc,
124 Left_Opnd =>
125 Make_Identifier (Loc, Name_uC),
126 Right_Opnd =>
127 New_Reference_To (RTE (
128 RE_POK_Protected_Procedure), Loc)),
129 Right_Opnd =>
130 Make_Op_Eq (Loc,
131 Left_Opnd =>
132 Make_Identifier (Loc, Name_uC),
133 Right_Opnd =>
134 New_Reference_To (RTE (
135 RE_POK_Task_Procedure), Loc)))),
137 Then_Statements =>
138 New_List (
139 Make_Assignment_Statement (Loc,
140 Name => Make_Identifier (Loc, Name_uF),
141 Expression => New_Reference_To (Standard_True, Loc)),
142 Make_Simple_Return_Statement (Loc))));
143 end Build_Common_Dispatching_Select_Statements;
145 -------------------------
146 -- Build_CW_Membership --
147 -------------------------
149 function Build_CW_Membership
150 (Loc : Source_Ptr;
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
158 begin
159 return
160 Make_Op_Subtract (Loc,
161 Left_Opnd =>
162 Make_Selected_Component (Loc,
163 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
164 Selector_Name =>
165 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
167 Right_Opnd =>
168 Make_Selected_Component (Loc,
169 Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
170 Selector_Name =>
171 New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
172 end Build_Pos;
174 -- Start of processing for Build_CW_Membership
176 begin
177 return
178 Make_And_Then (Loc,
179 Left_Opnd =>
180 Make_Op_Ge (Loc,
181 Left_Opnd => Build_Pos,
182 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
184 Right_Opnd =>
185 Make_Op_Eq (Loc,
186 Left_Opnd =>
187 Make_Indexed_Component (Loc,
188 Prefix =>
189 Make_Selected_Component (Loc,
190 Prefix => Build_TSD (Loc, Obj_Tag_Node),
191 Selector_Name =>
192 New_Reference_To
193 (RTE_Record_Component (RE_Tags_Table), Loc)),
194 Expressions =>
195 New_List (Build_Pos)),
197 Right_Opnd => Typ_Tag_Node));
198 end Build_CW_Membership;
200 --------------
201 -- Build_DT --
202 --------------
204 function Build_DT
205 (Loc : Source_Ptr;
206 Tag_Node : Node_Id) return Node_Id is
207 begin
208 return
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)));
213 end Build_DT;
215 ----------------------------
216 -- Build_Get_Access_Level --
217 ----------------------------
219 function Build_Get_Access_Level
220 (Loc : Source_Ptr;
221 Tag_Node : Node_Id) return Node_Id
223 begin
224 return
225 Make_Selected_Component (Loc,
226 Prefix => Build_TSD (Loc, Tag_Node),
227 Selector_Name =>
228 New_Reference_To
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
237 (Loc : Source_Ptr;
238 Tag_Node : Node_Id;
239 Position : Uint) return Node_Id
241 begin
242 return
243 Make_Indexed_Component (Loc,
244 Prefix =>
245 Build_Predef_Prims (Loc, Tag_Node),
246 Expressions =>
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
255 (Loc : Source_Ptr;
256 Typ : Entity_Id;
257 Old_Tag_Node : Node_Id;
258 New_Tag_Node : Node_Id;
259 Num_Prims : Nat) return Node_Id
261 begin
262 if RTE_Available (RE_DT) then
263 return
264 Make_Assignment_Statement (Loc,
265 Name =>
266 Make_Slice (Loc,
267 Prefix =>
268 Make_Selected_Component (Loc,
269 Prefix =>
270 Build_DT (Loc, New_Tag_Node),
271 Selector_Name =>
272 New_Reference_To
273 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
274 Discrete_Range =>
275 Make_Range (Loc,
276 Low_Bound => Make_Integer_Literal (Loc, 1),
277 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
279 Expression =>
280 Make_Slice (Loc,
281 Prefix =>
282 Make_Selected_Component (Loc,
283 Prefix =>
284 Build_DT (Loc, Old_Tag_Node),
285 Selector_Name =>
286 New_Reference_To
287 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
288 Discrete_Range =>
289 Make_Range (Loc,
290 Low_Bound => Make_Integer_Literal (Loc, 1),
291 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
292 else
293 return
294 Make_Assignment_Statement (Loc,
295 Name =>
296 Make_Slice (Loc,
297 Prefix =>
298 Unchecked_Convert_To
299 (Node (Last_Elmt (Access_Disp_Table (Typ))),
300 New_Tag_Node),
301 Discrete_Range =>
302 Make_Range (Loc,
303 Low_Bound => Make_Integer_Literal (Loc, 1),
304 High_Bound => Make_Integer_Literal (Loc, Num_Prims))),
306 Expression =>
307 Make_Slice (Loc,
308 Prefix =>
309 Unchecked_Convert_To
310 (Node (Last_Elmt (Access_Disp_Table (Typ))),
311 Old_Tag_Node),
312 Discrete_Range =>
313 Make_Range (Loc,
314 Low_Bound => Make_Integer_Literal (Loc, 1),
315 High_Bound => Make_Integer_Literal (Loc, Num_Prims))));
316 end if;
317 end Build_Inherit_Prims;
319 -------------------------------
320 -- Build_Get_Prim_Op_Address --
321 -------------------------------
323 function Build_Get_Prim_Op_Address
324 (Loc : Source_Ptr;
325 Typ : Entity_Id;
326 Tag_Node : Node_Id;
327 Position : Uint) return Node_Id
329 begin
330 pragma Assert
331 (Position <= DT_Entry_Count (First_Tag_Component (Typ)));
333 -- At the end of the Access_Disp_Table list we have the type
334 -- declaration required to convert the tag into a pointer to
335 -- the prims_ptr table (see Freeze_Record_Type).
337 return
338 Make_Indexed_Component (Loc,
339 Prefix =>
340 Unchecked_Convert_To
341 (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node),
342 Expressions => New_List (Make_Integer_Literal (Loc, Position)));
343 end Build_Get_Prim_Op_Address;
345 -----------------------------
346 -- Build_Get_Transportable --
347 -----------------------------
349 function Build_Get_Transportable
350 (Loc : Source_Ptr;
351 Tag_Node : Node_Id) return Node_Id
353 begin
354 return
355 Make_Selected_Component (Loc,
356 Prefix => Build_TSD (Loc, Tag_Node),
357 Selector_Name =>
358 New_Reference_To
359 (RTE_Record_Component (RE_Transportable), Loc));
360 end Build_Get_Transportable;
362 ------------------------------------
363 -- Build_Inherit_Predefined_Prims --
364 ------------------------------------
366 function Build_Inherit_Predefined_Prims
367 (Loc : Source_Ptr;
368 Old_Tag_Node : Node_Id;
369 New_Tag_Node : Node_Id) return Node_Id
371 begin
372 if RTE_Available (RE_DT) then
373 return
374 Make_Assignment_Statement (Loc,
375 Name =>
376 Make_Slice (Loc,
377 Prefix =>
378 Make_Explicit_Dereference (Loc,
379 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
380 Make_Selected_Component (Loc,
381 Prefix =>
382 Build_DT (Loc, New_Tag_Node),
383 Selector_Name =>
384 New_Reference_To
385 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
386 Discrete_Range => Make_Range (Loc,
387 Make_Integer_Literal (Loc, Uint_1),
388 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
390 Expression =>
391 Make_Slice (Loc,
392 Prefix =>
393 Make_Explicit_Dereference (Loc,
394 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
395 Make_Selected_Component (Loc,
396 Prefix =>
397 Build_DT (Loc, Old_Tag_Node),
398 Selector_Name =>
399 New_Reference_To
400 (RTE_Record_Component (RE_Predef_Prims), Loc)))),
402 Discrete_Range =>
403 Make_Range (Loc,
404 Low_Bound => Make_Integer_Literal (Loc, 1),
405 High_Bound =>
406 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
407 else
408 return
409 Make_Assignment_Statement (Loc,
410 Name =>
411 Make_Slice (Loc,
412 Prefix =>
413 Make_Explicit_Dereference (Loc,
414 Build_Predef_Prims (Loc, New_Tag_Node)),
415 Discrete_Range => Make_Range (Loc,
416 Make_Integer_Literal (Loc, Uint_1),
417 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))),
419 Expression =>
420 Make_Slice (Loc,
421 Prefix =>
422 Make_Explicit_Dereference (Loc,
423 Build_Predef_Prims (Loc, Old_Tag_Node)),
424 Discrete_Range =>
425 Make_Range (Loc,
426 Low_Bound => Make_Integer_Literal (Loc, 1),
427 High_Bound =>
428 New_Reference_To (RTE (RE_Max_Predef_Prims), Loc))));
429 end if;
430 end Build_Inherit_Predefined_Prims;
432 ------------------------
433 -- Build_Predef_Prims --
434 ------------------------
436 function Build_Predef_Prims
437 (Loc : Source_Ptr;
438 Tag_Node : Node_Id) return Node_Id
440 begin
441 return
442 Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr),
443 Make_Explicit_Dereference (Loc,
444 Unchecked_Convert_To (RTE (RE_Addr_Ptr),
445 Make_Function_Call (Loc,
446 Name =>
447 Make_Expanded_Name (Loc,
448 Chars => Name_Op_Subtract,
449 Prefix =>
450 New_Reference_To
451 (RTU_Entity (System_Storage_Elements), Loc),
452 Selector_Name =>
453 Make_Identifier (Loc,
454 Chars => Name_Op_Subtract)),
456 Parameter_Associations => New_List (
457 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
458 New_Reference_To (RTE (RE_DT_Predef_Prims_Offset),
459 Loc))))));
460 end Build_Predef_Prims;
462 ------------------------------------------
463 -- Build_Set_Predefined_Prim_Op_Address --
464 ------------------------------------------
466 function Build_Set_Predefined_Prim_Op_Address
467 (Loc : Source_Ptr;
468 Tag_Node : Node_Id;
469 Position : Uint;
470 Address_Node : Node_Id) return Node_Id
472 begin
473 return
474 Make_Assignment_Statement (Loc,
475 Name => Build_Get_Predefined_Prim_Op_Address (Loc,
476 Tag_Node, Position),
477 Expression => Address_Node);
478 end Build_Set_Predefined_Prim_Op_Address;
480 -------------------------------
481 -- Build_Set_Prim_Op_Address --
482 -------------------------------
484 function Build_Set_Prim_Op_Address
485 (Loc : Source_Ptr;
486 Typ : Entity_Id;
487 Tag_Node : Node_Id;
488 Position : Uint;
489 Address_Node : Node_Id) return Node_Id
491 begin
492 return
493 Make_Assignment_Statement (Loc,
494 Name => Build_Get_Prim_Op_Address
495 (Loc, Typ, Tag_Node, Position),
496 Expression => Address_Node);
497 end Build_Set_Prim_Op_Address;
499 ---------------
500 -- Build_TSD --
501 ---------------
503 function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
504 begin
505 return
506 Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
507 Make_Explicit_Dereference (Loc,
508 Prefix => Unchecked_Convert_To (RTE (RE_Addr_Ptr),
509 Make_Function_Call (Loc,
510 Name =>
511 Make_Expanded_Name (Loc,
512 Chars => Name_Op_Subtract,
513 Prefix =>
514 New_Reference_To
515 (RTU_Entity (System_Storage_Elements), Loc),
516 Selector_Name =>
517 Make_Identifier (Loc,
518 Chars => Name_Op_Subtract)),
520 Parameter_Associations => New_List (
521 Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
522 New_Reference_To
523 (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));
524 end Build_TSD;
526 end Exp_Atag;