blob: 80bc9189520aaee38e24bffa3c66f13375129800 [file] [log] [blame]
Sebastian Redl3b3c8742010-08-18 23:57:11 +00001//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//
Douglas Gregoref84c4b2009-04-09 22:27:44 +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//
Sebastian Redl2c499f62010-08-18 23:56:43 +000010// This file defines the ASTReader class, which reads AST files.
Douglas Gregoref84c4b2009-04-09 22:27:44 +000011//
12//===----------------------------------------------------------------------===//
Chris Lattner92ba5ff2009-04-27 05:14:47 +000013
Sebastian Redlf5b13462010-08-18 23:57:17 +000014#include "clang/Serialization/ASTReader.h"
15#include "clang/Serialization/ASTDeserializationListener.h"
Argyrios Kyrtzidis4bd97102010-08-20 16:03:52 +000016#include "ASTCommon.h"
Douglas Gregor55abb232009-04-10 20:39:37 +000017#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbar732ef8a2009-11-11 23:58:53 +000018#include "clang/Frontend/Utils.h"
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000019#include "clang/Sema/Sema.h"
Douglas Gregor1a0d0b92009-04-14 00:24:19 +000020#include "clang/AST/ASTConsumer.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000021#include "clang/AST/ASTContext.h"
Douglas Gregorfeb84b02009-04-14 21:18:50 +000022#include "clang/AST/Expr.h"
John McCallbfd822c2010-08-24 07:32:53 +000023#include "clang/AST/ExprCXX.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000024#include "clang/AST/Type.h"
John McCall8f115c62009-10-16 21:56:05 +000025#include "clang/AST/TypeLocVisitor.h"
Chris Lattner34321bc2009-04-10 21:41:48 +000026#include "clang/Lex/MacroInfo.h"
Douglas Gregoraae92242010-03-19 21:51:54 +000027#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000028#include "clang/Lex/Preprocessor.h"
Steve Naroff3fa455a2009-04-24 20:03:17 +000029#include "clang/Lex/HeaderSearch.h"
Douglas Gregora868bbd2009-04-21 22:25:48 +000030#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000031#include "clang/Basic/SourceManager.h"
Douglas Gregor4c7626e2009-04-13 16:31:14 +000032#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000033#include "clang/Basic/FileManager.h"
Douglas Gregorbfbde532009-04-10 21:16:55 +000034#include "clang/Basic/TargetInfo.h"
Douglas Gregord54f3a12009-10-05 21:07:28 +000035#include "clang/Basic/Version.h"
Daniel Dunbarf8502d52009-10-17 23:52:28 +000036#include "llvm/ADT/StringExtras.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000037#include "llvm/Bitcode/BitstreamReader.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000038#include "llvm/Support/MemoryBuffer.h"
John McCall0ad16662009-10-29 08:12:44 +000039#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +000040#include "llvm/System/Path.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000041#include <algorithm>
Douglas Gregorc379c072009-04-28 18:58:38 +000042#include <iterator>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000043#include <cstdio>
Douglas Gregorc5046832009-04-27 18:38:38 +000044#include <sys/stat.h>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000045using namespace clang;
Sebastian Redl539c5062010-08-18 23:57:32 +000046using namespace clang::serialization;
Douglas Gregoref84c4b2009-04-09 22:27:44 +000047
48//===----------------------------------------------------------------------===//
Sebastian Redld44cd6a2010-08-18 23:57:06 +000049// PCH validator implementation
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000050//===----------------------------------------------------------------------===//
51
Sebastian Redl3e31c722010-08-18 23:56:56 +000052ASTReaderListener::~ASTReaderListener() {}
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000053
54bool
55PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
56 const LangOptions &PPLangOpts = PP.getLangOptions();
57#define PARSE_LANGOPT_BENIGN(Option)
58#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
59 if (PPLangOpts.Option != LangOpts.Option) { \
60 Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
61 return true; \
62 }
63
64 PARSE_LANGOPT_BENIGN(Trigraphs);
65 PARSE_LANGOPT_BENIGN(BCPLComment);
66 PARSE_LANGOPT_BENIGN(DollarIdents);
67 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
68 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
Chandler Carruthe03aa552010-04-17 20:17:31 +000069 PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000070 PARSE_LANGOPT_BENIGN(ImplicitInt);
71 PARSE_LANGOPT_BENIGN(Digraphs);
72 PARSE_LANGOPT_BENIGN(HexFloats);
73 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
74 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
75 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
76 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
77 PARSE_LANGOPT_BENIGN(CXXOperatorName);
78 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
79 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
80 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
Fariborz Jahanian45878032010-02-09 19:31:38 +000081 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +000082 PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
83 diag::warn_pch_no_constant_cfstrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000084 PARSE_LANGOPT_BENIGN(PascalStrings);
85 PARSE_LANGOPT_BENIGN(WritableStrings);
Mike Stump11289f42009-09-09 15:08:12 +000086 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000087 diag::warn_pch_lax_vector_conversions);
Nate Begeman9d905792009-06-25 22:57:40 +000088 PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000089 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +000090 PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000091 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
92 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
93 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
Mike Stump11289f42009-09-09 15:08:12 +000094 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000095 diag::warn_pch_thread_safe_statics);
Daniel Dunbara77eaeb2009-09-03 04:54:28 +000096 PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000097 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
98 PARSE_LANGOPT_BENIGN(EmitAllDecls);
99 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
Chris Lattner51924e512010-06-26 21:25:03 +0000100 PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
Mike Stump11289f42009-09-09 15:08:12 +0000101 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000102 diag::warn_pch_heinous_extensions);
103 // FIXME: Most of the options below are benign if the macro wasn't
104 // used. Unfortunately, this means that a PCH compiled without
105 // optimization can't be used with optimization turned on, even
106 // though the only thing that changes is whether __OPTIMIZE__ was
107 // defined... but if __OPTIMIZE__ never showed up in the header, it
108 // doesn't matter. We could consider making this some special kind
109 // of check.
110 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
111 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
112 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
113 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
114 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
115 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
116 PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
117 PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
John Thompsoned4e2952009-11-05 20:14:16 +0000118 PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000119 if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
Mike Stump11289f42009-09-09 15:08:12 +0000120 Reader.Diag(diag::warn_pch_gc_mode)
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000121 << LangOpts.getGCMode() << PPLangOpts.getGCMode();
122 return true;
123 }
124 PARSE_LANGOPT_BENIGN(getVisibilityMode());
Daniel Dunbar143021e2009-09-21 04:16:19 +0000125 PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
126 diag::warn_pch_stack_protector);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000127 PARSE_LANGOPT_BENIGN(InstantiationDepth);
Nate Begeman9d905792009-06-25 22:57:40 +0000128 PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
Mike Stumpd9546382009-12-12 01:27:46 +0000129 PARSE_LANGOPT_BENIGN(CatchUndefined);
Daniel Dunbar143021e2009-09-21 04:16:19 +0000130 PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
Douglas Gregor8ed0c0b2010-07-09 17:35:33 +0000131 PARSE_LANGOPT_BENIGN(SpellChecking);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +0000132#undef PARSE_LANGOPT_IMPORTANT
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000133#undef PARSE_LANGOPT_BENIGN
134
135 return false;
136}
137
Daniel Dunbar20a682d2009-11-11 00:52:11 +0000138bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
139 if (Triple == PP.getTargetInfo().getTriple().str())
140 return false;
141
142 Reader.Diag(diag::warn_pch_target_triple)
143 << Triple << PP.getTargetInfo().getTriple().str();
144 return true;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000145}
146
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000147struct EmptyStringRef {
Benjamin Kramer8d5609b2010-07-14 23:19:41 +0000148 bool operator ()(llvm::StringRef r) const { return r.empty(); }
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000149};
150struct EmptyBlock {
151 bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); }
152};
153
154static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
155 PCHPredefinesBlocks R) {
156 // First, sum up the lengths.
157 unsigned LL = 0, RL = 0;
158 for (unsigned I = 0, N = L.size(); I != N; ++I) {
159 LL += L[I].size();
160 }
161 for (unsigned I = 0, N = R.size(); I != N; ++I) {
162 RL += R[I].Data.size();
163 }
164 if (LL != RL)
165 return false;
166 if (LL == 0 && RL == 0)
167 return true;
168
169 // Kick out empty parts, they confuse the algorithm below.
170 L.erase(std::remove_if(L.begin(), L.end(), EmptyStringRef()), L.end());
171 R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
172
173 // Do it the hard way. At this point, both vectors must be non-empty.
174 llvm::StringRef LR = L[0], RR = R[0].Data;
175 unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
Daniel Dunbar01ad0a72010-07-16 00:00:11 +0000176 (void) RN;
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000177 for (;;) {
178 // Compare the current pieces.
179 if (LR.size() == RR.size()) {
180 // If they're the same length, it's pretty easy.
181 if (LR != RR)
182 return false;
183 // Both pieces are done, advance.
184 ++LI;
185 ++RI;
186 // If either string is done, they're both done, since they're the same
187 // length.
188 if (LI == LN) {
189 assert(RI == RN && "Strings not the same length after all?");
190 return true;
191 }
192 LR = L[LI];
193 RR = R[RI].Data;
194 } else if (LR.size() < RR.size()) {
195 // Right piece is longer.
196 if (!RR.startswith(LR))
197 return false;
198 ++LI;
199 assert(LI != LN && "Strings not the same length after all?");
200 RR = RR.substr(LR.size());
201 LR = L[LI];
202 } else {
203 // Left piece is longer.
204 if (!LR.startswith(RR))
205 return false;
206 ++RI;
207 assert(RI != RN && "Strings not the same length after all?");
208 LR = LR.substr(RR.size());
209 RR = R[RI].Data;
210 }
211 }
212}
213
214static std::pair<FileID, llvm::StringRef::size_type>
215FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
216 std::pair<FileID, llvm::StringRef::size_type> Res;
217 for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
218 Res.second = Buffers[I].Data.find(MacroDef);
219 if (Res.second != llvm::StringRef::npos) {
220 Res.first = Buffers[I].BufferID;
221 break;
222 }
223 }
224 return Res;
225}
226
227bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000228 llvm::StringRef OriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000229 std::string &SuggestedPredefines) {
Daniel Dunbar732ef8a2009-11-11 23:58:53 +0000230 // We are in the context of an implicit include, so the predefines buffer will
231 // have a #include entry for the PCH file itself (as normalized by the
232 // preprocessor initialization). Find it and skip over it in the checking
233 // below.
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000234 llvm::SmallString<256> PCHInclude;
235 PCHInclude += "#include \"";
Daniel Dunbar732ef8a2009-11-11 23:58:53 +0000236 PCHInclude += NormalizeDashIncludePath(OriginalFileName);
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000237 PCHInclude += "\"\n";
238 std::pair<llvm::StringRef,llvm::StringRef> Split =
239 llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
240 llvm::StringRef Left = Split.first, Right = Split.second;
Ted Kremenek1ff615c2010-03-18 00:56:54 +0000241 if (Left == PP.getPredefines()) {
242 Error("Missing PCH include entry!");
243 return true;
244 }
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000245
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000246 // If the concatenation of all the PCH buffers is equal to the adjusted
247 // command line, we're done.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000248 llvm::SmallVector<llvm::StringRef, 2> CommandLine;
249 CommandLine.push_back(Left);
250 CommandLine.push_back(Right);
251 if (EqualConcatenations(CommandLine, Buffers))
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000252 return false;
253
254 SourceManager &SourceMgr = PP.getSourceManager();
Mike Stump11289f42009-09-09 15:08:12 +0000255
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000256 // The predefines buffers are different. Determine what the differences are,
257 // and whether they require us to reject the PCH file.
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000258 llvm::SmallVector<llvm::StringRef, 8> PCHLines;
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000259 for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
260 Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000261
262 llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
263 Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
264 Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000265
Daniel Dunbar499baed2009-11-11 05:26:28 +0000266 // Sort both sets of predefined buffer lines, since we allow some extra
267 // definitions and they may appear at any point in the output.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000268 std::sort(CmdLineLines.begin(), CmdLineLines.end());
269 std::sort(PCHLines.begin(), PCHLines.end());
270
Daniel Dunbar499baed2009-11-11 05:26:28 +0000271 // Determine which predefines that were used to build the PCH file are missing
272 // from the command line.
273 std::vector<llvm::StringRef> MissingPredefines;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000274 std::set_difference(PCHLines.begin(), PCHLines.end(),
275 CmdLineLines.begin(), CmdLineLines.end(),
276 std::back_inserter(MissingPredefines));
277
278 bool MissingDefines = false;
279 bool ConflictingDefines = false;
280 for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
Daniel Dunbar499baed2009-11-11 05:26:28 +0000281 llvm::StringRef Missing = MissingPredefines[I];
282 if (!Missing.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000283 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
284 return true;
285 }
Mike Stump11289f42009-09-09 15:08:12 +0000286
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000287 // This is a macro definition. Determine the name of the macro we're
288 // defining.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000289 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump11289f42009-09-09 15:08:12 +0000290 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000291 = Missing.find_first_of("( \n\r", StartOfMacroName);
292 assert(EndOfMacroName != std::string::npos &&
293 "Couldn't find the end of the macro name");
Daniel Dunbar499baed2009-11-11 05:26:28 +0000294 llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000295
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000296 // Determine whether this macro was given a different definition on the
297 // command line.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000298 std::string MacroDefStart = "#define " + MacroName.str();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000299 std::string::size_type MacroDefLen = MacroDefStart.size();
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000300 llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000301 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
302 MacroDefStart);
303 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000304 if (!ConflictPos->startswith(MacroDefStart)) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000305 // Different macro; we're done.
306 ConflictPos = CmdLineLines.end();
Mike Stump11289f42009-09-09 15:08:12 +0000307 break;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000308 }
Mike Stump11289f42009-09-09 15:08:12 +0000309
310 assert(ConflictPos->size() > MacroDefLen &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000311 "Invalid #define in predefines buffer?");
Mike Stump11289f42009-09-09 15:08:12 +0000312 if ((*ConflictPos)[MacroDefLen] != ' ' &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000313 (*ConflictPos)[MacroDefLen] != '(')
314 continue; // Longer macro name; keep trying.
Mike Stump11289f42009-09-09 15:08:12 +0000315
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000316 // We found a conflicting macro definition.
317 break;
318 }
Mike Stump11289f42009-09-09 15:08:12 +0000319
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000320 if (ConflictPos != CmdLineLines.end()) {
321 Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
322 << MacroName;
323
324 // Show the definition of this macro within the PCH file.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000325 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
326 FindMacro(Buffers, Missing);
327 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
328 SourceLocation PCHMissingLoc =
329 SourceMgr.getLocForStartOfFile(MacroLoc.first)
330 .getFileLocWithOffset(MacroLoc.second);
Daniel Dunbar499baed2009-11-11 05:26:28 +0000331 Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000332
333 ConflictingDefines = true;
334 continue;
335 }
Mike Stump11289f42009-09-09 15:08:12 +0000336
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000337 // If the macro doesn't conflict, then we'll just pick up the macro
338 // definition from the PCH file. Warn the user that they made a mistake.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000339 if (ConflictingDefines)
340 continue; // Don't complain if there are already conflicting defs
Mike Stump11289f42009-09-09 15:08:12 +0000341
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000342 if (!MissingDefines) {
343 Reader.Diag(diag::warn_cmdline_missing_macro_defs);
344 MissingDefines = true;
345 }
346
347 // Show the definition of this macro within the PCH file.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000348 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
349 FindMacro(Buffers, Missing);
350 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
351 SourceLocation PCHMissingLoc =
352 SourceMgr.getLocForStartOfFile(MacroLoc.first)
353 .getFileLocWithOffset(MacroLoc.second);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000354 Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
355 }
Mike Stump11289f42009-09-09 15:08:12 +0000356
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000357 if (ConflictingDefines)
358 return true;
Mike Stump11289f42009-09-09 15:08:12 +0000359
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000360 // Determine what predefines were introduced based on command-line
361 // parameters that were not present when building the PCH
362 // file. Extra #defines are okay, so long as the identifiers being
363 // defined were not used within the precompiled header.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000364 std::vector<llvm::StringRef> ExtraPredefines;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000365 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
366 PCHLines.begin(), PCHLines.end(),
Mike Stump11289f42009-09-09 15:08:12 +0000367 std::back_inserter(ExtraPredefines));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000368 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
Daniel Dunbar499baed2009-11-11 05:26:28 +0000369 llvm::StringRef &Extra = ExtraPredefines[I];
370 if (!Extra.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000371 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
372 return true;
373 }
374
375 // This is an extra macro definition. Determine the name of the
376 // macro we're defining.
377 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump11289f42009-09-09 15:08:12 +0000378 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000379 = Extra.find_first_of("( \n\r", StartOfMacroName);
380 assert(EndOfMacroName != std::string::npos &&
381 "Couldn't find the end of the macro name");
Daniel Dunbar499baed2009-11-11 05:26:28 +0000382 llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000383
384 // Check whether this name was used somewhere in the PCH file. If
385 // so, defining it as a macro could change behavior, so we reject
386 // the PCH file.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000387 if (IdentifierInfo *II = Reader.get(MacroName)) {
Daniel Dunbar045c92f2009-11-11 00:52:00 +0000388 Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000389 return true;
390 }
391
392 // Add this definition to the suggested predefines buffer.
393 SuggestedPredefines += Extra;
394 SuggestedPredefines += '\n';
395 }
396
397 // If we get here, it's because the predefines buffer had compatible
398 // contents. Accept the PCH file.
399 return false;
400}
401
Douglas Gregor5712ebc2010-03-16 16:35:32 +0000402void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
403 unsigned ID) {
404 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
405 ++NumHeaderInfos;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000406}
407
408void PCHValidator::ReadCounter(unsigned Value) {
409 PP.setCounterValue(Value);
410}
411
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000412//===----------------------------------------------------------------------===//
Sebastian Redl2c499f62010-08-18 23:56:43 +0000413// AST reader implementation
Douglas Gregora868bbd2009-04-21 22:25:48 +0000414//===----------------------------------------------------------------------===//
415
Sebastian Redl07a89a82010-07-30 00:29:29 +0000416void
Sebastian Redl3e31c722010-08-18 23:56:56 +0000417ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
Sebastian Redl07a89a82010-07-30 00:29:29 +0000418 DeserializationListener = Listener;
419 if (DeserializationListener)
420 DeserializationListener->SetReader(this);
421}
422
Chris Lattner92ba5ff2009-04-27 05:14:47 +0000423
Douglas Gregora868bbd2009-04-21 22:25:48 +0000424namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000425class ASTSelectorLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000426 ASTReader &Reader;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000427
428public:
Sebastian Redl834bb972010-08-04 17:20:04 +0000429 struct data_type {
Sebastian Redl539c5062010-08-18 23:57:32 +0000430 SelectorID ID;
Sebastian Redl834bb972010-08-04 17:20:04 +0000431 ObjCMethodList Instance, Factory;
432 };
Douglas Gregorc78d3462009-04-24 21:10:55 +0000433
434 typedef Selector external_key_type;
435 typedef external_key_type internal_key_type;
436
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000437 explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
Mike Stump11289f42009-09-09 15:08:12 +0000438
Douglas Gregorc78d3462009-04-24 21:10:55 +0000439 static bool EqualKey(const internal_key_type& a,
440 const internal_key_type& b) {
441 return a == b;
442 }
Mike Stump11289f42009-09-09 15:08:12 +0000443
Douglas Gregorc78d3462009-04-24 21:10:55 +0000444 static unsigned ComputeHash(Selector Sel) {
Argyrios Kyrtzidis4bd97102010-08-20 16:03:52 +0000445 return serialization::ComputeHash(Sel);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000446 }
Mike Stump11289f42009-09-09 15:08:12 +0000447
Douglas Gregorc78d3462009-04-24 21:10:55 +0000448 // This hopefully will just get inlined and removed by the optimizer.
449 static const internal_key_type&
450 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump11289f42009-09-09 15:08:12 +0000451
Douglas Gregorc78d3462009-04-24 21:10:55 +0000452 static std::pair<unsigned, unsigned>
453 ReadKeyDataLength(const unsigned char*& d) {
454 using namespace clang::io;
455 unsigned KeyLen = ReadUnalignedLE16(d);
456 unsigned DataLen = ReadUnalignedLE16(d);
457 return std::make_pair(KeyLen, DataLen);
458 }
Mike Stump11289f42009-09-09 15:08:12 +0000459
Douglas Gregor95c13f52009-04-25 17:48:32 +0000460 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000461 using namespace clang::io;
Chris Lattner8575daa2009-04-27 21:45:14 +0000462 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000463 unsigned N = ReadUnalignedLE16(d);
Mike Stump11289f42009-09-09 15:08:12 +0000464 IdentifierInfo *FirstII
Douglas Gregorc78d3462009-04-24 21:10:55 +0000465 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
466 if (N == 0)
467 return SelTable.getNullarySelector(FirstII);
468 else if (N == 1)
469 return SelTable.getUnarySelector(FirstII);
470
471 llvm::SmallVector<IdentifierInfo *, 16> Args;
472 Args.push_back(FirstII);
473 for (unsigned I = 1; I != N; ++I)
474 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
475
Douglas Gregor038c3382009-05-22 22:45:36 +0000476 return SelTable.getSelector(N, Args.data());
Douglas Gregorc78d3462009-04-24 21:10:55 +0000477 }
Mike Stump11289f42009-09-09 15:08:12 +0000478
Douglas Gregorc78d3462009-04-24 21:10:55 +0000479 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
480 using namespace clang::io;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000481
482 data_type Result;
483
Sebastian Redl834bb972010-08-04 17:20:04 +0000484 Result.ID = ReadUnalignedLE32(d);
485 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
486 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
487
Douglas Gregorc78d3462009-04-24 21:10:55 +0000488 // Load instance methods
489 ObjCMethodList *Prev = 0;
490 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +0000491 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000492 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000493 if (!Result.Instance.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000494 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000495 Result.Instance.Method = Method;
496 Prev = &Result.Instance;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000497 continue;
498 }
499
Ted Kremenekda4abf12010-02-11 00:53:01 +0000500 ObjCMethodList *Mem =
501 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
502 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000503 Prev = Prev->Next;
504 }
505
506 // Load factory methods
507 Prev = 0;
508 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +0000509 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000510 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000511 if (!Result.Factory.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000512 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000513 Result.Factory.Method = Method;
514 Prev = &Result.Factory;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000515 continue;
516 }
517
Ted Kremenekda4abf12010-02-11 00:53:01 +0000518 ObjCMethodList *Mem =
519 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
520 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000521 Prev = Prev->Next;
522 }
523
524 return Result;
525 }
526};
Mike Stump11289f42009-09-09 15:08:12 +0000527
528} // end anonymous namespace
Douglas Gregorc78d3462009-04-24 21:10:55 +0000529
530/// \brief The on-disk hash table used for the global method pool.
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000531typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
532 ASTSelectorLookupTable;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000533
534namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000535class ASTIdentifierLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000536 ASTReader &Reader;
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000537 llvm::BitstreamCursor &Stream;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000538
539 // If we know the IdentifierInfo in advance, it is here and we will
540 // not build a new one. Used when deserializing information about an
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000541 // identifier that was constructed before the AST file was read.
Douglas Gregora868bbd2009-04-21 22:25:48 +0000542 IdentifierInfo *KnownII;
543
544public:
545 typedef IdentifierInfo * data_type;
546
547 typedef const std::pair<const char*, unsigned> external_key_type;
548
549 typedef external_key_type internal_key_type;
550
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000551 ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000552 IdentifierInfo *II = 0)
553 : Reader(Reader), Stream(Stream), KnownII(II) { }
Mike Stump11289f42009-09-09 15:08:12 +0000554
Douglas Gregora868bbd2009-04-21 22:25:48 +0000555 static bool EqualKey(const internal_key_type& a,
556 const internal_key_type& b) {
557 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
558 : false;
559 }
Mike Stump11289f42009-09-09 15:08:12 +0000560
Douglas Gregora868bbd2009-04-21 22:25:48 +0000561 static unsigned ComputeHash(const internal_key_type& a) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000562 return llvm::HashString(llvm::StringRef(a.first, a.second));
Douglas Gregora868bbd2009-04-21 22:25:48 +0000563 }
Mike Stump11289f42009-09-09 15:08:12 +0000564
Douglas Gregora868bbd2009-04-21 22:25:48 +0000565 // This hopefully will just get inlined and removed by the optimizer.
566 static const internal_key_type&
567 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump11289f42009-09-09 15:08:12 +0000568
Douglas Gregora868bbd2009-04-21 22:25:48 +0000569 static std::pair<unsigned, unsigned>
570 ReadKeyDataLength(const unsigned char*& d) {
571 using namespace clang::io;
Douglas Gregor6b7bf5a2009-04-25 20:26:24 +0000572 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregor5287b4e2009-04-25 21:04:17 +0000573 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000574 return std::make_pair(KeyLen, DataLen);
575 }
Mike Stump11289f42009-09-09 15:08:12 +0000576
Douglas Gregora868bbd2009-04-21 22:25:48 +0000577 static std::pair<const char*, unsigned>
578 ReadKey(const unsigned char* d, unsigned n) {
579 assert(n >= 2 && d[n-1] == '\0');
580 return std::make_pair((const char*) d, n-1);
581 }
Mike Stump11289f42009-09-09 15:08:12 +0000582
583 IdentifierInfo *ReadData(const internal_key_type& k,
Douglas Gregora868bbd2009-04-21 22:25:48 +0000584 const unsigned char* d,
585 unsigned DataLen) {
586 using namespace clang::io;
Sebastian Redl539c5062010-08-18 23:57:32 +0000587 IdentID ID = ReadUnalignedLE32(d);
Douglas Gregor1d583f22009-04-28 21:18:29 +0000588 bool IsInteresting = ID & 0x01;
589
590 // Wipe out the "is interesting" bit.
591 ID = ID >> 1;
592
593 if (!IsInteresting) {
Sebastian Redl98912122010-07-27 23:01:28 +0000594 // For uninteresting identifiers, just build the IdentifierInfo
Douglas Gregor1d583f22009-04-28 21:18:29 +0000595 // and associate it with the persistent ID.
596 IdentifierInfo *II = KnownII;
597 if (!II)
Sebastian Redl07a89a82010-07-30 00:29:29 +0000598 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregor1d583f22009-04-28 21:18:29 +0000599 Reader.SetIdentifierInfo(ID, II);
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000600 II->setIsFromAST();
Douglas Gregor1d583f22009-04-28 21:18:29 +0000601 return II;
602 }
603
Douglas Gregorb9256522009-04-28 21:32:13 +0000604 unsigned Bits = ReadUnalignedLE16(d);
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000605 bool CPlusPlusOperatorKeyword = Bits & 0x01;
606 Bits >>= 1;
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000607 bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
608 Bits >>= 1;
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000609 bool Poisoned = Bits & 0x01;
610 Bits >>= 1;
611 bool ExtensionToken = Bits & 0x01;
612 Bits >>= 1;
613 bool hasMacroDefinition = Bits & 0x01;
614 Bits >>= 1;
615 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
616 Bits >>= 10;
Mike Stump11289f42009-09-09 15:08:12 +0000617
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000618 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregorb9256522009-04-28 21:32:13 +0000619 DataLen -= 6;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000620
621 // Build the IdentifierInfo itself and link the identifier ID with
622 // the new IdentifierInfo.
623 IdentifierInfo *II = KnownII;
624 if (!II)
Sebastian Redl07a89a82010-07-30 00:29:29 +0000625 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000626 Reader.SetIdentifierInfo(ID, II);
627
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000628 // Set or check the various bits in the IdentifierInfo structure.
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000629 // Token IDs are read-only.
630 if (HasRevertedTokenIDToIdentifier)
631 II->RevertTokenIDToIdentifier();
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000632 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
Mike Stump11289f42009-09-09 15:08:12 +0000633 assert(II->isExtensionToken() == ExtensionToken &&
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000634 "Incorrect extension token flag");
635 (void)ExtensionToken;
636 II->setIsPoisoned(Poisoned);
637 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
638 "Incorrect C++ operator keyword flag");
639 (void)CPlusPlusOperatorKeyword;
640
Douglas Gregorc3366a52009-04-21 23:56:24 +0000641 // If this identifier is a macro, deserialize the macro
642 // definition.
643 if (hasMacroDefinition) {
Douglas Gregorb9256522009-04-28 21:32:13 +0000644 uint32_t Offset = ReadUnalignedLE32(d);
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000645 Reader.ReadMacroRecord(Stream, Offset);
Douglas Gregorb9256522009-04-28 21:32:13 +0000646 DataLen -= 4;
Douglas Gregorc3366a52009-04-21 23:56:24 +0000647 }
Douglas Gregora868bbd2009-04-21 22:25:48 +0000648
649 // Read all of the declarations visible at global scope with this
650 // name.
Chris Lattner1d728882009-04-27 22:17:41 +0000651 if (Reader.getContext() == 0) return II;
Douglas Gregor1342e842009-07-06 18:54:52 +0000652 if (DataLen > 0) {
653 llvm::SmallVector<uint32_t, 4> DeclIDs;
654 for (; DataLen > 0; DataLen -= 4)
655 DeclIDs.push_back(ReadUnalignedLE32(d));
656 Reader.SetGloballyVisibleDecls(II, DeclIDs);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000657 }
Mike Stump11289f42009-09-09 15:08:12 +0000658
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000659 II->setIsFromAST();
Douglas Gregora868bbd2009-04-21 22:25:48 +0000660 return II;
661 }
662};
Mike Stump11289f42009-09-09 15:08:12 +0000663
664} // end anonymous namespace
Douglas Gregora868bbd2009-04-21 22:25:48 +0000665
666/// \brief The on-disk hash table used to contain information about
667/// all of the identifiers in the program.
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000668typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
669 ASTIdentifierLookupTable;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000670
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +0000671namespace {
672class ASTDeclContextNameLookupTrait {
673 ASTReader &Reader;
674
675public:
676 /// \brief Pair of begin/end iterators for DeclIDs.
677 typedef std::pair<DeclID *, DeclID *> data_type;
678
679 /// \brief Special internal key for declaration names.
680 /// The hash table creates keys for comparison; we do not create
681 /// a DeclarationName for the internal key to avoid deserializing types.
682 struct DeclNameKey {
683 DeclarationName::NameKind Kind;
684 uint64_t Data;
685 DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
686 };
687
688 typedef DeclarationName external_key_type;
689 typedef DeclNameKey internal_key_type;
690
691 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
692
693 static bool EqualKey(const internal_key_type& a,
694 const internal_key_type& b) {
695 return a.Kind == b.Kind && a.Data == b.Data;
696 }
697
698 unsigned ComputeHash(const DeclNameKey &Key) const {
699 llvm::FoldingSetNodeID ID;
700 ID.AddInteger(Key.Kind);
701
702 switch (Key.Kind) {
703 case DeclarationName::Identifier:
704 case DeclarationName::CXXLiteralOperatorName:
705 ID.AddString(((IdentifierInfo*)Key.Data)->getName());
706 break;
707 case DeclarationName::ObjCZeroArgSelector:
708 case DeclarationName::ObjCOneArgSelector:
709 case DeclarationName::ObjCMultiArgSelector:
710 ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
711 break;
712 case DeclarationName::CXXConstructorName:
713 case DeclarationName::CXXDestructorName:
714 case DeclarationName::CXXConversionFunctionName:
715 ID.AddInteger((TypeID)Key.Data);
716 break;
717 case DeclarationName::CXXOperatorName:
718 ID.AddInteger((OverloadedOperatorKind)Key.Data);
719 break;
720 case DeclarationName::CXXUsingDirective:
721 break;
722 }
723
724 return ID.ComputeHash();
725 }
726
727 internal_key_type GetInternalKey(const external_key_type& Name) const {
728 DeclNameKey Key;
729 Key.Kind = Name.getNameKind();
730 switch (Name.getNameKind()) {
731 case DeclarationName::Identifier:
732 Key.Data = (uint64_t)Name.getAsIdentifierInfo();
733 break;
734 case DeclarationName::ObjCZeroArgSelector:
735 case DeclarationName::ObjCOneArgSelector:
736 case DeclarationName::ObjCMultiArgSelector:
737 Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
738 break;
739 case DeclarationName::CXXConstructorName:
740 case DeclarationName::CXXDestructorName:
741 case DeclarationName::CXXConversionFunctionName:
742 Key.Data = Reader.GetTypeID(Name.getCXXNameType());
743 break;
744 case DeclarationName::CXXOperatorName:
745 Key.Data = Name.getCXXOverloadedOperator();
746 break;
747 case DeclarationName::CXXLiteralOperatorName:
748 Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
749 break;
750 case DeclarationName::CXXUsingDirective:
751 break;
752 }
753
754 return Key;
755 }
756
Argyrios Kyrtzidisd32ee892010-08-20 23:35:55 +0000757 external_key_type GetExternalKey(const internal_key_type& Key) const {
758 ASTContext *Context = Reader.getContext();
759 switch (Key.Kind) {
760 case DeclarationName::Identifier:
761 return DeclarationName((IdentifierInfo*)Key.Data);
762
763 case DeclarationName::ObjCZeroArgSelector:
764 case DeclarationName::ObjCOneArgSelector:
765 case DeclarationName::ObjCMultiArgSelector:
766 return DeclarationName(Selector(Key.Data));
767
768 case DeclarationName::CXXConstructorName:
769 return Context->DeclarationNames.getCXXConstructorName(
770 Context->getCanonicalType(Reader.GetType(Key.Data)));
771
772 case DeclarationName::CXXDestructorName:
773 return Context->DeclarationNames.getCXXDestructorName(
774 Context->getCanonicalType(Reader.GetType(Key.Data)));
775
776 case DeclarationName::CXXConversionFunctionName:
777 return Context->DeclarationNames.getCXXConversionFunctionName(
778 Context->getCanonicalType(Reader.GetType(Key.Data)));
779
780 case DeclarationName::CXXOperatorName:
781 return Context->DeclarationNames.getCXXOperatorName(
782 (OverloadedOperatorKind)Key.Data);
783
784 case DeclarationName::CXXLiteralOperatorName:
785 return Context->DeclarationNames.getCXXLiteralOperatorName(
786 (IdentifierInfo*)Key.Data);
787
788 case DeclarationName::CXXUsingDirective:
789 return DeclarationName::getUsingDirectiveName();
790 }
791
792 llvm_unreachable("Invalid Name Kind ?");
793 }
794
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +0000795 static std::pair<unsigned, unsigned>
796 ReadKeyDataLength(const unsigned char*& d) {
797 using namespace clang::io;
798 unsigned KeyLen = ReadUnalignedLE16(d);
799 unsigned DataLen = ReadUnalignedLE16(d);
800 return std::make_pair(KeyLen, DataLen);
801 }
802
803 internal_key_type ReadKey(const unsigned char* d, unsigned) {
804 using namespace clang::io;
805
806 DeclNameKey Key;
807 Key.Kind = (DeclarationName::NameKind)*d++;
808 switch (Key.Kind) {
809 case DeclarationName::Identifier:
810 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
811 break;
812 case DeclarationName::ObjCZeroArgSelector:
813 case DeclarationName::ObjCOneArgSelector:
814 case DeclarationName::ObjCMultiArgSelector:
815 Key.Data =
816 (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
817 break;
818 case DeclarationName::CXXConstructorName:
819 case DeclarationName::CXXDestructorName:
820 case DeclarationName::CXXConversionFunctionName:
821 Key.Data = ReadUnalignedLE32(d); // TypeID
822 break;
823 case DeclarationName::CXXOperatorName:
824 Key.Data = *d++; // OverloadedOperatorKind
825 break;
826 case DeclarationName::CXXLiteralOperatorName:
827 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
828 break;
829 case DeclarationName::CXXUsingDirective:
830 break;
831 }
832
833 return Key;
834 }
835
836 data_type ReadData(internal_key_type, const unsigned char* d,
837 unsigned DataLen) {
838 using namespace clang::io;
839 unsigned NumDecls = ReadUnalignedLE16(d);
840 DeclID *Start = (DeclID *)d;
841 return std::make_pair(Start, Start + NumDecls);
842 }
843};
844
845} // end anonymous namespace
846
847/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
848typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
849 ASTDeclContextNameLookupTable;
850
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +0000851bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
852 const std::pair<uint64_t, uint64_t> &Offsets,
853 DeclContextInfo &Info) {
854 SavedStreamPosition SavedPosition(Cursor);
855 // First the lexical decls.
856 if (Offsets.first != 0) {
857 Cursor.JumpToBit(Offsets.first);
858
859 RecordData Record;
860 const char *Blob;
861 unsigned BlobLen;
862 unsigned Code = Cursor.ReadCode();
863 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
864 if (RecCode != DECL_CONTEXT_LEXICAL) {
865 Error("Expected lexical block");
866 return true;
867 }
868
869 Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
870 Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
871 } else {
872 Info.LexicalDecls = 0;
873 Info.NumLexicalDecls = 0;
874 }
875
876 // Now the lookup table.
877 if (Offsets.second != 0) {
878 Cursor.JumpToBit(Offsets.second);
879
880 RecordData Record;
881 const char *Blob;
882 unsigned BlobLen;
883 unsigned Code = Cursor.ReadCode();
884 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
885 if (RecCode != DECL_CONTEXT_VISIBLE) {
886 Error("Expected visible lookup table block");
887 return true;
888 }
889 Info.NameLookupTableData
890 = ASTDeclContextNameLookupTable::Create(
891 (const unsigned char *)Blob + Record[0],
892 (const unsigned char *)Blob,
893 ASTDeclContextNameLookupTrait(*this));
Sebastian Redl9d8f58b2010-08-24 00:50:00 +0000894 } else {
895 Info.NameLookupTableData = 0;
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +0000896 }
897
898 return false;
899}
900
Sebastian Redl2c499f62010-08-18 23:56:43 +0000901void ASTReader::Error(const char *Msg) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +0000902 Diag(diag::err_fe_pch_malformed) << Msg;
Douglas Gregoref84c4b2009-04-09 22:27:44 +0000903}
904
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000905/// \brief Tell the AST listener about the predefines buffers in the chain.
Sebastian Redl2c499f62010-08-18 23:56:43 +0000906bool ASTReader::CheckPredefinesBuffers() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000907 if (Listener)
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000908 return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000909 ActualOriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000910 SuggestedPredefines);
Douglas Gregorc379c072009-04-28 18:58:38 +0000911 return false;
Douglas Gregor92863e42009-04-10 23:10:45 +0000912}
913
Douglas Gregorc5046832009-04-27 18:38:38 +0000914//===----------------------------------------------------------------------===//
915// Source Manager Deserialization
916//===----------------------------------------------------------------------===//
917
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000918/// \brief Read the line table in the source manager block.
919/// \returns true if ther was an error.
Sebastian Redl2c499f62010-08-18 23:56:43 +0000920bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000921 unsigned Idx = 0;
922 LineTableInfo &LineTable = SourceMgr.getLineTable();
923
924 // Parse the file names
Douglas Gregora8854652009-04-13 17:12:42 +0000925 std::map<int, int> FileIDs;
926 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000927 // Extract the file name
928 unsigned FilenameLen = Record[Idx++];
929 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
930 Idx += FilenameLen;
Douglas Gregor0086a5a2009-07-07 00:12:59 +0000931 MaybeAddSystemRootToFilename(Filename);
Mike Stump11289f42009-09-09 15:08:12 +0000932 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Douglas Gregora8854652009-04-13 17:12:42 +0000933 Filename.size());
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000934 }
935
936 // Parse the line entries
937 std::vector<LineEntry> Entries;
938 while (Idx < Record.size()) {
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000939 int FID = Record[Idx++];
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000940
941 // Extract the line entries
942 unsigned NumEntries = Record[Idx++];
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000943 assert(NumEntries && "Numentries is 00000");
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000944 Entries.clear();
945 Entries.reserve(NumEntries);
946 for (unsigned I = 0; I != NumEntries; ++I) {
947 unsigned FileOffset = Record[Idx++];
948 unsigned LineNo = Record[Idx++];
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000949 int FilenameID = FileIDs[Record[Idx++]];
Mike Stump11289f42009-09-09 15:08:12 +0000950 SrcMgr::CharacteristicKind FileKind
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000951 = (SrcMgr::CharacteristicKind)Record[Idx++];
952 unsigned IncludeOffset = Record[Idx++];
953 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
954 FileKind, IncludeOffset));
955 }
956 LineTable.AddEntry(FID, Entries);
957 }
958
959 return false;
960}
961
Douglas Gregorc5046832009-04-27 18:38:38 +0000962namespace {
963
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000964class ASTStatData {
Douglas Gregorc5046832009-04-27 18:38:38 +0000965public:
966 const bool hasStat;
967 const ino_t ino;
968 const dev_t dev;
969 const mode_t mode;
970 const time_t mtime;
971 const off_t size;
Mike Stump11289f42009-09-09 15:08:12 +0000972
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000973 ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
Mike Stump11289f42009-09-09 15:08:12 +0000974 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
975
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000976 ASTStatData()
Douglas Gregorc5046832009-04-27 18:38:38 +0000977 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
978};
979
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000980class ASTStatLookupTrait {
Douglas Gregorc5046832009-04-27 18:38:38 +0000981 public:
982 typedef const char *external_key_type;
983 typedef const char *internal_key_type;
984
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000985 typedef ASTStatData data_type;
Douglas Gregorc5046832009-04-27 18:38:38 +0000986
987 static unsigned ComputeHash(const char *path) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000988 return llvm::HashString(path);
Douglas Gregorc5046832009-04-27 18:38:38 +0000989 }
990
991 static internal_key_type GetInternalKey(const char *path) { return path; }
992
993 static bool EqualKey(internal_key_type a, internal_key_type b) {
994 return strcmp(a, b) == 0;
995 }
996
997 static std::pair<unsigned, unsigned>
998 ReadKeyDataLength(const unsigned char*& d) {
999 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
1000 unsigned DataLen = (unsigned) *d++;
1001 return std::make_pair(KeyLen + 1, DataLen);
1002 }
1003
1004 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
1005 return (const char *)d;
1006 }
1007
1008 static data_type ReadData(const internal_key_type, const unsigned char *d,
1009 unsigned /*DataLen*/) {
1010 using namespace clang::io;
1011
1012 if (*d++ == 1)
1013 return data_type();
1014
1015 ino_t ino = (ino_t) ReadUnalignedLE32(d);
1016 dev_t dev = (dev_t) ReadUnalignedLE32(d);
1017 mode_t mode = (mode_t) ReadUnalignedLE16(d);
Mike Stump11289f42009-09-09 15:08:12 +00001018 time_t mtime = (time_t) ReadUnalignedLE64(d);
Douglas Gregorc5046832009-04-27 18:38:38 +00001019 off_t size = (off_t) ReadUnalignedLE64(d);
1020 return data_type(ino, dev, mode, mtime, size);
1021 }
1022};
1023
1024/// \brief stat() cache for precompiled headers.
1025///
1026/// This cache is very similar to the stat cache used by pretokenized
1027/// headers.
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001028class ASTStatCache : public StatSysCallCache {
1029 typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
Douglas Gregorc5046832009-04-27 18:38:38 +00001030 CacheTy *Cache;
1031
1032 unsigned &NumStatHits, &NumStatMisses;
Mike Stump11289f42009-09-09 15:08:12 +00001033public:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001034 ASTStatCache(const unsigned char *Buckets,
Douglas Gregorc5046832009-04-27 18:38:38 +00001035 const unsigned char *Base,
1036 unsigned &NumStatHits,
Mike Stump11289f42009-09-09 15:08:12 +00001037 unsigned &NumStatMisses)
Douglas Gregorc5046832009-04-27 18:38:38 +00001038 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
1039 Cache = CacheTy::Create(Buckets, Base);
1040 }
1041
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001042 ~ASTStatCache() { delete Cache; }
Mike Stump11289f42009-09-09 15:08:12 +00001043
Douglas Gregorc5046832009-04-27 18:38:38 +00001044 int stat(const char *path, struct stat *buf) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001045 // Do the lookup for the file's data in the AST file.
Douglas Gregorc5046832009-04-27 18:38:38 +00001046 CacheTy::iterator I = Cache->find(path);
1047
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001048 // If we don't get a hit in the AST file just forward to 'stat'.
Douglas Gregorc5046832009-04-27 18:38:38 +00001049 if (I == Cache->end()) {
1050 ++NumStatMisses;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001051 return StatSysCallCache::stat(path, buf);
Douglas Gregorc5046832009-04-27 18:38:38 +00001052 }
Mike Stump11289f42009-09-09 15:08:12 +00001053
Douglas Gregorc5046832009-04-27 18:38:38 +00001054 ++NumStatHits;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001055 ASTStatData Data = *I;
Mike Stump11289f42009-09-09 15:08:12 +00001056
Douglas Gregorc5046832009-04-27 18:38:38 +00001057 if (!Data.hasStat)
1058 return 1;
1059
1060 buf->st_ino = Data.ino;
1061 buf->st_dev = Data.dev;
1062 buf->st_mtime = Data.mtime;
1063 buf->st_mode = Data.mode;
1064 buf->st_size = Data.size;
1065 return 0;
1066 }
1067};
1068} // end anonymous namespace
1069
1070
Sebastian Redl393f8b72010-07-19 20:52:06 +00001071/// \brief Read a source manager block
Sebastian Redl2c499f62010-08-18 23:56:43 +00001072ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001073 using namespace SrcMgr;
Douglas Gregor258ae542009-04-27 06:38:32 +00001074
Sebastian Redl393f8b72010-07-19 20:52:06 +00001075 llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
Sebastian Redl34522812010-07-16 17:50:48 +00001076
Douglas Gregor258ae542009-04-27 06:38:32 +00001077 // Set the source-location entry cursor to the current position in
1078 // the stream. This cursor will be used to read the contents of the
1079 // source manager block initially, and then lazily read
1080 // source-location entries as needed.
Sebastian Redl393f8b72010-07-19 20:52:06 +00001081 SLocEntryCursor = F.Stream;
Douglas Gregor258ae542009-04-27 06:38:32 +00001082
1083 // The stream itself is going to skip over the source manager block.
Sebastian Redl393f8b72010-07-19 20:52:06 +00001084 if (F.Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001085 Error("malformed block record in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001086 return Failure;
1087 }
1088
1089 // Enter the source manager block.
Sebastian Redl539c5062010-08-18 23:57:32 +00001090 if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001091 Error("malformed source manager block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001092 return Failure;
1093 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001094
Douglas Gregora7f71a92009-04-10 03:52:48 +00001095 RecordData Record;
1096 while (true) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001097 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001098 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001099 if (SLocEntryCursor.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001100 Error("error at end of Source Manager block in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001101 return Failure;
1102 }
Douglas Gregor92863e42009-04-10 23:10:45 +00001103 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001104 }
Mike Stump11289f42009-09-09 15:08:12 +00001105
Douglas Gregora7f71a92009-04-10 03:52:48 +00001106 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1107 // No known subblocks, always skip them.
Douglas Gregor258ae542009-04-27 06:38:32 +00001108 SLocEntryCursor.ReadSubBlockID();
1109 if (SLocEntryCursor.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001110 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001111 return Failure;
1112 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001113 continue;
1114 }
Mike Stump11289f42009-09-09 15:08:12 +00001115
Douglas Gregora7f71a92009-04-10 03:52:48 +00001116 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001117 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001118 continue;
1119 }
Mike Stump11289f42009-09-09 15:08:12 +00001120
Douglas Gregora7f71a92009-04-10 03:52:48 +00001121 // Read a record.
1122 const char *BlobStart;
1123 unsigned BlobLen;
1124 Record.clear();
Douglas Gregor258ae542009-04-27 06:38:32 +00001125 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001126 default: // Default behavior: ignore.
1127 break;
1128
Sebastian Redl539c5062010-08-18 23:57:32 +00001129 case SM_LINE_TABLE:
Sebastian Redlb293a452010-07-20 21:20:32 +00001130 if (ParseLineTable(Record))
Douglas Gregor4c7626e2009-04-13 16:31:14 +00001131 return Failure;
Chris Lattner184e65d2009-04-14 23:22:57 +00001132 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001133
Sebastian Redl539c5062010-08-18 23:57:32 +00001134 case SM_SLOC_FILE_ENTRY:
1135 case SM_SLOC_BUFFER_ENTRY:
1136 case SM_SLOC_INSTANTIATION_ENTRY:
Douglas Gregor258ae542009-04-27 06:38:32 +00001137 // Once we hit one of the source location entries, we're done.
1138 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001139 }
1140 }
1141}
1142
Sebastian Redl06750302010-07-20 21:50:20 +00001143/// \brief Get a cursor that's correctly positioned for reading the source
1144/// location entry with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001145llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
Sebastian Redl06750302010-07-20 21:50:20 +00001146 assert(ID != 0 && ID <= TotalNumSLocEntries &&
1147 "SLocCursorForID should only be called for real IDs.");
1148
1149 ID -= 1;
1150 PerFileData *F = 0;
1151 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1152 F = Chain[N - I - 1];
1153 if (ID < F->LocalNumSLocEntries)
1154 break;
1155 ID -= F->LocalNumSLocEntries;
1156 }
1157 assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
1158
1159 F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
1160 return F->SLocEntryCursor;
1161}
1162
Douglas Gregor258ae542009-04-27 06:38:32 +00001163/// \brief Read in the source location entry with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001164ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001165 if (ID == 0)
1166 return Success;
1167
1168 if (ID > TotalNumSLocEntries) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001169 Error("source location entry ID out-of-range for AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001170 return Failure;
1171 }
1172
Sebastian Redl06750302010-07-20 21:50:20 +00001173 llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
Sebastian Redl34522812010-07-16 17:50:48 +00001174
Douglas Gregor258ae542009-04-27 06:38:32 +00001175 ++NumSLocEntriesRead;
Douglas Gregor258ae542009-04-27 06:38:32 +00001176 unsigned Code = SLocEntryCursor.ReadCode();
1177 if (Code == llvm::bitc::END_BLOCK ||
1178 Code == llvm::bitc::ENTER_SUBBLOCK ||
1179 Code == llvm::bitc::DEFINE_ABBREV) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001180 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001181 return Failure;
1182 }
1183
Douglas Gregor258ae542009-04-27 06:38:32 +00001184 RecordData Record;
1185 const char *BlobStart;
1186 unsigned BlobLen;
1187 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1188 default:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001189 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001190 return Failure;
1191
Sebastian Redl539c5062010-08-18 23:57:32 +00001192 case SM_SLOC_FILE_ENTRY: {
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001193 std::string Filename(BlobStart, BlobStart + BlobLen);
1194 MaybeAddSystemRootToFilename(Filename);
1195 const FileEntry *File = FileMgr.getFile(Filename);
Chris Lattnerd20dc872009-06-15 04:35:16 +00001196 if (File == 0) {
1197 std::string ErrorStr = "could not find file '";
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001198 ErrorStr += Filename;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001199 ErrorStr += "' referenced by AST file";
Chris Lattnerd20dc872009-06-15 04:35:16 +00001200 Error(ErrorStr.c_str());
1201 return Failure;
1202 }
Mike Stump11289f42009-09-09 15:08:12 +00001203
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001204 if (Record.size() < 10) {
Ted Kremenekabb1ddd2010-03-18 21:23:05 +00001205 Error("source location entry is incorrect");
1206 return Failure;
1207 }
1208
Douglas Gregorce3a8292010-07-27 00:27:13 +00001209 if (!DisableValidation &&
1210 ((off_t)Record[4] != File->getSize()
Douglas Gregor08288f22010-04-09 15:54:22 +00001211#if !defined(LLVM_ON_WIN32)
1212 // In our regression testing, the Windows file system seems to
1213 // have inconsistent modification times that sometimes
1214 // erroneously trigger this error-handling path.
Douglas Gregorce3a8292010-07-27 00:27:13 +00001215 || (time_t)Record[5] != File->getModificationTime()
Douglas Gregor08288f22010-04-09 15:54:22 +00001216#endif
Douglas Gregorce3a8292010-07-27 00:27:13 +00001217 )) {
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001218 Diag(diag::err_fe_pch_file_modified)
1219 << Filename;
1220 return Failure;
1221 }
1222
Douglas Gregor258ae542009-04-27 06:38:32 +00001223 FileID FID = SourceMgr.createFileID(File,
1224 SourceLocation::getFromRawEncoding(Record[1]),
1225 (SrcMgr::CharacteristicKind)Record[2],
1226 ID, Record[0]);
1227 if (Record[3])
1228 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
1229 .setHasLineDirectives();
1230
Douglas Gregor5712ebc2010-03-16 16:35:32 +00001231 // Reconstruct header-search information for this file.
1232 HeaderFileInfo HFI;
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001233 HFI.isImport = Record[6];
1234 HFI.DirInfo = Record[7];
1235 HFI.NumIncludes = Record[8];
1236 HFI.ControllingMacroID = Record[9];
Douglas Gregor5712ebc2010-03-16 16:35:32 +00001237 if (Listener)
1238 Listener->ReadHeaderFileInfo(HFI, File->getUID());
Douglas Gregor258ae542009-04-27 06:38:32 +00001239 break;
1240 }
1241
Sebastian Redl539c5062010-08-18 23:57:32 +00001242 case SM_SLOC_BUFFER_ENTRY: {
Douglas Gregor258ae542009-04-27 06:38:32 +00001243 const char *Name = BlobStart;
1244 unsigned Offset = Record[0];
1245 unsigned Code = SLocEntryCursor.ReadCode();
1246 Record.clear();
Mike Stump11289f42009-09-09 15:08:12 +00001247 unsigned RecCode
Douglas Gregor258ae542009-04-27 06:38:32 +00001248 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001249
Sebastian Redl539c5062010-08-18 23:57:32 +00001250 if (RecCode != SM_SLOC_BUFFER_BLOB) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001251 Error("AST record has invalid code");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001252 return Failure;
1253 }
1254
Douglas Gregor258ae542009-04-27 06:38:32 +00001255 llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00001256 = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
1257 Name);
Douglas Gregor258ae542009-04-27 06:38:32 +00001258 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
Mike Stump11289f42009-09-09 15:08:12 +00001259
Douglas Gregore6648fb2009-04-28 20:33:11 +00001260 if (strcmp(Name, "<built-in>") == 0) {
Sebastian Redl75fbb3b2010-07-14 17:49:11 +00001261 PCHPredefinesBlock Block = {
1262 BufferID,
1263 llvm::StringRef(BlobStart, BlobLen - 1)
1264 };
1265 PCHPredefinesBuffers.push_back(Block);
Douglas Gregore6648fb2009-04-28 20:33:11 +00001266 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001267
1268 break;
1269 }
1270
Sebastian Redl539c5062010-08-18 23:57:32 +00001271 case SM_SLOC_INSTANTIATION_ENTRY: {
Mike Stump11289f42009-09-09 15:08:12 +00001272 SourceLocation SpellingLoc
Douglas Gregor258ae542009-04-27 06:38:32 +00001273 = SourceLocation::getFromRawEncoding(Record[1]);
1274 SourceMgr.createInstantiationLoc(SpellingLoc,
1275 SourceLocation::getFromRawEncoding(Record[2]),
1276 SourceLocation::getFromRawEncoding(Record[3]),
1277 Record[4],
1278 ID,
1279 Record[0]);
1280 break;
Mike Stump11289f42009-09-09 15:08:12 +00001281 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001282 }
1283
1284 return Success;
1285}
1286
Chris Lattnere78a6be2009-04-27 01:05:14 +00001287/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
1288/// specified cursor. Read the abbreviations that are at the top of the block
1289/// and then leave the cursor pointing into the block.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001290bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
Chris Lattnere78a6be2009-04-27 01:05:14 +00001291 unsigned BlockID) {
1292 if (Cursor.EnterSubBlock(BlockID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001293 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001294 return Failure;
1295 }
Mike Stump11289f42009-09-09 15:08:12 +00001296
Chris Lattnere78a6be2009-04-27 01:05:14 +00001297 while (true) {
1298 unsigned Code = Cursor.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00001299
Chris Lattnere78a6be2009-04-27 01:05:14 +00001300 // We expect all abbrevs to be at the start of the block.
1301 if (Code != llvm::bitc::DEFINE_ABBREV)
1302 return false;
1303 Cursor.ReadAbbrevRecord();
1304 }
1305}
1306
Sebastian Redl2c499f62010-08-18 23:56:43 +00001307void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001308 assert(PP && "Forgot to set Preprocessor ?");
Mike Stump11289f42009-09-09 15:08:12 +00001309
Douglas Gregorc3366a52009-04-21 23:56:24 +00001310 // Keep track of where we are in the stream, then jump back there
1311 // after reading this macro.
1312 SavedStreamPosition SavedPosition(Stream);
1313
1314 Stream.JumpToBit(Offset);
1315 RecordData Record;
1316 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
1317 MacroInfo *Macro = 0;
Mike Stump11289f42009-09-09 15:08:12 +00001318
Douglas Gregorc3366a52009-04-21 23:56:24 +00001319 while (true) {
1320 unsigned Code = Stream.ReadCode();
1321 switch (Code) {
1322 case llvm::bitc::END_BLOCK:
1323 return;
1324
1325 case llvm::bitc::ENTER_SUBBLOCK:
1326 // No known subblocks, always skip them.
1327 Stream.ReadSubBlockID();
1328 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001329 Error("malformed block record in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001330 return;
1331 }
1332 continue;
Mike Stump11289f42009-09-09 15:08:12 +00001333
Douglas Gregorc3366a52009-04-21 23:56:24 +00001334 case llvm::bitc::DEFINE_ABBREV:
1335 Stream.ReadAbbrevRecord();
1336 continue;
1337 default: break;
1338 }
1339
1340 // Read a record.
1341 Record.clear();
Sebastian Redl539c5062010-08-18 23:57:32 +00001342 PreprocessorRecordTypes RecType =
1343 (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001344 switch (RecType) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001345 case PP_MACRO_OBJECT_LIKE:
1346 case PP_MACRO_FUNCTION_LIKE: {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001347 // If we already have a macro, that means that we've hit the end
1348 // of the definition of the macro we were looking for. We're
1349 // done.
1350 if (Macro)
1351 return;
1352
1353 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
1354 if (II == 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001355 Error("macro must have a name in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001356 return;
1357 }
1358 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1359 bool isUsed = Record[2];
Mike Stump11289f42009-09-09 15:08:12 +00001360
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001361 MacroInfo *MI = PP->AllocateMacroInfo(Loc);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001362 MI->setIsUsed(isUsed);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001363 MI->setIsFromAST();
Mike Stump11289f42009-09-09 15:08:12 +00001364
Douglas Gregoraae92242010-03-19 21:51:54 +00001365 unsigned NextIndex = 3;
Sebastian Redl539c5062010-08-18 23:57:32 +00001366 if (RecType == PP_MACRO_FUNCTION_LIKE) {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001367 // Decode function-like macro info.
1368 bool isC99VarArgs = Record[3];
1369 bool isGNUVarArgs = Record[4];
1370 MacroArgs.clear();
1371 unsigned NumArgs = Record[5];
Douglas Gregoraae92242010-03-19 21:51:54 +00001372 NextIndex = 6 + NumArgs;
Douglas Gregorc3366a52009-04-21 23:56:24 +00001373 for (unsigned i = 0; i != NumArgs; ++i)
1374 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
1375
1376 // Install function-like macro info.
1377 MI->setIsFunctionLike();
1378 if (isC99VarArgs) MI->setIsC99Varargs();
1379 if (isGNUVarArgs) MI->setIsGNUVarargs();
Douglas Gregor038c3382009-05-22 22:45:36 +00001380 MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001381 PP->getPreprocessorAllocator());
Douglas Gregorc3366a52009-04-21 23:56:24 +00001382 }
1383
1384 // Finally, install the macro.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001385 PP->setMacroInfo(II, MI);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001386
1387 // Remember that we saw this macro last so that we add the tokens that
1388 // form its body to it.
1389 Macro = MI;
Douglas Gregoraae92242010-03-19 21:51:54 +00001390
1391 if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
1392 // We have a macro definition. Load it now.
1393 PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
1394 getMacroDefinition(Record[NextIndex]));
1395 }
1396
Douglas Gregorc3366a52009-04-21 23:56:24 +00001397 ++NumMacrosRead;
1398 break;
1399 }
Mike Stump11289f42009-09-09 15:08:12 +00001400
Sebastian Redl539c5062010-08-18 23:57:32 +00001401 case PP_TOKEN: {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001402 // If we see a TOKEN before a PP_MACRO_*, then the file is
1403 // erroneous, just pretend we didn't see this.
1404 if (Macro == 0) break;
Mike Stump11289f42009-09-09 15:08:12 +00001405
Douglas Gregorc3366a52009-04-21 23:56:24 +00001406 Token Tok;
1407 Tok.startToken();
1408 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1409 Tok.setLength(Record[1]);
1410 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1411 Tok.setIdentifierInfo(II);
1412 Tok.setKind((tok::TokenKind)Record[3]);
1413 Tok.setFlag((Token::TokenFlags)Record[4]);
1414 Macro->AddTokenToBody(Tok);
1415 break;
1416 }
Douglas Gregoraae92242010-03-19 21:51:54 +00001417
Sebastian Redl539c5062010-08-18 23:57:32 +00001418 case PP_MACRO_INSTANTIATION: {
Douglas Gregoraae92242010-03-19 21:51:54 +00001419 // If we already have a macro, that means that we've hit the end
1420 // of the definition of the macro we were looking for. We're
1421 // done.
1422 if (Macro)
1423 return;
1424
1425 if (!PP->getPreprocessingRecord()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001426 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-03-19 21:51:54 +00001427 return;
1428 }
1429
1430 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1431 if (PPRec.getPreprocessedEntity(Record[0]))
1432 return;
1433
1434 MacroInstantiation *MI
1435 = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
1436 SourceRange(
1437 SourceLocation::getFromRawEncoding(Record[1]),
1438 SourceLocation::getFromRawEncoding(Record[2])),
1439 getMacroDefinition(Record[4]));
1440 PPRec.SetPreallocatedEntity(Record[0], MI);
1441 return;
1442 }
1443
Sebastian Redl539c5062010-08-18 23:57:32 +00001444 case PP_MACRO_DEFINITION: {
Douglas Gregoraae92242010-03-19 21:51:54 +00001445 // If we already have a macro, that means that we've hit the end
1446 // of the definition of the macro we were looking for. We're
1447 // done.
1448 if (Macro)
1449 return;
1450
1451 if (!PP->getPreprocessingRecord()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001452 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-03-19 21:51:54 +00001453 return;
1454 }
1455
1456 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1457 if (PPRec.getPreprocessedEntity(Record[0]))
1458 return;
1459
1460 if (Record[1] >= MacroDefinitionsLoaded.size()) {
1461 Error("out-of-bounds macro definition record");
1462 return;
1463 }
1464
1465 MacroDefinition *MD
1466 = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
1467 SourceLocation::getFromRawEncoding(Record[5]),
1468 SourceRange(
1469 SourceLocation::getFromRawEncoding(Record[2]),
1470 SourceLocation::getFromRawEncoding(Record[3])));
1471 PPRec.SetPreallocatedEntity(Record[0], MD);
1472 MacroDefinitionsLoaded[Record[1]] = MD;
1473 return;
1474 }
Steve Naroff3fa455a2009-04-24 20:03:17 +00001475 }
Douglas Gregorc3366a52009-04-21 23:56:24 +00001476 }
1477}
1478
Sebastian Redl2c499f62010-08-18 23:56:43 +00001479void ASTReader::ReadDefinedMacros() {
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001480 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1481 llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
Sebastian Redl34522812010-07-16 17:50:48 +00001482
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001483 // If there was no preprocessor block, skip this file.
1484 if (!MacroCursor.getBitStreamReader())
1485 continue;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001486
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001487 llvm::BitstreamCursor Cursor = MacroCursor;
Sebastian Redl539c5062010-08-18 23:57:32 +00001488 if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001489 Error("malformed preprocessor block record in AST file");
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001490 return;
1491 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001492
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001493 RecordData Record;
1494 while (true) {
1495 unsigned Code = Cursor.ReadCode();
1496 if (Code == llvm::bitc::END_BLOCK) {
1497 if (Cursor.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001498 Error("error at end of preprocessor block in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001499 return;
1500 }
1501 break;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001502 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001503
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001504 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1505 // No known subblocks, always skip them.
1506 Cursor.ReadSubBlockID();
1507 if (Cursor.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001508 Error("malformed block record in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001509 return;
1510 }
1511 continue;
1512 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001513
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001514 if (Code == llvm::bitc::DEFINE_ABBREV) {
1515 Cursor.ReadAbbrevRecord();
1516 continue;
1517 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001518
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001519 // Read a record.
1520 const char *BlobStart;
1521 unsigned BlobLen;
1522 Record.clear();
1523 switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1524 default: // Default behavior: ignore.
1525 break;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001526
Sebastian Redl539c5062010-08-18 23:57:32 +00001527 case PP_MACRO_OBJECT_LIKE:
1528 case PP_MACRO_FUNCTION_LIKE:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001529 DecodeIdentifierInfo(Record[0]);
1530 break;
1531
Sebastian Redl539c5062010-08-18 23:57:32 +00001532 case PP_TOKEN:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001533 // Ignore tokens.
1534 break;
Douglas Gregoraae92242010-03-19 21:51:54 +00001535
Sebastian Redl539c5062010-08-18 23:57:32 +00001536 case PP_MACRO_INSTANTIATION:
1537 case PP_MACRO_DEFINITION:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001538 // Read the macro record.
1539 ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
1540 break;
1541 }
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001542 }
1543 }
1544}
1545
Sebastian Redl539c5062010-08-18 23:57:32 +00001546MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) {
Douglas Gregoraae92242010-03-19 21:51:54 +00001547 if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
1548 return 0;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001549
1550 if (!MacroDefinitionsLoaded[ID]) {
1551 unsigned Index = ID;
1552 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1553 PerFileData &F = *Chain[N - I - 1];
1554 if (Index < F.LocalNumMacroDefinitions) {
1555 ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
1556 break;
1557 }
1558 Index -= F.LocalNumMacroDefinitions;
1559 }
1560 assert(MacroDefinitionsLoaded[ID] && "Broken chain");
1561 }
1562
Douglas Gregoraae92242010-03-19 21:51:54 +00001563 return MacroDefinitionsLoaded[ID];
1564}
1565
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001566/// \brief If we are loading a relocatable PCH file, and the filename is
1567/// not an absolute path, add the system root to the beginning of the file
1568/// name.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001569void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001570 // If this is not a relocatable PCH file, there's nothing to do.
1571 if (!RelocatablePCH)
1572 return;
Mike Stump11289f42009-09-09 15:08:12 +00001573
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +00001574 if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001575 return;
1576
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001577 if (isysroot == 0) {
1578 // If no system root was given, default to '/'
1579 Filename.insert(Filename.begin(), '/');
1580 return;
1581 }
Mike Stump11289f42009-09-09 15:08:12 +00001582
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001583 unsigned Length = strlen(isysroot);
1584 if (isysroot[Length - 1] != '/')
1585 Filename.insert(Filename.begin(), '/');
Mike Stump11289f42009-09-09 15:08:12 +00001586
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001587 Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1588}
1589
Sebastian Redl2c499f62010-08-18 23:56:43 +00001590ASTReader::ASTReadResult
Sebastian Redl3e31c722010-08-18 23:56:56 +00001591ASTReader::ReadASTBlock(PerFileData &F) {
Sebastian Redl34522812010-07-16 17:50:48 +00001592 llvm::BitstreamCursor &Stream = F.Stream;
1593
Sebastian Redl539c5062010-08-18 23:57:32 +00001594 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001595 Error("malformed block record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001596 return Failure;
1597 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001598
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001599 // Read all of the records and blocks for the ASt file.
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001600 RecordData Record;
Sebastian Redl393f8b72010-07-19 20:52:06 +00001601 bool First = true;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001602 while (!Stream.AtEndOfStream()) {
1603 unsigned Code = Stream.ReadCode();
1604 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor55abb232009-04-10 20:39:37 +00001605 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001606 Error("error at end of module block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001607 return Failure;
1608 }
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001609
Douglas Gregor55abb232009-04-10 20:39:37 +00001610 return Success;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001611 }
1612
1613 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1614 switch (Stream.ReadSubBlockID()) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001615 case DECLTYPES_BLOCK_ID:
Chris Lattnere78a6be2009-04-27 01:05:14 +00001616 // We lazily load the decls block, but we want to set up the
1617 // DeclsCursor cursor to point into it. Clone our current bitcode
1618 // cursor to it, enter the block and read the abbrevs in that block.
1619 // With the main cursor, we just skip over it.
Sebastian Redl34522812010-07-16 17:50:48 +00001620 F.DeclsCursor = Stream;
Chris Lattnere78a6be2009-04-27 01:05:14 +00001621 if (Stream.SkipBlock() || // Skip with the main cursor.
1622 // Read the abbrevs.
Sebastian Redl539c5062010-08-18 23:57:32 +00001623 ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001624 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001625 return Failure;
1626 }
1627 break;
Mike Stump11289f42009-09-09 15:08:12 +00001628
Sebastian Redl539c5062010-08-18 23:57:32 +00001629 case PREPROCESSOR_BLOCK_ID:
Sebastian Redl34522812010-07-16 17:50:48 +00001630 F.MacroCursor = Stream;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001631 if (PP)
1632 PP->setExternalSource(this);
1633
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001634 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001635 Error("malformed block record in AST file");
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001636 return Failure;
1637 }
1638 break;
Steve Naroff2ddea052009-04-23 10:39:46 +00001639
Sebastian Redl539c5062010-08-18 23:57:32 +00001640 case SOURCE_MANAGER_BLOCK_ID:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001641 switch (ReadSourceManagerBlock(F)) {
Douglas Gregor92863e42009-04-10 23:10:45 +00001642 case Success:
1643 break;
1644
1645 case Failure:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001646 Error("malformed source manager block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001647 return Failure;
Douglas Gregor92863e42009-04-10 23:10:45 +00001648
1649 case IgnorePCH:
1650 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00001651 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001652 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001653 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001654 First = false;
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001655 continue;
1656 }
1657
1658 if (Code == llvm::bitc::DEFINE_ABBREV) {
1659 Stream.ReadAbbrevRecord();
1660 continue;
1661 }
1662
1663 // Read and process a record.
1664 Record.clear();
Douglas Gregorbfbde532009-04-10 21:16:55 +00001665 const char *BlobStart = 0;
1666 unsigned BlobLen = 0;
Sebastian Redl539c5062010-08-18 23:57:32 +00001667 switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
Douglas Gregorbfbde532009-04-10 21:16:55 +00001668 &BlobStart, &BlobLen)) {
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001669 default: // Default behavior: ignore.
1670 break;
1671
Sebastian Redl539c5062010-08-18 23:57:32 +00001672 case METADATA: {
1673 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1674 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001675 : diag::warn_pch_version_too_new);
1676 return IgnorePCH;
1677 }
1678
1679 RelocatablePCH = Record[4];
1680 if (Listener) {
1681 std::string TargetTriple(BlobStart, BlobLen);
1682 if (Listener->ReadTargetTriple(TargetTriple))
1683 return IgnorePCH;
1684 }
1685 break;
1686 }
1687
Sebastian Redl539c5062010-08-18 23:57:32 +00001688 case CHAINED_METADATA: {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001689 if (!First) {
1690 Error("CHAINED_METADATA is not first record in block");
1691 return Failure;
1692 }
Sebastian Redl539c5062010-08-18 23:57:32 +00001693 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1694 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001695 : diag::warn_pch_version_too_new);
1696 return IgnorePCH;
1697 }
1698
1699 // Load the chained file.
Sebastian Redl3e31c722010-08-18 23:56:56 +00001700 switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001701 case Failure: return Failure;
1702 // If we have to ignore the dependency, we'll have to ignore this too.
1703 case IgnorePCH: return IgnorePCH;
1704 case Success: break;
1705 }
1706 break;
1707 }
1708
Sebastian Redl539c5062010-08-18 23:57:32 +00001709 case TYPE_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001710 if (F.LocalNumTypes != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001711 Error("duplicate TYPE_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001712 return Failure;
1713 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001714 F.TypeOffsets = (const uint32_t *)BlobStart;
1715 F.LocalNumTypes = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001716 break;
1717
Sebastian Redl539c5062010-08-18 23:57:32 +00001718 case DECL_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001719 if (F.LocalNumDecls != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001720 Error("duplicate DECL_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001721 return Failure;
1722 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001723 F.DeclOffsets = (const uint32_t *)BlobStart;
1724 F.LocalNumDecls = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001725 break;
Douglas Gregor55abb232009-04-10 20:39:37 +00001726
Sebastian Redl539c5062010-08-18 23:57:32 +00001727 case TU_UPDATE_LEXICAL: {
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001728 DeclContextInfo Info = {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00001729 /* No visible information */ 0,
Sebastian Redl539c5062010-08-18 23:57:32 +00001730 reinterpret_cast<const DeclID *>(BlobStart),
1731 BlobLen / sizeof(DeclID)
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001732 };
1733 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1734 break;
1735 }
1736
Sebastian Redld7dce0a2010-08-24 00:50:04 +00001737 case UPDATE_VISIBLE: {
1738 serialization::DeclID ID = Record[0];
1739 void *Table = ASTDeclContextNameLookupTable::Create(
1740 (const unsigned char *)BlobStart + Record[1],
1741 (const unsigned char *)BlobStart,
1742 ASTDeclContextNameLookupTrait(*this));
1743 if (ID == 1) { // Is it the TU?
1744 DeclContextInfo Info = {
1745 Table, /* No lexical inforamtion */ 0, 0
1746 };
1747 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1748 } else
1749 PendingVisibleUpdates[ID].push_back(Table);
1750 break;
1751 }
1752
Sebastian Redl539c5062010-08-18 23:57:32 +00001753 case REDECLS_UPDATE_LATEST: {
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00001754 assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
1755 for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001756 DeclID First = Record[i], Latest = Record[i+1];
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00001757 assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
1758 Latest > FirstLatestDeclIDs[First]) &&
1759 "The new latest is supposed to come after the previous latest");
1760 FirstLatestDeclIDs[First] = Latest;
1761 }
1762 break;
1763 }
1764
Sebastian Redl539c5062010-08-18 23:57:32 +00001765 case LANGUAGE_OPTIONS:
Douglas Gregorce3a8292010-07-27 00:27:13 +00001766 if (ParseLanguageOptions(Record) && !DisableValidation)
Douglas Gregor55abb232009-04-10 20:39:37 +00001767 return IgnorePCH;
1768 break;
Douglas Gregorbfbde532009-04-10 21:16:55 +00001769
Sebastian Redl539c5062010-08-18 23:57:32 +00001770 case IDENTIFIER_TABLE:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001771 F.IdentifierTableData = BlobStart;
Douglas Gregor0e149972009-04-25 19:10:14 +00001772 if (Record[0]) {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001773 F.IdentifierLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001774 = ASTIdentifierLookupTable::Create(
Sebastian Redl393f8b72010-07-19 20:52:06 +00001775 (const unsigned char *)F.IdentifierTableData + Record[0],
1776 (const unsigned char *)F.IdentifierTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001777 ASTIdentifierLookupTrait(*this, F.Stream));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001778 if (PP)
1779 PP->getIdentifierTable().setExternalIdentifierLookup(this);
Douglas Gregor0e149972009-04-25 19:10:14 +00001780 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001781 break;
1782
Sebastian Redl539c5062010-08-18 23:57:32 +00001783 case IDENTIFIER_OFFSET:
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001784 if (F.LocalNumIdentifiers != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001785 Error("duplicate IDENTIFIER_OFFSET record in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001786 return Failure;
1787 }
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001788 F.IdentifierOffsets = (const uint32_t *)BlobStart;
1789 F.LocalNumIdentifiers = Record[0];
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001790 break;
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00001791
Sebastian Redl539c5062010-08-18 23:57:32 +00001792 case EXTERNAL_DEFINITIONS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001793 // Optimization for the first block.
1794 if (ExternalDefinitions.empty())
1795 ExternalDefinitions.swap(Record);
1796 else
1797 ExternalDefinitions.insert(ExternalDefinitions.end(),
1798 Record.begin(), Record.end());
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00001799 break;
Douglas Gregor08f01292009-04-17 22:13:46 +00001800
Sebastian Redl539c5062010-08-18 23:57:32 +00001801 case SPECIAL_TYPES:
Sebastian Redlb293a452010-07-20 21:20:32 +00001802 // Optimization for the first block
1803 if (SpecialTypes.empty())
1804 SpecialTypes.swap(Record);
1805 else
1806 SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
Douglas Gregor652d82a2009-04-18 05:55:16 +00001807 break;
1808
Sebastian Redl539c5062010-08-18 23:57:32 +00001809 case STATISTICS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001810 TotalNumStatements += Record[0];
1811 TotalNumMacros += Record[1];
1812 TotalLexicalDeclContexts += Record[2];
1813 TotalVisibleDeclContexts += Record[3];
Douglas Gregor08f01292009-04-17 22:13:46 +00001814 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001815
Sebastian Redl539c5062010-08-18 23:57:32 +00001816 case TENTATIVE_DEFINITIONS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001817 // Optimization for the first block.
1818 if (TentativeDefinitions.empty())
1819 TentativeDefinitions.swap(Record);
1820 else
1821 TentativeDefinitions.insert(TentativeDefinitions.end(),
1822 Record.begin(), Record.end());
Douglas Gregord4df8652009-04-22 22:02:47 +00001823 break;
Douglas Gregoracfc76c2009-04-22 22:18:58 +00001824
Sebastian Redl539c5062010-08-18 23:57:32 +00001825 case UNUSED_FILESCOPED_DECLS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001826 // Optimization for the first block.
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001827 if (UnusedFileScopedDecls.empty())
1828 UnusedFileScopedDecls.swap(Record);
Sebastian Redlb293a452010-07-20 21:20:32 +00001829 else
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001830 UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
1831 Record.begin(), Record.end());
Tanya Lattner90073802010-02-12 00:07:30 +00001832 break;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001833
Sebastian Redl539c5062010-08-18 23:57:32 +00001834 case WEAK_UNDECLARED_IDENTIFIERS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001835 // Later blocks overwrite earlier ones.
1836 WeakUndeclaredIdentifiers.swap(Record);
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00001837 break;
1838
Sebastian Redl539c5062010-08-18 23:57:32 +00001839 case LOCALLY_SCOPED_EXTERNAL_DECLS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001840 // Optimization for the first block.
1841 if (LocallyScopedExternalDecls.empty())
1842 LocallyScopedExternalDecls.swap(Record);
1843 else
1844 LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
1845 Record.begin(), Record.end());
Douglas Gregoracfc76c2009-04-22 22:18:58 +00001846 break;
Douglas Gregorc78d3462009-04-24 21:10:55 +00001847
Sebastian Redl539c5062010-08-18 23:57:32 +00001848 case SELECTOR_OFFSETS:
Sebastian Redla19a67f2010-08-03 21:58:15 +00001849 F.SelectorOffsets = (const uint32_t *)BlobStart;
Sebastian Redlada023c2010-08-04 20:40:17 +00001850 F.LocalNumSelectors = Record[0];
Douglas Gregor95c13f52009-04-25 17:48:32 +00001851 break;
1852
Sebastian Redl539c5062010-08-18 23:57:32 +00001853 case METHOD_POOL:
Sebastian Redlada023c2010-08-04 20:40:17 +00001854 F.SelectorLookupTableData = (const unsigned char *)BlobStart;
Douglas Gregor95c13f52009-04-25 17:48:32 +00001855 if (Record[0])
Sebastian Redlada023c2010-08-04 20:40:17 +00001856 F.SelectorLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001857 = ASTSelectorLookupTable::Create(
Sebastian Redlada023c2010-08-04 20:40:17 +00001858 F.SelectorLookupTableData + Record[0],
1859 F.SelectorLookupTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001860 ASTSelectorLookupTrait(*this));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00001861 TotalNumMethodPoolEntries += Record[1];
Douglas Gregorc78d3462009-04-24 21:10:55 +00001862 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001863
Sebastian Redl539c5062010-08-18 23:57:32 +00001864 case REFERENCED_SELECTOR_POOL: {
Sebastian Redlada023c2010-08-04 20:40:17 +00001865 ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
1866 Record.begin(), Record.end());
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00001867 break;
Sebastian Redl66c5eef2010-07-27 00:17:23 +00001868 }
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00001869
Sebastian Redl539c5062010-08-18 23:57:32 +00001870 case PP_COUNTER_VALUE:
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001871 if (!Record.empty() && Listener)
1872 Listener->ReadCounter(Record[0]);
Douglas Gregoreda6a892009-04-26 00:07:37 +00001873 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001874
Sebastian Redl539c5062010-08-18 23:57:32 +00001875 case SOURCE_LOCATION_OFFSETS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001876 F.SLocOffsets = (const uint32_t *)BlobStart;
1877 F.LocalNumSLocEntries = Record[0];
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001878 // We cannot delay this until the entire chain is loaded, because then
1879 // source location preloads would also have to be delayed.
1880 // FIXME: Is there a reason not to do that?
Sebastian Redlb293a452010-07-20 21:20:32 +00001881 TotalNumSLocEntries += F.LocalNumSLocEntries;
Douglas Gregord54f3a12009-10-05 21:07:28 +00001882 SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
Douglas Gregor258ae542009-04-27 06:38:32 +00001883 break;
1884
Sebastian Redl539c5062010-08-18 23:57:32 +00001885 case SOURCE_LOCATION_PRELOADS:
Douglas Gregor258ae542009-04-27 06:38:32 +00001886 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
Sebastian Redl2c499f62010-08-18 23:56:43 +00001887 ASTReadResult Result = ReadSLocEntryRecord(Record[I]);
Douglas Gregor258ae542009-04-27 06:38:32 +00001888 if (Result != Success)
1889 return Result;
1890 }
1891 break;
Douglas Gregorc5046832009-04-27 18:38:38 +00001892
Sebastian Redl539c5062010-08-18 23:57:32 +00001893 case STAT_CACHE: {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001894 ASTStatCache *MyStatCache =
1895 new ASTStatCache((const unsigned char *)BlobStart + Record[0],
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001896 (const unsigned char *)BlobStart,
1897 NumStatHits, NumStatMisses);
1898 FileMgr.addStatCache(MyStatCache);
Sebastian Redl34522812010-07-16 17:50:48 +00001899 F.StatCache = MyStatCache;
Douglas Gregorc5046832009-04-27 18:38:38 +00001900 break;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001901 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001902
Sebastian Redl539c5062010-08-18 23:57:32 +00001903 case EXT_VECTOR_DECLS:
Sebastian Redl04f5c312010-07-28 21:38:49 +00001904 // Optimization for the first block.
1905 if (ExtVectorDecls.empty())
1906 ExtVectorDecls.swap(Record);
1907 else
1908 ExtVectorDecls.insert(ExtVectorDecls.end(),
1909 Record.begin(), Record.end());
Douglas Gregor61cac2b2009-04-27 20:06:05 +00001910 break;
1911
Sebastian Redl539c5062010-08-18 23:57:32 +00001912 case VTABLE_USES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001913 // Later tables overwrite earlier ones.
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001914 VTableUses.swap(Record);
1915 break;
1916
Sebastian Redl539c5062010-08-18 23:57:32 +00001917 case DYNAMIC_CLASSES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001918 // Optimization for the first block.
1919 if (DynamicClasses.empty())
1920 DynamicClasses.swap(Record);
1921 else
1922 DynamicClasses.insert(DynamicClasses.end(),
1923 Record.begin(), Record.end());
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001924 break;
1925
Sebastian Redl539c5062010-08-18 23:57:32 +00001926 case PENDING_IMPLICIT_INSTANTIATIONS:
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00001927 // Optimization for the first block.
1928 if (PendingImplicitInstantiations.empty())
1929 PendingImplicitInstantiations.swap(Record);
1930 else
1931 PendingImplicitInstantiations.insert(
1932 PendingImplicitInstantiations.end(), Record.begin(), Record.end());
1933 break;
1934
Sebastian Redl539c5062010-08-18 23:57:32 +00001935 case SEMA_DECL_REFS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001936 // Later tables overwrite earlier ones.
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00001937 SemaDeclRefs.swap(Record);
1938 break;
1939
Sebastian Redl539c5062010-08-18 23:57:32 +00001940 case ORIGINAL_FILE_NAME:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001941 // The primary AST will be the last to get here, so it will be the one
Sebastian Redlb293a452010-07-20 21:20:32 +00001942 // that's used.
Daniel Dunbar000c4ff2009-11-11 05:29:04 +00001943 ActualOriginalFileName.assign(BlobStart, BlobLen);
1944 OriginalFileName = ActualOriginalFileName;
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001945 MaybeAddSystemRootToFilename(OriginalFileName);
Douglas Gregor45fe0362009-05-12 01:31:05 +00001946 break;
Mike Stump11289f42009-09-09 15:08:12 +00001947
Sebastian Redl539c5062010-08-18 23:57:32 +00001948 case VERSION_CONTROL_BRANCH_REVISION: {
Ted Kremenek8bd09292010-02-12 23:31:14 +00001949 const std::string &CurBranch = getClangFullRepositoryVersion();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001950 llvm::StringRef ASTBranch(BlobStart, BlobLen);
1951 if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
1952 Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
Douglas Gregord54f3a12009-10-05 21:07:28 +00001953 return IgnorePCH;
1954 }
1955 break;
1956 }
Sebastian Redlfa061442010-07-21 20:07:32 +00001957
Sebastian Redl539c5062010-08-18 23:57:32 +00001958 case MACRO_DEFINITION_OFFSETS:
Sebastian Redlfa061442010-07-21 20:07:32 +00001959 F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
1960 F.NumPreallocatedPreprocessingEntities = Record[0];
1961 F.LocalNumMacroDefinitions = Record[1];
Douglas Gregoraae92242010-03-19 21:51:54 +00001962 break;
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001963
Sebastian Redl539c5062010-08-18 23:57:32 +00001964 case DECL_REPLACEMENTS: {
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001965 if (Record.size() % 2 != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001966 Error("invalid DECL_REPLACEMENTS block in AST file");
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001967 return Failure;
1968 }
1969 for (unsigned I = 0, N = Record.size(); I != N; I += 2)
Sebastian Redl539c5062010-08-18 23:57:32 +00001970 ReplacedDecls[static_cast<DeclID>(Record[I])] =
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001971 std::make_pair(&F, Record[I+1]);
1972 break;
1973 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001974 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001975 First = false;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001976 }
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001977 Error("premature end of bitstream in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001978 return Failure;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001979}
1980
Sebastian Redl3e31c722010-08-18 23:56:56 +00001981ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
1982 switch(ReadASTCore(FileName)) {
Sebastian Redl2abc0382010-07-16 20:41:52 +00001983 case Failure: return Failure;
1984 case IgnorePCH: return IgnorePCH;
1985 case Success: break;
1986 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001987
1988 // Here comes stuff that we only do once the entire chain is loaded.
1989
Sebastian Redlb293a452010-07-20 21:20:32 +00001990 // Allocate space for loaded identifiers, decls and types.
Sebastian Redlfa061442010-07-21 20:07:32 +00001991 unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
Sebastian Redlada023c2010-08-04 20:40:17 +00001992 TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
1993 TotalNumSelectors = 0;
Sebastian Redl9e687992010-07-19 22:06:55 +00001994 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001995 TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
Sebastian Redl9e687992010-07-19 22:06:55 +00001996 TotalNumTypes += Chain[I]->LocalNumTypes;
1997 TotalNumDecls += Chain[I]->LocalNumDecls;
Sebastian Redlfa061442010-07-21 20:07:32 +00001998 TotalNumPreallocatedPreprocessingEntities +=
1999 Chain[I]->NumPreallocatedPreprocessingEntities;
2000 TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
Sebastian Redlada023c2010-08-04 20:40:17 +00002001 TotalNumSelectors += Chain[I]->LocalNumSelectors;
Sebastian Redl9e687992010-07-19 22:06:55 +00002002 }
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00002003 IdentifiersLoaded.resize(TotalNumIdentifiers);
Sebastian Redl9e687992010-07-19 22:06:55 +00002004 TypesLoaded.resize(TotalNumTypes);
2005 DeclsLoaded.resize(TotalNumDecls);
Sebastian Redlfa061442010-07-21 20:07:32 +00002006 MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
2007 if (PP) {
2008 if (TotalNumIdentifiers > 0)
2009 PP->getHeaderSearchInfo().SetExternalLookup(this);
2010 if (TotalNumPreallocatedPreprocessingEntities > 0) {
2011 if (!PP->getPreprocessingRecord())
2012 PP->createPreprocessingRecord();
2013 PP->getPreprocessingRecord()->SetExternalSource(*this,
2014 TotalNumPreallocatedPreprocessingEntities);
2015 }
2016 }
Sebastian Redlada023c2010-08-04 20:40:17 +00002017 SelectorsLoaded.resize(TotalNumSelectors);
Sebastian Redl9e687992010-07-19 22:06:55 +00002018
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002019 // Check the predefines buffers.
Douglas Gregorce3a8292010-07-27 00:27:13 +00002020 if (!DisableValidation && CheckPredefinesBuffers())
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002021 return IgnorePCH;
2022
2023 if (PP) {
2024 // Initialization of keywords and pragmas occurs before the
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002025 // AST file is read, so there may be some identifiers that were
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002026 // loaded into the IdentifierTable before we intercepted the
2027 // creation of identifiers. Iterate through the list of known
2028 // identifiers and determine whether we have to establish
2029 // preprocessor definitions or top-level identifier declaration
2030 // chains for those identifiers.
2031 //
2032 // We copy the IdentifierInfo pointers to a small vector first,
2033 // since de-serializing declarations or macro definitions can add
2034 // new entries into the identifier table, invalidating the
2035 // iterators.
2036 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
2037 for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
2038 IdEnd = PP->getIdentifierTable().end();
2039 Id != IdEnd; ++Id)
2040 Identifiers.push_back(Id->second);
Sebastian Redlfa061442010-07-21 20:07:32 +00002041 // We need to search the tables in all files.
Sebastian Redlfa061442010-07-21 20:07:32 +00002042 for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002043 ASTIdentifierLookupTable *IdTable
2044 = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
2045 // Not all AST files necessarily have identifier tables, only the useful
Sebastian Redl5c415f32010-07-22 17:01:13 +00002046 // ones.
2047 if (!IdTable)
2048 continue;
Sebastian Redlfa061442010-07-21 20:07:32 +00002049 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
2050 IdentifierInfo *II = Identifiers[I];
2051 // Look in the on-disk hash tables for an entry for this identifier
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002052 ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
Sebastian Redlfa061442010-07-21 20:07:32 +00002053 std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002054 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
Sebastian Redlb293a452010-07-20 21:20:32 +00002055 if (Pos == IdTable->end())
2056 continue;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002057
Sebastian Redlb293a452010-07-20 21:20:32 +00002058 // Dereferencing the iterator has the effect of populating the
2059 // IdentifierInfo node with the various declarations it needs.
2060 (void)*Pos;
2061 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002062 }
2063 }
2064
2065 if (Context)
2066 InitializeContext(*Context);
2067
2068 return Success;
2069}
2070
Sebastian Redl3e31c722010-08-18 23:56:56 +00002071ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002072 Chain.push_back(new PerFileData());
Sebastian Redl34522812010-07-16 17:50:48 +00002073 PerFileData &F = *Chain.back();
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002074
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002075 // Set the AST file name.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002076 F.FileName = FileName;
2077
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002078 // Open the AST file.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002079 //
2080 // FIXME: This shouldn't be here, we should just take a raw_ostream.
2081 std::string ErrStr;
2082 F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
2083 if (!F.Buffer) {
2084 Error(ErrStr.c_str());
2085 return IgnorePCH;
2086 }
2087
2088 // Initialize the stream
2089 F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
2090 (const unsigned char *)F.Buffer->getBufferEnd());
Sebastian Redl34522812010-07-16 17:50:48 +00002091 llvm::BitstreamCursor &Stream = F.Stream;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002092 Stream.init(F.StreamFile);
Sebastian Redlfa061442010-07-21 20:07:32 +00002093 F.SizeInBits = F.Buffer->getBufferSize() * 8;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002094
2095 // Sniff for the signature.
2096 if (Stream.Read(8) != 'C' ||
2097 Stream.Read(8) != 'P' ||
2098 Stream.Read(8) != 'C' ||
2099 Stream.Read(8) != 'H') {
2100 Diag(diag::err_not_a_pch_file) << FileName;
2101 return Failure;
2102 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002103
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002104 while (!Stream.AtEndOfStream()) {
2105 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002106
Douglas Gregor92863e42009-04-10 23:10:45 +00002107 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002108 Error("invalid record at top-level of AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002109 return Failure;
2110 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002111
2112 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregora868bbd2009-04-21 22:25:48 +00002113
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002114 // We only know the AST subblock ID.
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002115 switch (BlockID) {
2116 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregor92863e42009-04-10 23:10:45 +00002117 if (Stream.ReadBlockInfoBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002118 Error("malformed BlockInfoBlock in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002119 return Failure;
2120 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002121 break;
Sebastian Redl539c5062010-08-18 23:57:32 +00002122 case AST_BLOCK_ID:
Sebastian Redl3e31c722010-08-18 23:56:56 +00002123 switch (ReadASTBlock(F)) {
Douglas Gregor55abb232009-04-10 20:39:37 +00002124 case Success:
2125 break;
2126
2127 case Failure:
Douglas Gregor92863e42009-04-10 23:10:45 +00002128 return Failure;
Douglas Gregor55abb232009-04-10 20:39:37 +00002129
2130 case IgnorePCH:
Douglas Gregorbfbde532009-04-10 21:16:55 +00002131 // FIXME: We could consider reading through to the end of this
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002132 // AST block, skipping subblocks, to see if there are other
2133 // AST blocks elsewhere.
Douglas Gregor0bc12932009-04-27 21:28:04 +00002134
2135 // Clear out any preallocated source location entries, so that
2136 // the source manager does not try to resolve them later.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002137 SourceMgr.ClearPreallocatedSLocEntries();
Douglas Gregor0bc12932009-04-27 21:28:04 +00002138
2139 // Remove the stat cache.
Sebastian Redl34522812010-07-16 17:50:48 +00002140 if (F.StatCache)
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002141 FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
Douglas Gregor0bc12932009-04-27 21:28:04 +00002142
Douglas Gregor92863e42009-04-10 23:10:45 +00002143 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00002144 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002145 break;
2146 default:
Douglas Gregor92863e42009-04-10 23:10:45 +00002147 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002148 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002149 return Failure;
2150 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002151 break;
2152 }
Mike Stump11289f42009-09-09 15:08:12 +00002153 }
2154
Sebastian Redl2abc0382010-07-16 20:41:52 +00002155 return Success;
2156}
2157
Sebastian Redl2c499f62010-08-18 23:56:43 +00002158void ASTReader::setPreprocessor(Preprocessor &pp) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002159 PP = &pp;
Sebastian Redlfa061442010-07-21 20:07:32 +00002160
2161 unsigned TotalNum = 0;
2162 for (unsigned I = 0, N = Chain.size(); I != N; ++I)
2163 TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
2164 if (TotalNum) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002165 if (!PP->getPreprocessingRecord())
2166 PP->createPreprocessingRecord();
Sebastian Redlfa061442010-07-21 20:07:32 +00002167 PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
Douglas Gregoraae92242010-03-19 21:51:54 +00002168 }
2169}
2170
Sebastian Redl2c499f62010-08-18 23:56:43 +00002171void ASTReader::InitializeContext(ASTContext &Ctx) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002172 Context = &Ctx;
2173 assert(Context && "Passed null context!");
2174
2175 assert(PP && "Forgot to set Preprocessor ?");
2176 PP->getIdentifierTable().setExternalIdentifierLookup(this);
2177 PP->getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor9882a5a2010-01-04 19:18:44 +00002178 PP->setExternalSource(this);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00002179
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002180 // Load the translation unit declaration
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00002181 GetTranslationUnitDecl();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002182
2183 // Load the special types.
2184 Context->setBuiltinVaListType(
Sebastian Redl539c5062010-08-18 23:57:32 +00002185 GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
2186 if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002187 Context->setObjCIdType(GetType(Id));
Sebastian Redl539c5062010-08-18 23:57:32 +00002188 if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002189 Context->setObjCSelType(GetType(Sel));
Sebastian Redl539c5062010-08-18 23:57:32 +00002190 if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002191 Context->setObjCProtoType(GetType(Proto));
Sebastian Redl539c5062010-08-18 23:57:32 +00002192 if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002193 Context->setObjCClassType(GetType(Class));
Steve Naroff7cae42b2009-07-10 23:34:53 +00002194
Sebastian Redl539c5062010-08-18 23:57:32 +00002195 if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002196 Context->setCFConstantStringType(GetType(String));
Mike Stump11289f42009-09-09 15:08:12 +00002197 if (unsigned FastEnum
Sebastian Redl539c5062010-08-18 23:57:32 +00002198 = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002199 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
Sebastian Redl539c5062010-08-18 23:57:32 +00002200 if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
Douglas Gregor27821ce2009-07-07 16:35:42 +00002201 QualType FileType = GetType(File);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002202 if (FileType.isNull()) {
2203 Error("FILE type is NULL");
2204 return;
2205 }
John McCall9dd450b2009-09-21 23:43:11 +00002206 if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
Douglas Gregor27821ce2009-07-07 16:35:42 +00002207 Context->setFILEDecl(Typedef->getDecl());
2208 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002209 const TagType *Tag = FileType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002210 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002211 Error("Invalid FILE type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002212 return;
2213 }
Douglas Gregor27821ce2009-07-07 16:35:42 +00002214 Context->setFILEDecl(Tag->getDecl());
2215 }
2216 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002217 if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002218 QualType Jmp_bufType = GetType(Jmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002219 if (Jmp_bufType.isNull()) {
2220 Error("jmp_bug type is NULL");
2221 return;
2222 }
John McCall9dd450b2009-09-21 23:43:11 +00002223 if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002224 Context->setjmp_bufDecl(Typedef->getDecl());
2225 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002226 const TagType *Tag = Jmp_bufType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002227 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002228 Error("Invalid jmp_buf type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002229 return;
2230 }
Mike Stumpa4de80b2009-07-28 02:25:19 +00002231 Context->setjmp_bufDecl(Tag->getDecl());
2232 }
2233 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002234 if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002235 QualType Sigjmp_bufType = GetType(Sigjmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002236 if (Sigjmp_bufType.isNull()) {
2237 Error("sigjmp_buf type is NULL");
2238 return;
2239 }
John McCall9dd450b2009-09-21 23:43:11 +00002240 if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002241 Context->setsigjmp_bufDecl(Typedef->getDecl());
2242 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002243 const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002244 assert(Tag && "Invalid sigjmp_buf type in AST file");
Mike Stumpa4de80b2009-07-28 02:25:19 +00002245 Context->setsigjmp_bufDecl(Tag->getDecl());
2246 }
2247 }
Mike Stump11289f42009-09-09 15:08:12 +00002248 if (unsigned ObjCIdRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002249 = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002250 Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
Mike Stump11289f42009-09-09 15:08:12 +00002251 if (unsigned ObjCClassRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002252 = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002253 Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002254 if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Mike Stumpd0153282009-10-20 02:12:22 +00002255 Context->setBlockDescriptorType(GetType(String));
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002256 if (unsigned String
Sebastian Redl539c5062010-08-18 23:57:32 +00002257 = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002258 Context->setBlockDescriptorExtendedType(GetType(String));
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002259 if (unsigned ObjCSelRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002260 = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002261 Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002262 if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002263 Context->setNSConstantStringType(GetType(String));
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002264
Sebastian Redl539c5062010-08-18 23:57:32 +00002265 if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002266 Context->setInt128Installed();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002267}
2268
Douglas Gregor45fe0362009-05-12 01:31:05 +00002269/// \brief Retrieve the name of the original source file name
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002270/// directly from the AST file, without actually loading the AST
Douglas Gregor45fe0362009-05-12 01:31:05 +00002271/// file.
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002272std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
Daniel Dunbar3b951482009-12-03 09:13:06 +00002273 Diagnostic &Diags) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002274 // Open the AST file.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002275 std::string ErrStr;
2276 llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002277 Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr));
Douglas Gregor45fe0362009-05-12 01:31:05 +00002278 if (!Buffer) {
Daniel Dunbar3b951482009-12-03 09:13:06 +00002279 Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002280 return std::string();
2281 }
2282
2283 // Initialize the stream
2284 llvm::BitstreamReader StreamFile;
2285 llvm::BitstreamCursor Stream;
Mike Stump11289f42009-09-09 15:08:12 +00002286 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
Douglas Gregor45fe0362009-05-12 01:31:05 +00002287 (const unsigned char *)Buffer->getBufferEnd());
2288 Stream.init(StreamFile);
2289
2290 // Sniff for the signature.
2291 if (Stream.Read(8) != 'C' ||
2292 Stream.Read(8) != 'P' ||
2293 Stream.Read(8) != 'C' ||
2294 Stream.Read(8) != 'H') {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002295 Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002296 return std::string();
2297 }
2298
2299 RecordData Record;
2300 while (!Stream.AtEndOfStream()) {
2301 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002302
Douglas Gregor45fe0362009-05-12 01:31:05 +00002303 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2304 unsigned BlockID = Stream.ReadSubBlockID();
Mike Stump11289f42009-09-09 15:08:12 +00002305
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002306 // We only know the AST subblock ID.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002307 switch (BlockID) {
Sebastian Redl539c5062010-08-18 23:57:32 +00002308 case AST_BLOCK_ID:
2309 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002310 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002311 return std::string();
2312 }
2313 break;
Mike Stump11289f42009-09-09 15:08:12 +00002314
Douglas Gregor45fe0362009-05-12 01:31:05 +00002315 default:
2316 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002317 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002318 return std::string();
2319 }
2320 break;
2321 }
2322 continue;
2323 }
2324
2325 if (Code == llvm::bitc::END_BLOCK) {
2326 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002327 Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002328 return std::string();
2329 }
2330 continue;
2331 }
2332
2333 if (Code == llvm::bitc::DEFINE_ABBREV) {
2334 Stream.ReadAbbrevRecord();
2335 continue;
2336 }
2337
2338 Record.clear();
2339 const char *BlobStart = 0;
2340 unsigned BlobLen = 0;
Mike Stump11289f42009-09-09 15:08:12 +00002341 if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
Sebastian Redl539c5062010-08-18 23:57:32 +00002342 == ORIGINAL_FILE_NAME)
Douglas Gregor45fe0362009-05-12 01:31:05 +00002343 return std::string(BlobStart, BlobLen);
Mike Stump11289f42009-09-09 15:08:12 +00002344 }
Douglas Gregor45fe0362009-05-12 01:31:05 +00002345
2346 return std::string();
2347}
2348
Douglas Gregor55abb232009-04-10 20:39:37 +00002349/// \brief Parse the record that corresponds to a LangOptions data
2350/// structure.
2351///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002352/// This routine parses the language options from the AST file and then gives
2353/// them to the AST listener if one is set.
Douglas Gregor55abb232009-04-10 20:39:37 +00002354///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002355/// \returns true if the listener deems the file unacceptable, false otherwise.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002356bool ASTReader::ParseLanguageOptions(
Douglas Gregor55abb232009-04-10 20:39:37 +00002357 const llvm::SmallVectorImpl<uint64_t> &Record) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002358 if (Listener) {
2359 LangOptions LangOpts;
Mike Stump11289f42009-09-09 15:08:12 +00002360
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002361 #define PARSE_LANGOPT(Option) \
2362 LangOpts.Option = Record[Idx]; \
2363 ++Idx
Mike Stump11289f42009-09-09 15:08:12 +00002364
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002365 unsigned Idx = 0;
2366 PARSE_LANGOPT(Trigraphs);
2367 PARSE_LANGOPT(BCPLComment);
2368 PARSE_LANGOPT(DollarIdents);
2369 PARSE_LANGOPT(AsmPreprocessor);
2370 PARSE_LANGOPT(GNUMode);
Chandler Carruthe03aa552010-04-17 20:17:31 +00002371 PARSE_LANGOPT(GNUKeywords);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002372 PARSE_LANGOPT(ImplicitInt);
2373 PARSE_LANGOPT(Digraphs);
2374 PARSE_LANGOPT(HexFloats);
2375 PARSE_LANGOPT(C99);
2376 PARSE_LANGOPT(Microsoft);
2377 PARSE_LANGOPT(CPlusPlus);
2378 PARSE_LANGOPT(CPlusPlus0x);
2379 PARSE_LANGOPT(CXXOperatorNames);
2380 PARSE_LANGOPT(ObjC1);
2381 PARSE_LANGOPT(ObjC2);
2382 PARSE_LANGOPT(ObjCNonFragileABI);
Fariborz Jahanian45878032010-02-09 19:31:38 +00002383 PARSE_LANGOPT(ObjCNonFragileABI2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +00002384 PARSE_LANGOPT(NoConstantCFStrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002385 PARSE_LANGOPT(PascalStrings);
2386 PARSE_LANGOPT(WritableStrings);
2387 PARSE_LANGOPT(LaxVectorConversions);
Nate Begemanf2911662009-06-25 23:01:11 +00002388 PARSE_LANGOPT(AltiVec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002389 PARSE_LANGOPT(Exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +00002390 PARSE_LANGOPT(SjLjExceptions);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002391 PARSE_LANGOPT(NeXTRuntime);
2392 PARSE_LANGOPT(Freestanding);
2393 PARSE_LANGOPT(NoBuiltin);
2394 PARSE_LANGOPT(ThreadsafeStatics);
Douglas Gregorb3286fe2009-09-03 14:36:33 +00002395 PARSE_LANGOPT(POSIXThreads);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002396 PARSE_LANGOPT(Blocks);
2397 PARSE_LANGOPT(EmitAllDecls);
2398 PARSE_LANGOPT(MathErrno);
Chris Lattner51924e512010-06-26 21:25:03 +00002399 LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
2400 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002401 PARSE_LANGOPT(HeinousExtensions);
2402 PARSE_LANGOPT(Optimize);
2403 PARSE_LANGOPT(OptimizeSize);
2404 PARSE_LANGOPT(Static);
2405 PARSE_LANGOPT(PICLevel);
2406 PARSE_LANGOPT(GNUInline);
2407 PARSE_LANGOPT(NoInline);
2408 PARSE_LANGOPT(AccessControl);
2409 PARSE_LANGOPT(CharIsSigned);
John Thompsoned4e2952009-11-05 20:14:16 +00002410 PARSE_LANGOPT(ShortWChar);
Chris Lattner51924e512010-06-26 21:25:03 +00002411 LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
2412 LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
Daniel Dunbar143021e2009-09-21 04:16:19 +00002413 LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Chris Lattner51924e512010-06-26 21:25:03 +00002414 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002415 PARSE_LANGOPT(InstantiationDepth);
Nate Begemanf2911662009-06-25 23:01:11 +00002416 PARSE_LANGOPT(OpenCL);
Mike Stumpd9546382009-12-12 01:27:46 +00002417 PARSE_LANGOPT(CatchUndefined);
2418 // FIXME: Missing ElideConstructors?!
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002419 #undef PARSE_LANGOPT
Douglas Gregor55abb232009-04-10 20:39:37 +00002420
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002421 return Listener->ReadLanguageOptions(LangOpts);
Douglas Gregor55abb232009-04-10 20:39:37 +00002422 }
Douglas Gregor55abb232009-04-10 20:39:37 +00002423
2424 return false;
2425}
2426
Sebastian Redl2c499f62010-08-18 23:56:43 +00002427void ASTReader::ReadPreprocessedEntities() {
Douglas Gregoraae92242010-03-19 21:51:54 +00002428 ReadDefinedMacros();
2429}
2430
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002431/// \brief Get the correct cursor and offset for loading a type.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002432ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002433 PerFileData *F = 0;
2434 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
2435 F = Chain[N - I - 1];
2436 if (Index < F->LocalNumTypes)
2437 break;
2438 Index -= F->LocalNumTypes;
2439 }
2440 assert(F && F->LocalNumTypes > Index && "Broken chain");
Sebastian Redlb2831db2010-07-20 22:55:31 +00002441 return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002442}
2443
2444/// \brief Read and return the type with the given index..
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002445///
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002446/// The index is the type ID, shifted and minus the number of predefs. This
2447/// routine actually reads the record corresponding to the type at the given
2448/// location. It is a helper routine for GetType, which deals with reading type
2449/// IDs.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002450QualType ASTReader::ReadTypeRecord(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002451 RecordLocation Loc = TypeCursorForIndex(Index);
Sebastian Redlb2831db2010-07-20 22:55:31 +00002452 llvm::BitstreamCursor &DeclsCursor = *Loc.first;
Sebastian Redl34522812010-07-16 17:50:48 +00002453
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002454 // Keep track of where we are in the stream, then jump back there
2455 // after reading this type.
Douglas Gregor12bfa382009-10-17 00:13:19 +00002456 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002457
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00002458 ReadingKindTracker ReadingKind(Read_Type, *this);
Sebastian Redleaa4ade2010-08-11 18:52:41 +00002459
Douglas Gregor1342e842009-07-06 18:54:52 +00002460 // Note that we are loading a type record.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00002461 Deserializing AType(this);
Mike Stump11289f42009-09-09 15:08:12 +00002462
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002463 DeclsCursor.JumpToBit(Loc.second);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002464 RecordData Record;
Douglas Gregor12bfa382009-10-17 00:13:19 +00002465 unsigned Code = DeclsCursor.ReadCode();
Sebastian Redl539c5062010-08-18 23:57:32 +00002466 switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
2467 case TYPE_EXT_QUAL: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002468 if (Record.size() != 2) {
2469 Error("Incorrect encoding of extended qualifier type");
2470 return QualType();
2471 }
Douglas Gregor455b8f42009-04-15 22:00:08 +00002472 QualType Base = GetType(Record[0]);
John McCall8ccfcb52009-09-24 19:53:00 +00002473 Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
2474 return Context->getQualifiedType(Base, Quals);
Douglas Gregor455b8f42009-04-15 22:00:08 +00002475 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002476
Sebastian Redl539c5062010-08-18 23:57:32 +00002477 case TYPE_COMPLEX: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002478 if (Record.size() != 1) {
2479 Error("Incorrect encoding of complex type");
2480 return QualType();
2481 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002482 QualType ElemType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002483 return Context->getComplexType(ElemType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002484 }
2485
Sebastian Redl539c5062010-08-18 23:57:32 +00002486 case TYPE_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002487 if (Record.size() != 1) {
2488 Error("Incorrect encoding of pointer type");
2489 return QualType();
2490 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002491 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002492 return Context->getPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002493 }
2494
Sebastian Redl539c5062010-08-18 23:57:32 +00002495 case TYPE_BLOCK_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002496 if (Record.size() != 1) {
2497 Error("Incorrect encoding of block pointer type");
2498 return QualType();
2499 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002500 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002501 return Context->getBlockPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002502 }
2503
Sebastian Redl539c5062010-08-18 23:57:32 +00002504 case TYPE_LVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002505 if (Record.size() != 1) {
2506 Error("Incorrect encoding of lvalue reference type");
2507 return QualType();
2508 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002509 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002510 return Context->getLValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002511 }
2512
Sebastian Redl539c5062010-08-18 23:57:32 +00002513 case TYPE_RVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002514 if (Record.size() != 1) {
2515 Error("Incorrect encoding of rvalue reference type");
2516 return QualType();
2517 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002518 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002519 return Context->getRValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002520 }
2521
Sebastian Redl539c5062010-08-18 23:57:32 +00002522 case TYPE_MEMBER_POINTER: {
Argyrios Kyrtzidisee776bc2010-07-02 11:55:15 +00002523 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002524 Error("Incorrect encoding of member pointer type");
2525 return QualType();
2526 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002527 QualType PointeeType = GetType(Record[0]);
2528 QualType ClassType = GetType(Record[1]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002529 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002530 }
2531
Sebastian Redl539c5062010-08-18 23:57:32 +00002532 case TYPE_CONSTANT_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002533 QualType ElementType = GetType(Record[0]);
2534 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2535 unsigned IndexTypeQuals = Record[2];
2536 unsigned Idx = 3;
2537 llvm::APInt Size = ReadAPInt(Record, Idx);
Douglas Gregor04318252009-07-06 15:59:29 +00002538 return Context->getConstantArrayType(ElementType, Size,
2539 ASM, IndexTypeQuals);
2540 }
2541
Sebastian Redl539c5062010-08-18 23:57:32 +00002542 case TYPE_INCOMPLETE_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002543 QualType ElementType = GetType(Record[0]);
2544 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2545 unsigned IndexTypeQuals = Record[2];
Chris Lattner8575daa2009-04-27 21:45:14 +00002546 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002547 }
2548
Sebastian Redl539c5062010-08-18 23:57:32 +00002549 case TYPE_VARIABLE_ARRAY: {
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002550 QualType ElementType = GetType(Record[0]);
2551 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2552 unsigned IndexTypeQuals = Record[2];
Douglas Gregor04318252009-07-06 15:59:29 +00002553 SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
2554 SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002555 return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor),
Douglas Gregor04318252009-07-06 15:59:29 +00002556 ASM, IndexTypeQuals,
2557 SourceRange(LBLoc, RBLoc));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002558 }
2559
Sebastian Redl539c5062010-08-18 23:57:32 +00002560 case TYPE_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002561 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002562 Error("incorrect encoding of vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002563 return QualType();
2564 }
2565
2566 QualType ElementType = GetType(Record[0]);
2567 unsigned NumElements = Record[1];
Chris Lattner37141f42010-06-23 06:00:24 +00002568 unsigned AltiVecSpec = Record[2];
2569 return Context->getVectorType(ElementType, NumElements,
2570 (VectorType::AltiVecSpecific)AltiVecSpec);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002571 }
2572
Sebastian Redl539c5062010-08-18 23:57:32 +00002573 case TYPE_EXT_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002574 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002575 Error("incorrect encoding of extended vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002576 return QualType();
2577 }
2578
2579 QualType ElementType = GetType(Record[0]);
2580 unsigned NumElements = Record[1];
Chris Lattner8575daa2009-04-27 21:45:14 +00002581 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002582 }
2583
Sebastian Redl539c5062010-08-18 23:57:32 +00002584 case TYPE_FUNCTION_NO_PROTO: {
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002585 if (Record.size() != 4) {
Douglas Gregor6f00bf82009-04-28 21:53:25 +00002586 Error("incorrect encoding of no-proto function type");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002587 return QualType();
2588 }
2589 QualType ResultType = GetType(Record[0]);
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002590 FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002591 return Context->getFunctionNoProtoType(ResultType, Info);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002592 }
2593
Sebastian Redl539c5062010-08-18 23:57:32 +00002594 case TYPE_FUNCTION_PROTO: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002595 QualType ResultType = GetType(Record[0]);
Douglas Gregordc728752009-12-22 18:11:50 +00002596 bool NoReturn = Record[1];
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002597 unsigned RegParm = Record[2];
2598 CallingConv CallConv = (CallingConv)Record[3];
2599 unsigned Idx = 4;
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002600 unsigned NumParams = Record[Idx++];
2601 llvm::SmallVector<QualType, 16> ParamTypes;
2602 for (unsigned I = 0; I != NumParams; ++I)
2603 ParamTypes.push_back(GetType(Record[Idx++]));
2604 bool isVariadic = Record[Idx++];
2605 unsigned Quals = Record[Idx++];
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002606 bool hasExceptionSpec = Record[Idx++];
2607 bool hasAnyExceptionSpec = Record[Idx++];
2608 unsigned NumExceptions = Record[Idx++];
2609 llvm::SmallVector<QualType, 2> Exceptions;
2610 for (unsigned I = 0; I != NumExceptions; ++I)
2611 Exceptions.push_back(GetType(Record[Idx++]));
Jay Foad7d0479f2009-05-21 09:52:38 +00002612 return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002613 isVariadic, Quals, hasExceptionSpec,
2614 hasAnyExceptionSpec, NumExceptions,
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002615 Exceptions.data(),
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002616 FunctionType::ExtInfo(NoReturn, RegParm,
2617 CallConv));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002618 }
2619
Sebastian Redl539c5062010-08-18 23:57:32 +00002620 case TYPE_UNRESOLVED_USING:
John McCallb96ec562009-12-04 22:46:56 +00002621 return Context->getTypeDeclType(
2622 cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
2623
Sebastian Redl539c5062010-08-18 23:57:32 +00002624 case TYPE_TYPEDEF: {
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002625 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002626 Error("incorrect encoding of typedef type");
2627 return QualType();
2628 }
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002629 TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
2630 QualType Canonical = GetType(Record[1]);
2631 return Context->getTypedefType(Decl, Canonical);
2632 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002633
Sebastian Redl539c5062010-08-18 23:57:32 +00002634 case TYPE_TYPEOF_EXPR:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002635 return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002636
Sebastian Redl539c5062010-08-18 23:57:32 +00002637 case TYPE_TYPEOF: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002638 if (Record.size() != 1) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002639 Error("incorrect encoding of typeof(type) in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002640 return QualType();
2641 }
2642 QualType UnderlyingType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002643 return Context->getTypeOfType(UnderlyingType);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002644 }
Mike Stump11289f42009-09-09 15:08:12 +00002645
Sebastian Redl539c5062010-08-18 23:57:32 +00002646 case TYPE_DECLTYPE:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002647 return Context->getDecltypeType(ReadExpr(DeclsCursor));
Anders Carlsson81df7b82009-06-24 19:06:50 +00002648
Sebastian Redl539c5062010-08-18 23:57:32 +00002649 case TYPE_RECORD: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002650 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002651 Error("incorrect encoding of record type");
2652 return QualType();
2653 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002654 bool IsDependent = Record[0];
2655 QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
2656 T->Dependent = IsDependent;
2657 return T;
2658 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002659
Sebastian Redl539c5062010-08-18 23:57:32 +00002660 case TYPE_ENUM: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002661 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002662 Error("incorrect encoding of enum type");
2663 return QualType();
2664 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002665 bool IsDependent = Record[0];
2666 QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
2667 T->Dependent = IsDependent;
2668 return T;
2669 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00002670
Sebastian Redl539c5062010-08-18 23:57:32 +00002671 case TYPE_ELABORATED: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002672 unsigned Idx = 0;
2673 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2674 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2675 QualType NamedType = GetType(Record[Idx++]);
2676 return Context->getElaboratedType(Keyword, NNS, NamedType);
John McCallfcc33b02009-09-05 00:15:47 +00002677 }
2678
Sebastian Redl539c5062010-08-18 23:57:32 +00002679 case TYPE_OBJC_INTERFACE: {
Chris Lattner587cbe12009-04-22 06:45:28 +00002680 unsigned Idx = 0;
2681 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002682 return Context->getObjCInterfaceType(ItfD);
2683 }
2684
Sebastian Redl539c5062010-08-18 23:57:32 +00002685 case TYPE_OBJC_OBJECT: {
John McCall8b07ec22010-05-15 11:32:37 +00002686 unsigned Idx = 0;
2687 QualType Base = GetType(Record[Idx++]);
Chris Lattner587cbe12009-04-22 06:45:28 +00002688 unsigned NumProtos = Record[Idx++];
2689 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
2690 for (unsigned I = 0; I != NumProtos; ++I)
2691 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
John McCall8b07ec22010-05-15 11:32:37 +00002692 return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
Chris Lattner587cbe12009-04-22 06:45:28 +00002693 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002694
Sebastian Redl539c5062010-08-18 23:57:32 +00002695 case TYPE_OBJC_OBJECT_POINTER: {
Chris Lattner6e054af2009-04-22 06:40:03 +00002696 unsigned Idx = 0;
John McCall8b07ec22010-05-15 11:32:37 +00002697 QualType Pointee = GetType(Record[Idx++]);
2698 return Context->getObjCObjectPointerType(Pointee);
Chris Lattner6e054af2009-04-22 06:40:03 +00002699 }
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002700
Sebastian Redl539c5062010-08-18 23:57:32 +00002701 case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
John McCallcebee162009-10-18 09:09:24 +00002702 unsigned Idx = 0;
2703 QualType Parm = GetType(Record[Idx++]);
2704 QualType Replacement = GetType(Record[Idx++]);
2705 return
2706 Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2707 Replacement);
2708 }
John McCalle78aac42010-03-10 03:28:59 +00002709
Sebastian Redl539c5062010-08-18 23:57:32 +00002710 case TYPE_INJECTED_CLASS_NAME: {
John McCalle78aac42010-03-10 03:28:59 +00002711 CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
2712 QualType TST = GetType(Record[1]); // probably derivable
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002713 // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002714 // for AST reading, too much interdependencies.
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002715 return
2716 QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
John McCalle78aac42010-03-10 03:28:59 +00002717 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002718
Sebastian Redl539c5062010-08-18 23:57:32 +00002719 case TYPE_TEMPLATE_TYPE_PARM: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002720 unsigned Idx = 0;
2721 unsigned Depth = Record[Idx++];
2722 unsigned Index = Record[Idx++];
2723 bool Pack = Record[Idx++];
2724 IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
2725 return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
2726 }
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002727
Sebastian Redl539c5062010-08-18 23:57:32 +00002728 case TYPE_DEPENDENT_NAME: {
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002729 unsigned Idx = 0;
2730 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2731 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2732 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
Argyrios Kyrtzidise9290952010-07-02 11:55:24 +00002733 QualType Canon = GetType(Record[Idx++]);
2734 return Context->getDependentNameType(Keyword, NNS, Name, Canon);
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002735 }
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002736
Sebastian Redl539c5062010-08-18 23:57:32 +00002737 case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002738 unsigned Idx = 0;
2739 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2740 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2741 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
2742 unsigned NumArgs = Record[Idx++];
2743 llvm::SmallVector<TemplateArgument, 8> Args;
2744 Args.reserve(NumArgs);
2745 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002746 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002747 return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
2748 Args.size(), Args.data());
2749 }
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002750
Sebastian Redl539c5062010-08-18 23:57:32 +00002751 case TYPE_DEPENDENT_SIZED_ARRAY: {
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002752 unsigned Idx = 0;
2753
2754 // ArrayType
2755 QualType ElementType = GetType(Record[Idx++]);
2756 ArrayType::ArraySizeModifier ASM
2757 = (ArrayType::ArraySizeModifier)Record[Idx++];
2758 unsigned IndexTypeQuals = Record[Idx++];
2759
2760 // DependentSizedArrayType
Sebastian Redlc67764e2010-07-22 22:43:28 +00002761 Expr *NumElts = ReadExpr(DeclsCursor);
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002762 SourceRange Brackets = ReadSourceRange(Record, Idx);
2763
2764 return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
2765 IndexTypeQuals, Brackets);
2766 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002767
Sebastian Redl539c5062010-08-18 23:57:32 +00002768 case TYPE_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002769 unsigned Idx = 0;
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002770 bool IsDependent = Record[Idx++];
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002771 TemplateName Name = ReadTemplateName(Record, Idx);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002772 llvm::SmallVector<TemplateArgument, 8> Args;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002773 ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00002774 QualType Canon = GetType(Record[Idx++]);
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002775 QualType T;
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002776 if (Canon.isNull())
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002777 T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
2778 Args.size());
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002779 else
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002780 T = Context->getTemplateSpecializationType(Name, Args.data(),
2781 Args.size(), Canon);
2782 T->Dependent = IsDependent;
2783 return T;
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002784 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002785 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002786 // Suppress a GCC warning
2787 return QualType();
2788}
2789
John McCall8f115c62009-10-16 21:56:05 +00002790namespace {
2791
2792class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
Sebastian Redl2c499f62010-08-18 23:56:43 +00002793 ASTReader &Reader;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002794 llvm::BitstreamCursor &DeclsCursor;
Sebastian Redl2c499f62010-08-18 23:56:43 +00002795 const ASTReader::RecordData &Record;
John McCall8f115c62009-10-16 21:56:05 +00002796 unsigned &Idx;
2797
2798public:
Sebastian Redl2c499f62010-08-18 23:56:43 +00002799 TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
2800 const ASTReader::RecordData &Record, unsigned &Idx)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002801 : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
John McCall8f115c62009-10-16 21:56:05 +00002802
John McCall17001972009-10-18 01:05:36 +00002803 // We want compile-time assurance that we've enumerated all of
2804 // these, so unfortunately we have to declare them first, then
2805 // define them out-of-line.
2806#define ABSTRACT_TYPELOC(CLASS, PARENT)
John McCall8f115c62009-10-16 21:56:05 +00002807#define TYPELOC(CLASS, PARENT) \
John McCall17001972009-10-18 01:05:36 +00002808 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
John McCall8f115c62009-10-16 21:56:05 +00002809#include "clang/AST/TypeLocNodes.def"
2810
John McCall17001972009-10-18 01:05:36 +00002811 void VisitFunctionTypeLoc(FunctionTypeLoc);
2812 void VisitArrayTypeLoc(ArrayTypeLoc);
John McCall8f115c62009-10-16 21:56:05 +00002813};
2814
2815}
2816
John McCall17001972009-10-18 01:05:36 +00002817void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
John McCall8f115c62009-10-16 21:56:05 +00002818 // nothing to do
2819}
John McCall17001972009-10-18 01:05:36 +00002820void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Douglas Gregorc9b7a592010-01-18 18:04:31 +00002821 TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2822 if (TL.needsExtraLocalData()) {
2823 TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2824 TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2825 TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2826 TL.setModeAttr(Record[Idx++]);
2827 }
John McCall8f115c62009-10-16 21:56:05 +00002828}
John McCall17001972009-10-18 01:05:36 +00002829void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2830 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002831}
John McCall17001972009-10-18 01:05:36 +00002832void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2833 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002834}
John McCall17001972009-10-18 01:05:36 +00002835void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2836 TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002837}
John McCall17001972009-10-18 01:05:36 +00002838void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2839 TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002840}
John McCall17001972009-10-18 01:05:36 +00002841void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2842 TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002843}
John McCall17001972009-10-18 01:05:36 +00002844void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2845 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002846}
John McCall17001972009-10-18 01:05:36 +00002847void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2848 TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2849 TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002850 if (Record[Idx++])
Sebastian Redlc67764e2010-07-22 22:43:28 +00002851 TL.setSizeExpr(Reader.ReadExpr(DeclsCursor));
Douglas Gregor12bfa382009-10-17 00:13:19 +00002852 else
John McCall17001972009-10-18 01:05:36 +00002853 TL.setSizeExpr(0);
2854}
2855void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2856 VisitArrayTypeLoc(TL);
2857}
2858void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2859 VisitArrayTypeLoc(TL);
2860}
2861void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2862 VisitArrayTypeLoc(TL);
2863}
2864void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2865 DependentSizedArrayTypeLoc TL) {
2866 VisitArrayTypeLoc(TL);
2867}
2868void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2869 DependentSizedExtVectorTypeLoc TL) {
2870 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2871}
2872void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2873 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2874}
2875void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2876 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2877}
2878void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2879 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2880 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2881 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
John McCalle6347002009-10-23 01:28:53 +00002882 TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
John McCall17001972009-10-18 01:05:36 +00002883 }
2884}
2885void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2886 VisitFunctionTypeLoc(TL);
2887}
2888void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2889 VisitFunctionTypeLoc(TL);
2890}
John McCallb96ec562009-12-04 22:46:56 +00002891void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2892 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2893}
John McCall17001972009-10-18 01:05:36 +00002894void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2895 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2896}
2897void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002898 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2899 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2900 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall17001972009-10-18 01:05:36 +00002901}
2902void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002903 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2904 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2905 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Sebastian Redlc67764e2010-07-22 22:43:28 +00002906 TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002907}
2908void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2909 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2910}
2911void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2912 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2913}
2914void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2915 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2916}
John McCall17001972009-10-18 01:05:36 +00002917void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2918 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2919}
John McCallcebee162009-10-18 09:09:24 +00002920void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2921 SubstTemplateTypeParmTypeLoc TL) {
2922 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2923}
John McCall17001972009-10-18 01:05:36 +00002924void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2925 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002926 TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2927 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2928 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2929 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2930 TL.setArgLocInfo(i,
2931 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002932 DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002933}
Abramo Bagnara6150c882010-05-11 21:36:43 +00002934void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002935 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2936 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002937}
John McCalle78aac42010-03-10 03:28:59 +00002938void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
2939 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2940}
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +00002941void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002942 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2943 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002944 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2945}
John McCallc392f372010-06-11 00:33:02 +00002946void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
2947 DependentTemplateSpecializationTypeLoc TL) {
2948 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2949 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
2950 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2951 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2952 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2953 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
2954 TL.setArgLocInfo(I,
2955 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002956 DeclsCursor, Record, Idx));
John McCallc392f372010-06-11 00:33:02 +00002957}
John McCall17001972009-10-18 01:05:36 +00002958void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2959 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002960}
2961void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
2962 TL.setHasBaseTypeAsWritten(Record[Idx++]);
John McCall17001972009-10-18 01:05:36 +00002963 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2964 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2965 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2966 TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002967}
John McCallfc93cf92009-10-22 22:37:11 +00002968void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2969 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCallfc93cf92009-10-22 22:37:11 +00002970}
John McCall8f115c62009-10-16 21:56:05 +00002971
Sebastian Redl2c499f62010-08-18 23:56:43 +00002972TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00002973 const RecordData &Record,
John McCall8f115c62009-10-16 21:56:05 +00002974 unsigned &Idx) {
2975 QualType InfoTy = GetType(Record[Idx++]);
2976 if (InfoTy.isNull())
2977 return 0;
2978
John McCallbcd03502009-12-07 02:54:59 +00002979 TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002980 TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
John McCallbcd03502009-12-07 02:54:59 +00002981 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
John McCall8f115c62009-10-16 21:56:05 +00002982 TLR.Visit(TL);
John McCallbcd03502009-12-07 02:54:59 +00002983 return TInfo;
John McCall8f115c62009-10-16 21:56:05 +00002984}
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002985
Sebastian Redl539c5062010-08-18 23:57:32 +00002986QualType ASTReader::GetType(TypeID ID) {
John McCall8ccfcb52009-09-24 19:53:00 +00002987 unsigned FastQuals = ID & Qualifiers::FastMask;
2988 unsigned Index = ID >> Qualifiers::FastWidth;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002989
Sebastian Redl539c5062010-08-18 23:57:32 +00002990 if (Index < NUM_PREDEF_TYPE_IDS) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002991 QualType T;
Sebastian Redl539c5062010-08-18 23:57:32 +00002992 switch ((PredefinedTypeIDs)Index) {
2993 case PREDEF_TYPE_NULL_ID: return QualType();
2994 case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
2995 case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002996
Sebastian Redl539c5062010-08-18 23:57:32 +00002997 case PREDEF_TYPE_CHAR_U_ID:
2998 case PREDEF_TYPE_CHAR_S_ID:
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002999 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattner8575daa2009-04-27 21:45:14 +00003000 T = Context->CharTy;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003001 break;
3002
Sebastian Redl539c5062010-08-18 23:57:32 +00003003 case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
3004 case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
3005 case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
3006 case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
3007 case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
3008 case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
3009 case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
3010 case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
3011 case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
3012 case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
3013 case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
3014 case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
3015 case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
3016 case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
3017 case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
3018 case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
3019 case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
3020 case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
3021 case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
3022 case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
3023 case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
3024 case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
3025 case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
3026 case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003027 }
3028
3029 assert(!T.isNull() && "Unknown predefined type");
John McCall8ccfcb52009-09-24 19:53:00 +00003030 return T.withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003031 }
3032
Sebastian Redl539c5062010-08-18 23:57:32 +00003033 Index -= NUM_PREDEF_TYPE_IDS;
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003034 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Sebastian Redl409183f2010-07-14 20:26:45 +00003035 if (TypesLoaded[Index].isNull()) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003036 TypesLoaded[Index] = ReadTypeRecord(Index);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003037 TypesLoaded[Index]->setFromAST();
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003038 TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003039 if (DeserializationListener)
Argyrios Kyrtzidisbb5c7eae2010-08-20 16:03:59 +00003040 DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003041 TypesLoaded[Index]);
Sebastian Redl409183f2010-07-14 20:26:45 +00003042 }
Mike Stump11289f42009-09-09 15:08:12 +00003043
John McCall8ccfcb52009-09-24 19:53:00 +00003044 return TypesLoaded[Index].withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003045}
3046
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003047TypeID ASTReader::GetTypeID(QualType T) const {
3048 return MakeTypeID(T,
3049 std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
3050}
3051
3052TypeIdx ASTReader::GetTypeIdx(QualType T) const {
3053 if (T.isNull())
3054 return TypeIdx();
3055 assert(!T.getLocalFastQualifiers());
3056
3057 TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3058 // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
3059 // comparing keys of ASTDeclContextNameLookupTable.
3060 // If the type didn't come from the AST file use a specially marked index
3061 // so that any hash/key comparison fail since no such index is stored
3062 // in a AST file.
3063 if (I == TypeIdxs.end())
3064 return TypeIdx(-1);
3065 return I->second;
3066}
3067
John McCall0ad16662009-10-29 08:12:44 +00003068TemplateArgumentLocInfo
Sebastian Redl2c499f62010-08-18 23:56:43 +00003069ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003070 llvm::BitstreamCursor &DeclsCursor,
John McCall0ad16662009-10-29 08:12:44 +00003071 const RecordData &Record,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003072 unsigned &Index) {
John McCall0ad16662009-10-29 08:12:44 +00003073 switch (Kind) {
3074 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003075 return ReadExpr(DeclsCursor);
John McCall0ad16662009-10-29 08:12:44 +00003076 case TemplateArgument::Type:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003077 return GetTypeSourceInfo(DeclsCursor, Record, Index);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003078 case TemplateArgument::Template: {
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003079 SourceRange QualifierRange = ReadSourceRange(Record, Index);
3080 SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
3081 return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003082 }
John McCall0ad16662009-10-29 08:12:44 +00003083 case TemplateArgument::Null:
3084 case TemplateArgument::Integral:
3085 case TemplateArgument::Declaration:
3086 case TemplateArgument::Pack:
3087 return TemplateArgumentLocInfo();
3088 }
Jeffrey Yasskin1615d452009-12-12 05:05:38 +00003089 llvm_unreachable("unexpected template argument loc");
John McCall0ad16662009-10-29 08:12:44 +00003090 return TemplateArgumentLocInfo();
3091}
3092
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003093TemplateArgumentLoc
Sebastian Redl2c499f62010-08-18 23:56:43 +00003094ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003095 const RecordData &Record, unsigned &Index) {
3096 TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003097
3098 if (Arg.getKind() == TemplateArgument::Expression) {
3099 if (Record[Index++]) // bool InfoHasSameExpr.
3100 return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
3101 }
3102 return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00003103 DeclsCursor,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003104 Record, Index));
Argyrios Kyrtzidisae85e242010-06-22 09:54:59 +00003105}
3106
Sebastian Redl2c499f62010-08-18 23:56:43 +00003107Decl *ASTReader::GetExternalDecl(uint32_t ID) {
John McCall75b960e2010-06-01 09:23:16 +00003108 return GetDecl(ID);
3109}
3110
Sebastian Redl2c499f62010-08-18 23:56:43 +00003111TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003112 if (!DeclsLoaded[0]) {
Sebastian Redld7dce0a2010-08-24 00:50:04 +00003113 ReadDeclRecord(0, 1);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003114 if (DeserializationListener)
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003115 DeserializationListener->DeclRead(1, DeclsLoaded[0]);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003116 }
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00003117
3118 return cast<TranslationUnitDecl>(DeclsLoaded[0]);
3119}
3120
Sebastian Redl539c5062010-08-18 23:57:32 +00003121Decl *ASTReader::GetDecl(DeclID ID) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003122 if (ID == 0)
3123 return 0;
3124
Douglas Gregor745ed142009-04-25 18:35:21 +00003125 if (ID > DeclsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003126 Error("declaration ID out-of-range for AST file");
Douglas Gregor745ed142009-04-25 18:35:21 +00003127 return 0;
3128 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003129
Douglas Gregor745ed142009-04-25 18:35:21 +00003130 unsigned Index = ID - 1;
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003131 if (!DeclsLoaded[Index]) {
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00003132 ReadDeclRecord(Index, ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003133 if (DeserializationListener)
3134 DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
3135 }
Douglas Gregor745ed142009-04-25 18:35:21 +00003136
3137 return DeclsLoaded[Index];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003138}
3139
Chris Lattner9c28af02009-04-27 05:46:25 +00003140/// \brief Resolve the offset of a statement into a statement.
3141///
3142/// This operation will read a new statement from the external
3143/// source each time it is called, and is meant to be used via a
3144/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Sebastian Redl2c499f62010-08-18 23:56:43 +00003145Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
Sebastian Redl5c415f32010-07-22 17:01:13 +00003146 // Offset here is a global offset across the entire chain.
3147 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3148 PerFileData &F = *Chain[N - I - 1];
3149 if (Offset < F.SizeInBits) {
3150 // Since we know that this statement is part of a decl, make sure to use
3151 // the decl cursor to read it.
3152 F.DeclsCursor.JumpToBit(Offset);
3153 return ReadStmtFromStream(F.DeclsCursor);
3154 }
3155 Offset -= F.SizeInBits;
3156 }
3157 llvm_unreachable("Broken chain");
Douglas Gregor3c3aa612009-04-18 00:07:54 +00003158}
3159
Sebastian Redl2c499f62010-08-18 23:56:43 +00003160bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003161 llvm::SmallVectorImpl<Decl*> &Decls) {
Mike Stump11289f42009-09-09 15:08:12 +00003162 assert(DC->hasExternalLexicalStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003163 "DeclContext has no lexical decls in storage");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003164
Sebastian Redl5c415f32010-07-22 17:01:13 +00003165 // There might be lexical decls in multiple parts of the chain, for the TU
3166 // at least.
3167 DeclContextInfos &Infos = DeclContextOffsets[DC];
3168 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3169 I != E; ++I) {
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003170 // IDs can be 0 if this context doesn't contain declarations.
3171 if (!I->LexicalDecls)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003172 continue;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003173
3174 // Load all of the declaration IDs
Sebastian Redl539c5062010-08-18 23:57:32 +00003175 for (const DeclID *ID = I->LexicalDecls,
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003176 *IDE = ID + I->NumLexicalDecls;
3177 ID != IDE; ++ID)
3178 Decls.push_back(GetDecl(*ID));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003179 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003180
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003181 ++NumLexicalDeclContextsRead;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003182 return false;
3183}
3184
John McCall75b960e2010-06-01 09:23:16 +00003185DeclContext::lookup_result
Sebastian Redl2c499f62010-08-18 23:56:43 +00003186ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003187 DeclarationName Name) {
Mike Stump11289f42009-09-09 15:08:12 +00003188 assert(DC->hasExternalVisibleStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003189 "DeclContext has no visible decls in storage");
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003190 if (!Name)
3191 return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
3192 DeclContext::lookup_iterator(0));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003193
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003194 llvm::SmallVector<NamedDecl *, 64> Decls;
Sebastian Redl471ac2f2010-08-24 00:49:55 +00003195 // There might be visible decls in multiple parts of the chain, for the TU
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003196 // and namespaces. For any given name, the last available results replace
3197 // all earlier ones. For this reason, we walk in reverse.
Sebastian Redl5c415f32010-07-22 17:01:13 +00003198 DeclContextInfos &Infos = DeclContextOffsets[DC];
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003199 for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
Sebastian Redl5c415f32010-07-22 17:01:13 +00003200 I != E; ++I) {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003201 if (!I->NameLookupTableData)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003202 continue;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003203
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003204 ASTDeclContextNameLookupTable *LookupTable =
3205 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3206 ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
3207 if (Pos == LookupTable->end())
Sebastian Redl5c415f32010-07-22 17:01:13 +00003208 continue;
3209
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003210 ASTDeclContextNameLookupTrait::data_type Data = *Pos;
3211 for (; Data.first != Data.second; ++Data.first)
3212 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003213 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003214 }
3215
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003216 ++NumVisibleDeclContextsRead;
John McCall75b960e2010-06-01 09:23:16 +00003217
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003218 SetExternalVisibleDeclsForName(DC, Name, Decls);
John McCall75b960e2010-06-01 09:23:16 +00003219 return const_cast<DeclContext*>(DC)->lookup(Name);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003220}
3221
Argyrios Kyrtzidisd32ee892010-08-20 23:35:55 +00003222void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
3223 assert(DC->hasExternalVisibleStorage() &&
3224 "DeclContext has no visible decls in storage");
3225
3226 llvm::SmallVector<NamedDecl *, 64> Decls;
3227 // There might be visible decls in multiple parts of the chain, for the TU
3228 // and namespaces.
3229 DeclContextInfos &Infos = DeclContextOffsets[DC];
3230 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3231 I != E; ++I) {
3232 if (!I->NameLookupTableData)
3233 continue;
3234
3235 ASTDeclContextNameLookupTable *LookupTable =
3236 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3237 for (ASTDeclContextNameLookupTable::item_iterator
3238 ItemI = LookupTable->item_begin(),
3239 ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
3240 ASTDeclContextNameLookupTable::item_iterator::value_type Val
3241 = *ItemI;
3242 ASTDeclContextNameLookupTrait::data_type Data = Val.second;
3243 Decls.clear();
3244 for (; Data.first != Data.second; ++Data.first)
3245 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
3246 MaterializeVisibleDeclsForName(DC, Val.first, Decls);
3247 }
3248 }
3249}
3250
Sebastian Redl2c499f62010-08-18 23:56:43 +00003251void ASTReader::PassInterestingDeclsToConsumer() {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003252 assert(Consumer);
3253 while (!InterestingDecls.empty()) {
3254 DeclGroupRef DG(InterestingDecls.front());
3255 InterestingDecls.pop_front();
Sebastian Redleaa4ade2010-08-11 18:52:41 +00003256 Consumer->HandleInterestingDecl(DG);
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003257 }
3258}
3259
Sebastian Redl2c499f62010-08-18 23:56:43 +00003260void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregorb985eeb2009-04-22 19:09:20 +00003261 this->Consumer = Consumer;
3262
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003263 if (!Consumer)
3264 return;
3265
3266 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003267 // Force deserialization of this decl, which will cause it to be queued for
3268 // passing to the consumer.
Daniel Dunbar865c2a72009-09-17 03:06:44 +00003269 GetDecl(ExternalDefinitions[I]);
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003270 }
Douglas Gregorf005eac2009-04-25 00:41:30 +00003271
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003272 PassInterestingDeclsToConsumer();
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003273}
3274
Sebastian Redl2c499f62010-08-18 23:56:43 +00003275void ASTReader::PrintStats() {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003276 std::fprintf(stderr, "*** AST File Statistics:\n");
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003277
Mike Stump11289f42009-09-09 15:08:12 +00003278 unsigned NumTypesLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003279 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
John McCall8ccfcb52009-09-24 19:53:00 +00003280 QualType());
Douglas Gregor0e149972009-04-25 19:10:14 +00003281 unsigned NumDeclsLoaded
3282 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
3283 (Decl *)0);
3284 unsigned NumIdentifiersLoaded
3285 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
3286 IdentifiersLoaded.end(),
3287 (IdentifierInfo *)0);
Mike Stump11289f42009-09-09 15:08:12 +00003288 unsigned NumSelectorsLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003289 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
3290 SelectorsLoaded.end(),
3291 Selector());
Douglas Gregorc3b1dd12009-04-13 20:50:16 +00003292
Douglas Gregorc5046832009-04-27 18:38:38 +00003293 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
3294 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor258ae542009-04-27 06:38:32 +00003295 if (TotalNumSLocEntries)
3296 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
3297 NumSLocEntriesRead, TotalNumSLocEntries,
3298 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor745ed142009-04-25 18:35:21 +00003299 if (!TypesLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003300 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003301 NumTypesLoaded, (unsigned)TypesLoaded.size(),
3302 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
3303 if (!DeclsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003304 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003305 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
3306 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor0e149972009-04-25 19:10:14 +00003307 if (!IdentifiersLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003308 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor0e149972009-04-25 19:10:14 +00003309 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
3310 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Sebastian Redlada023c2010-08-04 20:40:17 +00003311 if (!SelectorsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003312 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
Sebastian Redlada023c2010-08-04 20:40:17 +00003313 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
3314 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
Douglas Gregor95c13f52009-04-25 17:48:32 +00003315 if (TotalNumStatements)
3316 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
3317 NumStatementsRead, TotalNumStatements,
3318 ((float)NumStatementsRead/TotalNumStatements * 100));
3319 if (TotalNumMacros)
3320 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
3321 NumMacrosRead, TotalNumMacros,
3322 ((float)NumMacrosRead/TotalNumMacros * 100));
3323 if (TotalLexicalDeclContexts)
3324 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
3325 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
3326 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
3327 * 100));
3328 if (TotalVisibleDeclContexts)
3329 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
3330 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
3331 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
3332 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003333 if (TotalNumMethodPoolEntries) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003334 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003335 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
3336 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
Douglas Gregor95c13f52009-04-25 17:48:32 +00003337 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003338 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
Douglas Gregor95c13f52009-04-25 17:48:32 +00003339 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003340 std::fprintf(stderr, "\n");
3341}
3342
Sebastian Redl2c499f62010-08-18 23:56:43 +00003343void ASTReader::InitializeSema(Sema &S) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003344 SemaObj = &S;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003345 S.ExternalSource = this;
3346
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003347 // Makes sure any declarations that were deserialized "too early"
3348 // still get added to the identifier's declaration chains.
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003349 if (SemaObj->TUScope) {
3350 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
John McCall48871652010-08-21 09:40:31 +00003351 SemaObj->TUScope->AddDecl(PreloadedDecls[I]);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003352 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
3353 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003354 }
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003355 PreloadedDecls.clear();
Douglas Gregord4df8652009-04-22 22:02:47 +00003356
3357 // If there were any tentative definitions, deserialize them and add
Sebastian Redl35351a92010-01-31 22:27:38 +00003358 // them to Sema's list of tentative definitions.
Douglas Gregord4df8652009-04-22 22:02:47 +00003359 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
3360 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
Sebastian Redl35351a92010-01-31 22:27:38 +00003361 SemaObj->TentativeDefinitions.push_back(Var);
Douglas Gregord4df8652009-04-22 22:02:47 +00003362 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00003363
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00003364 // If there were any unused file scoped decls, deserialize them and add to
3365 // Sema's list of unused file scoped decls.
3366 for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
3367 DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
3368 SemaObj->UnusedFileScopedDecls.push_back(D);
Tanya Lattner90073802010-02-12 00:07:30 +00003369 }
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003370
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00003371 // If there were any weak undeclared identifiers, deserialize them and add to
3372 // Sema's list of weak undeclared identifiers.
3373 if (!WeakUndeclaredIdentifiers.empty()) {
3374 unsigned Idx = 0;
3375 for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
3376 IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3377 IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3378 SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
3379 bool Used = WeakUndeclaredIdentifiers[Idx++];
3380 Sema::WeakInfo WI(AliasId, Loc);
3381 WI.setUsed(Used);
3382 SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
3383 }
3384 }
3385
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003386 // If there were any locally-scoped external declarations,
3387 // deserialize them and add them to Sema's table of locally-scoped
3388 // external declarations.
3389 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
3390 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
3391 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
3392 }
Douglas Gregor61cac2b2009-04-27 20:06:05 +00003393
3394 // If there were any ext_vector type declarations, deserialize them
3395 // and add them to Sema's vector of such declarations.
3396 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
3397 SemaObj->ExtVectorDecls.push_back(
3398 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003399
3400 // FIXME: Do VTable uses and dynamic classes deserialize too much ?
3401 // Can we cut them down before writing them ?
3402
3403 // If there were any VTable uses, deserialize the information and add it
3404 // to Sema's vector and map of VTable uses.
Argyrios Kyrtzidisedee67f2010-08-03 17:29:52 +00003405 if (!VTableUses.empty()) {
3406 unsigned Idx = 0;
3407 for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
3408 CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
3409 SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
3410 bool DefinitionRequired = VTableUses[Idx++];
3411 SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
3412 SemaObj->VTablesUsed[Class] = DefinitionRequired;
3413 }
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003414 }
3415
3416 // If there were any dynamic classes declarations, deserialize them
3417 // and add them to Sema's vector of such declarations.
3418 for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
3419 SemaObj->DynamicClasses.push_back(
3420 cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003421
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00003422 // If there were any pending implicit instantiations, deserialize them
3423 // and add them to Sema's queue of such instantiations.
3424 assert(PendingImplicitInstantiations.size() % 2 == 0 &&
3425 "Expected pairs of entries");
3426 for (unsigned Idx = 0, N = PendingImplicitInstantiations.size(); Idx < N;) {
3427 ValueDecl *D=cast<ValueDecl>(GetDecl(PendingImplicitInstantiations[Idx++]));
3428 SourceLocation Loc = ReadSourceLocation(PendingImplicitInstantiations, Idx);
3429 SemaObj->PendingImplicitInstantiations.push_back(std::make_pair(D, Loc));
3430 }
3431
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00003432 // Load the offsets of the declarations that Sema references.
3433 // They will be lazily deserialized when needed.
3434 if (!SemaDeclRefs.empty()) {
3435 assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
3436 SemaObj->StdNamespace = SemaDeclRefs[0];
3437 SemaObj->StdBadAlloc = SemaDeclRefs[1];
3438 }
3439
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003440 // If there are @selector references added them to its pool. This is for
3441 // implementation of -Wselector.
Sebastian Redlada023c2010-08-04 20:40:17 +00003442 if (!ReferencedSelectorsData.empty()) {
3443 unsigned int DataSize = ReferencedSelectorsData.size()-1;
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003444 unsigned I = 0;
3445 while (I < DataSize) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003446 Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003447 SourceLocation SelLoc =
Sebastian Redlada023c2010-08-04 20:40:17 +00003448 SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003449 SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
3450 }
3451 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003452}
3453
Sebastian Redl2c499f62010-08-18 23:56:43 +00003454IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Sebastian Redl78f51772010-08-02 18:30:12 +00003455 // Try to find this name within our on-disk hash tables. We start with the
3456 // most recent one, since that one contains the most up-to-date info.
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003457 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003458 ASTIdentifierLookupTable *IdTable
3459 = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003460 if (!IdTable)
3461 continue;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003462 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003463 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003464 if (Pos == IdTable->end())
3465 continue;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003466
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003467 // Dereferencing the iterator has the effect of building the
3468 // IdentifierInfo node and populating it with the various
3469 // declarations it needs.
Sebastian Redl78f51772010-08-02 18:30:12 +00003470 return *Pos;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003471 }
Sebastian Redl78f51772010-08-02 18:30:12 +00003472 return 0;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003473}
3474
Mike Stump11289f42009-09-09 15:08:12 +00003475std::pair<ObjCMethodList, ObjCMethodList>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003476ASTReader::ReadMethodPool(Selector Sel) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003477 // Find this selector in a hash table. We want to find the most recent entry.
3478 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3479 PerFileData &F = *Chain[I];
3480 if (!F.SelectorLookupTable)
3481 continue;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003482
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003483 ASTSelectorLookupTable *PoolTable
3484 = (ASTSelectorLookupTable*)F.SelectorLookupTable;
3485 ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
Sebastian Redlada023c2010-08-04 20:40:17 +00003486 if (Pos != PoolTable->end()) {
3487 ++NumSelectorsRead;
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003488 // FIXME: Not quite happy with the statistics here. We probably should
3489 // disable this tracking when called via LoadSelector.
3490 // Also, should entries without methods count as misses?
3491 ++NumMethodPoolEntriesRead;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003492 ASTSelectorLookupTrait::data_type Data = *Pos;
Sebastian Redlada023c2010-08-04 20:40:17 +00003493 if (DeserializationListener)
3494 DeserializationListener->SelectorRead(Data.ID, Sel);
3495 return std::make_pair(Data.Instance, Data.Factory);
3496 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003497 }
Douglas Gregorc78d3462009-04-24 21:10:55 +00003498
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003499 ++NumMethodPoolMisses;
Sebastian Redlada023c2010-08-04 20:40:17 +00003500 return std::pair<ObjCMethodList, ObjCMethodList>();
Douglas Gregorc78d3462009-04-24 21:10:55 +00003501}
3502
Sebastian Redl2c499f62010-08-18 23:56:43 +00003503void ASTReader::LoadSelector(Selector Sel) {
Sebastian Redld95a56e2010-08-04 18:21:41 +00003504 // It would be complicated to avoid reading the methods anyway. So don't.
3505 ReadMethodPool(Sel);
3506}
3507
Sebastian Redl2c499f62010-08-18 23:56:43 +00003508void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003509 assert(ID && "Non-zero identifier ID required");
Douglas Gregor6f00bf82009-04-28 21:53:25 +00003510 assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
Douglas Gregor0e149972009-04-25 19:10:14 +00003511 IdentifiersLoaded[ID - 1] = II;
Sebastian Redlff4a2952010-07-23 23:49:55 +00003512 if (DeserializationListener)
3513 DeserializationListener->IdentifierRead(ID, II);
Douglas Gregora868bbd2009-04-21 22:25:48 +00003514}
3515
Douglas Gregor1342e842009-07-06 18:54:52 +00003516/// \brief Set the globally-visible declarations associated with the given
3517/// identifier.
3518///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003519/// If the AST reader is currently in a state where the given declaration IDs
Mike Stump11289f42009-09-09 15:08:12 +00003520/// cannot safely be resolved, they are queued until it is safe to resolve
Douglas Gregor1342e842009-07-06 18:54:52 +00003521/// them.
3522///
3523/// \param II an IdentifierInfo that refers to one or more globally-visible
3524/// declarations.
3525///
3526/// \param DeclIDs the set of declaration IDs with the name @p II that are
3527/// visible at global scope.
3528///
3529/// \param Nonrecursive should be true to indicate that the caller knows that
3530/// this call is non-recursive, and therefore the globally-visible declarations
3531/// will not be placed onto the pending queue.
Mike Stump11289f42009-09-09 15:08:12 +00003532void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003533ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
Douglas Gregor1342e842009-07-06 18:54:52 +00003534 const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
3535 bool Nonrecursive) {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00003536 if (NumCurrentElementsDeserializing && !Nonrecursive) {
Douglas Gregor1342e842009-07-06 18:54:52 +00003537 PendingIdentifierInfos.push_back(PendingIdentifierInfo());
3538 PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
3539 PII.II = II;
3540 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
3541 PII.DeclIDs.push_back(DeclIDs[I]);
3542 return;
3543 }
Mike Stump11289f42009-09-09 15:08:12 +00003544
Douglas Gregor1342e842009-07-06 18:54:52 +00003545 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
3546 NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
3547 if (SemaObj) {
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003548 if (SemaObj->TUScope) {
3549 // Introduce this declaration into the translation-unit scope
3550 // and add it to the declaration chain for this identifier, so
3551 // that (unqualified) name lookup will find it.
John McCall48871652010-08-21 09:40:31 +00003552 SemaObj->TUScope->AddDecl(D);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003553 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
3554 }
Douglas Gregor1342e842009-07-06 18:54:52 +00003555 } else {
3556 // Queue this declaration so that it will be added to the
3557 // translation unit scope and identifier's declaration chain
3558 // once a Sema object is known.
3559 PreloadedDecls.push_back(D);
3560 }
3561 }
3562}
3563
Sebastian Redl2c499f62010-08-18 23:56:43 +00003564IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003565 if (ID == 0)
3566 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00003567
Sebastian Redlc713b962010-07-21 00:46:22 +00003568 if (IdentifiersLoaded.empty()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003569 Error("no identifier table in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003570 return 0;
3571 }
Mike Stump11289f42009-09-09 15:08:12 +00003572
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003573 assert(PP && "Forgot to set Preprocessor ?");
Sebastian Redlc713b962010-07-21 00:46:22 +00003574 ID -= 1;
3575 if (!IdentifiersLoaded[ID]) {
3576 unsigned Index = ID;
3577 const char *Str = 0;
3578 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3579 PerFileData *F = Chain[N - I - 1];
3580 if (Index < F->LocalNumIdentifiers) {
3581 uint32_t Offset = F->IdentifierOffsets[Index];
3582 Str = F->IdentifierTableData + Offset;
3583 break;
3584 }
3585 Index -= F->LocalNumIdentifiers;
3586 }
3587 assert(Str && "Broken Chain");
Douglas Gregor5287b4e2009-04-25 21:04:17 +00003588
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003589 // All of the strings in the AST file are preceded by a 16-bit length.
3590 // Extract that 16-bit length to avoid having to execute strlen().
Ted Kremenekca42a512009-10-23 04:45:31 +00003591 // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
3592 // unsigned integers. This is important to avoid integer overflow when
3593 // we cast them to 'unsigned'.
Ted Kremenek49c52322009-10-23 03:57:22 +00003594 const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
Douglas Gregorab4df582009-04-28 20:01:51 +00003595 unsigned StrLen = (((unsigned) StrLenPtr[0])
3596 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Sebastian Redlc713b962010-07-21 00:46:22 +00003597 IdentifiersLoaded[ID]
Kovarththanan Rajaratnama3b09592010-03-12 10:32:27 +00003598 = &PP->getIdentifierTable().get(Str, StrLen);
Sebastian Redlff4a2952010-07-23 23:49:55 +00003599 if (DeserializationListener)
3600 DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003601 }
Mike Stump11289f42009-09-09 15:08:12 +00003602
Sebastian Redlc713b962010-07-21 00:46:22 +00003603 return IdentifiersLoaded[ID];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003604}
3605
Sebastian Redl2c499f62010-08-18 23:56:43 +00003606void ASTReader::ReadSLocEntry(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00003607 ReadSLocEntryRecord(ID);
3608}
3609
Sebastian Redl2c499f62010-08-18 23:56:43 +00003610Selector ASTReader::DecodeSelector(unsigned ID) {
Steve Naroff2ddea052009-04-23 10:39:46 +00003611 if (ID == 0)
3612 return Selector();
Mike Stump11289f42009-09-09 15:08:12 +00003613
Sebastian Redlada023c2010-08-04 20:40:17 +00003614 if (ID > SelectorsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003615 Error("selector ID out of range in AST file");
Steve Naroff2ddea052009-04-23 10:39:46 +00003616 return Selector();
3617 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003618
Sebastian Redlada023c2010-08-04 20:40:17 +00003619 if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003620 // Load this selector from the selector table.
Sebastian Redlada023c2010-08-04 20:40:17 +00003621 unsigned Idx = ID - 1;
3622 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3623 PerFileData &F = *Chain[N - I - 1];
3624 if (Idx < F.LocalNumSelectors) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003625 ASTSelectorLookupTrait Trait(*this);
Sebastian Redlada023c2010-08-04 20:40:17 +00003626 SelectorsLoaded[ID - 1] =
3627 Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
3628 if (DeserializationListener)
3629 DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
3630 break;
3631 }
3632 Idx -= F.LocalNumSelectors;
3633 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003634 }
3635
Sebastian Redlada023c2010-08-04 20:40:17 +00003636 return SelectorsLoaded[ID - 1];
Steve Naroff2ddea052009-04-23 10:39:46 +00003637}
3638
Sebastian Redl2c499f62010-08-18 23:56:43 +00003639Selector ASTReader::GetExternalSelector(uint32_t ID) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003640 return DecodeSelector(ID);
3641}
3642
Sebastian Redl2c499f62010-08-18 23:56:43 +00003643uint32_t ASTReader::GetNumExternalSelectors() {
Sebastian Redlada023c2010-08-04 20:40:17 +00003644 // ID 0 (the null selector) is considered an external selector.
3645 return getTotalNumSelectors() + 1;
Douglas Gregord720daf2010-04-06 17:30:22 +00003646}
3647
Mike Stump11289f42009-09-09 15:08:12 +00003648DeclarationName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003649ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003650 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
3651 switch (Kind) {
3652 case DeclarationName::Identifier:
3653 return DeclarationName(GetIdentifierInfo(Record, Idx));
3654
3655 case DeclarationName::ObjCZeroArgSelector:
3656 case DeclarationName::ObjCOneArgSelector:
3657 case DeclarationName::ObjCMultiArgSelector:
Steve Naroff3c301dc2009-04-23 15:15:40 +00003658 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003659
3660 case DeclarationName::CXXConstructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003661 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003662 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003663
3664 case DeclarationName::CXXDestructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003665 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003666 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003667
3668 case DeclarationName::CXXConversionFunctionName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003669 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003670 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003671
3672 case DeclarationName::CXXOperatorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003673 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003674 (OverloadedOperatorKind)Record[Idx++]);
3675
Alexis Hunt3d221f22009-11-29 07:34:05 +00003676 case DeclarationName::CXXLiteralOperatorName:
3677 return Context->DeclarationNames.getCXXLiteralOperatorName(
3678 GetIdentifierInfo(Record, Idx));
3679
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003680 case DeclarationName::CXXUsingDirective:
3681 return DeclarationName::getUsingDirectiveName();
3682 }
3683
3684 // Required to silence GCC warning
3685 return DeclarationName();
3686}
Douglas Gregor55abb232009-04-10 20:39:37 +00003687
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003688TemplateName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003689ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003690 TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
3691 switch (Kind) {
3692 case TemplateName::Template:
3693 return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
3694
3695 case TemplateName::OverloadedTemplate: {
3696 unsigned size = Record[Idx++];
3697 UnresolvedSet<8> Decls;
3698 while (size--)
3699 Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
3700
3701 return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
3702 }
3703
3704 case TemplateName::QualifiedTemplate: {
3705 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3706 bool hasTemplKeyword = Record[Idx++];
3707 TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
3708 return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
3709 }
3710
3711 case TemplateName::DependentTemplate: {
3712 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3713 if (Record[Idx++]) // isIdentifier
3714 return Context->getDependentTemplateName(NNS,
3715 GetIdentifierInfo(Record, Idx));
3716 return Context->getDependentTemplateName(NNS,
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003717 (OverloadedOperatorKind)Record[Idx++]);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003718 }
3719 }
3720
3721 assert(0 && "Unhandled template name kind!");
3722 return TemplateName();
3723}
3724
3725TemplateArgument
Sebastian Redl2c499f62010-08-18 23:56:43 +00003726ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003727 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003728 switch ((TemplateArgument::ArgKind)Record[Idx++]) {
3729 case TemplateArgument::Null:
3730 return TemplateArgument();
3731 case TemplateArgument::Type:
3732 return TemplateArgument(GetType(Record[Idx++]));
3733 case TemplateArgument::Declaration:
3734 return TemplateArgument(GetDecl(Record[Idx++]));
Argyrios Kyrtzidis0b0369a2010-06-28 09:31:34 +00003735 case TemplateArgument::Integral: {
3736 llvm::APSInt Value = ReadAPSInt(Record, Idx);
3737 QualType T = GetType(Record[Idx++]);
3738 return TemplateArgument(Value, T);
3739 }
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003740 case TemplateArgument::Template:
3741 return TemplateArgument(ReadTemplateName(Record, Idx));
3742 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003743 return TemplateArgument(ReadExpr(DeclsCursor));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003744 case TemplateArgument::Pack: {
3745 unsigned NumArgs = Record[Idx++];
3746 llvm::SmallVector<TemplateArgument, 8> Args;
3747 Args.reserve(NumArgs);
3748 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003749 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003750 TemplateArgument TemplArg;
3751 TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
3752 return TemplArg;
3753 }
3754 }
3755
3756 assert(0 && "Unhandled template argument kind!");
3757 return TemplateArgument();
3758}
3759
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003760TemplateParameterList *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003761ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003762 SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
3763 SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
3764 SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
3765
3766 unsigned NumParams = Record[Idx++];
3767 llvm::SmallVector<NamedDecl *, 16> Params;
3768 Params.reserve(NumParams);
3769 while (NumParams--)
3770 Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
3771
3772 TemplateParameterList* TemplateParams =
3773 TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
3774 Params.data(), Params.size(), RAngleLoc);
3775 return TemplateParams;
3776}
3777
3778void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003779ASTReader::
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003780ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003781 llvm::BitstreamCursor &DeclsCursor,
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003782 const RecordData &Record, unsigned &Idx) {
3783 unsigned NumTemplateArgs = Record[Idx++];
3784 TemplArgs.reserve(NumTemplateArgs);
3785 while (NumTemplateArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003786 TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003787}
3788
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003789/// \brief Read a UnresolvedSet structure.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003790void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003791 const RecordData &Record, unsigned &Idx) {
3792 unsigned NumDecls = Record[Idx++];
3793 while (NumDecls--) {
3794 NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
3795 AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
3796 Set.addDecl(D, AS);
3797 }
3798}
3799
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003800CXXBaseSpecifier
Sebastian Redl2c499f62010-08-18 23:56:43 +00003801ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
Nick Lewycky19b9f952010-07-26 16:56:01 +00003802 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003803 bool isVirtual = static_cast<bool>(Record[Idx++]);
3804 bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
3805 AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003806 TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003807 SourceRange Range = ReadSourceRange(Record, Idx);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003808 return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003809}
3810
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003811std::pair<CXXBaseOrMemberInitializer **, unsigned>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003812ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003813 const RecordData &Record,
3814 unsigned &Idx) {
3815 CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
3816 unsigned NumInitializers = Record[Idx++];
3817 if (NumInitializers) {
3818 ASTContext &C = *getContext();
3819
3820 BaseOrMemberInitializers
3821 = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
3822 for (unsigned i=0; i != NumInitializers; ++i) {
3823 TypeSourceInfo *BaseClassInfo = 0;
3824 bool IsBaseVirtual = false;
3825 FieldDecl *Member = 0;
3826
3827 bool IsBaseInitializer = Record[Idx++];
3828 if (IsBaseInitializer) {
3829 BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
3830 IsBaseVirtual = Record[Idx++];
3831 } else {
3832 Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
3833 }
3834 SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
3835 Expr *Init = ReadExpr(Cursor);
3836 FieldDecl *AnonUnionMember
3837 = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
3838 SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
3839 SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
3840 bool IsWritten = Record[Idx++];
3841 unsigned SourceOrderOrNumArrayIndices;
3842 llvm::SmallVector<VarDecl *, 8> Indices;
3843 if (IsWritten) {
3844 SourceOrderOrNumArrayIndices = Record[Idx++];
3845 } else {
3846 SourceOrderOrNumArrayIndices = Record[Idx++];
3847 Indices.reserve(SourceOrderOrNumArrayIndices);
3848 for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
3849 Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
3850 }
3851
3852 CXXBaseOrMemberInitializer *BOMInit;
3853 if (IsBaseInitializer) {
3854 BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
3855 IsBaseVirtual, LParenLoc,
3856 Init, RParenLoc);
3857 } else if (IsWritten) {
3858 BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
3859 LParenLoc, Init, RParenLoc);
3860 } else {
3861 BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
3862 LParenLoc, Init, RParenLoc,
3863 Indices.data(),
3864 Indices.size());
3865 }
3866
3867 BOMInit->setAnonUnionMember(AnonUnionMember);
3868 BaseOrMemberInitializers[i] = BOMInit;
3869 }
3870 }
3871
3872 return std::make_pair(BaseOrMemberInitializers, NumInitializers);
3873}
3874
Chris Lattnerca025db2010-05-07 21:43:38 +00003875NestedNameSpecifier *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003876ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
Chris Lattnerca025db2010-05-07 21:43:38 +00003877 unsigned N = Record[Idx++];
3878 NestedNameSpecifier *NNS = 0, *Prev = 0;
3879 for (unsigned I = 0; I != N; ++I) {
3880 NestedNameSpecifier::SpecifierKind Kind
3881 = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
3882 switch (Kind) {
3883 case NestedNameSpecifier::Identifier: {
3884 IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
3885 NNS = NestedNameSpecifier::Create(*Context, Prev, II);
3886 break;
3887 }
3888
3889 case NestedNameSpecifier::Namespace: {
3890 NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
3891 NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
3892 break;
3893 }
3894
3895 case NestedNameSpecifier::TypeSpec:
3896 case NestedNameSpecifier::TypeSpecWithTemplate: {
3897 Type *T = GetType(Record[Idx++]).getTypePtr();
3898 bool Template = Record[Idx++];
3899 NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
3900 break;
3901 }
3902
3903 case NestedNameSpecifier::Global: {
3904 NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
3905 // No associated value, and there can't be a prefix.
3906 break;
3907 }
Chris Lattnerca025db2010-05-07 21:43:38 +00003908 }
Argyrios Kyrtzidisad65c692010-07-07 15:46:30 +00003909 Prev = NNS;
Chris Lattnerca025db2010-05-07 21:43:38 +00003910 }
3911 return NNS;
3912}
3913
3914SourceRange
Sebastian Redl2c499f62010-08-18 23:56:43 +00003915ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
Daniel Dunbar6d3bc082010-06-02 15:47:10 +00003916 SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
3917 SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
3918 return SourceRange(beg, end);
Chris Lattnerca025db2010-05-07 21:43:38 +00003919}
3920
Douglas Gregor1daeb692009-04-13 18:14:40 +00003921/// \brief Read an integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003922llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003923 unsigned BitWidth = Record[Idx++];
3924 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
3925 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
3926 Idx += NumWords;
3927 return Result;
3928}
3929
3930/// \brief Read a signed integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003931llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003932 bool isUnsigned = Record[Idx++];
3933 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
3934}
3935
Douglas Gregore0a3a512009-04-14 21:55:33 +00003936/// \brief Read a floating-point value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003937llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregore0a3a512009-04-14 21:55:33 +00003938 return llvm::APFloat(ReadAPInt(Record, Idx));
3939}
3940
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003941// \brief Read a string
Sebastian Redl2c499f62010-08-18 23:56:43 +00003942std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003943 unsigned Len = Record[Idx++];
Jay Foad7d0479f2009-05-21 09:52:38 +00003944 std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003945 Idx += Len;
3946 return Result;
3947}
3948
Sebastian Redl2c499f62010-08-18 23:56:43 +00003949CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
Chris Lattnercba86142010-05-10 00:25:06 +00003950 unsigned &Idx) {
3951 CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
3952 return CXXTemporary::Create(*Context, Decl);
3953}
3954
Sebastian Redl2c499f62010-08-18 23:56:43 +00003955DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
Douglas Gregor92863e42009-04-10 23:10:45 +00003956 return Diag(SourceLocation(), DiagID);
3957}
3958
Sebastian Redl2c499f62010-08-18 23:56:43 +00003959DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003960 return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
Douglas Gregor55abb232009-04-10 20:39:37 +00003961}
Douglas Gregora9af1d12009-04-17 00:04:06 +00003962
Douglas Gregora868bbd2009-04-21 22:25:48 +00003963/// \brief Retrieve the identifier table associated with the
3964/// preprocessor.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003965IdentifierTable &ASTReader::getIdentifierTable() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003966 assert(PP && "Forgot to set Preprocessor ?");
3967 return PP->getIdentifierTable();
Douglas Gregora868bbd2009-04-21 22:25:48 +00003968}
3969
Douglas Gregora9af1d12009-04-17 00:04:06 +00003970/// \brief Record that the given ID maps to the given switch-case
3971/// statement.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003972void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003973 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
3974 SwitchCaseStmts[ID] = SC;
3975}
3976
3977/// \brief Retrieve the switch-case statement with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003978SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003979 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
3980 return SwitchCaseStmts[ID];
3981}
Douglas Gregor6cc68a42009-04-17 18:18:49 +00003982
3983/// \brief Record that the given label statement has been
3984/// deserialized and has the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003985void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
Mike Stump11289f42009-09-09 15:08:12 +00003986 assert(LabelStmts.find(ID) == LabelStmts.end() &&
Douglas Gregor6cc68a42009-04-17 18:18:49 +00003987 "Deserialized label twice");
3988 LabelStmts[ID] = S;
3989
3990 // If we've already seen any goto statements that point to this
3991 // label, resolve them now.
3992 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
3993 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
3994 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
3995 Goto->second->setLabel(S);
3996 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor779d8652009-04-17 18:58:21 +00003997
3998 // If we've already seen any address-label statements that point to
3999 // this label, resolve them now.
4000 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
Mike Stump11289f42009-09-09 15:08:12 +00004001 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
Douglas Gregor779d8652009-04-17 18:58:21 +00004002 = UnresolvedAddrLabelExprs.equal_range(ID);
Mike Stump11289f42009-09-09 15:08:12 +00004003 for (AddrLabelIter AddrLabel = AddrLabels.first;
Douglas Gregor779d8652009-04-17 18:58:21 +00004004 AddrLabel != AddrLabels.second; ++AddrLabel)
4005 AddrLabel->second->setLabel(S);
4006 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004007}
4008
4009/// \brief Set the label of the given statement to the label
4010/// identified by ID.
4011///
4012/// Depending on the order in which the label and other statements
4013/// referencing that label occur, this operation may complete
4014/// immediately (updating the statement) or it may queue the
4015/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004016void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004017 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4018 if (Label != LabelStmts.end()) {
4019 // We've already seen this label, so set the label of the goto and
4020 // we're done.
4021 S->setLabel(Label->second);
4022 } else {
4023 // We haven't seen this label yet, so add this goto to the set of
4024 // unresolved goto statements.
4025 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
4026 }
4027}
Douglas Gregor779d8652009-04-17 18:58:21 +00004028
4029/// \brief Set the label of the given expression to the label
4030/// identified by ID.
4031///
4032/// Depending on the order in which the label and other statements
4033/// referencing that label occur, this operation may complete
4034/// immediately (updating the statement) or it may queue the
4035/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004036void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
Douglas Gregor779d8652009-04-17 18:58:21 +00004037 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4038 if (Label != LabelStmts.end()) {
4039 // We've already seen this label, so set the label of the
4040 // label-address expression and we're done.
4041 S->setLabel(Label->second);
4042 } else {
4043 // We haven't seen this label yet, so add this label-address
4044 // expression to the set of unresolved label-address expressions.
4045 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
4046 }
4047}
Douglas Gregor1342e842009-07-06 18:54:52 +00004048
Sebastian Redl2c499f62010-08-18 23:56:43 +00004049void ASTReader::FinishedDeserializing() {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004050 assert(NumCurrentElementsDeserializing &&
4051 "FinishedDeserializing not paired with StartedDeserializing");
4052 if (NumCurrentElementsDeserializing == 1) {
Douglas Gregor1342e842009-07-06 18:54:52 +00004053 // If any identifiers with corresponding top-level declarations have
4054 // been loaded, load those declarations now.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004055 while (!PendingIdentifierInfos.empty()) {
4056 SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
4057 PendingIdentifierInfos.front().DeclIDs, true);
4058 PendingIdentifierInfos.pop_front();
Douglas Gregor1342e842009-07-06 18:54:52 +00004059 }
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00004060
4061 // We are not in recursive loading, so it's safe to pass the "interesting"
4062 // decls to the consumer.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004063 if (Consumer)
4064 PassInterestingDeclsToConsumer();
Douglas Gregor1342e842009-07-06 18:54:52 +00004065 }
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004066 --NumCurrentElementsDeserializing;
Douglas Gregor1342e842009-07-06 18:54:52 +00004067}
Douglas Gregorb473b072010-08-19 00:28:17 +00004068
Sebastian Redld7dce0a2010-08-24 00:50:04 +00004069ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
4070 const char *isysroot, bool DisableValidation)
4071 : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
4072 SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
4073 Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
4074 Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
4075 NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
4076 TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
4077 NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
4078 NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
4079 TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
4080 TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
4081 TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
4082 RelocatablePCH = false;
4083}
4084
4085ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
4086 Diagnostic &Diags, const char *isysroot,
4087 bool DisableValidation)
4088 : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
4089 Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
4090 isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
4091 NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
4092 NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
4093 TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
4094 NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
4095 NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
4096 NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
4097 NumCurrentElementsDeserializing(0) {
4098 RelocatablePCH = false;
4099}
4100
4101ASTReader::~ASTReader() {
4102 for (unsigned i = 0, e = Chain.size(); i != e; ++i)
4103 delete Chain[e - i - 1];
4104 // Delete all visible decl lookup tables
4105 for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
4106 E = DeclContextOffsets.end();
4107 I != E; ++I) {
4108 for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
4109 J != F; ++J) {
4110 if (J->NameLookupTableData)
4111 delete static_cast<ASTDeclContextNameLookupTable*>(
4112 J->NameLookupTableData);
4113 }
4114 }
4115 for (DeclContextVisibleUpdatesPending::iterator
4116 I = PendingVisibleUpdates.begin(),
4117 E = PendingVisibleUpdates.end();
4118 I != E; ++I) {
4119 for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
4120 F = I->second.end();
4121 J != F; ++J)
4122 delete static_cast<ASTDeclContextNameLookupTable*>(*J);
4123 }
4124}
4125
Douglas Gregorb473b072010-08-19 00:28:17 +00004126ASTReader::PerFileData::PerFileData()
4127 : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
4128 LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
4129 IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0),
4130 LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
4131 NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0),
4132 SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0)
4133{}
4134
4135ASTReader::PerFileData::~PerFileData() {
4136 delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
4137 delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
4138}
4139