Patchwork [Ada] Duplicate entries for parameters in gnatxref output

login
register
mail settings
Submitter Arnaud Charlet
Date Oct. 29, 2012, 11:01 a.m.
Message ID <20121029110135.GA17157@adacore.com>
Download mbox | patch
Permalink /patch/194964/
State New
Headers show

Comments

Arnaud Charlet - Oct. 29, 2012, 11:01 a.m.
When a call to a subprogram in another package uses named parameters,
gnatxref will sometimes output duplicate entries for the parameter,
depending on the order in which the ALI files are read.

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

2012-10-29  Emmanuel Briot  <briot@adacore.com>

	* xr_tabls.adb, xr_tabls.ads (Add_Declaration, Add_Reference): No
	longer assume that a parameter declaration is seen after the subprogram
	that uses it.

Patch

Index: xr_tabls.adb
===================================================================
--- xr_tabls.adb	(revision 192918)
+++ xr_tabls.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1998-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1998-2012, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -223,6 +223,7 @@ 
       Line         : Natural;
       Column       : Natural;
       Decl_Type    : Character;
+      Is_Parameter : Boolean := False;
       Remove_Only  : Boolean := False;
       Symbol_Match : Boolean := True)
       return         Declaration_Reference
@@ -235,7 +236,7 @@ 
       New_Decl : Declaration_Reference :=
                    Entities_HTable.Get (Key'Unchecked_Access);
 
-      Is_Parameter : Boolean := False;
+      Is_Param : Boolean := Is_Parameter;
 
    begin
       --  Insert the Declaration in the table. There might already be a
@@ -243,7 +244,7 @@ 
       --  need to check that first.
 
       if New_Decl /= null and then New_Decl.Symbol_Length = 0 then
-         Is_Parameter := New_Decl.Is_Parameter;
+         Is_Param := Is_Parameter or else New_Decl.Is_Parameter;
          Entities_HTable.Remove (Key'Unrestricted_Access);
          Entities_Count := Entities_Count - 1;
          Free (New_Decl.Key);
@@ -269,7 +270,7 @@ 
                                       Column        => Column,
                                       Source_Line   => null,
                                       Next          => null),
-              Is_Parameter  => Is_Parameter,
+              Is_Parameter  => Is_Param,
               Decl_Type     => Decl_Type,
               Body_Ref      => null,
               Ref_Ref       => null,
@@ -294,6 +295,10 @@ 
       then
          New_Decl.Match := Default_Match
            or else Match (File_Ref, Line, Column);
+         New_Decl.Is_Parameter := New_Decl.Is_Parameter or else Is_Param;
+
+      elsif New_Decl /= null then
+         New_Decl.Is_Parameter := New_Decl.Is_Parameter or else Is_Param;
       end if;
 
       return New_Decl;
@@ -392,6 +397,8 @@ 
       Labels_As_Ref : Boolean)
    is
       New_Ref : Reference;
+      New_Decl : Declaration_Reference;
+      pragma Unreferenced (New_Decl);
 
    begin
       case Ref_Type is
@@ -407,37 +414,22 @@ 
          when '=' | '<' | '>' | '^' =>
 
             --  Create a dummy declaration in the table to report it as a
-            --  parameter. Note that the current declaration for the subprogram
-            --  comes before the declaration of the parameter.
+            --  parameter.
+            --  In a given ALI file, the declaration of the subprogram comes
+            --  before the declaration of the parameter. However, it is
+            --  possible that another ALI file has been parsed that also
+            --  references the parameter (for instance a named parameter in a
+            --  call), so we need to check whether there already exists a
+            --  declaration for the parameter.
 
-            declare
-               Key      : constant String :=
-                            Key_From_Ref (File_Ref, Line, Column);
-               New_Decl : Declaration_Reference;
+            New_Decl := Add_Declaration
+              (File_Ref  => File_Ref,
+               Symbol    => "",
+               Line      => Line,
+               Column    => Column,
+               Decl_Type => ' ',
+               Is_Parameter => True);
 
-            begin
-               New_Decl := new Declaration_Record'
-                 (Symbol_Length => 0,
-                  Symbol        => "",
-                  Key           => new String'(Key),
-                  Decl          => new Reference_Record'
-                                     (File          => File_Ref,
-                                      Line          => Line,
-                                      Column        => Column,
-                                      Source_Line   => null,
-                                      Next          => null),
-                  Is_Parameter  => True,
-                  Decl_Type     => ' ',
-                  Body_Ref      => null,
-                  Ref_Ref       => null,
-                  Modif_Ref     => null,
-                  Match         => False,
-                  Par_Symbol    => null,
-                  Next          => null);
-               Entities_HTable.Set (New_Decl);
-               Entities_Count := Entities_Count + 1;
-            end;
-
          when 'e' | 'z' | 't' | 'p' | 'P' | 'k' | 'd' =>
             return;
 
Index: xr_tabls.ads
===================================================================
--- xr_tabls.ads	(revision 192918)
+++ xr_tabls.ads	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1998-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1998-2012, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -78,6 +78,7 @@ 
       Line         : Natural;
       Column       : Natural;
       Decl_Type    : Character;
+      Is_Parameter : Boolean := False;
       Remove_Only  : Boolean := False;
       Symbol_Match : Boolean := True)
       return         Declaration_Reference;
@@ -89,6 +90,8 @@ 
    --  the command line. In that case, the entity will not be output by
    --  gnatfind. If Symbol_Match is True, the entity will only be output if the
    --  file name itself matches.
+   --  Is_Parameter should be set to True if the entity is known to be a
+   --  subprogram parameter.
 
    procedure Add_Parent
      (Declaration : in out Declaration_Reference;