is
Loc : constant Source_Ptr := Sloc (Expr);
- Non_Static : exception;
- -- Raised if something non-static is found
-
Btyp : constant Entity_Id := Base_Type (Typ);
BLo : constant Uint := Expr_Value (Type_Low_Bound (Btyp));
function Build_Val (V : Uint) return Node_Id;
-- Return an analyzed N_Identifier node referencing this value, suitable
- -- for use as an entry in the Static_Discrte_Predicate list. This node
+ -- for use as an entry in the Static_Discrete_Predicate list. This node
-- is typed with the base type.
function Build_Range (Lo : Uint; Hi : Uint) return Node_Id;
-- use as an entry in the Static_Discrete_Predicate list. This node is
-- typed with the base type.
- function Get_RList (Exp : Node_Id) return RList;
+ function Get_RList
+ (Exp : Node_Id;
+ Static : access Boolean) return RList;
-- This is a recursive routine that converts the given expression into a
-- list of ranges, suitable for use in building the static predicate.
+ -- Static.all will be set to False if the expression is found to be non
+ -- static. Note that Static.all should be set to True by the caller.
function Is_False (R : RList) return Boolean;
pragma Inline (Is_False);
-- a static expression or static range, gets either the expression value
-- or the high bound of the range.
- function Membership_Entry (N : Node_Id) return RList;
+ function Membership_Entry
+ (N : Node_Id; Static : access Boolean) return RList;
-- Given a single membership entry (range, value, or subtype), returns
- -- the corresponding range list. Raises Static_Error if not static.
+ -- the corresponding range list. Set Static.all to False if not static.
- function Membership_Entries (N : Node_Id) return RList;
+ function Membership_Entries
+ (N : Node_Id; Static : access Boolean) return RList;
-- Given an element on an alternatives list of a membership operation,
-- returns the range list corresponding to this entry and all following
-- entries (i.e. returns the "or" of this list of values).
+ -- Set Static.all to False if not static.
- function Stat_Pred (Typ : Entity_Id) return RList;
- -- Given a type, if it has a static predicate, then return the predicate
- -- as a range list, otherwise raise Non_Static.
+ function Stat_Pred
+ (Typ : Entity_Id;
+ Static : access Boolean) return RList;
+ -- Given a type, if it has a static predicate, then set Result to the
+ -- predicate as a range list, otherwise set Static.all to False.
-----------
-- "and" --
-- Get_RList --
---------------
- function Get_RList (Exp : Node_Id) return RList is
+ function Get_RList
+ (Exp : Node_Id;
+ Static : access Boolean) return RList
+ is
Op : Node_Kind;
Val : Uint;
when N_And_Then
| N_Op_And
=>
- return Get_RList (Left_Opnd (Exp))
+ return Get_RList (Left_Opnd (Exp), Static)
and
- Get_RList (Right_Opnd (Exp));
+ Get_RList (Right_Opnd (Exp), Static);
-- Or
when N_Op_Or
| N_Or_Else
=>
- return Get_RList (Left_Opnd (Exp))
+ return Get_RList (Left_Opnd (Exp), Static)
or
- Get_RList (Right_Opnd (Exp));
+ Get_RList (Right_Opnd (Exp), Static);
-- Not
when N_Op_Not =>
- return not Get_RList (Right_Opnd (Exp));
+ return not Get_RList (Right_Opnd (Exp), Static);
-- Comparisons of type with static value
-- Other cases are non-static
else
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
-- Construct range according to comparison operation
when N_In =>
if not Is_Type_Ref (Left_Opnd (Exp)) then
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
if Present (Right_Opnd (Exp)) then
- return Membership_Entry (Right_Opnd (Exp));
+ return Membership_Entry (Right_Opnd (Exp), Static);
else
- return Membership_Entries (First (Alternatives (Exp)));
+ return Membership_Entries
+ (First (Alternatives (Exp)), Static);
end if;
-- Negative membership (NOT IN)
when N_Not_In =>
if not Is_Type_Ref (Left_Opnd (Exp)) then
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
if Present (Right_Opnd (Exp)) then
- return not Membership_Entry (Right_Opnd (Exp));
+ return not Membership_Entry (Right_Opnd (Exp), Static);
else
- return not Membership_Entries (First (Alternatives (Exp)));
+ return not Membership_Entries
+ (First (Alternatives (Exp)), Static);
end if;
-- Function call, may be call to static predicate
or else
Is_Predicate_Function_M (Ent)
then
- return Stat_Pred (Etype (First_Formal (Ent)));
+ return Stat_Pred (Etype (First_Formal (Ent)), Static);
end if;
end;
end if;
-- Other function call cases are non-static
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
-- Qualified expression, dig out the expression
when N_Qualified_Expression =>
- return Get_RList (Expression (Exp));
+ return Get_RList (Expression (Exp), Static);
when N_Case_Expression =>
declare
Dep := Expression (Alt);
if not Is_OK_Static_Expression (Dep) then
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
elsif Is_True (Expr_Value (Dep)) then
Append_List_To (Choices,
Next (Alt);
end loop;
- return Membership_Entries (First (Choices));
+ return Membership_Entries (First (Choices), Static);
end;
-- Expression with actions: if no actions, dig out expression
when N_Expression_With_Actions =>
if Is_Empty_List (Actions (Exp)) then
- return Get_RList (Expression (Exp));
+ return Get_RList (Expression (Exp), Static);
else
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
-- Xor operator
when N_Op_Xor =>
- return (Get_RList (Left_Opnd (Exp))
- and not Get_RList (Right_Opnd (Exp)))
- or (Get_RList (Right_Opnd (Exp))
- and not Get_RList (Left_Opnd (Exp)));
+ return (Get_RList (Left_Opnd (Exp), Static)
+ and not Get_RList (Right_Opnd (Exp), Static))
+ or (Get_RList (Right_Opnd (Exp), Static)
+ and not Get_RList (Left_Opnd (Exp), Static));
-- Any other node type is non-static
when others =>
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end case;
end Get_RList;
-- Membership_Entries --
------------------------
- function Membership_Entries (N : Node_Id) return RList is
+ function Membership_Entries
+ (N : Node_Id; Static : access Boolean) return RList is
begin
if No (Next (N)) then
- return Membership_Entry (N);
+ return Membership_Entry (N, Static);
else
- return Membership_Entry (N) or Membership_Entries (Next (N));
+ return Membership_Entry (N, Static)
+ or Membership_Entries (Next (N), Static);
end if;
end Membership_Entries;
-- Membership_Entry --
----------------------
- function Membership_Entry (N : Node_Id) return RList is
+ function Membership_Entry
+ (N : Node_Id; Static : access Boolean) return RList
+ is
Val : Uint;
SLo : Uint;
SHi : Uint;
or else
not Is_OK_Static_Expression (High_Bound (N))
then
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
else
SLo := Expr_Value (Low_Bound (N));
SHi := Expr_Value (High_Bound (N));
-- If type has predicates, process them
if Has_Predicates (Entity (N)) then
- return Stat_Pred (Entity (N));
+ return Stat_Pred (Entity (N), Static);
-- For static subtype without predicates, get range
-- Any other type makes us non-static
else
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
-- Any other kind of identifier in predicate (e.g. a non-static
-- expression value) means this is not a static predicate.
else
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
end if;
end Membership_Entry;
-- Stat_Pred --
---------------
- function Stat_Pred (Typ : Entity_Id) return RList is
+ function Stat_Pred
+ (Typ : Entity_Id;
+ Static : access Boolean) return RList is
begin
-- Not static if type does not have static predicates
if not Has_Static_Predicate (Typ) then
- raise Non_Static;
+ Static.all := False;
+ return False_Range;
end if;
-- Otherwise we convert the predicate list to a range list
-- Analyze the expression to see if it is a static predicate
declare
- Ranges : constant RList := Get_RList (Expr);
+ Static : aliased Boolean := True;
+ Ranges : constant RList := Get_RList (Expr, Static'Access);
-- Range list from expression if it is static
Plist : List_Id;
begin
+ -- If non-static, return doing nothing
+
+ if not Static then
+ return;
+ end if;
+
-- Convert range list into a form for the static predicate. In the
-- Ranges array, we just have raw ranges, these must be converted
-- to properly typed and analyzed static expressions or range nodes.
end if;
end;
end;
-
- -- If non-static, return doing nothing
-
- exception
- when Non_Static =>
- return;
end Build_Discrete_Static_Predicate;
--------------------------------