summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch5.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch5.adb')
-rw-r--r--gcc/ada/sem_ch5.adb63
1 files changed, 54 insertions, 9 deletions
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 6b799ee5979..0077db2677a 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -597,6 +597,12 @@ package body Sem_Ch5 is
----------------------------
procedure Analyze_Case_Statement (N : Node_Id) is
+ Exp : Node_Id;
+ Exp_Type : Entity_Id;
+ Exp_Btype : Entity_Id;
+ Last_Choice : Nat;
+ Dont_Care : Boolean;
+ Others_Present : Boolean;
Statements_Analyzed : Boolean := False;
-- Set True if at least some statement sequences get analyzed.
@@ -640,22 +646,61 @@ package body Sem_Ch5 is
------------------------
procedure Process_Statements (Alternative : Node_Id) is
+ Choices : constant List_Id := Discrete_Choices (Alternative);
+ Ent : Entity_Id;
+
begin
Unblocked_Exit_Count := Unblocked_Exit_Count + 1;
Statements_Analyzed := True;
+
+ -- An interesting optimization. If the case statement expression
+ -- is a simple entity, then we can set the current value within
+ -- an alternative if the alternative has one possible value.
+
+ -- case N is
+ -- when 1 => alpha
+ -- when 2 | 3 => beta
+ -- when others => gamma
+
+ -- Here we know that N is initially 1 within alpha, but for beta
+ -- and gamma, we do not know anything more about the initial value.
+
+ if Is_Entity_Name (Exp) then
+ Ent := Entity (Exp);
+
+ if Ekind (Ent) = E_Variable
+ or else
+ Ekind (Ent) = E_In_Out_Parameter
+ or else
+ Ekind (Ent) = E_Out_Parameter
+ then
+ if List_Length (Choices) = 1
+ and then Nkind (First (Choices)) in N_Subexpr
+ and then Compile_Time_Known_Value (First (Choices))
+ then
+ Set_Current_Value (Entity (Exp), First (Choices));
+ end if;
+
+ Analyze_Statements (Statements (Alternative));
+
+ -- After analyzing the case, set the current value to empty
+ -- since we won't know what it is for the next alternative
+ -- (unless reset by this same circuit), or after the case.
+
+ Set_Current_Value (Entity (Exp), Empty);
+ return;
+ end if;
+ end if;
+
+ -- Case where expression is not an entity name of a variable
+
Analyze_Statements (Statements (Alternative));
end Process_Statements;
- -- Variables local to Analyze_Case_Statement.
-
- Exp : Node_Id;
- Exp_Type : Entity_Id;
- Exp_Btype : Entity_Id;
+ -- Table to record choices. Put after subprograms since we make
+ -- a call to Number_Of_Choices to get the right number of entries.
- Case_Table : Choice_Table_Type (1 .. Number_Of_Choices (N));
- Last_Choice : Nat;
- Dont_Care : Boolean;
- Others_Present : Boolean;
+ Case_Table : Choice_Table_Type (1 .. Number_Of_Choices (N));
-- Start of processing for Analyze_Case_Statement