[Ada] Notes from subunits incorrectly recorded in ALI files

Arnaud Charlet charlet@adacore.com
Wed Jul 30 15:10:00 GMT 2014


This change fixes the way annotations coming from subunits are recorded in
ALI files, so that their original source location (including the source file
name of the subunit) is correctly preserved.

The following commands must produce the shown output:

$ gcc -c annot_separate.adb
$ sed -n -e '/^U/s/	.*//p' -e '/^N/p' annot_separate.ali
U annot_separate%b
N A3:4 foo bar "from pak.adb"
N A3:4:annot_separate-q.adb foo bar "from pak-q.adb"
U annot_separate%s
N A3:4 foo bar "from pak.ads"

--
package body Annot_Separate is
   pragma Annotate (Foo, Bar, "from pak.adb");
   procedure P is begin null; end P;
   procedure Q is separate;
end Annot_Separate;
--
package Annot_Separate is
   pragma Annotate (Foo, Bar, "from pak.ads");
   procedure P;
   procedure Q;
end Annot_Separate;
separate (Annot_Separate)
procedure Q is
   pragma Annotate (Foo, Bar, "from pak-q.adb");
begin
   null;
end Q;

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-07-30  Thomas Quinot  <quinot@adacore.com>

	* lib.ads (Notes): Simplify. The Unit component in Notes_Entry
	is redundant. Instead used the pragma Node_Id directly as the
	element type.
	* lib.adb (Store_Note): Store only notes that do not come from
	an instance, and that are in the extended main source unit.
	* lib-writ (Write_Unit_Information): Annotations from subunits
	must be emitted along with those for the main unit, and they
	must carry a specific file name.
	* ali.ads (Notes_Record): Use a File_Name_Type instead of a
	Unit_Id for the source file containing the pragma, as in the
	case of annotations from subunits we might not have a readily
	available unit id.
	* ali.adb (Scan_ALI): Account for above change in data structure.

-------------- next part --------------
Index: lib.adb
===================================================================
--- lib.adb	(revision 213263)
+++ lib.adb	(working copy)
@@ -1046,8 +1046,16 @@
    ----------------
 
    procedure Store_Note (N : Node_Id) is
+      Sfile : constant Source_File_Index := Get_Source_File_Index (Sloc (N));
    begin
-      Notes.Append ((Pragma_Node => N, Unit => Current_Sem_Unit));
+      --  Notes for a generic are emitted when processing the template, never
+      --  in instances.
+
+      if In_Extended_Main_Code_Unit (N)
+        and then Instance (Sfile) = No_Instance_Id
+      then
+         Notes.Append (N);
+      end if;
    end Store_Note;
 
    -------------------------------
Index: lib.ads
===================================================================
--- lib.ads	(revision 213263)
+++ lib.ads	(working copy)
@@ -826,13 +826,8 @@
 
    --  The following table stores references to pragmas that generate Notes
 
-   type Notes_Entry is record
-      Pragma_Node : Node_Id;
-      Unit        : Unit_Number_Type;
-   end record;
-
    package Notes is new Table.Table (
-     Table_Component_Type => Notes_Entry,
+     Table_Component_Type => Node_Id,
      Table_Index_Type     => Integer,
      Table_Low_Bound      => 1,
      Table_Initial        => Alloc.Notes_Initial,
Index: lib-writ.adb
===================================================================
--- lib-writ.adb	(revision 213263)
+++ lib-writ.adb	(working copy)
@@ -647,13 +647,26 @@
 
          for J in 1 .. Notes.Last loop
             declare
-               N : constant Node_Id          := Notes.Table (J).Pragma_Node;
+               N : constant Node_Id          := Notes.Table (J);
                L : constant Source_Ptr       := Sloc (N);
-               U : constant Unit_Number_Type := Notes.Table (J).Unit;
+               U : constant Unit_Number_Type :=
+                     Unit (Get_Source_File_Index (L));
                C : Character;
 
+               Note_Unit : Unit_Number_Type;
+               --  The unit in whose U section this note must be emitted:
+               --  notes for subunits are emitted along with the main unit;
+               --  all other notes are emitted as part of the enclosing
+               --  compilation unit.
+
             begin
-               if U = Unit_Num then
+               if Nkind (Unit (Cunit (U))) = N_Subunit then
+                  Note_Unit := Main_Unit;
+               else
+                  Note_Unit := U;
+               end if;
+
+               if Note_Unit = Unit_Num then
                   Write_Info_Initiate ('N');
                   Write_Info_Char (' ');
 
@@ -677,6 +690,15 @@
                   Write_Info_Char (':');
                   Write_Info_Int (Int (Get_Column_Number (L)));
 
+                  --  Indicate source file of annotation if different from
+                  --  compilation unit source file (case of annotation coming
+                  --  from a separate).
+
+                  if Get_Source_File_Index (L) /= Source_Index (Unit_Num) then
+                     Write_Info_Char (':');
+                     Write_Info_Name (File_Name (Get_Source_File_Index (L)));
+                  end if;
+
                   declare
                      A : Node_Id;
 
Index: ali.adb
===================================================================
--- ali.adb	(revision 213263)
+++ ali.adb	(working copy)
@@ -2185,20 +2185,30 @@
                Notes.Table (Notes.Last).Pragma_Line := Get_Nat;
                Checkc (':');
                Notes.Table (Notes.Last).Pragma_Col  := Get_Nat;
-               Notes.Table (Notes.Last).Unit        := Units.Last;
 
+               if not At_Eol and then Nextc = ':' then
+                  Checkc (':');
+                  Notes.Table (Notes.Last).Pragma_Source_File :=
+                    Get_File_Name (Lower => True);
+               else
+                  Notes.Table (Notes.Last).Pragma_Source_File :=
+                    Units.Table (Units.Last).Sfile;
+               end if;
+
                if At_Eol then
                   Notes.Table (Notes.Last).Pragma_Args := No_Name;
 
                else
+                  --  Note: can't use Get_Name here as the remainder of the
+                  --  line is unstructured text whose syntax depends on the
+                  --  particular pragma used.
+
                   Checkc (' ');
 
                   Name_Len := 0;
                   while not At_Eol loop
                      Add_Char_To_Name_Buffer (Getc);
                   end loop;
-
-                  Notes.Table (Notes.Last).Pragma_Args := Name_Enter;
                end if;
 
                Skip_Eol;
Index: ali.ads
===================================================================
--- ali.ads	(revision 213263)
+++ ali.ads	(working copy)
@@ -669,8 +669,8 @@
       Pragma_Col : Nat;
       --  Column number of pragma
 
-      Unit : Unit_Id;
-      --  Unit_Id for the entry
+      Pragma_Source_File : File_Name_Type;
+      --  Source file of pragma
 
       Pragma_Args : Name_Id;
       --  Pragma arguments. No_Name if no arguments, otherwise a single


More information about the Gcc-patches mailing list