with Sinfo; use Sinfo;
with Snames; use Snames;
with Stand; use Stand;
-with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
-- with tagged components, but not clear whether it's worthwhile ???;
-- in the case of the JVM, object tags are handled implicitly)
- if Is_Tagged_Type (Component_Type (Typ)) and then VM_Target = No_VM then
+ if Is_Tagged_Type (Component_Type (Typ))
+ and then Tagged_Type_Expansion
+ then
return False;
end if;
Append_To (L, A);
-- Adjust the tag if tagged (because of possible view
- -- conversions), unless compiling for the Java VM where
+ -- conversions), unless compiling for a VM where
-- tags are implicit.
if Present (Comp_Type)
and then Is_Tagged_Type (Comp_Type)
- and then VM_Target = No_VM
+ and then Tagged_Type_Expansion
then
A :=
Make_OK_Assignment_Statement (Loc,
end if;
end Gen_Ctrl_Actions_For_Aggr;
+ function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result;
+ -- If default expression of a component mentions a discriminant of the
+ -- type, it must be rewritten as the discriminant of the target object.
+
function Replace_Type (Expr : Node_Id) return Traverse_Result;
-- If the aggregate contains a self-reference, traverse each expression
-- to replace a possible self-reference with a reference to the proper
-- component of the target of the assignment.
+ --------------------------
+ -- Rewrite_Discriminant --
+ --------------------------
+
+ function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (Expr) = N_Identifier
+ and then Present (Entity (Expr))
+ and then Ekind (Entity (Expr)) = E_In_Parameter
+ and then Present (Discriminal_Link (Entity (Expr)))
+ then
+ Rewrite (Expr,
+ Make_Selected_Component (Loc,
+ Prefix => New_Occurrence_Of (Obj, Loc),
+ Selector_Name => Make_Identifier (Loc, Chars (Expr))));
+ end if;
+ return OK;
+ end Rewrite_Discriminant;
+
------------------
-- Replace_Type --
------------------
procedure Replace_Self_Reference is
new Traverse_Proc (Replace_Type);
+ procedure Replace_Discriminants is
+ new Traverse_Proc (Rewrite_Discriminant);
+
-- Start of processing for Build_Record_Aggr_Code
begin
Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
Set_Assignment_OK (Ref);
- if Has_Default_Init_Comps (N)
- or else Has_Task (Base_Type (Init_Typ))
- then
- Append_List_To (L,
- Build_Initialization_Call (Loc,
- Id_Ref => Ref,
- Typ => Init_Typ,
- In_Init_Proc => Within_Init_Proc,
- With_Default_Init => True));
- else
- Append_List_To (L,
- Build_Initialization_Call (Loc,
- Id_Ref => Ref,
- Typ => Init_Typ,
- In_Init_Proc => Within_Init_Proc));
- end if;
+ Append_List_To (L,
+ Build_Initialization_Call (Loc,
+ Id_Ref => Ref,
+ Typ => Init_Typ,
+ In_Init_Proc => Within_Init_Proc,
+ With_Default_Init => Has_Default_Init_Comps (N)
+ or else
+ Has_Task (Base_Type (Init_Typ))));
if Is_Constrained (Entity (A))
and then Has_Discriminants (Entity (A))
Check_Ancestor_Discriminants (Entity (A));
end if;
+ -- Handle calls to C++ constructors
+
+ elsif Is_CPP_Constructor_Call (A) then
+ Init_Typ := Etype (A);
+ Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
+ Set_Assignment_OK (Ref);
+
+ Append_List_To (L,
+ Build_Initialization_Call (Loc,
+ Id_Ref => Ref,
+ Typ => Init_Typ,
+ In_Init_Proc => Within_Init_Proc,
+ With_Default_Init => Has_Default_Init_Comps (N),
+ Constructor_Ref => A));
+
-- Ada 2005 (AI-287): If the ancestor part is an aggregate of
-- limited type, a recursive call expands the ancestor. Note that
-- in the limited case, the ancestor part must be either a
-- the subsequent deep_adjust works properly (unless VM_Target,
-- where tags are implicit).
- if VM_Target = No_VM then
+ if Tagged_Type_Expansion then
Instr :=
Make_OK_Assignment_Statement (Loc,
Name =>
-- Expr_Q is not delayed aggregate
else
+ if Has_Discriminants (Typ) then
+ Replace_Discriminants (Expr_Q);
+ end if;
+
Instr :=
Make_OK_Assignment_Statement (Loc,
Name => Comp_Expr,
- Expression => Expression (Comp));
+ Expression => Expr_Q);
Set_No_Ctrl_Actions (Instr);
Append_To (L, Instr);
-- tmp.comp._tag := comp_typ'tag;
- if Is_Tagged_Type (Comp_Type) and then VM_Target = No_VM then
+ if Is_Tagged_Type (Comp_Type)
+ and then Tagged_Type_Expansion
+ then
Instr :=
Make_OK_Assignment_Statement (Loc,
Name =>
elsif Is_CPP_Class (Typ) then
null;
- elsif Is_Tagged_Type (Typ) and then VM_Target = No_VM then
+ elsif Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then
Instr :=
Make_OK_Assignment_Statement (Loc,
Name =>
else
Set_Etype (N, Typ);
- if VM_Target = No_VM then
+ if Tagged_Type_Expansion then
Expand_Record_Aggregate (N,
Orig_Tag =>
New_Occurrence_Of
or else (Is_Entity_Name (Expr_Q)
and then
Ekind (Entity (Expr_Q)) in Formal_Kind))
- and then VM_Target = No_VM
+ and then Tagged_Type_Expansion
then
Static_Components := False;
return True;
-- an atomic move for it.
if Is_Atomic (Typ)
- and then Nkind_In (Parent (N), N_Object_Declaration,
- N_Assignment_Statement)
and then Comes_From_Source (Parent (N))
+ and then Is_Atomic_Aggregate (N, Typ)
then
- Expand_Atomic_Aggregate (N, Typ);
return;
-- No special management required for aggregates used to initialize
if Present (Orig_Tag) then
Tag_Value := Orig_Tag;
- elsif VM_Target /= No_VM then
+ elsif not Tagged_Type_Expansion then
Tag_Value := Empty;
else
Tag_Value :=
-- For a root type, the tag component is added (unless compiling
-- for the VMs, where tags are implicit).
- elsif VM_Target = No_VM then
+ elsif Tagged_Type_Expansion then
declare
Tag_Name : constant Node_Id :=
New_Occurrence_Of
begin
return Static_Dispatch_Tables
- and then VM_Target = No_VM
+ and then Tagged_Type_Expansion
and then RTU_Loaded (Ada_Tags)
-- Avoid circularity when rebuilding the compiler