aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_case.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_case.adb')
-rw-r--r--gcc/ada/sem_case.adb224
1 files changed, 179 insertions, 45 deletions
diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb
index 27a5c67..6701776 100644
--- a/gcc/ada/sem_case.adb
+++ b/gcc/ada/sem_case.adb
@@ -26,6 +26,8 @@
with Atree; use Atree;
with Einfo; use Einfo;
with Errout; use Errout;
+with Exp_Util; use Exp_Util;
+with Freeze; use Freeze;
with Namet; use Namet;
with Nlists; use Nlists;
with Nmake; use Nmake;
@@ -65,7 +67,7 @@ package body Sem_Case is
-- Local Subprograms --
-----------------------
- procedure Check_Choices
+ procedure Check_Choice_Set
(Choice_Table : in out Choice_Table_Type;
Bounds_Type : Entity_Id;
Subtyp : Entity_Id;
@@ -95,7 +97,7 @@ package body Sem_Case is
(Case_Table : Choice_Table_Type;
Others_Choice : Node_Id;
Choice_Type : Entity_Id);
- -- The case table is the table generated by a call to Analyze_Choices
+ -- The case table is the table generated by a call to Check_Choices
-- (with just 1 .. Last_Choice entries present). Others_Choice is a
-- pointer to the N_Others_Choice node (this routine is only called if
-- an others choice is present), and Choice_Type is the discrete type
@@ -103,11 +105,11 @@ package body Sem_Case is
-- determine the set of values covered by others. This choice list is
-- set in the Others_Discrete_Choices field of the N_Others_Choice node.
- -------------------
- -- Check_Choices --
- -------------------
+ ----------------------
+ -- Check_Choice_Set --
+ ----------------------
- procedure Check_Choices
+ procedure Check_Choice_Set
(Choice_Table : in out Choice_Table_Type;
Bounds_Type : Entity_Id;
Subtyp : Entity_Id;
@@ -598,7 +600,7 @@ package body Sem_Case is
Prev_Lo : Uint;
Prev_Hi : Uint;
- -- Start of processing for Check_Choices
+ -- Start of processing for Check_Choice_Set
begin
-- Choice_Table must start at 0 which is an unused location used by the
@@ -714,7 +716,7 @@ package body Sem_Case is
end if;
end if;
end if;
- end Check_Choices;
+ end Check_Choice_Set;
------------------
-- Choice_Image --
@@ -799,11 +801,10 @@ package body Sem_Case is
Previous_Hi : Uint;
function Build_Choice (Value1, Value2 : Uint) return Node_Id;
- -- Builds a node representing the missing choices given by the
- -- Value1 and Value2. A N_Range node is built if there is more than
- -- one literal value missing. Otherwise a single N_Integer_Literal,
- -- N_Identifier or N_Character_Literal is built depending on what
- -- Choice_Type is.
+ -- Builds a node representing the missing choices given by Value1 and
+ -- Value2. A N_Range node is built if there is more than one literal
+ -- value missing. Otherwise a single N_Integer_Literal, N_Identifier
+ -- or N_Character_Literal is built depending on what Choice_Type is.
function Lit_Of (Value : Uint) return Node_Id;
-- Returns the Node_Id for the enumeration literal corresponding to the
@@ -975,11 +976,11 @@ package body Sem_Case is
null;
end No_OP;
- --------------------------------
- -- Generic_Choices_Processing --
- --------------------------------
+ -----------------------------
+ -- Generic_Analyze_Choices --
+ -----------------------------
- package body Generic_Choices_Processing is
+ package body Generic_Analyze_Choices is
-- The following type is used to gather the entries for the choice
-- table, so that we can then allocate the right length.
@@ -992,20 +993,143 @@ package body Sem_Case is
Nxt : Link_Ptr;
end record;
- procedure Free is new Ada.Unchecked_Deallocation (Link, Link_Ptr);
-
---------------------
-- Analyze_Choices --
---------------------
procedure Analyze_Choices
- (N : Node_Id;
- Subtyp : Entity_Id;
- Raises_CE : out Boolean;
- Others_Present : out Boolean)
+ (Alternatives : List_Id;
+ Subtyp : Entity_Id)
+ is
+ Choice_Type : constant Entity_Id := Base_Type (Subtyp);
+ -- The actual type against which the discrete choices are resolved.
+ -- Note that this type is always the base type not the subtype of the
+ -- ruling expression, index or discriminant.
+
+ Expected_Type : Entity_Id;
+ -- The expected type of each choice. Equal to Choice_Type, except if
+ -- the expression is universal, in which case the choices can be of
+ -- any integer type.
+
+ Alt : Node_Id;
+ -- A case statement alternative or a variant in a record type
+ -- declaration.
+
+ Choice : Node_Id;
+ Kind : Node_Kind;
+ -- The node kind of the current Choice
+
+ begin
+ -- Set Expected type (= choice type except for universal integer,
+ -- where we accept any integer type as a choice).
+
+ if Choice_Type = Universal_Integer then
+ Expected_Type := Any_Integer;
+ else
+ Expected_Type := Choice_Type;
+ end if;
+
+ -- Now loop through the case alternatives or record variants
+
+ Alt := First (Alternatives);
+ while Present (Alt) loop
+
+ -- If pragma, just analyze it
+
+ if Nkind (Alt) = N_Pragma then
+ Analyze (Alt);
+
+ -- Otherwise we have an alternative. In most cases the semantic
+ -- processing leaves the list of choices unchanged
+
+ -- Check each choice against its base type
+
+ else
+ Choice := First (Discrete_Choices (Alt));
+ while Present (Choice) loop
+ Analyze (Choice);
+ Kind := Nkind (Choice);
+
+ -- Choice is a Range
+
+ if Kind = N_Range
+ or else (Kind = N_Attribute_Reference
+ and then Attribute_Name (Choice) = Name_Range)
+ then
+ Resolve (Choice, Expected_Type);
+
+ -- Choice is a subtype name, nothing further to do now
+
+ elsif Is_Entity_Name (Choice)
+ and then Is_Type (Entity (Choice))
+ then
+ null;
+
+ -- Choice is a subtype indication
+
+ elsif Kind = N_Subtype_Indication then
+ Resolve_Discrete_Subtype_Indication
+ (Choice, Expected_Type);
+
+ -- Others choice, no analysis needed
+
+ elsif Kind = N_Others_Choice then
+ null;
+
+ -- Only other possibility is an expression
+
+ else
+ Resolve (Choice, Expected_Type);
+ end if;
+
+ -- Move to next choice
+
+ Next (Choice);
+ end loop;
+
+ Process_Associated_Node (Alt);
+ end if;
+
+ Next (Alt);
+ end loop;
+ end Analyze_Choices;
+
+ end Generic_Analyze_Choices;
+
+ ---------------------------
+ -- Generic_Check_Choices --
+ ---------------------------
+
+ package body Generic_Check_Choices is
+
+ -- The following type is used to gather the entries for the choice
+ -- table, so that we can then allocate the right length.
+
+ type Link;
+ type Link_Ptr is access all Link;
+
+ type Link is record
+ Val : Choice_Bounds;
+ Nxt : Link_Ptr;
+ end record;
+
+ procedure Free is new Ada.Unchecked_Deallocation (Link, Link_Ptr);
+
+ -------------------
+ -- Check_Choices --
+ -------------------
+
+ procedure Check_Choices
+ (N : Node_Id;
+ Alternatives : List_Id;
+ Subtyp : Entity_Id;
+ Others_Present : out Boolean)
is
E : Entity_Id;
+ Raises_CE : Boolean;
+ -- Set True if one of the bounds of a choice raises CE
+
Enode : Node_Id;
-- This is where we post error messages for bounds out of range
@@ -1042,9 +1166,6 @@ package body Sem_Case is
Kind : Node_Kind;
-- The node kind of the current Choice
- Delete_Choice : Boolean;
- -- Set to True to delete the current choice
-
Others_Choice : Node_Id := Empty;
-- Remember others choice if it is present (empty otherwise)
@@ -1166,12 +1287,22 @@ package body Sem_Case is
Num_Choices := Num_Choices + 1;
end Check;
- -- Start of processing for Analyze_Choices
+ -- Start of processing for Check_Choices
begin
Raises_CE := False;
Others_Present := False;
+ -- If Subtyp is not a discrete type or there was some other error,
+ -- then don't try any semantic checking on the choices since we have
+ -- a complete mess.
+
+ if not Is_Discrete_Type (Subtyp)
+ or else Subtyp = Any_Type
+ then
+ return;
+ end if;
+
-- If Subtyp is not a static subtype Ada 95 requires then we use the
-- bounds of its base type to determine the values covered by the
-- discrete choices.
@@ -1210,7 +1341,7 @@ package body Sem_Case is
-- Now loop through the case alternatives or record variants
- Alt := First (Get_Alternatives (N));
+ Alt := First (Alternatives);
while Present (Alt) loop
-- If pragma, just analyze it
@@ -1226,7 +1357,6 @@ package body Sem_Case is
else
Choice := First (Discrete_Choices (Alt));
while Present (Choice) loop
- Delete_Choice := False;
Analyze (Choice);
Kind := Nkind (Choice);
@@ -1244,9 +1374,19 @@ package body Sem_Case is
elsif Is_Entity_Name (Choice)
and then Is_Type (Entity (Choice))
then
+ -- We have to make sure the subtype is frozen, it must be
+ -- before we can do the following analyses on choices!
+
+ Insert_Actions
+ (N, Freeze_Entity (Entity (Choice), Choice));
+
+ -- Check for inappropriate type
+
if not Covers (Expected_Type, Etype (Choice)) then
Wrong_Type (Choice, Choice_Type);
+ -- Type is OK, so check further
+
else
E := Entity (Choice);
@@ -1285,6 +1425,8 @@ package body Sem_Case is
Next (P);
end loop;
end;
+
+ Set_Has_SP_Choice (Alt);
end if;
-- Not predicated subtype case
@@ -1318,7 +1460,8 @@ package body Sem_Case is
else
if Is_OK_Static_Expression (L)
- and then Is_OK_Static_Expression (H)
+ and then
+ Is_OK_Static_Expression (H)
then
if Expr_Value (L) > Expr_Value (H) then
Process_Empty_Choice (Choice);
@@ -1348,7 +1491,7 @@ package body Sem_Case is
elsif Kind = N_Others_Choice then
if not (Choice = First (Discrete_Choices (Alt))
and then Choice = Last (Discrete_Choices (Alt))
- and then Alt = Last (Get_Alternatives (N)))
+ and then Alt = Last (Alternatives))
then
Error_Msg_N
("the choice OTHERS must appear alone and last",
@@ -1366,18 +1509,9 @@ package body Sem_Case is
Check (Choice, Choice, Choice);
end if;
- -- Move to next choice, deleting the current one if the
- -- flag requesting this deletion is set True.
+ -- Move to next choice
- declare
- C : constant Node_Id := Choice;
- begin
- Next (Choice);
-
- if Delete_Choice then
- Remove (C);
- end if;
- end;
+ Next (Choice);
end loop;
Process_Associated_Node (Alt);
@@ -1407,7 +1541,7 @@ package body Sem_Case is
end loop;
end;
- Check_Choices
+ Check_Choice_Set
(Choice_Table,
Bounds_Type,
Subtyp,
@@ -1426,8 +1560,8 @@ package body Sem_Case is
Choice_Type => Bounds_Type);
end if;
end;
- end Analyze_Choices;
+ end Check_Choices;
- end Generic_Choices_Processing;
+ end Generic_Check_Choices;
end Sem_Case;