with Sem_Eval; use Sem_Eval;
with Sem_Mech; use Sem_Mech;
with Sem_Res; use Sem_Res;
+with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
use Sem_Util.Storage_Model_Support;
with Sinfo; use Sinfo;
function Replace_Type (Expr : Node_Id) return Traverse_Result is
begin
- -- Note regarding the Root_Type test below: Aggregate components for
+ -- Note about the Is_Ancestor test below: aggregate components for
-- self-referential types include attribute references to the current
- -- instance, of the form: Typ'access, etc.. These references are
+ -- instance, of the form: Typ'access, etc. These references are
-- rewritten as references to the target of the aggregate: the
-- left-hand side of an assignment, the entity in a declaration,
- -- or a temporary. Without this test, we would improperly extended
- -- this rewriting to attribute references whose prefix was not the
+ -- or a temporary. Without this test, we would improperly extend
+ -- this rewriting to attribute references whose prefix is not the
-- type of the aggregate.
if Nkind (Expr) = N_Attribute_Reference
and then Is_Entity_Name (Prefix (Expr))
and then Is_Type (Entity (Prefix (Expr)))
- and then Root_Type (Etype (N)) = Root_Type (Entity (Prefix (Expr)))
+ and then
+ Is_Ancestor
+ (Entity (Prefix (Expr)), Etype (N), Use_Full_View => True)
then
if Is_Entity_Name (Lhs) then
Rewrite (Prefix (Expr), New_Occurrence_Of (Entity (Lhs), Loc));
Component_Associations (New_Aggr));
-- If the discriminant constraint is a current instance, mark the
- -- current aggregate so that the self-reference can be expanded
- -- later. The constraint may refer to the subtype of aggregate, so
- -- use base type for comparison.
+ -- current aggregate so that the self-reference can be expanded by
+ -- Build_Record_Aggr_Code.Replace_Type later.
if Nkind (Discr_Val) = N_Attribute_Reference
and then Is_Entity_Name (Prefix (Discr_Val))
and then Is_Type (Entity (Prefix (Discr_Val)))
- and then Base_Type (Etype (N)) = Entity (Prefix (Discr_Val))
+ and then
+ Is_Ancestor
+ (Entity (Prefix (Discr_Val)),
+ Etype (N),
+ Use_Full_View => True)
then
Set_Has_Self_Reference (N);
end if;
(T1 : Entity_Id;
T2 : Entity_Id;
Use_Full_View : Boolean := False) return Boolean;
- -- T1 is a tagged type (not class-wide). Verify that it is one of the
- -- ancestors of type T2 (which may or not be class-wide). If Use_Full_View
- -- is True then the full-view of private parents is used when climbing
- -- through the parents of T2.
+ -- T1 is a type (not class-wide). Verify that it is one of the ancestors of
+ -- type T2 (which may or not be class-wide). If Use_Full_View is True, then
+ -- the full view of private parents is used when climbing T2's parents.
--
-- Note: For analysis purposes the flag Use_Full_View must be set to False
-- (otherwise we break the privacy contract since this routine returns true