1 //===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides internal definitions used in the AST reader.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
15 #define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
17 #include "MultiOnDiskHashTable.h"
18 #include "clang/AST/DeclarationName.h"
19 #include "clang/Basic/LLVM.h"
20 #include "clang/Serialization/ASTBitCodes.h"
21 #include "llvm/ADT/DenseSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Support/OnDiskHashTable.h"
32 struct HeaderFileInfo;
34 class IdentifierTable;
37 namespace serialization {
43 /// Class that performs name lookup into a DeclContext stored
45 class ASTDeclContextNameLookupTrait {
50 // Maximum number of lookup tables we allow before condensing the tables.
51 static const int MaxTables = 4;
53 /// The lookup result is a list of global declaration IDs.
54 using data_type = SmallVector<DeclID, 4>;
56 struct data_type_builder {
58 llvm::DenseSet<DeclID> Found;
60 data_type_builder(data_type &D) : Data(D) {}
62 void insert(DeclID ID) {
63 // Just use a linear scan unless we have more than a few IDs.
64 if (Found.empty() && !Data.empty()) {
65 if (Data.size() <= 4) {
73 // Switch to tracking found IDs in the set.
74 Found.insert(Data.begin(), Data.end());
77 if (Found.insert(ID).second)
81 using hash_value_type = unsigned;
82 using offset_type = unsigned;
83 using file_type = ModuleFile *;
85 using external_key_type = DeclarationName;
86 using internal_key_type = DeclarationNameKey;
88 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
89 : Reader(Reader), F(F) {}
91 static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
95 static hash_value_type ComputeHash(const internal_key_type &Key) {
99 static internal_key_type GetInternalKey(const external_key_type &Name) {
103 static std::pair<unsigned, unsigned>
104 ReadKeyDataLength(const unsigned char *&d);
106 internal_key_type ReadKey(const unsigned char *d, unsigned);
108 void ReadDataInto(internal_key_type, const unsigned char *d,
109 unsigned DataLen, data_type_builder &Val);
111 static void MergeDataInto(const data_type &From, data_type_builder &To) {
112 To.Data.reserve(To.Data.size() + From.size());
113 for (DeclID ID : From)
117 file_type ReadFileRef(const unsigned char *&d);
120 struct DeclContextLookupTable {
121 MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
124 /// Base class for the trait describing the on-disk hash table for the
125 /// identifiers in an AST file.
127 /// This class is not useful by itself; rather, it provides common
128 /// functionality for accessing the on-disk hash table of identifiers
129 /// in an AST file. Different subclasses customize that functionality
130 /// based on what information they are interested in. Those subclasses
131 /// must provide the \c data_type type and the ReadData operation, only.
132 class ASTIdentifierLookupTraitBase {
134 using external_key_type = StringRef;
135 using internal_key_type = StringRef;
136 using hash_value_type = unsigned;
137 using offset_type = unsigned;
139 static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
143 static hash_value_type ComputeHash(const internal_key_type& a);
145 static std::pair<unsigned, unsigned>
146 ReadKeyDataLength(const unsigned char*& d);
148 // This hopefully will just get inlined and removed by the optimizer.
149 static const internal_key_type&
150 GetInternalKey(const external_key_type& x) { return x; }
152 // This hopefully will just get inlined and removed by the optimizer.
153 static const external_key_type&
154 GetExternalKey(const internal_key_type& x) { return x; }
156 static internal_key_type ReadKey(const unsigned char* d, unsigned n);
159 /// Class that performs lookup for an identifier stored in an AST file.
160 class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
164 // If we know the IdentifierInfo in advance, it is here and we will
165 // not build a new one. Used when deserializing information about an
166 // identifier that was constructed before the AST file was read.
167 IdentifierInfo *KnownII;
170 using data_type = IdentifierInfo *;
172 ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
173 IdentifierInfo *II = nullptr)
174 : Reader(Reader), F(F), KnownII(II) {}
176 data_type ReadData(const internal_key_type& k,
177 const unsigned char* d,
180 IdentID ReadIdentifierID(const unsigned char *d);
182 ASTReader &getReader() const { return Reader; }
185 /// The on-disk hash table used to contain information about
186 /// all of the identifiers in the program.
187 using ASTIdentifierLookupTable =
188 llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
190 /// Class that performs lookup for a selector's entries in the global
191 /// method pool stored in an AST file.
192 class ASTSelectorLookupTrait {
199 unsigned InstanceBits;
200 unsigned FactoryBits;
201 bool InstanceHasMoreThanOneDecl;
202 bool FactoryHasMoreThanOneDecl;
203 SmallVector<ObjCMethodDecl *, 2> Instance;
204 SmallVector<ObjCMethodDecl *, 2> Factory;
207 using external_key_type = Selector;
208 using internal_key_type = external_key_type;
209 using hash_value_type = unsigned;
210 using offset_type = unsigned;
212 ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
213 : Reader(Reader), F(F) {}
215 static bool EqualKey(const internal_key_type& a,
216 const internal_key_type& b) {
220 static hash_value_type ComputeHash(Selector Sel);
222 static const internal_key_type&
223 GetInternalKey(const external_key_type& x) { return x; }
225 static std::pair<unsigned, unsigned>
226 ReadKeyDataLength(const unsigned char*& d);
228 internal_key_type ReadKey(const unsigned char* d, unsigned);
229 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
232 /// The on-disk hash table used for the global method pool.
233 using ASTSelectorLookupTable =
234 llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
236 /// Trait class used to search the on-disk hash table containing all of
237 /// the header search information.
239 /// The on-disk hash table contains a mapping from each header path to
240 /// information about that header (how many times it has been included, its
241 /// controlling macro, etc.). Note that we actually hash based on the size
242 /// and mtime, and support "deep" comparisons of file names based on current
243 /// inode numbers, so that the search can cope with non-normalized path names
245 class HeaderFileInfoTrait {
249 const char *FrameworkStrings;
252 using external_key_type = const FileEntry *;
254 struct internal_key_type {
261 using internal_key_ref = const internal_key_type &;
263 using data_type = HeaderFileInfo;
264 using hash_value_type = unsigned;
265 using offset_type = unsigned;
267 HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
268 const char *FrameworkStrings)
269 : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
271 static hash_value_type ComputeHash(internal_key_ref ikey);
272 internal_key_type GetInternalKey(const FileEntry *FE);
273 bool EqualKey(internal_key_ref a, internal_key_ref b);
275 static std::pair<unsigned, unsigned>
276 ReadKeyDataLength(const unsigned char*& d);
278 static internal_key_type ReadKey(const unsigned char *d, unsigned);
280 data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
283 /// The on-disk hash table used for known header files.
284 using HeaderFileInfoLookupTable =
285 llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
287 } // namespace reader
289 } // namespace serialization
293 #endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H