[Ada] Proper implementation of interfacing aspects.
Arnaud Charlet
charlet@adacore.com
Tue Jun 12 09:23:00 GMT 2012
This patch implements properly the aspects Convention, Import, Export, Link_
Name and External_Name, which replace the corresponding Ada 2005 pragmas.
Compiling missing_convention.ads must yield:
missing_convention.ads:3:07: missing Convention aspect for Export/Import
---
function missing_convention return Integer
with
Export => True,
Link_Name => "example";
---
Tested on x86_64-pc-linux-gnu, committed on trunk
2012-06-12 Ed Schonberg <schonberg@adacore.com>
* exp_prag.adb (Expand_Pragma_Import_Or_Interface): revert previous
patch. The processing of interfacing aspects now generates a
proper Ada 2005 pragma.
* sem_prag.adb (Analyze_Pragma, cases Pragma_Export and
Pragma_Import): revert previous patch. The processing of
interfacing aspects now generates a proper Ada 2005 pragma.
* sem_ch13.adb (Analyze_Aspect_Specifications): generate proper
pragam for aspects Convention, Import and Export. Scan list
of aspects to collect link name and external name if present,
and verify that a complete pragma can be generated.
-------------- next part --------------
Index: exp_prag.adb
===================================================================
--- exp_prag.adb (revision 188428)
+++ exp_prag.adb (working copy)
@@ -531,14 +531,7 @@
Init_Call : Node_Id;
begin
- -- If the pragma comes from an aspect, the entity is its first argument.
-
- if Present (Corresponding_Aspect (N)) then
- Def_Id := Entity (Arg1 (N));
- else
- Def_Id := Entity (Arg2 (N));
- end if;
-
+ Def_Id := Entity (Arg2 (N));
if Ekind (Def_Id) = E_Variable then
-- Find generated initialization call for object, if any
Index: sem_prag.adb
===================================================================
--- sem_prag.adb (revision 188428)
+++ sem_prag.adb (working copy)
@@ -8647,29 +8647,8 @@
Name_External_Name,
Name_Link_Name));
- if Present (Corresponding_Aspect (N)) then
+ Check_At_Least_N_Arguments (2);
- -- If the pragma comes from an Aspect, there is a single entity
- -- parameter and an optional booean value with default true.
- -- The convention must be provided by a separate aspect.
-
- Check_At_Least_N_Arguments (1);
- Check_At_Most_N_Arguments (2);
- Def_Id := Entity (Arg1);
-
- if No (Arg2) then
-
- -- If the aspect has a default True value, set corresponding
- -- flag on the entity.
-
- Set_Is_Exported (Def_Id);
- end if;
- return;
-
- else
- Check_At_Least_N_Arguments (2);
- end if;
-
Check_At_Most_N_Arguments (4);
Process_Convention (C, Def_Id);
@@ -9603,30 +9582,10 @@
Name_External_Name,
Name_Link_Name));
- if Present (Corresponding_Aspect (N)) then
+ Check_At_Least_N_Arguments (2);
+ Check_At_Most_N_Arguments (4);
+ Process_Import_Or_Interface;
- -- If the pragma comes from an Aspect, there is a single entity
- -- parameter and an optional booean value with default true.
- -- The convention must be provided by a separate aspect.
-
- Check_At_Least_N_Arguments (1);
- Check_At_Most_N_Arguments (2);
-
- if No (Arg2) then
-
- -- If the aspect has a default True value, set corresponding
- -- flag on the entity.
-
- Set_Is_Imported (Entity (Arg1));
- end if;
- return;
-
- else
- Check_At_Least_N_Arguments (2);
- Check_At_Most_N_Arguments (4);
- Process_Import_Or_Interface;
- end if;
-
----------------------
-- Import_Exception --
----------------------
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb (revision 188428)
+++ sem_ch13.adb (working copy)
@@ -949,6 +949,33 @@
end if;
goto Continue;
+
+ elsif A_Id = Aspect_Import
+ or else A_Id = Aspect_Export
+ then
+
+ -- Verify that there is an aspect Convention that will
+ -- incorporate the Import/Export aspect, and eventual
+ -- Link/External names.
+
+ declare
+ A : Node_Id;
+
+ begin
+ A := First (L);
+ while Present (A) loop
+ exit when Chars (Identifier (A)) = Name_Convention;
+ Next (A);
+ end loop;
+
+ if No (A) then
+ Error_Msg_N
+ ("missing Convention aspect for Export/Import",
+ Aspect);
+ end if;
+ end;
+
+ goto Continue;
end if;
-- For all other aspects we just create a matching pragma
@@ -1168,14 +1195,74 @@
-- the second argument is a local name referring to the entity,
-- and the first argument is the aspect definition expression.
- when Aspect_Convention =>
- Aitem :=
- Make_Pragma (Loc,
- Pragma_Argument_Associations =>
- New_List (Relocate_Node (Expr), Ent),
- Pragma_Identifier =>
- Make_Identifier (Sloc (Id), Chars (Id)));
+ when Aspect_Convention =>
+ -- The aspect may be part of the specification of an import
+ -- or export pragma. Scan the aspect list to gather the
+ -- other components, if any. The name of the generated
+ -- pragma is one of Convention/Import/Export.
+
+ declare
+ P_Name : Name_Id;
+ A_Name : Name_Id;
+ A : Node_Id;
+ Arg_List : List_Id;
+ Found : Boolean;
+ L_Assoc : Node_Id;
+ E_Assoc : Node_Id;
+
+ begin
+ P_Name := Chars (Id);
+ Found := False;
+ Arg_List := New_List;
+ L_Assoc := Empty;
+ E_Assoc := Empty;
+
+ A := First (L);
+ while Present (A) loop
+ A_Name := Chars (Identifier (A));
+
+ if A_Name = Name_Import
+ or else A_Name = Name_Export
+ then
+ if Found then
+ Error_Msg_N ("conflicting", A);
+ else
+ Found := True;
+ end if;
+
+ P_Name := A_Name;
+
+ elsif A_Name = Name_Link_Name then
+ L_Assoc := Make_Pragma_Argument_Association (Loc,
+ Chars => A_Name,
+ Expression => Relocate_Node (Expression (A)));
+
+ elsif A_Name = Name_External_Name then
+ E_Assoc := Make_Pragma_Argument_Association (Loc,
+ Chars => A_Name,
+ Expression => Relocate_Node (Expression (A)));
+ end if;
+
+ Next (A);
+ end loop;
+
+ Arg_List := New_List (Relocate_Node (Expr), Ent);
+ if Present (L_Assoc) then
+ Append_To (Arg_List, L_Assoc);
+ end if;
+
+ if Present (E_Assoc) then
+ Append_To (Arg_List, E_Assoc);
+ end if;
+
+ Aitem :=
+ Make_Pragma (Loc,
+ Pragma_Argument_Associations => Arg_List,
+ Pragma_Identifier =>
+ Make_Identifier (Loc, P_Name));
+ end;
+
when Aspect_Warnings =>
-- Construct the pragma
@@ -1570,13 +1657,33 @@
Analyze_Aspect_Dimension_System (N, Id, Expr);
goto Continue;
- -- Placeholders for new aspects without corresponding pragmas
+ when Aspect_External_Name |
+ Aspect_Link_Name =>
- when Aspect_External_Name =>
- null;
+ -- Verify that there is an Import/Export aspect defined for
+ -- the entity. The processing of that aspect in turn checks
+ -- that there is a Convention aspect declared. The pragma is
+ -- constructed when processing the Convention aspect.
- when Aspect_Link_Name =>
- null;
+ declare
+ A : Node_Id;
+
+ begin
+ A := First (L);
+ while Present (A) loop
+ exit when Chars (Identifier (A)) = Name_Export
+ or else Chars (Identifier (A)) = Name_Import;
+ Next (A);
+ end loop;
+
+ if No (A) then
+ Error_Msg_N
+ ("Missing Import/Export for Link/External name",
+ Aspect);
+ end if;
+ end;
+
+ goto Continue;
end case;
-- If a delay is required, we delay the freeze (not much point in
More information about the Gcc-patches
mailing list