-- d.I Do not ignore enum representation clauses in CodePeer mode
-- d.J Relaxed rules for pragma No_Return
-- d.K Do not reject components in extensions overlapping with parent
- -- d.L Depend on back end for limited types in if and case expressions
-- d.M Relaxed RM semantics
-- d.N Use rounding when converting from floating point to fixed point
-- d.O Dump internal SCO tables
-- clause but they cannot be fully supported by the GCC type system.
-- This switch nevertheless allows them for the sake of compatibility.
- -- d.L Normally the front end generates special expansion for conditional
- -- expressions of a limited type. This debug flag removes this special
- -- case expansion, leaving it up to the back end to handle conditional
- -- expressions correctly.
-
-- d.M Relaxed RM semantics. This flag sets Opt.Relaxed_RM_Semantics
-- See Opt.Relaxed_RM_Semantics for more details.
Alt : Node_Id;
Case_Stmt : Node_Id;
Decl : Node_Id;
- Expr : Node_Id;
Target : Entity_Id := Empty;
Target_Typ : Entity_Id;
-- In all other cases expand into
- -- do
-- type Ptr_Typ is access all Typ;
-- Target : Ptr_Typ;
-- case X is
-- Target := BX'Unrestricted_Access;
-- ...
-- end case;
- -- in Target.all end;
+
+ -- and replace the case expression by a reference to Target.all.
-- This approach avoids extra copies of potentially large objects. It
-- also allows handling of values of limited or unconstrained types.
Prepend_List (Actions (Alt), Stmts);
end if;
- -- Finalize any transient objects on exit from the alternative.
- -- This is done only in the return optimization case because
- -- otherwise the case expression is converted into an expression
- -- with actions which already contains this form of processing.
-
- if Optimize_Return_Stmt then
- Process_If_Case_Statements (N, Stmts);
- end if;
-
Append_To
(Alternatives (Case_Stmt),
Make_Case_Statement_Alternative (Sloc (Alt),
Discrete_Choices => Discrete_Choices (Alt),
Statements => Stmts));
+
+ -- Finalize any transient objects on exit from the alternative.
+ -- This needs to be done only when the case expression is _not_
+ -- later converted into an expression with actions, which already
+ -- contains this form of processing, and after Stmts is attached
+ -- to the Alternatives list above (for Safe_To_Capture_Value).
+
+ if Optimize_Return_Stmt or else not Is_Copy_Type (Typ) then
+ Process_If_Case_Statements (N, Stmts);
+ end if;
end;
Next (Alt);
Rewrite (Par, Case_Stmt);
Analyze (Par);
- -- Otherwise convert the case expression into an expression with actions
+ -- Otherwise rewrite the case expression itself
else
Append_To (Acts, Case_Stmt);
if Is_Copy_Type (Typ) then
- Expr := New_Occurrence_Of (Target, Loc);
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Expression => New_Occurrence_Of (Target, Loc),
+ Actions => Acts));
else
- Expr :=
+ Insert_Actions (N, Acts);
+ Rewrite (N,
Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Target, Loc));
+ Prefix => New_Occurrence_Of (Target, Loc)));
end if;
- -- Generate:
- -- do
- -- ...
- -- in Target[.all] end;
-
- Rewrite (N,
- Make_Expression_With_Actions (Loc,
- Expression => Expr,
- Actions => Acts));
-
Analyze_And_Resolve (N, Typ);
end if;
end Expand_N_Case_Expression;
Set_From_Conditional_Expression (New_If);
- -- If the type is limited, and the back end does not handle limited
- -- types, then we expand as follows to avoid the possibility of
- -- improper copying.
+ -- If the type is by reference, then we expand as follows to avoid the
+ -- possibility of improper copying.
-- type Ptr is access all Typ;
-- Cnn : Ptr;
-- and replace the if expression by a reference to Cnn.all.
- -- This special case can be skipped if the back end handles limited
- -- types properly and ensures that no incorrect copies are made.
-
- elsif Is_By_Reference_Type (Typ)
- and then not Back_End_Handles_Limited_Types
- then
+ elsif Is_By_Reference_Type (Typ) then
-- When the "then" or "else" expressions involve controlled function
-- calls, generated temporaries are chained on the corresponding list
-- of actions. These temporaries need to be finalized after the if
Suppress_Options.Suppress (Alignment_Check) := True;
end if;
- -- Set switch indicating if back end can handle limited types, and
- -- guarantee that no incorrect copies are made (e.g. in the context
- -- of an if or case expression).
-
- -- Debug flag -gnatd.L decisively sets usage on
-
- if Debug_Flag_Dot_LL then
- Back_End_Handles_Limited_Types := True;
-
- -- If no debug flag, usage off for SCIL cases
-
- elsif Generate_SCIL then
- Back_End_Handles_Limited_Types := False;
-
- -- Otherwise normal gcc back end, for now still turn flag off by
- -- default, since there are unresolved problems in the front end.
-
- else
- Back_End_Handles_Limited_Types := False;
- end if;
-
-- Return slot support is disabled if -gnatd_r is specified
if Debug_Flag_Underscore_R then
-- Unchecked_Conversion instantiations require checking based on annotated
-- values.
- Back_End_Handles_Limited_Types : Boolean;
- -- This flag is set True if the back end can properly handle limited or
- -- other by reference types, and avoid copies. If this flag is False, then
- -- the front end does special expansion for if/case expressions to make
- -- sure that no copy occurs. If the flag is True, then the expansion for
- -- if and case expressions relies on the back end properly handling things.
- -- Currently the default is False for all cases (set in gnat1drv). The
- -- default can be modified using -gnatd.L (sets the flag True). This is
- -- used to test the possibility of having the backend handle this.
-
Back_End_Inlining : Boolean := False;
-- GNAT
-- Set True to activate inlining by back-end expansion. This is the normal