aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/freeze.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/freeze.adb')
-rw-r--r--gcc/ada/freeze.adb185
1 files changed, 164 insertions, 21 deletions
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index c161338..ac9f570 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -46,6 +46,7 @@ with Rident; use Rident;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
+with Sem_Case; use Sem_Case;
with Sem_Cat; use Sem_Cat;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch7; use Sem_Ch7;
@@ -846,8 +847,9 @@ package body Freeze is
and then Nkind (Type_Definition (Parent (T))) =
N_Record_Definition
and then not Null_Present (Type_Definition (Parent (T)))
- and then Present (Variant_Part
- (Component_List (Type_Definition (Parent (T)))))
+ and then
+ Present (Variant_Part
+ (Component_List (Type_Definition (Parent (T)))))
then
-- If variant part is present, and type is unconstrained,
-- then we must have defaulted discriminants, or a size
@@ -2272,7 +2274,7 @@ package body Freeze is
begin
if Present (Alloc) then
- -- If component is pointer to a classwide type, freeze
+ -- If component is pointer to a class-wide type, freeze
-- the specific type in the expression being allocated.
-- The expression may be a subtype indication, in which
-- case freeze the subtype mark.
@@ -2367,7 +2369,8 @@ package body Freeze is
if Present (ADC) and then Base_Type (Rec) = Rec then
if not (Placed_Component or else Is_Packed (Rec)) then
- Error_Msg_N ("??bit order specification has no effect", ADC);
+ Error_Msg_N
+ ("??bit order specification has no effect", ADC);
Error_Msg_N
("\??since no component clauses were specified", ADC);
@@ -2443,15 +2446,13 @@ package body Freeze is
-- remote type here since that is what we are semantically freezing.
-- This prevents the freeze node for that type in an inner scope.
- -- Also, Check for controlled components and unchecked unions.
- -- Finally, enforce the restriction that access attributes with a
- -- current instance prefix can only apply to limited types.
-
if Ekind (Rec) = E_Record_Type then
if Present (Corresponding_Remote_Type (Rec)) then
Freeze_And_Append (Corresponding_Remote_Type (Rec), N, Result);
end if;
+ -- Check for controlled components and unchecked unions.
+
Comp := First_Component (Rec);
while Present (Comp) loop
@@ -2459,18 +2460,18 @@ package body Freeze is
-- equivalent type. See Make_CW_Equivalent_Type.
if not Is_Class_Wide_Equivalent_Type (Rec)
- and then (Has_Controlled_Component (Etype (Comp))
- or else (Chars (Comp) /= Name_uParent
- and then Is_Controlled (Etype (Comp)))
- or else (Is_Protected_Type (Etype (Comp))
- and then
- Present
- (Corresponding_Record_Type
- (Etype (Comp)))
- and then
- Has_Controlled_Component
- (Corresponding_Record_Type
- (Etype (Comp)))))
+ and then
+ (Has_Controlled_Component (Etype (Comp))
+ or else
+ (Chars (Comp) /= Name_uParent
+ and then Is_Controlled (Etype (Comp)))
+ or else
+ (Is_Protected_Type (Etype (Comp))
+ and then
+ Present (Corresponding_Record_Type (Etype (Comp)))
+ and then
+ Has_Controlled_Component
+ (Corresponding_Record_Type (Etype (Comp)))))
then
Set_Has_Controlled_Component (Rec);
end if;
@@ -2490,11 +2491,17 @@ package body Freeze is
end loop;
end if;
+ -- Enforce the restriction that access attributes with a current
+ -- instance prefix can only apply to limited types. This comment
+ -- is floating here, but does not seem to belong here???
+
+ -- Set component alignment if not otherwise already set
+
Set_Component_Alignment_If_Not_Set (Rec);
-- For first subtypes, check if there are any fixed-point fields with
-- component clauses, where we must check the size. This is not done
- -- till the freeze point, since for fixed-point types, we do not know
+ -- till the freeze point since for fixed-point types, we do not know
-- the size until the type is frozen. Similar processing applies to
-- bit packed arrays.
@@ -2613,6 +2620,142 @@ package body Freeze is
end;
end if;
end if;
+
+ -- All done if not a full record definition
+
+ if Ekind (Rec) /= E_Record_Type then
+ return;
+ end if;
+
+ -- Finallly we need to check the variant part to make sure that
+ -- the set of choices for each variant covers the corresponding
+ -- discriminant. This check has to be delayed to the freeze point
+ -- because we may have statically predicated subtypes, whose choice
+ -- list is not known till the subtype is frozen.
+
+ Check_Variant_Part : declare
+ D : constant Node_Id := Declaration_Node (Rec);
+ T : Node_Id;
+ C : Node_Id;
+ V : Node_Id;
+
+ Others_Present : Boolean;
+ pragma Warnings (Off, Others_Present);
+ -- Indicates others present, not used in this case
+
+ procedure Non_Static_Choice_Error (Choice : Node_Id);
+ -- Error routine invoked by the generic instantiation below when
+ -- the variant part has a non static choice.
+
+ procedure Process_Declarations (Variant : Node_Id);
+ -- Processes declarations associated with a variant. We analyzed
+ -- the declarations earlier (in Sem_Ch3.Analyze_Variant_Part),
+ -- but we still need the recursive call to Check_Choices for any
+ -- nested variant to get its choices properly processed. This is
+ -- also where we expand out the choices if expansion is active.
+
+ package Variant_Choices_Processing is new
+ Generic_Check_Choices
+ (Process_Empty_Choice => No_OP,
+ Process_Non_Static_Choice => Non_Static_Choice_Error,
+ Process_Associated_Node => Process_Declarations);
+ use Variant_Choices_Processing;
+
+ -----------------------------
+ -- Non_Static_Choice_Error --
+ -----------------------------
+
+ procedure Non_Static_Choice_Error (Choice : Node_Id) is
+ begin
+ Flag_Non_Static_Expr
+ ("choice given in variant part is not static!", Choice);
+ end Non_Static_Choice_Error;
+
+ --------------------------
+ -- Process_Declarations --
+ --------------------------
+
+ procedure Process_Declarations (Variant : Node_Id) is
+ CL : constant Node_Id := Component_List (Variant);
+ VP : Node_Id;
+
+ begin
+ -- Check for static predicate present in this variant
+
+ if Has_SP_Choice (Variant) then
+
+ -- Here we expand. You might expect to find this call in
+ -- Expand_N_Variant_Part, but that is called when we first
+ -- see the variant part, and we cannot do this expansion
+ -- earlier than the freeze point, since for statically
+ -- predicated subtypes, the predicate is not known till
+ -- the freeze point.
+
+ -- Furthermore, we do this expansion even if the expander
+ -- is not active, because other semantic processing, e.g.
+ -- for aggregates, requires the expanded list of choices.
+
+ -- If the expander is not active, then we can't just clobber
+ -- the list since it would invalidate the ASIS -gnatct tree.
+ -- So we have to rewrite the variant part with a Rewrite
+ -- call that replaces it with a copy and clobber the copy.
+
+ if not Expander_Active then
+ declare
+ NewV : constant Node_Id := New_Copy (Variant);
+ begin
+ Set_Discrete_Choices
+ (NewV, New_Copy_List (Discrete_Choices (Variant)));
+ Rewrite (Variant, NewV);
+ end;
+ end if;
+
+ Expand_Static_Predicates_In_Choices (Variant);
+ end if;
+
+ -- We don't need to worry about the declarations in the variant
+ -- (since they were analyzed by Analyze_Choices when we first
+ -- encountered the variant), but we do need to take care of
+ -- expansion of any nested variants.
+
+ if not Null_Present (CL) then
+ VP := Variant_Part (CL);
+
+ if Present (VP) then
+ Check_Choices
+ (VP, Variants (VP), Etype (Name (VP)), Others_Present);
+ end if;
+ end if;
+ end Process_Declarations;
+
+ -- Start of processing for Check_Variant_Part
+
+ begin
+ -- Find component list
+
+ C := Empty;
+
+ if Nkind (D) = N_Full_Type_Declaration then
+ T := Type_Definition (D);
+
+ if Nkind (T) = N_Record_Definition then
+ C := Component_List (T);
+
+ elsif Nkind (T) = N_Derived_Type_Definition
+ and then Present (Record_Extension_Part (T))
+ then
+ C := Component_List (Record_Extension_Part (T));
+ end if;
+ end if;
+
+ -- If we have a variant part, check choices
+
+ if Present (C) and then Present (Variant_Part (C)) then
+ V := Variant_Part (C);
+ Check_Choices
+ (V, Variants (V), Etype (Name (V)), Others_Present);
+ end if;
+ end Check_Variant_Part;
end Freeze_Record_Type;
-- Start of processing for Freeze_Entity