* arm.c (FL_WBUF): Define.
[official-gcc.git] / gcc / ada / exp_disp.adb
blob8bb0cac38dbb63abe1261a0cd6de60b1ab68a77f
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ D I S P --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2005 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 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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Checks; use Checks;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Exp_Ch7; use Exp_Ch7;
33 with Exp_Tss; use Exp_Tss;
34 with Exp_Util; use Exp_Util;
35 with Fname; use Fname;
36 with Itypes; use Itypes;
37 with Lib; use Lib;
38 with Nlists; use Nlists;
39 with Nmake; use Nmake;
40 with Opt; use Opt;
41 with Rtsfind; use Rtsfind;
42 with Sem_Disp; use Sem_Disp;
43 with Sem_Res; use Sem_Res;
44 with Sem_Util; use Sem_Util;
45 with Sinfo; use Sinfo;
46 with Snames; use Snames;
47 with Stand; use Stand;
48 with Tbuild; use Tbuild;
49 with Uintp; use Uintp;
51 package body Exp_Disp is
53 Ada_Actions : constant array (DT_Access_Action) of RE_Id :=
54 (CW_Membership => RE_CW_Membership,
55 DT_Entry_Size => RE_DT_Entry_Size,
56 DT_Prologue_Size => RE_DT_Prologue_Size,
57 Get_External_Tag => RE_Get_External_Tag,
58 Get_Prim_Op_Address => RE_Get_Prim_Op_Address,
59 Get_RC_Offset => RE_Get_RC_Offset,
60 Get_Remotely_Callable => RE_Get_Remotely_Callable,
61 Inherit_DT => RE_Inherit_DT,
62 Inherit_TSD => RE_Inherit_TSD,
63 Register_Tag => RE_Register_Tag,
64 Set_Expanded_Name => RE_Set_Expanded_Name,
65 Set_External_Tag => RE_Set_External_Tag,
66 Set_Prim_Op_Address => RE_Set_Prim_Op_Address,
67 Set_RC_Offset => RE_Set_RC_Offset,
68 Set_Remotely_Callable => RE_Set_Remotely_Callable,
69 Set_TSD => RE_Set_TSD,
70 TSD_Entry_Size => RE_TSD_Entry_Size,
71 TSD_Prologue_Size => RE_TSD_Prologue_Size);
73 CPP_Actions : constant array (DT_Access_Action) of RE_Id :=
74 (CW_Membership => RE_CPP_CW_Membership,
75 DT_Entry_Size => RE_CPP_DT_Entry_Size,
76 DT_Prologue_Size => RE_CPP_DT_Prologue_Size,
77 Get_External_Tag => RE_CPP_Get_External_Tag,
78 Get_Prim_Op_Address => RE_CPP_Get_Prim_Op_Address,
79 Get_RC_Offset => RE_CPP_Get_RC_Offset,
80 Get_Remotely_Callable => RE_CPP_Get_Remotely_Callable,
81 Inherit_DT => RE_CPP_Inherit_DT,
82 Inherit_TSD => RE_CPP_Inherit_TSD,
83 Register_Tag => RE_CPP_Register_Tag,
84 Set_Expanded_Name => RE_CPP_Set_Expanded_Name,
85 Set_External_Tag => RE_CPP_Set_External_Tag,
86 Set_Prim_Op_Address => RE_CPP_Set_Prim_Op_Address,
87 Set_RC_Offset => RE_CPP_Set_RC_Offset,
88 Set_Remotely_Callable => RE_CPP_Set_Remotely_Callable,
89 Set_TSD => RE_CPP_Set_TSD,
90 TSD_Entry_Size => RE_CPP_TSD_Entry_Size,
91 TSD_Prologue_Size => RE_CPP_TSD_Prologue_Size);
93 Action_Is_Proc : constant array (DT_Access_Action) of Boolean :=
94 (CW_Membership => False,
95 DT_Entry_Size => False,
96 DT_Prologue_Size => False,
97 Get_External_Tag => False,
98 Get_Prim_Op_Address => False,
99 Get_Remotely_Callable => False,
100 Get_RC_Offset => False,
101 Inherit_DT => True,
102 Inherit_TSD => True,
103 Register_Tag => True,
104 Set_Expanded_Name => True,
105 Set_External_Tag => True,
106 Set_Prim_Op_Address => True,
107 Set_RC_Offset => True,
108 Set_Remotely_Callable => True,
109 Set_TSD => True,
110 TSD_Entry_Size => False,
111 TSD_Prologue_Size => False);
113 Action_Nb_Arg : constant array (DT_Access_Action) of Int :=
114 (CW_Membership => 2,
115 DT_Entry_Size => 0,
116 DT_Prologue_Size => 0,
117 Get_External_Tag => 1,
118 Get_Prim_Op_Address => 2,
119 Get_RC_Offset => 1,
120 Get_Remotely_Callable => 1,
121 Inherit_DT => 3,
122 Inherit_TSD => 2,
123 Register_Tag => 1,
124 Set_Expanded_Name => 2,
125 Set_External_Tag => 2,
126 Set_Prim_Op_Address => 3,
127 Set_RC_Offset => 2,
128 Set_Remotely_Callable => 2,
129 Set_TSD => 2,
130 TSD_Entry_Size => 0,
131 TSD_Prologue_Size => 0);
133 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
134 -- Check if the type has a private view or if the public view appears
135 -- in the visible part of a package spec.
137 -----------------------------
138 -- Expand_Dispatching_Call --
139 -----------------------------
141 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
142 Loc : constant Source_Ptr := Sloc (Call_Node);
143 Call_Typ : constant Entity_Id := Etype (Call_Node);
145 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
146 Param_List : constant List_Id := Parameter_Associations (Call_Node);
147 Subp : Entity_Id := Entity (Name (Call_Node));
149 CW_Typ : Entity_Id;
150 New_Call : Node_Id;
151 New_Call_Name : Node_Id;
152 New_Params : List_Id := No_List;
153 Param : Node_Id;
154 Res_Typ : Entity_Id;
155 Subp_Ptr_Typ : Entity_Id;
156 Subp_Typ : Entity_Id;
157 Typ : Entity_Id;
158 Eq_Prim_Op : Entity_Id := Empty;
159 Controlling_Tag : Node_Id;
161 function New_Value (From : Node_Id) return Node_Id;
162 -- From is the original Expression. New_Value is equivalent to a call
163 -- to Duplicate_Subexpr with an explicit dereference when From is an
164 -- access parameter.
166 function Controlling_Type (Subp : Entity_Id) return Entity_Id;
167 -- Returns the tagged type for which Subp is a primitive subprogram
169 ---------------
170 -- New_Value --
171 ---------------
173 function New_Value (From : Node_Id) return Node_Id is
174 Res : constant Node_Id := Duplicate_Subexpr (From);
175 begin
176 if Is_Access_Type (Etype (From)) then
177 return Make_Explicit_Dereference (Sloc (From), Res);
178 else
179 return Res;
180 end if;
181 end New_Value;
183 ----------------------
184 -- Controlling_Type --
185 ----------------------
187 function Controlling_Type (Subp : Entity_Id) return Entity_Id is
188 begin
189 if Ekind (Subp) = E_Function
190 and then Has_Controlling_Result (Subp)
191 then
192 return Base_Type (Etype (Subp));
194 else
195 declare
196 Formal : Entity_Id := First_Formal (Subp);
198 begin
199 while Present (Formal) loop
200 if Is_Controlling_Formal (Formal) then
201 if Is_Access_Type (Etype (Formal)) then
202 return Base_Type (Designated_Type (Etype (Formal)));
203 else
204 return Base_Type (Etype (Formal));
205 end if;
206 end if;
208 Next_Formal (Formal);
209 end loop;
210 end;
211 end if;
213 -- Controlling type not found (should never happen)
215 return Empty;
216 end Controlling_Type;
218 -- Start of processing for Expand_Dispatching_Call
220 begin
221 -- If this is an inherited operation that was overridden, the body
222 -- that is being called is its alias.
224 if Present (Alias (Subp))
225 and then Is_Inherited_Operation (Subp)
226 and then No (DTC_Entity (Subp))
227 then
228 Subp := Alias (Subp);
229 end if;
231 -- Expand_Dispatching_Call is called directly from the semantics,
232 -- so we need a check to see whether expansion is active before
233 -- proceeding.
235 if not Expander_Active then
236 return;
237 end if;
239 -- Definition of the class-wide type and the tagged type
241 -- If the controlling argument is itself a tag rather than a tagged
242 -- object, then use the class-wide type associated with the subprogram's
243 -- controlling type. This case can occur when a call to an inherited
244 -- primitive has an actual that originated from a default parameter
245 -- given by a tag-indeterminate call and when there is no other
246 -- controlling argument providing the tag (AI-239 requires dispatching).
247 -- This capability of dispatching directly by tag is also needed by the
248 -- implementation of AI-260 (for the generic dispatching constructors).
250 if Etype (Ctrl_Arg) = RTE (RE_Tag) then
251 CW_Typ := Class_Wide_Type (Controlling_Type (Subp));
253 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
254 CW_Typ := Designated_Type (Etype (Ctrl_Arg));
256 else
257 CW_Typ := Etype (Ctrl_Arg);
258 end if;
260 Typ := Root_Type (CW_Typ);
262 if not Is_Limited_Type (Typ) then
263 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
264 end if;
266 if Is_CPP_Class (Root_Type (Typ)) then
268 -- Create a new parameter list with the displaced 'this'
270 New_Params := New_List;
271 Param := First_Actual (Call_Node);
272 while Present (Param) loop
274 -- We assume that dispatching through the main dispatch table
275 -- (referenced by Tag_Component) doesn't require a displacement
276 -- so the expansion below is only done when dispatching on
277 -- another vtable pointer, in which case the first argument
278 -- is expanded into :
280 -- typ!(Displaced_This (Address!(Param)))
282 if Param = Ctrl_Arg
283 and then DTC_Entity (Subp) /= First_Tag_Component (Typ)
284 then
285 Append_To (New_Params,
287 Unchecked_Convert_To (Etype (Param),
288 Make_Function_Call (Loc,
289 Name => New_Reference_To (RTE (RE_Displaced_This), Loc),
290 Parameter_Associations => New_List (
292 -- Current_This
294 Make_Unchecked_Type_Conversion (Loc,
295 Subtype_Mark =>
296 New_Reference_To (RTE (RE_Address), Loc),
297 Expression => Relocate_Node (Param)),
299 -- Vptr
301 Make_Selected_Component (Loc,
302 Prefix => Duplicate_Subexpr (Ctrl_Arg),
303 Selector_Name =>
304 New_Reference_To (DTC_Entity (Subp), Loc)),
306 -- Position
308 Make_Integer_Literal (Loc, DT_Position (Subp))))));
310 else
311 Append_To (New_Params, Relocate_Node (Param));
312 end if;
314 Next_Actual (Param);
315 end loop;
317 elsif Present (Param_List) then
319 -- Generate the Tag checks when appropriate
321 New_Params := New_List;
323 Param := First_Actual (Call_Node);
324 while Present (Param) loop
326 -- No tag check with itself
328 if Param = Ctrl_Arg then
329 Append_To (New_Params,
330 Duplicate_Subexpr_Move_Checks (Param));
332 -- No tag check for parameter whose type is neither tagged nor
333 -- access to tagged (for access parameters)
335 elsif No (Find_Controlling_Arg (Param)) then
336 Append_To (New_Params, Relocate_Node (Param));
338 -- No tag check for function dispatching on result if the
339 -- Tag given by the context is this one
341 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
342 Append_To (New_Params, Relocate_Node (Param));
344 -- "=" is the only dispatching operation allowed to get
345 -- operands with incompatible tags (it just returns false).
346 -- We use Duplicate_Subexpr_Move_Checks instead of calling
347 -- Relocate_Node because the value will be duplicated to
348 -- check the tags.
350 elsif Subp = Eq_Prim_Op then
351 Append_To (New_Params,
352 Duplicate_Subexpr_Move_Checks (Param));
354 -- No check in presence of suppress flags
356 elsif Tag_Checks_Suppressed (Etype (Param))
357 or else (Is_Access_Type (Etype (Param))
358 and then Tag_Checks_Suppressed
359 (Designated_Type (Etype (Param))))
360 then
361 Append_To (New_Params, Relocate_Node (Param));
363 -- Optimization: no tag checks if the parameters are identical
365 elsif Is_Entity_Name (Param)
366 and then Is_Entity_Name (Ctrl_Arg)
367 and then Entity (Param) = Entity (Ctrl_Arg)
368 then
369 Append_To (New_Params, Relocate_Node (Param));
371 -- Now we need to generate the Tag check
373 else
374 -- Generate code for tag equality check
375 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
377 Insert_Action (Ctrl_Arg,
378 Make_Implicit_If_Statement (Call_Node,
379 Condition =>
380 Make_Op_Ne (Loc,
381 Left_Opnd =>
382 Make_Selected_Component (Loc,
383 Prefix => New_Value (Ctrl_Arg),
384 Selector_Name =>
385 New_Reference_To
386 (First_Tag_Component (Typ), Loc)),
388 Right_Opnd =>
389 Make_Selected_Component (Loc,
390 Prefix =>
391 Unchecked_Convert_To (Typ, New_Value (Param)),
392 Selector_Name =>
393 New_Reference_To
394 (First_Tag_Component (Typ), Loc))),
396 Then_Statements =>
397 New_List (New_Constraint_Error (Loc))));
399 Append_To (New_Params, Relocate_Node (Param));
400 end if;
402 Next_Actual (Param);
403 end loop;
404 end if;
406 -- Generate the appropriate subprogram pointer type
408 if Etype (Subp) = Typ then
409 Res_Typ := CW_Typ;
410 else
411 Res_Typ := Etype (Subp);
412 end if;
414 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
415 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
416 Set_Etype (Subp_Typ, Res_Typ);
417 Init_Size_Align (Subp_Ptr_Typ);
418 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
420 -- Create a new list of parameters which is a copy of the old formal
421 -- list including the creation of a new set of matching entities.
423 declare
424 Old_Formal : Entity_Id := First_Formal (Subp);
425 New_Formal : Entity_Id;
426 Extra : Entity_Id;
428 begin
429 if Present (Old_Formal) then
430 New_Formal := New_Copy (Old_Formal);
431 Set_First_Entity (Subp_Typ, New_Formal);
432 Param := First_Actual (Call_Node);
434 loop
435 Set_Scope (New_Formal, Subp_Typ);
437 -- Change all the controlling argument types to be class-wide
438 -- to avoid a recursion in dispatching.
440 if Is_Controlling_Formal (New_Formal) then
441 Set_Etype (New_Formal, Etype (Param));
442 end if;
444 if Is_Itype (Etype (New_Formal)) then
445 Extra := New_Copy (Etype (New_Formal));
447 if Ekind (Extra) = E_Record_Subtype
448 or else Ekind (Extra) = E_Class_Wide_Subtype
449 then
450 Set_Cloned_Subtype (Extra, Etype (New_Formal));
451 end if;
453 Set_Etype (New_Formal, Extra);
454 Set_Scope (Etype (New_Formal), Subp_Typ);
455 end if;
457 Extra := New_Formal;
458 Next_Formal (Old_Formal);
459 exit when No (Old_Formal);
461 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
462 Next_Entity (New_Formal);
463 Next_Actual (Param);
464 end loop;
465 Set_Last_Entity (Subp_Typ, Extra);
467 -- Copy extra formals
469 New_Formal := First_Entity (Subp_Typ);
470 while Present (New_Formal) loop
471 if Present (Extra_Constrained (New_Formal)) then
472 Set_Extra_Formal (Extra,
473 New_Copy (Extra_Constrained (New_Formal)));
474 Extra := Extra_Formal (Extra);
475 Set_Extra_Constrained (New_Formal, Extra);
477 elsif Present (Extra_Accessibility (New_Formal)) then
478 Set_Extra_Formal (Extra,
479 New_Copy (Extra_Accessibility (New_Formal)));
480 Extra := Extra_Formal (Extra);
481 Set_Extra_Accessibility (New_Formal, Extra);
482 end if;
484 Next_Formal (New_Formal);
485 end loop;
486 end if;
487 end;
489 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
490 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
492 -- If the controlling argument is a value of type Ada.Tag then
493 -- use it directly. Otherwise, the tag must be extracted from
494 -- the controlling object.
496 if Etype (Ctrl_Arg) = RTE (RE_Tag) then
497 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
499 else
500 Controlling_Tag :=
501 Make_Selected_Component (Loc,
502 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
503 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
504 end if;
506 -- Generate:
507 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
509 New_Call_Name :=
510 Unchecked_Convert_To (Subp_Ptr_Typ,
511 Make_DT_Access_Action (Typ,
512 Action => Get_Prim_Op_Address,
513 Args => New_List (
515 -- Vptr
517 Controlling_Tag,
519 -- Position
521 Make_Integer_Literal (Loc, DT_Position (Subp)))));
523 if Nkind (Call_Node) = N_Function_Call then
524 New_Call :=
525 Make_Function_Call (Loc,
526 Name => New_Call_Name,
527 Parameter_Associations => New_Params);
529 -- If this is a dispatching "=", we must first compare the tags so
530 -- we generate: x.tag = y.tag and then x = y
532 if Subp = Eq_Prim_Op then
533 Param := First_Actual (Call_Node);
534 New_Call :=
535 Make_And_Then (Loc,
536 Left_Opnd =>
537 Make_Op_Eq (Loc,
538 Left_Opnd =>
539 Make_Selected_Component (Loc,
540 Prefix => New_Value (Param),
541 Selector_Name =>
542 New_Reference_To
543 (First_Tag_Component (Typ), Loc)),
545 Right_Opnd =>
546 Make_Selected_Component (Loc,
547 Prefix =>
548 Unchecked_Convert_To (Typ,
549 New_Value (Next_Actual (Param))),
550 Selector_Name =>
551 New_Reference_To
552 (First_Tag_Component (Typ), Loc))),
554 Right_Opnd => New_Call);
555 end if;
557 else
558 New_Call :=
559 Make_Procedure_Call_Statement (Loc,
560 Name => New_Call_Name,
561 Parameter_Associations => New_Params);
562 end if;
564 Rewrite (Call_Node, New_Call);
565 Analyze_And_Resolve (Call_Node, Call_Typ);
566 end Expand_Dispatching_Call;
568 -------------
569 -- Fill_DT --
570 -------------
572 function Fill_DT_Entry
573 (Loc : Source_Ptr;
574 Prim : Entity_Id)
575 return Node_Id
577 Typ : constant Entity_Id := Scope (DTC_Entity (Prim));
578 DT_Ptr : constant Entity_Id := Node (First_Elmt
579 (Access_Disp_Table (Typ)));
581 begin
582 return
583 Make_DT_Access_Action (Typ,
584 Action => Set_Prim_Op_Address,
585 Args => New_List (
586 New_Reference_To (DT_Ptr, Loc), -- DTptr
588 Make_Integer_Literal (Loc, DT_Position (Prim)), -- Position
590 Make_Attribute_Reference (Loc, -- Value
591 Prefix => New_Reference_To (Prim, Loc),
592 Attribute_Name => Name_Address)));
593 end Fill_DT_Entry;
595 ---------------------------
596 -- Get_Remotely_Callable --
597 ---------------------------
599 function Get_Remotely_Callable (Obj : Node_Id) return Node_Id is
600 Loc : constant Source_Ptr := Sloc (Obj);
602 begin
603 return Make_DT_Access_Action
604 (Typ => Etype (Obj),
605 Action => Get_Remotely_Callable,
606 Args => New_List (
607 Make_Selected_Component (Loc,
608 Prefix => Obj,
609 Selector_Name => Make_Identifier (Loc, Name_uTag))));
610 end Get_Remotely_Callable;
612 -------------
613 -- Make_DT --
614 -------------
616 function Make_DT (Typ : Entity_Id) return List_Id is
617 Loc : constant Source_Ptr := Sloc (Typ);
619 ADT_List : constant Elist_Id := New_Elmt_List;
620 Result : constant List_Id := New_List;
621 Elab_Code : constant List_Id := New_List;
623 Tname : constant Name_Id := Chars (Typ);
624 Name_DT : constant Name_Id := New_External_Name (Tname, 'T');
625 Name_DT_Ptr : constant Name_Id := New_External_Name (Tname, 'P');
626 Name_TSD : constant Name_Id := New_External_Name (Tname, 'B');
627 Name_Exname : constant Name_Id := New_External_Name (Tname, 'E');
628 Name_No_Reg : constant Name_Id := New_External_Name (Tname, 'F');
630 DT : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT);
631 DT_Ptr : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT_Ptr);
632 TSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_TSD);
633 Exname : constant Node_Id := Make_Defining_Identifier (Loc, Name_Exname);
634 No_Reg : constant Node_Id := Make_Defining_Identifier (Loc, Name_No_Reg);
636 I_Depth : Int;
637 Generalized_Tag : Entity_Id;
638 Size_Expr_Node : Node_Id;
639 Old_Tag1 : Node_Id;
640 Old_Tag2 : Node_Id;
642 begin
643 if not RTE_Available (RE_Tag) then
644 Error_Msg_CRT ("tagged types", Typ);
645 return New_List;
646 end if;
648 if Is_CPP_Class (Root_Type (Typ)) then
649 Generalized_Tag := RTE (RE_Vtable_Ptr);
650 else
651 Generalized_Tag := RTE (RE_Tag);
652 end if;
654 -- Dispatch table and related entities are allocated statically
656 Set_Ekind (DT, E_Variable);
657 Set_Is_Statically_Allocated (DT);
659 Set_Ekind (DT_Ptr, E_Variable);
660 Set_Is_Statically_Allocated (DT_Ptr);
662 Set_Ekind (TSD, E_Variable);
663 Set_Is_Statically_Allocated (TSD);
665 Set_Ekind (Exname, E_Variable);
666 Set_Is_Statically_Allocated (Exname);
668 Set_Ekind (No_Reg, E_Variable);
669 Set_Is_Statically_Allocated (No_Reg);
671 -- Generate code to create the storage for the Dispatch_Table object:
673 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
674 -- for DT'Alignment use Address'Alignment
676 Size_Expr_Node :=
677 Make_Op_Add (Loc,
678 Left_Opnd => Make_DT_Access_Action (Typ, DT_Prologue_Size, No_List),
679 Right_Opnd =>
680 Make_Op_Multiply (Loc,
681 Left_Opnd =>
682 Make_DT_Access_Action (Typ, DT_Entry_Size, No_List),
683 Right_Opnd =>
684 Make_Integer_Literal (Loc,
685 DT_Entry_Count (First_Tag_Component (Typ)))));
687 Append_To (Result,
688 Make_Object_Declaration (Loc,
689 Defining_Identifier => DT,
690 Aliased_Present => True,
691 Object_Definition =>
692 Make_Subtype_Indication (Loc,
693 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
694 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
695 Constraints => New_List (
696 Make_Range (Loc,
697 Low_Bound => Make_Integer_Literal (Loc, 1),
698 High_Bound => Size_Expr_Node))))));
700 Append_To (Result,
701 Make_Attribute_Definition_Clause (Loc,
702 Name => New_Reference_To (DT, Loc),
703 Chars => Name_Alignment,
704 Expression =>
705 Make_Attribute_Reference (Loc,
706 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
707 Attribute_Name => Name_Alignment)));
709 -- Generate code to create the pointer to the dispatch table
711 -- DT_Ptr : Tag := Tag!(DT'Address); Ada case
712 -- or
713 -- DT_Ptr : Vtable_Ptr := Vtable_Ptr!(DT'Address); CPP case
715 -- According to the C++ ABI, the base of the vtable is located
716 -- after the following prologue: Offset_To_Top, Typeinfo_Ptr.
717 -- Hence, move the pointer to the base of the vtable down, after
718 -- this prologue.
720 Append_To (Result,
721 Make_Object_Declaration (Loc,
722 Defining_Identifier => DT_Ptr,
723 Constant_Present => True,
724 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
725 Expression =>
726 Unchecked_Convert_To (Generalized_Tag,
727 Make_Op_Add (Loc,
728 Left_Opnd =>
729 Unchecked_Convert_To (RTE (RE_Storage_Offset),
730 Make_Attribute_Reference (Loc,
731 Prefix => New_Reference_To (DT, Loc),
732 Attribute_Name => Name_Address)),
733 Right_Opnd =>
734 Make_DT_Access_Action (Typ,
735 DT_Prologue_Size, No_List)))));
737 -- Generate code to define the boolean that controls registration, in
738 -- order to avoid multiple registrations for tagged types defined in
739 -- multiple-called scopes
741 Append_To (Result,
742 Make_Object_Declaration (Loc,
743 Defining_Identifier => No_Reg,
744 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
745 Expression => New_Reference_To (Standard_True, Loc)));
747 -- Set Access_Disp_Table field to be the dispatch table pointer
749 Append_Elmt (DT_Ptr, ADT_List);
750 Set_Access_Disp_Table (Typ, ADT_List);
752 -- Count ancestors to compute the inheritance depth. For private
753 -- extensions, always go to the full view in order to compute the real
754 -- inheritance depth.
756 declare
757 Parent_Type : Entity_Id := Typ;
758 P : Entity_Id;
760 begin
761 I_Depth := 0;
763 loop
764 P := Etype (Parent_Type);
766 if Is_Private_Type (P) then
767 P := Full_View (Base_Type (P));
768 end if;
770 exit when P = Parent_Type;
772 I_Depth := I_Depth + 1;
773 Parent_Type := P;
774 end loop;
775 end;
777 -- Generate code to create the storage for the type specific data object
779 -- TSD: Storage_Array (1..TSD_Prologue_Size+(1+Idepth)*TSD_Entry_Size);
780 -- for TSD'Alignment use Address'Alignment
782 Size_Expr_Node :=
783 Make_Op_Add (Loc,
784 Left_Opnd =>
785 Make_DT_Access_Action (Typ, TSD_Prologue_Size, No_List),
786 Right_Opnd =>
787 Make_Op_Multiply (Loc,
788 Left_Opnd =>
789 Make_DT_Access_Action (Typ, TSD_Entry_Size, No_List),
790 Right_Opnd =>
791 Make_Op_Add (Loc,
792 Left_Opnd => Make_Integer_Literal (Loc, 1),
793 Right_Opnd =>
794 Make_Integer_Literal (Loc, I_Depth))));
796 Append_To (Result,
797 Make_Object_Declaration (Loc,
798 Defining_Identifier => TSD,
799 Aliased_Present => True,
800 Object_Definition =>
801 Make_Subtype_Indication (Loc,
802 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
803 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
804 Constraints => New_List (
805 Make_Range (Loc,
806 Low_Bound => Make_Integer_Literal (Loc, 1),
807 High_Bound => Size_Expr_Node))))));
809 Append_To (Result,
810 Make_Attribute_Definition_Clause (Loc,
811 Name => New_Reference_To (TSD, Loc),
812 Chars => Name_Alignment,
813 Expression =>
814 Make_Attribute_Reference (Loc,
815 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
816 Attribute_Name => Name_Alignment)));
818 -- Generate code to put the Address of the TSD in the dispatch table
819 -- Set_TSD (DT_Ptr, TSD);
821 Append_To (Elab_Code,
822 Make_DT_Access_Action (Typ,
823 Action => Set_TSD,
824 Args => New_List (
825 New_Reference_To (DT_Ptr, Loc), -- DTptr
826 Make_Attribute_Reference (Loc, -- Value
827 Prefix => New_Reference_To (TSD, Loc),
828 Attribute_Name => Name_Address))));
830 if Typ = Etype (Typ)
831 or else Is_CPP_Class (Etype (Typ))
832 then
833 Old_Tag1 :=
834 Unchecked_Convert_To (Generalized_Tag,
835 Make_Integer_Literal (Loc, 0));
836 Old_Tag2 :=
837 Unchecked_Convert_To (Generalized_Tag,
838 Make_Integer_Literal (Loc, 0));
840 else
841 Old_Tag1 :=
842 New_Reference_To
843 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
844 Old_Tag2 :=
845 New_Reference_To
846 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
847 end if;
849 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
851 Append_To (Elab_Code,
852 Make_DT_Access_Action (Typ,
853 Action => Inherit_DT,
854 Args => New_List (
855 Node1 => Old_Tag1,
856 Node2 => New_Reference_To (DT_Ptr, Loc),
857 Node3 => Make_Integer_Literal (Loc,
858 DT_Entry_Count (First_Tag_Component (Etype (Typ)))))));
860 -- Generate: Inherit_TSD (parent'tag, DT_Ptr);
862 Append_To (Elab_Code,
863 Make_DT_Access_Action (Typ,
864 Action => Inherit_TSD,
865 Args => New_List (
866 Node1 => Old_Tag2,
867 Node2 => New_Reference_To (DT_Ptr, Loc))));
869 -- Generate: Exname : constant String := full_qualified_name (typ);
870 -- The type itself may be an anonymous parent type, so use the first
871 -- subtype to have a user-recognizable name.
873 Append_To (Result,
874 Make_Object_Declaration (Loc,
875 Defining_Identifier => Exname,
876 Constant_Present => True,
877 Object_Definition => New_Reference_To (Standard_String, Loc),
878 Expression =>
879 Make_String_Literal (Loc,
880 Full_Qualified_Name (First_Subtype (Typ)))));
882 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
884 Append_To (Elab_Code,
885 Make_DT_Access_Action (Typ,
886 Action => Set_Expanded_Name,
887 Args => New_List (
888 Node1 => New_Reference_To (DT_Ptr, Loc),
889 Node2 =>
890 Make_Attribute_Reference (Loc,
891 Prefix => New_Reference_To (Exname, Loc),
892 Attribute_Name => Name_Address))));
894 -- for types with no controlled components
895 -- Generate: Set_RC_Offset (DT_Ptr, 0);
896 -- for simple types with controlled components
897 -- Generate: Set_RC_Offset (DT_Ptr, type._record_controller'position);
898 -- for complex types with controlled components where the position
899 -- of the record controller is not statically computable, if there are
900 -- controlled components at this level
901 -- Generate: Set_RC_Offset (DT_Ptr, -1);
902 -- to indicate that the _controller field is right after the _parent or
903 -- if there are no controlled components at this level,
904 -- Generate: Set_RC_Offset (DT_Ptr, -2);
905 -- to indicate that we need to get the position from the parent.
907 declare
908 Position : Node_Id;
910 begin
911 if not Has_Controlled_Component (Typ) then
912 Position := Make_Integer_Literal (Loc, 0);
914 elsif Etype (Typ) /= Typ and then Has_Discriminants (Etype (Typ)) then
915 if Has_New_Controlled_Component (Typ) then
916 Position := Make_Integer_Literal (Loc, -1);
917 else
918 Position := Make_Integer_Literal (Loc, -2);
919 end if;
920 else
921 Position :=
922 Make_Attribute_Reference (Loc,
923 Prefix =>
924 Make_Selected_Component (Loc,
925 Prefix => New_Reference_To (Typ, Loc),
926 Selector_Name =>
927 New_Reference_To (Controller_Component (Typ), Loc)),
928 Attribute_Name => Name_Position);
930 -- This is not proper Ada code to use the attribute 'Position
931 -- on something else than an object but this is supported by
932 -- the back end (see comment on the Bit_Component attribute in
933 -- sem_attr). So we avoid semantic checking here.
935 Set_Analyzed (Position);
936 Set_Etype (Prefix (Position), RTE (RE_Record_Controller));
937 Set_Etype (Prefix (Prefix (Position)), Typ);
938 Set_Etype (Selector_Name (Prefix (Position)),
939 RTE (RE_Record_Controller));
940 Set_Etype (Position, RTE (RE_Storage_Offset));
941 end if;
943 Append_To (Elab_Code,
944 Make_DT_Access_Action (Typ,
945 Action => Set_RC_Offset,
946 Args => New_List (
947 Node1 => New_Reference_To (DT_Ptr, Loc),
948 Node2 => Position)));
949 end;
951 -- Generate: Set_Remotely_Callable (DT_Ptr, Status);
952 -- where Status is described in E.4 (18)
954 declare
955 Status : Entity_Id;
957 begin
958 Status :=
959 Boolean_Literals
960 (Is_Pure (Typ)
961 or else Is_Shared_Passive (Typ)
962 or else
963 ((Is_Remote_Types (Typ)
964 or else Is_Remote_Call_Interface (Typ))
965 and then Original_View_In_Visible_Part (Typ))
966 or else not Comes_From_Source (Typ));
968 Append_To (Elab_Code,
969 Make_DT_Access_Action (Typ,
970 Action => Set_Remotely_Callable,
971 Args => New_List (
972 New_Occurrence_Of (DT_Ptr, Loc),
973 New_Occurrence_Of (Status, Loc))));
974 end;
976 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
977 -- Should be the external name not the qualified name???
979 if not Has_External_Tag_Rep_Clause (Typ) then
980 Append_To (Elab_Code,
981 Make_DT_Access_Action (Typ,
982 Action => Set_External_Tag,
983 Args => New_List (
984 Node1 => New_Reference_To (DT_Ptr, Loc),
985 Node2 =>
986 Make_Attribute_Reference (Loc,
987 Prefix => New_Reference_To (Exname, Loc),
988 Attribute_Name => Name_Address))));
990 -- Generate code to register the Tag in the External_Tag hash
991 -- table for the pure Ada type only.
993 -- Register_Tag (Dt_Ptr);
995 -- Skip this if routine not available, or in No_Run_Time mode
997 if RTE_Available (RE_Register_Tag)
998 and then Is_RTE (Generalized_Tag, RE_Tag)
999 and then not No_Run_Time_Mode
1000 then
1001 Append_To (Elab_Code,
1002 Make_Procedure_Call_Statement (Loc,
1003 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
1004 Parameter_Associations =>
1005 New_List (New_Reference_To (DT_Ptr, Loc))));
1006 end if;
1007 end if;
1009 -- Generate:
1010 -- if No_Reg then
1011 -- <elab_code>
1012 -- No_Reg := False;
1013 -- end if;
1015 Append_To (Elab_Code,
1016 Make_Assignment_Statement (Loc,
1017 Name => New_Reference_To (No_Reg, Loc),
1018 Expression => New_Reference_To (Standard_False, Loc)));
1020 Append_To (Result,
1021 Make_Implicit_If_Statement (Typ,
1022 Condition => New_Reference_To (No_Reg, Loc),
1023 Then_Statements => Elab_Code));
1025 return Result;
1026 end Make_DT;
1028 ---------------------------
1029 -- Make_DT_Access_Action --
1030 ---------------------------
1032 function Make_DT_Access_Action
1033 (Typ : Entity_Id;
1034 Action : DT_Access_Action;
1035 Args : List_Id)
1036 return Node_Id
1038 Action_Name : Entity_Id;
1039 Loc : Source_Ptr;
1041 begin
1042 if Is_CPP_Class (Root_Type (Typ)) then
1043 Action_Name := RTE (CPP_Actions (Action));
1044 else
1045 Action_Name := RTE (Ada_Actions (Action));
1046 end if;
1048 if No (Args) then
1050 -- This is a constant
1052 return New_Reference_To (Action_Name, Sloc (Typ));
1053 end if;
1055 pragma Assert (List_Length (Args) = Action_Nb_Arg (Action));
1057 Loc := Sloc (First (Args));
1059 if Action_Is_Proc (Action) then
1060 return
1061 Make_Procedure_Call_Statement (Loc,
1062 Name => New_Reference_To (Action_Name, Loc),
1063 Parameter_Associations => Args);
1065 else
1066 return
1067 Make_Function_Call (Loc,
1068 Name => New_Reference_To (Action_Name, Loc),
1069 Parameter_Associations => Args);
1070 end if;
1071 end Make_DT_Access_Action;
1073 -----------------------------------
1074 -- Original_View_In_Visible_Part --
1075 -----------------------------------
1077 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
1078 Scop : constant Entity_Id := Scope (Typ);
1080 begin
1081 -- The scope must be a package
1083 if Ekind (Scop) /= E_Package
1084 and then Ekind (Scop) /= E_Generic_Package
1085 then
1086 return False;
1087 end if;
1089 -- A type with a private declaration has a private view declared in
1090 -- the visible part.
1092 if Has_Private_Declaration (Typ) then
1093 return True;
1094 end if;
1096 return List_Containing (Parent (Typ)) =
1097 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
1098 end Original_View_In_Visible_Part;
1100 -------------------------
1101 -- Set_All_DT_Position --
1102 -------------------------
1104 procedure Set_All_DT_Position (Typ : Entity_Id) is
1105 Parent_Typ : constant Entity_Id := Etype (Typ);
1106 Root_Typ : constant Entity_Id := Root_Type (Typ);
1107 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
1108 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
1109 Adjusted : Boolean := False;
1110 Finalized : Boolean := False;
1111 Parent_EC : Int;
1112 Nb_Prim : Int;
1113 Prim : Entity_Id;
1114 Prim_Elmt : Elmt_Id;
1116 begin
1118 -- Get Entry_Count of the parent
1120 if Parent_Typ /= Typ
1121 and then DT_Entry_Count (First_Tag_Component (Parent_Typ)) /= No_Uint
1122 then
1123 Parent_EC := UI_To_Int (DT_Entry_Count
1124 (First_Tag_Component (Parent_Typ)));
1125 else
1126 Parent_EC := 0;
1127 end if;
1129 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
1130 -- give a coherent set of information
1132 if Is_CPP_Class (Root_Typ) then
1134 -- Compute the number of primitive operations in the main Vtable
1135 -- Set their position:
1136 -- - where it was set if overriden or inherited
1137 -- - after the end of the parent vtable otherwise
1139 Prim_Elmt := First_Prim;
1140 Nb_Prim := 0;
1141 while Present (Prim_Elmt) loop
1142 Prim := Node (Prim_Elmt);
1144 if not Is_CPP_Class (Typ) then
1145 Set_DTC_Entity (Prim, The_Tag);
1147 elsif Present (Alias (Prim)) then
1148 Set_DTC_Entity (Prim, DTC_Entity (Alias (Prim)));
1149 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
1151 elsif No (DTC_Entity (Prim)) and then Is_CPP_Class (Typ) then
1152 Error_Msg_NE ("is a primitive operation of&," &
1153 " pragma Cpp_Virtual required", Prim, Typ);
1154 end if;
1156 if DTC_Entity (Prim) = The_Tag then
1158 -- Get the slot from the parent subprogram if any
1160 declare
1161 H : Entity_Id := Homonym (Prim);
1163 begin
1164 while Present (H) loop
1165 if Present (DTC_Entity (H))
1166 and then Root_Type (Scope (DTC_Entity (H))) = Root_Typ
1167 then
1168 Set_DT_Position (Prim, DT_Position (H));
1169 exit;
1170 end if;
1172 H := Homonym (H);
1173 end loop;
1174 end;
1176 -- Otherwise take the canonical slot after the end of the
1177 -- parent Vtable
1179 if DT_Position (Prim) = No_Uint then
1180 Nb_Prim := Nb_Prim + 1;
1181 Set_DT_Position (Prim, UI_From_Int (Parent_EC + Nb_Prim));
1183 elsif UI_To_Int (DT_Position (Prim)) > Parent_EC then
1184 Nb_Prim := Nb_Prim + 1;
1185 end if;
1186 end if;
1188 Next_Elmt (Prim_Elmt);
1189 end loop;
1191 -- Check that the declared size of the Vtable is bigger or equal
1192 -- than the number of primitive operations (if bigger it means that
1193 -- some of the c++ virtual functions were not imported, that is
1194 -- allowed)
1196 if DT_Entry_Count (The_Tag) = No_Uint
1197 or else not Is_CPP_Class (Typ)
1198 then
1199 Set_DT_Entry_Count (The_Tag, UI_From_Int (Parent_EC + Nb_Prim));
1201 elsif UI_To_Int (DT_Entry_Count (The_Tag)) < Parent_EC + Nb_Prim then
1202 Error_Msg_N ("not enough room in the Vtable for all virtual"
1203 & " functions", The_Tag);
1204 end if;
1206 -- Check that Positions are not duplicate nor outside the range of
1207 -- the Vtable
1209 declare
1210 Size : constant Int := UI_To_Int (DT_Entry_Count (The_Tag));
1211 Pos : Int;
1212 Prim_Pos_Table : array (1 .. Size) of Entity_Id :=
1213 (others => Empty);
1215 begin
1216 Prim_Elmt := First_Prim;
1217 while Present (Prim_Elmt) loop
1218 Prim := Node (Prim_Elmt);
1220 if DTC_Entity (Prim) = The_Tag then
1221 Pos := UI_To_Int (DT_Position (Prim));
1223 if Pos not in Prim_Pos_Table'Range then
1224 Error_Msg_N
1225 ("position not in range of virtual table", Prim);
1227 elsif Present (Prim_Pos_Table (Pos)) then
1228 Error_Msg_NE ("cannot be at the same position in the"
1229 & " vtable than&", Prim, Prim_Pos_Table (Pos));
1231 else
1232 Prim_Pos_Table (Pos) := Prim;
1233 end if;
1234 end if;
1236 Next_Elmt (Prim_Elmt);
1237 end loop;
1238 end;
1240 -- For regular Ada tagged types, just set the DT_Position for
1241 -- each primitive operation. Perform some sanity checks to avoid
1242 -- to build completely inconsistant dispatch tables.
1244 -- Note that the _Size primitive is always set at position 1 in order
1245 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
1246 -- in a-tags.ad?)
1248 else
1249 Nb_Prim := 1;
1250 Prim_Elmt := First_Prim;
1251 while Present (Prim_Elmt) loop
1252 Nb_Prim := Nb_Prim + 1;
1253 Prim := Node (Prim_Elmt);
1254 Set_DTC_Entity (Prim, The_Tag);
1256 if Chars (Prim) = Name_uSize then
1257 Set_DT_Position (Prim, Uint_1);
1258 Nb_Prim := Nb_Prim - 1;
1259 else
1260 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
1261 end if;
1263 if Chars (Prim) = Name_Finalize
1264 and then
1265 (Is_Predefined_File_Name (Unit_File_Name (Current_Sem_Unit))
1266 or else not Is_Predefined_File_Name
1267 (Unit_File_Name (Get_Source_Unit (Prim))))
1268 then
1269 Finalized := True;
1270 end if;
1272 if Chars (Prim) = Name_Adjust then
1273 Adjusted := True;
1274 end if;
1276 -- An abstract operation cannot be declared in the private part
1277 -- for a visible abstract type, because it could never be over-
1278 -- ridden. For explicit declarations this is checked at the point
1279 -- of declaration, but for inherited operations it must be done
1280 -- when building the dispatch table. Input is excluded because
1282 if Is_Abstract (Typ)
1283 and then Is_Abstract (Prim)
1284 and then Present (Alias (Prim))
1285 and then Is_Derived_Type (Typ)
1286 and then In_Private_Part (Current_Scope)
1287 and then List_Containing (Parent (Prim))
1288 = Private_Declarations
1289 (Specification (Unit_Declaration_Node (Current_Scope)))
1290 and then Original_View_In_Visible_Part (Typ)
1291 then
1292 -- We exclude Input and Output stream operations because
1293 -- Limited_Controlled inherits useless Input and Output
1294 -- stream operations from Root_Controlled, which can
1295 -- never be overridden.
1297 if not Is_TSS (Prim, TSS_Stream_Input)
1298 and then
1299 not Is_TSS (Prim, TSS_Stream_Output)
1300 then
1301 Error_Msg_NE
1302 ("abstract inherited private operation&" &
1303 " must be overridden ('R'M 3.9.3(10))",
1304 Parent (Typ), Prim);
1305 end if;
1306 end if;
1307 Next_Elmt (Prim_Elmt);
1308 end loop;
1310 if Is_Controlled (Typ) then
1311 if not Finalized then
1312 Error_Msg_N
1313 ("controlled type has no explicit Finalize method?", Typ);
1315 elsif not Adjusted then
1316 Error_Msg_N
1317 ("controlled type has no explicit Adjust method?", Typ);
1318 end if;
1319 end if;
1321 Set_DT_Entry_Count (The_Tag, UI_From_Int (Nb_Prim));
1323 -- The derived type must have at least as many components as its
1324 -- parent (for root types, the Etype points back to itself
1325 -- and the test should not fail)
1327 pragma Assert (
1328 DT_Entry_Count (The_Tag) >=
1329 DT_Entry_Count (First_Tag_Component (Parent_Typ)));
1330 end if;
1331 end Set_All_DT_Position;
1333 -----------------------------
1334 -- Set_Default_Constructor --
1335 -----------------------------
1337 procedure Set_Default_Constructor (Typ : Entity_Id) is
1338 Loc : Source_Ptr;
1339 Init : Entity_Id;
1340 Param : Entity_Id;
1341 E : Entity_Id;
1343 begin
1344 -- Look for the default constructor entity. For now only the
1345 -- default constructor has the flag Is_Constructor.
1347 E := Next_Entity (Typ);
1348 while Present (E)
1349 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
1350 loop
1351 Next_Entity (E);
1352 end loop;
1354 -- Create the init procedure
1356 if Present (E) then
1357 Loc := Sloc (E);
1358 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
1359 Param := Make_Defining_Identifier (Loc, Name_X);
1361 Discard_Node (
1362 Make_Subprogram_Declaration (Loc,
1363 Make_Procedure_Specification (Loc,
1364 Defining_Unit_Name => Init,
1365 Parameter_Specifications => New_List (
1366 Make_Parameter_Specification (Loc,
1367 Defining_Identifier => Param,
1368 Parameter_Type => New_Reference_To (Typ, Loc))))));
1370 Set_Init_Proc (Typ, Init);
1371 Set_Is_Imported (Init);
1372 Set_Interface_Name (Init, Interface_Name (E));
1373 Set_Convention (Init, Convention_C);
1374 Set_Is_Public (Init);
1375 Set_Has_Completion (Init);
1377 -- If there are no constructors, mark the type as abstract since we
1378 -- won't be able to declare objects of that type.
1380 else
1381 Set_Is_Abstract (Typ);
1382 end if;
1383 end Set_Default_Constructor;
1385 end Exp_Disp;