blob: 265a77fdb215a807f7ac1da0bca69dd2a583cfbb [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//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Douglas Gregord44252e2011-08-25 20:47:51 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file provides internal definitions used in the AST reader.
10//
11//===----------------------------------------------------------------------===//
Eugene Zelenkob7d89102017-11-11 00:08:50 +000012
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
Mehdi Amini9670f842016-07-18 19:02:11 +000016#include "MultiOnDiskHashTable.h"
Douglas Gregord44252e2011-08-25 20:47:51 +000017#include "clang/AST/DeclarationName.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000018#include "clang/Basic/LLVM.h"
Douglas Gregorbfd73d72013-01-23 18:53:14 +000019#include "clang/Serialization/ASTBitCodes.h"
Richard Smithd88a7f12015-09-01 20:35:42 +000020#include "llvm/ADT/DenseSet.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000021#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
Justin Bognerbb094f02014-04-18 19:57:06 +000023#include "llvm/Support/OnDiskHashTable.h"
Eugene Zelenkob7d89102017-11-11 00:08:50 +000024#include <ctime>
Chandler Carruth3a022472012-12-04 09:13:33 +000025#include <utility>
Douglas Gregord44252e2011-08-25 20:47:51 +000026
27namespace clang {
28
29class ASTReader;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +000030class FileEntry;
Eugene Zelenkob7d89102017-11-11 00:08:50 +000031struct HeaderFileInfo;
32class HeaderSearch;
33class IdentifierTable;
34class ObjCMethodDecl;
Fangrui Song6907ce22018-07-30 19:24:48 +000035
Douglas Gregord44252e2011-08-25 20:47:51 +000036namespace serialization {
37
Douglas Gregorde3ef502011-11-30 23:21:26 +000038class ModuleFile;
Douglas Gregord44252e2011-08-25 20:47:51 +000039
40namespace reader {
41
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000042/// Class that performs name lookup into a DeclContext stored
Douglas Gregord44252e2011-08-25 20:47:51 +000043/// in an AST file.
44class ASTDeclContextNameLookupTrait {
45 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +000046 ModuleFile &F;
Fangrui Song6907ce22018-07-30 19:24:48 +000047
Douglas Gregord44252e2011-08-25 20:47:51 +000048public:
Richard Smithd88a7f12015-09-01 20:35:42 +000049 // 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.
Eugene Zelenkob7d89102017-11-11 00:08:50 +000053 using data_type = SmallVector<DeclID, 4>;
54
Richard Smithd88a7f12015-09-01 20:35:42 +000055 struct data_type_builder {
56 data_type &Data;
57 llvm::DenseSet<DeclID> Found;
58
59 data_type_builder(data_type &D) : Data(D) {}
Eugene Zelenkob7d89102017-11-11 00:08:50 +000060
Richard Smithd88a7f12015-09-01 20:35:42 +000061 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 };
Eugene Zelenkob7d89102017-11-11 00:08:50 +000080 using hash_value_type = unsigned;
81 using offset_type = unsigned;
82 using file_type = ModuleFile *;
Douglas Gregord44252e2011-08-25 20:47:51 +000083
Eugene Zelenkob7d89102017-11-11 00:08:50 +000084 using external_key_type = DeclarationName;
85 using internal_key_type = DeclarationNameKey;
Douglas Gregord44252e2011-08-25 20:47:51 +000086
Nick Lewycky2bd0ab22012-04-16 02:51:46 +000087 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
Eugene Zelenkob7d89102017-11-11 00:08:50 +000088 : Reader(Reader), F(F) {}
Douglas Gregord44252e2011-08-25 20:47:51 +000089
Richard Smithd88a7f12015-09-01 20:35:42 +000090 static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
Richard Smitha06c7e62015-08-26 23:55:49 +000091 return a == b;
Douglas Gregord44252e2011-08-25 20:47:51 +000092 }
93
Richard Smitha06c7e62015-08-26 23:55:49 +000094 static hash_value_type ComputeHash(const internal_key_type &Key) {
95 return Key.getHash();
96 }
Eugene Zelenkob7d89102017-11-11 00:08:50 +000097
Richard Smitha06c7e62015-08-26 23:55:49 +000098 static internal_key_type GetInternalKey(const external_key_type &Name) {
99 return Name;
100 }
Douglas Gregord44252e2011-08-25 20:47:51 +0000101
Nick Lewycky2bd0ab22012-04-16 02:51:46 +0000102 static std::pair<unsigned, unsigned>
Richard Smitha06c7e62015-08-26 23:55:49 +0000103 ReadKeyDataLength(const unsigned char *&d);
Douglas Gregord44252e2011-08-25 20:47:51 +0000104
Richard Smitha06c7e62015-08-26 23:55:49 +0000105 internal_key_type ReadKey(const unsigned char *d, unsigned);
Douglas Gregord44252e2011-08-25 20:47:51 +0000106
Richard Smithd88a7f12015-09-01 20:35:42 +0000107 void ReadDataInto(internal_key_type, const unsigned char *d,
108 unsigned DataLen, data_type_builder &Val);
109
110 static void MergeDataInto(const data_type &From, data_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<ASTDeclContextNameLookupTrait> Table;
Douglas Gregord44252e2011-08-25 20:47:51 +0000121};
122
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000123/// Base class for the trait describing the on-disk hash table for the
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000124/// 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
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000130/// must provide the \c data_type type and the ReadData operation, only.
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000131class ASTIdentifierLookupTraitBase {
132public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000133 using external_key_type = StringRef;
134 using internal_key_type = StringRef;
135 using hash_value_type = unsigned;
136 using offset_type = unsigned;
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000137
138 static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
139 return a == b;
140 }
141
Justin Bogner25463f12014-04-18 20:27:24 +0000142 static hash_value_type ComputeHash(const internal_key_type& a);
Fangrui Song6907ce22018-07-30 19:24:48 +0000143
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000144 static std::pair<unsigned, unsigned>
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_type& x) { return x; }
Fangrui Song6907ce22018-07-30 19:24:48 +0000150
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000151 // This hopefully will just get inlined and removed by the optimizer.
152 static const external_key_type&
153 GetExternalKey(const internal_key_type& x) { return x; }
154
Fangrui Song6907ce22018-07-30 19:24:48 +0000155 static internal_key_type ReadKey(const unsigned char* d, unsigned n);
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000156};
157
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000158/// Class that performs lookup for an identifier stored in an AST file.
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000159class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
Douglas Gregord44252e2011-08-25 20:47:51 +0000160 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000161 ModuleFile &F;
Fangrui Song6907ce22018-07-30 19:24:48 +0000162
Douglas Gregord44252e2011-08-25 20:47:51 +0000163 // 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;
Fangrui Song6907ce22018-07-30 19:24:48 +0000167
Douglas Gregord44252e2011-08-25 20:47:51 +0000168public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000169 using data_type = IdentifierInfo *;
Craig Toppera13603a2014-05-22 05:54:18 +0000170
Douglas Gregorde3ef502011-11-30 23:21:26 +0000171 ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
Craig Toppera13603a2014-05-22 05:54:18 +0000172 IdentifierInfo *II = nullptr)
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000173 : Reader(Reader), F(F), KnownII(II) {}
Craig Toppera13603a2014-05-22 05:54:18 +0000174
Douglas Gregorbfd73d72013-01-23 18:53:14 +0000175 data_type ReadData(const internal_key_type& k,
176 const unsigned char* d,
177 unsigned DataLen);
Fangrui Song6907ce22018-07-30 19:24:48 +0000178
Richard Smith79bf9202015-08-24 03:33:22 +0000179 IdentID ReadIdentifierID(const unsigned char *d);
180
Douglas Gregor247afcc2012-01-24 15:24:38 +0000181 ASTReader &getReader() const { return Reader; }
Douglas Gregord44252e2011-08-25 20:47:51 +0000182};
Fangrui Song6907ce22018-07-30 19:24:48 +0000183
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000184/// The on-disk hash table used to contain information about
Douglas Gregord44252e2011-08-25 20:47:51 +0000185/// all of the identifiers in the program.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000186using ASTIdentifierLookupTable =
187 llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
Douglas Gregord44252e2011-08-25 20:47:51 +0000188
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000189/// Class that performs lookup for a selector's entries in the global
Douglas Gregord44252e2011-08-25 20:47:51 +0000190/// method pool stored in an AST file.
191class ASTSelectorLookupTrait {
192 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000193 ModuleFile &F;
Fangrui Song6907ce22018-07-30 19:24:48 +0000194
Douglas Gregord44252e2011-08-25 20:47:51 +0000195public:
196 struct data_type {
197 SelectorID ID;
Argyrios Kyrtzidisd3da6e02013-04-17 00:08:58 +0000198 unsigned InstanceBits;
199 unsigned FactoryBits;
Nico Weberff4b35e2014-12-27 22:14:15 +0000200 bool InstanceHasMoreThanOneDecl;
201 bool FactoryHasMoreThanOneDecl;
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000202 SmallVector<ObjCMethodDecl *, 2> Instance;
203 SmallVector<ObjCMethodDecl *, 2> Factory;
Douglas Gregord44252e2011-08-25 20:47:51 +0000204 };
Fangrui Song6907ce22018-07-30 19:24:48 +0000205
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000206 using external_key_type = Selector;
207 using internal_key_type = external_key_type;
208 using hash_value_type = unsigned;
209 using offset_type = unsigned;
Fangrui Song6907ce22018-07-30 19:24:48 +0000210
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000211 ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
212 : Reader(Reader), F(F) {}
Fangrui Song6907ce22018-07-30 19:24:48 +0000213
Douglas Gregord44252e2011-08-25 20:47:51 +0000214 static bool EqualKey(const internal_key_type& a,
215 const internal_key_type& b) {
216 return a == b;
217 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000218
Justin Bogner25463f12014-04-18 20:27:24 +0000219 static hash_value_type ComputeHash(Selector Sel);
Fangrui Song6907ce22018-07-30 19:24:48 +0000220
Douglas Gregord44252e2011-08-25 20:47:51 +0000221 static const internal_key_type&
Chris Lattnerd2cd41c2011-09-10 16:13:42 +0000222 GetInternalKey(const external_key_type& x) { return x; }
Fangrui Song6907ce22018-07-30 19:24:48 +0000223
Douglas Gregord44252e2011-08-25 20:47:51 +0000224 static std::pair<unsigned, unsigned>
225 ReadKeyDataLength(const unsigned char*& d);
Fangrui Song6907ce22018-07-30 19:24:48 +0000226
Douglas Gregord44252e2011-08-25 20:47:51 +0000227 internal_key_type ReadKey(const unsigned char* d, unsigned);
228 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
229};
Fangrui Song6907ce22018-07-30 19:24:48 +0000230
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000231/// The on-disk hash table used for the global method pool.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000232using ASTSelectorLookupTable =
233 llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
Fangrui Song6907ce22018-07-30 19:24:48 +0000234
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000235/// Trait class used to search the on-disk hash table containing all of
Douglas Gregord44252e2011-08-25 20:47:51 +0000236/// the header search information.
237///
Fangrui Song6907ce22018-07-30 19:24:48 +0000238/// The on-disk hash table contains a mapping from each header path to
Douglas Gregord44252e2011-08-25 20:47:51 +0000239/// information about that header (how many times it has been included, its
Richard Smith7ed1bc92014-12-05 22:42:13 +0000240/// 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
Douglas Gregord44252e2011-08-25 20:47:51 +0000242/// inode numbers, so that the search can cope with non-normalized path names
243/// and symlinks.
244class HeaderFileInfoTrait {
245 ASTReader &Reader;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000246 ModuleFile &M;
Douglas Gregord44252e2011-08-25 20:47:51 +0000247 HeaderSearch *HS;
248 const char *FrameworkStrings;
Ted Kremenek03cb1372013-02-05 06:21:59 +0000249
Douglas Gregord44252e2011-08-25 20:47:51 +0000250public:
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000251 using external_key_type = const FileEntry *;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000252
253 struct internal_key_type {
254 off_t Size;
255 time_t ModTime;
Mehdi Amini004b9c72016-10-10 22:52:47 +0000256 StringRef Filename;
Richard Smith7ed1bc92014-12-05 22:42:13 +0000257 bool Imported;
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000258 };
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000259
260 using internal_key_ref = const internal_key_type &;
Fangrui Song6907ce22018-07-30 19:24:48 +0000261
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000262 using data_type = HeaderFileInfo;
263 using hash_value_type = unsigned;
264 using offset_type = unsigned;
Fangrui Song6907ce22018-07-30 19:24:48 +0000265
Douglas Gregorde3ef502011-11-30 23:21:26 +0000266 HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
Argyrios Kyrtzidisb42863e2013-03-06 18:12:41 +0000267 const char *FrameworkStrings)
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000268 : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
Fangrui Song6907ce22018-07-30 19:24:48 +0000269
Justin Bogner25463f12014-04-18 20:27:24 +0000270 static hash_value_type ComputeHash(internal_key_ref ikey);
Richard Smithe75ee0f2015-08-17 07:13:32 +0000271 internal_key_type GetInternalKey(const FileEntry *FE);
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000272 bool EqualKey(internal_key_ref a, internal_key_ref b);
Fangrui Song6907ce22018-07-30 19:24:48 +0000273
Douglas Gregord44252e2011-08-25 20:47:51 +0000274 static std::pair<unsigned, unsigned>
275 ReadKeyDataLength(const unsigned char*& d);
Fangrui Song6907ce22018-07-30 19:24:48 +0000276
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000277 static internal_key_type ReadKey(const unsigned char *d, unsigned);
Fangrui Song6907ce22018-07-30 19:24:48 +0000278
Argyrios Kyrtzidis5c2a3452013-03-06 18:12:47 +0000279 data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
Douglas Gregord44252e2011-08-25 20:47:51 +0000280};
281
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000282/// The on-disk hash table used for known header files.
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000283using HeaderFileInfoLookupTable =
284 llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
Fangrui Song6907ce22018-07-30 19:24:48 +0000285
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000286} // namespace reader
Douglas Gregord44252e2011-08-25 20:47:51 +0000287
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000288} // namespace serialization
Douglas Gregord44252e2011-08-25 20:47:51 +0000289
Eugene Zelenkob7d89102017-11-11 00:08:50 +0000290} // namespace clang
291
292#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H