blob: d392364a971bb29f0fff4972919c3dc0f7f8d3af [file] [log] [blame]
Douglas Gregord44252e2011-08-25 20:47:51 +00001//===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides internal definitions used in the AST reader.
11//
12//===----------------------------------------------------------------------===//
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000013#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
14#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
Douglas Gregord44252e2011-08-25 20:47:51 +000015
Douglas Gregord44252e2011-08-25 20:47:51 +000016#include "clang/AST/DeclarationName.h"
Douglas Gregorbfd73d72013-01-23 18:53:14 +000017#include "clang/Serialization/ASTBitCodes.h"
Richard Smithd88a7f12015-09-01 20:35:42 +000018#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/PointerUnion.h"
20#include "llvm/ADT/TinyPtrVector.h"
Douglas Gregorde95ead2012-01-06 16:09:53 +000021#include "llvm/Support/Endian.h"
Justin Bognerbb094f02014-04-18 19:57:06 +000022#include "llvm/Support/OnDiskHashTable.h"
Richard Smithd88a7f12015-09-01 20:35:42 +000023#include "MultiOnDiskHashTable.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000024#include <utility>
Douglas Gregord44252e2011-08-25 20:47:51 +000025
26namespace clang {
27
28class ASTReader;
29class HeaderSearch;
30struct HeaderFileInfo;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +000031class FileEntry;
Douglas Gregord44252e2011-08-25 20:47:51 +000032
33namespace serialization {
34
Douglas Gregorde3ef502011-11-30 23:21:26 +000035class ModuleFile;
Douglas Gregord44252e2011-08-25 20:47:51 +000036
37namespace reader {
38
39/// \brief Class that performs name lookup into a DeclContext stored
40/// in an AST file.
41class ASTDeclContextNameLookupTrait {
42 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +000043 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +000044
45public:
Richard Smithd88a7f12015-09-01 20:35:42 +000046 // Maximum number of lookup tables we allow before condensing the tables.
47 static const int MaxTables = 4;
48
49 /// The lookup result is a list of global declaration IDs.
50 typedef llvm::SmallVector<DeclID, 4> data_type;
51 struct data_type_builder {
52 data_type &Data;
53 llvm::DenseSet<DeclID> Found;
54
55 data_type_builder(data_type &D) : Data(D) {}
56 void insert(DeclID ID) {
57 // Just use a linear scan unless we have more than a few IDs.
58 if (Found.empty() && !Data.empty()) {
59 if (Data.size() <= 4) {
60 for (auto I : Found)
61 if (I == ID)
62 return;
63 Data.push_back(ID);
64 return;
65 }
66
67 // Switch to tracking found IDs in the set.
68 Found.insert(Data.begin(), Data.end());
69 }
70
71 if (Found.insert(ID).second)
72 Data.push_back(ID);
73 }
74 };
Justin Bogner25463f12014-04-18 20:27:24 +000075 typedef unsigned hash_value_type;
76 typedef unsigned offset_type;
Richard Smithd88a7f12015-09-01 20:35:42 +000077 typedef ModuleFile *file_type;
Douglas Gregord44252e2011-08-25 20:47:51 +000078
Douglas Gregord44252e2011-08-25 20:47:51 +000079 typedef DeclarationName external_key_type;
Richard Smitha06c7e62015-08-26 23:55:49 +000080 typedef DeclarationNameKey internal_key_type;
Douglas Gregord44252e2011-08-25 20:47:51 +000081
Nick Lewycky2bd0ab22012-04-16 02:51:46 +000082 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
Douglas Gregord44252e2011-08-25 20:47:51 +000083 : Reader(Reader), F(F) { }
84
Richard Smithd88a7f12015-09-01 20:35:42 +000085 static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
Richard Smitha06c7e62015-08-26 23:55:49 +000086 return a == b;
Douglas Gregord44252e2011-08-25 20:47:51 +000087 }
88
Richard Smitha06c7e62015-08-26 23:55:49 +000089 static hash_value_type ComputeHash(const internal_key_type &Key) {
90 return Key.getHash();
91 }
92 static internal_key_type GetInternalKey(const external_key_type &Name) {
93 return Name;
94 }
Douglas Gregord44252e2011-08-25 20:47:51 +000095
Nick Lewycky2bd0ab22012-04-16 02:51:46 +000096 static std::pair<unsigned, unsigned>
Richard Smitha06c7e62015-08-26 23:55:49 +000097 ReadKeyDataLength(const unsigned char *&d);
Douglas Gregord44252e2011-08-25 20:47:51 +000098
Richard Smitha06c7e62015-08-26 23:55:49 +000099 internal_key_type ReadKey(const unsigned char *d, unsigned);
Douglas Gregord44252e2011-08-25 20:47:51 +0000100
Richard Smithd88a7f12015-09-01 20:35:42 +0000101 void ReadDataInto(internal_key_type, const unsigned char *d,
102 unsigned DataLen, data_type_builder &Val);
103
104 static void MergeDataInto(const data_type &From, data_type_builder &To) {
105 To.Data.reserve(To.Data.size() + From.size());
106 for (DeclID ID : From)
107 To.insert(ID);
108 }
109
110 file_type ReadFileRef(const unsigned char *&d);
111};
112
113struct DeclContextLookupTable {
114 MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
115
116 // These look redundant, but don't remove them -- they work around MSVC 2013's
117 // inability to synthesize move operations. Without them, the
118 // MultiOnDiskHashTable will be copied (despite being move-only!).
119 DeclContextLookupTable() : Table() {}
120 DeclContextLookupTable(DeclContextLookupTable &&O)
121 : Table(std::move(O.Table)) {}
122 DeclContextLookupTable &operator=(DeclContextLookupTable &&O) {
123 Table = std::move(O.Table);
124 return *this;
125 }
Douglas Gregord44252e2011-08-25 20:47:51 +0000126};
127
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000128/// \brief Base class for the trait describing the on-disk hash table for the
129/// identifiers in an AST file.
130///
131/// This class is not useful by itself; rather, it provides common
132/// functionality for accessing the on-disk hash table of identifiers
133/// in an AST file. Different subclasses customize that functionality
134/// based on what information they are interested in. Those subclasses
135/// must provide the \c data_type typedef and the ReadData operation,
136/// only.
137class ASTIdentifierLookupTraitBase {
138public:
139 typedef StringRef external_key_type;
140 typedef StringRef internal_key_type;
Justin Bogner25463f12014-04-18 20:27:24 +0000141 typedef unsigned hash_value_type;
142 typedef unsigned offset_type;
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000143
144 static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
145 return a == b;
146 }
147
Justin Bogner25463f12014-04-18 20:27:24 +0000148 static hash_value_type ComputeHash(const internal_key_type& a);
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000149
150 static std::pair<unsigned, unsigned>
151 ReadKeyDataLength(const unsigned char*& d);
152
153 // This hopefully will just get inlined and removed by the optimizer.
154 static const internal_key_type&
155 GetInternalKey(const external_key_type& x) { return x; }
156
157 // This hopefully will just get inlined and removed by the optimizer.
158 static const external_key_type&
159 GetExternalKey(const internal_key_type& x) { return x; }
160
161 static internal_key_type ReadKey(const unsigned char* d, unsigned n);
162};
163
Douglas Gregord44252e2011-08-25 20:47:51 +0000164/// \brief Class that performs lookup for an identifier stored in an AST file.
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000165class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
Douglas Gregord44252e2011-08-25 20:47:51 +0000166 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000167 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +0000168
169 // If we know the IdentifierInfo in advance, it is here and we will
170 // not build a new one. Used when deserializing information about an
171 // identifier that was constructed before the AST file was read.
172 IdentifierInfo *KnownII;
173
174public:
175 typedef IdentifierInfo * data_type;
Craig Toppera13603a2014-05-22 05:54:18 +0000176
Douglas Gregorde3ef502011-11-30 23:21:26 +0000177 ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
Craig Toppera13603a2014-05-22 05:54:18 +0000178 IdentifierInfo *II = nullptr)
Douglas Gregord44252e2011-08-25 20:47:51 +0000179 : Reader(Reader), F(F), KnownII(II) { }
Craig Toppera13603a2014-05-22 05:54:18 +0000180
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000181 data_type ReadData(const internal_key_type& k,
182 const unsigned char* d,
183 unsigned DataLen);
Douglas Gregor247afcc2012-01-24 15:24:38 +0000184
Richard Smith79bf9202015-08-24 03:33:22 +0000185 IdentID ReadIdentifierID(const unsigned char *d);
186
Douglas Gregor247afcc2012-01-24 15:24:38 +0000187 ASTReader &getReader() const { return Reader; }
Douglas Gregord44252e2011-08-25 20:47:51 +0000188};
189
190/// \brief The on-disk hash table used to contain information about
191/// all of the identifiers in the program.
Justin Bognerbb094f02014-04-18 19:57:06 +0000192typedef llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>
Douglas Gregord44252e2011-08-25 20:47:51 +0000193 ASTIdentifierLookupTable;
194
195/// \brief Class that performs lookup for a selector's entries in the global
196/// method pool stored in an AST file.
197class ASTSelectorLookupTrait {
198 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000199 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +0000200
201public:
202 struct data_type {
203 SelectorID ID;
Argyrios Kyrtzidisd3da6e02013-04-17 00:08:58 +0000204 unsigned InstanceBits;
205 unsigned FactoryBits;
Nico Weberff4b35e2014-12-27 22:14:15 +0000206 bool InstanceHasMoreThanOneDecl;
207 bool FactoryHasMoreThanOneDecl;
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000208 SmallVector<ObjCMethodDecl *, 2> Instance;
209 SmallVector<ObjCMethodDecl *, 2> Factory;
Douglas Gregord44252e2011-08-25 20:47:51 +0000210 };
211
212 typedef Selector external_key_type;
213 typedef external_key_type internal_key_type;
Justin Bogner25463f12014-04-18 20:27:24 +0000214 typedef unsigned hash_value_type;
215 typedef unsigned offset_type;
Douglas Gregord44252e2011-08-25 20:47:51 +0000216
Douglas Gregorde3ef502011-11-30 23:21:26 +0000217 ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
Douglas Gregord44252e2011-08-25 20:47:51 +0000218 : Reader(Reader), F(F) { }
219
220 static bool EqualKey(const internal_key_type& a,
221 const internal_key_type& b) {
222 return a == b;
223 }
224
Justin Bogner25463f12014-04-18 20:27:24 +0000225 static hash_value_type ComputeHash(Selector Sel);
Douglas Gregord44252e2011-08-25 20:47:51 +0000226
227 static const internal_key_type&
Chris Lattnerd2cd41c2011-09-10 16:13:42 +0000228 GetInternalKey(const external_key_type& x) { return x; }
Douglas Gregord44252e2011-08-25 20:47:51 +0000229
230 static std::pair<unsigned, unsigned>
231 ReadKeyDataLength(const unsigned char*& d);
232
233 internal_key_type ReadKey(const unsigned char* d, unsigned);
234 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
235};
236
237/// \brief The on-disk hash table used for the global method pool.
Justin Bognerbb094f02014-04-18 19:57:06 +0000238typedef llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>
Douglas Gregord44252e2011-08-25 20:47:51 +0000239 ASTSelectorLookupTable;
240
241/// \brief Trait class used to search the on-disk hash table containing all of
242/// the header search information.
243///
244/// The on-disk hash table contains a mapping from each header path to
245/// information about that header (how many times it has been included, its
Richard Smith7ed1bc92014-12-05 22:42:13 +0000246/// controlling macro, etc.). Note that we actually hash based on the size
247/// and mtime, and support "deep" comparisons of file names based on current
Douglas Gregord44252e2011-08-25 20:47:51 +0000248/// inode numbers, so that the search can cope with non-normalized path names
249/// and symlinks.
250class HeaderFileInfoTrait {
251 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000252 ModuleFile &M;
Douglas Gregord44252e2011-08-25 20:47:51 +0000253 HeaderSearch *HS;
254 const char *FrameworkStrings;
Ted Kremenek03cb1372013-02-05 06:21:59 +0000255
Douglas Gregord44252e2011-08-25 20:47:51 +0000256public:
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000257 typedef const FileEntry *external_key_type;
258
259 struct internal_key_type {
260 off_t Size;
261 time_t ModTime;
262 const char *Filename;
Richard Smith7ed1bc92014-12-05 22:42:13 +0000263 bool Imported;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000264 };
265 typedef const internal_key_type &internal_key_ref;
Douglas Gregord44252e2011-08-25 20:47:51 +0000266
267 typedef HeaderFileInfo data_type;
Justin Bogner25463f12014-04-18 20:27:24 +0000268 typedef unsigned hash_value_type;
269 typedef unsigned offset_type;
Douglas Gregord44252e2011-08-25 20:47:51 +0000270
Douglas Gregorde3ef502011-11-30 23:21:26 +0000271 HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
Argyrios Kyrtzidisb42863e2013-03-06 18:12:41 +0000272 const char *FrameworkStrings)
273 : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { }
Douglas Gregord44252e2011-08-25 20:47:51 +0000274
Justin Bogner25463f12014-04-18 20:27:24 +0000275 static hash_value_type ComputeHash(internal_key_ref ikey);
Richard Smithe75ee0f2015-08-17 07:13:32 +0000276 internal_key_type GetInternalKey(const FileEntry *FE);
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000277 bool EqualKey(internal_key_ref a, internal_key_ref b);
Douglas Gregord44252e2011-08-25 20:47:51 +0000278
279 static std::pair<unsigned, unsigned>
280 ReadKeyDataLength(const unsigned char*& d);
281
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000282 static internal_key_type ReadKey(const unsigned char *d, unsigned);
Douglas Gregord44252e2011-08-25 20:47:51 +0000283
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000284 data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
Douglas Gregord44252e2011-08-25 20:47:51 +0000285};
286
287/// \brief The on-disk hash table used for known header files.
Justin Bognerbb094f02014-04-18 19:57:06 +0000288typedef llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>
Douglas Gregord44252e2011-08-25 20:47:51 +0000289 HeaderFileInfoLookupTable;
290
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000291} // end namespace clang::serialization::reader
292} // end namespace clang::serialization
Douglas Gregord44252e2011-08-25 20:47:51 +0000293} // end namespace clang
294
295
296#endif