libgpr2_24.0.0_eda3c693/src/lib/gpr2-source_info-parser-ali.ads

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
--
--  Copyright (C) 2019-2023, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-Exception
--

private with Ada.Containers.Indefinite_Hashed_Maps;
private with GPR2.Path_Name;
private with GPR2.Unit;

package GPR2.Source_Info.Parser.ALI is

   type Object is new Parser.Object
     (Language => Ada_Language,
      Kind     => LI) with private;

   overriding procedure Compute
     (Self   : not null access Object;
      Data   : in out Source_Info.Object'Class;
      Source : Project.Source.Object);
   --  Setup Data with the information from GNAT .ali file

   overriding procedure Clear_Cache (Self : not null access Object);
   --  Clear cached ALI data

private

   use type Ada.Containers.Hash_Type;
   use type GPR2.Unit.Object;

   type Cache_Holder is record
      Unit      : GPR2.Unit.Object;
      Checksum  : Word;
      Timestamp : Ada.Calendar.Time;
      Depends   : Dependency_Vectors_Ref.Ref;
   end record;
   --  When parsing ALI files, we retrieve information for the whole
   --  compilation unit at once. This information will be split into
   --  potentially several source_info objects (spec, body and separates).
   --  In order to not re-parse the ALI file for each of those parts, we
   --  cache the information.

   overriding function "=" (L, R : Cache_Holder) return Boolean is
     (L.Unit = R.Unit and then
      L.Checksum = R.Checksum);

   type Cache_Key (LI_Length  : Natural; Src_Length : Natural) is record
      LI      : Filename_Type (1 .. LI_Length);
      Src     : Filename_Type (1 .. Src_Length);
      LI_Kind : GPR2.Unit.Library_Unit_Type;
   end record;

   function Image (Key : Cache_Key) return String is
     (String (Key.LI) & "@" &
        GPR2.Path_Name.Simple_Name (String (Key.Src)) & "%" &
      (case Key.LI_Kind is
       when GPR2.Unit.Body_Kind => "b",
       when GPR2.Unit.Spec_Kind => "s",
       when GPR2.Unit.S_Separate => "sep"));

   function Hash (Key : Cache_Key) return Ada.Containers.Hash_Type is
     (Hash (Key.LI) + Hash (Key.Src) +
          Ada.Containers.Hash_Type
           (GPR2.Unit.Library_Unit_Type'Pos (Key.LI_Kind)));

   function Equivalent_Cache_Keys (Left, Right : Cache_Key) return Boolean is
     (Left.LI = Right.LI
      and then Left.Src = Right.Src
      and then Left.LI_Kind = Right.LI_Kind);
   --  This function is for map container. We can't use default "=" function
   --  because it is binary comparison, but we should compare Filename_Type
   --  components with its overridden "=" function.

   package Cache_Map is new Ada.Containers.Indefinite_Hashed_Maps
     (Cache_Key, Cache_Holder, Hash, Equivalent_Keys => Equivalent_Cache_Keys);
   --  This caches the information for spec and body units. The key identifies
   --  the ALI file, the source and the kind of library unit.

   package Sep_Cache_Map is new Ada.Containers.Indefinite_Hashed_Maps
     (String, Cache_Holder, Ada.Strings.Hash, "=");
   --  This caches the information for separate units. Those can be retrieved
   --  by their unit name (lower-cased).

   type Object is new Parser.Object
     (Language => Ada_Language,
      Kind     => LI)
   with record
      Cache     : Cache_Map.Map;
      Sep_Cache : Sep_Cache_Map.Map;
   end record;

end GPR2.Source_Info.Parser.ALI;