1 //===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides internal definitions used in the AST reader.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
14 #define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
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"
31 struct HeaderFileInfo
;
35 namespace serialization
{
41 /// Class that performs name lookup into a DeclContext stored
43 class ASTDeclContextNameLookupTrait
{
48 // Maximum number of lookup tables we allow before condensing the tables.
49 static const int MaxTables
= 4;
51 /// The lookup result is a list of global declaration IDs.
52 using data_type
= SmallVector
<GlobalDeclID
, 4>;
54 struct data_type_builder
{
56 llvm::DenseSet
<GlobalDeclID
> Found
;
58 data_type_builder(data_type
&D
) : Data(D
) {}
60 void insert(GlobalDeclID ID
) {
61 // Just use a linear scan unless we have more than a few IDs.
62 if (Found
.empty() && !Data
.empty()) {
63 if (Data
.size() <= 4) {
71 // Switch to tracking found IDs in the set.
72 Found
.insert(Data
.begin(), Data
.end());
75 if (Found
.insert(ID
).second
)
79 using hash_value_type
= unsigned;
80 using offset_type
= unsigned;
81 using file_type
= ModuleFile
*;
83 using external_key_type
= DeclarationName
;
84 using internal_key_type
= DeclarationNameKey
;
86 explicit ASTDeclContextNameLookupTrait(ASTReader
&Reader
, ModuleFile
&F
)
87 : Reader(Reader
), F(F
) {}
89 static bool EqualKey(const internal_key_type
&a
, const internal_key_type
&b
) {
93 static hash_value_type
ComputeHash(const internal_key_type
&Key
) {
97 static internal_key_type
GetInternalKey(const external_key_type
&Name
) {
101 static std::pair
<unsigned, unsigned>
102 ReadKeyDataLength(const unsigned char *&d
);
104 internal_key_type
ReadKey(const unsigned char *d
, unsigned);
106 void ReadDataInto(internal_key_type
, const unsigned char *d
,
107 unsigned DataLen
, data_type_builder
&Val
);
109 static void MergeDataInto(const data_type
&From
, data_type_builder
&To
) {
110 To
.Data
.reserve(To
.Data
.size() + From
.size());
111 for (GlobalDeclID ID
: From
)
115 file_type
ReadFileRef(const unsigned char *&d
);
118 struct DeclContextLookupTable
{
119 MultiOnDiskHashTable
<ASTDeclContextNameLookupTrait
> Table
;
122 /// Base class for the trait describing the on-disk hash table for the
123 /// identifiers in an AST file.
125 /// This class is not useful by itself; rather, it provides common
126 /// functionality for accessing the on-disk hash table of identifiers
127 /// in an AST file. Different subclasses customize that functionality
128 /// based on what information they are interested in. Those subclasses
129 /// must provide the \c data_type type and the ReadData operation, only.
130 class ASTIdentifierLookupTraitBase
{
132 using external_key_type
= StringRef
;
133 using internal_key_type
= StringRef
;
134 using hash_value_type
= unsigned;
135 using offset_type
= unsigned;
137 static bool EqualKey(const internal_key_type
& a
, const internal_key_type
& b
) {
141 static hash_value_type
ComputeHash(const internal_key_type
& a
);
143 static std::pair
<unsigned, unsigned>
144 ReadKeyDataLength(const unsigned char*& d
);
146 // This hopefully will just get inlined and removed by the optimizer.
147 static const internal_key_type
&
148 GetInternalKey(const external_key_type
& x
) { return x
; }
150 // This hopefully will just get inlined and removed by the optimizer.
151 static const external_key_type
&
152 GetExternalKey(const internal_key_type
& x
) { return x
; }
154 static internal_key_type
ReadKey(const unsigned char* d
, unsigned n
);
157 /// Class that performs lookup for an identifier stored in an AST file.
158 class ASTIdentifierLookupTrait
: public ASTIdentifierLookupTraitBase
{
162 // If we know the IdentifierInfo in advance, it is here and we will
163 // not build a new one. Used when deserializing information about an
164 // identifier that was constructed before the AST file was read.
165 IdentifierInfo
*KnownII
;
168 using data_type
= IdentifierInfo
*;
170 ASTIdentifierLookupTrait(ASTReader
&Reader
, ModuleFile
&F
,
171 IdentifierInfo
*II
= nullptr)
172 : Reader(Reader
), F(F
), KnownII(II
) {}
174 data_type
ReadData(const internal_key_type
& k
,
175 const unsigned char* d
,
178 IdentifierID
ReadIdentifierID(const unsigned char *d
);
180 ASTReader
&getReader() const { return Reader
; }
183 /// The on-disk hash table used to contain information about
184 /// all of the identifiers in the program.
185 using ASTIdentifierLookupTable
=
186 llvm::OnDiskIterableChainedHashTable
<ASTIdentifierLookupTrait
>;
188 /// Class that performs lookup for a selector's entries in the global
189 /// method pool stored in an AST file.
190 class ASTSelectorLookupTrait
{
197 unsigned InstanceBits
;
198 unsigned FactoryBits
;
199 bool InstanceHasMoreThanOneDecl
;
200 bool FactoryHasMoreThanOneDecl
;
201 SmallVector
<ObjCMethodDecl
*, 2> Instance
;
202 SmallVector
<ObjCMethodDecl
*, 2> Factory
;
205 using external_key_type
= Selector
;
206 using internal_key_type
= external_key_type
;
207 using hash_value_type
= unsigned;
208 using offset_type
= unsigned;
210 ASTSelectorLookupTrait(ASTReader
&Reader
, ModuleFile
&F
)
211 : Reader(Reader
), F(F
) {}
213 static bool EqualKey(const internal_key_type
& a
,
214 const internal_key_type
& b
) {
218 static hash_value_type
ComputeHash(Selector Sel
);
220 static const internal_key_type
&
221 GetInternalKey(const external_key_type
& x
) { return x
; }
223 static std::pair
<unsigned, unsigned>
224 ReadKeyDataLength(const unsigned char*& d
);
226 internal_key_type
ReadKey(const unsigned char* d
, unsigned);
227 data_type
ReadData(Selector
, const unsigned char* d
, unsigned DataLen
);
230 /// The on-disk hash table used for the global method pool.
231 using ASTSelectorLookupTable
=
232 llvm::OnDiskChainedHashTable
<ASTSelectorLookupTrait
>;
234 /// Trait class used to search the on-disk hash table containing all of
235 /// the header search information.
237 /// The on-disk hash table contains a mapping from each header path to
238 /// information about that header (how many times it has been included, its
239 /// controlling macro, etc.). Note that we actually hash based on the size
240 /// and mtime, and support "deep" comparisons of file names based on current
241 /// inode numbers, so that the search can cope with non-normalized path names
243 class HeaderFileInfoTrait
{
248 using external_key_type
= FileEntryRef
;
250 struct internal_key_type
{
257 using internal_key_ref
= const internal_key_type
&;
259 using data_type
= HeaderFileInfo
;
260 using hash_value_type
= unsigned;
261 using offset_type
= unsigned;
263 HeaderFileInfoTrait(ASTReader
&Reader
, ModuleFile
&M
)
264 : Reader(Reader
), M(M
) {}
266 static hash_value_type
ComputeHash(internal_key_ref ikey
);
267 internal_key_type
GetInternalKey(external_key_type ekey
);
268 bool EqualKey(internal_key_ref a
, internal_key_ref b
);
270 static std::pair
<unsigned, unsigned>
271 ReadKeyDataLength(const unsigned char*& d
);
273 static internal_key_type
ReadKey(const unsigned char *d
, unsigned);
275 data_type
ReadData(internal_key_ref
,const unsigned char *d
, unsigned DataLen
);
278 OptionalFileEntryRef
getFile(const internal_key_type
&Key
);
281 /// The on-disk hash table used for known header files.
282 using HeaderFileInfoLookupTable
=
283 llvm::OnDiskChainedHashTable
<HeaderFileInfoTrait
>;
285 } // namespace reader
287 } // namespace serialization
291 #endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H