blob: 38b343ffe83d4713253c479453507f7b75f818d8 [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"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000023#include "clang/AST/Type.h"
John McCall8f115c62009-10-16 21:56:05 +000024#include "clang/AST/TypeLocVisitor.h"
Chris Lattner34321bc2009-04-10 21:41:48 +000025#include "clang/Lex/MacroInfo.h"
Douglas Gregoraae92242010-03-19 21:51:54 +000026#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000027#include "clang/Lex/Preprocessor.h"
Steve Naroff3fa455a2009-04-24 20:03:17 +000028#include "clang/Lex/HeaderSearch.h"
Douglas Gregora868bbd2009-04-21 22:25:48 +000029#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000030#include "clang/Basic/SourceManager.h"
Douglas Gregor4c7626e2009-04-13 16:31:14 +000031#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000032#include "clang/Basic/FileManager.h"
Douglas Gregorbfbde532009-04-10 21:16:55 +000033#include "clang/Basic/TargetInfo.h"
Douglas Gregord54f3a12009-10-05 21:07:28 +000034#include "clang/Basic/Version.h"
Daniel Dunbarf8502d52009-10-17 23:52:28 +000035#include "llvm/ADT/StringExtras.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000036#include "llvm/Bitcode/BitstreamReader.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000037#include "llvm/Support/MemoryBuffer.h"
John McCall0ad16662009-10-29 08:12:44 +000038#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +000039#include "llvm/System/Path.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000040#include <algorithm>
Douglas Gregorc379c072009-04-28 18:58:38 +000041#include <iterator>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000042#include <cstdio>
Douglas Gregorc5046832009-04-27 18:38:38 +000043#include <sys/stat.h>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000044using namespace clang;
Sebastian Redl539c5062010-08-18 23:57:32 +000045using namespace clang::serialization;
Douglas Gregoref84c4b2009-04-09 22:27:44 +000046
47//===----------------------------------------------------------------------===//
Sebastian Redld44cd6a2010-08-18 23:57:06 +000048// PCH validator implementation
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000049//===----------------------------------------------------------------------===//
50
Sebastian Redl3e31c722010-08-18 23:56:56 +000051ASTReaderListener::~ASTReaderListener() {}
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000052
53bool
54PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
55 const LangOptions &PPLangOpts = PP.getLangOptions();
56#define PARSE_LANGOPT_BENIGN(Option)
57#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
58 if (PPLangOpts.Option != LangOpts.Option) { \
59 Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
60 return true; \
61 }
62
63 PARSE_LANGOPT_BENIGN(Trigraphs);
64 PARSE_LANGOPT_BENIGN(BCPLComment);
65 PARSE_LANGOPT_BENIGN(DollarIdents);
66 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
67 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
Chandler Carruthe03aa552010-04-17 20:17:31 +000068 PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000069 PARSE_LANGOPT_BENIGN(ImplicitInt);
70 PARSE_LANGOPT_BENIGN(Digraphs);
71 PARSE_LANGOPT_BENIGN(HexFloats);
72 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
73 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
74 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
75 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
76 PARSE_LANGOPT_BENIGN(CXXOperatorName);
77 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
78 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
79 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
Fariborz Jahanian45878032010-02-09 19:31:38 +000080 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +000081 PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
82 diag::warn_pch_no_constant_cfstrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000083 PARSE_LANGOPT_BENIGN(PascalStrings);
84 PARSE_LANGOPT_BENIGN(WritableStrings);
Mike Stump11289f42009-09-09 15:08:12 +000085 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000086 diag::warn_pch_lax_vector_conversions);
Nate Begeman9d905792009-06-25 22:57:40 +000087 PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000088 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +000089 PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000090 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
91 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
92 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
Mike Stump11289f42009-09-09 15:08:12 +000093 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000094 diag::warn_pch_thread_safe_statics);
Daniel Dunbara77eaeb2009-09-03 04:54:28 +000095 PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000096 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
97 PARSE_LANGOPT_BENIGN(EmitAllDecls);
98 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
Chris Lattner51924e512010-06-26 21:25:03 +000099 PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
Mike Stump11289f42009-09-09 15:08:12 +0000100 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000101 diag::warn_pch_heinous_extensions);
102 // FIXME: Most of the options below are benign if the macro wasn't
103 // used. Unfortunately, this means that a PCH compiled without
104 // optimization can't be used with optimization turned on, even
105 // though the only thing that changes is whether __OPTIMIZE__ was
106 // defined... but if __OPTIMIZE__ never showed up in the header, it
107 // doesn't matter. We could consider making this some special kind
108 // of check.
109 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
110 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
111 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
112 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
113 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
114 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
115 PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
116 PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
John Thompsoned4e2952009-11-05 20:14:16 +0000117 PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000118 if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
Mike Stump11289f42009-09-09 15:08:12 +0000119 Reader.Diag(diag::warn_pch_gc_mode)
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000120 << LangOpts.getGCMode() << PPLangOpts.getGCMode();
121 return true;
122 }
123 PARSE_LANGOPT_BENIGN(getVisibilityMode());
Daniel Dunbar143021e2009-09-21 04:16:19 +0000124 PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
125 diag::warn_pch_stack_protector);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000126 PARSE_LANGOPT_BENIGN(InstantiationDepth);
Nate Begeman9d905792009-06-25 22:57:40 +0000127 PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
Mike Stumpd9546382009-12-12 01:27:46 +0000128 PARSE_LANGOPT_BENIGN(CatchUndefined);
Daniel Dunbar143021e2009-09-21 04:16:19 +0000129 PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
Douglas Gregor8ed0c0b2010-07-09 17:35:33 +0000130 PARSE_LANGOPT_BENIGN(SpellChecking);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +0000131#undef PARSE_LANGOPT_IMPORTANT
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000132#undef PARSE_LANGOPT_BENIGN
133
134 return false;
135}
136
Daniel Dunbar20a682d2009-11-11 00:52:11 +0000137bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
138 if (Triple == PP.getTargetInfo().getTriple().str())
139 return false;
140
141 Reader.Diag(diag::warn_pch_target_triple)
142 << Triple << PP.getTargetInfo().getTriple().str();
143 return true;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000144}
145
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000146struct EmptyStringRef {
Benjamin Kramer8d5609b2010-07-14 23:19:41 +0000147 bool operator ()(llvm::StringRef r) const { return r.empty(); }
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000148};
149struct EmptyBlock {
150 bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); }
151};
152
153static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
154 PCHPredefinesBlocks R) {
155 // First, sum up the lengths.
156 unsigned LL = 0, RL = 0;
157 for (unsigned I = 0, N = L.size(); I != N; ++I) {
158 LL += L[I].size();
159 }
160 for (unsigned I = 0, N = R.size(); I != N; ++I) {
161 RL += R[I].Data.size();
162 }
163 if (LL != RL)
164 return false;
165 if (LL == 0 && RL == 0)
166 return true;
167
168 // Kick out empty parts, they confuse the algorithm below.
169 L.erase(std::remove_if(L.begin(), L.end(), EmptyStringRef()), L.end());
170 R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
171
172 // Do it the hard way. At this point, both vectors must be non-empty.
173 llvm::StringRef LR = L[0], RR = R[0].Data;
174 unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
Daniel Dunbar01ad0a72010-07-16 00:00:11 +0000175 (void) RN;
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000176 for (;;) {
177 // Compare the current pieces.
178 if (LR.size() == RR.size()) {
179 // If they're the same length, it's pretty easy.
180 if (LR != RR)
181 return false;
182 // Both pieces are done, advance.
183 ++LI;
184 ++RI;
185 // If either string is done, they're both done, since they're the same
186 // length.
187 if (LI == LN) {
188 assert(RI == RN && "Strings not the same length after all?");
189 return true;
190 }
191 LR = L[LI];
192 RR = R[RI].Data;
193 } else if (LR.size() < RR.size()) {
194 // Right piece is longer.
195 if (!RR.startswith(LR))
196 return false;
197 ++LI;
198 assert(LI != LN && "Strings not the same length after all?");
199 RR = RR.substr(LR.size());
200 LR = L[LI];
201 } else {
202 // Left piece is longer.
203 if (!LR.startswith(RR))
204 return false;
205 ++RI;
206 assert(RI != RN && "Strings not the same length after all?");
207 LR = LR.substr(RR.size());
208 RR = R[RI].Data;
209 }
210 }
211}
212
213static std::pair<FileID, llvm::StringRef::size_type>
214FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
215 std::pair<FileID, llvm::StringRef::size_type> Res;
216 for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
217 Res.second = Buffers[I].Data.find(MacroDef);
218 if (Res.second != llvm::StringRef::npos) {
219 Res.first = Buffers[I].BufferID;
220 break;
221 }
222 }
223 return Res;
224}
225
226bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000227 llvm::StringRef OriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000228 std::string &SuggestedPredefines) {
Daniel Dunbar732ef8a2009-11-11 23:58:53 +0000229 // We are in the context of an implicit include, so the predefines buffer will
230 // have a #include entry for the PCH file itself (as normalized by the
231 // preprocessor initialization). Find it and skip over it in the checking
232 // below.
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000233 llvm::SmallString<256> PCHInclude;
234 PCHInclude += "#include \"";
Daniel Dunbar732ef8a2009-11-11 23:58:53 +0000235 PCHInclude += NormalizeDashIncludePath(OriginalFileName);
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000236 PCHInclude += "\"\n";
237 std::pair<llvm::StringRef,llvm::StringRef> Split =
238 llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
239 llvm::StringRef Left = Split.first, Right = Split.second;
Ted Kremenek1ff615c2010-03-18 00:56:54 +0000240 if (Left == PP.getPredefines()) {
241 Error("Missing PCH include entry!");
242 return true;
243 }
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000244
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000245 // If the concatenation of all the PCH buffers is equal to the adjusted
246 // command line, we're done.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000247 llvm::SmallVector<llvm::StringRef, 2> CommandLine;
248 CommandLine.push_back(Left);
249 CommandLine.push_back(Right);
250 if (EqualConcatenations(CommandLine, Buffers))
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000251 return false;
252
253 SourceManager &SourceMgr = PP.getSourceManager();
Mike Stump11289f42009-09-09 15:08:12 +0000254
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000255 // The predefines buffers are different. Determine what the differences are,
256 // and whether they require us to reject the PCH file.
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000257 llvm::SmallVector<llvm::StringRef, 8> PCHLines;
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000258 for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
259 Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000260
261 llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
262 Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
263 Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000264
Daniel Dunbar499baed2009-11-11 05:26:28 +0000265 // Sort both sets of predefined buffer lines, since we allow some extra
266 // definitions and they may appear at any point in the output.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000267 std::sort(CmdLineLines.begin(), CmdLineLines.end());
268 std::sort(PCHLines.begin(), PCHLines.end());
269
Daniel Dunbar499baed2009-11-11 05:26:28 +0000270 // Determine which predefines that were used to build the PCH file are missing
271 // from the command line.
272 std::vector<llvm::StringRef> MissingPredefines;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000273 std::set_difference(PCHLines.begin(), PCHLines.end(),
274 CmdLineLines.begin(), CmdLineLines.end(),
275 std::back_inserter(MissingPredefines));
276
277 bool MissingDefines = false;
278 bool ConflictingDefines = false;
279 for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
Daniel Dunbar499baed2009-11-11 05:26:28 +0000280 llvm::StringRef Missing = MissingPredefines[I];
281 if (!Missing.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000282 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
283 return true;
284 }
Mike Stump11289f42009-09-09 15:08:12 +0000285
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000286 // This is a macro definition. Determine the name of the macro we're
287 // defining.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000288 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump11289f42009-09-09 15:08:12 +0000289 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000290 = Missing.find_first_of("( \n\r", StartOfMacroName);
291 assert(EndOfMacroName != std::string::npos &&
292 "Couldn't find the end of the macro name");
Daniel Dunbar499baed2009-11-11 05:26:28 +0000293 llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000294
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000295 // Determine whether this macro was given a different definition on the
296 // command line.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000297 std::string MacroDefStart = "#define " + MacroName.str();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000298 std::string::size_type MacroDefLen = MacroDefStart.size();
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000299 llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000300 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
301 MacroDefStart);
302 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000303 if (!ConflictPos->startswith(MacroDefStart)) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000304 // Different macro; we're done.
305 ConflictPos = CmdLineLines.end();
Mike Stump11289f42009-09-09 15:08:12 +0000306 break;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000307 }
Mike Stump11289f42009-09-09 15:08:12 +0000308
309 assert(ConflictPos->size() > MacroDefLen &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000310 "Invalid #define in predefines buffer?");
Mike Stump11289f42009-09-09 15:08:12 +0000311 if ((*ConflictPos)[MacroDefLen] != ' ' &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000312 (*ConflictPos)[MacroDefLen] != '(')
313 continue; // Longer macro name; keep trying.
Mike Stump11289f42009-09-09 15:08:12 +0000314
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000315 // We found a conflicting macro definition.
316 break;
317 }
Mike Stump11289f42009-09-09 15:08:12 +0000318
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000319 if (ConflictPos != CmdLineLines.end()) {
320 Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
321 << MacroName;
322
323 // Show the definition of this macro within the PCH file.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000324 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
325 FindMacro(Buffers, Missing);
326 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
327 SourceLocation PCHMissingLoc =
328 SourceMgr.getLocForStartOfFile(MacroLoc.first)
329 .getFileLocWithOffset(MacroLoc.second);
Daniel Dunbar499baed2009-11-11 05:26:28 +0000330 Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000331
332 ConflictingDefines = true;
333 continue;
334 }
Mike Stump11289f42009-09-09 15:08:12 +0000335
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000336 // If the macro doesn't conflict, then we'll just pick up the macro
337 // definition from the PCH file. Warn the user that they made a mistake.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000338 if (ConflictingDefines)
339 continue; // Don't complain if there are already conflicting defs
Mike Stump11289f42009-09-09 15:08:12 +0000340
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000341 if (!MissingDefines) {
342 Reader.Diag(diag::warn_cmdline_missing_macro_defs);
343 MissingDefines = true;
344 }
345
346 // Show the definition of this macro within the PCH file.
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000347 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
348 FindMacro(Buffers, Missing);
349 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
350 SourceLocation PCHMissingLoc =
351 SourceMgr.getLocForStartOfFile(MacroLoc.first)
352 .getFileLocWithOffset(MacroLoc.second);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000353 Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
354 }
Mike Stump11289f42009-09-09 15:08:12 +0000355
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000356 if (ConflictingDefines)
357 return true;
Mike Stump11289f42009-09-09 15:08:12 +0000358
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000359 // Determine what predefines were introduced based on command-line
360 // parameters that were not present when building the PCH
361 // file. Extra #defines are okay, so long as the identifiers being
362 // defined were not used within the precompiled header.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000363 std::vector<llvm::StringRef> ExtraPredefines;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000364 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
365 PCHLines.begin(), PCHLines.end(),
Mike Stump11289f42009-09-09 15:08:12 +0000366 std::back_inserter(ExtraPredefines));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000367 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
Daniel Dunbar499baed2009-11-11 05:26:28 +0000368 llvm::StringRef &Extra = ExtraPredefines[I];
369 if (!Extra.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000370 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
371 return true;
372 }
373
374 // This is an extra macro definition. Determine the name of the
375 // macro we're defining.
376 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump11289f42009-09-09 15:08:12 +0000377 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000378 = Extra.find_first_of("( \n\r", StartOfMacroName);
379 assert(EndOfMacroName != std::string::npos &&
380 "Couldn't find the end of the macro name");
Daniel Dunbar499baed2009-11-11 05:26:28 +0000381 llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000382
383 // Check whether this name was used somewhere in the PCH file. If
384 // so, defining it as a macro could change behavior, so we reject
385 // the PCH file.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000386 if (IdentifierInfo *II = Reader.get(MacroName)) {
Daniel Dunbar045c92f2009-11-11 00:52:00 +0000387 Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000388 return true;
389 }
390
391 // Add this definition to the suggested predefines buffer.
392 SuggestedPredefines += Extra;
393 SuggestedPredefines += '\n';
394 }
395
396 // If we get here, it's because the predefines buffer had compatible
397 // contents. Accept the PCH file.
398 return false;
399}
400
Douglas Gregor5712ebc2010-03-16 16:35:32 +0000401void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
402 unsigned ID) {
403 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
404 ++NumHeaderInfos;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000405}
406
407void PCHValidator::ReadCounter(unsigned Value) {
408 PP.setCounterValue(Value);
409}
410
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000411//===----------------------------------------------------------------------===//
Sebastian Redl2c499f62010-08-18 23:56:43 +0000412// AST reader implementation
Douglas Gregora868bbd2009-04-21 22:25:48 +0000413//===----------------------------------------------------------------------===//
414
Sebastian Redl07a89a82010-07-30 00:29:29 +0000415void
Sebastian Redl3e31c722010-08-18 23:56:56 +0000416ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
Sebastian Redl07a89a82010-07-30 00:29:29 +0000417 DeserializationListener = Listener;
418 if (DeserializationListener)
419 DeserializationListener->SetReader(this);
420}
421
Chris Lattner92ba5ff2009-04-27 05:14:47 +0000422
Douglas Gregora868bbd2009-04-21 22:25:48 +0000423namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000424class ASTSelectorLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000425 ASTReader &Reader;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000426
427public:
Sebastian Redl834bb972010-08-04 17:20:04 +0000428 struct data_type {
Sebastian Redl539c5062010-08-18 23:57:32 +0000429 SelectorID ID;
Sebastian Redl834bb972010-08-04 17:20:04 +0000430 ObjCMethodList Instance, Factory;
431 };
Douglas Gregorc78d3462009-04-24 21:10:55 +0000432
433 typedef Selector external_key_type;
434 typedef external_key_type internal_key_type;
435
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000436 explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
Mike Stump11289f42009-09-09 15:08:12 +0000437
Douglas Gregorc78d3462009-04-24 21:10:55 +0000438 static bool EqualKey(const internal_key_type& a,
439 const internal_key_type& b) {
440 return a == b;
441 }
Mike Stump11289f42009-09-09 15:08:12 +0000442
Douglas Gregorc78d3462009-04-24 21:10:55 +0000443 static unsigned ComputeHash(Selector Sel) {
Argyrios Kyrtzidis4bd97102010-08-20 16:03:52 +0000444 return serialization::ComputeHash(Sel);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000445 }
Mike Stump11289f42009-09-09 15:08:12 +0000446
Douglas Gregorc78d3462009-04-24 21:10:55 +0000447 // This hopefully will just get inlined and removed by the optimizer.
448 static const internal_key_type&
449 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump11289f42009-09-09 15:08:12 +0000450
Douglas Gregorc78d3462009-04-24 21:10:55 +0000451 static std::pair<unsigned, unsigned>
452 ReadKeyDataLength(const unsigned char*& d) {
453 using namespace clang::io;
454 unsigned KeyLen = ReadUnalignedLE16(d);
455 unsigned DataLen = ReadUnalignedLE16(d);
456 return std::make_pair(KeyLen, DataLen);
457 }
Mike Stump11289f42009-09-09 15:08:12 +0000458
Douglas Gregor95c13f52009-04-25 17:48:32 +0000459 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000460 using namespace clang::io;
Chris Lattner8575daa2009-04-27 21:45:14 +0000461 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000462 unsigned N = ReadUnalignedLE16(d);
Mike Stump11289f42009-09-09 15:08:12 +0000463 IdentifierInfo *FirstII
Douglas Gregorc78d3462009-04-24 21:10:55 +0000464 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
465 if (N == 0)
466 return SelTable.getNullarySelector(FirstII);
467 else if (N == 1)
468 return SelTable.getUnarySelector(FirstII);
469
470 llvm::SmallVector<IdentifierInfo *, 16> Args;
471 Args.push_back(FirstII);
472 for (unsigned I = 1; I != N; ++I)
473 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
474
Douglas Gregor038c3382009-05-22 22:45:36 +0000475 return SelTable.getSelector(N, Args.data());
Douglas Gregorc78d3462009-04-24 21:10:55 +0000476 }
Mike Stump11289f42009-09-09 15:08:12 +0000477
Douglas Gregorc78d3462009-04-24 21:10:55 +0000478 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
479 using namespace clang::io;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000480
481 data_type Result;
482
Sebastian Redl834bb972010-08-04 17:20:04 +0000483 Result.ID = ReadUnalignedLE32(d);
484 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
485 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
486
Douglas Gregorc78d3462009-04-24 21:10:55 +0000487 // Load instance methods
488 ObjCMethodList *Prev = 0;
489 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +0000490 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000491 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000492 if (!Result.Instance.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000493 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000494 Result.Instance.Method = Method;
495 Prev = &Result.Instance;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000496 continue;
497 }
498
Ted Kremenekda4abf12010-02-11 00:53:01 +0000499 ObjCMethodList *Mem =
500 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
501 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000502 Prev = Prev->Next;
503 }
504
505 // Load factory methods
506 Prev = 0;
507 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +0000508 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000509 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000510 if (!Result.Factory.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000511 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000512 Result.Factory.Method = Method;
513 Prev = &Result.Factory;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000514 continue;
515 }
516
Ted Kremenekda4abf12010-02-11 00:53:01 +0000517 ObjCMethodList *Mem =
518 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
519 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000520 Prev = Prev->Next;
521 }
522
523 return Result;
524 }
525};
Mike Stump11289f42009-09-09 15:08:12 +0000526
527} // end anonymous namespace
Douglas Gregorc78d3462009-04-24 21:10:55 +0000528
529/// \brief The on-disk hash table used for the global method pool.
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000530typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
531 ASTSelectorLookupTable;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000532
533namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000534class ASTIdentifierLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000535 ASTReader &Reader;
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000536 llvm::BitstreamCursor &Stream;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000537
538 // If we know the IdentifierInfo in advance, it is here and we will
539 // not build a new one. Used when deserializing information about an
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000540 // identifier that was constructed before the AST file was read.
Douglas Gregora868bbd2009-04-21 22:25:48 +0000541 IdentifierInfo *KnownII;
542
543public:
544 typedef IdentifierInfo * data_type;
545
546 typedef const std::pair<const char*, unsigned> external_key_type;
547
548 typedef external_key_type internal_key_type;
549
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000550 ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000551 IdentifierInfo *II = 0)
552 : Reader(Reader), Stream(Stream), KnownII(II) { }
Mike Stump11289f42009-09-09 15:08:12 +0000553
Douglas Gregora868bbd2009-04-21 22:25:48 +0000554 static bool EqualKey(const internal_key_type& a,
555 const internal_key_type& b) {
556 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
557 : false;
558 }
Mike Stump11289f42009-09-09 15:08:12 +0000559
Douglas Gregora868bbd2009-04-21 22:25:48 +0000560 static unsigned ComputeHash(const internal_key_type& a) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000561 return llvm::HashString(llvm::StringRef(a.first, a.second));
Douglas Gregora868bbd2009-04-21 22:25:48 +0000562 }
Mike Stump11289f42009-09-09 15:08:12 +0000563
Douglas Gregora868bbd2009-04-21 22:25:48 +0000564 // This hopefully will just get inlined and removed by the optimizer.
565 static const internal_key_type&
566 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump11289f42009-09-09 15:08:12 +0000567
Douglas Gregora868bbd2009-04-21 22:25:48 +0000568 static std::pair<unsigned, unsigned>
569 ReadKeyDataLength(const unsigned char*& d) {
570 using namespace clang::io;
Douglas Gregor6b7bf5a2009-04-25 20:26:24 +0000571 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregor5287b4e2009-04-25 21:04:17 +0000572 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000573 return std::make_pair(KeyLen, DataLen);
574 }
Mike Stump11289f42009-09-09 15:08:12 +0000575
Douglas Gregora868bbd2009-04-21 22:25:48 +0000576 static std::pair<const char*, unsigned>
577 ReadKey(const unsigned char* d, unsigned n) {
578 assert(n >= 2 && d[n-1] == '\0');
579 return std::make_pair((const char*) d, n-1);
580 }
Mike Stump11289f42009-09-09 15:08:12 +0000581
582 IdentifierInfo *ReadData(const internal_key_type& k,
Douglas Gregora868bbd2009-04-21 22:25:48 +0000583 const unsigned char* d,
584 unsigned DataLen) {
585 using namespace clang::io;
Sebastian Redl539c5062010-08-18 23:57:32 +0000586 IdentID ID = ReadUnalignedLE32(d);
Douglas Gregor1d583f22009-04-28 21:18:29 +0000587 bool IsInteresting = ID & 0x01;
588
589 // Wipe out the "is interesting" bit.
590 ID = ID >> 1;
591
592 if (!IsInteresting) {
Sebastian Redl98912122010-07-27 23:01:28 +0000593 // For uninteresting identifiers, just build the IdentifierInfo
Douglas Gregor1d583f22009-04-28 21:18:29 +0000594 // and associate it with the persistent ID.
595 IdentifierInfo *II = KnownII;
596 if (!II)
Sebastian Redl07a89a82010-07-30 00:29:29 +0000597 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregor1d583f22009-04-28 21:18:29 +0000598 Reader.SetIdentifierInfo(ID, II);
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000599 II->setIsFromAST();
Douglas Gregor1d583f22009-04-28 21:18:29 +0000600 return II;
601 }
602
Douglas Gregorb9256522009-04-28 21:32:13 +0000603 unsigned Bits = ReadUnalignedLE16(d);
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000604 bool CPlusPlusOperatorKeyword = Bits & 0x01;
605 Bits >>= 1;
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000606 bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
607 Bits >>= 1;
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000608 bool Poisoned = Bits & 0x01;
609 Bits >>= 1;
610 bool ExtensionToken = Bits & 0x01;
611 Bits >>= 1;
612 bool hasMacroDefinition = Bits & 0x01;
613 Bits >>= 1;
614 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
615 Bits >>= 10;
Mike Stump11289f42009-09-09 15:08:12 +0000616
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000617 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregorb9256522009-04-28 21:32:13 +0000618 DataLen -= 6;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000619
620 // Build the IdentifierInfo itself and link the identifier ID with
621 // the new IdentifierInfo.
622 IdentifierInfo *II = KnownII;
623 if (!II)
Sebastian Redl07a89a82010-07-30 00:29:29 +0000624 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000625 Reader.SetIdentifierInfo(ID, II);
626
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000627 // Set or check the various bits in the IdentifierInfo structure.
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000628 // Token IDs are read-only.
629 if (HasRevertedTokenIDToIdentifier)
630 II->RevertTokenIDToIdentifier();
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000631 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
Mike Stump11289f42009-09-09 15:08:12 +0000632 assert(II->isExtensionToken() == ExtensionToken &&
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000633 "Incorrect extension token flag");
634 (void)ExtensionToken;
635 II->setIsPoisoned(Poisoned);
636 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
637 "Incorrect C++ operator keyword flag");
638 (void)CPlusPlusOperatorKeyword;
639
Douglas Gregorc3366a52009-04-21 23:56:24 +0000640 // If this identifier is a macro, deserialize the macro
641 // definition.
642 if (hasMacroDefinition) {
Douglas Gregorb9256522009-04-28 21:32:13 +0000643 uint32_t Offset = ReadUnalignedLE32(d);
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000644 Reader.ReadMacroRecord(Stream, Offset);
Douglas Gregorb9256522009-04-28 21:32:13 +0000645 DataLen -= 4;
Douglas Gregorc3366a52009-04-21 23:56:24 +0000646 }
Douglas Gregora868bbd2009-04-21 22:25:48 +0000647
648 // Read all of the declarations visible at global scope with this
649 // name.
Chris Lattner1d728882009-04-27 22:17:41 +0000650 if (Reader.getContext() == 0) return II;
Douglas Gregor1342e842009-07-06 18:54:52 +0000651 if (DataLen > 0) {
652 llvm::SmallVector<uint32_t, 4> DeclIDs;
653 for (; DataLen > 0; DataLen -= 4)
654 DeclIDs.push_back(ReadUnalignedLE32(d));
655 Reader.SetGloballyVisibleDecls(II, DeclIDs);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000656 }
Mike Stump11289f42009-09-09 15:08:12 +0000657
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000658 II->setIsFromAST();
Douglas Gregora868bbd2009-04-21 22:25:48 +0000659 return II;
660 }
661};
Mike Stump11289f42009-09-09 15:08:12 +0000662
663} // end anonymous namespace
Douglas Gregora868bbd2009-04-21 22:25:48 +0000664
665/// \brief The on-disk hash table used to contain information about
666/// all of the identifiers in the program.
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000667typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
668 ASTIdentifierLookupTable;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000669
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +0000670namespace {
671class ASTDeclContextNameLookupTrait {
672 ASTReader &Reader;
673
674public:
675 /// \brief Pair of begin/end iterators for DeclIDs.
676 typedef std::pair<DeclID *, DeclID *> data_type;
677
678 /// \brief Special internal key for declaration names.
679 /// The hash table creates keys for comparison; we do not create
680 /// a DeclarationName for the internal key to avoid deserializing types.
681 struct DeclNameKey {
682 DeclarationName::NameKind Kind;
683 uint64_t Data;
684 DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
685 };
686
687 typedef DeclarationName external_key_type;
688 typedef DeclNameKey internal_key_type;
689
690 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
691
692 static bool EqualKey(const internal_key_type& a,
693 const internal_key_type& b) {
694 return a.Kind == b.Kind && a.Data == b.Data;
695 }
696
697 unsigned ComputeHash(const DeclNameKey &Key) const {
698 llvm::FoldingSetNodeID ID;
699 ID.AddInteger(Key.Kind);
700
701 switch (Key.Kind) {
702 case DeclarationName::Identifier:
703 case DeclarationName::CXXLiteralOperatorName:
704 ID.AddString(((IdentifierInfo*)Key.Data)->getName());
705 break;
706 case DeclarationName::ObjCZeroArgSelector:
707 case DeclarationName::ObjCOneArgSelector:
708 case DeclarationName::ObjCMultiArgSelector:
709 ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
710 break;
711 case DeclarationName::CXXConstructorName:
712 case DeclarationName::CXXDestructorName:
713 case DeclarationName::CXXConversionFunctionName:
714 ID.AddInteger((TypeID)Key.Data);
715 break;
716 case DeclarationName::CXXOperatorName:
717 ID.AddInteger((OverloadedOperatorKind)Key.Data);
718 break;
719 case DeclarationName::CXXUsingDirective:
720 break;
721 }
722
723 return ID.ComputeHash();
724 }
725
726 internal_key_type GetInternalKey(const external_key_type& Name) const {
727 DeclNameKey Key;
728 Key.Kind = Name.getNameKind();
729 switch (Name.getNameKind()) {
730 case DeclarationName::Identifier:
731 Key.Data = (uint64_t)Name.getAsIdentifierInfo();
732 break;
733 case DeclarationName::ObjCZeroArgSelector:
734 case DeclarationName::ObjCOneArgSelector:
735 case DeclarationName::ObjCMultiArgSelector:
736 Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
737 break;
738 case DeclarationName::CXXConstructorName:
739 case DeclarationName::CXXDestructorName:
740 case DeclarationName::CXXConversionFunctionName:
741 Key.Data = Reader.GetTypeID(Name.getCXXNameType());
742 break;
743 case DeclarationName::CXXOperatorName:
744 Key.Data = Name.getCXXOverloadedOperator();
745 break;
746 case DeclarationName::CXXLiteralOperatorName:
747 Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
748 break;
749 case DeclarationName::CXXUsingDirective:
750 break;
751 }
752
753 return Key;
754 }
755
Argyrios Kyrtzidisd32ee892010-08-20 23:35:55 +0000756 external_key_type GetExternalKey(const internal_key_type& Key) const {
757 ASTContext *Context = Reader.getContext();
758 switch (Key.Kind) {
759 case DeclarationName::Identifier:
760 return DeclarationName((IdentifierInfo*)Key.Data);
761
762 case DeclarationName::ObjCZeroArgSelector:
763 case DeclarationName::ObjCOneArgSelector:
764 case DeclarationName::ObjCMultiArgSelector:
765 return DeclarationName(Selector(Key.Data));
766
767 case DeclarationName::CXXConstructorName:
768 return Context->DeclarationNames.getCXXConstructorName(
769 Context->getCanonicalType(Reader.GetType(Key.Data)));
770
771 case DeclarationName::CXXDestructorName:
772 return Context->DeclarationNames.getCXXDestructorName(
773 Context->getCanonicalType(Reader.GetType(Key.Data)));
774
775 case DeclarationName::CXXConversionFunctionName:
776 return Context->DeclarationNames.getCXXConversionFunctionName(
777 Context->getCanonicalType(Reader.GetType(Key.Data)));
778
779 case DeclarationName::CXXOperatorName:
780 return Context->DeclarationNames.getCXXOperatorName(
781 (OverloadedOperatorKind)Key.Data);
782
783 case DeclarationName::CXXLiteralOperatorName:
784 return Context->DeclarationNames.getCXXLiteralOperatorName(
785 (IdentifierInfo*)Key.Data);
786
787 case DeclarationName::CXXUsingDirective:
788 return DeclarationName::getUsingDirectiveName();
789 }
790
791 llvm_unreachable("Invalid Name Kind ?");
792 }
793
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +0000794 static std::pair<unsigned, unsigned>
795 ReadKeyDataLength(const unsigned char*& d) {
796 using namespace clang::io;
797 unsigned KeyLen = ReadUnalignedLE16(d);
798 unsigned DataLen = ReadUnalignedLE16(d);
799 return std::make_pair(KeyLen, DataLen);
800 }
801
802 internal_key_type ReadKey(const unsigned char* d, unsigned) {
803 using namespace clang::io;
804
805 DeclNameKey Key;
806 Key.Kind = (DeclarationName::NameKind)*d++;
807 switch (Key.Kind) {
808 case DeclarationName::Identifier:
809 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
810 break;
811 case DeclarationName::ObjCZeroArgSelector:
812 case DeclarationName::ObjCOneArgSelector:
813 case DeclarationName::ObjCMultiArgSelector:
814 Key.Data =
815 (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
816 break;
817 case DeclarationName::CXXConstructorName:
818 case DeclarationName::CXXDestructorName:
819 case DeclarationName::CXXConversionFunctionName:
820 Key.Data = ReadUnalignedLE32(d); // TypeID
821 break;
822 case DeclarationName::CXXOperatorName:
823 Key.Data = *d++; // OverloadedOperatorKind
824 break;
825 case DeclarationName::CXXLiteralOperatorName:
826 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
827 break;
828 case DeclarationName::CXXUsingDirective:
829 break;
830 }
831
832 return Key;
833 }
834
835 data_type ReadData(internal_key_type, const unsigned char* d,
836 unsigned DataLen) {
837 using namespace clang::io;
838 unsigned NumDecls = ReadUnalignedLE16(d);
839 DeclID *Start = (DeclID *)d;
840 return std::make_pair(Start, Start + NumDecls);
841 }
842};
843
844} // end anonymous namespace
845
846/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
847typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
848 ASTDeclContextNameLookupTable;
849
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +0000850bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
851 const std::pair<uint64_t, uint64_t> &Offsets,
852 DeclContextInfo &Info) {
853 SavedStreamPosition SavedPosition(Cursor);
854 // First the lexical decls.
855 if (Offsets.first != 0) {
856 Cursor.JumpToBit(Offsets.first);
857
858 RecordData Record;
859 const char *Blob;
860 unsigned BlobLen;
861 unsigned Code = Cursor.ReadCode();
862 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
863 if (RecCode != DECL_CONTEXT_LEXICAL) {
864 Error("Expected lexical block");
865 return true;
866 }
867
868 Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
869 Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
870 } else {
871 Info.LexicalDecls = 0;
872 Info.NumLexicalDecls = 0;
873 }
874
875 // Now the lookup table.
876 if (Offsets.second != 0) {
877 Cursor.JumpToBit(Offsets.second);
878
879 RecordData Record;
880 const char *Blob;
881 unsigned BlobLen;
882 unsigned Code = Cursor.ReadCode();
883 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
884 if (RecCode != DECL_CONTEXT_VISIBLE) {
885 Error("Expected visible lookup table block");
886 return true;
887 }
888 Info.NameLookupTableData
889 = ASTDeclContextNameLookupTable::Create(
890 (const unsigned char *)Blob + Record[0],
891 (const unsigned char *)Blob,
892 ASTDeclContextNameLookupTrait(*this));
Sebastian Redl9d8f58b2010-08-24 00:50:00 +0000893 } else {
894 Info.NameLookupTableData = 0;
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +0000895 }
896
897 return false;
898}
899
Sebastian Redl2c499f62010-08-18 23:56:43 +0000900void ASTReader::Error(const char *Msg) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +0000901 Diag(diag::err_fe_pch_malformed) << Msg;
Douglas Gregoref84c4b2009-04-09 22:27:44 +0000902}
903
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000904/// \brief Tell the AST listener about the predefines buffers in the chain.
Sebastian Redl2c499f62010-08-18 23:56:43 +0000905bool ASTReader::CheckPredefinesBuffers() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000906 if (Listener)
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000907 return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000908 ActualOriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000909 SuggestedPredefines);
Douglas Gregorc379c072009-04-28 18:58:38 +0000910 return false;
Douglas Gregor92863e42009-04-10 23:10:45 +0000911}
912
Douglas Gregorc5046832009-04-27 18:38:38 +0000913//===----------------------------------------------------------------------===//
914// Source Manager Deserialization
915//===----------------------------------------------------------------------===//
916
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000917/// \brief Read the line table in the source manager block.
918/// \returns true if ther was an error.
Sebastian Redl2c499f62010-08-18 23:56:43 +0000919bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000920 unsigned Idx = 0;
921 LineTableInfo &LineTable = SourceMgr.getLineTable();
922
923 // Parse the file names
Douglas Gregora8854652009-04-13 17:12:42 +0000924 std::map<int, int> FileIDs;
925 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000926 // Extract the file name
927 unsigned FilenameLen = Record[Idx++];
928 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
929 Idx += FilenameLen;
Douglas Gregor0086a5a2009-07-07 00:12:59 +0000930 MaybeAddSystemRootToFilename(Filename);
Mike Stump11289f42009-09-09 15:08:12 +0000931 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Douglas Gregora8854652009-04-13 17:12:42 +0000932 Filename.size());
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000933 }
934
935 // Parse the line entries
936 std::vector<LineEntry> Entries;
937 while (Idx < Record.size()) {
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000938 int FID = Record[Idx++];
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000939
940 // Extract the line entries
941 unsigned NumEntries = Record[Idx++];
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000942 assert(NumEntries && "Numentries is 00000");
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000943 Entries.clear();
944 Entries.reserve(NumEntries);
945 for (unsigned I = 0; I != NumEntries; ++I) {
946 unsigned FileOffset = Record[Idx++];
947 unsigned LineNo = Record[Idx++];
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000948 int FilenameID = FileIDs[Record[Idx++]];
Mike Stump11289f42009-09-09 15:08:12 +0000949 SrcMgr::CharacteristicKind FileKind
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000950 = (SrcMgr::CharacteristicKind)Record[Idx++];
951 unsigned IncludeOffset = Record[Idx++];
952 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
953 FileKind, IncludeOffset));
954 }
955 LineTable.AddEntry(FID, Entries);
956 }
957
958 return false;
959}
960
Douglas Gregorc5046832009-04-27 18:38:38 +0000961namespace {
962
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000963class ASTStatData {
Douglas Gregorc5046832009-04-27 18:38:38 +0000964public:
965 const bool hasStat;
966 const ino_t ino;
967 const dev_t dev;
968 const mode_t mode;
969 const time_t mtime;
970 const off_t size;
Mike Stump11289f42009-09-09 15:08:12 +0000971
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000972 ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
Mike Stump11289f42009-09-09 15:08:12 +0000973 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
974
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000975 ASTStatData()
Douglas Gregorc5046832009-04-27 18:38:38 +0000976 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
977};
978
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000979class ASTStatLookupTrait {
Douglas Gregorc5046832009-04-27 18:38:38 +0000980 public:
981 typedef const char *external_key_type;
982 typedef const char *internal_key_type;
983
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000984 typedef ASTStatData data_type;
Douglas Gregorc5046832009-04-27 18:38:38 +0000985
986 static unsigned ComputeHash(const char *path) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000987 return llvm::HashString(path);
Douglas Gregorc5046832009-04-27 18:38:38 +0000988 }
989
990 static internal_key_type GetInternalKey(const char *path) { return path; }
991
992 static bool EqualKey(internal_key_type a, internal_key_type b) {
993 return strcmp(a, b) == 0;
994 }
995
996 static std::pair<unsigned, unsigned>
997 ReadKeyDataLength(const unsigned char*& d) {
998 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
999 unsigned DataLen = (unsigned) *d++;
1000 return std::make_pair(KeyLen + 1, DataLen);
1001 }
1002
1003 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
1004 return (const char *)d;
1005 }
1006
1007 static data_type ReadData(const internal_key_type, const unsigned char *d,
1008 unsigned /*DataLen*/) {
1009 using namespace clang::io;
1010
1011 if (*d++ == 1)
1012 return data_type();
1013
1014 ino_t ino = (ino_t) ReadUnalignedLE32(d);
1015 dev_t dev = (dev_t) ReadUnalignedLE32(d);
1016 mode_t mode = (mode_t) ReadUnalignedLE16(d);
Mike Stump11289f42009-09-09 15:08:12 +00001017 time_t mtime = (time_t) ReadUnalignedLE64(d);
Douglas Gregorc5046832009-04-27 18:38:38 +00001018 off_t size = (off_t) ReadUnalignedLE64(d);
1019 return data_type(ino, dev, mode, mtime, size);
1020 }
1021};
1022
1023/// \brief stat() cache for precompiled headers.
1024///
1025/// This cache is very similar to the stat cache used by pretokenized
1026/// headers.
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001027class ASTStatCache : public StatSysCallCache {
1028 typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
Douglas Gregorc5046832009-04-27 18:38:38 +00001029 CacheTy *Cache;
1030
1031 unsigned &NumStatHits, &NumStatMisses;
Mike Stump11289f42009-09-09 15:08:12 +00001032public:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001033 ASTStatCache(const unsigned char *Buckets,
Douglas Gregorc5046832009-04-27 18:38:38 +00001034 const unsigned char *Base,
1035 unsigned &NumStatHits,
Mike Stump11289f42009-09-09 15:08:12 +00001036 unsigned &NumStatMisses)
Douglas Gregorc5046832009-04-27 18:38:38 +00001037 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
1038 Cache = CacheTy::Create(Buckets, Base);
1039 }
1040
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001041 ~ASTStatCache() { delete Cache; }
Mike Stump11289f42009-09-09 15:08:12 +00001042
Douglas Gregorc5046832009-04-27 18:38:38 +00001043 int stat(const char *path, struct stat *buf) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001044 // Do the lookup for the file's data in the AST file.
Douglas Gregorc5046832009-04-27 18:38:38 +00001045 CacheTy::iterator I = Cache->find(path);
1046
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001047 // If we don't get a hit in the AST file just forward to 'stat'.
Douglas Gregorc5046832009-04-27 18:38:38 +00001048 if (I == Cache->end()) {
1049 ++NumStatMisses;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001050 return StatSysCallCache::stat(path, buf);
Douglas Gregorc5046832009-04-27 18:38:38 +00001051 }
Mike Stump11289f42009-09-09 15:08:12 +00001052
Douglas Gregorc5046832009-04-27 18:38:38 +00001053 ++NumStatHits;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001054 ASTStatData Data = *I;
Mike Stump11289f42009-09-09 15:08:12 +00001055
Douglas Gregorc5046832009-04-27 18:38:38 +00001056 if (!Data.hasStat)
1057 return 1;
1058
1059 buf->st_ino = Data.ino;
1060 buf->st_dev = Data.dev;
1061 buf->st_mtime = Data.mtime;
1062 buf->st_mode = Data.mode;
1063 buf->st_size = Data.size;
1064 return 0;
1065 }
1066};
1067} // end anonymous namespace
1068
1069
Sebastian Redl393f8b72010-07-19 20:52:06 +00001070/// \brief Read a source manager block
Sebastian Redl2c499f62010-08-18 23:56:43 +00001071ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001072 using namespace SrcMgr;
Douglas Gregor258ae542009-04-27 06:38:32 +00001073
Sebastian Redl393f8b72010-07-19 20:52:06 +00001074 llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
Sebastian Redl34522812010-07-16 17:50:48 +00001075
Douglas Gregor258ae542009-04-27 06:38:32 +00001076 // Set the source-location entry cursor to the current position in
1077 // the stream. This cursor will be used to read the contents of the
1078 // source manager block initially, and then lazily read
1079 // source-location entries as needed.
Sebastian Redl393f8b72010-07-19 20:52:06 +00001080 SLocEntryCursor = F.Stream;
Douglas Gregor258ae542009-04-27 06:38:32 +00001081
1082 // The stream itself is going to skip over the source manager block.
Sebastian Redl393f8b72010-07-19 20:52:06 +00001083 if (F.Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001084 Error("malformed block record in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001085 return Failure;
1086 }
1087
1088 // Enter the source manager block.
Sebastian Redl539c5062010-08-18 23:57:32 +00001089 if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001090 Error("malformed source manager block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001091 return Failure;
1092 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001093
Douglas Gregora7f71a92009-04-10 03:52:48 +00001094 RecordData Record;
1095 while (true) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001096 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001097 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001098 if (SLocEntryCursor.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001099 Error("error at end of Source Manager block in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001100 return Failure;
1101 }
Douglas Gregor92863e42009-04-10 23:10:45 +00001102 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001103 }
Mike Stump11289f42009-09-09 15:08:12 +00001104
Douglas Gregora7f71a92009-04-10 03:52:48 +00001105 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1106 // No known subblocks, always skip them.
Douglas Gregor258ae542009-04-27 06:38:32 +00001107 SLocEntryCursor.ReadSubBlockID();
1108 if (SLocEntryCursor.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001109 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001110 return Failure;
1111 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001112 continue;
1113 }
Mike Stump11289f42009-09-09 15:08:12 +00001114
Douglas Gregora7f71a92009-04-10 03:52:48 +00001115 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001116 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001117 continue;
1118 }
Mike Stump11289f42009-09-09 15:08:12 +00001119
Douglas Gregora7f71a92009-04-10 03:52:48 +00001120 // Read a record.
1121 const char *BlobStart;
1122 unsigned BlobLen;
1123 Record.clear();
Douglas Gregor258ae542009-04-27 06:38:32 +00001124 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001125 default: // Default behavior: ignore.
1126 break;
1127
Sebastian Redl539c5062010-08-18 23:57:32 +00001128 case SM_LINE_TABLE:
Sebastian Redlb293a452010-07-20 21:20:32 +00001129 if (ParseLineTable(Record))
Douglas Gregor4c7626e2009-04-13 16:31:14 +00001130 return Failure;
Chris Lattner184e65d2009-04-14 23:22:57 +00001131 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001132
Sebastian Redl539c5062010-08-18 23:57:32 +00001133 case SM_SLOC_FILE_ENTRY:
1134 case SM_SLOC_BUFFER_ENTRY:
1135 case SM_SLOC_INSTANTIATION_ENTRY:
Douglas Gregor258ae542009-04-27 06:38:32 +00001136 // Once we hit one of the source location entries, we're done.
1137 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001138 }
1139 }
1140}
1141
Sebastian Redl06750302010-07-20 21:50:20 +00001142/// \brief Get a cursor that's correctly positioned for reading the source
1143/// location entry with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001144llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
Sebastian Redl06750302010-07-20 21:50:20 +00001145 assert(ID != 0 && ID <= TotalNumSLocEntries &&
1146 "SLocCursorForID should only be called for real IDs.");
1147
1148 ID -= 1;
1149 PerFileData *F = 0;
1150 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1151 F = Chain[N - I - 1];
1152 if (ID < F->LocalNumSLocEntries)
1153 break;
1154 ID -= F->LocalNumSLocEntries;
1155 }
1156 assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
1157
1158 F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
1159 return F->SLocEntryCursor;
1160}
1161
Douglas Gregor258ae542009-04-27 06:38:32 +00001162/// \brief Read in the source location entry with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001163ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001164 if (ID == 0)
1165 return Success;
1166
1167 if (ID > TotalNumSLocEntries) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001168 Error("source location entry ID out-of-range for AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001169 return Failure;
1170 }
1171
Sebastian Redl06750302010-07-20 21:50:20 +00001172 llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
Sebastian Redl34522812010-07-16 17:50:48 +00001173
Douglas Gregor258ae542009-04-27 06:38:32 +00001174 ++NumSLocEntriesRead;
Douglas Gregor258ae542009-04-27 06:38:32 +00001175 unsigned Code = SLocEntryCursor.ReadCode();
1176 if (Code == llvm::bitc::END_BLOCK ||
1177 Code == llvm::bitc::ENTER_SUBBLOCK ||
1178 Code == llvm::bitc::DEFINE_ABBREV) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001179 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001180 return Failure;
1181 }
1182
Douglas Gregor258ae542009-04-27 06:38:32 +00001183 RecordData Record;
1184 const char *BlobStart;
1185 unsigned BlobLen;
1186 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1187 default:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001188 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001189 return Failure;
1190
Sebastian Redl539c5062010-08-18 23:57:32 +00001191 case SM_SLOC_FILE_ENTRY: {
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001192 std::string Filename(BlobStart, BlobStart + BlobLen);
1193 MaybeAddSystemRootToFilename(Filename);
1194 const FileEntry *File = FileMgr.getFile(Filename);
Chris Lattnerd20dc872009-06-15 04:35:16 +00001195 if (File == 0) {
1196 std::string ErrorStr = "could not find file '";
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001197 ErrorStr += Filename;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001198 ErrorStr += "' referenced by AST file";
Chris Lattnerd20dc872009-06-15 04:35:16 +00001199 Error(ErrorStr.c_str());
1200 return Failure;
1201 }
Mike Stump11289f42009-09-09 15:08:12 +00001202
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001203 if (Record.size() < 10) {
Ted Kremenekabb1ddd2010-03-18 21:23:05 +00001204 Error("source location entry is incorrect");
1205 return Failure;
1206 }
1207
Douglas Gregorce3a8292010-07-27 00:27:13 +00001208 if (!DisableValidation &&
1209 ((off_t)Record[4] != File->getSize()
Douglas Gregor08288f22010-04-09 15:54:22 +00001210#if !defined(LLVM_ON_WIN32)
1211 // In our regression testing, the Windows file system seems to
1212 // have inconsistent modification times that sometimes
1213 // erroneously trigger this error-handling path.
Douglas Gregorce3a8292010-07-27 00:27:13 +00001214 || (time_t)Record[5] != File->getModificationTime()
Douglas Gregor08288f22010-04-09 15:54:22 +00001215#endif
Douglas Gregorce3a8292010-07-27 00:27:13 +00001216 )) {
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001217 Diag(diag::err_fe_pch_file_modified)
1218 << Filename;
1219 return Failure;
1220 }
1221
Douglas Gregor258ae542009-04-27 06:38:32 +00001222 FileID FID = SourceMgr.createFileID(File,
1223 SourceLocation::getFromRawEncoding(Record[1]),
1224 (SrcMgr::CharacteristicKind)Record[2],
1225 ID, Record[0]);
1226 if (Record[3])
1227 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
1228 .setHasLineDirectives();
1229
Douglas Gregor5712ebc2010-03-16 16:35:32 +00001230 // Reconstruct header-search information for this file.
1231 HeaderFileInfo HFI;
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001232 HFI.isImport = Record[6];
1233 HFI.DirInfo = Record[7];
1234 HFI.NumIncludes = Record[8];
1235 HFI.ControllingMacroID = Record[9];
Douglas Gregor5712ebc2010-03-16 16:35:32 +00001236 if (Listener)
1237 Listener->ReadHeaderFileInfo(HFI, File->getUID());
Douglas Gregor258ae542009-04-27 06:38:32 +00001238 break;
1239 }
1240
Sebastian Redl539c5062010-08-18 23:57:32 +00001241 case SM_SLOC_BUFFER_ENTRY: {
Douglas Gregor258ae542009-04-27 06:38:32 +00001242 const char *Name = BlobStart;
1243 unsigned Offset = Record[0];
1244 unsigned Code = SLocEntryCursor.ReadCode();
1245 Record.clear();
Mike Stump11289f42009-09-09 15:08:12 +00001246 unsigned RecCode
Douglas Gregor258ae542009-04-27 06:38:32 +00001247 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001248
Sebastian Redl539c5062010-08-18 23:57:32 +00001249 if (RecCode != SM_SLOC_BUFFER_BLOB) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001250 Error("AST record has invalid code");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001251 return Failure;
1252 }
1253
Douglas Gregor258ae542009-04-27 06:38:32 +00001254 llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00001255 = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
1256 Name);
Douglas Gregor258ae542009-04-27 06:38:32 +00001257 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
Mike Stump11289f42009-09-09 15:08:12 +00001258
Douglas Gregore6648fb2009-04-28 20:33:11 +00001259 if (strcmp(Name, "<built-in>") == 0) {
Sebastian Redl75fbb3b2010-07-14 17:49:11 +00001260 PCHPredefinesBlock Block = {
1261 BufferID,
1262 llvm::StringRef(BlobStart, BlobLen - 1)
1263 };
1264 PCHPredefinesBuffers.push_back(Block);
Douglas Gregore6648fb2009-04-28 20:33:11 +00001265 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001266
1267 break;
1268 }
1269
Sebastian Redl539c5062010-08-18 23:57:32 +00001270 case SM_SLOC_INSTANTIATION_ENTRY: {
Mike Stump11289f42009-09-09 15:08:12 +00001271 SourceLocation SpellingLoc
Douglas Gregor258ae542009-04-27 06:38:32 +00001272 = SourceLocation::getFromRawEncoding(Record[1]);
1273 SourceMgr.createInstantiationLoc(SpellingLoc,
1274 SourceLocation::getFromRawEncoding(Record[2]),
1275 SourceLocation::getFromRawEncoding(Record[3]),
1276 Record[4],
1277 ID,
1278 Record[0]);
1279 break;
Mike Stump11289f42009-09-09 15:08:12 +00001280 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001281 }
1282
1283 return Success;
1284}
1285
Chris Lattnere78a6be2009-04-27 01:05:14 +00001286/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
1287/// specified cursor. Read the abbreviations that are at the top of the block
1288/// and then leave the cursor pointing into the block.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001289bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
Chris Lattnere78a6be2009-04-27 01:05:14 +00001290 unsigned BlockID) {
1291 if (Cursor.EnterSubBlock(BlockID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001292 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001293 return Failure;
1294 }
Mike Stump11289f42009-09-09 15:08:12 +00001295
Chris Lattnere78a6be2009-04-27 01:05:14 +00001296 while (true) {
1297 unsigned Code = Cursor.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00001298
Chris Lattnere78a6be2009-04-27 01:05:14 +00001299 // We expect all abbrevs to be at the start of the block.
1300 if (Code != llvm::bitc::DEFINE_ABBREV)
1301 return false;
1302 Cursor.ReadAbbrevRecord();
1303 }
1304}
1305
Sebastian Redl2c499f62010-08-18 23:56:43 +00001306void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001307 assert(PP && "Forgot to set Preprocessor ?");
Mike Stump11289f42009-09-09 15:08:12 +00001308
Douglas Gregorc3366a52009-04-21 23:56:24 +00001309 // Keep track of where we are in the stream, then jump back there
1310 // after reading this macro.
1311 SavedStreamPosition SavedPosition(Stream);
1312
1313 Stream.JumpToBit(Offset);
1314 RecordData Record;
1315 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
1316 MacroInfo *Macro = 0;
Mike Stump11289f42009-09-09 15:08:12 +00001317
Douglas Gregorc3366a52009-04-21 23:56:24 +00001318 while (true) {
1319 unsigned Code = Stream.ReadCode();
1320 switch (Code) {
1321 case llvm::bitc::END_BLOCK:
1322 return;
1323
1324 case llvm::bitc::ENTER_SUBBLOCK:
1325 // No known subblocks, always skip them.
1326 Stream.ReadSubBlockID();
1327 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001328 Error("malformed block record in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001329 return;
1330 }
1331 continue;
Mike Stump11289f42009-09-09 15:08:12 +00001332
Douglas Gregorc3366a52009-04-21 23:56:24 +00001333 case llvm::bitc::DEFINE_ABBREV:
1334 Stream.ReadAbbrevRecord();
1335 continue;
1336 default: break;
1337 }
1338
1339 // Read a record.
1340 Record.clear();
Sebastian Redl539c5062010-08-18 23:57:32 +00001341 PreprocessorRecordTypes RecType =
1342 (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001343 switch (RecType) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001344 case PP_MACRO_OBJECT_LIKE:
1345 case PP_MACRO_FUNCTION_LIKE: {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001346 // If we already have a macro, that means that we've hit the end
1347 // of the definition of the macro we were looking for. We're
1348 // done.
1349 if (Macro)
1350 return;
1351
1352 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
1353 if (II == 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001354 Error("macro must have a name in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001355 return;
1356 }
1357 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1358 bool isUsed = Record[2];
Mike Stump11289f42009-09-09 15:08:12 +00001359
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001360 MacroInfo *MI = PP->AllocateMacroInfo(Loc);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001361 MI->setIsUsed(isUsed);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001362 MI->setIsFromAST();
Mike Stump11289f42009-09-09 15:08:12 +00001363
Douglas Gregoraae92242010-03-19 21:51:54 +00001364 unsigned NextIndex = 3;
Sebastian Redl539c5062010-08-18 23:57:32 +00001365 if (RecType == PP_MACRO_FUNCTION_LIKE) {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001366 // Decode function-like macro info.
1367 bool isC99VarArgs = Record[3];
1368 bool isGNUVarArgs = Record[4];
1369 MacroArgs.clear();
1370 unsigned NumArgs = Record[5];
Douglas Gregoraae92242010-03-19 21:51:54 +00001371 NextIndex = 6 + NumArgs;
Douglas Gregorc3366a52009-04-21 23:56:24 +00001372 for (unsigned i = 0; i != NumArgs; ++i)
1373 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
1374
1375 // Install function-like macro info.
1376 MI->setIsFunctionLike();
1377 if (isC99VarArgs) MI->setIsC99Varargs();
1378 if (isGNUVarArgs) MI->setIsGNUVarargs();
Douglas Gregor038c3382009-05-22 22:45:36 +00001379 MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001380 PP->getPreprocessorAllocator());
Douglas Gregorc3366a52009-04-21 23:56:24 +00001381 }
1382
1383 // Finally, install the macro.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001384 PP->setMacroInfo(II, MI);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001385
1386 // Remember that we saw this macro last so that we add the tokens that
1387 // form its body to it.
1388 Macro = MI;
Douglas Gregoraae92242010-03-19 21:51:54 +00001389
1390 if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
1391 // We have a macro definition. Load it now.
1392 PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
1393 getMacroDefinition(Record[NextIndex]));
1394 }
1395
Douglas Gregorc3366a52009-04-21 23:56:24 +00001396 ++NumMacrosRead;
1397 break;
1398 }
Mike Stump11289f42009-09-09 15:08:12 +00001399
Sebastian Redl539c5062010-08-18 23:57:32 +00001400 case PP_TOKEN: {
Douglas Gregorc3366a52009-04-21 23:56:24 +00001401 // If we see a TOKEN before a PP_MACRO_*, then the file is
1402 // erroneous, just pretend we didn't see this.
1403 if (Macro == 0) break;
Mike Stump11289f42009-09-09 15:08:12 +00001404
Douglas Gregorc3366a52009-04-21 23:56:24 +00001405 Token Tok;
1406 Tok.startToken();
1407 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1408 Tok.setLength(Record[1]);
1409 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1410 Tok.setIdentifierInfo(II);
1411 Tok.setKind((tok::TokenKind)Record[3]);
1412 Tok.setFlag((Token::TokenFlags)Record[4]);
1413 Macro->AddTokenToBody(Tok);
1414 break;
1415 }
Douglas Gregoraae92242010-03-19 21:51:54 +00001416
Sebastian Redl539c5062010-08-18 23:57:32 +00001417 case PP_MACRO_INSTANTIATION: {
Douglas Gregoraae92242010-03-19 21:51:54 +00001418 // If we already have a macro, that means that we've hit the end
1419 // of the definition of the macro we were looking for. We're
1420 // done.
1421 if (Macro)
1422 return;
1423
1424 if (!PP->getPreprocessingRecord()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001425 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-03-19 21:51:54 +00001426 return;
1427 }
1428
1429 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1430 if (PPRec.getPreprocessedEntity(Record[0]))
1431 return;
1432
1433 MacroInstantiation *MI
1434 = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
1435 SourceRange(
1436 SourceLocation::getFromRawEncoding(Record[1]),
1437 SourceLocation::getFromRawEncoding(Record[2])),
1438 getMacroDefinition(Record[4]));
1439 PPRec.SetPreallocatedEntity(Record[0], MI);
1440 return;
1441 }
1442
Sebastian Redl539c5062010-08-18 23:57:32 +00001443 case PP_MACRO_DEFINITION: {
Douglas Gregoraae92242010-03-19 21:51:54 +00001444 // If we already have a macro, that means that we've hit the end
1445 // of the definition of the macro we were looking for. We're
1446 // done.
1447 if (Macro)
1448 return;
1449
1450 if (!PP->getPreprocessingRecord()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001451 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-03-19 21:51:54 +00001452 return;
1453 }
1454
1455 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1456 if (PPRec.getPreprocessedEntity(Record[0]))
1457 return;
1458
1459 if (Record[1] >= MacroDefinitionsLoaded.size()) {
1460 Error("out-of-bounds macro definition record");
1461 return;
1462 }
1463
1464 MacroDefinition *MD
1465 = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
1466 SourceLocation::getFromRawEncoding(Record[5]),
1467 SourceRange(
1468 SourceLocation::getFromRawEncoding(Record[2]),
1469 SourceLocation::getFromRawEncoding(Record[3])));
1470 PPRec.SetPreallocatedEntity(Record[0], MD);
1471 MacroDefinitionsLoaded[Record[1]] = MD;
1472 return;
1473 }
Steve Naroff3fa455a2009-04-24 20:03:17 +00001474 }
Douglas Gregorc3366a52009-04-21 23:56:24 +00001475 }
1476}
1477
Sebastian Redl2c499f62010-08-18 23:56:43 +00001478void ASTReader::ReadDefinedMacros() {
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001479 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1480 llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
Sebastian Redl34522812010-07-16 17:50:48 +00001481
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001482 // If there was no preprocessor block, skip this file.
1483 if (!MacroCursor.getBitStreamReader())
1484 continue;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001485
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001486 llvm::BitstreamCursor Cursor = MacroCursor;
Sebastian Redl539c5062010-08-18 23:57:32 +00001487 if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001488 Error("malformed preprocessor block record in AST file");
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001489 return;
1490 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001491
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001492 RecordData Record;
1493 while (true) {
1494 unsigned Code = Cursor.ReadCode();
1495 if (Code == llvm::bitc::END_BLOCK) {
1496 if (Cursor.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001497 Error("error at end of preprocessor block in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001498 return;
1499 }
1500 break;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001501 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001502
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001503 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1504 // No known subblocks, always skip them.
1505 Cursor.ReadSubBlockID();
1506 if (Cursor.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001507 Error("malformed block record in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001508 return;
1509 }
1510 continue;
1511 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001512
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001513 if (Code == llvm::bitc::DEFINE_ABBREV) {
1514 Cursor.ReadAbbrevRecord();
1515 continue;
1516 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001517
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001518 // Read a record.
1519 const char *BlobStart;
1520 unsigned BlobLen;
1521 Record.clear();
1522 switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1523 default: // Default behavior: ignore.
1524 break;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001525
Sebastian Redl539c5062010-08-18 23:57:32 +00001526 case PP_MACRO_OBJECT_LIKE:
1527 case PP_MACRO_FUNCTION_LIKE:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001528 DecodeIdentifierInfo(Record[0]);
1529 break;
1530
Sebastian Redl539c5062010-08-18 23:57:32 +00001531 case PP_TOKEN:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001532 // Ignore tokens.
1533 break;
Douglas Gregoraae92242010-03-19 21:51:54 +00001534
Sebastian Redl539c5062010-08-18 23:57:32 +00001535 case PP_MACRO_INSTANTIATION:
1536 case PP_MACRO_DEFINITION:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001537 // Read the macro record.
1538 ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
1539 break;
1540 }
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001541 }
1542 }
1543}
1544
Sebastian Redl539c5062010-08-18 23:57:32 +00001545MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) {
Douglas Gregoraae92242010-03-19 21:51:54 +00001546 if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
1547 return 0;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001548
1549 if (!MacroDefinitionsLoaded[ID]) {
1550 unsigned Index = ID;
1551 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1552 PerFileData &F = *Chain[N - I - 1];
1553 if (Index < F.LocalNumMacroDefinitions) {
1554 ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
1555 break;
1556 }
1557 Index -= F.LocalNumMacroDefinitions;
1558 }
1559 assert(MacroDefinitionsLoaded[ID] && "Broken chain");
1560 }
1561
Douglas Gregoraae92242010-03-19 21:51:54 +00001562 return MacroDefinitionsLoaded[ID];
1563}
1564
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001565/// \brief If we are loading a relocatable PCH file, and the filename is
1566/// not an absolute path, add the system root to the beginning of the file
1567/// name.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001568void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001569 // If this is not a relocatable PCH file, there's nothing to do.
1570 if (!RelocatablePCH)
1571 return;
Mike Stump11289f42009-09-09 15:08:12 +00001572
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +00001573 if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001574 return;
1575
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001576 if (isysroot == 0) {
1577 // If no system root was given, default to '/'
1578 Filename.insert(Filename.begin(), '/');
1579 return;
1580 }
Mike Stump11289f42009-09-09 15:08:12 +00001581
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001582 unsigned Length = strlen(isysroot);
1583 if (isysroot[Length - 1] != '/')
1584 Filename.insert(Filename.begin(), '/');
Mike Stump11289f42009-09-09 15:08:12 +00001585
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001586 Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1587}
1588
Sebastian Redl2c499f62010-08-18 23:56:43 +00001589ASTReader::ASTReadResult
Sebastian Redl3e31c722010-08-18 23:56:56 +00001590ASTReader::ReadASTBlock(PerFileData &F) {
Sebastian Redl34522812010-07-16 17:50:48 +00001591 llvm::BitstreamCursor &Stream = F.Stream;
1592
Sebastian Redl539c5062010-08-18 23:57:32 +00001593 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001594 Error("malformed block record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001595 return Failure;
1596 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001597
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001598 // Read all of the records and blocks for the ASt file.
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001599 RecordData Record;
Sebastian Redl393f8b72010-07-19 20:52:06 +00001600 bool First = true;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001601 while (!Stream.AtEndOfStream()) {
1602 unsigned Code = Stream.ReadCode();
1603 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor55abb232009-04-10 20:39:37 +00001604 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001605 Error("error at end of module block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001606 return Failure;
1607 }
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001608
Douglas Gregor55abb232009-04-10 20:39:37 +00001609 return Success;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001610 }
1611
1612 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1613 switch (Stream.ReadSubBlockID()) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001614 case DECLTYPES_BLOCK_ID:
Chris Lattnere78a6be2009-04-27 01:05:14 +00001615 // We lazily load the decls block, but we want to set up the
1616 // DeclsCursor cursor to point into it. Clone our current bitcode
1617 // cursor to it, enter the block and read the abbrevs in that block.
1618 // With the main cursor, we just skip over it.
Sebastian Redl34522812010-07-16 17:50:48 +00001619 F.DeclsCursor = Stream;
Chris Lattnere78a6be2009-04-27 01:05:14 +00001620 if (Stream.SkipBlock() || // Skip with the main cursor.
1621 // Read the abbrevs.
Sebastian Redl539c5062010-08-18 23:57:32 +00001622 ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001623 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001624 return Failure;
1625 }
1626 break;
Mike Stump11289f42009-09-09 15:08:12 +00001627
Sebastian Redl539c5062010-08-18 23:57:32 +00001628 case PREPROCESSOR_BLOCK_ID:
Sebastian Redl34522812010-07-16 17:50:48 +00001629 F.MacroCursor = Stream;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001630 if (PP)
1631 PP->setExternalSource(this);
1632
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001633 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001634 Error("malformed block record in AST file");
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001635 return Failure;
1636 }
1637 break;
Steve Naroff2ddea052009-04-23 10:39:46 +00001638
Sebastian Redl539c5062010-08-18 23:57:32 +00001639 case SOURCE_MANAGER_BLOCK_ID:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001640 switch (ReadSourceManagerBlock(F)) {
Douglas Gregor92863e42009-04-10 23:10:45 +00001641 case Success:
1642 break;
1643
1644 case Failure:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001645 Error("malformed source manager block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001646 return Failure;
Douglas Gregor92863e42009-04-10 23:10:45 +00001647
1648 case IgnorePCH:
1649 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00001650 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001651 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001652 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001653 First = false;
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001654 continue;
1655 }
1656
1657 if (Code == llvm::bitc::DEFINE_ABBREV) {
1658 Stream.ReadAbbrevRecord();
1659 continue;
1660 }
1661
1662 // Read and process a record.
1663 Record.clear();
Douglas Gregorbfbde532009-04-10 21:16:55 +00001664 const char *BlobStart = 0;
1665 unsigned BlobLen = 0;
Sebastian Redl539c5062010-08-18 23:57:32 +00001666 switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
Douglas Gregorbfbde532009-04-10 21:16:55 +00001667 &BlobStart, &BlobLen)) {
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001668 default: // Default behavior: ignore.
1669 break;
1670
Sebastian Redl539c5062010-08-18 23:57:32 +00001671 case METADATA: {
1672 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1673 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001674 : diag::warn_pch_version_too_new);
1675 return IgnorePCH;
1676 }
1677
1678 RelocatablePCH = Record[4];
1679 if (Listener) {
1680 std::string TargetTriple(BlobStart, BlobLen);
1681 if (Listener->ReadTargetTriple(TargetTriple))
1682 return IgnorePCH;
1683 }
1684 break;
1685 }
1686
Sebastian Redl539c5062010-08-18 23:57:32 +00001687 case CHAINED_METADATA: {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001688 if (!First) {
1689 Error("CHAINED_METADATA is not first record in block");
1690 return Failure;
1691 }
Sebastian Redl539c5062010-08-18 23:57:32 +00001692 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1693 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001694 : diag::warn_pch_version_too_new);
1695 return IgnorePCH;
1696 }
1697
1698 // Load the chained file.
Sebastian Redl3e31c722010-08-18 23:56:56 +00001699 switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001700 case Failure: return Failure;
1701 // If we have to ignore the dependency, we'll have to ignore this too.
1702 case IgnorePCH: return IgnorePCH;
1703 case Success: break;
1704 }
1705 break;
1706 }
1707
Sebastian Redl539c5062010-08-18 23:57:32 +00001708 case TYPE_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001709 if (F.LocalNumTypes != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001710 Error("duplicate TYPE_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001711 return Failure;
1712 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001713 F.TypeOffsets = (const uint32_t *)BlobStart;
1714 F.LocalNumTypes = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001715 break;
1716
Sebastian Redl539c5062010-08-18 23:57:32 +00001717 case DECL_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001718 if (F.LocalNumDecls != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001719 Error("duplicate DECL_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001720 return Failure;
1721 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001722 F.DeclOffsets = (const uint32_t *)BlobStart;
1723 F.LocalNumDecls = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001724 break;
Douglas Gregor55abb232009-04-10 20:39:37 +00001725
Sebastian Redl539c5062010-08-18 23:57:32 +00001726 case TU_UPDATE_LEXICAL: {
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001727 DeclContextInfo Info = {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00001728 /* No visible information */ 0,
Sebastian Redl539c5062010-08-18 23:57:32 +00001729 reinterpret_cast<const DeclID *>(BlobStart),
1730 BlobLen / sizeof(DeclID)
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001731 };
1732 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1733 break;
1734 }
1735
Sebastian Redld7dce0a2010-08-24 00:50:04 +00001736 case UPDATE_VISIBLE: {
1737 serialization::DeclID ID = Record[0];
1738 void *Table = ASTDeclContextNameLookupTable::Create(
1739 (const unsigned char *)BlobStart + Record[1],
1740 (const unsigned char *)BlobStart,
1741 ASTDeclContextNameLookupTrait(*this));
1742 if (ID == 1) { // Is it the TU?
1743 DeclContextInfo Info = {
1744 Table, /* No lexical inforamtion */ 0, 0
1745 };
1746 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1747 } else
1748 PendingVisibleUpdates[ID].push_back(Table);
1749 break;
1750 }
1751
Sebastian Redl539c5062010-08-18 23:57:32 +00001752 case REDECLS_UPDATE_LATEST: {
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00001753 assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
1754 for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001755 DeclID First = Record[i], Latest = Record[i+1];
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00001756 assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
1757 Latest > FirstLatestDeclIDs[First]) &&
1758 "The new latest is supposed to come after the previous latest");
1759 FirstLatestDeclIDs[First] = Latest;
1760 }
1761 break;
1762 }
1763
Sebastian Redl539c5062010-08-18 23:57:32 +00001764 case LANGUAGE_OPTIONS:
Douglas Gregorce3a8292010-07-27 00:27:13 +00001765 if (ParseLanguageOptions(Record) && !DisableValidation)
Douglas Gregor55abb232009-04-10 20:39:37 +00001766 return IgnorePCH;
1767 break;
Douglas Gregorbfbde532009-04-10 21:16:55 +00001768
Sebastian Redl539c5062010-08-18 23:57:32 +00001769 case IDENTIFIER_TABLE:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001770 F.IdentifierTableData = BlobStart;
Douglas Gregor0e149972009-04-25 19:10:14 +00001771 if (Record[0]) {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001772 F.IdentifierLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001773 = ASTIdentifierLookupTable::Create(
Sebastian Redl393f8b72010-07-19 20:52:06 +00001774 (const unsigned char *)F.IdentifierTableData + Record[0],
1775 (const unsigned char *)F.IdentifierTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001776 ASTIdentifierLookupTrait(*this, F.Stream));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001777 if (PP)
1778 PP->getIdentifierTable().setExternalIdentifierLookup(this);
Douglas Gregor0e149972009-04-25 19:10:14 +00001779 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001780 break;
1781
Sebastian Redl539c5062010-08-18 23:57:32 +00001782 case IDENTIFIER_OFFSET:
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001783 if (F.LocalNumIdentifiers != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001784 Error("duplicate IDENTIFIER_OFFSET record in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001785 return Failure;
1786 }
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001787 F.IdentifierOffsets = (const uint32_t *)BlobStart;
1788 F.LocalNumIdentifiers = Record[0];
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001789 break;
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00001790
Sebastian Redl539c5062010-08-18 23:57:32 +00001791 case EXTERNAL_DEFINITIONS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001792 // Optimization for the first block.
1793 if (ExternalDefinitions.empty())
1794 ExternalDefinitions.swap(Record);
1795 else
1796 ExternalDefinitions.insert(ExternalDefinitions.end(),
1797 Record.begin(), Record.end());
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00001798 break;
Douglas Gregor08f01292009-04-17 22:13:46 +00001799
Sebastian Redl539c5062010-08-18 23:57:32 +00001800 case SPECIAL_TYPES:
Sebastian Redlb293a452010-07-20 21:20:32 +00001801 // Optimization for the first block
1802 if (SpecialTypes.empty())
1803 SpecialTypes.swap(Record);
1804 else
1805 SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
Douglas Gregor652d82a2009-04-18 05:55:16 +00001806 break;
1807
Sebastian Redl539c5062010-08-18 23:57:32 +00001808 case STATISTICS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001809 TotalNumStatements += Record[0];
1810 TotalNumMacros += Record[1];
1811 TotalLexicalDeclContexts += Record[2];
1812 TotalVisibleDeclContexts += Record[3];
Douglas Gregor08f01292009-04-17 22:13:46 +00001813 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001814
Sebastian Redl539c5062010-08-18 23:57:32 +00001815 case TENTATIVE_DEFINITIONS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001816 // Optimization for the first block.
1817 if (TentativeDefinitions.empty())
1818 TentativeDefinitions.swap(Record);
1819 else
1820 TentativeDefinitions.insert(TentativeDefinitions.end(),
1821 Record.begin(), Record.end());
Douglas Gregord4df8652009-04-22 22:02:47 +00001822 break;
Douglas Gregoracfc76c2009-04-22 22:18:58 +00001823
Sebastian Redl539c5062010-08-18 23:57:32 +00001824 case UNUSED_FILESCOPED_DECLS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001825 // Optimization for the first block.
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001826 if (UnusedFileScopedDecls.empty())
1827 UnusedFileScopedDecls.swap(Record);
Sebastian Redlb293a452010-07-20 21:20:32 +00001828 else
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001829 UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
1830 Record.begin(), Record.end());
Tanya Lattner90073802010-02-12 00:07:30 +00001831 break;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001832
Sebastian Redl539c5062010-08-18 23:57:32 +00001833 case WEAK_UNDECLARED_IDENTIFIERS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001834 // Later blocks overwrite earlier ones.
1835 WeakUndeclaredIdentifiers.swap(Record);
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00001836 break;
1837
Sebastian Redl539c5062010-08-18 23:57:32 +00001838 case LOCALLY_SCOPED_EXTERNAL_DECLS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001839 // Optimization for the first block.
1840 if (LocallyScopedExternalDecls.empty())
1841 LocallyScopedExternalDecls.swap(Record);
1842 else
1843 LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
1844 Record.begin(), Record.end());
Douglas Gregoracfc76c2009-04-22 22:18:58 +00001845 break;
Douglas Gregorc78d3462009-04-24 21:10:55 +00001846
Sebastian Redl539c5062010-08-18 23:57:32 +00001847 case SELECTOR_OFFSETS:
Sebastian Redla19a67f2010-08-03 21:58:15 +00001848 F.SelectorOffsets = (const uint32_t *)BlobStart;
Sebastian Redlada023c2010-08-04 20:40:17 +00001849 F.LocalNumSelectors = Record[0];
Douglas Gregor95c13f52009-04-25 17:48:32 +00001850 break;
1851
Sebastian Redl539c5062010-08-18 23:57:32 +00001852 case METHOD_POOL:
Sebastian Redlada023c2010-08-04 20:40:17 +00001853 F.SelectorLookupTableData = (const unsigned char *)BlobStart;
Douglas Gregor95c13f52009-04-25 17:48:32 +00001854 if (Record[0])
Sebastian Redlada023c2010-08-04 20:40:17 +00001855 F.SelectorLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001856 = ASTSelectorLookupTable::Create(
Sebastian Redlada023c2010-08-04 20:40:17 +00001857 F.SelectorLookupTableData + Record[0],
1858 F.SelectorLookupTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001859 ASTSelectorLookupTrait(*this));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00001860 TotalNumMethodPoolEntries += Record[1];
Douglas Gregorc78d3462009-04-24 21:10:55 +00001861 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001862
Sebastian Redl539c5062010-08-18 23:57:32 +00001863 case REFERENCED_SELECTOR_POOL: {
Sebastian Redlada023c2010-08-04 20:40:17 +00001864 ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
1865 Record.begin(), Record.end());
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00001866 break;
Sebastian Redl66c5eef2010-07-27 00:17:23 +00001867 }
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00001868
Sebastian Redl539c5062010-08-18 23:57:32 +00001869 case PP_COUNTER_VALUE:
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001870 if (!Record.empty() && Listener)
1871 Listener->ReadCounter(Record[0]);
Douglas Gregoreda6a892009-04-26 00:07:37 +00001872 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001873
Sebastian Redl539c5062010-08-18 23:57:32 +00001874 case SOURCE_LOCATION_OFFSETS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001875 F.SLocOffsets = (const uint32_t *)BlobStart;
1876 F.LocalNumSLocEntries = Record[0];
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001877 // We cannot delay this until the entire chain is loaded, because then
1878 // source location preloads would also have to be delayed.
1879 // FIXME: Is there a reason not to do that?
Sebastian Redlb293a452010-07-20 21:20:32 +00001880 TotalNumSLocEntries += F.LocalNumSLocEntries;
Douglas Gregord54f3a12009-10-05 21:07:28 +00001881 SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
Douglas Gregor258ae542009-04-27 06:38:32 +00001882 break;
1883
Sebastian Redl539c5062010-08-18 23:57:32 +00001884 case SOURCE_LOCATION_PRELOADS:
Douglas Gregor258ae542009-04-27 06:38:32 +00001885 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
Sebastian Redl2c499f62010-08-18 23:56:43 +00001886 ASTReadResult Result = ReadSLocEntryRecord(Record[I]);
Douglas Gregor258ae542009-04-27 06:38:32 +00001887 if (Result != Success)
1888 return Result;
1889 }
1890 break;
Douglas Gregorc5046832009-04-27 18:38:38 +00001891
Sebastian Redl539c5062010-08-18 23:57:32 +00001892 case STAT_CACHE: {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001893 ASTStatCache *MyStatCache =
1894 new ASTStatCache((const unsigned char *)BlobStart + Record[0],
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001895 (const unsigned char *)BlobStart,
1896 NumStatHits, NumStatMisses);
1897 FileMgr.addStatCache(MyStatCache);
Sebastian Redl34522812010-07-16 17:50:48 +00001898 F.StatCache = MyStatCache;
Douglas Gregorc5046832009-04-27 18:38:38 +00001899 break;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001900 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001901
Sebastian Redl539c5062010-08-18 23:57:32 +00001902 case EXT_VECTOR_DECLS:
Sebastian Redl04f5c312010-07-28 21:38:49 +00001903 // Optimization for the first block.
1904 if (ExtVectorDecls.empty())
1905 ExtVectorDecls.swap(Record);
1906 else
1907 ExtVectorDecls.insert(ExtVectorDecls.end(),
1908 Record.begin(), Record.end());
Douglas Gregor61cac2b2009-04-27 20:06:05 +00001909 break;
1910
Sebastian Redl539c5062010-08-18 23:57:32 +00001911 case VTABLE_USES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001912 // Later tables overwrite earlier ones.
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001913 VTableUses.swap(Record);
1914 break;
1915
Sebastian Redl539c5062010-08-18 23:57:32 +00001916 case DYNAMIC_CLASSES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001917 // Optimization for the first block.
1918 if (DynamicClasses.empty())
1919 DynamicClasses.swap(Record);
1920 else
1921 DynamicClasses.insert(DynamicClasses.end(),
1922 Record.begin(), Record.end());
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001923 break;
1924
Sebastian Redl539c5062010-08-18 23:57:32 +00001925 case PENDING_IMPLICIT_INSTANTIATIONS:
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00001926 // Optimization for the first block.
1927 if (PendingImplicitInstantiations.empty())
1928 PendingImplicitInstantiations.swap(Record);
1929 else
1930 PendingImplicitInstantiations.insert(
1931 PendingImplicitInstantiations.end(), Record.begin(), Record.end());
1932 break;
1933
Sebastian Redl539c5062010-08-18 23:57:32 +00001934 case SEMA_DECL_REFS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001935 // Later tables overwrite earlier ones.
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00001936 SemaDeclRefs.swap(Record);
1937 break;
1938
Sebastian Redl539c5062010-08-18 23:57:32 +00001939 case ORIGINAL_FILE_NAME:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001940 // The primary AST will be the last to get here, so it will be the one
Sebastian Redlb293a452010-07-20 21:20:32 +00001941 // that's used.
Daniel Dunbar000c4ff2009-11-11 05:29:04 +00001942 ActualOriginalFileName.assign(BlobStart, BlobLen);
1943 OriginalFileName = ActualOriginalFileName;
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001944 MaybeAddSystemRootToFilename(OriginalFileName);
Douglas Gregor45fe0362009-05-12 01:31:05 +00001945 break;
Mike Stump11289f42009-09-09 15:08:12 +00001946
Sebastian Redl539c5062010-08-18 23:57:32 +00001947 case VERSION_CONTROL_BRANCH_REVISION: {
Ted Kremenek8bd09292010-02-12 23:31:14 +00001948 const std::string &CurBranch = getClangFullRepositoryVersion();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001949 llvm::StringRef ASTBranch(BlobStart, BlobLen);
1950 if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
1951 Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
Douglas Gregord54f3a12009-10-05 21:07:28 +00001952 return IgnorePCH;
1953 }
1954 break;
1955 }
Sebastian Redlfa061442010-07-21 20:07:32 +00001956
Sebastian Redl539c5062010-08-18 23:57:32 +00001957 case MACRO_DEFINITION_OFFSETS:
Sebastian Redlfa061442010-07-21 20:07:32 +00001958 F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
1959 F.NumPreallocatedPreprocessingEntities = Record[0];
1960 F.LocalNumMacroDefinitions = Record[1];
Douglas Gregoraae92242010-03-19 21:51:54 +00001961 break;
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001962
Sebastian Redl539c5062010-08-18 23:57:32 +00001963 case DECL_REPLACEMENTS: {
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001964 if (Record.size() % 2 != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001965 Error("invalid DECL_REPLACEMENTS block in AST file");
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001966 return Failure;
1967 }
1968 for (unsigned I = 0, N = Record.size(); I != N; I += 2)
Sebastian Redl539c5062010-08-18 23:57:32 +00001969 ReplacedDecls[static_cast<DeclID>(Record[I])] =
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001970 std::make_pair(&F, Record[I+1]);
1971 break;
1972 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001973 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001974 First = false;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001975 }
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001976 Error("premature end of bitstream in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001977 return Failure;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001978}
1979
Sebastian Redl3e31c722010-08-18 23:56:56 +00001980ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
1981 switch(ReadASTCore(FileName)) {
Sebastian Redl2abc0382010-07-16 20:41:52 +00001982 case Failure: return Failure;
1983 case IgnorePCH: return IgnorePCH;
1984 case Success: break;
1985 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001986
1987 // Here comes stuff that we only do once the entire chain is loaded.
1988
Sebastian Redlb293a452010-07-20 21:20:32 +00001989 // Allocate space for loaded identifiers, decls and types.
Sebastian Redlfa061442010-07-21 20:07:32 +00001990 unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
Sebastian Redlada023c2010-08-04 20:40:17 +00001991 TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
1992 TotalNumSelectors = 0;
Sebastian Redl9e687992010-07-19 22:06:55 +00001993 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001994 TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
Sebastian Redl9e687992010-07-19 22:06:55 +00001995 TotalNumTypes += Chain[I]->LocalNumTypes;
1996 TotalNumDecls += Chain[I]->LocalNumDecls;
Sebastian Redlfa061442010-07-21 20:07:32 +00001997 TotalNumPreallocatedPreprocessingEntities +=
1998 Chain[I]->NumPreallocatedPreprocessingEntities;
1999 TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
Sebastian Redlada023c2010-08-04 20:40:17 +00002000 TotalNumSelectors += Chain[I]->LocalNumSelectors;
Sebastian Redl9e687992010-07-19 22:06:55 +00002001 }
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00002002 IdentifiersLoaded.resize(TotalNumIdentifiers);
Sebastian Redl9e687992010-07-19 22:06:55 +00002003 TypesLoaded.resize(TotalNumTypes);
2004 DeclsLoaded.resize(TotalNumDecls);
Sebastian Redlfa061442010-07-21 20:07:32 +00002005 MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
2006 if (PP) {
2007 if (TotalNumIdentifiers > 0)
2008 PP->getHeaderSearchInfo().SetExternalLookup(this);
2009 if (TotalNumPreallocatedPreprocessingEntities > 0) {
2010 if (!PP->getPreprocessingRecord())
2011 PP->createPreprocessingRecord();
2012 PP->getPreprocessingRecord()->SetExternalSource(*this,
2013 TotalNumPreallocatedPreprocessingEntities);
2014 }
2015 }
Sebastian Redlada023c2010-08-04 20:40:17 +00002016 SelectorsLoaded.resize(TotalNumSelectors);
Sebastian Redl9e687992010-07-19 22:06:55 +00002017
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002018 // Check the predefines buffers.
Douglas Gregorce3a8292010-07-27 00:27:13 +00002019 if (!DisableValidation && CheckPredefinesBuffers())
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002020 return IgnorePCH;
2021
2022 if (PP) {
2023 // Initialization of keywords and pragmas occurs before the
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002024 // AST file is read, so there may be some identifiers that were
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002025 // loaded into the IdentifierTable before we intercepted the
2026 // creation of identifiers. Iterate through the list of known
2027 // identifiers and determine whether we have to establish
2028 // preprocessor definitions or top-level identifier declaration
2029 // chains for those identifiers.
2030 //
2031 // We copy the IdentifierInfo pointers to a small vector first,
2032 // since de-serializing declarations or macro definitions can add
2033 // new entries into the identifier table, invalidating the
2034 // iterators.
2035 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
2036 for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
2037 IdEnd = PP->getIdentifierTable().end();
2038 Id != IdEnd; ++Id)
2039 Identifiers.push_back(Id->second);
Sebastian Redlfa061442010-07-21 20:07:32 +00002040 // We need to search the tables in all files.
Sebastian Redlfa061442010-07-21 20:07:32 +00002041 for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002042 ASTIdentifierLookupTable *IdTable
2043 = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
2044 // Not all AST files necessarily have identifier tables, only the useful
Sebastian Redl5c415f32010-07-22 17:01:13 +00002045 // ones.
2046 if (!IdTable)
2047 continue;
Sebastian Redlfa061442010-07-21 20:07:32 +00002048 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
2049 IdentifierInfo *II = Identifiers[I];
2050 // Look in the on-disk hash tables for an entry for this identifier
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002051 ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
Sebastian Redlfa061442010-07-21 20:07:32 +00002052 std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002053 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
Sebastian Redlb293a452010-07-20 21:20:32 +00002054 if (Pos == IdTable->end())
2055 continue;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002056
Sebastian Redlb293a452010-07-20 21:20:32 +00002057 // Dereferencing the iterator has the effect of populating the
2058 // IdentifierInfo node with the various declarations it needs.
2059 (void)*Pos;
2060 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002061 }
2062 }
2063
2064 if (Context)
2065 InitializeContext(*Context);
2066
2067 return Success;
2068}
2069
Sebastian Redl3e31c722010-08-18 23:56:56 +00002070ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002071 Chain.push_back(new PerFileData());
Sebastian Redl34522812010-07-16 17:50:48 +00002072 PerFileData &F = *Chain.back();
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002073
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002074 // Set the AST file name.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002075 F.FileName = FileName;
2076
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002077 // Open the AST file.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002078 //
2079 // FIXME: This shouldn't be here, we should just take a raw_ostream.
2080 std::string ErrStr;
2081 F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
2082 if (!F.Buffer) {
2083 Error(ErrStr.c_str());
2084 return IgnorePCH;
2085 }
2086
2087 // Initialize the stream
2088 F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
2089 (const unsigned char *)F.Buffer->getBufferEnd());
Sebastian Redl34522812010-07-16 17:50:48 +00002090 llvm::BitstreamCursor &Stream = F.Stream;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002091 Stream.init(F.StreamFile);
Sebastian Redlfa061442010-07-21 20:07:32 +00002092 F.SizeInBits = F.Buffer->getBufferSize() * 8;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002093
2094 // Sniff for the signature.
2095 if (Stream.Read(8) != 'C' ||
2096 Stream.Read(8) != 'P' ||
2097 Stream.Read(8) != 'C' ||
2098 Stream.Read(8) != 'H') {
2099 Diag(diag::err_not_a_pch_file) << FileName;
2100 return Failure;
2101 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002102
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002103 while (!Stream.AtEndOfStream()) {
2104 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002105
Douglas Gregor92863e42009-04-10 23:10:45 +00002106 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002107 Error("invalid record at top-level of AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002108 return Failure;
2109 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002110
2111 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregora868bbd2009-04-21 22:25:48 +00002112
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002113 // We only know the AST subblock ID.
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002114 switch (BlockID) {
2115 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregor92863e42009-04-10 23:10:45 +00002116 if (Stream.ReadBlockInfoBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002117 Error("malformed BlockInfoBlock in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002118 return Failure;
2119 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002120 break;
Sebastian Redl539c5062010-08-18 23:57:32 +00002121 case AST_BLOCK_ID:
Sebastian Redl3e31c722010-08-18 23:56:56 +00002122 switch (ReadASTBlock(F)) {
Douglas Gregor55abb232009-04-10 20:39:37 +00002123 case Success:
2124 break;
2125
2126 case Failure:
Douglas Gregor92863e42009-04-10 23:10:45 +00002127 return Failure;
Douglas Gregor55abb232009-04-10 20:39:37 +00002128
2129 case IgnorePCH:
Douglas Gregorbfbde532009-04-10 21:16:55 +00002130 // FIXME: We could consider reading through to the end of this
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002131 // AST block, skipping subblocks, to see if there are other
2132 // AST blocks elsewhere.
Douglas Gregor0bc12932009-04-27 21:28:04 +00002133
2134 // Clear out any preallocated source location entries, so that
2135 // the source manager does not try to resolve them later.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002136 SourceMgr.ClearPreallocatedSLocEntries();
Douglas Gregor0bc12932009-04-27 21:28:04 +00002137
2138 // Remove the stat cache.
Sebastian Redl34522812010-07-16 17:50:48 +00002139 if (F.StatCache)
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002140 FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
Douglas Gregor0bc12932009-04-27 21:28:04 +00002141
Douglas Gregor92863e42009-04-10 23:10:45 +00002142 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00002143 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002144 break;
2145 default:
Douglas Gregor92863e42009-04-10 23:10:45 +00002146 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002147 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002148 return Failure;
2149 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002150 break;
2151 }
Mike Stump11289f42009-09-09 15:08:12 +00002152 }
2153
Sebastian Redl2abc0382010-07-16 20:41:52 +00002154 return Success;
2155}
2156
Sebastian Redl2c499f62010-08-18 23:56:43 +00002157void ASTReader::setPreprocessor(Preprocessor &pp) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002158 PP = &pp;
Sebastian Redlfa061442010-07-21 20:07:32 +00002159
2160 unsigned TotalNum = 0;
2161 for (unsigned I = 0, N = Chain.size(); I != N; ++I)
2162 TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
2163 if (TotalNum) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002164 if (!PP->getPreprocessingRecord())
2165 PP->createPreprocessingRecord();
Sebastian Redlfa061442010-07-21 20:07:32 +00002166 PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
Douglas Gregoraae92242010-03-19 21:51:54 +00002167 }
2168}
2169
Sebastian Redl2c499f62010-08-18 23:56:43 +00002170void ASTReader::InitializeContext(ASTContext &Ctx) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002171 Context = &Ctx;
2172 assert(Context && "Passed null context!");
2173
2174 assert(PP && "Forgot to set Preprocessor ?");
2175 PP->getIdentifierTable().setExternalIdentifierLookup(this);
2176 PP->getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor9882a5a2010-01-04 19:18:44 +00002177 PP->setExternalSource(this);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00002178
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002179 // Load the translation unit declaration
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00002180 GetTranslationUnitDecl();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002181
2182 // Load the special types.
2183 Context->setBuiltinVaListType(
Sebastian Redl539c5062010-08-18 23:57:32 +00002184 GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
2185 if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002186 Context->setObjCIdType(GetType(Id));
Sebastian Redl539c5062010-08-18 23:57:32 +00002187 if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002188 Context->setObjCSelType(GetType(Sel));
Sebastian Redl539c5062010-08-18 23:57:32 +00002189 if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002190 Context->setObjCProtoType(GetType(Proto));
Sebastian Redl539c5062010-08-18 23:57:32 +00002191 if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002192 Context->setObjCClassType(GetType(Class));
Steve Naroff7cae42b2009-07-10 23:34:53 +00002193
Sebastian Redl539c5062010-08-18 23:57:32 +00002194 if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002195 Context->setCFConstantStringType(GetType(String));
Mike Stump11289f42009-09-09 15:08:12 +00002196 if (unsigned FastEnum
Sebastian Redl539c5062010-08-18 23:57:32 +00002197 = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002198 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
Sebastian Redl539c5062010-08-18 23:57:32 +00002199 if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
Douglas Gregor27821ce2009-07-07 16:35:42 +00002200 QualType FileType = GetType(File);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002201 if (FileType.isNull()) {
2202 Error("FILE type is NULL");
2203 return;
2204 }
John McCall9dd450b2009-09-21 23:43:11 +00002205 if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
Douglas Gregor27821ce2009-07-07 16:35:42 +00002206 Context->setFILEDecl(Typedef->getDecl());
2207 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002208 const TagType *Tag = FileType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002209 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002210 Error("Invalid FILE type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002211 return;
2212 }
Douglas Gregor27821ce2009-07-07 16:35:42 +00002213 Context->setFILEDecl(Tag->getDecl());
2214 }
2215 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002216 if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002217 QualType Jmp_bufType = GetType(Jmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002218 if (Jmp_bufType.isNull()) {
2219 Error("jmp_bug type is NULL");
2220 return;
2221 }
John McCall9dd450b2009-09-21 23:43:11 +00002222 if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002223 Context->setjmp_bufDecl(Typedef->getDecl());
2224 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002225 const TagType *Tag = Jmp_bufType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002226 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002227 Error("Invalid jmp_buf type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002228 return;
2229 }
Mike Stumpa4de80b2009-07-28 02:25:19 +00002230 Context->setjmp_bufDecl(Tag->getDecl());
2231 }
2232 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002233 if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002234 QualType Sigjmp_bufType = GetType(Sigjmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002235 if (Sigjmp_bufType.isNull()) {
2236 Error("sigjmp_buf type is NULL");
2237 return;
2238 }
John McCall9dd450b2009-09-21 23:43:11 +00002239 if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002240 Context->setsigjmp_bufDecl(Typedef->getDecl());
2241 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002242 const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002243 assert(Tag && "Invalid sigjmp_buf type in AST file");
Mike Stumpa4de80b2009-07-28 02:25:19 +00002244 Context->setsigjmp_bufDecl(Tag->getDecl());
2245 }
2246 }
Mike Stump11289f42009-09-09 15:08:12 +00002247 if (unsigned ObjCIdRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002248 = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002249 Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
Mike Stump11289f42009-09-09 15:08:12 +00002250 if (unsigned ObjCClassRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002251 = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002252 Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002253 if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Mike Stumpd0153282009-10-20 02:12:22 +00002254 Context->setBlockDescriptorType(GetType(String));
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002255 if (unsigned String
Sebastian Redl539c5062010-08-18 23:57:32 +00002256 = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002257 Context->setBlockDescriptorExtendedType(GetType(String));
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002258 if (unsigned ObjCSelRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002259 = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002260 Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002261 if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002262 Context->setNSConstantStringType(GetType(String));
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002263
Sebastian Redl539c5062010-08-18 23:57:32 +00002264 if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002265 Context->setInt128Installed();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002266}
2267
Douglas Gregor45fe0362009-05-12 01:31:05 +00002268/// \brief Retrieve the name of the original source file name
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002269/// directly from the AST file, without actually loading the AST
Douglas Gregor45fe0362009-05-12 01:31:05 +00002270/// file.
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002271std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
Daniel Dunbar3b951482009-12-03 09:13:06 +00002272 Diagnostic &Diags) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002273 // Open the AST file.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002274 std::string ErrStr;
2275 llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002276 Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr));
Douglas Gregor45fe0362009-05-12 01:31:05 +00002277 if (!Buffer) {
Daniel Dunbar3b951482009-12-03 09:13:06 +00002278 Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002279 return std::string();
2280 }
2281
2282 // Initialize the stream
2283 llvm::BitstreamReader StreamFile;
2284 llvm::BitstreamCursor Stream;
Mike Stump11289f42009-09-09 15:08:12 +00002285 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
Douglas Gregor45fe0362009-05-12 01:31:05 +00002286 (const unsigned char *)Buffer->getBufferEnd());
2287 Stream.init(StreamFile);
2288
2289 // Sniff for the signature.
2290 if (Stream.Read(8) != 'C' ||
2291 Stream.Read(8) != 'P' ||
2292 Stream.Read(8) != 'C' ||
2293 Stream.Read(8) != 'H') {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002294 Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002295 return std::string();
2296 }
2297
2298 RecordData Record;
2299 while (!Stream.AtEndOfStream()) {
2300 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002301
Douglas Gregor45fe0362009-05-12 01:31:05 +00002302 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2303 unsigned BlockID = Stream.ReadSubBlockID();
Mike Stump11289f42009-09-09 15:08:12 +00002304
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002305 // We only know the AST subblock ID.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002306 switch (BlockID) {
Sebastian Redl539c5062010-08-18 23:57:32 +00002307 case AST_BLOCK_ID:
2308 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002309 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002310 return std::string();
2311 }
2312 break;
Mike Stump11289f42009-09-09 15:08:12 +00002313
Douglas Gregor45fe0362009-05-12 01:31:05 +00002314 default:
2315 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002316 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002317 return std::string();
2318 }
2319 break;
2320 }
2321 continue;
2322 }
2323
2324 if (Code == llvm::bitc::END_BLOCK) {
2325 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002326 Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002327 return std::string();
2328 }
2329 continue;
2330 }
2331
2332 if (Code == llvm::bitc::DEFINE_ABBREV) {
2333 Stream.ReadAbbrevRecord();
2334 continue;
2335 }
2336
2337 Record.clear();
2338 const char *BlobStart = 0;
2339 unsigned BlobLen = 0;
Mike Stump11289f42009-09-09 15:08:12 +00002340 if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
Sebastian Redl539c5062010-08-18 23:57:32 +00002341 == ORIGINAL_FILE_NAME)
Douglas Gregor45fe0362009-05-12 01:31:05 +00002342 return std::string(BlobStart, BlobLen);
Mike Stump11289f42009-09-09 15:08:12 +00002343 }
Douglas Gregor45fe0362009-05-12 01:31:05 +00002344
2345 return std::string();
2346}
2347
Douglas Gregor55abb232009-04-10 20:39:37 +00002348/// \brief Parse the record that corresponds to a LangOptions data
2349/// structure.
2350///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002351/// This routine parses the language options from the AST file and then gives
2352/// them to the AST listener if one is set.
Douglas Gregor55abb232009-04-10 20:39:37 +00002353///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002354/// \returns true if the listener deems the file unacceptable, false otherwise.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002355bool ASTReader::ParseLanguageOptions(
Douglas Gregor55abb232009-04-10 20:39:37 +00002356 const llvm::SmallVectorImpl<uint64_t> &Record) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002357 if (Listener) {
2358 LangOptions LangOpts;
Mike Stump11289f42009-09-09 15:08:12 +00002359
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002360 #define PARSE_LANGOPT(Option) \
2361 LangOpts.Option = Record[Idx]; \
2362 ++Idx
Mike Stump11289f42009-09-09 15:08:12 +00002363
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002364 unsigned Idx = 0;
2365 PARSE_LANGOPT(Trigraphs);
2366 PARSE_LANGOPT(BCPLComment);
2367 PARSE_LANGOPT(DollarIdents);
2368 PARSE_LANGOPT(AsmPreprocessor);
2369 PARSE_LANGOPT(GNUMode);
Chandler Carruthe03aa552010-04-17 20:17:31 +00002370 PARSE_LANGOPT(GNUKeywords);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002371 PARSE_LANGOPT(ImplicitInt);
2372 PARSE_LANGOPT(Digraphs);
2373 PARSE_LANGOPT(HexFloats);
2374 PARSE_LANGOPT(C99);
2375 PARSE_LANGOPT(Microsoft);
2376 PARSE_LANGOPT(CPlusPlus);
2377 PARSE_LANGOPT(CPlusPlus0x);
2378 PARSE_LANGOPT(CXXOperatorNames);
2379 PARSE_LANGOPT(ObjC1);
2380 PARSE_LANGOPT(ObjC2);
2381 PARSE_LANGOPT(ObjCNonFragileABI);
Fariborz Jahanian45878032010-02-09 19:31:38 +00002382 PARSE_LANGOPT(ObjCNonFragileABI2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +00002383 PARSE_LANGOPT(NoConstantCFStrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002384 PARSE_LANGOPT(PascalStrings);
2385 PARSE_LANGOPT(WritableStrings);
2386 PARSE_LANGOPT(LaxVectorConversions);
Nate Begemanf2911662009-06-25 23:01:11 +00002387 PARSE_LANGOPT(AltiVec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002388 PARSE_LANGOPT(Exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +00002389 PARSE_LANGOPT(SjLjExceptions);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002390 PARSE_LANGOPT(NeXTRuntime);
2391 PARSE_LANGOPT(Freestanding);
2392 PARSE_LANGOPT(NoBuiltin);
2393 PARSE_LANGOPT(ThreadsafeStatics);
Douglas Gregorb3286fe2009-09-03 14:36:33 +00002394 PARSE_LANGOPT(POSIXThreads);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002395 PARSE_LANGOPT(Blocks);
2396 PARSE_LANGOPT(EmitAllDecls);
2397 PARSE_LANGOPT(MathErrno);
Chris Lattner51924e512010-06-26 21:25:03 +00002398 LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
2399 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002400 PARSE_LANGOPT(HeinousExtensions);
2401 PARSE_LANGOPT(Optimize);
2402 PARSE_LANGOPT(OptimizeSize);
2403 PARSE_LANGOPT(Static);
2404 PARSE_LANGOPT(PICLevel);
2405 PARSE_LANGOPT(GNUInline);
2406 PARSE_LANGOPT(NoInline);
2407 PARSE_LANGOPT(AccessControl);
2408 PARSE_LANGOPT(CharIsSigned);
John Thompsoned4e2952009-11-05 20:14:16 +00002409 PARSE_LANGOPT(ShortWChar);
Chris Lattner51924e512010-06-26 21:25:03 +00002410 LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
2411 LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
Daniel Dunbar143021e2009-09-21 04:16:19 +00002412 LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Chris Lattner51924e512010-06-26 21:25:03 +00002413 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002414 PARSE_LANGOPT(InstantiationDepth);
Nate Begemanf2911662009-06-25 23:01:11 +00002415 PARSE_LANGOPT(OpenCL);
Mike Stumpd9546382009-12-12 01:27:46 +00002416 PARSE_LANGOPT(CatchUndefined);
2417 // FIXME: Missing ElideConstructors?!
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002418 #undef PARSE_LANGOPT
Douglas Gregor55abb232009-04-10 20:39:37 +00002419
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002420 return Listener->ReadLanguageOptions(LangOpts);
Douglas Gregor55abb232009-04-10 20:39:37 +00002421 }
Douglas Gregor55abb232009-04-10 20:39:37 +00002422
2423 return false;
2424}
2425
Sebastian Redl2c499f62010-08-18 23:56:43 +00002426void ASTReader::ReadPreprocessedEntities() {
Douglas Gregoraae92242010-03-19 21:51:54 +00002427 ReadDefinedMacros();
2428}
2429
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002430/// \brief Get the correct cursor and offset for loading a type.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002431ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002432 PerFileData *F = 0;
2433 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
2434 F = Chain[N - I - 1];
2435 if (Index < F->LocalNumTypes)
2436 break;
2437 Index -= F->LocalNumTypes;
2438 }
2439 assert(F && F->LocalNumTypes > Index && "Broken chain");
Sebastian Redlb2831db2010-07-20 22:55:31 +00002440 return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002441}
2442
2443/// \brief Read and return the type with the given index..
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002444///
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002445/// The index is the type ID, shifted and minus the number of predefs. This
2446/// routine actually reads the record corresponding to the type at the given
2447/// location. It is a helper routine for GetType, which deals with reading type
2448/// IDs.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002449QualType ASTReader::ReadTypeRecord(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002450 RecordLocation Loc = TypeCursorForIndex(Index);
Sebastian Redlb2831db2010-07-20 22:55:31 +00002451 llvm::BitstreamCursor &DeclsCursor = *Loc.first;
Sebastian Redl34522812010-07-16 17:50:48 +00002452
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002453 // Keep track of where we are in the stream, then jump back there
2454 // after reading this type.
Douglas Gregor12bfa382009-10-17 00:13:19 +00002455 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002456
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00002457 ReadingKindTracker ReadingKind(Read_Type, *this);
Sebastian Redleaa4ade2010-08-11 18:52:41 +00002458
Douglas Gregor1342e842009-07-06 18:54:52 +00002459 // Note that we are loading a type record.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00002460 Deserializing AType(this);
Mike Stump11289f42009-09-09 15:08:12 +00002461
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002462 DeclsCursor.JumpToBit(Loc.second);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002463 RecordData Record;
Douglas Gregor12bfa382009-10-17 00:13:19 +00002464 unsigned Code = DeclsCursor.ReadCode();
Sebastian Redl539c5062010-08-18 23:57:32 +00002465 switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
2466 case TYPE_EXT_QUAL: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002467 if (Record.size() != 2) {
2468 Error("Incorrect encoding of extended qualifier type");
2469 return QualType();
2470 }
Douglas Gregor455b8f42009-04-15 22:00:08 +00002471 QualType Base = GetType(Record[0]);
John McCall8ccfcb52009-09-24 19:53:00 +00002472 Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
2473 return Context->getQualifiedType(Base, Quals);
Douglas Gregor455b8f42009-04-15 22:00:08 +00002474 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002475
Sebastian Redl539c5062010-08-18 23:57:32 +00002476 case TYPE_COMPLEX: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002477 if (Record.size() != 1) {
2478 Error("Incorrect encoding of complex type");
2479 return QualType();
2480 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002481 QualType ElemType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002482 return Context->getComplexType(ElemType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002483 }
2484
Sebastian Redl539c5062010-08-18 23:57:32 +00002485 case TYPE_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002486 if (Record.size() != 1) {
2487 Error("Incorrect encoding of pointer type");
2488 return QualType();
2489 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002490 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002491 return Context->getPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002492 }
2493
Sebastian Redl539c5062010-08-18 23:57:32 +00002494 case TYPE_BLOCK_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002495 if (Record.size() != 1) {
2496 Error("Incorrect encoding of block pointer type");
2497 return QualType();
2498 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002499 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002500 return Context->getBlockPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002501 }
2502
Sebastian Redl539c5062010-08-18 23:57:32 +00002503 case TYPE_LVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002504 if (Record.size() != 1) {
2505 Error("Incorrect encoding of lvalue reference type");
2506 return QualType();
2507 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002508 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002509 return Context->getLValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002510 }
2511
Sebastian Redl539c5062010-08-18 23:57:32 +00002512 case TYPE_RVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002513 if (Record.size() != 1) {
2514 Error("Incorrect encoding of rvalue reference type");
2515 return QualType();
2516 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002517 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002518 return Context->getRValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002519 }
2520
Sebastian Redl539c5062010-08-18 23:57:32 +00002521 case TYPE_MEMBER_POINTER: {
Argyrios Kyrtzidisee776bc2010-07-02 11:55:15 +00002522 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002523 Error("Incorrect encoding of member pointer type");
2524 return QualType();
2525 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002526 QualType PointeeType = GetType(Record[0]);
2527 QualType ClassType = GetType(Record[1]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002528 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002529 }
2530
Sebastian Redl539c5062010-08-18 23:57:32 +00002531 case TYPE_CONSTANT_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002532 QualType ElementType = GetType(Record[0]);
2533 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2534 unsigned IndexTypeQuals = Record[2];
2535 unsigned Idx = 3;
2536 llvm::APInt Size = ReadAPInt(Record, Idx);
Douglas Gregor04318252009-07-06 15:59:29 +00002537 return Context->getConstantArrayType(ElementType, Size,
2538 ASM, IndexTypeQuals);
2539 }
2540
Sebastian Redl539c5062010-08-18 23:57:32 +00002541 case TYPE_INCOMPLETE_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002542 QualType ElementType = GetType(Record[0]);
2543 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2544 unsigned IndexTypeQuals = Record[2];
Chris Lattner8575daa2009-04-27 21:45:14 +00002545 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002546 }
2547
Sebastian Redl539c5062010-08-18 23:57:32 +00002548 case TYPE_VARIABLE_ARRAY: {
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002549 QualType ElementType = GetType(Record[0]);
2550 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2551 unsigned IndexTypeQuals = Record[2];
Douglas Gregor04318252009-07-06 15:59:29 +00002552 SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
2553 SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002554 return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor),
Douglas Gregor04318252009-07-06 15:59:29 +00002555 ASM, IndexTypeQuals,
2556 SourceRange(LBLoc, RBLoc));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002557 }
2558
Sebastian Redl539c5062010-08-18 23:57:32 +00002559 case TYPE_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002560 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002561 Error("incorrect encoding of vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002562 return QualType();
2563 }
2564
2565 QualType ElementType = GetType(Record[0]);
2566 unsigned NumElements = Record[1];
Chris Lattner37141f42010-06-23 06:00:24 +00002567 unsigned AltiVecSpec = Record[2];
2568 return Context->getVectorType(ElementType, NumElements,
2569 (VectorType::AltiVecSpecific)AltiVecSpec);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002570 }
2571
Sebastian Redl539c5062010-08-18 23:57:32 +00002572 case TYPE_EXT_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002573 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002574 Error("incorrect encoding of extended vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002575 return QualType();
2576 }
2577
2578 QualType ElementType = GetType(Record[0]);
2579 unsigned NumElements = Record[1];
Chris Lattner8575daa2009-04-27 21:45:14 +00002580 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002581 }
2582
Sebastian Redl539c5062010-08-18 23:57:32 +00002583 case TYPE_FUNCTION_NO_PROTO: {
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002584 if (Record.size() != 4) {
Douglas Gregor6f00bf82009-04-28 21:53:25 +00002585 Error("incorrect encoding of no-proto function type");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002586 return QualType();
2587 }
2588 QualType ResultType = GetType(Record[0]);
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002589 FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002590 return Context->getFunctionNoProtoType(ResultType, Info);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002591 }
2592
Sebastian Redl539c5062010-08-18 23:57:32 +00002593 case TYPE_FUNCTION_PROTO: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002594 QualType ResultType = GetType(Record[0]);
Douglas Gregordc728752009-12-22 18:11:50 +00002595 bool NoReturn = Record[1];
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002596 unsigned RegParm = Record[2];
2597 CallingConv CallConv = (CallingConv)Record[3];
2598 unsigned Idx = 4;
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002599 unsigned NumParams = Record[Idx++];
2600 llvm::SmallVector<QualType, 16> ParamTypes;
2601 for (unsigned I = 0; I != NumParams; ++I)
2602 ParamTypes.push_back(GetType(Record[Idx++]));
2603 bool isVariadic = Record[Idx++];
2604 unsigned Quals = Record[Idx++];
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002605 bool hasExceptionSpec = Record[Idx++];
2606 bool hasAnyExceptionSpec = Record[Idx++];
2607 unsigned NumExceptions = Record[Idx++];
2608 llvm::SmallVector<QualType, 2> Exceptions;
2609 for (unsigned I = 0; I != NumExceptions; ++I)
2610 Exceptions.push_back(GetType(Record[Idx++]));
Jay Foad7d0479f2009-05-21 09:52:38 +00002611 return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002612 isVariadic, Quals, hasExceptionSpec,
2613 hasAnyExceptionSpec, NumExceptions,
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002614 Exceptions.data(),
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002615 FunctionType::ExtInfo(NoReturn, RegParm,
2616 CallConv));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002617 }
2618
Sebastian Redl539c5062010-08-18 23:57:32 +00002619 case TYPE_UNRESOLVED_USING:
John McCallb96ec562009-12-04 22:46:56 +00002620 return Context->getTypeDeclType(
2621 cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
2622
Sebastian Redl539c5062010-08-18 23:57:32 +00002623 case TYPE_TYPEDEF: {
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002624 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002625 Error("incorrect encoding of typedef type");
2626 return QualType();
2627 }
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002628 TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
2629 QualType Canonical = GetType(Record[1]);
2630 return Context->getTypedefType(Decl, Canonical);
2631 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002632
Sebastian Redl539c5062010-08-18 23:57:32 +00002633 case TYPE_TYPEOF_EXPR:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002634 return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002635
Sebastian Redl539c5062010-08-18 23:57:32 +00002636 case TYPE_TYPEOF: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002637 if (Record.size() != 1) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002638 Error("incorrect encoding of typeof(type) in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002639 return QualType();
2640 }
2641 QualType UnderlyingType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002642 return Context->getTypeOfType(UnderlyingType);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002643 }
Mike Stump11289f42009-09-09 15:08:12 +00002644
Sebastian Redl539c5062010-08-18 23:57:32 +00002645 case TYPE_DECLTYPE:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002646 return Context->getDecltypeType(ReadExpr(DeclsCursor));
Anders Carlsson81df7b82009-06-24 19:06:50 +00002647
Sebastian Redl539c5062010-08-18 23:57:32 +00002648 case TYPE_RECORD: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002649 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002650 Error("incorrect encoding of record type");
2651 return QualType();
2652 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002653 bool IsDependent = Record[0];
2654 QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
2655 T->Dependent = IsDependent;
2656 return T;
2657 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002658
Sebastian Redl539c5062010-08-18 23:57:32 +00002659 case TYPE_ENUM: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002660 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002661 Error("incorrect encoding of enum type");
2662 return QualType();
2663 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002664 bool IsDependent = Record[0];
2665 QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
2666 T->Dependent = IsDependent;
2667 return T;
2668 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00002669
Sebastian Redl539c5062010-08-18 23:57:32 +00002670 case TYPE_ELABORATED: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002671 unsigned Idx = 0;
2672 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2673 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2674 QualType NamedType = GetType(Record[Idx++]);
2675 return Context->getElaboratedType(Keyword, NNS, NamedType);
John McCallfcc33b02009-09-05 00:15:47 +00002676 }
2677
Sebastian Redl539c5062010-08-18 23:57:32 +00002678 case TYPE_OBJC_INTERFACE: {
Chris Lattner587cbe12009-04-22 06:45:28 +00002679 unsigned Idx = 0;
2680 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002681 return Context->getObjCInterfaceType(ItfD);
2682 }
2683
Sebastian Redl539c5062010-08-18 23:57:32 +00002684 case TYPE_OBJC_OBJECT: {
John McCall8b07ec22010-05-15 11:32:37 +00002685 unsigned Idx = 0;
2686 QualType Base = GetType(Record[Idx++]);
Chris Lattner587cbe12009-04-22 06:45:28 +00002687 unsigned NumProtos = Record[Idx++];
2688 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
2689 for (unsigned I = 0; I != NumProtos; ++I)
2690 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
John McCall8b07ec22010-05-15 11:32:37 +00002691 return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
Chris Lattner587cbe12009-04-22 06:45:28 +00002692 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002693
Sebastian Redl539c5062010-08-18 23:57:32 +00002694 case TYPE_OBJC_OBJECT_POINTER: {
Chris Lattner6e054af2009-04-22 06:40:03 +00002695 unsigned Idx = 0;
John McCall8b07ec22010-05-15 11:32:37 +00002696 QualType Pointee = GetType(Record[Idx++]);
2697 return Context->getObjCObjectPointerType(Pointee);
Chris Lattner6e054af2009-04-22 06:40:03 +00002698 }
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002699
Sebastian Redl539c5062010-08-18 23:57:32 +00002700 case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
John McCallcebee162009-10-18 09:09:24 +00002701 unsigned Idx = 0;
2702 QualType Parm = GetType(Record[Idx++]);
2703 QualType Replacement = GetType(Record[Idx++]);
2704 return
2705 Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2706 Replacement);
2707 }
John McCalle78aac42010-03-10 03:28:59 +00002708
Sebastian Redl539c5062010-08-18 23:57:32 +00002709 case TYPE_INJECTED_CLASS_NAME: {
John McCalle78aac42010-03-10 03:28:59 +00002710 CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
2711 QualType TST = GetType(Record[1]); // probably derivable
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002712 // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002713 // for AST reading, too much interdependencies.
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002714 return
2715 QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
John McCalle78aac42010-03-10 03:28:59 +00002716 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002717
Sebastian Redl539c5062010-08-18 23:57:32 +00002718 case TYPE_TEMPLATE_TYPE_PARM: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002719 unsigned Idx = 0;
2720 unsigned Depth = Record[Idx++];
2721 unsigned Index = Record[Idx++];
2722 bool Pack = Record[Idx++];
2723 IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
2724 return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
2725 }
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002726
Sebastian Redl539c5062010-08-18 23:57:32 +00002727 case TYPE_DEPENDENT_NAME: {
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002728 unsigned Idx = 0;
2729 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2730 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2731 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
Argyrios Kyrtzidise9290952010-07-02 11:55:24 +00002732 QualType Canon = GetType(Record[Idx++]);
2733 return Context->getDependentNameType(Keyword, NNS, Name, Canon);
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002734 }
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002735
Sebastian Redl539c5062010-08-18 23:57:32 +00002736 case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002737 unsigned Idx = 0;
2738 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2739 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2740 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
2741 unsigned NumArgs = Record[Idx++];
2742 llvm::SmallVector<TemplateArgument, 8> Args;
2743 Args.reserve(NumArgs);
2744 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002745 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002746 return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
2747 Args.size(), Args.data());
2748 }
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002749
Sebastian Redl539c5062010-08-18 23:57:32 +00002750 case TYPE_DEPENDENT_SIZED_ARRAY: {
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002751 unsigned Idx = 0;
2752
2753 // ArrayType
2754 QualType ElementType = GetType(Record[Idx++]);
2755 ArrayType::ArraySizeModifier ASM
2756 = (ArrayType::ArraySizeModifier)Record[Idx++];
2757 unsigned IndexTypeQuals = Record[Idx++];
2758
2759 // DependentSizedArrayType
Sebastian Redlc67764e2010-07-22 22:43:28 +00002760 Expr *NumElts = ReadExpr(DeclsCursor);
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002761 SourceRange Brackets = ReadSourceRange(Record, Idx);
2762
2763 return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
2764 IndexTypeQuals, Brackets);
2765 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002766
Sebastian Redl539c5062010-08-18 23:57:32 +00002767 case TYPE_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002768 unsigned Idx = 0;
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002769 bool IsDependent = Record[Idx++];
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002770 TemplateName Name = ReadTemplateName(Record, Idx);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002771 llvm::SmallVector<TemplateArgument, 8> Args;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002772 ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00002773 QualType Canon = GetType(Record[Idx++]);
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002774 QualType T;
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002775 if (Canon.isNull())
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002776 T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
2777 Args.size());
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002778 else
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002779 T = Context->getTemplateSpecializationType(Name, Args.data(),
2780 Args.size(), Canon);
2781 T->Dependent = IsDependent;
2782 return T;
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002783 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002784 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002785 // Suppress a GCC warning
2786 return QualType();
2787}
2788
John McCall8f115c62009-10-16 21:56:05 +00002789namespace {
2790
2791class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
Sebastian Redl2c499f62010-08-18 23:56:43 +00002792 ASTReader &Reader;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002793 llvm::BitstreamCursor &DeclsCursor;
Sebastian Redl2c499f62010-08-18 23:56:43 +00002794 const ASTReader::RecordData &Record;
John McCall8f115c62009-10-16 21:56:05 +00002795 unsigned &Idx;
2796
2797public:
Sebastian Redl2c499f62010-08-18 23:56:43 +00002798 TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
2799 const ASTReader::RecordData &Record, unsigned &Idx)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002800 : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
John McCall8f115c62009-10-16 21:56:05 +00002801
John McCall17001972009-10-18 01:05:36 +00002802 // We want compile-time assurance that we've enumerated all of
2803 // these, so unfortunately we have to declare them first, then
2804 // define them out-of-line.
2805#define ABSTRACT_TYPELOC(CLASS, PARENT)
John McCall8f115c62009-10-16 21:56:05 +00002806#define TYPELOC(CLASS, PARENT) \
John McCall17001972009-10-18 01:05:36 +00002807 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
John McCall8f115c62009-10-16 21:56:05 +00002808#include "clang/AST/TypeLocNodes.def"
2809
John McCall17001972009-10-18 01:05:36 +00002810 void VisitFunctionTypeLoc(FunctionTypeLoc);
2811 void VisitArrayTypeLoc(ArrayTypeLoc);
John McCall8f115c62009-10-16 21:56:05 +00002812};
2813
2814}
2815
John McCall17001972009-10-18 01:05:36 +00002816void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
John McCall8f115c62009-10-16 21:56:05 +00002817 // nothing to do
2818}
John McCall17001972009-10-18 01:05:36 +00002819void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Douglas Gregorc9b7a592010-01-18 18:04:31 +00002820 TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2821 if (TL.needsExtraLocalData()) {
2822 TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2823 TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2824 TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2825 TL.setModeAttr(Record[Idx++]);
2826 }
John McCall8f115c62009-10-16 21:56:05 +00002827}
John McCall17001972009-10-18 01:05:36 +00002828void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2829 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002830}
John McCall17001972009-10-18 01:05:36 +00002831void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2832 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002833}
John McCall17001972009-10-18 01:05:36 +00002834void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2835 TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002836}
John McCall17001972009-10-18 01:05:36 +00002837void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2838 TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002839}
John McCall17001972009-10-18 01:05:36 +00002840void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2841 TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002842}
John McCall17001972009-10-18 01:05:36 +00002843void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2844 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002845}
John McCall17001972009-10-18 01:05:36 +00002846void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2847 TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2848 TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002849 if (Record[Idx++])
Sebastian Redlc67764e2010-07-22 22:43:28 +00002850 TL.setSizeExpr(Reader.ReadExpr(DeclsCursor));
Douglas Gregor12bfa382009-10-17 00:13:19 +00002851 else
John McCall17001972009-10-18 01:05:36 +00002852 TL.setSizeExpr(0);
2853}
2854void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2855 VisitArrayTypeLoc(TL);
2856}
2857void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2858 VisitArrayTypeLoc(TL);
2859}
2860void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2861 VisitArrayTypeLoc(TL);
2862}
2863void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2864 DependentSizedArrayTypeLoc TL) {
2865 VisitArrayTypeLoc(TL);
2866}
2867void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2868 DependentSizedExtVectorTypeLoc TL) {
2869 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2870}
2871void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2872 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2873}
2874void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2875 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2876}
2877void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2878 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2879 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2880 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
John McCalle6347002009-10-23 01:28:53 +00002881 TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
John McCall17001972009-10-18 01:05:36 +00002882 }
2883}
2884void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2885 VisitFunctionTypeLoc(TL);
2886}
2887void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2888 VisitFunctionTypeLoc(TL);
2889}
John McCallb96ec562009-12-04 22:46:56 +00002890void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2891 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2892}
John McCall17001972009-10-18 01:05:36 +00002893void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2894 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2895}
2896void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002897 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2898 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2899 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall17001972009-10-18 01:05:36 +00002900}
2901void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002902 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2903 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2904 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Sebastian Redlc67764e2010-07-22 22:43:28 +00002905 TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002906}
2907void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2908 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2909}
2910void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2911 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2912}
2913void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2914 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2915}
John McCall17001972009-10-18 01:05:36 +00002916void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2917 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2918}
John McCallcebee162009-10-18 09:09:24 +00002919void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2920 SubstTemplateTypeParmTypeLoc TL) {
2921 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2922}
John McCall17001972009-10-18 01:05:36 +00002923void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2924 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002925 TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2926 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2927 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2928 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2929 TL.setArgLocInfo(i,
2930 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002931 DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002932}
Abramo Bagnara6150c882010-05-11 21:36:43 +00002933void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002934 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2935 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002936}
John McCalle78aac42010-03-10 03:28:59 +00002937void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
2938 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2939}
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +00002940void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002941 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2942 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002943 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2944}
John McCallc392f372010-06-11 00:33:02 +00002945void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
2946 DependentTemplateSpecializationTypeLoc TL) {
2947 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2948 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
2949 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2950 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2951 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2952 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
2953 TL.setArgLocInfo(I,
2954 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002955 DeclsCursor, Record, Idx));
John McCallc392f372010-06-11 00:33:02 +00002956}
John McCall17001972009-10-18 01:05:36 +00002957void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2958 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002959}
2960void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
2961 TL.setHasBaseTypeAsWritten(Record[Idx++]);
John McCall17001972009-10-18 01:05:36 +00002962 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2963 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2964 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2965 TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002966}
John McCallfc93cf92009-10-22 22:37:11 +00002967void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2968 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCallfc93cf92009-10-22 22:37:11 +00002969}
John McCall8f115c62009-10-16 21:56:05 +00002970
Sebastian Redl2c499f62010-08-18 23:56:43 +00002971TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00002972 const RecordData &Record,
John McCall8f115c62009-10-16 21:56:05 +00002973 unsigned &Idx) {
2974 QualType InfoTy = GetType(Record[Idx++]);
2975 if (InfoTy.isNull())
2976 return 0;
2977
John McCallbcd03502009-12-07 02:54:59 +00002978 TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002979 TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
John McCallbcd03502009-12-07 02:54:59 +00002980 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
John McCall8f115c62009-10-16 21:56:05 +00002981 TLR.Visit(TL);
John McCallbcd03502009-12-07 02:54:59 +00002982 return TInfo;
John McCall8f115c62009-10-16 21:56:05 +00002983}
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002984
Sebastian Redl539c5062010-08-18 23:57:32 +00002985QualType ASTReader::GetType(TypeID ID) {
John McCall8ccfcb52009-09-24 19:53:00 +00002986 unsigned FastQuals = ID & Qualifiers::FastMask;
2987 unsigned Index = ID >> Qualifiers::FastWidth;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002988
Sebastian Redl539c5062010-08-18 23:57:32 +00002989 if (Index < NUM_PREDEF_TYPE_IDS) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002990 QualType T;
Sebastian Redl539c5062010-08-18 23:57:32 +00002991 switch ((PredefinedTypeIDs)Index) {
2992 case PREDEF_TYPE_NULL_ID: return QualType();
2993 case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
2994 case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002995
Sebastian Redl539c5062010-08-18 23:57:32 +00002996 case PREDEF_TYPE_CHAR_U_ID:
2997 case PREDEF_TYPE_CHAR_S_ID:
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002998 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattner8575daa2009-04-27 21:45:14 +00002999 T = Context->CharTy;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003000 break;
3001
Sebastian Redl539c5062010-08-18 23:57:32 +00003002 case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
3003 case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
3004 case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
3005 case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
3006 case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
3007 case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
3008 case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
3009 case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
3010 case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
3011 case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
3012 case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
3013 case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
3014 case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
3015 case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
3016 case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
3017 case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
3018 case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
3019 case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
3020 case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
3021 case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
3022 case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
3023 case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
3024 case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
3025 case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003026 }
3027
3028 assert(!T.isNull() && "Unknown predefined type");
John McCall8ccfcb52009-09-24 19:53:00 +00003029 return T.withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003030 }
3031
Sebastian Redl539c5062010-08-18 23:57:32 +00003032 Index -= NUM_PREDEF_TYPE_IDS;
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003033 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Sebastian Redl409183f2010-07-14 20:26:45 +00003034 if (TypesLoaded[Index].isNull()) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003035 TypesLoaded[Index] = ReadTypeRecord(Index);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003036 TypesLoaded[Index]->setFromAST();
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003037 TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003038 if (DeserializationListener)
Argyrios Kyrtzidisbb5c7eae2010-08-20 16:03:59 +00003039 DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003040 TypesLoaded[Index]);
Sebastian Redl409183f2010-07-14 20:26:45 +00003041 }
Mike Stump11289f42009-09-09 15:08:12 +00003042
John McCall8ccfcb52009-09-24 19:53:00 +00003043 return TypesLoaded[Index].withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003044}
3045
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003046TypeID ASTReader::GetTypeID(QualType T) const {
3047 return MakeTypeID(T,
3048 std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
3049}
3050
3051TypeIdx ASTReader::GetTypeIdx(QualType T) const {
3052 if (T.isNull())
3053 return TypeIdx();
3054 assert(!T.getLocalFastQualifiers());
3055
3056 TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3057 // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
3058 // comparing keys of ASTDeclContextNameLookupTable.
3059 // If the type didn't come from the AST file use a specially marked index
3060 // so that any hash/key comparison fail since no such index is stored
3061 // in a AST file.
3062 if (I == TypeIdxs.end())
3063 return TypeIdx(-1);
3064 return I->second;
3065}
3066
John McCall0ad16662009-10-29 08:12:44 +00003067TemplateArgumentLocInfo
Sebastian Redl2c499f62010-08-18 23:56:43 +00003068ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003069 llvm::BitstreamCursor &DeclsCursor,
John McCall0ad16662009-10-29 08:12:44 +00003070 const RecordData &Record,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003071 unsigned &Index) {
John McCall0ad16662009-10-29 08:12:44 +00003072 switch (Kind) {
3073 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003074 return ReadExpr(DeclsCursor);
John McCall0ad16662009-10-29 08:12:44 +00003075 case TemplateArgument::Type:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003076 return GetTypeSourceInfo(DeclsCursor, Record, Index);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003077 case TemplateArgument::Template: {
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003078 SourceRange QualifierRange = ReadSourceRange(Record, Index);
3079 SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
3080 return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003081 }
John McCall0ad16662009-10-29 08:12:44 +00003082 case TemplateArgument::Null:
3083 case TemplateArgument::Integral:
3084 case TemplateArgument::Declaration:
3085 case TemplateArgument::Pack:
3086 return TemplateArgumentLocInfo();
3087 }
Jeffrey Yasskin1615d452009-12-12 05:05:38 +00003088 llvm_unreachable("unexpected template argument loc");
John McCall0ad16662009-10-29 08:12:44 +00003089 return TemplateArgumentLocInfo();
3090}
3091
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003092TemplateArgumentLoc
Sebastian Redl2c499f62010-08-18 23:56:43 +00003093ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003094 const RecordData &Record, unsigned &Index) {
3095 TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003096
3097 if (Arg.getKind() == TemplateArgument::Expression) {
3098 if (Record[Index++]) // bool InfoHasSameExpr.
3099 return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
3100 }
3101 return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00003102 DeclsCursor,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003103 Record, Index));
Argyrios Kyrtzidisae85e242010-06-22 09:54:59 +00003104}
3105
Sebastian Redl2c499f62010-08-18 23:56:43 +00003106Decl *ASTReader::GetExternalDecl(uint32_t ID) {
John McCall75b960e2010-06-01 09:23:16 +00003107 return GetDecl(ID);
3108}
3109
Sebastian Redl2c499f62010-08-18 23:56:43 +00003110TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003111 if (!DeclsLoaded[0]) {
Sebastian Redld7dce0a2010-08-24 00:50:04 +00003112 ReadDeclRecord(0, 1);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003113 if (DeserializationListener)
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003114 DeserializationListener->DeclRead(1, DeclsLoaded[0]);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003115 }
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00003116
3117 return cast<TranslationUnitDecl>(DeclsLoaded[0]);
3118}
3119
Sebastian Redl539c5062010-08-18 23:57:32 +00003120Decl *ASTReader::GetDecl(DeclID ID) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003121 if (ID == 0)
3122 return 0;
3123
Douglas Gregor745ed142009-04-25 18:35:21 +00003124 if (ID > DeclsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003125 Error("declaration ID out-of-range for AST file");
Douglas Gregor745ed142009-04-25 18:35:21 +00003126 return 0;
3127 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003128
Douglas Gregor745ed142009-04-25 18:35:21 +00003129 unsigned Index = ID - 1;
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003130 if (!DeclsLoaded[Index]) {
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00003131 ReadDeclRecord(Index, ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003132 if (DeserializationListener)
3133 DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
3134 }
Douglas Gregor745ed142009-04-25 18:35:21 +00003135
3136 return DeclsLoaded[Index];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003137}
3138
Chris Lattner9c28af02009-04-27 05:46:25 +00003139/// \brief Resolve the offset of a statement into a statement.
3140///
3141/// This operation will read a new statement from the external
3142/// source each time it is called, and is meant to be used via a
3143/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Sebastian Redl2c499f62010-08-18 23:56:43 +00003144Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
Sebastian Redl5c415f32010-07-22 17:01:13 +00003145 // Offset here is a global offset across the entire chain.
3146 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3147 PerFileData &F = *Chain[N - I - 1];
3148 if (Offset < F.SizeInBits) {
3149 // Since we know that this statement is part of a decl, make sure to use
3150 // the decl cursor to read it.
3151 F.DeclsCursor.JumpToBit(Offset);
3152 return ReadStmtFromStream(F.DeclsCursor);
3153 }
3154 Offset -= F.SizeInBits;
3155 }
3156 llvm_unreachable("Broken chain");
Douglas Gregor3c3aa612009-04-18 00:07:54 +00003157}
3158
Sebastian Redl2c499f62010-08-18 23:56:43 +00003159bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003160 llvm::SmallVectorImpl<Decl*> &Decls) {
Mike Stump11289f42009-09-09 15:08:12 +00003161 assert(DC->hasExternalLexicalStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003162 "DeclContext has no lexical decls in storage");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003163
Sebastian Redl5c415f32010-07-22 17:01:13 +00003164 // There might be lexical decls in multiple parts of the chain, for the TU
3165 // at least.
3166 DeclContextInfos &Infos = DeclContextOffsets[DC];
3167 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3168 I != E; ++I) {
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003169 // IDs can be 0 if this context doesn't contain declarations.
3170 if (!I->LexicalDecls)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003171 continue;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003172
3173 // Load all of the declaration IDs
Sebastian Redl539c5062010-08-18 23:57:32 +00003174 for (const DeclID *ID = I->LexicalDecls,
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003175 *IDE = ID + I->NumLexicalDecls;
3176 ID != IDE; ++ID)
3177 Decls.push_back(GetDecl(*ID));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003178 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003179
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003180 ++NumLexicalDeclContextsRead;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003181 return false;
3182}
3183
John McCall75b960e2010-06-01 09:23:16 +00003184DeclContext::lookup_result
Sebastian Redl2c499f62010-08-18 23:56:43 +00003185ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003186 DeclarationName Name) {
Mike Stump11289f42009-09-09 15:08:12 +00003187 assert(DC->hasExternalVisibleStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003188 "DeclContext has no visible decls in storage");
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003189 if (!Name)
3190 return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
3191 DeclContext::lookup_iterator(0));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003192
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003193 llvm::SmallVector<NamedDecl *, 64> Decls;
Sebastian Redl471ac2f2010-08-24 00:49:55 +00003194 // There might be visible decls in multiple parts of the chain, for the TU
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003195 // and namespaces. For any given name, the last available results replace
3196 // all earlier ones. For this reason, we walk in reverse.
Sebastian Redl5c415f32010-07-22 17:01:13 +00003197 DeclContextInfos &Infos = DeclContextOffsets[DC];
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003198 for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
Sebastian Redl5c415f32010-07-22 17:01:13 +00003199 I != E; ++I) {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003200 if (!I->NameLookupTableData)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003201 continue;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003202
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003203 ASTDeclContextNameLookupTable *LookupTable =
3204 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3205 ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
3206 if (Pos == LookupTable->end())
Sebastian Redl5c415f32010-07-22 17:01:13 +00003207 continue;
3208
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003209 ASTDeclContextNameLookupTrait::data_type Data = *Pos;
3210 for (; Data.first != Data.second; ++Data.first)
3211 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003212 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003213 }
3214
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003215 ++NumVisibleDeclContextsRead;
John McCall75b960e2010-06-01 09:23:16 +00003216
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003217 SetExternalVisibleDeclsForName(DC, Name, Decls);
John McCall75b960e2010-06-01 09:23:16 +00003218 return const_cast<DeclContext*>(DC)->lookup(Name);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003219}
3220
Argyrios Kyrtzidisd32ee892010-08-20 23:35:55 +00003221void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
3222 assert(DC->hasExternalVisibleStorage() &&
3223 "DeclContext has no visible decls in storage");
3224
3225 llvm::SmallVector<NamedDecl *, 64> Decls;
3226 // There might be visible decls in multiple parts of the chain, for the TU
3227 // and namespaces.
3228 DeclContextInfos &Infos = DeclContextOffsets[DC];
3229 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3230 I != E; ++I) {
3231 if (!I->NameLookupTableData)
3232 continue;
3233
3234 ASTDeclContextNameLookupTable *LookupTable =
3235 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3236 for (ASTDeclContextNameLookupTable::item_iterator
3237 ItemI = LookupTable->item_begin(),
3238 ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
3239 ASTDeclContextNameLookupTable::item_iterator::value_type Val
3240 = *ItemI;
3241 ASTDeclContextNameLookupTrait::data_type Data = Val.second;
3242 Decls.clear();
3243 for (; Data.first != Data.second; ++Data.first)
3244 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
3245 MaterializeVisibleDeclsForName(DC, Val.first, Decls);
3246 }
3247 }
3248}
3249
Sebastian Redl2c499f62010-08-18 23:56:43 +00003250void ASTReader::PassInterestingDeclsToConsumer() {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003251 assert(Consumer);
3252 while (!InterestingDecls.empty()) {
3253 DeclGroupRef DG(InterestingDecls.front());
3254 InterestingDecls.pop_front();
Sebastian Redleaa4ade2010-08-11 18:52:41 +00003255 Consumer->HandleInterestingDecl(DG);
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003256 }
3257}
3258
Sebastian Redl2c499f62010-08-18 23:56:43 +00003259void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregorb985eeb2009-04-22 19:09:20 +00003260 this->Consumer = Consumer;
3261
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003262 if (!Consumer)
3263 return;
3264
3265 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003266 // Force deserialization of this decl, which will cause it to be queued for
3267 // passing to the consumer.
Daniel Dunbar865c2a72009-09-17 03:06:44 +00003268 GetDecl(ExternalDefinitions[I]);
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003269 }
Douglas Gregorf005eac2009-04-25 00:41:30 +00003270
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003271 PassInterestingDeclsToConsumer();
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003272}
3273
Sebastian Redl2c499f62010-08-18 23:56:43 +00003274void ASTReader::PrintStats() {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003275 std::fprintf(stderr, "*** AST File Statistics:\n");
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003276
Mike Stump11289f42009-09-09 15:08:12 +00003277 unsigned NumTypesLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003278 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
John McCall8ccfcb52009-09-24 19:53:00 +00003279 QualType());
Douglas Gregor0e149972009-04-25 19:10:14 +00003280 unsigned NumDeclsLoaded
3281 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
3282 (Decl *)0);
3283 unsigned NumIdentifiersLoaded
3284 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
3285 IdentifiersLoaded.end(),
3286 (IdentifierInfo *)0);
Mike Stump11289f42009-09-09 15:08:12 +00003287 unsigned NumSelectorsLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003288 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
3289 SelectorsLoaded.end(),
3290 Selector());
Douglas Gregorc3b1dd12009-04-13 20:50:16 +00003291
Douglas Gregorc5046832009-04-27 18:38:38 +00003292 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
3293 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor258ae542009-04-27 06:38:32 +00003294 if (TotalNumSLocEntries)
3295 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
3296 NumSLocEntriesRead, TotalNumSLocEntries,
3297 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor745ed142009-04-25 18:35:21 +00003298 if (!TypesLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003299 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003300 NumTypesLoaded, (unsigned)TypesLoaded.size(),
3301 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
3302 if (!DeclsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003303 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003304 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
3305 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor0e149972009-04-25 19:10:14 +00003306 if (!IdentifiersLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003307 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor0e149972009-04-25 19:10:14 +00003308 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
3309 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Sebastian Redlada023c2010-08-04 20:40:17 +00003310 if (!SelectorsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003311 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
Sebastian Redlada023c2010-08-04 20:40:17 +00003312 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
3313 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
Douglas Gregor95c13f52009-04-25 17:48:32 +00003314 if (TotalNumStatements)
3315 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
3316 NumStatementsRead, TotalNumStatements,
3317 ((float)NumStatementsRead/TotalNumStatements * 100));
3318 if (TotalNumMacros)
3319 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
3320 NumMacrosRead, TotalNumMacros,
3321 ((float)NumMacrosRead/TotalNumMacros * 100));
3322 if (TotalLexicalDeclContexts)
3323 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
3324 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
3325 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
3326 * 100));
3327 if (TotalVisibleDeclContexts)
3328 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
3329 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
3330 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
3331 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003332 if (TotalNumMethodPoolEntries) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003333 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003334 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
3335 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
Douglas Gregor95c13f52009-04-25 17:48:32 +00003336 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003337 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
Douglas Gregor95c13f52009-04-25 17:48:32 +00003338 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003339 std::fprintf(stderr, "\n");
3340}
3341
Sebastian Redl2c499f62010-08-18 23:56:43 +00003342void ASTReader::InitializeSema(Sema &S) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003343 SemaObj = &S;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003344 S.ExternalSource = this;
3345
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003346 // Makes sure any declarations that were deserialized "too early"
3347 // still get added to the identifier's declaration chains.
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003348 if (SemaObj->TUScope) {
3349 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
John McCall48871652010-08-21 09:40:31 +00003350 SemaObj->TUScope->AddDecl(PreloadedDecls[I]);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003351 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
3352 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003353 }
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003354 PreloadedDecls.clear();
Douglas Gregord4df8652009-04-22 22:02:47 +00003355
3356 // If there were any tentative definitions, deserialize them and add
Sebastian Redl35351a92010-01-31 22:27:38 +00003357 // them to Sema's list of tentative definitions.
Douglas Gregord4df8652009-04-22 22:02:47 +00003358 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
3359 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
Sebastian Redl35351a92010-01-31 22:27:38 +00003360 SemaObj->TentativeDefinitions.push_back(Var);
Douglas Gregord4df8652009-04-22 22:02:47 +00003361 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00003362
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00003363 // If there were any unused file scoped decls, deserialize them and add to
3364 // Sema's list of unused file scoped decls.
3365 for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
3366 DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
3367 SemaObj->UnusedFileScopedDecls.push_back(D);
Tanya Lattner90073802010-02-12 00:07:30 +00003368 }
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003369
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00003370 // If there were any weak undeclared identifiers, deserialize them and add to
3371 // Sema's list of weak undeclared identifiers.
3372 if (!WeakUndeclaredIdentifiers.empty()) {
3373 unsigned Idx = 0;
3374 for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
3375 IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3376 IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3377 SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
3378 bool Used = WeakUndeclaredIdentifiers[Idx++];
3379 Sema::WeakInfo WI(AliasId, Loc);
3380 WI.setUsed(Used);
3381 SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
3382 }
3383 }
3384
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003385 // If there were any locally-scoped external declarations,
3386 // deserialize them and add them to Sema's table of locally-scoped
3387 // external declarations.
3388 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
3389 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
3390 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
3391 }
Douglas Gregor61cac2b2009-04-27 20:06:05 +00003392
3393 // If there were any ext_vector type declarations, deserialize them
3394 // and add them to Sema's vector of such declarations.
3395 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
3396 SemaObj->ExtVectorDecls.push_back(
3397 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003398
3399 // FIXME: Do VTable uses and dynamic classes deserialize too much ?
3400 // Can we cut them down before writing them ?
3401
3402 // If there were any VTable uses, deserialize the information and add it
3403 // to Sema's vector and map of VTable uses.
Argyrios Kyrtzidisedee67f2010-08-03 17:29:52 +00003404 if (!VTableUses.empty()) {
3405 unsigned Idx = 0;
3406 for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
3407 CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
3408 SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
3409 bool DefinitionRequired = VTableUses[Idx++];
3410 SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
3411 SemaObj->VTablesUsed[Class] = DefinitionRequired;
3412 }
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003413 }
3414
3415 // If there were any dynamic classes declarations, deserialize them
3416 // and add them to Sema's vector of such declarations.
3417 for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
3418 SemaObj->DynamicClasses.push_back(
3419 cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003420
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00003421 // If there were any pending implicit instantiations, deserialize them
3422 // and add them to Sema's queue of such instantiations.
3423 assert(PendingImplicitInstantiations.size() % 2 == 0 &&
3424 "Expected pairs of entries");
3425 for (unsigned Idx = 0, N = PendingImplicitInstantiations.size(); Idx < N;) {
3426 ValueDecl *D=cast<ValueDecl>(GetDecl(PendingImplicitInstantiations[Idx++]));
3427 SourceLocation Loc = ReadSourceLocation(PendingImplicitInstantiations, Idx);
3428 SemaObj->PendingImplicitInstantiations.push_back(std::make_pair(D, Loc));
3429 }
3430
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00003431 // Load the offsets of the declarations that Sema references.
3432 // They will be lazily deserialized when needed.
3433 if (!SemaDeclRefs.empty()) {
3434 assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
3435 SemaObj->StdNamespace = SemaDeclRefs[0];
3436 SemaObj->StdBadAlloc = SemaDeclRefs[1];
3437 }
3438
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003439 // If there are @selector references added them to its pool. This is for
3440 // implementation of -Wselector.
Sebastian Redlada023c2010-08-04 20:40:17 +00003441 if (!ReferencedSelectorsData.empty()) {
3442 unsigned int DataSize = ReferencedSelectorsData.size()-1;
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003443 unsigned I = 0;
3444 while (I < DataSize) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003445 Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003446 SourceLocation SelLoc =
Sebastian Redlada023c2010-08-04 20:40:17 +00003447 SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003448 SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
3449 }
3450 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003451}
3452
Sebastian Redl2c499f62010-08-18 23:56:43 +00003453IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Sebastian Redl78f51772010-08-02 18:30:12 +00003454 // Try to find this name within our on-disk hash tables. We start with the
3455 // most recent one, since that one contains the most up-to-date info.
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003456 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003457 ASTIdentifierLookupTable *IdTable
3458 = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003459 if (!IdTable)
3460 continue;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003461 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003462 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003463 if (Pos == IdTable->end())
3464 continue;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003465
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003466 // Dereferencing the iterator has the effect of building the
3467 // IdentifierInfo node and populating it with the various
3468 // declarations it needs.
Sebastian Redl78f51772010-08-02 18:30:12 +00003469 return *Pos;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003470 }
Sebastian Redl78f51772010-08-02 18:30:12 +00003471 return 0;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003472}
3473
Mike Stump11289f42009-09-09 15:08:12 +00003474std::pair<ObjCMethodList, ObjCMethodList>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003475ASTReader::ReadMethodPool(Selector Sel) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003476 // Find this selector in a hash table. We want to find the most recent entry.
3477 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3478 PerFileData &F = *Chain[I];
3479 if (!F.SelectorLookupTable)
3480 continue;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003481
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003482 ASTSelectorLookupTable *PoolTable
3483 = (ASTSelectorLookupTable*)F.SelectorLookupTable;
3484 ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
Sebastian Redlada023c2010-08-04 20:40:17 +00003485 if (Pos != PoolTable->end()) {
3486 ++NumSelectorsRead;
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003487 // FIXME: Not quite happy with the statistics here. We probably should
3488 // disable this tracking when called via LoadSelector.
3489 // Also, should entries without methods count as misses?
3490 ++NumMethodPoolEntriesRead;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003491 ASTSelectorLookupTrait::data_type Data = *Pos;
Sebastian Redlada023c2010-08-04 20:40:17 +00003492 if (DeserializationListener)
3493 DeserializationListener->SelectorRead(Data.ID, Sel);
3494 return std::make_pair(Data.Instance, Data.Factory);
3495 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003496 }
Douglas Gregorc78d3462009-04-24 21:10:55 +00003497
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003498 ++NumMethodPoolMisses;
Sebastian Redlada023c2010-08-04 20:40:17 +00003499 return std::pair<ObjCMethodList, ObjCMethodList>();
Douglas Gregorc78d3462009-04-24 21:10:55 +00003500}
3501
Sebastian Redl2c499f62010-08-18 23:56:43 +00003502void ASTReader::LoadSelector(Selector Sel) {
Sebastian Redld95a56e2010-08-04 18:21:41 +00003503 // It would be complicated to avoid reading the methods anyway. So don't.
3504 ReadMethodPool(Sel);
3505}
3506
Sebastian Redl2c499f62010-08-18 23:56:43 +00003507void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003508 assert(ID && "Non-zero identifier ID required");
Douglas Gregor6f00bf82009-04-28 21:53:25 +00003509 assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
Douglas Gregor0e149972009-04-25 19:10:14 +00003510 IdentifiersLoaded[ID - 1] = II;
Sebastian Redlff4a2952010-07-23 23:49:55 +00003511 if (DeserializationListener)
3512 DeserializationListener->IdentifierRead(ID, II);
Douglas Gregora868bbd2009-04-21 22:25:48 +00003513}
3514
Douglas Gregor1342e842009-07-06 18:54:52 +00003515/// \brief Set the globally-visible declarations associated with the given
3516/// identifier.
3517///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003518/// If the AST reader is currently in a state where the given declaration IDs
Mike Stump11289f42009-09-09 15:08:12 +00003519/// cannot safely be resolved, they are queued until it is safe to resolve
Douglas Gregor1342e842009-07-06 18:54:52 +00003520/// them.
3521///
3522/// \param II an IdentifierInfo that refers to one or more globally-visible
3523/// declarations.
3524///
3525/// \param DeclIDs the set of declaration IDs with the name @p II that are
3526/// visible at global scope.
3527///
3528/// \param Nonrecursive should be true to indicate that the caller knows that
3529/// this call is non-recursive, and therefore the globally-visible declarations
3530/// will not be placed onto the pending queue.
Mike Stump11289f42009-09-09 15:08:12 +00003531void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003532ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
Douglas Gregor1342e842009-07-06 18:54:52 +00003533 const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
3534 bool Nonrecursive) {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00003535 if (NumCurrentElementsDeserializing && !Nonrecursive) {
Douglas Gregor1342e842009-07-06 18:54:52 +00003536 PendingIdentifierInfos.push_back(PendingIdentifierInfo());
3537 PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
3538 PII.II = II;
3539 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
3540 PII.DeclIDs.push_back(DeclIDs[I]);
3541 return;
3542 }
Mike Stump11289f42009-09-09 15:08:12 +00003543
Douglas Gregor1342e842009-07-06 18:54:52 +00003544 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
3545 NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
3546 if (SemaObj) {
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003547 if (SemaObj->TUScope) {
3548 // Introduce this declaration into the translation-unit scope
3549 // and add it to the declaration chain for this identifier, so
3550 // that (unqualified) name lookup will find it.
John McCall48871652010-08-21 09:40:31 +00003551 SemaObj->TUScope->AddDecl(D);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003552 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
3553 }
Douglas Gregor1342e842009-07-06 18:54:52 +00003554 } else {
3555 // Queue this declaration so that it will be added to the
3556 // translation unit scope and identifier's declaration chain
3557 // once a Sema object is known.
3558 PreloadedDecls.push_back(D);
3559 }
3560 }
3561}
3562
Sebastian Redl2c499f62010-08-18 23:56:43 +00003563IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003564 if (ID == 0)
3565 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00003566
Sebastian Redlc713b962010-07-21 00:46:22 +00003567 if (IdentifiersLoaded.empty()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003568 Error("no identifier table in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003569 return 0;
3570 }
Mike Stump11289f42009-09-09 15:08:12 +00003571
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003572 assert(PP && "Forgot to set Preprocessor ?");
Sebastian Redlc713b962010-07-21 00:46:22 +00003573 ID -= 1;
3574 if (!IdentifiersLoaded[ID]) {
3575 unsigned Index = ID;
3576 const char *Str = 0;
3577 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3578 PerFileData *F = Chain[N - I - 1];
3579 if (Index < F->LocalNumIdentifiers) {
3580 uint32_t Offset = F->IdentifierOffsets[Index];
3581 Str = F->IdentifierTableData + Offset;
3582 break;
3583 }
3584 Index -= F->LocalNumIdentifiers;
3585 }
3586 assert(Str && "Broken Chain");
Douglas Gregor5287b4e2009-04-25 21:04:17 +00003587
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003588 // All of the strings in the AST file are preceded by a 16-bit length.
3589 // Extract that 16-bit length to avoid having to execute strlen().
Ted Kremenekca42a512009-10-23 04:45:31 +00003590 // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
3591 // unsigned integers. This is important to avoid integer overflow when
3592 // we cast them to 'unsigned'.
Ted Kremenek49c52322009-10-23 03:57:22 +00003593 const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
Douglas Gregorab4df582009-04-28 20:01:51 +00003594 unsigned StrLen = (((unsigned) StrLenPtr[0])
3595 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Sebastian Redlc713b962010-07-21 00:46:22 +00003596 IdentifiersLoaded[ID]
Kovarththanan Rajaratnama3b09592010-03-12 10:32:27 +00003597 = &PP->getIdentifierTable().get(Str, StrLen);
Sebastian Redlff4a2952010-07-23 23:49:55 +00003598 if (DeserializationListener)
3599 DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003600 }
Mike Stump11289f42009-09-09 15:08:12 +00003601
Sebastian Redlc713b962010-07-21 00:46:22 +00003602 return IdentifiersLoaded[ID];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003603}
3604
Sebastian Redl2c499f62010-08-18 23:56:43 +00003605void ASTReader::ReadSLocEntry(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00003606 ReadSLocEntryRecord(ID);
3607}
3608
Sebastian Redl2c499f62010-08-18 23:56:43 +00003609Selector ASTReader::DecodeSelector(unsigned ID) {
Steve Naroff2ddea052009-04-23 10:39:46 +00003610 if (ID == 0)
3611 return Selector();
Mike Stump11289f42009-09-09 15:08:12 +00003612
Sebastian Redlada023c2010-08-04 20:40:17 +00003613 if (ID > SelectorsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003614 Error("selector ID out of range in AST file");
Steve Naroff2ddea052009-04-23 10:39:46 +00003615 return Selector();
3616 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003617
Sebastian Redlada023c2010-08-04 20:40:17 +00003618 if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003619 // Load this selector from the selector table.
Sebastian Redlada023c2010-08-04 20:40:17 +00003620 unsigned Idx = ID - 1;
3621 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3622 PerFileData &F = *Chain[N - I - 1];
3623 if (Idx < F.LocalNumSelectors) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003624 ASTSelectorLookupTrait Trait(*this);
Sebastian Redlada023c2010-08-04 20:40:17 +00003625 SelectorsLoaded[ID - 1] =
3626 Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
3627 if (DeserializationListener)
3628 DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
3629 break;
3630 }
3631 Idx -= F.LocalNumSelectors;
3632 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003633 }
3634
Sebastian Redlada023c2010-08-04 20:40:17 +00003635 return SelectorsLoaded[ID - 1];
Steve Naroff2ddea052009-04-23 10:39:46 +00003636}
3637
Sebastian Redl2c499f62010-08-18 23:56:43 +00003638Selector ASTReader::GetExternalSelector(uint32_t ID) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003639 return DecodeSelector(ID);
3640}
3641
Sebastian Redl2c499f62010-08-18 23:56:43 +00003642uint32_t ASTReader::GetNumExternalSelectors() {
Sebastian Redlada023c2010-08-04 20:40:17 +00003643 // ID 0 (the null selector) is considered an external selector.
3644 return getTotalNumSelectors() + 1;
Douglas Gregord720daf2010-04-06 17:30:22 +00003645}
3646
Mike Stump11289f42009-09-09 15:08:12 +00003647DeclarationName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003648ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003649 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
3650 switch (Kind) {
3651 case DeclarationName::Identifier:
3652 return DeclarationName(GetIdentifierInfo(Record, Idx));
3653
3654 case DeclarationName::ObjCZeroArgSelector:
3655 case DeclarationName::ObjCOneArgSelector:
3656 case DeclarationName::ObjCMultiArgSelector:
Steve Naroff3c301dc2009-04-23 15:15:40 +00003657 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003658
3659 case DeclarationName::CXXConstructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003660 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003661 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003662
3663 case DeclarationName::CXXDestructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003664 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003665 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003666
3667 case DeclarationName::CXXConversionFunctionName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003668 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003669 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003670
3671 case DeclarationName::CXXOperatorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003672 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003673 (OverloadedOperatorKind)Record[Idx++]);
3674
Alexis Hunt3d221f22009-11-29 07:34:05 +00003675 case DeclarationName::CXXLiteralOperatorName:
3676 return Context->DeclarationNames.getCXXLiteralOperatorName(
3677 GetIdentifierInfo(Record, Idx));
3678
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003679 case DeclarationName::CXXUsingDirective:
3680 return DeclarationName::getUsingDirectiveName();
3681 }
3682
3683 // Required to silence GCC warning
3684 return DeclarationName();
3685}
Douglas Gregor55abb232009-04-10 20:39:37 +00003686
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003687TemplateName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003688ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003689 TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
3690 switch (Kind) {
3691 case TemplateName::Template:
3692 return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
3693
3694 case TemplateName::OverloadedTemplate: {
3695 unsigned size = Record[Idx++];
3696 UnresolvedSet<8> Decls;
3697 while (size--)
3698 Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
3699
3700 return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
3701 }
3702
3703 case TemplateName::QualifiedTemplate: {
3704 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3705 bool hasTemplKeyword = Record[Idx++];
3706 TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
3707 return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
3708 }
3709
3710 case TemplateName::DependentTemplate: {
3711 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3712 if (Record[Idx++]) // isIdentifier
3713 return Context->getDependentTemplateName(NNS,
3714 GetIdentifierInfo(Record, Idx));
3715 return Context->getDependentTemplateName(NNS,
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003716 (OverloadedOperatorKind)Record[Idx++]);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003717 }
3718 }
3719
3720 assert(0 && "Unhandled template name kind!");
3721 return TemplateName();
3722}
3723
3724TemplateArgument
Sebastian Redl2c499f62010-08-18 23:56:43 +00003725ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003726 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003727 switch ((TemplateArgument::ArgKind)Record[Idx++]) {
3728 case TemplateArgument::Null:
3729 return TemplateArgument();
3730 case TemplateArgument::Type:
3731 return TemplateArgument(GetType(Record[Idx++]));
3732 case TemplateArgument::Declaration:
3733 return TemplateArgument(GetDecl(Record[Idx++]));
Argyrios Kyrtzidis0b0369a2010-06-28 09:31:34 +00003734 case TemplateArgument::Integral: {
3735 llvm::APSInt Value = ReadAPSInt(Record, Idx);
3736 QualType T = GetType(Record[Idx++]);
3737 return TemplateArgument(Value, T);
3738 }
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003739 case TemplateArgument::Template:
3740 return TemplateArgument(ReadTemplateName(Record, Idx));
3741 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003742 return TemplateArgument(ReadExpr(DeclsCursor));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003743 case TemplateArgument::Pack: {
3744 unsigned NumArgs = Record[Idx++];
3745 llvm::SmallVector<TemplateArgument, 8> Args;
3746 Args.reserve(NumArgs);
3747 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003748 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003749 TemplateArgument TemplArg;
3750 TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
3751 return TemplArg;
3752 }
3753 }
3754
3755 assert(0 && "Unhandled template argument kind!");
3756 return TemplateArgument();
3757}
3758
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003759TemplateParameterList *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003760ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003761 SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
3762 SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
3763 SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
3764
3765 unsigned NumParams = Record[Idx++];
3766 llvm::SmallVector<NamedDecl *, 16> Params;
3767 Params.reserve(NumParams);
3768 while (NumParams--)
3769 Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
3770
3771 TemplateParameterList* TemplateParams =
3772 TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
3773 Params.data(), Params.size(), RAngleLoc);
3774 return TemplateParams;
3775}
3776
3777void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003778ASTReader::
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003779ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003780 llvm::BitstreamCursor &DeclsCursor,
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003781 const RecordData &Record, unsigned &Idx) {
3782 unsigned NumTemplateArgs = Record[Idx++];
3783 TemplArgs.reserve(NumTemplateArgs);
3784 while (NumTemplateArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003785 TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003786}
3787
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003788/// \brief Read a UnresolvedSet structure.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003789void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003790 const RecordData &Record, unsigned &Idx) {
3791 unsigned NumDecls = Record[Idx++];
3792 while (NumDecls--) {
3793 NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
3794 AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
3795 Set.addDecl(D, AS);
3796 }
3797}
3798
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003799CXXBaseSpecifier
Sebastian Redl2c499f62010-08-18 23:56:43 +00003800ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
Nick Lewycky19b9f952010-07-26 16:56:01 +00003801 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003802 bool isVirtual = static_cast<bool>(Record[Idx++]);
3803 bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
3804 AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003805 TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003806 SourceRange Range = ReadSourceRange(Record, Idx);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003807 return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003808}
3809
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003810std::pair<CXXBaseOrMemberInitializer **, unsigned>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003811ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003812 const RecordData &Record,
3813 unsigned &Idx) {
3814 CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
3815 unsigned NumInitializers = Record[Idx++];
3816 if (NumInitializers) {
3817 ASTContext &C = *getContext();
3818
3819 BaseOrMemberInitializers
3820 = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
3821 for (unsigned i=0; i != NumInitializers; ++i) {
3822 TypeSourceInfo *BaseClassInfo = 0;
3823 bool IsBaseVirtual = false;
3824 FieldDecl *Member = 0;
3825
3826 bool IsBaseInitializer = Record[Idx++];
3827 if (IsBaseInitializer) {
3828 BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
3829 IsBaseVirtual = Record[Idx++];
3830 } else {
3831 Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
3832 }
3833 SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
3834 Expr *Init = ReadExpr(Cursor);
3835 FieldDecl *AnonUnionMember
3836 = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
3837 SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
3838 SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
3839 bool IsWritten = Record[Idx++];
3840 unsigned SourceOrderOrNumArrayIndices;
3841 llvm::SmallVector<VarDecl *, 8> Indices;
3842 if (IsWritten) {
3843 SourceOrderOrNumArrayIndices = Record[Idx++];
3844 } else {
3845 SourceOrderOrNumArrayIndices = Record[Idx++];
3846 Indices.reserve(SourceOrderOrNumArrayIndices);
3847 for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
3848 Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
3849 }
3850
3851 CXXBaseOrMemberInitializer *BOMInit;
3852 if (IsBaseInitializer) {
3853 BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
3854 IsBaseVirtual, LParenLoc,
3855 Init, RParenLoc);
3856 } else if (IsWritten) {
3857 BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
3858 LParenLoc, Init, RParenLoc);
3859 } else {
3860 BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
3861 LParenLoc, Init, RParenLoc,
3862 Indices.data(),
3863 Indices.size());
3864 }
3865
3866 BOMInit->setAnonUnionMember(AnonUnionMember);
3867 BaseOrMemberInitializers[i] = BOMInit;
3868 }
3869 }
3870
3871 return std::make_pair(BaseOrMemberInitializers, NumInitializers);
3872}
3873
Chris Lattnerca025db2010-05-07 21:43:38 +00003874NestedNameSpecifier *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003875ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
Chris Lattnerca025db2010-05-07 21:43:38 +00003876 unsigned N = Record[Idx++];
3877 NestedNameSpecifier *NNS = 0, *Prev = 0;
3878 for (unsigned I = 0; I != N; ++I) {
3879 NestedNameSpecifier::SpecifierKind Kind
3880 = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
3881 switch (Kind) {
3882 case NestedNameSpecifier::Identifier: {
3883 IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
3884 NNS = NestedNameSpecifier::Create(*Context, Prev, II);
3885 break;
3886 }
3887
3888 case NestedNameSpecifier::Namespace: {
3889 NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
3890 NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
3891 break;
3892 }
3893
3894 case NestedNameSpecifier::TypeSpec:
3895 case NestedNameSpecifier::TypeSpecWithTemplate: {
3896 Type *T = GetType(Record[Idx++]).getTypePtr();
3897 bool Template = Record[Idx++];
3898 NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
3899 break;
3900 }
3901
3902 case NestedNameSpecifier::Global: {
3903 NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
3904 // No associated value, and there can't be a prefix.
3905 break;
3906 }
Chris Lattnerca025db2010-05-07 21:43:38 +00003907 }
Argyrios Kyrtzidisad65c692010-07-07 15:46:30 +00003908 Prev = NNS;
Chris Lattnerca025db2010-05-07 21:43:38 +00003909 }
3910 return NNS;
3911}
3912
3913SourceRange
Sebastian Redl2c499f62010-08-18 23:56:43 +00003914ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
Daniel Dunbar6d3bc082010-06-02 15:47:10 +00003915 SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
3916 SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
3917 return SourceRange(beg, end);
Chris Lattnerca025db2010-05-07 21:43:38 +00003918}
3919
Douglas Gregor1daeb692009-04-13 18:14:40 +00003920/// \brief Read an integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003921llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003922 unsigned BitWidth = Record[Idx++];
3923 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
3924 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
3925 Idx += NumWords;
3926 return Result;
3927}
3928
3929/// \brief Read a signed integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003930llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003931 bool isUnsigned = Record[Idx++];
3932 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
3933}
3934
Douglas Gregore0a3a512009-04-14 21:55:33 +00003935/// \brief Read a floating-point value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003936llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregore0a3a512009-04-14 21:55:33 +00003937 return llvm::APFloat(ReadAPInt(Record, Idx));
3938}
3939
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003940// \brief Read a string
Sebastian Redl2c499f62010-08-18 23:56:43 +00003941std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003942 unsigned Len = Record[Idx++];
Jay Foad7d0479f2009-05-21 09:52:38 +00003943 std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003944 Idx += Len;
3945 return Result;
3946}
3947
Sebastian Redl2c499f62010-08-18 23:56:43 +00003948CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
Chris Lattnercba86142010-05-10 00:25:06 +00003949 unsigned &Idx) {
3950 CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
3951 return CXXTemporary::Create(*Context, Decl);
3952}
3953
Sebastian Redl2c499f62010-08-18 23:56:43 +00003954DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
Douglas Gregor92863e42009-04-10 23:10:45 +00003955 return Diag(SourceLocation(), DiagID);
3956}
3957
Sebastian Redl2c499f62010-08-18 23:56:43 +00003958DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003959 return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
Douglas Gregor55abb232009-04-10 20:39:37 +00003960}
Douglas Gregora9af1d12009-04-17 00:04:06 +00003961
Douglas Gregora868bbd2009-04-21 22:25:48 +00003962/// \brief Retrieve the identifier table associated with the
3963/// preprocessor.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003964IdentifierTable &ASTReader::getIdentifierTable() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003965 assert(PP && "Forgot to set Preprocessor ?");
3966 return PP->getIdentifierTable();
Douglas Gregora868bbd2009-04-21 22:25:48 +00003967}
3968
Douglas Gregora9af1d12009-04-17 00:04:06 +00003969/// \brief Record that the given ID maps to the given switch-case
3970/// statement.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003971void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003972 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
3973 SwitchCaseStmts[ID] = SC;
3974}
3975
3976/// \brief Retrieve the switch-case statement with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003977SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003978 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
3979 return SwitchCaseStmts[ID];
3980}
Douglas Gregor6cc68a42009-04-17 18:18:49 +00003981
3982/// \brief Record that the given label statement has been
3983/// deserialized and has the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003984void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
Mike Stump11289f42009-09-09 15:08:12 +00003985 assert(LabelStmts.find(ID) == LabelStmts.end() &&
Douglas Gregor6cc68a42009-04-17 18:18:49 +00003986 "Deserialized label twice");
3987 LabelStmts[ID] = S;
3988
3989 // If we've already seen any goto statements that point to this
3990 // label, resolve them now.
3991 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
3992 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
3993 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
3994 Goto->second->setLabel(S);
3995 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor779d8652009-04-17 18:58:21 +00003996
3997 // If we've already seen any address-label statements that point to
3998 // this label, resolve them now.
3999 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
Mike Stump11289f42009-09-09 15:08:12 +00004000 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
Douglas Gregor779d8652009-04-17 18:58:21 +00004001 = UnresolvedAddrLabelExprs.equal_range(ID);
Mike Stump11289f42009-09-09 15:08:12 +00004002 for (AddrLabelIter AddrLabel = AddrLabels.first;
Douglas Gregor779d8652009-04-17 18:58:21 +00004003 AddrLabel != AddrLabels.second; ++AddrLabel)
4004 AddrLabel->second->setLabel(S);
4005 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004006}
4007
4008/// \brief Set the label of the given statement to the label
4009/// identified by ID.
4010///
4011/// Depending on the order in which the label and other statements
4012/// referencing that label occur, this operation may complete
4013/// immediately (updating the statement) or it may queue the
4014/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004015void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004016 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4017 if (Label != LabelStmts.end()) {
4018 // We've already seen this label, so set the label of the goto and
4019 // we're done.
4020 S->setLabel(Label->second);
4021 } else {
4022 // We haven't seen this label yet, so add this goto to the set of
4023 // unresolved goto statements.
4024 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
4025 }
4026}
Douglas Gregor779d8652009-04-17 18:58:21 +00004027
4028/// \brief Set the label of the given expression to the label
4029/// identified by ID.
4030///
4031/// Depending on the order in which the label and other statements
4032/// referencing that label occur, this operation may complete
4033/// immediately (updating the statement) or it may queue the
4034/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004035void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
Douglas Gregor779d8652009-04-17 18:58:21 +00004036 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4037 if (Label != LabelStmts.end()) {
4038 // We've already seen this label, so set the label of the
4039 // label-address expression and we're done.
4040 S->setLabel(Label->second);
4041 } else {
4042 // We haven't seen this label yet, so add this label-address
4043 // expression to the set of unresolved label-address expressions.
4044 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
4045 }
4046}
Douglas Gregor1342e842009-07-06 18:54:52 +00004047
Sebastian Redl2c499f62010-08-18 23:56:43 +00004048void ASTReader::FinishedDeserializing() {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004049 assert(NumCurrentElementsDeserializing &&
4050 "FinishedDeserializing not paired with StartedDeserializing");
4051 if (NumCurrentElementsDeserializing == 1) {
Douglas Gregor1342e842009-07-06 18:54:52 +00004052 // If any identifiers with corresponding top-level declarations have
4053 // been loaded, load those declarations now.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004054 while (!PendingIdentifierInfos.empty()) {
4055 SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
4056 PendingIdentifierInfos.front().DeclIDs, true);
4057 PendingIdentifierInfos.pop_front();
Douglas Gregor1342e842009-07-06 18:54:52 +00004058 }
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00004059
4060 // We are not in recursive loading, so it's safe to pass the "interesting"
4061 // decls to the consumer.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004062 if (Consumer)
4063 PassInterestingDeclsToConsumer();
Douglas Gregor1342e842009-07-06 18:54:52 +00004064 }
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004065 --NumCurrentElementsDeserializing;
Douglas Gregor1342e842009-07-06 18:54:52 +00004066}
Douglas Gregorb473b072010-08-19 00:28:17 +00004067
Sebastian Redld7dce0a2010-08-24 00:50:04 +00004068ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
4069 const char *isysroot, bool DisableValidation)
4070 : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
4071 SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
4072 Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
4073 Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
4074 NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
4075 TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
4076 NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
4077 NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
4078 TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
4079 TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
4080 TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
4081 RelocatablePCH = false;
4082}
4083
4084ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
4085 Diagnostic &Diags, const char *isysroot,
4086 bool DisableValidation)
4087 : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
4088 Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
4089 isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
4090 NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
4091 NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
4092 TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
4093 NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
4094 NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
4095 NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
4096 NumCurrentElementsDeserializing(0) {
4097 RelocatablePCH = false;
4098}
4099
4100ASTReader::~ASTReader() {
4101 for (unsigned i = 0, e = Chain.size(); i != e; ++i)
4102 delete Chain[e - i - 1];
4103 // Delete all visible decl lookup tables
4104 for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
4105 E = DeclContextOffsets.end();
4106 I != E; ++I) {
4107 for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
4108 J != F; ++J) {
4109 if (J->NameLookupTableData)
4110 delete static_cast<ASTDeclContextNameLookupTable*>(
4111 J->NameLookupTableData);
4112 }
4113 }
4114 for (DeclContextVisibleUpdatesPending::iterator
4115 I = PendingVisibleUpdates.begin(),
4116 E = PendingVisibleUpdates.end();
4117 I != E; ++I) {
4118 for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
4119 F = I->second.end();
4120 J != F; ++J)
4121 delete static_cast<ASTDeclContextNameLookupTable*>(*J);
4122 }
4123}
4124
Douglas Gregorb473b072010-08-19 00:28:17 +00004125ASTReader::PerFileData::PerFileData()
4126 : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
4127 LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
4128 IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0),
4129 LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
4130 NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0),
4131 SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0)
4132{}
4133
4134ASTReader::PerFileData::~PerFileData() {
4135 delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
4136 delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
4137}
4138