then
declare
O_Ent : Entity_Id;
+ O_Typ : Entity_Id;
Off : Boolean;
begin
- Find_Overlaid_Entity (Addr, O_Ent, Off);
+ Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off);
if Ekind (O_Ent) = E_Constant
and then Etype (O_Ent) = Typ
declare
Expr : constant Node_Id := Expression (N);
O_Ent : Entity_Id;
+ O_Typ : Entity_Id;
Off : Boolean;
begin
return;
end if;
- Find_Overlaid_Entity (N, O_Ent, Off);
+ Find_Overlaid_Entity (N, O_Ent, O_Typ, Off);
if Present (O_Ent) then
if (Is_Record_Type (Etype (U_Ent))
or else Is_Array_Type (Etype (U_Ent)))
- and then (Is_Record_Type (Etype (O_Ent))
- or else Is_Array_Type (Etype (O_Ent)))
+ and then (Is_Record_Type (O_Typ)
+ or else Is_Array_Type (O_Typ))
and then Reverse_Storage_Order (Etype (U_Ent)) /=
- Reverse_Storage_Order (Etype (O_Ent))
+ Reverse_Storage_Order (O_Typ)
then
Error_Msg_N
("??overlay changes scalar storage order", Expr);
--------------------------
procedure Find_Overlaid_Entity
- (N : Node_Id;
- Ent : out Entity_Id;
- Off : out Boolean)
+ (N : Node_Id;
+ Ent : out Entity_Id;
+ Ovrl_Typ : out Entity_Id;
+ Off : out Boolean)
is
pragma Assert
(Nkind (N) = N_Attribute_Definition_Clause
-- constant that eventually references Y'Address.
Ent := Empty;
+ Ovrl_Typ := Empty;
Off := False;
Expr := Expression (N);
and then Is_Concurrent_Type (Scope (Ent)));
Ent := Empty;
end if;
+
+ if No (Ovrl_Typ) then
+ Ovrl_Typ := Etype (Ent);
+ end if;
+
return;
-- Check for components
elsif Nkind (Expr) in N_Selected_Component | N_Indexed_Component then
+ if Nkind (Expr) = N_Selected_Component then
+ -- If Something.Other'Address, use
+ -- the Etype of the Other component.
+
+ if No (Ovrl_Typ) then
+ Ovrl_Typ := Etype (Entity (Selector_Name (Expr)));
+ end if;
+
+ else
+ -- If Something(Index)'Address, use
+ -- the Etype of the array component.
+
+ if No (Ovrl_Typ) then
+ Ovrl_Typ := Etype (Expr);
+ end if;
+ end if;
+
Expr := Prefix (Expr);
Off := True;
declare
Addr : constant Node_Id := Address_Clause (Ent);
O_Ent : Entity_Id;
+ O_Typ : Entity_Id;
Off : Boolean;
begin
- Find_Overlaid_Entity (Addr, O_Ent, Off);
+ Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off);
Error_Msg_Sloc := Sloc (Addr);
Error_Msg_NE
------------------------------
function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id is
- Address : Node_Id;
- Alias : Entity_Id := E;
- Offset : Boolean;
+ Address : Node_Id;
+ Alias : Entity_Id := E;
+ Offset : Boolean;
+ Ovrl_Typ : Entity_Id;
begin
-- Currently this routine is only called for stand-alone objects that
loop
Address := Address_Clause (Alias);
if Present (Address) then
- Find_Overlaid_Entity (Address, Alias, Offset);
+ Find_Overlaid_Entity (Address, Alias, Ovrl_Typ, Offset);
if Present (Alias) then
null;
else
-- loop are nested within the block.
procedure Find_Overlaid_Entity
- (N : Node_Id;
- Ent : out Entity_Id;
- Off : out Boolean);
+ (N : Node_Id;
+ Ent : out Entity_Id;
+ Ovrl_Typ : out Entity_Id;
+ Off : out Boolean);
-- The node N should be an address representation clause. Determines if the
-- target expression is the address of an entity with an optional offset.
-- If so, set Ent to the entity and, if there is an offset, set Off to
-- True, otherwise to False. If it is not possible to determine that the
-- address is of this form, then set Ent to Empty.
+ -- Ovrl_Typ is set to the type being overlaid and can be different than the
+ -- type of Ent, for example when the address clause is applied to a record
+ -- component or to an element of an array.
function Find_Parameter_Type (Param : Node_Id) return Entity_Id;
-- Return the type of formal parameter Param as determined by its