blob: 2b92ae65ea84c9b18d72342a625d2bd291e6c90b [file] [log] [blame]
Eugene Zelenkob7d89102017-11-11 00:08:50 +00001//===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
Douglas Gregord44252e2011-08-25 20:47:51 +00002//
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//===----------------------------------------------------------------------===//
Eugene Zelenkob7d89102017-11-11 00:08:50 +000013
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000014#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
15#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
Douglas Gregord44252e2011-08-25 20:47:51 +000016
Mehdi Amini9670f842016-07-18 19:02:11 +000017#include "MultiOnDiskHashTable.h"
Douglas Gregord44252e2011-08-25 20:47:51 +000018#include "clang/AST/DeclarationName.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000019#include "clang/Basic/LLVM.h"
Douglas Gregorbfd73d72013-01-23 18:53:14 +000020#include "clang/Serialization/ASTBitCodes.h"
Richard Smithd88a7f12015-09-01 20:35:42 +000021#include "llvm/ADT/DenseSet.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000022#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
Justin Bognerbb094f02014-04-18 19:57:06 +000024#include "llvm/Support/OnDiskHashTable.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000025#include <ctime>
Chandler Carruth3a022472012-12-04 09:13:33 +000026#include <utility>
Douglas Gregord44252e2011-08-25 20:47:51 +000027
28namespace clang {
29
30class ASTReader;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +000031class FileEntry;
Eugene Zelenkob7d89102017-11-11 00:08:50 +000032struct HeaderFileInfo;
33class HeaderSearch;
34class IdentifierTable;
35class ObjCMethodDecl;
Douglas Gregord44252e2011-08-25 20:47:51 +000036
37namespace serialization {
38
Douglas Gregorde3ef502011-11-30 23:21:26 +000039class ModuleFile;
Douglas Gregord44252e2011-08-25 20:47:51 +000040
41namespace reader {
42
43/// \brief Class that performs name lookup into a DeclContext stored
44/// in an AST file.
45class ASTDeclContextNameLookupTrait {
46 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +000047 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +000048
49public:
Richard Smithd88a7f12015-09-01 20:35:42 +000050 // Maximum number of lookup tables we allow before condensing the tables.
51 static const int MaxTables = 4;
52
53 /// The lookup result is a list of global declaration IDs.
Eugene Zelenkob7d89102017-11-11 00:08:50 +000054 using data_type = SmallVector<DeclID, 4>;
55
Richard Smithd88a7f12015-09-01 20:35:42 +000056 struct data_type_builder {
57 data_type &Data;
58 llvm::DenseSet<DeclID> Found;
59
60 data_type_builder(data_type &D) : Data(D) {}
Eugene Zelenkob7d89102017-11-11 00:08:50 +000061
Richard Smithd88a7f12015-09-01 20:35:42 +000062 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) {
66 for (auto I : Found)
67 if (I == ID)
68 return;
69 Data.push_back(ID);
70 return;
71 }
72
73 // Switch to tracking found IDs in the set.
74 Found.insert(Data.begin(), Data.end());
75 }
76
77 if (Found.insert(ID).second)
78 Data.push_back(ID);
79 }
80 };
Eugene Zelenkob7d89102017-11-11 00:08:50 +000081 using hash_value_type = unsigned;
82 using offset_type = unsigned;
83 using file_type = ModuleFile *;
Douglas Gregord44252e2011-08-25 20:47:51 +000084
Eugene Zelenkob7d89102017-11-11 00:08:50 +000085 using external_key_type = DeclarationName;
86 using internal_key_type = DeclarationNameKey;
Douglas Gregord44252e2011-08-25 20:47:51 +000087
Nick Lewycky2bd0ab22012-04-16 02:51:46 +000088 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
Eugene Zelenkob7d89102017-11-11 00:08:50 +000089 : Reader(Reader), F(F) {}
Douglas Gregord44252e2011-08-25 20:47:51 +000090
Richard Smithd88a7f12015-09-01 20:35:42 +000091 static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
Richard Smitha06c7e62015-08-26 23:55:49 +000092 return a == b;
Douglas Gregord44252e2011-08-25 20:47:51 +000093 }
94
Richard Smitha06c7e62015-08-26 23:55:49 +000095 static hash_value_type ComputeHash(const internal_key_type &Key) {
96 return Key.getHash();
97 }
Eugene Zelenkob7d89102017-11-11 00:08:50 +000098
Richard Smitha06c7e62015-08-26 23:55:49 +000099 static internal_key_type GetInternalKey(const external_key_type &Name) {
100 return Name;
101 }
Douglas Gregord44252e2011-08-25 20:47:51 +0000102
Nick Lewycky2bd0ab22012-04-16 02:51:46 +0000103 static std::pair<unsigned, unsigned>
Richard Smitha06c7e62015-08-26 23:55:49 +0000104 ReadKeyDataLength(const unsigned char *&d);
Douglas Gregord44252e2011-08-25 20:47:51 +0000105
Richard Smitha06c7e62015-08-26 23:55:49 +0000106 internal_key_type ReadKey(const unsigned char *d, unsigned);
Douglas Gregord44252e2011-08-25 20:47:51 +0000107
Richard Smithd88a7f12015-09-01 20:35:42 +0000108 void ReadDataInto(internal_key_type, const unsigned char *d,
109 unsigned DataLen, data_type_builder &Val);
110
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)
114 To.insert(ID);
115 }
116
117 file_type ReadFileRef(const unsigned char *&d);
118};
119
120struct DeclContextLookupTable {
121 MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
Douglas Gregord44252e2011-08-25 20:47:51 +0000122};
123
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000124/// \brief Base class for the trait describing the on-disk hash table for the
125/// identifiers in an AST file.
126///
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
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000131/// must provide the \c data_type type and the ReadData operation, only.
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000132class ASTIdentifierLookupTraitBase {
133public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000134 using external_key_type = StringRef;
135 using internal_key_type = StringRef;
136 using hash_value_type = unsigned;
137 using offset_type = unsigned;
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000138
139 static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
140 return a == b;
141 }
142
Justin Bogner25463f12014-04-18 20:27:24 +0000143 static hash_value_type ComputeHash(const internal_key_type& a);
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000144
145 static std::pair<unsigned, unsigned>
146 ReadKeyDataLength(const unsigned char*& d);
147
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; }
151
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; }
155
156 static internal_key_type ReadKey(const unsigned char* d, unsigned n);
157};
158
Douglas Gregord44252e2011-08-25 20:47:51 +0000159/// \brief Class that performs lookup for an identifier stored in an AST file.
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000160class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
Douglas Gregord44252e2011-08-25 20:47:51 +0000161 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000162 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +0000163
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;
168
169public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000170 using data_type = IdentifierInfo *;
Craig Toppera13603a2014-05-22 05:54:18 +0000171
Douglas Gregorde3ef502011-11-30 23:21:26 +0000172 ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
Craig Toppera13603a2014-05-22 05:54:18 +0000173 IdentifierInfo *II = nullptr)
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000174 : Reader(Reader), F(F), KnownII(II) {}
Craig Toppera13603a2014-05-22 05:54:18 +0000175
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000176 data_type ReadData(const internal_key_type& k,
177 const unsigned char* d,
178 unsigned DataLen);
Douglas Gregor247afcc2012-01-24 15:24:38 +0000179
Richard Smith79bf9202015-08-24 03:33:22 +0000180 IdentID ReadIdentifierID(const unsigned char *d);
181
Douglas Gregor247afcc2012-01-24 15:24:38 +0000182 ASTReader &getReader() const { return Reader; }
Douglas Gregord44252e2011-08-25 20:47:51 +0000183};
184
185/// \brief The on-disk hash table used to contain information about
186/// all of the identifiers in the program.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000187using ASTIdentifierLookupTable =
188 llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
Douglas Gregord44252e2011-08-25 20:47:51 +0000189
190/// \brief Class that performs lookup for a selector's entries in the global
191/// method pool stored in an AST file.
192class ASTSelectorLookupTrait {
193 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000194 ModuleFile &F;
Douglas Gregord44252e2011-08-25 20:47:51 +0000195
196public:
197 struct data_type {
198 SelectorID ID;
Argyrios Kyrtzidisd3da6e02013-04-17 00:08:58 +0000199 unsigned InstanceBits;
200 unsigned FactoryBits;
Nico Weberff4b35e2014-12-27 22:14:15 +0000201 bool InstanceHasMoreThanOneDecl;
202 bool FactoryHasMoreThanOneDecl;
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000203 SmallVector<ObjCMethodDecl *, 2> Instance;
204 SmallVector<ObjCMethodDecl *, 2> Factory;
Douglas Gregord44252e2011-08-25 20:47:51 +0000205 };
206
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000207 using external_key_type = Selector;
208 using internal_key_type = external_key_type;
209 using hash_value_type = unsigned;
210 using offset_type = unsigned;
Douglas Gregord44252e2011-08-25 20:47:51 +0000211
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000212 ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
213 : Reader(Reader), F(F) {}
Douglas Gregord44252e2011-08-25 20:47:51 +0000214
215 static bool EqualKey(const internal_key_type& a,
216 const internal_key_type& b) {
217 return a == b;
218 }
219
Justin Bogner25463f12014-04-18 20:27:24 +0000220 static hash_value_type ComputeHash(Selector Sel);
Douglas Gregord44252e2011-08-25 20:47:51 +0000221
222 static const internal_key_type&
Chris Lattnerd2cd41c2011-09-10 16:13:42 +0000223 GetInternalKey(const external_key_type& x) { return x; }
Douglas Gregord44252e2011-08-25 20:47:51 +0000224
225 static std::pair<unsigned, unsigned>
226 ReadKeyDataLength(const unsigned char*& d);
227
228 internal_key_type ReadKey(const unsigned char* d, unsigned);
229 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
230};
231
232/// \brief The on-disk hash table used for the global method pool.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000233using ASTSelectorLookupTable =
234 llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
Douglas Gregord44252e2011-08-25 20:47:51 +0000235
236/// \brief Trait class used to search the on-disk hash table containing all of
237/// the header search information.
238///
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
Richard Smith7ed1bc92014-12-05 22:42:13 +0000241/// 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
Douglas Gregord44252e2011-08-25 20:47:51 +0000243/// inode numbers, so that the search can cope with non-normalized path names
244/// and symlinks.
245class HeaderFileInfoTrait {
246 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000247 ModuleFile &M;
Douglas Gregord44252e2011-08-25 20:47:51 +0000248 HeaderSearch *HS;
249 const char *FrameworkStrings;
Ted Kremenek03cb1372013-02-05 06:21:59 +0000250
Douglas Gregord44252e2011-08-25 20:47:51 +0000251public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000252 using external_key_type = const FileEntry *;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000253
254 struct internal_key_type {
255 off_t Size;
256 time_t ModTime;
Mehdi Amini004b9c72016-10-10 22:52:47 +0000257 StringRef Filename;
Richard Smith7ed1bc92014-12-05 22:42:13 +0000258 bool Imported;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000259 };
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000260
261 using internal_key_ref = const internal_key_type &;
Douglas Gregord44252e2011-08-25 20:47:51 +0000262
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000263 using data_type = HeaderFileInfo;
264 using hash_value_type = unsigned;
265 using offset_type = unsigned;
Douglas Gregord44252e2011-08-25 20:47:51 +0000266
Douglas Gregorde3ef502011-11-30 23:21:26 +0000267 HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
Argyrios Kyrtzidisb42863e2013-03-06 18:12:41 +0000268 const char *FrameworkStrings)
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000269 : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
Douglas Gregord44252e2011-08-25 20:47:51 +0000270
Justin Bogner25463f12014-04-18 20:27:24 +0000271 static hash_value_type ComputeHash(internal_key_ref ikey);
Richard Smithe75ee0f2015-08-17 07:13:32 +0000272 internal_key_type GetInternalKey(const FileEntry *FE);
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000273 bool EqualKey(internal_key_ref a, internal_key_ref b);
Douglas Gregord44252e2011-08-25 20:47:51 +0000274
275 static std::pair<unsigned, unsigned>
276 ReadKeyDataLength(const unsigned char*& d);
277
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000278 static internal_key_type ReadKey(const unsigned char *d, unsigned);
Douglas Gregord44252e2011-08-25 20:47:51 +0000279
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000280 data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
Douglas Gregord44252e2011-08-25 20:47:51 +0000281};
282
283/// \brief The on-disk hash table used for known header files.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000284using HeaderFileInfoLookupTable =
285 llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
Douglas Gregord44252e2011-08-25 20:47:51 +0000286
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000287} // namespace reader
Douglas Gregord44252e2011-08-25 20:47:51 +0000288
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000289} // namespace serialization
Douglas Gregord44252e2011-08-25 20:47:51 +0000290
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000291} // namespace clang
292
293#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H