Clang Project

clang_source_code/lib/Serialization/ASTReaderInternals.h
1//===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file provides internal definitions used in the AST reader.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
14#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
15
16#include "MultiOnDiskHashTable.h"
17#include "clang/AST/DeclarationName.h"
18#include "clang/Basic/LLVM.h"
19#include "clang/Serialization/ASTBitCodes.h"
20#include "llvm/ADT/DenseSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/OnDiskHashTable.h"
24#include <ctime>
25#include <utility>
26
27namespace clang {
28
29class ASTReader;
30class FileEntry;
31struct HeaderFileInfo;
32class HeaderSearch;
33class IdentifierTable;
34class ObjCMethodDecl;
35
36namespace serialization {
37
38class ModuleFile;
39
40namespace reader {
41
42/// Class that performs name lookup into a DeclContext stored
43/// in an AST file.
44class ASTDeclContextNameLookupTrait {
45  ASTReader &Reader;
46  ModuleFile &F;
47
48public:
49  // Maximum number of lookup tables we allow before condensing the tables.
50  static const int MaxTables = 4;
51
52  /// The lookup result is a list of global declaration IDs.
53  using data_type = SmallVector<DeclID4>;
54
55  struct data_type_builder {
56    data_type &Data;
57    llvm::DenseSet<DeclID> Found;
58
59    data_type_builder(data_type &D) : Data(D) {}
60
61    void insert(DeclID ID) {
62      // Just use a linear scan unless we have more than a few IDs.
63      if (Found.empty() && !Data.empty()) {
64        if (Data.size() <= 4) {
65          for (auto I : Found)
66            if (I == ID)
67              return;
68          Data.push_back(ID);
69          return;
70        }
71
72        // Switch to tracking found IDs in the set.
73        Found.insert(Data.begin(), Data.end());
74      }
75
76      if (Found.insert(ID).second)
77        Data.push_back(ID);
78    }
79  };
80  using hash_value_type = unsigned;
81  using offset_type = unsigned;
82  using file_type = ModuleFile *;
83
84  using external_key_type = DeclarationName;
85  using internal_key_type = DeclarationNameKey;
86
87  explicit ASTDeclContextNameLookupTrait(ASTReader &ReaderModuleFile &F)
88      : Reader(Reader), F(F) {}
89
90  static bool EqualKey(const internal_key_type &aconst internal_key_type &b) {
91    return a == b;
92  }
93
94  static hash_value_type ComputeHash(const internal_key_type &Key) {
95    return Key.getHash();
96  }
97
98  static internal_key_type GetInternalKey(const external_key_type &Name) {
99    return Name;
100  }
101
102  static std::pair<unsignedunsigned>
103  ReadKeyDataLength(const unsigned char *&d);
104
105  internal_key_type ReadKey(const unsigned char *dunsigned);
106
107  void ReadDataInto(internal_key_typeconst unsigned char *d,
108                    unsigned DataLendata_type_builder &Val);
109
110  static void MergeDataInto(const data_type &Fromdata_type_builder &To) {
111    To.Data.reserve(To.Data.size() + From.size());
112    for (DeclID ID : From)
113      To.insert(ID);
114  }
115
116  file_type ReadFileRef(const unsigned char *&d);
117};
118
119struct DeclContextLookupTable {
120  MultiOnDiskHashTable<ASTDeclContextNameLookupTraitTable;
121};
122
123/// Base class for the trait describing the on-disk hash table for the
124/// identifiers in an AST file.
125///
126/// This class is not useful by itself; rather, it provides common
127/// functionality for accessing the on-disk hash table of identifiers
128/// in an AST file. Different subclasses customize that functionality
129/// based on what information they are interested in. Those subclasses
130/// must provide the \c data_type type and the ReadData operation, only.
131class ASTIdentifierLookupTraitBase {
132public:
133  using external_key_type = StringRef;
134  using internal_key_type = StringRef;
135  using hash_value_type = unsigned;
136  using offset_type = unsigned;
137
138  static bool EqualKey(const internal_key_typeaconst internal_key_typeb) {
139    return a == b;
140  }
141
142  static hash_value_type ComputeHash(const internal_key_typea);
143
144  static std::pair<unsignedunsigned>
145  ReadKeyDataLength(const unsigned char*& d);
146
147  // This hopefully will just get inlined and removed by the optimizer.
148  static const internal_key_type&
149  GetInternalKey(const external_key_typex) { return x; }
150
151  // This hopefully will just get inlined and removed by the optimizer.
152  static const external_key_type&
153  GetExternalKey(const internal_key_typex) { return x; }
154
155  static internal_key_type ReadKey(const unsigned chardunsigned n);
156};
157
158/// Class that performs lookup for an identifier stored in an AST file.
159class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
160  ASTReader &Reader;
161  ModuleFile &F;
162
163  // If we know the IdentifierInfo in advance, it is here and we will
164  // not build a new one. Used when deserializing information about an
165  // identifier that was constructed before the AST file was read.
166  IdentifierInfo *KnownII;
167
168public:
169  using data_type = IdentifierInfo *;
170
171  ASTIdentifierLookupTrait(ASTReader &ReaderModuleFile &F,
172                           IdentifierInfo *II = nullptr)
173      : Reader(Reader), F(F), KnownII(II) {}
174
175  data_type ReadData(const internal_key_typek,
176                     const unsigned chard,
177                     unsigned DataLen);
178
179  IdentID ReadIdentifierID(const unsigned char *d);
180
181  ASTReader &getReader() const { return Reader; }
182};
183
184/// The on-disk hash table used to contain information about
185/// all of the identifiers in the program.
186using ASTIdentifierLookupTable =
187    llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
188
189/// Class that performs lookup for a selector's entries in the global
190/// method pool stored in an AST file.
191class ASTSelectorLookupTrait {
192  ASTReader &Reader;
193  ModuleFile &F;
194
195public:
196  struct data_type {
197    SelectorID ID;
198    unsigned InstanceBits;
199    unsigned FactoryBits;
200    bool InstanceHasMoreThanOneDecl;
201    bool FactoryHasMoreThanOneDecl;
202    SmallVector<ObjCMethodDecl *, 2Instance;
203    SmallVector<ObjCMethodDecl *, 2Factory;
204  };
205
206  using external_key_type = Selector;
207  using internal_key_type = external_key_type;
208  using hash_value_type = unsigned;
209  using offset_type = unsigned;
210
211  ASTSelectorLookupTrait(ASTReader &ReaderModuleFile &F)
212      : Reader(Reader), F(F) {}
213
214  static bool EqualKey(const internal_key_typea,
215                       const internal_key_typeb) {
216    return a == b;
217  }
218
219  static hash_value_type ComputeHash(Selector Sel);
220
221  static const internal_key_type&
222  GetInternalKey(const external_key_typex) { return x; }
223
224  static std::pair<unsignedunsigned>
225  ReadKeyDataLength(const unsigned char*& d);
226
227  internal_key_type ReadKey(const unsigned chardunsigned);
228  data_type ReadData(Selectorconst unsigned chardunsigned DataLen);
229};
230
231/// The on-disk hash table used for the global method pool.
232using ASTSelectorLookupTable =
233    llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
234
235/// Trait class used to search the on-disk hash table containing all of
236/// the header search information.
237///
238/// The on-disk hash table contains a mapping from each header path to
239/// information about that header (how many times it has been included, its
240/// controlling macro, etc.). Note that we actually hash based on the size
241/// and mtime, and support "deep" comparisons of file names based on current
242/// inode numbers, so that the search can cope with non-normalized path names
243/// and symlinks.
244class HeaderFileInfoTrait {
245  ASTReader &Reader;
246  ModuleFile &M;
247  HeaderSearch *HS;
248  const char *FrameworkStrings;
249
250public:
251  using external_key_type = const FileEntry *;
252
253  struct internal_key_type {
254    off_t Size;
255    time_t ModTime;
256    StringRef Filename;
257    bool Imported;
258  };
259
260  using internal_key_ref = const internal_key_type &;
261
262  using data_type = HeaderFileInfo;
263  using hash_value_type = unsigned;
264  using offset_type = unsigned;
265
266  HeaderFileInfoTrait(ASTReader &ReaderModuleFile &MHeaderSearch *HS,
267                      const char *FrameworkStrings)
268      : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
269
270  static hash_value_type ComputeHash(internal_key_ref ikey);
271  internal_key_type GetInternalKey(const FileEntry *FE);
272  bool EqualKey(internal_key_ref ainternal_key_ref b);
273
274  static std::pair<unsignedunsigned>
275  ReadKeyDataLength(const unsigned char*& d);
276
277  static internal_key_type ReadKey(const unsigned char *dunsigned);
278
279  data_type ReadData(internal_key_ref,const unsigned char *dunsigned DataLen);
280};
281
282/// The on-disk hash table used for known header files.
283using HeaderFileInfoLookupTable =
284    llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
285
286// namespace reader
287
288// namespace serialization
289
290// namespace clang
291
292#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
293
clang::serialization::reader::ASTDeclContextNameLookupTrait::Reader
clang::serialization::reader::ASTDeclContextNameLookupTrait::F
clang::serialization::reader::ASTDeclContextNameLookupTrait::MaxTables
clang::serialization::reader::ASTDeclContextNameLookupTrait::data_type_builder
clang::serialization::reader::ASTDeclContextNameLookupTrait::data_type_builder::Data
clang::serialization::reader::ASTDeclContextNameLookupTrait::data_type_builder::Found
clang::serialization::reader::ASTDeclContextNameLookupTrait::data_type_builder::insert
clang::serialization::reader::ASTDeclContextNameLookupTrait::EqualKey
clang::serialization::reader::ASTDeclContextNameLookupTrait::ComputeHash
clang::serialization::reader::ASTDeclContextNameLookupTrait::GetInternalKey
clang::serialization::reader::ASTDeclContextNameLookupTrait::ReadKeyDataLength
clang::serialization::reader::ASTDeclContextNameLookupTrait::ReadKey
clang::serialization::reader::ASTDeclContextNameLookupTrait::ReadDataInto
clang::serialization::reader::ASTDeclContextNameLookupTrait::MergeDataInto
clang::serialization::reader::ASTDeclContextNameLookupTrait::ReadFileRef
clang::serialization::reader::DeclContextLookupTable::Table
clang::serialization::reader::ASTIdentifierLookupTraitBase::EqualKey
clang::serialization::reader::ASTIdentifierLookupTraitBase::ComputeHash
clang::serialization::reader::ASTIdentifierLookupTraitBase::ReadKeyDataLength
clang::serialization::reader::ASTIdentifierLookupTraitBase::GetInternalKey
clang::serialization::reader::ASTIdentifierLookupTraitBase::GetExternalKey
clang::serialization::reader::ASTIdentifierLookupTraitBase::ReadKey
clang::serialization::reader::ASTIdentifierLookupTrait::Reader
clang::serialization::reader::ASTIdentifierLookupTrait::F
clang::serialization::reader::ASTIdentifierLookupTrait::KnownII
clang::serialization::reader::ASTIdentifierLookupTrait::ReadData
clang::serialization::reader::ASTIdentifierLookupTrait::ReadIdentifierID
clang::serialization::reader::ASTIdentifierLookupTrait::getReader
clang::serialization::reader::ASTSelectorLookupTrait::Reader
clang::serialization::reader::ASTSelectorLookupTrait::F
clang::serialization::reader::ASTSelectorLookupTrait::data_type
clang::serialization::reader::ASTSelectorLookupTrait::data_type::ID
clang::serialization::reader::ASTSelectorLookupTrait::data_type::InstanceBits
clang::serialization::reader::ASTSelectorLookupTrait::data_type::FactoryBits
clang::serialization::reader::ASTSelectorLookupTrait::data_type::InstanceHasMoreThanOneDecl
clang::serialization::reader::ASTSelectorLookupTrait::data_type::FactoryHasMoreThanOneDecl
clang::serialization::reader::ASTSelectorLookupTrait::data_type::Instance
clang::serialization::reader::ASTSelectorLookupTrait::data_type::Factory
clang::serialization::reader::ASTSelectorLookupTrait::EqualKey
clang::serialization::reader::ASTSelectorLookupTrait::ComputeHash
clang::serialization::reader::ASTSelectorLookupTrait::GetInternalKey
clang::serialization::reader::ASTSelectorLookupTrait::ReadKeyDataLength
clang::serialization::reader::ASTSelectorLookupTrait::ReadKey
clang::serialization::reader::ASTSelectorLookupTrait::ReadData
clang::serialization::reader::HeaderFileInfoTrait::Reader
clang::serialization::reader::HeaderFileInfoTrait::M
clang::serialization::reader::HeaderFileInfoTrait::HS
clang::serialization::reader::HeaderFileInfoTrait::FrameworkStrings
clang::serialization::reader::HeaderFileInfoTrait::internal_key_type
clang::serialization::reader::HeaderFileInfoTrait::internal_key_type::Size
clang::serialization::reader::HeaderFileInfoTrait::internal_key_type::ModTime
clang::serialization::reader::HeaderFileInfoTrait::internal_key_type::Filename
clang::serialization::reader::HeaderFileInfoTrait::internal_key_type::Imported
clang::serialization::reader::HeaderFileInfoTrait::ComputeHash
clang::serialization::reader::HeaderFileInfoTrait::GetInternalKey
clang::serialization::reader::HeaderFileInfoTrait::EqualKey
clang::serialization::reader::HeaderFileInfoTrait::ReadKeyDataLength
clang::serialization::reader::HeaderFileInfoTrait::ReadKey
clang::serialization::reader::HeaderFileInfoTrait::ReadData