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 <schonb...@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.
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