[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