Commit d62520f3 by Hristian Kirtchev Committed by Arnaud Charlet

aspects.adb (Find_Aspect): New routine.

2013-04-12  Hristian Kirtchev  <kirtchev@adacore.com>

	* aspects.adb (Find_Aspect): New routine.
	(Find_Value_Of_Aspect): New routine.
	(Has_Aspect): Reimplemented.
	* aspects.ads (Find_Aspect): New routine.
	(Find_Value_Of_Aspect): New routine, previously known as Find_Aspect.
	* exp_ch5.adb (Expand_Iterator_Loop): Update the call to Find_Aspect.
	* exp_util.adb (Is_Iterated_Container): Update the call to Find_Aspect.
	* sem_ch4.adb (Try_Container_Indexing): Update calls to Find_Aspect.
	* sem_ch5.adb (Analyze_Iterator_Specification): Update
	the call to Find_Aspect. Use function Has_Aspect for better
	readability.
	(Preanalyze_Range): Use function Has_Aspect for better readability.
	* sem_ch13.adb (Check_One_Function): Update the call to Find_Aspect.
	* sem_prag.adb (Analyze_Pragma): There is no longer need to
	look at the parent to extract the corresponding pragma for
	aspect Global.

From-SVN: r197911
parent 489c6e19
2013-04-12 Hristian Kirtchev <kirtchev@adacore.com>
* aspects.adb (Find_Aspect): New routine.
(Find_Value_Of_Aspect): New routine.
(Has_Aspect): Reimplemented.
* aspects.ads (Find_Aspect): New routine.
(Find_Value_Of_Aspect): New routine, previously known as Find_Aspect.
* exp_ch5.adb (Expand_Iterator_Loop): Update the call to Find_Aspect.
* exp_util.adb (Is_Iterated_Container): Update the call to Find_Aspect.
* sem_ch4.adb (Try_Container_Indexing): Update calls to Find_Aspect.
* sem_ch5.adb (Analyze_Iterator_Specification): Update
the call to Find_Aspect. Use function Has_Aspect for better
readability.
(Preanalyze_Range): Use function Has_Aspect for better readability.
* sem_ch13.adb (Check_One_Function): Update the call to Find_Aspect.
* sem_prag.adb (Analyze_Pragma): There is no longer need to
look at the parent to extract the corresponding pragma for
aspect Global.
2013-04-12 Robert Dewar <dewar@adacore.com> 2013-04-12 Robert Dewar <dewar@adacore.com>
* checks.adb, sem_elab.adb, repinfo.adb, sem_ch4.adb, restrict.adb, * checks.adb, sem_elab.adb, repinfo.adb, sem_ch4.adb, restrict.adb,
......
...@@ -114,52 +114,91 @@ package body Aspects is ...@@ -114,52 +114,91 @@ package body Aspects is
-- Find_Aspect -- -- Find_Aspect --
----------------- -----------------
function Find_Aspect (Ent : Entity_Id; A : Aspect_Id) return Node_Id is function Find_Aspect (Id : Entity_Id; A : Aspect_Id) return Node_Id is
Ritem : Node_Id; Decl : Node_Id;
Typ : Entity_Id; Item : Node_Id;
Owner : Entity_Id;
Spec : Node_Id;
begin begin
Owner := Id;
-- If the aspect is an inherited one and the entity is a class-wide -- Handle various cases of base or inherited aspects for types
-- type, use the aspect of the specific type. If the type is a base
-- aspect, examine the rep. items of the base type.
if Is_Type (Ent) then if Is_Type (Id) then
if Base_Aspect (A) then if Base_Aspect (A) then
Typ := Base_Type (Ent); Owner := Base_Type (Owner);
else
Typ := Ent;
end if; end if;
if Is_Class_Wide_Type (Typ) if Is_Class_Wide_Type (Owner) and then Inherited_Aspect (A) then
and then Inherited_Aspect (A) Owner := Root_Type (Owner);
then
Ritem := First_Rep_Item (Etype (Typ));
else
Ritem := First_Rep_Item (Typ);
end if; end if;
else
Ritem := First_Rep_Item (Ent);
end if; end if;
while Present (Ritem) loop -- Search the representation items for the desired aspect
if Nkind (Ritem) = N_Aspect_Specification
and then Get_Aspect_Id (Chars (Identifier (Ritem))) = A Item := First_Rep_Item (Owner);
while Present (Item) loop
if Nkind (Item) = N_Aspect_Specification
and then Get_Aspect_Id (Chars (Identifier (Item))) = A
then then
if A = Aspect_Default_Iterator then return Item;
return Expression (Aspect_Rep_Item (Ritem));
else
return Expression (Ritem);
end if;
end if; end if;
Next_Rep_Item (Ritem); Next_Rep_Item (Item);
end loop; end loop;
-- Note that not all aspects are added to the chain of representation
-- items. In such cases, search the list of aspect specifications. First
-- find the declaration node where the aspects reside. This is usually
-- the parent or the parent of the parent.
Decl := Parent (Owner);
if not Permits_Aspect_Specifications (Decl) then
Decl := Parent (Decl);
end if;
-- Search the list of aspect specifications for the desired aspect
if Permits_Aspect_Specifications (Decl) then
Spec := First (Aspect_Specifications (Decl));
while Present (Spec) loop
if Get_Aspect_Id (Chars (Identifier (Spec))) = A then
return Spec;
end if;
Next (Spec);
end loop;
end if;
-- The entity does not carry any aspects or the desired aspect was not
-- found.
return Empty; return Empty;
end Find_Aspect; end Find_Aspect;
--------------------------
-- Find_Value_Of_Aspect --
--------------------------
function Find_Value_Of_Aspect
(Id : Entity_Id;
A : Aspect_Id) return Node_Id
is
Spec : constant Node_Id := Find_Aspect (Id, A);
begin
if Present (Spec) then
if A = Aspect_Default_Iterator then
return Expression (Aspect_Rep_Item (Spec));
else
return Expression (Spec);
end if;
end if;
return Empty;
end Find_Value_Of_Aspect;
------------------- -------------------
-- Get_Aspect_Id -- -- Get_Aspect_Id --
------------------- -------------------
...@@ -174,22 +213,8 @@ package body Aspects is ...@@ -174,22 +213,8 @@ package body Aspects is
---------------- ----------------
function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean is function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean is
Decl : constant Node_Id := Parent (Parent (Id));
Aspect : Node_Id;
begin begin
if Has_Aspects (Decl) then return Present (Find_Aspect (Id, A));
Aspect := First (Aspect_Specifications (Decl));
while Present (Aspect) loop
if Get_Aspect_Id (Chars (Identifier (Aspect))) = A then
return True;
end if;
Next (Aspect);
end loop;
end if;
return False;
end Has_Aspect; end Has_Aspect;
------------------ ------------------
......
...@@ -517,8 +517,15 @@ package Aspects is ...@@ -517,8 +517,15 @@ package Aspects is
-- Replace calls, and this function may be used to retrieve the aspect -- Replace calls, and this function may be used to retrieve the aspect
-- specifications for the original rewritten node in such cases. -- specifications for the original rewritten node in such cases.
function Find_Aspect (Ent : Entity_Id; A : Aspect_Id) return Node_Id; function Find_Aspect (Id : Entity_Id; A : Aspect_Id) return Node_Id;
-- Find value of a given aspect from aspect list of entity -- Find the aspect specification of aspect A associated with entity I.
-- Return Empty if Id does not have the requested aspect.
function Find_Value_Of_Aspect
(Id : Entity_Id;
A : Aspect_Id) return Node_Id;
-- Find the value of aspect A associated with entity Id. Return Empty if
-- Id does not have the requested aspect.
function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean; function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean;
-- Determine whether entity Id has aspect A -- Determine whether entity Id has aspect A
......
...@@ -3377,7 +3377,7 @@ package body Exp_Ch5 is ...@@ -3377,7 +3377,7 @@ package body Exp_Ch5 is
declare declare
Default_Iter : constant Entity_Id := Default_Iter : constant Entity_Id :=
Entity Entity
(Find_Aspect (Find_Value_Of_Aspect
(Etype (Container), (Etype (Container),
Aspect_Default_Iterator)); Aspect_Default_Iterator));
......
...@@ -4298,7 +4298,7 @@ package body Exp_Util is ...@@ -4298,7 +4298,7 @@ package body Exp_Util is
-- Look for aspect Default_Iterator -- Look for aspect Default_Iterator
if Has_Aspects (Parent (Typ)) then if Has_Aspects (Parent (Typ)) then
Aspect := Find_Aspect (Typ, Aspect_Default_Iterator); Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
if Present (Aspect) then if Present (Aspect) then
Iter := Entity (Aspect); Iter := Entity (Aspect);
......
...@@ -1226,11 +1226,10 @@ package body Sem_Ch13 is ...@@ -1226,11 +1226,10 @@ package body Sem_Ch13 is
Pragma_Identifier => Pragma_Identifier =>
Make_Identifier (Sloc (Id), Chars (Id))); Make_Identifier (Sloc (Id), Chars (Id)));
when Aspect_Synchronization => -- The aspect corresponds to pragma Implemented. Construct the
-- pragma.
-- The aspect corresponds to pragma Implemented.
-- Construct the pragma.
when Aspect_Synchronization =>
Aitem := Aitem :=
Make_Pragma (Loc, Make_Pragma (Loc,
Pragma_Argument_Associations => New_List ( Pragma_Argument_Associations => New_List (
...@@ -2338,7 +2337,7 @@ package body Sem_Ch13 is ...@@ -2338,7 +2337,7 @@ package body Sem_Ch13 is
procedure Check_One_Function (Subp : Entity_Id) is procedure Check_One_Function (Subp : Entity_Id) is
Default_Element : constant Node_Id := Default_Element : constant Node_Id :=
Find_Aspect Find_Value_Of_Aspect
(Etype (First_Formal (Subp)), (Etype (First_Formal (Subp)),
Aspect_Iterator_Element); Aspect_Iterator_Element);
......
...@@ -6717,11 +6717,13 @@ package body Sem_Ch4 is ...@@ -6717,11 +6717,13 @@ package body Sem_Ch4 is
Func_Name := Empty; Func_Name := Empty;
if Is_Variable (Prefix) then if Is_Variable (Prefix) then
Func_Name := Find_Aspect (Etype (Prefix), Aspect_Variable_Indexing); Func_Name :=
Find_Value_Of_Aspect (Etype (Prefix), Aspect_Variable_Indexing);
end if; end if;
if No (Func_Name) then if No (Func_Name) then
Func_Name := Find_Aspect (Etype (Prefix), Aspect_Constant_Indexing); Func_Name :=
Find_Value_Of_Aspect (Etype (Prefix), Aspect_Constant_Indexing);
end if; end if;
-- If aspect does not exist the expression is illegal. Error is -- If aspect does not exist the expression is illegal. Error is
......
...@@ -1789,7 +1789,7 @@ package body Sem_Ch5 is ...@@ -1789,7 +1789,7 @@ package body Sem_Ch5 is
declare declare
Element : constant Entity_Id := Element : constant Entity_Id :=
Find_Aspect (Typ, Aspect_Iterator_Element); Find_Value_Of_Aspect (Typ, Aspect_Iterator_Element);
begin begin
if No (Element) then if No (Element) then
Error_Msg_NE ("cannot iterate over&", N, Typ); Error_Msg_NE ("cannot iterate over&", N, Typ);
...@@ -1800,7 +1800,7 @@ package body Sem_Ch5 is ...@@ -1800,7 +1800,7 @@ package body Sem_Ch5 is
-- If the container has a variable indexing aspect, the -- If the container has a variable indexing aspect, the
-- element is a variable and is modifiable in the loop. -- element is a variable and is modifiable in the loop.
if Present (Find_Aspect (Typ, Aspect_Variable_Indexing)) then if Has_Aspect (Typ, Aspect_Variable_Indexing) then
Set_Ekind (Def_Id, E_Variable); Set_Ekind (Def_Id, E_Variable);
end if; end if;
end if; end if;
...@@ -1814,7 +1814,7 @@ package body Sem_Ch5 is ...@@ -1814,7 +1814,7 @@ package body Sem_Ch5 is
if Is_Entity_Name (Original_Node (Name (N))) if Is_Entity_Name (Original_Node (Name (N)))
and then not Is_Iterator (Typ) and then not Is_Iterator (Typ)
then then
if No (Find_Aspect (Typ, Aspect_Iterator_Element)) then if not Has_Aspect (Typ, Aspect_Iterator_Element) then
Error_Msg_NE Error_Msg_NE
("cannot iterate over&", Name (N), Typ); ("cannot iterate over&", Name (N), Typ);
else else
...@@ -3044,9 +3044,9 @@ package body Sem_Ch5 is ...@@ -3044,9 +3044,9 @@ package body Sem_Ch5 is
-- Check that the resulting object is an iterable container -- Check that the resulting object is an iterable container
elsif Present (Find_Aspect (Typ, Aspect_Iterator_Element)) elsif Has_Aspect (Typ, Aspect_Iterator_Element)
or else Present (Find_Aspect (Typ, Aspect_Constant_Indexing)) or else Has_Aspect (Typ, Aspect_Constant_Indexing)
or else Present (Find_Aspect (Typ, Aspect_Variable_Indexing)) or else Has_Aspect (Typ, Aspect_Variable_Indexing)
then then
null; null;
......
...@@ -9620,7 +9620,7 @@ package body Sem_Prag is ...@@ -9620,7 +9620,7 @@ package body Sem_Prag is
-- Retrieve the pragma as it contains the analyzed lists -- Retrieve the pragma as it contains the analyzed lists
Global := Aspect_Rep_Item (Parent (Global)); Global := Aspect_Rep_Item (Global);
-- The pragma may not have been analyzed because of the -- The pragma may not have been analyzed because of the
-- arbitrary declaration order of aspects. Make sure that -- arbitrary declaration order of aspects. Make sure that
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment