blob: 46448fff0c9d56c6dc3b2fbdf190ed5f6e7b626b [file] [log] [blame]
Sebastian Redl904c9c82010-08-18 23:57:11 +00001//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//
Douglas Gregor2cf26342009-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 Redlc43b54c2010-08-18 23:56:43 +000010// This file defines the ASTReader class, which reads AST files.
Douglas Gregor2cf26342009-04-09 22:27:44 +000011//
12//===----------------------------------------------------------------------===//
Chris Lattner4c6f9522009-04-27 05:14:47 +000013
Sebastian Redl6ab7cd82010-08-18 23:57:17 +000014#include "clang/Serialization/ASTReader.h"
15#include "clang/Serialization/ASTDeserializationListener.h"
Argyrios Kyrtzidis0eca89e2010-08-20 16:03:52 +000016#include "ASTCommon.h"
Douglas Gregor0a0428e2009-04-10 20:39:37 +000017#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbarc7162932009-11-11 23:58:53 +000018#include "clang/Frontend/Utils.h"
Douglas Gregore737f502010-08-12 20:07:10 +000019#include "clang/Sema/Sema.h"
John McCall5f1e0942010-08-24 08:50:51 +000020#include "clang/Sema/Scope.h"
Douglas Gregorfdd01722009-04-14 00:24:19 +000021#include "clang/AST/ASTConsumer.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000022#include "clang/AST/ASTContext.h"
Douglas Gregor0b748912009-04-14 21:18:50 +000023#include "clang/AST/Expr.h"
John McCall7a1fad32010-08-24 07:32:53 +000024#include "clang/AST/ExprCXX.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000025#include "clang/AST/Type.h"
John McCalla1ee0c52009-10-16 21:56:05 +000026#include "clang/AST/TypeLocVisitor.h"
Chris Lattner42d42b52009-04-10 21:41:48 +000027#include "clang/Lex/MacroInfo.h"
Douglas Gregor6a5a23f2010-03-19 21:51:54 +000028#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000029#include "clang/Lex/Preprocessor.h"
Steve Naroff83d63c72009-04-24 20:03:17 +000030#include "clang/Lex/HeaderSearch.h"
Douglas Gregor668c1a42009-04-21 22:25:48 +000031#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000032#include "clang/Basic/SourceManager.h"
Douglas Gregorbd945002009-04-13 16:31:14 +000033#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000034#include "clang/Basic/FileManager.h"
Douglas Gregor2bec0412009-04-10 21:16:55 +000035#include "clang/Basic/TargetInfo.h"
Douglas Gregor445e23e2009-10-05 21:07:28 +000036#include "clang/Basic/Version.h"
Daniel Dunbar2596e422009-10-17 23:52:28 +000037#include "llvm/ADT/StringExtras.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000038#include "llvm/Bitcode/BitstreamReader.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000039#include "llvm/Support/MemoryBuffer.h"
John McCall833ca992009-10-29 08:12:44 +000040#include "llvm/Support/ErrorHandling.h"
Daniel Dunbard5b21972009-11-18 19:50:41 +000041#include "llvm/System/Path.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000042#include <algorithm>
Douglas Gregore721f952009-04-28 18:58:38 +000043#include <iterator>
Douglas Gregor2cf26342009-04-09 22:27:44 +000044#include <cstdio>
Douglas Gregor4fed3f42009-04-27 18:38:38 +000045#include <sys/stat.h>
Douglas Gregor2cf26342009-04-09 22:27:44 +000046using namespace clang;
Sebastian Redl8538e8d2010-08-18 23:57:32 +000047using namespace clang::serialization;
Douglas Gregor2cf26342009-04-09 22:27:44 +000048
49//===----------------------------------------------------------------------===//
Sebastian Redl3c7f4132010-08-18 23:57:06 +000050// PCH validator implementation
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000051//===----------------------------------------------------------------------===//
52
Sebastian Redl571db7f2010-08-18 23:56:56 +000053ASTReaderListener::~ASTReaderListener() {}
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000054
55bool
56PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
57 const LangOptions &PPLangOpts = PP.getLangOptions();
58#define PARSE_LANGOPT_BENIGN(Option)
59#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
60 if (PPLangOpts.Option != LangOpts.Option) { \
61 Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
62 return true; \
63 }
64
65 PARSE_LANGOPT_BENIGN(Trigraphs);
66 PARSE_LANGOPT_BENIGN(BCPLComment);
67 PARSE_LANGOPT_BENIGN(DollarIdents);
68 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
69 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
Chandler Carrutheb5d7b72010-04-17 20:17:31 +000070 PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000071 PARSE_LANGOPT_BENIGN(ImplicitInt);
72 PARSE_LANGOPT_BENIGN(Digraphs);
73 PARSE_LANGOPT_BENIGN(HexFloats);
74 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
75 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
76 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
77 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
78 PARSE_LANGOPT_BENIGN(CXXOperatorName);
79 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
80 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
81 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
Fariborz Jahanian412e7982010-02-09 19:31:38 +000082 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
Fariborz Jahanian4c9d8d02010-04-22 21:01:59 +000083 PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
84 diag::warn_pch_no_constant_cfstrings);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000085 PARSE_LANGOPT_BENIGN(PascalStrings);
86 PARSE_LANGOPT_BENIGN(WritableStrings);
Mike Stump1eb44332009-09-09 15:08:12 +000087 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000088 diag::warn_pch_lax_vector_conversions);
Nate Begeman69cfb9b2009-06-25 22:57:40 +000089 PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000090 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
Daniel Dunbar73482882010-02-10 18:48:44 +000091 PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000092 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
93 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
94 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
Mike Stump1eb44332009-09-09 15:08:12 +000095 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000096 diag::warn_pch_thread_safe_statics);
Daniel Dunbar5345c392009-09-03 04:54:28 +000097 PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000098 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
99 PARSE_LANGOPT_BENIGN(EmitAllDecls);
100 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
Chris Lattnera4d71452010-06-26 21:25:03 +0000101 PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
Mike Stump1eb44332009-09-09 15:08:12 +0000102 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000103 diag::warn_pch_heinous_extensions);
104 // FIXME: Most of the options below are benign if the macro wasn't
105 // used. Unfortunately, this means that a PCH compiled without
106 // optimization can't be used with optimization turned on, even
107 // though the only thing that changes is whether __OPTIMIZE__ was
108 // defined... but if __OPTIMIZE__ never showed up in the header, it
109 // doesn't matter. We could consider making this some special kind
110 // of check.
111 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
112 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
113 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
114 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
115 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
116 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
117 PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
118 PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
John Thompsona6fda122009-11-05 20:14:16 +0000119 PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000120 if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000121 Reader.Diag(diag::warn_pch_gc_mode)
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000122 << LangOpts.getGCMode() << PPLangOpts.getGCMode();
123 return true;
124 }
125 PARSE_LANGOPT_BENIGN(getVisibilityMode());
Daniel Dunbarab8e2812009-09-21 04:16:19 +0000126 PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
127 diag::warn_pch_stack_protector);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000128 PARSE_LANGOPT_BENIGN(InstantiationDepth);
Nate Begeman69cfb9b2009-06-25 22:57:40 +0000129 PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
Mike Stump9c276ae2009-12-12 01:27:46 +0000130 PARSE_LANGOPT_BENIGN(CatchUndefined);
Daniel Dunbarab8e2812009-09-21 04:16:19 +0000131 PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
Douglas Gregora0068fc2010-07-09 17:35:33 +0000132 PARSE_LANGOPT_BENIGN(SpellChecking);
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +0000133#undef PARSE_LANGOPT_IMPORTANT
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000134#undef PARSE_LANGOPT_BENIGN
135
136 return false;
137}
138
Daniel Dunbardc3c0d22009-11-11 00:52:11 +0000139bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
140 if (Triple == PP.getTargetInfo().getTriple().str())
141 return false;
142
143 Reader.Diag(diag::warn_pch_target_triple)
144 << Triple << PP.getTargetInfo().getTriple().str();
145 return true;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000146}
147
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000148struct EmptyStringRef {
Benjamin Kramerec1b1cc2010-07-14 23:19:41 +0000149 bool operator ()(llvm::StringRef r) const { return r.empty(); }
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000150};
151struct EmptyBlock {
152 bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); }
153};
154
155static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
156 PCHPredefinesBlocks R) {
157 // First, sum up the lengths.
158 unsigned LL = 0, RL = 0;
159 for (unsigned I = 0, N = L.size(); I != N; ++I) {
160 LL += L[I].size();
161 }
162 for (unsigned I = 0, N = R.size(); I != N; ++I) {
163 RL += R[I].Data.size();
164 }
165 if (LL != RL)
166 return false;
167 if (LL == 0 && RL == 0)
168 return true;
169
170 // Kick out empty parts, they confuse the algorithm below.
171 L.erase(std::remove_if(L.begin(), L.end(), EmptyStringRef()), L.end());
172 R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
173
174 // Do it the hard way. At this point, both vectors must be non-empty.
175 llvm::StringRef LR = L[0], RR = R[0].Data;
176 unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
Daniel Dunbarc76c9e02010-07-16 00:00:11 +0000177 (void) RN;
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000178 for (;;) {
179 // Compare the current pieces.
180 if (LR.size() == RR.size()) {
181 // If they're the same length, it's pretty easy.
182 if (LR != RR)
183 return false;
184 // Both pieces are done, advance.
185 ++LI;
186 ++RI;
187 // If either string is done, they're both done, since they're the same
188 // length.
189 if (LI == LN) {
190 assert(RI == RN && "Strings not the same length after all?");
191 return true;
192 }
193 LR = L[LI];
194 RR = R[RI].Data;
195 } else if (LR.size() < RR.size()) {
196 // Right piece is longer.
197 if (!RR.startswith(LR))
198 return false;
199 ++LI;
200 assert(LI != LN && "Strings not the same length after all?");
201 RR = RR.substr(LR.size());
202 LR = L[LI];
203 } else {
204 // Left piece is longer.
205 if (!LR.startswith(RR))
206 return false;
207 ++RI;
208 assert(RI != RN && "Strings not the same length after all?");
209 LR = LR.substr(RR.size());
210 RR = R[RI].Data;
211 }
212 }
213}
214
215static std::pair<FileID, llvm::StringRef::size_type>
216FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
217 std::pair<FileID, llvm::StringRef::size_type> Res;
218 for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
219 Res.second = Buffers[I].Data.find(MacroDef);
220 if (Res.second != llvm::StringRef::npos) {
221 Res.first = Buffers[I].BufferID;
222 break;
223 }
224 }
225 return Res;
226}
227
228bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000229 llvm::StringRef OriginalFileName,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000230 std::string &SuggestedPredefines) {
Daniel Dunbarc7162932009-11-11 23:58:53 +0000231 // We are in the context of an implicit include, so the predefines buffer will
232 // have a #include entry for the PCH file itself (as normalized by the
233 // preprocessor initialization). Find it and skip over it in the checking
234 // below.
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000235 llvm::SmallString<256> PCHInclude;
236 PCHInclude += "#include \"";
Daniel Dunbarc7162932009-11-11 23:58:53 +0000237 PCHInclude += NormalizeDashIncludePath(OriginalFileName);
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000238 PCHInclude += "\"\n";
239 std::pair<llvm::StringRef,llvm::StringRef> Split =
240 llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
241 llvm::StringRef Left = Split.first, Right = Split.second;
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +0000242 if (Left == PP.getPredefines()) {
243 Error("Missing PCH include entry!");
244 return true;
245 }
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000246
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000247 // If the concatenation of all the PCH buffers is equal to the adjusted
248 // command line, we're done.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000249 llvm::SmallVector<llvm::StringRef, 2> CommandLine;
250 CommandLine.push_back(Left);
251 CommandLine.push_back(Right);
252 if (EqualConcatenations(CommandLine, Buffers))
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000253 return false;
254
255 SourceManager &SourceMgr = PP.getSourceManager();
Mike Stump1eb44332009-09-09 15:08:12 +0000256
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000257 // The predefines buffers are different. Determine what the differences are,
258 // and whether they require us to reject the PCH file.
Daniel Dunbare6750492009-11-13 16:46:11 +0000259 llvm::SmallVector<llvm::StringRef, 8> PCHLines;
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000260 for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
261 Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Daniel Dunbare6750492009-11-13 16:46:11 +0000262
263 llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
264 Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
265 Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000266
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000267 // Sort both sets of predefined buffer lines, since we allow some extra
268 // definitions and they may appear at any point in the output.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000269 std::sort(CmdLineLines.begin(), CmdLineLines.end());
270 std::sort(PCHLines.begin(), PCHLines.end());
271
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000272 // Determine which predefines that were used to build the PCH file are missing
273 // from the command line.
274 std::vector<llvm::StringRef> MissingPredefines;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000275 std::set_difference(PCHLines.begin(), PCHLines.end(),
276 CmdLineLines.begin(), CmdLineLines.end(),
277 std::back_inserter(MissingPredefines));
278
279 bool MissingDefines = false;
280 bool ConflictingDefines = false;
281 for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000282 llvm::StringRef Missing = MissingPredefines[I];
283 if (!Missing.startswith("#define ")) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000284 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
285 return true;
286 }
Mike Stump1eb44332009-09-09 15:08:12 +0000287
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000288 // This is a macro definition. Determine the name of the macro we're
289 // defining.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000290 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump1eb44332009-09-09 15:08:12 +0000291 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000292 = Missing.find_first_of("( \n\r", StartOfMacroName);
293 assert(EndOfMacroName != std::string::npos &&
294 "Couldn't find the end of the macro name");
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000295 llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000296
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000297 // Determine whether this macro was given a different definition on the
298 // command line.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000299 std::string MacroDefStart = "#define " + MacroName.str();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000300 std::string::size_type MacroDefLen = MacroDefStart.size();
Daniel Dunbare6750492009-11-13 16:46:11 +0000301 llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000302 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
303 MacroDefStart);
304 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000305 if (!ConflictPos->startswith(MacroDefStart)) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000306 // Different macro; we're done.
307 ConflictPos = CmdLineLines.end();
Mike Stump1eb44332009-09-09 15:08:12 +0000308 break;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000309 }
Mike Stump1eb44332009-09-09 15:08:12 +0000310
311 assert(ConflictPos->size() > MacroDefLen &&
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000312 "Invalid #define in predefines buffer?");
Mike Stump1eb44332009-09-09 15:08:12 +0000313 if ((*ConflictPos)[MacroDefLen] != ' ' &&
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000314 (*ConflictPos)[MacroDefLen] != '(')
315 continue; // Longer macro name; keep trying.
Mike Stump1eb44332009-09-09 15:08:12 +0000316
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000317 // We found a conflicting macro definition.
318 break;
319 }
Mike Stump1eb44332009-09-09 15:08:12 +0000320
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000321 if (ConflictPos != CmdLineLines.end()) {
322 Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
323 << MacroName;
324
325 // Show the definition of this macro within the PCH file.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000326 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
327 FindMacro(Buffers, Missing);
328 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
329 SourceLocation PCHMissingLoc =
330 SourceMgr.getLocForStartOfFile(MacroLoc.first)
331 .getFileLocWithOffset(MacroLoc.second);
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000332 Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000333
334 ConflictingDefines = true;
335 continue;
336 }
Mike Stump1eb44332009-09-09 15:08:12 +0000337
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000338 // If the macro doesn't conflict, then we'll just pick up the macro
339 // definition from the PCH file. Warn the user that they made a mistake.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000340 if (ConflictingDefines)
341 continue; // Don't complain if there are already conflicting defs
Mike Stump1eb44332009-09-09 15:08:12 +0000342
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000343 if (!MissingDefines) {
344 Reader.Diag(diag::warn_cmdline_missing_macro_defs);
345 MissingDefines = true;
346 }
347
348 // Show the definition of this macro within the PCH file.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000349 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
350 FindMacro(Buffers, Missing);
351 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
352 SourceLocation PCHMissingLoc =
353 SourceMgr.getLocForStartOfFile(MacroLoc.first)
354 .getFileLocWithOffset(MacroLoc.second);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000355 Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
356 }
Mike Stump1eb44332009-09-09 15:08:12 +0000357
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000358 if (ConflictingDefines)
359 return true;
Mike Stump1eb44332009-09-09 15:08:12 +0000360
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000361 // Determine what predefines were introduced based on command-line
362 // parameters that were not present when building the PCH
363 // file. Extra #defines are okay, so long as the identifiers being
364 // defined were not used within the precompiled header.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000365 std::vector<llvm::StringRef> ExtraPredefines;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000366 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
367 PCHLines.begin(), PCHLines.end(),
Mike Stump1eb44332009-09-09 15:08:12 +0000368 std::back_inserter(ExtraPredefines));
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000369 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000370 llvm::StringRef &Extra = ExtraPredefines[I];
371 if (!Extra.startswith("#define ")) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000372 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
373 return true;
374 }
375
376 // This is an extra macro definition. Determine the name of the
377 // macro we're defining.
378 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump1eb44332009-09-09 15:08:12 +0000379 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000380 = Extra.find_first_of("( \n\r", StartOfMacroName);
381 assert(EndOfMacroName != std::string::npos &&
382 "Couldn't find the end of the macro name");
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000383 llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000384
385 // Check whether this name was used somewhere in the PCH file. If
386 // so, defining it as a macro could change behavior, so we reject
387 // the PCH file.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000388 if (IdentifierInfo *II = Reader.get(MacroName)) {
Daniel Dunbar4fda42e2009-11-11 00:52:00 +0000389 Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000390 return true;
391 }
392
393 // Add this definition to the suggested predefines buffer.
394 SuggestedPredefines += Extra;
395 SuggestedPredefines += '\n';
396 }
397
398 // If we get here, it's because the predefines buffer had compatible
399 // contents. Accept the PCH file.
400 return false;
401}
402
Douglas Gregor12fab312010-03-16 16:35:32 +0000403void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
404 unsigned ID) {
405 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
406 ++NumHeaderInfos;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000407}
408
409void PCHValidator::ReadCounter(unsigned Value) {
410 PP.setCounterValue(Value);
411}
412
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000413//===----------------------------------------------------------------------===//
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000414// AST reader implementation
Douglas Gregor668c1a42009-04-21 22:25:48 +0000415//===----------------------------------------------------------------------===//
416
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000417void
Sebastian Redl571db7f2010-08-18 23:56:56 +0000418ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000419 DeserializationListener = Listener;
420 if (DeserializationListener)
421 DeserializationListener->SetReader(this);
422}
423
Chris Lattner4c6f9522009-04-27 05:14:47 +0000424
Douglas Gregor668c1a42009-04-21 22:25:48 +0000425namespace {
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000426class ASTSelectorLookupTrait {
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000427 ASTReader &Reader;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000428
429public:
Sebastian Redl5d050072010-08-04 17:20:04 +0000430 struct data_type {
Sebastian Redl8538e8d2010-08-18 23:57:32 +0000431 SelectorID ID;
Sebastian Redl5d050072010-08-04 17:20:04 +0000432 ObjCMethodList Instance, Factory;
433 };
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000434
435 typedef Selector external_key_type;
436 typedef external_key_type internal_key_type;
437
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000438 explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000439
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000440 static bool EqualKey(const internal_key_type& a,
441 const internal_key_type& b) {
442 return a == b;
443 }
Mike Stump1eb44332009-09-09 15:08:12 +0000444
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000445 static unsigned ComputeHash(Selector Sel) {
Argyrios Kyrtzidis0eca89e2010-08-20 16:03:52 +0000446 return serialization::ComputeHash(Sel);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000447 }
Mike Stump1eb44332009-09-09 15:08:12 +0000448
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000449 // This hopefully will just get inlined and removed by the optimizer.
450 static const internal_key_type&
451 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump1eb44332009-09-09 15:08:12 +0000452
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000453 static std::pair<unsigned, unsigned>
454 ReadKeyDataLength(const unsigned char*& d) {
455 using namespace clang::io;
456 unsigned KeyLen = ReadUnalignedLE16(d);
457 unsigned DataLen = ReadUnalignedLE16(d);
458 return std::make_pair(KeyLen, DataLen);
459 }
Mike Stump1eb44332009-09-09 15:08:12 +0000460
Douglas Gregor83941df2009-04-25 17:48:32 +0000461 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000462 using namespace clang::io;
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000463 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000464 unsigned N = ReadUnalignedLE16(d);
Mike Stump1eb44332009-09-09 15:08:12 +0000465 IdentifierInfo *FirstII
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000466 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
467 if (N == 0)
468 return SelTable.getNullarySelector(FirstII);
469 else if (N == 1)
470 return SelTable.getUnarySelector(FirstII);
471
472 llvm::SmallVector<IdentifierInfo *, 16> Args;
473 Args.push_back(FirstII);
474 for (unsigned I = 1; I != N; ++I)
475 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
476
Douglas Gregor75fdb232009-05-22 22:45:36 +0000477 return SelTable.getSelector(N, Args.data());
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000478 }
Mike Stump1eb44332009-09-09 15:08:12 +0000479
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000480 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
481 using namespace clang::io;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000482
483 data_type Result;
484
Sebastian Redl5d050072010-08-04 17:20:04 +0000485 Result.ID = ReadUnalignedLE32(d);
486 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
487 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
488
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000489 // Load instance methods
490 ObjCMethodList *Prev = 0;
491 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +0000492 ObjCMethodDecl *Method
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000493 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl5d050072010-08-04 17:20:04 +0000494 if (!Result.Instance.Method) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000495 // This is the first method, which is the easy case.
Sebastian Redl5d050072010-08-04 17:20:04 +0000496 Result.Instance.Method = Method;
497 Prev = &Result.Instance;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000498 continue;
499 }
500
Ted Kremenek298ed872010-02-11 00:53:01 +0000501 ObjCMethodList *Mem =
502 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
503 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000504 Prev = Prev->Next;
505 }
506
507 // Load factory methods
508 Prev = 0;
509 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +0000510 ObjCMethodDecl *Method
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000511 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl5d050072010-08-04 17:20:04 +0000512 if (!Result.Factory.Method) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000513 // This is the first method, which is the easy case.
Sebastian Redl5d050072010-08-04 17:20:04 +0000514 Result.Factory.Method = Method;
515 Prev = &Result.Factory;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000516 continue;
517 }
518
Ted Kremenek298ed872010-02-11 00:53:01 +0000519 ObjCMethodList *Mem =
520 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
521 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000522 Prev = Prev->Next;
523 }
524
525 return Result;
526 }
527};
Mike Stump1eb44332009-09-09 15:08:12 +0000528
529} // end anonymous namespace
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000530
531/// \brief The on-disk hash table used for the global method pool.
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000532typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
533 ASTSelectorLookupTable;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000534
535namespace {
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000536class ASTIdentifierLookupTrait {
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000537 ASTReader &Reader;
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000538 llvm::BitstreamCursor &Stream;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000539
540 // If we know the IdentifierInfo in advance, it is here and we will
541 // not build a new one. Used when deserializing information about an
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000542 // identifier that was constructed before the AST file was read.
Douglas Gregor668c1a42009-04-21 22:25:48 +0000543 IdentifierInfo *KnownII;
544
545public:
546 typedef IdentifierInfo * data_type;
547
548 typedef const std::pair<const char*, unsigned> external_key_type;
549
550 typedef external_key_type internal_key_type;
551
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000552 ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000553 IdentifierInfo *II = 0)
554 : Reader(Reader), Stream(Stream), KnownII(II) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000555
Douglas Gregor668c1a42009-04-21 22:25:48 +0000556 static bool EqualKey(const internal_key_type& a,
557 const internal_key_type& b) {
558 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
559 : false;
560 }
Mike Stump1eb44332009-09-09 15:08:12 +0000561
Douglas Gregor668c1a42009-04-21 22:25:48 +0000562 static unsigned ComputeHash(const internal_key_type& a) {
Daniel Dunbar2596e422009-10-17 23:52:28 +0000563 return llvm::HashString(llvm::StringRef(a.first, a.second));
Douglas Gregor668c1a42009-04-21 22:25:48 +0000564 }
Mike Stump1eb44332009-09-09 15:08:12 +0000565
Douglas Gregor668c1a42009-04-21 22:25:48 +0000566 // This hopefully will just get inlined and removed by the optimizer.
567 static const internal_key_type&
568 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump1eb44332009-09-09 15:08:12 +0000569
Douglas Gregor668c1a42009-04-21 22:25:48 +0000570 static std::pair<unsigned, unsigned>
571 ReadKeyDataLength(const unsigned char*& d) {
572 using namespace clang::io;
Douglas Gregor5f8e3302009-04-25 20:26:24 +0000573 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregord6595a42009-04-25 21:04:17 +0000574 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000575 return std::make_pair(KeyLen, DataLen);
576 }
Mike Stump1eb44332009-09-09 15:08:12 +0000577
Douglas Gregor668c1a42009-04-21 22:25:48 +0000578 static std::pair<const char*, unsigned>
579 ReadKey(const unsigned char* d, unsigned n) {
580 assert(n >= 2 && d[n-1] == '\0');
581 return std::make_pair((const char*) d, n-1);
582 }
Mike Stump1eb44332009-09-09 15:08:12 +0000583
584 IdentifierInfo *ReadData(const internal_key_type& k,
Douglas Gregor668c1a42009-04-21 22:25:48 +0000585 const unsigned char* d,
586 unsigned DataLen) {
587 using namespace clang::io;
Sebastian Redl8538e8d2010-08-18 23:57:32 +0000588 IdentID ID = ReadUnalignedLE32(d);
Douglas Gregora92193e2009-04-28 21:18:29 +0000589 bool IsInteresting = ID & 0x01;
590
591 // Wipe out the "is interesting" bit.
592 ID = ID >> 1;
593
594 if (!IsInteresting) {
Sebastian Redl083abdf2010-07-27 23:01:28 +0000595 // For uninteresting identifiers, just build the IdentifierInfo
Douglas Gregora92193e2009-04-28 21:18:29 +0000596 // and associate it with the persistent ID.
597 IdentifierInfo *II = KnownII;
598 if (!II)
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000599 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregora92193e2009-04-28 21:18:29 +0000600 Reader.SetIdentifierInfo(ID, II);
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000601 II->setIsFromAST();
Douglas Gregora92193e2009-04-28 21:18:29 +0000602 return II;
603 }
604
Douglas Gregor5998da52009-04-28 21:32:13 +0000605 unsigned Bits = ReadUnalignedLE16(d);
Douglas Gregor2deaea32009-04-22 18:49:13 +0000606 bool CPlusPlusOperatorKeyword = Bits & 0x01;
607 Bits >>= 1;
Argyrios Kyrtzidis646395b2010-08-11 22:55:12 +0000608 bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
609 Bits >>= 1;
Douglas Gregor2deaea32009-04-22 18:49:13 +0000610 bool Poisoned = Bits & 0x01;
611 Bits >>= 1;
612 bool ExtensionToken = Bits & 0x01;
613 Bits >>= 1;
614 bool hasMacroDefinition = Bits & 0x01;
615 Bits >>= 1;
616 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
617 Bits >>= 10;
Mike Stump1eb44332009-09-09 15:08:12 +0000618
Douglas Gregor2deaea32009-04-22 18:49:13 +0000619 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregor5998da52009-04-28 21:32:13 +0000620 DataLen -= 6;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000621
622 // Build the IdentifierInfo itself and link the identifier ID with
623 // the new IdentifierInfo.
624 IdentifierInfo *II = KnownII;
625 if (!II)
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000626 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000627 Reader.SetIdentifierInfo(ID, II);
628
Douglas Gregor2deaea32009-04-22 18:49:13 +0000629 // Set or check the various bits in the IdentifierInfo structure.
Argyrios Kyrtzidis646395b2010-08-11 22:55:12 +0000630 // Token IDs are read-only.
631 if (HasRevertedTokenIDToIdentifier)
632 II->RevertTokenIDToIdentifier();
Douglas Gregor2deaea32009-04-22 18:49:13 +0000633 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
Mike Stump1eb44332009-09-09 15:08:12 +0000634 assert(II->isExtensionToken() == ExtensionToken &&
Douglas Gregor2deaea32009-04-22 18:49:13 +0000635 "Incorrect extension token flag");
636 (void)ExtensionToken;
637 II->setIsPoisoned(Poisoned);
638 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
639 "Incorrect C++ operator keyword flag");
640 (void)CPlusPlusOperatorKeyword;
641
Douglas Gregor37e26842009-04-21 23:56:24 +0000642 // If this identifier is a macro, deserialize the macro
643 // definition.
644 if (hasMacroDefinition) {
Douglas Gregor5998da52009-04-28 21:32:13 +0000645 uint32_t Offset = ReadUnalignedLE32(d);
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000646 Reader.ReadMacroRecord(Stream, Offset);
Douglas Gregor5998da52009-04-28 21:32:13 +0000647 DataLen -= 4;
Douglas Gregor37e26842009-04-21 23:56:24 +0000648 }
Douglas Gregor668c1a42009-04-21 22:25:48 +0000649
650 // Read all of the declarations visible at global scope with this
651 // name.
Chris Lattner6bf690f2009-04-27 22:17:41 +0000652 if (Reader.getContext() == 0) return II;
Douglas Gregord89275b2009-07-06 18:54:52 +0000653 if (DataLen > 0) {
654 llvm::SmallVector<uint32_t, 4> DeclIDs;
655 for (; DataLen > 0; DataLen -= 4)
656 DeclIDs.push_back(ReadUnalignedLE32(d));
657 Reader.SetGloballyVisibleDecls(II, DeclIDs);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000658 }
Mike Stump1eb44332009-09-09 15:08:12 +0000659
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000660 II->setIsFromAST();
Douglas Gregor668c1a42009-04-21 22:25:48 +0000661 return II;
662 }
663};
Mike Stump1eb44332009-09-09 15:08:12 +0000664
665} // end anonymous namespace
Douglas Gregor668c1a42009-04-21 22:25:48 +0000666
667/// \brief The on-disk hash table used to contain information about
668/// all of the identifiers in the program.
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000669typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
670 ASTIdentifierLookupTable;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000671
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +0000672namespace {
673class ASTDeclContextNameLookupTrait {
674 ASTReader &Reader;
675
676public:
677 /// \brief Pair of begin/end iterators for DeclIDs.
678 typedef std::pair<DeclID *, DeclID *> data_type;
679
680 /// \brief Special internal key for declaration names.
681 /// The hash table creates keys for comparison; we do not create
682 /// a DeclarationName for the internal key to avoid deserializing types.
683 struct DeclNameKey {
684 DeclarationName::NameKind Kind;
685 uint64_t Data;
686 DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
687 };
688
689 typedef DeclarationName external_key_type;
690 typedef DeclNameKey internal_key_type;
691
692 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
693
694 static bool EqualKey(const internal_key_type& a,
695 const internal_key_type& b) {
696 return a.Kind == b.Kind && a.Data == b.Data;
697 }
698
699 unsigned ComputeHash(const DeclNameKey &Key) const {
700 llvm::FoldingSetNodeID ID;
701 ID.AddInteger(Key.Kind);
702
703 switch (Key.Kind) {
704 case DeclarationName::Identifier:
705 case DeclarationName::CXXLiteralOperatorName:
706 ID.AddString(((IdentifierInfo*)Key.Data)->getName());
707 break;
708 case DeclarationName::ObjCZeroArgSelector:
709 case DeclarationName::ObjCOneArgSelector:
710 case DeclarationName::ObjCMultiArgSelector:
711 ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
712 break;
713 case DeclarationName::CXXConstructorName:
714 case DeclarationName::CXXDestructorName:
715 case DeclarationName::CXXConversionFunctionName:
716 ID.AddInteger((TypeID)Key.Data);
717 break;
718 case DeclarationName::CXXOperatorName:
719 ID.AddInteger((OverloadedOperatorKind)Key.Data);
720 break;
721 case DeclarationName::CXXUsingDirective:
722 break;
723 }
724
725 return ID.ComputeHash();
726 }
727
728 internal_key_type GetInternalKey(const external_key_type& Name) const {
729 DeclNameKey Key;
730 Key.Kind = Name.getNameKind();
731 switch (Name.getNameKind()) {
732 case DeclarationName::Identifier:
733 Key.Data = (uint64_t)Name.getAsIdentifierInfo();
734 break;
735 case DeclarationName::ObjCZeroArgSelector:
736 case DeclarationName::ObjCOneArgSelector:
737 case DeclarationName::ObjCMultiArgSelector:
738 Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
739 break;
740 case DeclarationName::CXXConstructorName:
741 case DeclarationName::CXXDestructorName:
742 case DeclarationName::CXXConversionFunctionName:
743 Key.Data = Reader.GetTypeID(Name.getCXXNameType());
744 break;
745 case DeclarationName::CXXOperatorName:
746 Key.Data = Name.getCXXOverloadedOperator();
747 break;
748 case DeclarationName::CXXLiteralOperatorName:
749 Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
750 break;
751 case DeclarationName::CXXUsingDirective:
752 break;
753 }
754
755 return Key;
756 }
757
Argyrios Kyrtzidisa60786b2010-08-20 23:35:55 +0000758 external_key_type GetExternalKey(const internal_key_type& Key) const {
759 ASTContext *Context = Reader.getContext();
760 switch (Key.Kind) {
761 case DeclarationName::Identifier:
762 return DeclarationName((IdentifierInfo*)Key.Data);
763
764 case DeclarationName::ObjCZeroArgSelector:
765 case DeclarationName::ObjCOneArgSelector:
766 case DeclarationName::ObjCMultiArgSelector:
767 return DeclarationName(Selector(Key.Data));
768
769 case DeclarationName::CXXConstructorName:
770 return Context->DeclarationNames.getCXXConstructorName(
771 Context->getCanonicalType(Reader.GetType(Key.Data)));
772
773 case DeclarationName::CXXDestructorName:
774 return Context->DeclarationNames.getCXXDestructorName(
775 Context->getCanonicalType(Reader.GetType(Key.Data)));
776
777 case DeclarationName::CXXConversionFunctionName:
778 return Context->DeclarationNames.getCXXConversionFunctionName(
779 Context->getCanonicalType(Reader.GetType(Key.Data)));
780
781 case DeclarationName::CXXOperatorName:
782 return Context->DeclarationNames.getCXXOperatorName(
783 (OverloadedOperatorKind)Key.Data);
784
785 case DeclarationName::CXXLiteralOperatorName:
786 return Context->DeclarationNames.getCXXLiteralOperatorName(
787 (IdentifierInfo*)Key.Data);
788
789 case DeclarationName::CXXUsingDirective:
790 return DeclarationName::getUsingDirectiveName();
791 }
792
793 llvm_unreachable("Invalid Name Kind ?");
794 }
795
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +0000796 static std::pair<unsigned, unsigned>
797 ReadKeyDataLength(const unsigned char*& d) {
798 using namespace clang::io;
799 unsigned KeyLen = ReadUnalignedLE16(d);
800 unsigned DataLen = ReadUnalignedLE16(d);
801 return std::make_pair(KeyLen, DataLen);
802 }
803
804 internal_key_type ReadKey(const unsigned char* d, unsigned) {
805 using namespace clang::io;
806
807 DeclNameKey Key;
808 Key.Kind = (DeclarationName::NameKind)*d++;
809 switch (Key.Kind) {
810 case DeclarationName::Identifier:
811 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
812 break;
813 case DeclarationName::ObjCZeroArgSelector:
814 case DeclarationName::ObjCOneArgSelector:
815 case DeclarationName::ObjCMultiArgSelector:
816 Key.Data =
817 (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
818 break;
819 case DeclarationName::CXXConstructorName:
820 case DeclarationName::CXXDestructorName:
821 case DeclarationName::CXXConversionFunctionName:
822 Key.Data = ReadUnalignedLE32(d); // TypeID
823 break;
824 case DeclarationName::CXXOperatorName:
825 Key.Data = *d++; // OverloadedOperatorKind
826 break;
827 case DeclarationName::CXXLiteralOperatorName:
828 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
829 break;
830 case DeclarationName::CXXUsingDirective:
831 break;
832 }
833
834 return Key;
835 }
836
837 data_type ReadData(internal_key_type, const unsigned char* d,
838 unsigned DataLen) {
839 using namespace clang::io;
840 unsigned NumDecls = ReadUnalignedLE16(d);
841 DeclID *Start = (DeclID *)d;
842 return std::make_pair(Start, Start + NumDecls);
843 }
844};
845
846} // end anonymous namespace
847
848/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
849typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
850 ASTDeclContextNameLookupTable;
851
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +0000852bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
853 const std::pair<uint64_t, uint64_t> &Offsets,
854 DeclContextInfo &Info) {
855 SavedStreamPosition SavedPosition(Cursor);
856 // First the lexical decls.
857 if (Offsets.first != 0) {
858 Cursor.JumpToBit(Offsets.first);
859
860 RecordData Record;
861 const char *Blob;
862 unsigned BlobLen;
863 unsigned Code = Cursor.ReadCode();
864 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
865 if (RecCode != DECL_CONTEXT_LEXICAL) {
866 Error("Expected lexical block");
867 return true;
868 }
869
870 Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
871 Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
872 } else {
873 Info.LexicalDecls = 0;
874 Info.NumLexicalDecls = 0;
875 }
876
877 // Now the lookup table.
878 if (Offsets.second != 0) {
879 Cursor.JumpToBit(Offsets.second);
880
881 RecordData Record;
882 const char *Blob;
883 unsigned BlobLen;
884 unsigned Code = Cursor.ReadCode();
885 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
886 if (RecCode != DECL_CONTEXT_VISIBLE) {
887 Error("Expected visible lookup table block");
888 return true;
889 }
890 Info.NameLookupTableData
891 = ASTDeclContextNameLookupTable::Create(
892 (const unsigned char *)Blob + Record[0],
893 (const unsigned char *)Blob,
894 ASTDeclContextNameLookupTrait(*this));
Sebastian Redl0ea8f7f2010-08-24 00:50:00 +0000895 } else {
896 Info.NameLookupTableData = 0;
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +0000897 }
898
899 return false;
900}
901
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000902void ASTReader::Error(const char *Msg) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +0000903 Diag(diag::err_fe_pch_malformed) << Msg;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000904}
905
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000906/// \brief Tell the AST listener about the predefines buffers in the chain.
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000907bool ASTReader::CheckPredefinesBuffers() {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000908 if (Listener)
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000909 return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000910 ActualOriginalFileName,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000911 SuggestedPredefines);
Douglas Gregore721f952009-04-28 18:58:38 +0000912 return false;
Douglas Gregore1d918e2009-04-10 23:10:45 +0000913}
914
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000915//===----------------------------------------------------------------------===//
916// Source Manager Deserialization
917//===----------------------------------------------------------------------===//
918
Douglas Gregorbd945002009-04-13 16:31:14 +0000919/// \brief Read the line table in the source manager block.
920/// \returns true if ther was an error.
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000921bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000922 unsigned Idx = 0;
923 LineTableInfo &LineTable = SourceMgr.getLineTable();
924
925 // Parse the file names
Douglas Gregorff0a9872009-04-13 17:12:42 +0000926 std::map<int, int> FileIDs;
927 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000928 // Extract the file name
929 unsigned FilenameLen = Record[Idx++];
930 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
931 Idx += FilenameLen;
Douglas Gregore650c8c2009-07-07 00:12:59 +0000932 MaybeAddSystemRootToFilename(Filename);
Mike Stump1eb44332009-09-09 15:08:12 +0000933 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Douglas Gregorff0a9872009-04-13 17:12:42 +0000934 Filename.size());
Douglas Gregorbd945002009-04-13 16:31:14 +0000935 }
936
937 // Parse the line entries
938 std::vector<LineEntry> Entries;
939 while (Idx < Record.size()) {
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000940 int FID = Record[Idx++];
Douglas Gregorbd945002009-04-13 16:31:14 +0000941
942 // Extract the line entries
943 unsigned NumEntries = Record[Idx++];
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000944 assert(NumEntries && "Numentries is 00000");
Douglas Gregorbd945002009-04-13 16:31:14 +0000945 Entries.clear();
946 Entries.reserve(NumEntries);
947 for (unsigned I = 0; I != NumEntries; ++I) {
948 unsigned FileOffset = Record[Idx++];
949 unsigned LineNo = Record[Idx++];
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000950 int FilenameID = FileIDs[Record[Idx++]];
Mike Stump1eb44332009-09-09 15:08:12 +0000951 SrcMgr::CharacteristicKind FileKind
Douglas Gregorbd945002009-04-13 16:31:14 +0000952 = (SrcMgr::CharacteristicKind)Record[Idx++];
953 unsigned IncludeOffset = Record[Idx++];
954 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
955 FileKind, IncludeOffset));
956 }
957 LineTable.AddEntry(FID, Entries);
958 }
959
960 return false;
961}
962
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000963namespace {
964
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000965class ASTStatData {
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000966public:
967 const bool hasStat;
968 const ino_t ino;
969 const dev_t dev;
970 const mode_t mode;
971 const time_t mtime;
972 const off_t size;
Mike Stump1eb44332009-09-09 15:08:12 +0000973
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000974 ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
Mike Stump1eb44332009-09-09 15:08:12 +0000975 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
976
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000977 ASTStatData()
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000978 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
979};
980
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000981class ASTStatLookupTrait {
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000982 public:
983 typedef const char *external_key_type;
984 typedef const char *internal_key_type;
985
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000986 typedef ASTStatData data_type;
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000987
988 static unsigned ComputeHash(const char *path) {
Daniel Dunbar2596e422009-10-17 23:52:28 +0000989 return llvm::HashString(path);
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000990 }
991
992 static internal_key_type GetInternalKey(const char *path) { return path; }
993
994 static bool EqualKey(internal_key_type a, internal_key_type b) {
995 return strcmp(a, b) == 0;
996 }
997
998 static std::pair<unsigned, unsigned>
999 ReadKeyDataLength(const unsigned char*& d) {
1000 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
1001 unsigned DataLen = (unsigned) *d++;
1002 return std::make_pair(KeyLen + 1, DataLen);
1003 }
1004
1005 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
1006 return (const char *)d;
1007 }
1008
1009 static data_type ReadData(const internal_key_type, const unsigned char *d,
1010 unsigned /*DataLen*/) {
1011 using namespace clang::io;
1012
1013 if (*d++ == 1)
1014 return data_type();
1015
1016 ino_t ino = (ino_t) ReadUnalignedLE32(d);
1017 dev_t dev = (dev_t) ReadUnalignedLE32(d);
1018 mode_t mode = (mode_t) ReadUnalignedLE16(d);
Mike Stump1eb44332009-09-09 15:08:12 +00001019 time_t mtime = (time_t) ReadUnalignedLE64(d);
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001020 off_t size = (off_t) ReadUnalignedLE64(d);
1021 return data_type(ino, dev, mode, mtime, size);
1022 }
1023};
1024
1025/// \brief stat() cache for precompiled headers.
1026///
1027/// This cache is very similar to the stat cache used by pretokenized
1028/// headers.
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001029class ASTStatCache : public StatSysCallCache {
1030 typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001031 CacheTy *Cache;
1032
1033 unsigned &NumStatHits, &NumStatMisses;
Mike Stump1eb44332009-09-09 15:08:12 +00001034public:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001035 ASTStatCache(const unsigned char *Buckets,
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001036 const unsigned char *Base,
1037 unsigned &NumStatHits,
Mike Stump1eb44332009-09-09 15:08:12 +00001038 unsigned &NumStatMisses)
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001039 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
1040 Cache = CacheTy::Create(Buckets, Base);
1041 }
1042
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001043 ~ASTStatCache() { delete Cache; }
Mike Stump1eb44332009-09-09 15:08:12 +00001044
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001045 int stat(const char *path, struct stat *buf) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001046 // Do the lookup for the file's data in the AST file.
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001047 CacheTy::iterator I = Cache->find(path);
1048
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001049 // If we don't get a hit in the AST file just forward to 'stat'.
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001050 if (I == Cache->end()) {
1051 ++NumStatMisses;
Douglas Gregor52e71082009-10-16 18:18:30 +00001052 return StatSysCallCache::stat(path, buf);
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001053 }
Mike Stump1eb44332009-09-09 15:08:12 +00001054
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001055 ++NumStatHits;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001056 ASTStatData Data = *I;
Mike Stump1eb44332009-09-09 15:08:12 +00001057
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001058 if (!Data.hasStat)
1059 return 1;
1060
1061 buf->st_ino = Data.ino;
1062 buf->st_dev = Data.dev;
1063 buf->st_mtime = Data.mtime;
1064 buf->st_mode = Data.mode;
1065 buf->st_size = Data.size;
1066 return 0;
1067 }
1068};
1069} // end anonymous namespace
1070
1071
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001072/// \brief Read a source manager block
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001073ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
Douglas Gregor14f79002009-04-10 03:52:48 +00001074 using namespace SrcMgr;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001075
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001076 llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
Sebastian Redl9137a522010-07-16 17:50:48 +00001077
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001078 // Set the source-location entry cursor to the current position in
1079 // the stream. This cursor will be used to read the contents of the
1080 // source manager block initially, and then lazily read
1081 // source-location entries as needed.
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001082 SLocEntryCursor = F.Stream;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001083
1084 // The stream itself is going to skip over the source manager block.
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001085 if (F.Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001086 Error("malformed block record in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001087 return Failure;
1088 }
1089
1090 // Enter the source manager block.
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001091 if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001092 Error("malformed source manager block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001093 return Failure;
1094 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001095
Douglas Gregor14f79002009-04-10 03:52:48 +00001096 RecordData Record;
1097 while (true) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001098 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregor14f79002009-04-10 03:52:48 +00001099 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001100 if (SLocEntryCursor.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001101 Error("error at end of Source Manager block in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001102 return Failure;
1103 }
Douglas Gregore1d918e2009-04-10 23:10:45 +00001104 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +00001105 }
Mike Stump1eb44332009-09-09 15:08:12 +00001106
Douglas Gregor14f79002009-04-10 03:52:48 +00001107 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1108 // No known subblocks, always skip them.
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001109 SLocEntryCursor.ReadSubBlockID();
1110 if (SLocEntryCursor.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001111 Error("malformed block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001112 return Failure;
1113 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001114 continue;
1115 }
Mike Stump1eb44332009-09-09 15:08:12 +00001116
Douglas Gregor14f79002009-04-10 03:52:48 +00001117 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001118 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregor14f79002009-04-10 03:52:48 +00001119 continue;
1120 }
Mike Stump1eb44332009-09-09 15:08:12 +00001121
Douglas Gregor14f79002009-04-10 03:52:48 +00001122 // Read a record.
1123 const char *BlobStart;
1124 unsigned BlobLen;
1125 Record.clear();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001126 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregor14f79002009-04-10 03:52:48 +00001127 default: // Default behavior: ignore.
1128 break;
1129
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001130 case SM_LINE_TABLE:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001131 if (ParseLineTable(Record))
Douglas Gregorbd945002009-04-13 16:31:14 +00001132 return Failure;
Chris Lattner2c78b872009-04-14 23:22:57 +00001133 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001134
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001135 case SM_SLOC_FILE_ENTRY:
1136 case SM_SLOC_BUFFER_ENTRY:
1137 case SM_SLOC_INSTANTIATION_ENTRY:
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001138 // Once we hit one of the source location entries, we're done.
1139 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +00001140 }
1141 }
1142}
1143
Sebastian Redl190faf72010-07-20 21:50:20 +00001144/// \brief Get a cursor that's correctly positioned for reading the source
1145/// location entry with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001146llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
Sebastian Redl190faf72010-07-20 21:50:20 +00001147 assert(ID != 0 && ID <= TotalNumSLocEntries &&
1148 "SLocCursorForID should only be called for real IDs.");
1149
1150 ID -= 1;
1151 PerFileData *F = 0;
1152 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1153 F = Chain[N - I - 1];
1154 if (ID < F->LocalNumSLocEntries)
1155 break;
1156 ID -= F->LocalNumSLocEntries;
1157 }
1158 assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
1159
1160 F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
1161 return F->SLocEntryCursor;
1162}
1163
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001164/// \brief Read in the source location entry with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001165ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001166 if (ID == 0)
1167 return Success;
1168
1169 if (ID > TotalNumSLocEntries) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001170 Error("source location entry ID out-of-range for AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001171 return Failure;
1172 }
1173
Sebastian Redl190faf72010-07-20 21:50:20 +00001174 llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
Sebastian Redl9137a522010-07-16 17:50:48 +00001175
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001176 ++NumSLocEntriesRead;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001177 unsigned Code = SLocEntryCursor.ReadCode();
1178 if (Code == llvm::bitc::END_BLOCK ||
1179 Code == llvm::bitc::ENTER_SUBBLOCK ||
1180 Code == llvm::bitc::DEFINE_ABBREV) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001181 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001182 return Failure;
1183 }
1184
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001185 RecordData Record;
1186 const char *BlobStart;
1187 unsigned BlobLen;
1188 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1189 default:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001190 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001191 return Failure;
1192
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001193 case SM_SLOC_FILE_ENTRY: {
Douglas Gregore650c8c2009-07-07 00:12:59 +00001194 std::string Filename(BlobStart, BlobStart + BlobLen);
1195 MaybeAddSystemRootToFilename(Filename);
1196 const FileEntry *File = FileMgr.getFile(Filename);
Chris Lattnerd3555ae2009-06-15 04:35:16 +00001197 if (File == 0) {
1198 std::string ErrorStr = "could not find file '";
Douglas Gregore650c8c2009-07-07 00:12:59 +00001199 ErrorStr += Filename;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001200 ErrorStr += "' referenced by AST file";
Chris Lattnerd3555ae2009-06-15 04:35:16 +00001201 Error(ErrorStr.c_str());
1202 return Failure;
1203 }
Mike Stump1eb44332009-09-09 15:08:12 +00001204
Douglas Gregor2d52be52010-03-21 22:49:54 +00001205 if (Record.size() < 10) {
Ted Kremenek1857f622010-03-18 21:23:05 +00001206 Error("source location entry is incorrect");
1207 return Failure;
1208 }
1209
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001210 if (!DisableValidation &&
1211 ((off_t)Record[4] != File->getSize()
Douglas Gregor9f692a02010-04-09 15:54:22 +00001212#if !defined(LLVM_ON_WIN32)
1213 // In our regression testing, the Windows file system seems to
1214 // have inconsistent modification times that sometimes
1215 // erroneously trigger this error-handling path.
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001216 || (time_t)Record[5] != File->getModificationTime()
Douglas Gregor9f692a02010-04-09 15:54:22 +00001217#endif
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001218 )) {
Douglas Gregor2d52be52010-03-21 22:49:54 +00001219 Diag(diag::err_fe_pch_file_modified)
1220 << Filename;
1221 return Failure;
1222 }
1223
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001224 FileID FID = SourceMgr.createFileID(File,
1225 SourceLocation::getFromRawEncoding(Record[1]),
1226 (SrcMgr::CharacteristicKind)Record[2],
1227 ID, Record[0]);
1228 if (Record[3])
1229 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
1230 .setHasLineDirectives();
1231
Douglas Gregor12fab312010-03-16 16:35:32 +00001232 // Reconstruct header-search information for this file.
1233 HeaderFileInfo HFI;
Douglas Gregor2d52be52010-03-21 22:49:54 +00001234 HFI.isImport = Record[6];
1235 HFI.DirInfo = Record[7];
1236 HFI.NumIncludes = Record[8];
1237 HFI.ControllingMacroID = Record[9];
Douglas Gregor12fab312010-03-16 16:35:32 +00001238 if (Listener)
1239 Listener->ReadHeaderFileInfo(HFI, File->getUID());
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001240 break;
1241 }
1242
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001243 case SM_SLOC_BUFFER_ENTRY: {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001244 const char *Name = BlobStart;
1245 unsigned Offset = Record[0];
1246 unsigned Code = SLocEntryCursor.ReadCode();
1247 Record.clear();
Mike Stump1eb44332009-09-09 15:08:12 +00001248 unsigned RecCode
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001249 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00001250
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001251 if (RecCode != SM_SLOC_BUFFER_BLOB) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001252 Error("AST record has invalid code");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00001253 return Failure;
1254 }
1255
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001256 llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00001257 = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
1258 Name);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001259 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
Mike Stump1eb44332009-09-09 15:08:12 +00001260
Douglas Gregor92b059e2009-04-28 20:33:11 +00001261 if (strcmp(Name, "<built-in>") == 0) {
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +00001262 PCHPredefinesBlock Block = {
1263 BufferID,
1264 llvm::StringRef(BlobStart, BlobLen - 1)
1265 };
1266 PCHPredefinesBuffers.push_back(Block);
Douglas Gregor92b059e2009-04-28 20:33:11 +00001267 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001268
1269 break;
1270 }
1271
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001272 case SM_SLOC_INSTANTIATION_ENTRY: {
Mike Stump1eb44332009-09-09 15:08:12 +00001273 SourceLocation SpellingLoc
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001274 = SourceLocation::getFromRawEncoding(Record[1]);
1275 SourceMgr.createInstantiationLoc(SpellingLoc,
1276 SourceLocation::getFromRawEncoding(Record[2]),
1277 SourceLocation::getFromRawEncoding(Record[3]),
1278 Record[4],
1279 ID,
1280 Record[0]);
1281 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001282 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001283 }
1284
1285 return Success;
1286}
1287
Chris Lattner6367f6d2009-04-27 01:05:14 +00001288/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
1289/// specified cursor. Read the abbreviations that are at the top of the block
1290/// and then leave the cursor pointing into the block.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001291bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
Chris Lattner6367f6d2009-04-27 01:05:14 +00001292 unsigned BlockID) {
1293 if (Cursor.EnterSubBlock(BlockID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001294 Error("malformed block record in AST file");
Chris Lattner6367f6d2009-04-27 01:05:14 +00001295 return Failure;
1296 }
Mike Stump1eb44332009-09-09 15:08:12 +00001297
Chris Lattner6367f6d2009-04-27 01:05:14 +00001298 while (true) {
1299 unsigned Code = Cursor.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00001300
Chris Lattner6367f6d2009-04-27 01:05:14 +00001301 // We expect all abbrevs to be at the start of the block.
1302 if (Code != llvm::bitc::DEFINE_ABBREV)
1303 return false;
1304 Cursor.ReadAbbrevRecord();
1305 }
1306}
1307
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001308void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001309 assert(PP && "Forgot to set Preprocessor ?");
Mike Stump1eb44332009-09-09 15:08:12 +00001310
Douglas Gregor37e26842009-04-21 23:56:24 +00001311 // Keep track of where we are in the stream, then jump back there
1312 // after reading this macro.
1313 SavedStreamPosition SavedPosition(Stream);
1314
1315 Stream.JumpToBit(Offset);
1316 RecordData Record;
1317 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
1318 MacroInfo *Macro = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001319
Douglas Gregor37e26842009-04-21 23:56:24 +00001320 while (true) {
1321 unsigned Code = Stream.ReadCode();
1322 switch (Code) {
1323 case llvm::bitc::END_BLOCK:
1324 return;
1325
1326 case llvm::bitc::ENTER_SUBBLOCK:
1327 // No known subblocks, always skip them.
1328 Stream.ReadSubBlockID();
1329 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001330 Error("malformed block record in AST file");
Douglas Gregor37e26842009-04-21 23:56:24 +00001331 return;
1332 }
1333 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00001334
Douglas Gregor37e26842009-04-21 23:56:24 +00001335 case llvm::bitc::DEFINE_ABBREV:
1336 Stream.ReadAbbrevRecord();
1337 continue;
1338 default: break;
1339 }
1340
1341 // Read a record.
1342 Record.clear();
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001343 PreprocessorRecordTypes RecType =
1344 (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
Douglas Gregor37e26842009-04-21 23:56:24 +00001345 switch (RecType) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001346 case PP_MACRO_OBJECT_LIKE:
1347 case PP_MACRO_FUNCTION_LIKE: {
Douglas Gregor37e26842009-04-21 23:56:24 +00001348 // If we already have a macro, that means that we've hit the end
1349 // of the definition of the macro we were looking for. We're
1350 // done.
1351 if (Macro)
1352 return;
1353
1354 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
1355 if (II == 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001356 Error("macro must have a name in AST file");
Douglas Gregor37e26842009-04-21 23:56:24 +00001357 return;
1358 }
1359 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1360 bool isUsed = Record[2];
Mike Stump1eb44332009-09-09 15:08:12 +00001361
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001362 MacroInfo *MI = PP->AllocateMacroInfo(Loc);
Douglas Gregor37e26842009-04-21 23:56:24 +00001363 MI->setIsUsed(isUsed);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001364 MI->setIsFromAST();
Mike Stump1eb44332009-09-09 15:08:12 +00001365
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001366 unsigned NextIndex = 3;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001367 if (RecType == PP_MACRO_FUNCTION_LIKE) {
Douglas Gregor37e26842009-04-21 23:56:24 +00001368 // Decode function-like macro info.
1369 bool isC99VarArgs = Record[3];
1370 bool isGNUVarArgs = Record[4];
1371 MacroArgs.clear();
1372 unsigned NumArgs = Record[5];
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001373 NextIndex = 6 + NumArgs;
Douglas Gregor37e26842009-04-21 23:56:24 +00001374 for (unsigned i = 0; i != NumArgs; ++i)
1375 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
1376
1377 // Install function-like macro info.
1378 MI->setIsFunctionLike();
1379 if (isC99VarArgs) MI->setIsC99Varargs();
1380 if (isGNUVarArgs) MI->setIsGNUVarargs();
Douglas Gregor75fdb232009-05-22 22:45:36 +00001381 MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001382 PP->getPreprocessorAllocator());
Douglas Gregor37e26842009-04-21 23:56:24 +00001383 }
1384
1385 // Finally, install the macro.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001386 PP->setMacroInfo(II, MI);
Douglas Gregor37e26842009-04-21 23:56:24 +00001387
1388 // Remember that we saw this macro last so that we add the tokens that
1389 // form its body to it.
1390 Macro = MI;
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001391
1392 if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
1393 // We have a macro definition. Load it now.
1394 PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
1395 getMacroDefinition(Record[NextIndex]));
1396 }
1397
Douglas Gregor37e26842009-04-21 23:56:24 +00001398 ++NumMacrosRead;
1399 break;
1400 }
Mike Stump1eb44332009-09-09 15:08:12 +00001401
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001402 case PP_TOKEN: {
Douglas Gregor37e26842009-04-21 23:56:24 +00001403 // If we see a TOKEN before a PP_MACRO_*, then the file is
1404 // erroneous, just pretend we didn't see this.
1405 if (Macro == 0) break;
Mike Stump1eb44332009-09-09 15:08:12 +00001406
Douglas Gregor37e26842009-04-21 23:56:24 +00001407 Token Tok;
1408 Tok.startToken();
1409 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1410 Tok.setLength(Record[1]);
1411 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1412 Tok.setIdentifierInfo(II);
1413 Tok.setKind((tok::TokenKind)Record[3]);
1414 Tok.setFlag((Token::TokenFlags)Record[4]);
1415 Macro->AddTokenToBody(Tok);
1416 break;
1417 }
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001418
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001419 case PP_MACRO_INSTANTIATION: {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001420 // If we already have a macro, that means that we've hit the end
1421 // of the definition of the macro we were looking for. We're
1422 // done.
1423 if (Macro)
1424 return;
1425
1426 if (!PP->getPreprocessingRecord()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001427 Error("missing preprocessing record in AST file");
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001428 return;
1429 }
1430
1431 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1432 if (PPRec.getPreprocessedEntity(Record[0]))
1433 return;
1434
1435 MacroInstantiation *MI
1436 = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
1437 SourceRange(
1438 SourceLocation::getFromRawEncoding(Record[1]),
1439 SourceLocation::getFromRawEncoding(Record[2])),
1440 getMacroDefinition(Record[4]));
1441 PPRec.SetPreallocatedEntity(Record[0], MI);
1442 return;
1443 }
1444
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001445 case PP_MACRO_DEFINITION: {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001446 // If we already have a macro, that means that we've hit the end
1447 // of the definition of the macro we were looking for. We're
1448 // done.
1449 if (Macro)
1450 return;
1451
1452 if (!PP->getPreprocessingRecord()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001453 Error("missing preprocessing record in AST file");
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001454 return;
1455 }
1456
1457 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1458 if (PPRec.getPreprocessedEntity(Record[0]))
1459 return;
1460
1461 if (Record[1] >= MacroDefinitionsLoaded.size()) {
1462 Error("out-of-bounds macro definition record");
1463 return;
1464 }
1465
1466 MacroDefinition *MD
1467 = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
1468 SourceLocation::getFromRawEncoding(Record[5]),
1469 SourceRange(
1470 SourceLocation::getFromRawEncoding(Record[2]),
1471 SourceLocation::getFromRawEncoding(Record[3])));
1472 PPRec.SetPreallocatedEntity(Record[0], MD);
1473 MacroDefinitionsLoaded[Record[1]] = MD;
1474 return;
1475 }
Steve Naroff83d63c72009-04-24 20:03:17 +00001476 }
Douglas Gregor37e26842009-04-21 23:56:24 +00001477 }
1478}
1479
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001480void ASTReader::ReadDefinedMacros() {
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001481 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1482 llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
Sebastian Redl9137a522010-07-16 17:50:48 +00001483
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001484 // If there was no preprocessor block, skip this file.
1485 if (!MacroCursor.getBitStreamReader())
1486 continue;
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001487
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001488 llvm::BitstreamCursor Cursor = MacroCursor;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001489 if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001490 Error("malformed preprocessor block record in AST file");
Douglas Gregor88a35862010-01-04 19:18:44 +00001491 return;
1492 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001493
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001494 RecordData Record;
1495 while (true) {
1496 unsigned Code = Cursor.ReadCode();
1497 if (Code == llvm::bitc::END_BLOCK) {
1498 if (Cursor.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001499 Error("error at end of preprocessor block in AST file");
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001500 return;
1501 }
1502 break;
Douglas Gregor88a35862010-01-04 19:18:44 +00001503 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001504
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001505 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1506 // No known subblocks, always skip them.
1507 Cursor.ReadSubBlockID();
1508 if (Cursor.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001509 Error("malformed block record in AST file");
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001510 return;
1511 }
1512 continue;
1513 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001514
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001515 if (Code == llvm::bitc::DEFINE_ABBREV) {
1516 Cursor.ReadAbbrevRecord();
1517 continue;
1518 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001519
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001520 // Read a record.
1521 const char *BlobStart;
1522 unsigned BlobLen;
1523 Record.clear();
1524 switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1525 default: // Default behavior: ignore.
1526 break;
Douglas Gregor88a35862010-01-04 19:18:44 +00001527
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001528 case PP_MACRO_OBJECT_LIKE:
1529 case PP_MACRO_FUNCTION_LIKE:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001530 DecodeIdentifierInfo(Record[0]);
1531 break;
1532
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001533 case PP_TOKEN:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001534 // Ignore tokens.
1535 break;
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001536
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001537 case PP_MACRO_INSTANTIATION:
1538 case PP_MACRO_DEFINITION:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001539 // Read the macro record.
1540 ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
1541 break;
1542 }
Douglas Gregor88a35862010-01-04 19:18:44 +00001543 }
1544 }
1545}
1546
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001547MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001548 if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
1549 return 0;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001550
1551 if (!MacroDefinitionsLoaded[ID]) {
1552 unsigned Index = ID;
1553 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1554 PerFileData &F = *Chain[N - I - 1];
1555 if (Index < F.LocalNumMacroDefinitions) {
1556 ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
1557 break;
1558 }
1559 Index -= F.LocalNumMacroDefinitions;
1560 }
1561 assert(MacroDefinitionsLoaded[ID] && "Broken chain");
1562 }
1563
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001564 return MacroDefinitionsLoaded[ID];
1565}
1566
Douglas Gregore650c8c2009-07-07 00:12:59 +00001567/// \brief If we are loading a relocatable PCH file, and the filename is
1568/// not an absolute path, add the system root to the beginning of the file
1569/// name.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001570void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
Douglas Gregore650c8c2009-07-07 00:12:59 +00001571 // If this is not a relocatable PCH file, there's nothing to do.
1572 if (!RelocatablePCH)
1573 return;
Mike Stump1eb44332009-09-09 15:08:12 +00001574
Daniel Dunbard5b21972009-11-18 19:50:41 +00001575 if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
Douglas Gregore650c8c2009-07-07 00:12:59 +00001576 return;
1577
Douglas Gregore650c8c2009-07-07 00:12:59 +00001578 if (isysroot == 0) {
1579 // If no system root was given, default to '/'
1580 Filename.insert(Filename.begin(), '/');
1581 return;
1582 }
Mike Stump1eb44332009-09-09 15:08:12 +00001583
Douglas Gregore650c8c2009-07-07 00:12:59 +00001584 unsigned Length = strlen(isysroot);
1585 if (isysroot[Length - 1] != '/')
1586 Filename.insert(Filename.begin(), '/');
Mike Stump1eb44332009-09-09 15:08:12 +00001587
Douglas Gregore650c8c2009-07-07 00:12:59 +00001588 Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1589}
1590
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001591ASTReader::ASTReadResult
Sebastian Redl571db7f2010-08-18 23:56:56 +00001592ASTReader::ReadASTBlock(PerFileData &F) {
Sebastian Redl9137a522010-07-16 17:50:48 +00001593 llvm::BitstreamCursor &Stream = F.Stream;
1594
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001595 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001596 Error("malformed block record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001597 return Failure;
1598 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001599
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001600 // Read all of the records and blocks for the ASt file.
Douglas Gregor8038d512009-04-10 17:25:41 +00001601 RecordData Record;
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001602 bool First = true;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001603 while (!Stream.AtEndOfStream()) {
1604 unsigned Code = Stream.ReadCode();
1605 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001606 if (Stream.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001607 Error("error at end of module block in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001608 return Failure;
1609 }
Chris Lattner7356a312009-04-11 21:15:38 +00001610
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001611 return Success;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001612 }
1613
1614 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1615 switch (Stream.ReadSubBlockID()) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001616 case DECLTYPES_BLOCK_ID:
Chris Lattner6367f6d2009-04-27 01:05:14 +00001617 // We lazily load the decls block, but we want to set up the
1618 // DeclsCursor cursor to point into it. Clone our current bitcode
1619 // cursor to it, enter the block and read the abbrevs in that block.
1620 // With the main cursor, we just skip over it.
Sebastian Redl9137a522010-07-16 17:50:48 +00001621 F.DeclsCursor = Stream;
Chris Lattner6367f6d2009-04-27 01:05:14 +00001622 if (Stream.SkipBlock() || // Skip with the main cursor.
1623 // Read the abbrevs.
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001624 ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001625 Error("malformed block record in AST file");
Chris Lattner6367f6d2009-04-27 01:05:14 +00001626 return Failure;
1627 }
1628 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001629
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001630 case PREPROCESSOR_BLOCK_ID:
Sebastian Redl9137a522010-07-16 17:50:48 +00001631 F.MacroCursor = Stream;
Douglas Gregor88a35862010-01-04 19:18:44 +00001632 if (PP)
1633 PP->setExternalSource(this);
1634
Chris Lattner7356a312009-04-11 21:15:38 +00001635 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001636 Error("malformed block record in AST file");
Chris Lattner7356a312009-04-11 21:15:38 +00001637 return Failure;
1638 }
1639 break;
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001640
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001641 case SOURCE_MANAGER_BLOCK_ID:
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001642 switch (ReadSourceManagerBlock(F)) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00001643 case Success:
1644 break;
1645
1646 case Failure:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001647 Error("malformed source manager block in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001648 return Failure;
Douglas Gregore1d918e2009-04-10 23:10:45 +00001649
1650 case IgnorePCH:
1651 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001652 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001653 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001654 }
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001655 First = false;
Douglas Gregor8038d512009-04-10 17:25:41 +00001656 continue;
1657 }
1658
1659 if (Code == llvm::bitc::DEFINE_ABBREV) {
1660 Stream.ReadAbbrevRecord();
1661 continue;
1662 }
1663
1664 // Read and process a record.
1665 Record.clear();
Douglas Gregor2bec0412009-04-10 21:16:55 +00001666 const char *BlobStart = 0;
1667 unsigned BlobLen = 0;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001668 switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
Douglas Gregor2bec0412009-04-10 21:16:55 +00001669 &BlobStart, &BlobLen)) {
Douglas Gregor8038d512009-04-10 17:25:41 +00001670 default: // Default behavior: ignore.
1671 break;
1672
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001673 case METADATA: {
1674 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1675 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001676 : diag::warn_pch_version_too_new);
1677 return IgnorePCH;
1678 }
1679
1680 RelocatablePCH = Record[4];
1681 if (Listener) {
1682 std::string TargetTriple(BlobStart, BlobLen);
1683 if (Listener->ReadTargetTriple(TargetTriple))
1684 return IgnorePCH;
1685 }
1686 break;
1687 }
1688
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001689 case CHAINED_METADATA: {
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001690 if (!First) {
1691 Error("CHAINED_METADATA is not first record in block");
1692 return Failure;
1693 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001694 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1695 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001696 : diag::warn_pch_version_too_new);
1697 return IgnorePCH;
1698 }
1699
1700 // Load the chained file.
Sebastian Redl571db7f2010-08-18 23:56:56 +00001701 switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001702 case Failure: return Failure;
1703 // If we have to ignore the dependency, we'll have to ignore this too.
1704 case IgnorePCH: return IgnorePCH;
1705 case Success: break;
1706 }
1707 break;
1708 }
1709
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001710 case TYPE_OFFSET:
Sebastian Redl12d6da02010-07-19 22:06:55 +00001711 if (F.LocalNumTypes != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001712 Error("duplicate TYPE_OFFSET record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001713 return Failure;
1714 }
Sebastian Redl12d6da02010-07-19 22:06:55 +00001715 F.TypeOffsets = (const uint32_t *)BlobStart;
1716 F.LocalNumTypes = Record[0];
Douglas Gregor8038d512009-04-10 17:25:41 +00001717 break;
1718
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001719 case DECL_OFFSET:
Sebastian Redl12d6da02010-07-19 22:06:55 +00001720 if (F.LocalNumDecls != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001721 Error("duplicate DECL_OFFSET record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001722 return Failure;
1723 }
Sebastian Redl12d6da02010-07-19 22:06:55 +00001724 F.DeclOffsets = (const uint32_t *)BlobStart;
1725 F.LocalNumDecls = Record[0];
Douglas Gregor8038d512009-04-10 17:25:41 +00001726 break;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001727
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001728 case TU_UPDATE_LEXICAL: {
Sebastian Redld692af72010-07-27 18:24:41 +00001729 DeclContextInfo Info = {
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00001730 /* No visible information */ 0,
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001731 reinterpret_cast<const DeclID *>(BlobStart),
1732 BlobLen / sizeof(DeclID)
Sebastian Redld692af72010-07-27 18:24:41 +00001733 };
1734 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1735 break;
1736 }
1737
Sebastian Redle1dde812010-08-24 00:50:04 +00001738 case UPDATE_VISIBLE: {
1739 serialization::DeclID ID = Record[0];
1740 void *Table = ASTDeclContextNameLookupTable::Create(
1741 (const unsigned char *)BlobStart + Record[1],
1742 (const unsigned char *)BlobStart,
1743 ASTDeclContextNameLookupTrait(*this));
1744 if (ID == 1) { // Is it the TU?
1745 DeclContextInfo Info = {
1746 Table, /* No lexical inforamtion */ 0, 0
1747 };
1748 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1749 } else
1750 PendingVisibleUpdates[ID].push_back(Table);
1751 break;
1752 }
1753
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001754 case REDECLS_UPDATE_LATEST: {
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00001755 assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
1756 for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001757 DeclID First = Record[i], Latest = Record[i+1];
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00001758 assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
1759 Latest > FirstLatestDeclIDs[First]) &&
1760 "The new latest is supposed to come after the previous latest");
1761 FirstLatestDeclIDs[First] = Latest;
1762 }
1763 break;
1764 }
1765
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001766 case LANGUAGE_OPTIONS:
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001767 if (ParseLanguageOptions(Record) && !DisableValidation)
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001768 return IgnorePCH;
1769 break;
Douglas Gregor2bec0412009-04-10 21:16:55 +00001770
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001771 case IDENTIFIER_TABLE:
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001772 F.IdentifierTableData = BlobStart;
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001773 if (Record[0]) {
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001774 F.IdentifierLookupTable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001775 = ASTIdentifierLookupTable::Create(
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001776 (const unsigned char *)F.IdentifierTableData + Record[0],
1777 (const unsigned char *)F.IdentifierTableData,
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001778 ASTIdentifierLookupTrait(*this, F.Stream));
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001779 if (PP)
1780 PP->getIdentifierTable().setExternalIdentifierLookup(this);
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001781 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001782 break;
1783
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001784 case IDENTIFIER_OFFSET:
Sebastian Redl2da08f92010-07-19 22:28:42 +00001785 if (F.LocalNumIdentifiers != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001786 Error("duplicate IDENTIFIER_OFFSET record in AST file");
Douglas Gregorafaf3082009-04-11 00:14:32 +00001787 return Failure;
1788 }
Sebastian Redl2da08f92010-07-19 22:28:42 +00001789 F.IdentifierOffsets = (const uint32_t *)BlobStart;
1790 F.LocalNumIdentifiers = Record[0];
Douglas Gregorafaf3082009-04-11 00:14:32 +00001791 break;
Douglas Gregorfdd01722009-04-14 00:24:19 +00001792
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001793 case EXTERNAL_DEFINITIONS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001794 // Optimization for the first block.
1795 if (ExternalDefinitions.empty())
1796 ExternalDefinitions.swap(Record);
1797 else
1798 ExternalDefinitions.insert(ExternalDefinitions.end(),
1799 Record.begin(), Record.end());
Douglas Gregorfdd01722009-04-14 00:24:19 +00001800 break;
Douglas Gregor3e1af842009-04-17 22:13:46 +00001801
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001802 case SPECIAL_TYPES:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001803 // Optimization for the first block
1804 if (SpecialTypes.empty())
1805 SpecialTypes.swap(Record);
1806 else
1807 SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
Douglas Gregorad1de002009-04-18 05:55:16 +00001808 break;
1809
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001810 case STATISTICS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001811 TotalNumStatements += Record[0];
1812 TotalNumMacros += Record[1];
1813 TotalLexicalDeclContexts += Record[2];
1814 TotalVisibleDeclContexts += Record[3];
Douglas Gregor3e1af842009-04-17 22:13:46 +00001815 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001816
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001817 case TENTATIVE_DEFINITIONS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001818 // Optimization for the first block.
1819 if (TentativeDefinitions.empty())
1820 TentativeDefinitions.swap(Record);
1821 else
1822 TentativeDefinitions.insert(TentativeDefinitions.end(),
1823 Record.begin(), Record.end());
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00001824 break;
Douglas Gregor14c22f22009-04-22 22:18:58 +00001825
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001826 case UNUSED_FILESCOPED_DECLS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001827 // Optimization for the first block.
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00001828 if (UnusedFileScopedDecls.empty())
1829 UnusedFileScopedDecls.swap(Record);
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001830 else
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00001831 UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
1832 Record.begin(), Record.end());
Tanya Lattnere6bbc012010-02-12 00:07:30 +00001833 break;
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001834
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001835 case WEAK_UNDECLARED_IDENTIFIERS:
Sebastian Redl40566802010-08-05 18:21:25 +00001836 // Later blocks overwrite earlier ones.
1837 WeakUndeclaredIdentifiers.swap(Record);
Argyrios Kyrtzidis72b90572010-08-05 09:48:08 +00001838 break;
1839
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001840 case LOCALLY_SCOPED_EXTERNAL_DECLS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001841 // Optimization for the first block.
1842 if (LocallyScopedExternalDecls.empty())
1843 LocallyScopedExternalDecls.swap(Record);
1844 else
1845 LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
1846 Record.begin(), Record.end());
Douglas Gregor14c22f22009-04-22 22:18:58 +00001847 break;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001848
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001849 case SELECTOR_OFFSETS:
Sebastian Redl059612d2010-08-03 21:58:15 +00001850 F.SelectorOffsets = (const uint32_t *)BlobStart;
Sebastian Redl725cd962010-08-04 20:40:17 +00001851 F.LocalNumSelectors = Record[0];
Douglas Gregor83941df2009-04-25 17:48:32 +00001852 break;
1853
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001854 case METHOD_POOL:
Sebastian Redl725cd962010-08-04 20:40:17 +00001855 F.SelectorLookupTableData = (const unsigned char *)BlobStart;
Douglas Gregor83941df2009-04-25 17:48:32 +00001856 if (Record[0])
Sebastian Redl725cd962010-08-04 20:40:17 +00001857 F.SelectorLookupTable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001858 = ASTSelectorLookupTable::Create(
Sebastian Redl725cd962010-08-04 20:40:17 +00001859 F.SelectorLookupTableData + Record[0],
1860 F.SelectorLookupTableData,
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001861 ASTSelectorLookupTrait(*this));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00001862 TotalNumMethodPoolEntries += Record[1];
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001863 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001864
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001865 case REFERENCED_SELECTOR_POOL: {
Sebastian Redl725cd962010-08-04 20:40:17 +00001866 ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
1867 Record.begin(), Record.end());
Fariborz Jahanian32019832010-07-23 19:11:11 +00001868 break;
Sebastian Redl681d7232010-07-27 00:17:23 +00001869 }
Fariborz Jahanian32019832010-07-23 19:11:11 +00001870
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001871 case PP_COUNTER_VALUE:
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001872 if (!Record.empty() && Listener)
1873 Listener->ReadCounter(Record[0]);
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001874 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001875
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001876 case SOURCE_LOCATION_OFFSETS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001877 F.SLocOffsets = (const uint32_t *)BlobStart;
1878 F.LocalNumSLocEntries = Record[0];
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001879 // We cannot delay this until the entire chain is loaded, because then
1880 // source location preloads would also have to be delayed.
1881 // FIXME: Is there a reason not to do that?
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001882 TotalNumSLocEntries += F.LocalNumSLocEntries;
Douglas Gregor445e23e2009-10-05 21:07:28 +00001883 SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001884 break;
1885
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001886 case SOURCE_LOCATION_PRELOADS:
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001887 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001888 ASTReadResult Result = ReadSLocEntryRecord(Record[I]);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001889 if (Result != Success)
1890 return Result;
1891 }
1892 break;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001893
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001894 case STAT_CACHE: {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001895 ASTStatCache *MyStatCache =
1896 new ASTStatCache((const unsigned char *)BlobStart + Record[0],
Douglas Gregor52e71082009-10-16 18:18:30 +00001897 (const unsigned char *)BlobStart,
1898 NumStatHits, NumStatMisses);
1899 FileMgr.addStatCache(MyStatCache);
Sebastian Redl9137a522010-07-16 17:50:48 +00001900 F.StatCache = MyStatCache;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001901 break;
Douglas Gregor52e71082009-10-16 18:18:30 +00001902 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001903
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001904 case EXT_VECTOR_DECLS:
Sebastian Redla9f23682010-07-28 21:38:49 +00001905 // Optimization for the first block.
1906 if (ExtVectorDecls.empty())
1907 ExtVectorDecls.swap(Record);
1908 else
1909 ExtVectorDecls.insert(ExtVectorDecls.end(),
1910 Record.begin(), Record.end());
Douglas Gregorb81c1702009-04-27 20:06:05 +00001911 break;
1912
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001913 case VTABLE_USES:
Sebastian Redl40566802010-08-05 18:21:25 +00001914 // Later tables overwrite earlier ones.
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00001915 VTableUses.swap(Record);
1916 break;
1917
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001918 case DYNAMIC_CLASSES:
Sebastian Redl40566802010-08-05 18:21:25 +00001919 // Optimization for the first block.
1920 if (DynamicClasses.empty())
1921 DynamicClasses.swap(Record);
1922 else
1923 DynamicClasses.insert(DynamicClasses.end(),
1924 Record.begin(), Record.end());
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00001925 break;
1926
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001927 case PENDING_IMPLICIT_INSTANTIATIONS:
Argyrios Kyrtzidis0e036382010-08-05 09:48:16 +00001928 // Optimization for the first block.
1929 if (PendingImplicitInstantiations.empty())
1930 PendingImplicitInstantiations.swap(Record);
1931 else
1932 PendingImplicitInstantiations.insert(
1933 PendingImplicitInstantiations.end(), Record.begin(), Record.end());
1934 break;
1935
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001936 case SEMA_DECL_REFS:
Sebastian Redl40566802010-08-05 18:21:25 +00001937 // Later tables overwrite earlier ones.
Argyrios Kyrtzidis76c38d32010-08-02 07:14:54 +00001938 SemaDeclRefs.swap(Record);
1939 break;
1940
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001941 case ORIGINAL_FILE_NAME:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001942 // The primary AST will be the last to get here, so it will be the one
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001943 // that's used.
Daniel Dunbar7b5a1212009-11-11 05:29:04 +00001944 ActualOriginalFileName.assign(BlobStart, BlobLen);
1945 OriginalFileName = ActualOriginalFileName;
Douglas Gregore650c8c2009-07-07 00:12:59 +00001946 MaybeAddSystemRootToFilename(OriginalFileName);
Douglas Gregorb64c1932009-05-12 01:31:05 +00001947 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001948
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001949 case VERSION_CONTROL_BRANCH_REVISION: {
Ted Kremenek974be4d2010-02-12 23:31:14 +00001950 const std::string &CurBranch = getClangFullRepositoryVersion();
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001951 llvm::StringRef ASTBranch(BlobStart, BlobLen);
1952 if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
1953 Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
Douglas Gregor445e23e2009-10-05 21:07:28 +00001954 return IgnorePCH;
1955 }
1956 break;
1957 }
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001958
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001959 case MACRO_DEFINITION_OFFSETS:
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001960 F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
1961 F.NumPreallocatedPreprocessingEntities = Record[0];
1962 F.LocalNumMacroDefinitions = Record[1];
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001963 break;
Sebastian Redl0b17c612010-08-13 00:28:03 +00001964
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001965 case DECL_REPLACEMENTS: {
Sebastian Redl0b17c612010-08-13 00:28:03 +00001966 if (Record.size() % 2 != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001967 Error("invalid DECL_REPLACEMENTS block in AST file");
Sebastian Redl0b17c612010-08-13 00:28:03 +00001968 return Failure;
1969 }
1970 for (unsigned I = 0, N = Record.size(); I != N; I += 2)
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001971 ReplacedDecls[static_cast<DeclID>(Record[I])] =
Sebastian Redl0b17c612010-08-13 00:28:03 +00001972 std::make_pair(&F, Record[I+1]);
1973 break;
1974 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001975 }
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001976 First = false;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001977 }
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001978 Error("premature end of bitstream in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001979 return Failure;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001980}
1981
Sebastian Redl571db7f2010-08-18 23:56:56 +00001982ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
1983 switch(ReadASTCore(FileName)) {
Sebastian Redlcdf3b832010-07-16 20:41:52 +00001984 case Failure: return Failure;
1985 case IgnorePCH: return IgnorePCH;
1986 case Success: break;
1987 }
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001988
1989 // Here comes stuff that we only do once the entire chain is loaded.
1990
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001991 // Allocate space for loaded identifiers, decls and types.
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001992 unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
Sebastian Redl725cd962010-08-04 20:40:17 +00001993 TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
1994 TotalNumSelectors = 0;
Sebastian Redl12d6da02010-07-19 22:06:55 +00001995 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redl2da08f92010-07-19 22:28:42 +00001996 TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
Sebastian Redl12d6da02010-07-19 22:06:55 +00001997 TotalNumTypes += Chain[I]->LocalNumTypes;
1998 TotalNumDecls += Chain[I]->LocalNumDecls;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001999 TotalNumPreallocatedPreprocessingEntities +=
2000 Chain[I]->NumPreallocatedPreprocessingEntities;
2001 TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
Sebastian Redl725cd962010-08-04 20:40:17 +00002002 TotalNumSelectors += Chain[I]->LocalNumSelectors;
Sebastian Redl12d6da02010-07-19 22:06:55 +00002003 }
Sebastian Redl2da08f92010-07-19 22:28:42 +00002004 IdentifiersLoaded.resize(TotalNumIdentifiers);
Sebastian Redl12d6da02010-07-19 22:06:55 +00002005 TypesLoaded.resize(TotalNumTypes);
2006 DeclsLoaded.resize(TotalNumDecls);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002007 MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
2008 if (PP) {
2009 if (TotalNumIdentifiers > 0)
2010 PP->getHeaderSearchInfo().SetExternalLookup(this);
2011 if (TotalNumPreallocatedPreprocessingEntities > 0) {
2012 if (!PP->getPreprocessingRecord())
2013 PP->createPreprocessingRecord();
2014 PP->getPreprocessingRecord()->SetExternalSource(*this,
2015 TotalNumPreallocatedPreprocessingEntities);
2016 }
2017 }
Sebastian Redl725cd962010-08-04 20:40:17 +00002018 SelectorsLoaded.resize(TotalNumSelectors);
Sebastian Redl12d6da02010-07-19 22:06:55 +00002019
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002020 // Check the predefines buffers.
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00002021 if (!DisableValidation && CheckPredefinesBuffers())
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002022 return IgnorePCH;
2023
2024 if (PP) {
2025 // Initialization of keywords and pragmas occurs before the
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002026 // AST file is read, so there may be some identifiers that were
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002027 // loaded into the IdentifierTable before we intercepted the
2028 // creation of identifiers. Iterate through the list of known
2029 // identifiers and determine whether we have to establish
2030 // preprocessor definitions or top-level identifier declaration
2031 // chains for those identifiers.
2032 //
2033 // We copy the IdentifierInfo pointers to a small vector first,
2034 // since de-serializing declarations or macro definitions can add
2035 // new entries into the identifier table, invalidating the
2036 // iterators.
2037 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
2038 for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
2039 IdEnd = PP->getIdentifierTable().end();
2040 Id != IdEnd; ++Id)
2041 Identifiers.push_back(Id->second);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002042 // We need to search the tables in all files.
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002043 for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002044 ASTIdentifierLookupTable *IdTable
2045 = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
2046 // Not all AST files necessarily have identifier tables, only the useful
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00002047 // ones.
2048 if (!IdTable)
2049 continue;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002050 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
2051 IdentifierInfo *II = Identifiers[I];
2052 // Look in the on-disk hash tables for an entry for this identifier
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002053 ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002054 std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002055 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
Sebastian Redl518d8cb2010-07-20 21:20:32 +00002056 if (Pos == IdTable->end())
2057 continue;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002058
Sebastian Redl518d8cb2010-07-20 21:20:32 +00002059 // Dereferencing the iterator has the effect of populating the
2060 // IdentifierInfo node with the various declarations it needs.
2061 (void)*Pos;
2062 }
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002063 }
2064 }
2065
2066 if (Context)
2067 InitializeContext(*Context);
2068
2069 return Success;
2070}
2071
Sebastian Redl571db7f2010-08-18 23:56:56 +00002072ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002073 Chain.push_back(new PerFileData());
Sebastian Redl9137a522010-07-16 17:50:48 +00002074 PerFileData &F = *Chain.back();
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002075
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002076 // Set the AST file name.
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002077 F.FileName = FileName;
2078
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002079 // Open the AST file.
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002080 //
2081 // FIXME: This shouldn't be here, we should just take a raw_ostream.
2082 std::string ErrStr;
2083 F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
2084 if (!F.Buffer) {
2085 Error(ErrStr.c_str());
2086 return IgnorePCH;
2087 }
2088
2089 // Initialize the stream
2090 F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
2091 (const unsigned char *)F.Buffer->getBufferEnd());
Sebastian Redl9137a522010-07-16 17:50:48 +00002092 llvm::BitstreamCursor &Stream = F.Stream;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002093 Stream.init(F.StreamFile);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002094 F.SizeInBits = F.Buffer->getBufferSize() * 8;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002095
2096 // Sniff for the signature.
2097 if (Stream.Read(8) != 'C' ||
2098 Stream.Read(8) != 'P' ||
2099 Stream.Read(8) != 'C' ||
2100 Stream.Read(8) != 'H') {
2101 Diag(diag::err_not_a_pch_file) << FileName;
2102 return Failure;
2103 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002104
Douglas Gregor2cf26342009-04-09 22:27:44 +00002105 while (!Stream.AtEndOfStream()) {
2106 unsigned Code = Stream.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00002107
Douglas Gregore1d918e2009-04-10 23:10:45 +00002108 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002109 Error("invalid record at top-level of AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002110 return Failure;
2111 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002112
2113 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregor668c1a42009-04-21 22:25:48 +00002114
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002115 // We only know the AST subblock ID.
Douglas Gregor2cf26342009-04-09 22:27:44 +00002116 switch (BlockID) {
2117 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002118 if (Stream.ReadBlockInfoBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002119 Error("malformed BlockInfoBlock in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002120 return Failure;
2121 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002122 break;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002123 case AST_BLOCK_ID:
Sebastian Redl571db7f2010-08-18 23:56:56 +00002124 switch (ReadASTBlock(F)) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002125 case Success:
2126 break;
2127
2128 case Failure:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002129 return Failure;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002130
2131 case IgnorePCH:
Douglas Gregor2bec0412009-04-10 21:16:55 +00002132 // FIXME: We could consider reading through to the end of this
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002133 // AST block, skipping subblocks, to see if there are other
2134 // AST blocks elsewhere.
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002135
2136 // Clear out any preallocated source location entries, so that
2137 // the source manager does not try to resolve them later.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002138 SourceMgr.ClearPreallocatedSLocEntries();
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002139
2140 // Remove the stat cache.
Sebastian Redl9137a522010-07-16 17:50:48 +00002141 if (F.StatCache)
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002142 FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002143
Douglas Gregore1d918e2009-04-10 23:10:45 +00002144 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002145 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002146 break;
2147 default:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002148 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002149 Error("malformed block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002150 return Failure;
2151 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002152 break;
2153 }
Mike Stump1eb44332009-09-09 15:08:12 +00002154 }
2155
Sebastian Redlcdf3b832010-07-16 20:41:52 +00002156 return Success;
2157}
2158
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002159void ASTReader::setPreprocessor(Preprocessor &pp) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002160 PP = &pp;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002161
2162 unsigned TotalNum = 0;
2163 for (unsigned I = 0, N = Chain.size(); I != N; ++I)
2164 TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
2165 if (TotalNum) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002166 if (!PP->getPreprocessingRecord())
2167 PP->createPreprocessingRecord();
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002168 PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002169 }
2170}
2171
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002172void ASTReader::InitializeContext(ASTContext &Ctx) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002173 Context = &Ctx;
2174 assert(Context && "Passed null context!");
2175
2176 assert(PP && "Forgot to set Preprocessor ?");
2177 PP->getIdentifierTable().setExternalIdentifierLookup(this);
2178 PP->getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor88a35862010-01-04 19:18:44 +00002179 PP->setExternalSource(this);
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00002180
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002181 // Load the translation unit declaration
Argyrios Kyrtzidis8871a442010-07-08 17:13:02 +00002182 GetTranslationUnitDecl();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002183
2184 // Load the special types.
2185 Context->setBuiltinVaListType(
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002186 GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
2187 if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002188 Context->setObjCIdType(GetType(Id));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002189 if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002190 Context->setObjCSelType(GetType(Sel));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002191 if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002192 Context->setObjCProtoType(GetType(Proto));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002193 if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002194 Context->setObjCClassType(GetType(Class));
Steve Naroff14108da2009-07-10 23:34:53 +00002195
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002196 if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002197 Context->setCFConstantStringType(GetType(String));
Mike Stump1eb44332009-09-09 15:08:12 +00002198 if (unsigned FastEnum
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002199 = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002200 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002201 if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002202 QualType FileType = GetType(File);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002203 if (FileType.isNull()) {
2204 Error("FILE type is NULL");
2205 return;
2206 }
John McCall183700f2009-09-21 23:43:11 +00002207 if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002208 Context->setFILEDecl(Typedef->getDecl());
2209 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002210 const TagType *Tag = FileType->getAs<TagType>();
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002211 if (!Tag) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002212 Error("Invalid FILE type in AST file");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002213 return;
2214 }
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002215 Context->setFILEDecl(Tag->getDecl());
2216 }
2217 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002218 if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
Mike Stump782fa302009-07-28 02:25:19 +00002219 QualType Jmp_bufType = GetType(Jmp_buf);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002220 if (Jmp_bufType.isNull()) {
2221 Error("jmp_bug type is NULL");
2222 return;
2223 }
John McCall183700f2009-09-21 23:43:11 +00002224 if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
Mike Stump782fa302009-07-28 02:25:19 +00002225 Context->setjmp_bufDecl(Typedef->getDecl());
2226 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002227 const TagType *Tag = Jmp_bufType->getAs<TagType>();
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002228 if (!Tag) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002229 Error("Invalid jmp_buf type in AST file");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002230 return;
2231 }
Mike Stump782fa302009-07-28 02:25:19 +00002232 Context->setjmp_bufDecl(Tag->getDecl());
2233 }
2234 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002235 if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
Mike Stump782fa302009-07-28 02:25:19 +00002236 QualType Sigjmp_bufType = GetType(Sigjmp_buf);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002237 if (Sigjmp_bufType.isNull()) {
2238 Error("sigjmp_buf type is NULL");
2239 return;
2240 }
John McCall183700f2009-09-21 23:43:11 +00002241 if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
Mike Stump782fa302009-07-28 02:25:19 +00002242 Context->setsigjmp_bufDecl(Typedef->getDecl());
2243 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002244 const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002245 assert(Tag && "Invalid sigjmp_buf type in AST file");
Mike Stump782fa302009-07-28 02:25:19 +00002246 Context->setsigjmp_bufDecl(Tag->getDecl());
2247 }
2248 }
Mike Stump1eb44332009-09-09 15:08:12 +00002249 if (unsigned ObjCIdRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002250 = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
Douglas Gregord1571ac2009-08-21 00:27:50 +00002251 Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
Mike Stump1eb44332009-09-09 15:08:12 +00002252 if (unsigned ObjCClassRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002253 = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Douglas Gregord1571ac2009-08-21 00:27:50 +00002254 Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002255 if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Mike Stumpadaaad32009-10-20 02:12:22 +00002256 Context->setBlockDescriptorType(GetType(String));
Mike Stump083c25e2009-10-22 00:49:09 +00002257 if (unsigned String
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002258 = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Mike Stump083c25e2009-10-22 00:49:09 +00002259 Context->setBlockDescriptorExtendedType(GetType(String));
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002260 if (unsigned ObjCSelRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002261 = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002262 Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002263 if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002264 Context->setNSConstantStringType(GetType(String));
Argyrios Kyrtzidis00611382010-07-04 21:44:19 +00002265
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002266 if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
Argyrios Kyrtzidis00611382010-07-04 21:44:19 +00002267 Context->setInt128Installed();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002268}
2269
Douglas Gregorb64c1932009-05-12 01:31:05 +00002270/// \brief Retrieve the name of the original source file name
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002271/// directly from the AST file, without actually loading the AST
Douglas Gregorb64c1932009-05-12 01:31:05 +00002272/// file.
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002273std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
Daniel Dunbar93ebb1b2009-12-03 09:13:06 +00002274 Diagnostic &Diags) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002275 // Open the AST file.
Douglas Gregorb64c1932009-05-12 01:31:05 +00002276 std::string ErrStr;
2277 llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002278 Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr));
Douglas Gregorb64c1932009-05-12 01:31:05 +00002279 if (!Buffer) {
Daniel Dunbar93ebb1b2009-12-03 09:13:06 +00002280 Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002281 return std::string();
2282 }
2283
2284 // Initialize the stream
2285 llvm::BitstreamReader StreamFile;
2286 llvm::BitstreamCursor Stream;
Mike Stump1eb44332009-09-09 15:08:12 +00002287 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
Douglas Gregorb64c1932009-05-12 01:31:05 +00002288 (const unsigned char *)Buffer->getBufferEnd());
2289 Stream.init(StreamFile);
2290
2291 // Sniff for the signature.
2292 if (Stream.Read(8) != 'C' ||
2293 Stream.Read(8) != 'P' ||
2294 Stream.Read(8) != 'C' ||
2295 Stream.Read(8) != 'H') {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002296 Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002297 return std::string();
2298 }
2299
2300 RecordData Record;
2301 while (!Stream.AtEndOfStream()) {
2302 unsigned Code = Stream.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00002303
Douglas Gregorb64c1932009-05-12 01:31:05 +00002304 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2305 unsigned BlockID = Stream.ReadSubBlockID();
Mike Stump1eb44332009-09-09 15:08:12 +00002306
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002307 // We only know the AST subblock ID.
Douglas Gregorb64c1932009-05-12 01:31:05 +00002308 switch (BlockID) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002309 case AST_BLOCK_ID:
2310 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002311 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002312 return std::string();
2313 }
2314 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002315
Douglas Gregorb64c1932009-05-12 01:31:05 +00002316 default:
2317 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002318 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002319 return std::string();
2320 }
2321 break;
2322 }
2323 continue;
2324 }
2325
2326 if (Code == llvm::bitc::END_BLOCK) {
2327 if (Stream.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002328 Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002329 return std::string();
2330 }
2331 continue;
2332 }
2333
2334 if (Code == llvm::bitc::DEFINE_ABBREV) {
2335 Stream.ReadAbbrevRecord();
2336 continue;
2337 }
2338
2339 Record.clear();
2340 const char *BlobStart = 0;
2341 unsigned BlobLen = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00002342 if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002343 == ORIGINAL_FILE_NAME)
Douglas Gregorb64c1932009-05-12 01:31:05 +00002344 return std::string(BlobStart, BlobLen);
Mike Stump1eb44332009-09-09 15:08:12 +00002345 }
Douglas Gregorb64c1932009-05-12 01:31:05 +00002346
2347 return std::string();
2348}
2349
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002350/// \brief Parse the record that corresponds to a LangOptions data
2351/// structure.
2352///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002353/// This routine parses the language options from the AST file and then gives
2354/// them to the AST listener if one is set.
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002355///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002356/// \returns true if the listener deems the file unacceptable, false otherwise.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002357bool ASTReader::ParseLanguageOptions(
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002358 const llvm::SmallVectorImpl<uint64_t> &Record) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002359 if (Listener) {
2360 LangOptions LangOpts;
Mike Stump1eb44332009-09-09 15:08:12 +00002361
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002362 #define PARSE_LANGOPT(Option) \
2363 LangOpts.Option = Record[Idx]; \
2364 ++Idx
Mike Stump1eb44332009-09-09 15:08:12 +00002365
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002366 unsigned Idx = 0;
2367 PARSE_LANGOPT(Trigraphs);
2368 PARSE_LANGOPT(BCPLComment);
2369 PARSE_LANGOPT(DollarIdents);
2370 PARSE_LANGOPT(AsmPreprocessor);
2371 PARSE_LANGOPT(GNUMode);
Chandler Carrutheb5d7b72010-04-17 20:17:31 +00002372 PARSE_LANGOPT(GNUKeywords);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002373 PARSE_LANGOPT(ImplicitInt);
2374 PARSE_LANGOPT(Digraphs);
2375 PARSE_LANGOPT(HexFloats);
2376 PARSE_LANGOPT(C99);
2377 PARSE_LANGOPT(Microsoft);
2378 PARSE_LANGOPT(CPlusPlus);
2379 PARSE_LANGOPT(CPlusPlus0x);
2380 PARSE_LANGOPT(CXXOperatorNames);
2381 PARSE_LANGOPT(ObjC1);
2382 PARSE_LANGOPT(ObjC2);
2383 PARSE_LANGOPT(ObjCNonFragileABI);
Fariborz Jahanian412e7982010-02-09 19:31:38 +00002384 PARSE_LANGOPT(ObjCNonFragileABI2);
Fariborz Jahanian4c9d8d02010-04-22 21:01:59 +00002385 PARSE_LANGOPT(NoConstantCFStrings);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002386 PARSE_LANGOPT(PascalStrings);
2387 PARSE_LANGOPT(WritableStrings);
2388 PARSE_LANGOPT(LaxVectorConversions);
Nate Begemanb9e7e632009-06-25 23:01:11 +00002389 PARSE_LANGOPT(AltiVec);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002390 PARSE_LANGOPT(Exceptions);
Daniel Dunbar73482882010-02-10 18:48:44 +00002391 PARSE_LANGOPT(SjLjExceptions);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002392 PARSE_LANGOPT(NeXTRuntime);
2393 PARSE_LANGOPT(Freestanding);
2394 PARSE_LANGOPT(NoBuiltin);
2395 PARSE_LANGOPT(ThreadsafeStatics);
Douglas Gregor972d9542009-09-03 14:36:33 +00002396 PARSE_LANGOPT(POSIXThreads);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002397 PARSE_LANGOPT(Blocks);
2398 PARSE_LANGOPT(EmitAllDecls);
2399 PARSE_LANGOPT(MathErrno);
Chris Lattnera4d71452010-06-26 21:25:03 +00002400 LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
2401 Record[Idx++]);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002402 PARSE_LANGOPT(HeinousExtensions);
2403 PARSE_LANGOPT(Optimize);
2404 PARSE_LANGOPT(OptimizeSize);
2405 PARSE_LANGOPT(Static);
2406 PARSE_LANGOPT(PICLevel);
2407 PARSE_LANGOPT(GNUInline);
2408 PARSE_LANGOPT(NoInline);
2409 PARSE_LANGOPT(AccessControl);
2410 PARSE_LANGOPT(CharIsSigned);
John Thompsona6fda122009-11-05 20:14:16 +00002411 PARSE_LANGOPT(ShortWChar);
Chris Lattnera4d71452010-06-26 21:25:03 +00002412 LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
2413 LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
Daniel Dunbarab8e2812009-09-21 04:16:19 +00002414 LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Chris Lattnera4d71452010-06-26 21:25:03 +00002415 Record[Idx++]);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002416 PARSE_LANGOPT(InstantiationDepth);
Nate Begemanb9e7e632009-06-25 23:01:11 +00002417 PARSE_LANGOPT(OpenCL);
Mike Stump9c276ae2009-12-12 01:27:46 +00002418 PARSE_LANGOPT(CatchUndefined);
2419 // FIXME: Missing ElideConstructors?!
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002420 #undef PARSE_LANGOPT
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002421
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002422 return Listener->ReadLanguageOptions(LangOpts);
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002423 }
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002424
2425 return false;
2426}
2427
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002428void ASTReader::ReadPreprocessedEntities() {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002429 ReadDefinedMacros();
2430}
2431
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002432/// \brief Get the correct cursor and offset for loading a type.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002433ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002434 PerFileData *F = 0;
2435 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
2436 F = Chain[N - I - 1];
2437 if (Index < F->LocalNumTypes)
2438 break;
2439 Index -= F->LocalNumTypes;
2440 }
2441 assert(F && F->LocalNumTypes > Index && "Broken chain");
Sebastian Redl971dd442010-07-20 22:55:31 +00002442 return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002443}
2444
2445/// \brief Read and return the type with the given index..
Douglas Gregor2cf26342009-04-09 22:27:44 +00002446///
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002447/// The index is the type ID, shifted and minus the number of predefs. This
2448/// routine actually reads the record corresponding to the type at the given
2449/// location. It is a helper routine for GetType, which deals with reading type
2450/// IDs.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002451QualType ASTReader::ReadTypeRecord(unsigned Index) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002452 RecordLocation Loc = TypeCursorForIndex(Index);
Sebastian Redl971dd442010-07-20 22:55:31 +00002453 llvm::BitstreamCursor &DeclsCursor = *Loc.first;
Sebastian Redl9137a522010-07-16 17:50:48 +00002454
Douglas Gregor0b748912009-04-14 21:18:50 +00002455 // Keep track of where we are in the stream, then jump back there
2456 // after reading this type.
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002457 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00002458
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00002459 ReadingKindTracker ReadingKind(Read_Type, *this);
Sebastian Redl27372b42010-08-11 18:52:41 +00002460
Douglas Gregord89275b2009-07-06 18:54:52 +00002461 // Note that we are loading a type record.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00002462 Deserializing AType(this);
Mike Stump1eb44332009-09-09 15:08:12 +00002463
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002464 DeclsCursor.JumpToBit(Loc.second);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002465 RecordData Record;
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002466 unsigned Code = DeclsCursor.ReadCode();
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002467 switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
2468 case TYPE_EXT_QUAL: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002469 if (Record.size() != 2) {
2470 Error("Incorrect encoding of extended qualifier type");
2471 return QualType();
2472 }
Douglas Gregor6d473962009-04-15 22:00:08 +00002473 QualType Base = GetType(Record[0]);
John McCall0953e762009-09-24 19:53:00 +00002474 Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
2475 return Context->getQualifiedType(Base, Quals);
Douglas Gregor6d473962009-04-15 22:00:08 +00002476 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002477
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002478 case TYPE_COMPLEX: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002479 if (Record.size() != 1) {
2480 Error("Incorrect encoding of complex type");
2481 return QualType();
2482 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002483 QualType ElemType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002484 return Context->getComplexType(ElemType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002485 }
2486
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002487 case TYPE_POINTER: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002488 if (Record.size() != 1) {
2489 Error("Incorrect encoding of pointer type");
2490 return QualType();
2491 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002492 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002493 return Context->getPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002494 }
2495
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002496 case TYPE_BLOCK_POINTER: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002497 if (Record.size() != 1) {
2498 Error("Incorrect encoding of block pointer type");
2499 return QualType();
2500 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002501 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002502 return Context->getBlockPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002503 }
2504
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002505 case TYPE_LVALUE_REFERENCE: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002506 if (Record.size() != 1) {
2507 Error("Incorrect encoding of lvalue reference type");
2508 return QualType();
2509 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002510 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002511 return Context->getLValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002512 }
2513
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002514 case TYPE_RVALUE_REFERENCE: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002515 if (Record.size() != 1) {
2516 Error("Incorrect encoding of rvalue reference type");
2517 return QualType();
2518 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002519 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002520 return Context->getRValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002521 }
2522
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002523 case TYPE_MEMBER_POINTER: {
Argyrios Kyrtzidis240437b2010-07-02 11:55:15 +00002524 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002525 Error("Incorrect encoding of member pointer type");
2526 return QualType();
2527 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002528 QualType PointeeType = GetType(Record[0]);
2529 QualType ClassType = GetType(Record[1]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002530 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregor2cf26342009-04-09 22:27:44 +00002531 }
2532
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002533 case TYPE_CONSTANT_ARRAY: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002534 QualType ElementType = GetType(Record[0]);
2535 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2536 unsigned IndexTypeQuals = Record[2];
2537 unsigned Idx = 3;
2538 llvm::APInt Size = ReadAPInt(Record, Idx);
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002539 return Context->getConstantArrayType(ElementType, Size,
2540 ASM, IndexTypeQuals);
2541 }
2542
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002543 case TYPE_INCOMPLETE_ARRAY: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002544 QualType ElementType = GetType(Record[0]);
2545 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2546 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002547 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002548 }
2549
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002550 case TYPE_VARIABLE_ARRAY: {
Douglas Gregor0b748912009-04-14 21:18:50 +00002551 QualType ElementType = GetType(Record[0]);
2552 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2553 unsigned IndexTypeQuals = Record[2];
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002554 SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
2555 SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
Sebastian Redl577d4792010-07-22 22:43:28 +00002556 return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor),
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002557 ASM, IndexTypeQuals,
2558 SourceRange(LBLoc, RBLoc));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002559 }
2560
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002561 case TYPE_VECTOR: {
Chris Lattner788b0fd2010-06-23 06:00:24 +00002562 if (Record.size() != 3) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002563 Error("incorrect encoding of vector type in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002564 return QualType();
2565 }
2566
2567 QualType ElementType = GetType(Record[0]);
2568 unsigned NumElements = Record[1];
Chris Lattner788b0fd2010-06-23 06:00:24 +00002569 unsigned AltiVecSpec = Record[2];
2570 return Context->getVectorType(ElementType, NumElements,
2571 (VectorType::AltiVecSpecific)AltiVecSpec);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002572 }
2573
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002574 case TYPE_EXT_VECTOR: {
Chris Lattner788b0fd2010-06-23 06:00:24 +00002575 if (Record.size() != 3) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002576 Error("incorrect encoding of extended vector type in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002577 return QualType();
2578 }
2579
2580 QualType ElementType = GetType(Record[0]);
2581 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002582 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002583 }
2584
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002585 case TYPE_FUNCTION_NO_PROTO: {
Rafael Espindola425ef722010-03-30 22:15:11 +00002586 if (Record.size() != 4) {
Douglas Gregora02b1472009-04-28 21:53:25 +00002587 Error("incorrect encoding of no-proto function type");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002588 return QualType();
2589 }
2590 QualType ResultType = GetType(Record[0]);
Rafael Espindola425ef722010-03-30 22:15:11 +00002591 FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
Rafael Espindola264ba482010-03-30 20:24:48 +00002592 return Context->getFunctionNoProtoType(ResultType, Info);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002593 }
2594
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002595 case TYPE_FUNCTION_PROTO: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002596 QualType ResultType = GetType(Record[0]);
Douglas Gregor91236662009-12-22 18:11:50 +00002597 bool NoReturn = Record[1];
Rafael Espindola425ef722010-03-30 22:15:11 +00002598 unsigned RegParm = Record[2];
2599 CallingConv CallConv = (CallingConv)Record[3];
2600 unsigned Idx = 4;
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002601 unsigned NumParams = Record[Idx++];
2602 llvm::SmallVector<QualType, 16> ParamTypes;
2603 for (unsigned I = 0; I != NumParams; ++I)
2604 ParamTypes.push_back(GetType(Record[Idx++]));
2605 bool isVariadic = Record[Idx++];
2606 unsigned Quals = Record[Idx++];
Sebastian Redl465226e2009-05-27 22:11:52 +00002607 bool hasExceptionSpec = Record[Idx++];
2608 bool hasAnyExceptionSpec = Record[Idx++];
2609 unsigned NumExceptions = Record[Idx++];
2610 llvm::SmallVector<QualType, 2> Exceptions;
2611 for (unsigned I = 0; I != NumExceptions; ++I)
2612 Exceptions.push_back(GetType(Record[Idx++]));
Jay Foadbeaaccd2009-05-21 09:52:38 +00002613 return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
Sebastian Redl465226e2009-05-27 22:11:52 +00002614 isVariadic, Quals, hasExceptionSpec,
2615 hasAnyExceptionSpec, NumExceptions,
Rafael Espindola264ba482010-03-30 20:24:48 +00002616 Exceptions.data(),
Rafael Espindola425ef722010-03-30 22:15:11 +00002617 FunctionType::ExtInfo(NoReturn, RegParm,
2618 CallConv));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002619 }
2620
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002621 case TYPE_UNRESOLVED_USING:
John McCalled976492009-12-04 22:46:56 +00002622 return Context->getTypeDeclType(
2623 cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
2624
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002625 case TYPE_TYPEDEF: {
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002626 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002627 Error("incorrect encoding of typedef type");
2628 return QualType();
2629 }
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002630 TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
2631 QualType Canonical = GetType(Record[1]);
2632 return Context->getTypedefType(Decl, Canonical);
2633 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002634
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002635 case TYPE_TYPEOF_EXPR:
Sebastian Redl577d4792010-07-22 22:43:28 +00002636 return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002637
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002638 case TYPE_TYPEOF: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002639 if (Record.size() != 1) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002640 Error("incorrect encoding of typeof(type) in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002641 return QualType();
2642 }
2643 QualType UnderlyingType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002644 return Context->getTypeOfType(UnderlyingType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002645 }
Mike Stump1eb44332009-09-09 15:08:12 +00002646
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002647 case TYPE_DECLTYPE:
Sebastian Redl577d4792010-07-22 22:43:28 +00002648 return Context->getDecltypeType(ReadExpr(DeclsCursor));
Anders Carlsson395b4752009-06-24 19:06:50 +00002649
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002650 case TYPE_RECORD: {
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002651 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002652 Error("incorrect encoding of record type");
2653 return QualType();
2654 }
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002655 bool IsDependent = Record[0];
2656 QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
2657 T->Dependent = IsDependent;
2658 return T;
2659 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002660
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002661 case TYPE_ENUM: {
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002662 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002663 Error("incorrect encoding of enum type");
2664 return QualType();
2665 }
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002666 bool IsDependent = Record[0];
2667 QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
2668 T->Dependent = IsDependent;
2669 return T;
2670 }
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00002671
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002672 case TYPE_ELABORATED: {
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002673 unsigned Idx = 0;
2674 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2675 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2676 QualType NamedType = GetType(Record[Idx++]);
2677 return Context->getElaboratedType(Keyword, NNS, NamedType);
John McCall7da24312009-09-05 00:15:47 +00002678 }
2679
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002680 case TYPE_OBJC_INTERFACE: {
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002681 unsigned Idx = 0;
2682 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
John McCallc12c5bb2010-05-15 11:32:37 +00002683 return Context->getObjCInterfaceType(ItfD);
2684 }
2685
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002686 case TYPE_OBJC_OBJECT: {
John McCallc12c5bb2010-05-15 11:32:37 +00002687 unsigned Idx = 0;
2688 QualType Base = GetType(Record[Idx++]);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002689 unsigned NumProtos = Record[Idx++];
2690 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
2691 for (unsigned I = 0; I != NumProtos; ++I)
2692 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
John McCallc12c5bb2010-05-15 11:32:37 +00002693 return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002694 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002695
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002696 case TYPE_OBJC_OBJECT_POINTER: {
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00002697 unsigned Idx = 0;
John McCallc12c5bb2010-05-15 11:32:37 +00002698 QualType Pointee = GetType(Record[Idx++]);
2699 return Context->getObjCObjectPointerType(Pointee);
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00002700 }
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002701
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002702 case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
John McCall49a832b2009-10-18 09:09:24 +00002703 unsigned Idx = 0;
2704 QualType Parm = GetType(Record[Idx++]);
2705 QualType Replacement = GetType(Record[Idx++]);
2706 return
2707 Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2708 Replacement);
2709 }
John McCall3cb0ebd2010-03-10 03:28:59 +00002710
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002711 case TYPE_INJECTED_CLASS_NAME: {
John McCall3cb0ebd2010-03-10 03:28:59 +00002712 CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
2713 QualType TST = GetType(Record[1]); // probably derivable
Argyrios Kyrtzidis43921b52010-07-02 11:55:20 +00002714 // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002715 // for AST reading, too much interdependencies.
Argyrios Kyrtzidis43921b52010-07-02 11:55:20 +00002716 return
2717 QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
John McCall3cb0ebd2010-03-10 03:28:59 +00002718 }
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +00002719
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002720 case TYPE_TEMPLATE_TYPE_PARM: {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002721 unsigned Idx = 0;
2722 unsigned Depth = Record[Idx++];
2723 unsigned Index = Record[Idx++];
2724 bool Pack = Record[Idx++];
2725 IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
2726 return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
2727 }
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002728
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002729 case TYPE_DEPENDENT_NAME: {
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002730 unsigned Idx = 0;
2731 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2732 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2733 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
Argyrios Kyrtzidisf48d45e2010-07-02 11:55:24 +00002734 QualType Canon = GetType(Record[Idx++]);
2735 return Context->getDependentNameType(Keyword, NNS, Name, Canon);
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002736 }
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002737
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002738 case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002739 unsigned Idx = 0;
2740 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2741 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2742 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
2743 unsigned NumArgs = Record[Idx++];
2744 llvm::SmallVector<TemplateArgument, 8> Args;
2745 Args.reserve(NumArgs);
2746 while (NumArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00002747 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002748 return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
2749 Args.size(), Args.data());
2750 }
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002751
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002752 case TYPE_DEPENDENT_SIZED_ARRAY: {
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002753 unsigned Idx = 0;
2754
2755 // ArrayType
2756 QualType ElementType = GetType(Record[Idx++]);
2757 ArrayType::ArraySizeModifier ASM
2758 = (ArrayType::ArraySizeModifier)Record[Idx++];
2759 unsigned IndexTypeQuals = Record[Idx++];
2760
2761 // DependentSizedArrayType
Sebastian Redl577d4792010-07-22 22:43:28 +00002762 Expr *NumElts = ReadExpr(DeclsCursor);
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002763 SourceRange Brackets = ReadSourceRange(Record, Idx);
2764
2765 return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
2766 IndexTypeQuals, Brackets);
2767 }
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +00002768
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002769 case TYPE_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002770 unsigned Idx = 0;
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002771 bool IsDependent = Record[Idx++];
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002772 TemplateName Name = ReadTemplateName(Record, Idx);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002773 llvm::SmallVector<TemplateArgument, 8> Args;
Sebastian Redl577d4792010-07-22 22:43:28 +00002774 ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00002775 QualType Canon = GetType(Record[Idx++]);
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002776 QualType T;
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002777 if (Canon.isNull())
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002778 T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
2779 Args.size());
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002780 else
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002781 T = Context->getTemplateSpecializationType(Name, Args.data(),
2782 Args.size(), Canon);
2783 T->Dependent = IsDependent;
2784 return T;
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002785 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002786 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002787 // Suppress a GCC warning
2788 return QualType();
2789}
2790
John McCalla1ee0c52009-10-16 21:56:05 +00002791namespace {
2792
2793class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002794 ASTReader &Reader;
Sebastian Redl577d4792010-07-22 22:43:28 +00002795 llvm::BitstreamCursor &DeclsCursor;
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002796 const ASTReader::RecordData &Record;
John McCalla1ee0c52009-10-16 21:56:05 +00002797 unsigned &Idx;
2798
2799public:
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002800 TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
2801 const ASTReader::RecordData &Record, unsigned &Idx)
Sebastian Redl577d4792010-07-22 22:43:28 +00002802 : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
John McCalla1ee0c52009-10-16 21:56:05 +00002803
John McCall51bd8032009-10-18 01:05:36 +00002804 // We want compile-time assurance that we've enumerated all of
2805 // these, so unfortunately we have to declare them first, then
2806 // define them out-of-line.
2807#define ABSTRACT_TYPELOC(CLASS, PARENT)
John McCalla1ee0c52009-10-16 21:56:05 +00002808#define TYPELOC(CLASS, PARENT) \
John McCall51bd8032009-10-18 01:05:36 +00002809 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
John McCalla1ee0c52009-10-16 21:56:05 +00002810#include "clang/AST/TypeLocNodes.def"
2811
John McCall51bd8032009-10-18 01:05:36 +00002812 void VisitFunctionTypeLoc(FunctionTypeLoc);
2813 void VisitArrayTypeLoc(ArrayTypeLoc);
John McCalla1ee0c52009-10-16 21:56:05 +00002814};
2815
2816}
2817
John McCall51bd8032009-10-18 01:05:36 +00002818void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
John McCalla1ee0c52009-10-16 21:56:05 +00002819 // nothing to do
2820}
John McCall51bd8032009-10-18 01:05:36 +00002821void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Douglas Gregorddf889a2010-01-18 18:04:31 +00002822 TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2823 if (TL.needsExtraLocalData()) {
2824 TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2825 TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2826 TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2827 TL.setModeAttr(Record[Idx++]);
2828 }
John McCalla1ee0c52009-10-16 21:56:05 +00002829}
John McCall51bd8032009-10-18 01:05:36 +00002830void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2831 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002832}
John McCall51bd8032009-10-18 01:05:36 +00002833void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2834 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002835}
John McCall51bd8032009-10-18 01:05:36 +00002836void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2837 TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002838}
John McCall51bd8032009-10-18 01:05:36 +00002839void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2840 TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002841}
John McCall51bd8032009-10-18 01:05:36 +00002842void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2843 TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002844}
John McCall51bd8032009-10-18 01:05:36 +00002845void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2846 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002847}
John McCall51bd8032009-10-18 01:05:36 +00002848void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2849 TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2850 TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002851 if (Record[Idx++])
Sebastian Redl577d4792010-07-22 22:43:28 +00002852 TL.setSizeExpr(Reader.ReadExpr(DeclsCursor));
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002853 else
John McCall51bd8032009-10-18 01:05:36 +00002854 TL.setSizeExpr(0);
2855}
2856void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2857 VisitArrayTypeLoc(TL);
2858}
2859void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2860 VisitArrayTypeLoc(TL);
2861}
2862void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2863 VisitArrayTypeLoc(TL);
2864}
2865void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2866 DependentSizedArrayTypeLoc TL) {
2867 VisitArrayTypeLoc(TL);
2868}
2869void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2870 DependentSizedExtVectorTypeLoc TL) {
2871 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2872}
2873void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2874 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2875}
2876void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2877 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2878}
2879void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2880 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2881 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2882 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
John McCall86acc2a2009-10-23 01:28:53 +00002883 TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
John McCall51bd8032009-10-18 01:05:36 +00002884 }
2885}
2886void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2887 VisitFunctionTypeLoc(TL);
2888}
2889void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2890 VisitFunctionTypeLoc(TL);
2891}
John McCalled976492009-12-04 22:46:56 +00002892void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2893 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2894}
John McCall51bd8032009-10-18 01:05:36 +00002895void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2896 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2897}
2898void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
John McCallcfb708c2010-01-13 20:03:27 +00002899 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2900 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2901 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall51bd8032009-10-18 01:05:36 +00002902}
2903void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
John McCallcfb708c2010-01-13 20:03:27 +00002904 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2905 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2906 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Sebastian Redl577d4792010-07-22 22:43:28 +00002907 TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002908}
2909void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2910 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2911}
2912void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2913 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2914}
2915void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2916 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2917}
John McCall51bd8032009-10-18 01:05:36 +00002918void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2919 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2920}
John McCall49a832b2009-10-18 09:09:24 +00002921void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2922 SubstTemplateTypeParmTypeLoc TL) {
2923 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2924}
John McCall51bd8032009-10-18 01:05:36 +00002925void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2926 TemplateSpecializationTypeLoc TL) {
John McCall833ca992009-10-29 08:12:44 +00002927 TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2928 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2929 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2930 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2931 TL.setArgLocInfo(i,
2932 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00002933 DeclsCursor, Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002934}
Abramo Bagnara465d41b2010-05-11 21:36:43 +00002935void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00002936 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2937 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002938}
John McCall3cb0ebd2010-03-10 03:28:59 +00002939void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
2940 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2941}
Douglas Gregor4714c122010-03-31 17:34:00 +00002942void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00002943 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2944 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002945 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2946}
John McCall33500952010-06-11 00:33:02 +00002947void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
2948 DependentTemplateSpecializationTypeLoc TL) {
2949 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2950 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
2951 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2952 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2953 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2954 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
2955 TL.setArgLocInfo(I,
2956 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00002957 DeclsCursor, Record, Idx));
John McCall33500952010-06-11 00:33:02 +00002958}
John McCall51bd8032009-10-18 01:05:36 +00002959void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2960 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCallc12c5bb2010-05-15 11:32:37 +00002961}
2962void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
2963 TL.setHasBaseTypeAsWritten(Record[Idx++]);
John McCall51bd8032009-10-18 01:05:36 +00002964 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2965 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2966 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2967 TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002968}
John McCall54e14c42009-10-22 22:37:11 +00002969void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2970 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall54e14c42009-10-22 22:37:11 +00002971}
John McCalla1ee0c52009-10-16 21:56:05 +00002972
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002973TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00002974 const RecordData &Record,
John McCalla1ee0c52009-10-16 21:56:05 +00002975 unsigned &Idx) {
2976 QualType InfoTy = GetType(Record[Idx++]);
2977 if (InfoTy.isNull())
2978 return 0;
2979
John McCalla93c9342009-12-07 02:54:59 +00002980 TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
Sebastian Redl577d4792010-07-22 22:43:28 +00002981 TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
John McCalla93c9342009-12-07 02:54:59 +00002982 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
John McCalla1ee0c52009-10-16 21:56:05 +00002983 TLR.Visit(TL);
John McCalla93c9342009-12-07 02:54:59 +00002984 return TInfo;
John McCalla1ee0c52009-10-16 21:56:05 +00002985}
Douglas Gregor2cf26342009-04-09 22:27:44 +00002986
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002987QualType ASTReader::GetType(TypeID ID) {
John McCall0953e762009-09-24 19:53:00 +00002988 unsigned FastQuals = ID & Qualifiers::FastMask;
2989 unsigned Index = ID >> Qualifiers::FastWidth;
Douglas Gregor2cf26342009-04-09 22:27:44 +00002990
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002991 if (Index < NUM_PREDEF_TYPE_IDS) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00002992 QualType T;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002993 switch ((PredefinedTypeIDs)Index) {
2994 case PREDEF_TYPE_NULL_ID: return QualType();
2995 case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
2996 case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00002997
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002998 case PREDEF_TYPE_CHAR_U_ID:
2999 case PREDEF_TYPE_CHAR_S_ID:
Douglas Gregor2cf26342009-04-09 22:27:44 +00003000 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003001 T = Context->CharTy;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003002 break;
3003
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003004 case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
3005 case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
3006 case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
3007 case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
3008 case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
3009 case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
3010 case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
3011 case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
3012 case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
3013 case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
3014 case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
3015 case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
3016 case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
3017 case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
3018 case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
3019 case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
3020 case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
3021 case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
3022 case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
3023 case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
3024 case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
3025 case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
3026 case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
3027 case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003028 }
3029
3030 assert(!T.isNull() && "Unknown predefined type");
John McCall0953e762009-09-24 19:53:00 +00003031 return T.withFastQualifiers(FastQuals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003032 }
3033
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003034 Index -= NUM_PREDEF_TYPE_IDS;
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00003035 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Sebastian Redl07a353c2010-07-14 20:26:45 +00003036 if (TypesLoaded[Index].isNull()) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00003037 TypesLoaded[Index] = ReadTypeRecord(Index);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003038 TypesLoaded[Index]->setFromAST();
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +00003039 TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003040 if (DeserializationListener)
Argyrios Kyrtzidisc8e5d512010-08-20 16:03:59 +00003041 DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
Sebastian Redl1476ed42010-07-16 16:36:56 +00003042 TypesLoaded[Index]);
Sebastian Redl07a353c2010-07-14 20:26:45 +00003043 }
Mike Stump1eb44332009-09-09 15:08:12 +00003044
John McCall0953e762009-09-24 19:53:00 +00003045 return TypesLoaded[Index].withFastQualifiers(FastQuals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003046}
3047
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +00003048TypeID ASTReader::GetTypeID(QualType T) const {
3049 return MakeTypeID(T,
3050 std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
3051}
3052
3053TypeIdx ASTReader::GetTypeIdx(QualType T) const {
3054 if (T.isNull())
3055 return TypeIdx();
3056 assert(!T.getLocalFastQualifiers());
3057
3058 TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3059 // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
3060 // comparing keys of ASTDeclContextNameLookupTable.
3061 // If the type didn't come from the AST file use a specially marked index
3062 // so that any hash/key comparison fail since no such index is stored
3063 // in a AST file.
3064 if (I == TypeIdxs.end())
3065 return TypeIdx(-1);
3066 return I->second;
3067}
3068
John McCall833ca992009-10-29 08:12:44 +00003069TemplateArgumentLocInfo
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003070ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
Sebastian Redl577d4792010-07-22 22:43:28 +00003071 llvm::BitstreamCursor &DeclsCursor,
John McCall833ca992009-10-29 08:12:44 +00003072 const RecordData &Record,
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00003073 unsigned &Index) {
John McCall833ca992009-10-29 08:12:44 +00003074 switch (Kind) {
3075 case TemplateArgument::Expression:
Sebastian Redl577d4792010-07-22 22:43:28 +00003076 return ReadExpr(DeclsCursor);
John McCall833ca992009-10-29 08:12:44 +00003077 case TemplateArgument::Type:
Sebastian Redl577d4792010-07-22 22:43:28 +00003078 return GetTypeSourceInfo(DeclsCursor, Record, Index);
Douglas Gregor788cd062009-11-11 01:00:40 +00003079 case TemplateArgument::Template: {
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003080 SourceRange QualifierRange = ReadSourceRange(Record, Index);
3081 SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
3082 return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
Douglas Gregor788cd062009-11-11 01:00:40 +00003083 }
John McCall833ca992009-10-29 08:12:44 +00003084 case TemplateArgument::Null:
3085 case TemplateArgument::Integral:
3086 case TemplateArgument::Declaration:
3087 case TemplateArgument::Pack:
3088 return TemplateArgumentLocInfo();
3089 }
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +00003090 llvm_unreachable("unexpected template argument loc");
John McCall833ca992009-10-29 08:12:44 +00003091 return TemplateArgumentLocInfo();
3092}
3093
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003094TemplateArgumentLoc
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003095ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00003096 const RecordData &Record, unsigned &Index) {
3097 TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003098
3099 if (Arg.getKind() == TemplateArgument::Expression) {
3100 if (Record[Index++]) // bool InfoHasSameExpr.
3101 return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
3102 }
3103 return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00003104 DeclsCursor,
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00003105 Record, Index));
Argyrios Kyrtzidis44f8c372010-06-22 09:54:59 +00003106}
3107
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003108Decl *ASTReader::GetExternalDecl(uint32_t ID) {
John McCall76bd1f32010-06-01 09:23:16 +00003109 return GetDecl(ID);
3110}
3111
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003112TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
Sebastian Redl30c514c2010-07-14 23:45:08 +00003113 if (!DeclsLoaded[0]) {
Sebastian Redle1dde812010-08-24 00:50:04 +00003114 ReadDeclRecord(0, 1);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003115 if (DeserializationListener)
Sebastian Redl1476ed42010-07-16 16:36:56 +00003116 DeserializationListener->DeclRead(1, DeclsLoaded[0]);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003117 }
Argyrios Kyrtzidis8871a442010-07-08 17:13:02 +00003118
3119 return cast<TranslationUnitDecl>(DeclsLoaded[0]);
3120}
3121
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003122Decl *ASTReader::GetDecl(DeclID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00003123 if (ID == 0)
3124 return 0;
3125
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003126 if (ID > DeclsLoaded.size()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003127 Error("declaration ID out-of-range for AST file");
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003128 return 0;
3129 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003130
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003131 unsigned Index = ID - 1;
Sebastian Redl30c514c2010-07-14 23:45:08 +00003132 if (!DeclsLoaded[Index]) {
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00003133 ReadDeclRecord(Index, ID);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003134 if (DeserializationListener)
3135 DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
3136 }
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003137
3138 return DeclsLoaded[Index];
Douglas Gregor2cf26342009-04-09 22:27:44 +00003139}
3140
Chris Lattner887e2b32009-04-27 05:46:25 +00003141/// \brief Resolve the offset of a statement into a statement.
3142///
3143/// This operation will read a new statement from the external
3144/// source each time it is called, and is meant to be used via a
3145/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003146Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003147 // Offset here is a global offset across the entire chain.
3148 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3149 PerFileData &F = *Chain[N - I - 1];
3150 if (Offset < F.SizeInBits) {
3151 // Since we know that this statement is part of a decl, make sure to use
3152 // the decl cursor to read it.
3153 F.DeclsCursor.JumpToBit(Offset);
3154 return ReadStmtFromStream(F.DeclsCursor);
3155 }
3156 Offset -= F.SizeInBits;
3157 }
3158 llvm_unreachable("Broken chain");
Douglas Gregor250fc9c2009-04-18 00:07:54 +00003159}
3160
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003161bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
John McCall76bd1f32010-06-01 09:23:16 +00003162 llvm::SmallVectorImpl<Decl*> &Decls) {
Mike Stump1eb44332009-09-09 15:08:12 +00003163 assert(DC->hasExternalLexicalStorage() &&
Douglas Gregor2cf26342009-04-09 22:27:44 +00003164 "DeclContext has no lexical decls in storage");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003165
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003166 // There might be lexical decls in multiple parts of the chain, for the TU
3167 // at least.
3168 DeclContextInfos &Infos = DeclContextOffsets[DC];
3169 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3170 I != E; ++I) {
Sebastian Redl681d7232010-07-27 00:17:23 +00003171 // IDs can be 0 if this context doesn't contain declarations.
3172 if (!I->LexicalDecls)
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003173 continue;
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003174
3175 // Load all of the declaration IDs
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003176 for (const DeclID *ID = I->LexicalDecls,
Sebastian Redl681d7232010-07-27 00:17:23 +00003177 *IDE = ID + I->NumLexicalDecls;
3178 ID != IDE; ++ID)
3179 Decls.push_back(GetDecl(*ID));
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003180 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003181
Douglas Gregor25123082009-04-22 22:34:57 +00003182 ++NumLexicalDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003183 return false;
3184}
3185
John McCall76bd1f32010-06-01 09:23:16 +00003186DeclContext::lookup_result
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003187ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
John McCall76bd1f32010-06-01 09:23:16 +00003188 DeclarationName Name) {
Mike Stump1eb44332009-09-09 15:08:12 +00003189 assert(DC->hasExternalVisibleStorage() &&
Douglas Gregor2cf26342009-04-09 22:27:44 +00003190 "DeclContext has no visible decls in storage");
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003191 if (!Name)
3192 return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
3193 DeclContext::lookup_iterator(0));
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003194
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003195 llvm::SmallVector<NamedDecl *, 64> Decls;
Sebastian Redl8b122732010-08-24 00:49:55 +00003196 // There might be visible decls in multiple parts of the chain, for the TU
Sebastian Redl5967d622010-08-24 00:50:16 +00003197 // and namespaces. For any given name, the last available results replace
3198 // all earlier ones. For this reason, we walk in reverse.
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003199 DeclContextInfos &Infos = DeclContextOffsets[DC];
Sebastian Redl5967d622010-08-24 00:50:16 +00003200 for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003201 I != E; ++I) {
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003202 if (!I->NameLookupTableData)
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003203 continue;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003204
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003205 ASTDeclContextNameLookupTable *LookupTable =
3206 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3207 ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
3208 if (Pos == LookupTable->end())
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003209 continue;
3210
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003211 ASTDeclContextNameLookupTrait::data_type Data = *Pos;
3212 for (; Data.first != Data.second; ++Data.first)
3213 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
Sebastian Redl5967d622010-08-24 00:50:16 +00003214 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003215 }
3216
Douglas Gregor25123082009-04-22 22:34:57 +00003217 ++NumVisibleDeclContextsRead;
John McCall76bd1f32010-06-01 09:23:16 +00003218
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003219 SetExternalVisibleDeclsForName(DC, Name, Decls);
John McCall76bd1f32010-06-01 09:23:16 +00003220 return const_cast<DeclContext*>(DC)->lookup(Name);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003221}
3222
Argyrios Kyrtzidisa60786b2010-08-20 23:35:55 +00003223void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
3224 assert(DC->hasExternalVisibleStorage() &&
3225 "DeclContext has no visible decls in storage");
3226
3227 llvm::SmallVector<NamedDecl *, 64> Decls;
3228 // There might be visible decls in multiple parts of the chain, for the TU
3229 // and namespaces.
3230 DeclContextInfos &Infos = DeclContextOffsets[DC];
3231 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3232 I != E; ++I) {
3233 if (!I->NameLookupTableData)
3234 continue;
3235
3236 ASTDeclContextNameLookupTable *LookupTable =
3237 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3238 for (ASTDeclContextNameLookupTable::item_iterator
3239 ItemI = LookupTable->item_begin(),
3240 ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
3241 ASTDeclContextNameLookupTable::item_iterator::value_type Val
3242 = *ItemI;
3243 ASTDeclContextNameLookupTrait::data_type Data = Val.second;
3244 Decls.clear();
3245 for (; Data.first != Data.second; ++Data.first)
3246 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
3247 MaterializeVisibleDeclsForName(DC, Val.first, Decls);
3248 }
3249 }
3250}
3251
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003252void ASTReader::PassInterestingDeclsToConsumer() {
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003253 assert(Consumer);
3254 while (!InterestingDecls.empty()) {
3255 DeclGroupRef DG(InterestingDecls.front());
3256 InterestingDecls.pop_front();
Sebastian Redl27372b42010-08-11 18:52:41 +00003257 Consumer->HandleInterestingDecl(DG);
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003258 }
3259}
3260
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003261void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregor0af2ca42009-04-22 19:09:20 +00003262 this->Consumer = Consumer;
3263
Douglas Gregorfdd01722009-04-14 00:24:19 +00003264 if (!Consumer)
3265 return;
3266
3267 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003268 // Force deserialization of this decl, which will cause it to be queued for
3269 // passing to the consumer.
Daniel Dunbar04a0b502009-09-17 03:06:44 +00003270 GetDecl(ExternalDefinitions[I]);
Douglas Gregorfdd01722009-04-14 00:24:19 +00003271 }
Douglas Gregorc62a2fe2009-04-25 00:41:30 +00003272
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003273 PassInterestingDeclsToConsumer();
Douglas Gregorfdd01722009-04-14 00:24:19 +00003274}
3275
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003276void ASTReader::PrintStats() {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003277 std::fprintf(stderr, "*** AST File Statistics:\n");
Douglas Gregor2cf26342009-04-09 22:27:44 +00003278
Mike Stump1eb44332009-09-09 15:08:12 +00003279 unsigned NumTypesLoaded
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003280 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
John McCall0953e762009-09-24 19:53:00 +00003281 QualType());
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003282 unsigned NumDeclsLoaded
3283 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
3284 (Decl *)0);
3285 unsigned NumIdentifiersLoaded
3286 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
3287 IdentifiersLoaded.end(),
3288 (IdentifierInfo *)0);
Mike Stump1eb44332009-09-09 15:08:12 +00003289 unsigned NumSelectorsLoaded
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003290 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
3291 SelectorsLoaded.end(),
3292 Selector());
Douglas Gregor2d41cc12009-04-13 20:50:16 +00003293
Douglas Gregor4fed3f42009-04-27 18:38:38 +00003294 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
3295 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00003296 if (TotalNumSLocEntries)
3297 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
3298 NumSLocEntriesRead, TotalNumSLocEntries,
3299 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003300 if (!TypesLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003301 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003302 NumTypesLoaded, (unsigned)TypesLoaded.size(),
3303 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
3304 if (!DeclsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003305 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003306 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
3307 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003308 if (!IdentifiersLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003309 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003310 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
3311 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Sebastian Redl725cd962010-08-04 20:40:17 +00003312 if (!SelectorsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003313 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
Sebastian Redl725cd962010-08-04 20:40:17 +00003314 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
3315 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
Douglas Gregor83941df2009-04-25 17:48:32 +00003316 if (TotalNumStatements)
3317 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
3318 NumStatementsRead, TotalNumStatements,
3319 ((float)NumStatementsRead/TotalNumStatements * 100));
3320 if (TotalNumMacros)
3321 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
3322 NumMacrosRead, TotalNumMacros,
3323 ((float)NumMacrosRead/TotalNumMacros * 100));
3324 if (TotalLexicalDeclContexts)
3325 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
3326 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
3327 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
3328 * 100));
3329 if (TotalVisibleDeclContexts)
3330 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
3331 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
3332 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
3333 * 100));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003334 if (TotalNumMethodPoolEntries) {
Douglas Gregor83941df2009-04-25 17:48:32 +00003335 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003336 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
3337 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
Douglas Gregor83941df2009-04-25 17:48:32 +00003338 * 100));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003339 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
Douglas Gregor83941df2009-04-25 17:48:32 +00003340 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003341 std::fprintf(stderr, "\n");
3342}
3343
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003344void ASTReader::InitializeSema(Sema &S) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00003345 SemaObj = &S;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003346 S.ExternalSource = this;
3347
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00003348 // Makes sure any declarations that were deserialized "too early"
3349 // still get added to the identifier's declaration chains.
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003350 if (SemaObj->TUScope) {
3351 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
John McCalld226f652010-08-21 09:40:31 +00003352 SemaObj->TUScope->AddDecl(PreloadedDecls[I]);
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003353 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
3354 }
Douglas Gregor668c1a42009-04-21 22:25:48 +00003355 }
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00003356 PreloadedDecls.clear();
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003357
3358 // If there were any tentative definitions, deserialize them and add
Sebastian Redle9d12b62010-01-31 22:27:38 +00003359 // them to Sema's list of tentative definitions.
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003360 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
3361 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
Sebastian Redle9d12b62010-01-31 22:27:38 +00003362 SemaObj->TentativeDefinitions.push_back(Var);
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003363 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00003364
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00003365 // If there were any unused file scoped decls, deserialize them and add to
3366 // Sema's list of unused file scoped decls.
3367 for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
3368 DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
3369 SemaObj->UnusedFileScopedDecls.push_back(D);
Tanya Lattnere6bbc012010-02-12 00:07:30 +00003370 }
Douglas Gregor14c22f22009-04-22 22:18:58 +00003371
Argyrios Kyrtzidis72b90572010-08-05 09:48:08 +00003372 // If there were any weak undeclared identifiers, deserialize them and add to
3373 // Sema's list of weak undeclared identifiers.
3374 if (!WeakUndeclaredIdentifiers.empty()) {
3375 unsigned Idx = 0;
3376 for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
3377 IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3378 IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3379 SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
3380 bool Used = WeakUndeclaredIdentifiers[Idx++];
3381 Sema::WeakInfo WI(AliasId, Loc);
3382 WI.setUsed(Used);
3383 SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
3384 }
3385 }
3386
Douglas Gregor14c22f22009-04-22 22:18:58 +00003387 // If there were any locally-scoped external declarations,
3388 // deserialize them and add them to Sema's table of locally-scoped
3389 // external declarations.
3390 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
3391 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
3392 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
3393 }
Douglas Gregorb81c1702009-04-27 20:06:05 +00003394
3395 // If there were any ext_vector type declarations, deserialize them
3396 // and add them to Sema's vector of such declarations.
3397 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
3398 SemaObj->ExtVectorDecls.push_back(
3399 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00003400
3401 // FIXME: Do VTable uses and dynamic classes deserialize too much ?
3402 // Can we cut them down before writing them ?
3403
3404 // If there were any VTable uses, deserialize the information and add it
3405 // to Sema's vector and map of VTable uses.
Argyrios Kyrtzidisbe4ebcd2010-08-03 17:29:52 +00003406 if (!VTableUses.empty()) {
3407 unsigned Idx = 0;
3408 for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
3409 CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
3410 SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
3411 bool DefinitionRequired = VTableUses[Idx++];
3412 SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
3413 SemaObj->VTablesUsed[Class] = DefinitionRequired;
3414 }
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00003415 }
3416
3417 // If there were any dynamic classes declarations, deserialize them
3418 // and add them to Sema's vector of such declarations.
3419 for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
3420 SemaObj->DynamicClasses.push_back(
3421 cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
Fariborz Jahanian32019832010-07-23 19:11:11 +00003422
Argyrios Kyrtzidis0e036382010-08-05 09:48:16 +00003423 // If there were any pending implicit instantiations, deserialize them
3424 // and add them to Sema's queue of such instantiations.
3425 assert(PendingImplicitInstantiations.size() % 2 == 0 &&
3426 "Expected pairs of entries");
3427 for (unsigned Idx = 0, N = PendingImplicitInstantiations.size(); Idx < N;) {
3428 ValueDecl *D=cast<ValueDecl>(GetDecl(PendingImplicitInstantiations[Idx++]));
3429 SourceLocation Loc = ReadSourceLocation(PendingImplicitInstantiations, Idx);
3430 SemaObj->PendingImplicitInstantiations.push_back(std::make_pair(D, Loc));
3431 }
3432
Argyrios Kyrtzidis76c38d32010-08-02 07:14:54 +00003433 // Load the offsets of the declarations that Sema references.
3434 // They will be lazily deserialized when needed.
3435 if (!SemaDeclRefs.empty()) {
3436 assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
3437 SemaObj->StdNamespace = SemaDeclRefs[0];
3438 SemaObj->StdBadAlloc = SemaDeclRefs[1];
3439 }
3440
Fariborz Jahanian32019832010-07-23 19:11:11 +00003441 // If there are @selector references added them to its pool. This is for
3442 // implementation of -Wselector.
Sebastian Redl725cd962010-08-04 20:40:17 +00003443 if (!ReferencedSelectorsData.empty()) {
3444 unsigned int DataSize = ReferencedSelectorsData.size()-1;
Fariborz Jahanian32019832010-07-23 19:11:11 +00003445 unsigned I = 0;
3446 while (I < DataSize) {
Sebastian Redl725cd962010-08-04 20:40:17 +00003447 Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
Fariborz Jahanian32019832010-07-23 19:11:11 +00003448 SourceLocation SelLoc =
Sebastian Redl725cd962010-08-04 20:40:17 +00003449 SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
Fariborz Jahanian32019832010-07-23 19:11:11 +00003450 SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
3451 }
3452 }
Douglas Gregor668c1a42009-04-21 22:25:48 +00003453}
3454
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003455IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003456 // Try to find this name within our on-disk hash tables. We start with the
3457 // most recent one, since that one contains the most up-to-date info.
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003458 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003459 ASTIdentifierLookupTable *IdTable
3460 = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003461 if (!IdTable)
3462 continue;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003463 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003464 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003465 if (Pos == IdTable->end())
3466 continue;
Douglas Gregor668c1a42009-04-21 22:25:48 +00003467
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003468 // Dereferencing the iterator has the effect of building the
3469 // IdentifierInfo node and populating it with the various
3470 // declarations it needs.
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003471 return *Pos;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003472 }
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003473 return 0;
Douglas Gregor668c1a42009-04-21 22:25:48 +00003474}
3475
Mike Stump1eb44332009-09-09 15:08:12 +00003476std::pair<ObjCMethodList, ObjCMethodList>
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003477ASTReader::ReadMethodPool(Selector Sel) {
Sebastian Redl725cd962010-08-04 20:40:17 +00003478 // Find this selector in a hash table. We want to find the most recent entry.
3479 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3480 PerFileData &F = *Chain[I];
3481 if (!F.SelectorLookupTable)
3482 continue;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003483
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003484 ASTSelectorLookupTable *PoolTable
3485 = (ASTSelectorLookupTable*)F.SelectorLookupTable;
3486 ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
Sebastian Redl725cd962010-08-04 20:40:17 +00003487 if (Pos != PoolTable->end()) {
3488 ++NumSelectorsRead;
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003489 // FIXME: Not quite happy with the statistics here. We probably should
3490 // disable this tracking when called via LoadSelector.
3491 // Also, should entries without methods count as misses?
3492 ++NumMethodPoolEntriesRead;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003493 ASTSelectorLookupTrait::data_type Data = *Pos;
Sebastian Redl725cd962010-08-04 20:40:17 +00003494 if (DeserializationListener)
3495 DeserializationListener->SelectorRead(Data.ID, Sel);
3496 return std::make_pair(Data.Instance, Data.Factory);
3497 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003498 }
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003499
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003500 ++NumMethodPoolMisses;
Sebastian Redl725cd962010-08-04 20:40:17 +00003501 return std::pair<ObjCMethodList, ObjCMethodList>();
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003502}
3503
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003504void ASTReader::LoadSelector(Selector Sel) {
Sebastian Redle58aa892010-08-04 18:21:41 +00003505 // It would be complicated to avoid reading the methods anyway. So don't.
3506 ReadMethodPool(Sel);
3507}
3508
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003509void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00003510 assert(ID && "Non-zero identifier ID required");
Douglas Gregora02b1472009-04-28 21:53:25 +00003511 assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003512 IdentifiersLoaded[ID - 1] = II;
Sebastian Redlf2f0f032010-07-23 23:49:55 +00003513 if (DeserializationListener)
3514 DeserializationListener->IdentifierRead(ID, II);
Douglas Gregor668c1a42009-04-21 22:25:48 +00003515}
3516
Douglas Gregord89275b2009-07-06 18:54:52 +00003517/// \brief Set the globally-visible declarations associated with the given
3518/// identifier.
3519///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003520/// If the AST reader is currently in a state where the given declaration IDs
Mike Stump1eb44332009-09-09 15:08:12 +00003521/// cannot safely be resolved, they are queued until it is safe to resolve
Douglas Gregord89275b2009-07-06 18:54:52 +00003522/// them.
3523///
3524/// \param II an IdentifierInfo that refers to one or more globally-visible
3525/// declarations.
3526///
3527/// \param DeclIDs the set of declaration IDs with the name @p II that are
3528/// visible at global scope.
3529///
3530/// \param Nonrecursive should be true to indicate that the caller knows that
3531/// this call is non-recursive, and therefore the globally-visible declarations
3532/// will not be placed onto the pending queue.
Mike Stump1eb44332009-09-09 15:08:12 +00003533void
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003534ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
Douglas Gregord89275b2009-07-06 18:54:52 +00003535 const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
3536 bool Nonrecursive) {
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00003537 if (NumCurrentElementsDeserializing && !Nonrecursive) {
Douglas Gregord89275b2009-07-06 18:54:52 +00003538 PendingIdentifierInfos.push_back(PendingIdentifierInfo());
3539 PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
3540 PII.II = II;
3541 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
3542 PII.DeclIDs.push_back(DeclIDs[I]);
3543 return;
3544 }
Mike Stump1eb44332009-09-09 15:08:12 +00003545
Douglas Gregord89275b2009-07-06 18:54:52 +00003546 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
3547 NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
3548 if (SemaObj) {
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003549 if (SemaObj->TUScope) {
3550 // Introduce this declaration into the translation-unit scope
3551 // and add it to the declaration chain for this identifier, so
3552 // that (unqualified) name lookup will find it.
John McCalld226f652010-08-21 09:40:31 +00003553 SemaObj->TUScope->AddDecl(D);
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003554 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
3555 }
Douglas Gregord89275b2009-07-06 18:54:52 +00003556 } else {
3557 // Queue this declaration so that it will be added to the
3558 // translation unit scope and identifier's declaration chain
3559 // once a Sema object is known.
3560 PreloadedDecls.push_back(D);
3561 }
3562 }
3563}
3564
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003565IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00003566 if (ID == 0)
3567 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003568
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003569 if (IdentifiersLoaded.empty()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003570 Error("no identifier table in AST file");
Douglas Gregorafaf3082009-04-11 00:14:32 +00003571 return 0;
3572 }
Mike Stump1eb44332009-09-09 15:08:12 +00003573
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003574 assert(PP && "Forgot to set Preprocessor ?");
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003575 ID -= 1;
3576 if (!IdentifiersLoaded[ID]) {
3577 unsigned Index = ID;
3578 const char *Str = 0;
3579 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3580 PerFileData *F = Chain[N - I - 1];
3581 if (Index < F->LocalNumIdentifiers) {
3582 uint32_t Offset = F->IdentifierOffsets[Index];
3583 Str = F->IdentifierTableData + Offset;
3584 break;
3585 }
3586 Index -= F->LocalNumIdentifiers;
3587 }
3588 assert(Str && "Broken Chain");
Douglas Gregord6595a42009-04-25 21:04:17 +00003589
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003590 // All of the strings in the AST file are preceded by a 16-bit length.
3591 // Extract that 16-bit length to avoid having to execute strlen().
Ted Kremenek231bc0b2009-10-23 04:45:31 +00003592 // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
3593 // unsigned integers. This is important to avoid integer overflow when
3594 // we cast them to 'unsigned'.
Ted Kremenekff1ea462009-10-23 03:57:22 +00003595 const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
Douglas Gregor02fc7512009-04-28 20:01:51 +00003596 unsigned StrLen = (((unsigned) StrLenPtr[0])
3597 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003598 IdentifiersLoaded[ID]
Kovarththanan Rajaratnam811f4262010-03-12 10:32:27 +00003599 = &PP->getIdentifierTable().get(Str, StrLen);
Sebastian Redlf2f0f032010-07-23 23:49:55 +00003600 if (DeserializationListener)
3601 DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
Douglas Gregorafaf3082009-04-11 00:14:32 +00003602 }
Mike Stump1eb44332009-09-09 15:08:12 +00003603
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003604 return IdentifiersLoaded[ID];
Douglas Gregor2cf26342009-04-09 22:27:44 +00003605}
3606
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003607void ASTReader::ReadSLocEntry(unsigned ID) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00003608 ReadSLocEntryRecord(ID);
3609}
3610
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003611Selector ASTReader::DecodeSelector(unsigned ID) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003612 if (ID == 0)
3613 return Selector();
Mike Stump1eb44332009-09-09 15:08:12 +00003614
Sebastian Redl725cd962010-08-04 20:40:17 +00003615 if (ID > SelectorsLoaded.size()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003616 Error("selector ID out of range in AST file");
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003617 return Selector();
3618 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003619
Sebastian Redl725cd962010-08-04 20:40:17 +00003620 if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
Douglas Gregor83941df2009-04-25 17:48:32 +00003621 // Load this selector from the selector table.
Sebastian Redl725cd962010-08-04 20:40:17 +00003622 unsigned Idx = ID - 1;
3623 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3624 PerFileData &F = *Chain[N - I - 1];
3625 if (Idx < F.LocalNumSelectors) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003626 ASTSelectorLookupTrait Trait(*this);
Sebastian Redl725cd962010-08-04 20:40:17 +00003627 SelectorsLoaded[ID - 1] =
3628 Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
3629 if (DeserializationListener)
3630 DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
3631 break;
3632 }
3633 Idx -= F.LocalNumSelectors;
3634 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003635 }
3636
Sebastian Redl725cd962010-08-04 20:40:17 +00003637 return SelectorsLoaded[ID - 1];
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003638}
3639
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003640Selector ASTReader::GetExternalSelector(uint32_t ID) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003641 return DecodeSelector(ID);
3642}
3643
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003644uint32_t ASTReader::GetNumExternalSelectors() {
Sebastian Redl725cd962010-08-04 20:40:17 +00003645 // ID 0 (the null selector) is considered an external selector.
3646 return getTotalNumSelectors() + 1;
Douglas Gregor719770d2010-04-06 17:30:22 +00003647}
3648
Mike Stump1eb44332009-09-09 15:08:12 +00003649DeclarationName
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003650ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00003651 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
3652 switch (Kind) {
3653 case DeclarationName::Identifier:
3654 return DeclarationName(GetIdentifierInfo(Record, Idx));
3655
3656 case DeclarationName::ObjCZeroArgSelector:
3657 case DeclarationName::ObjCOneArgSelector:
3658 case DeclarationName::ObjCMultiArgSelector:
Steve Naroffa7503a72009-04-23 15:15:40 +00003659 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003660
3661 case DeclarationName::CXXConstructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003662 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003663 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003664
3665 case DeclarationName::CXXDestructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003666 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003667 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003668
3669 case DeclarationName::CXXConversionFunctionName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003670 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003671 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003672
3673 case DeclarationName::CXXOperatorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003674 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00003675 (OverloadedOperatorKind)Record[Idx++]);
3676
Sean Hunt3e518bd2009-11-29 07:34:05 +00003677 case DeclarationName::CXXLiteralOperatorName:
3678 return Context->DeclarationNames.getCXXLiteralOperatorName(
3679 GetIdentifierInfo(Record, Idx));
3680
Douglas Gregor2cf26342009-04-09 22:27:44 +00003681 case DeclarationName::CXXUsingDirective:
3682 return DeclarationName::getUsingDirectiveName();
3683 }
3684
3685 // Required to silence GCC warning
3686 return DeclarationName();
3687}
Douglas Gregor0a0428e2009-04-10 20:39:37 +00003688
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003689TemplateName
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003690ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003691 TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
3692 switch (Kind) {
3693 case TemplateName::Template:
3694 return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
3695
3696 case TemplateName::OverloadedTemplate: {
3697 unsigned size = Record[Idx++];
3698 UnresolvedSet<8> Decls;
3699 while (size--)
3700 Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
3701
3702 return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
3703 }
3704
3705 case TemplateName::QualifiedTemplate: {
3706 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3707 bool hasTemplKeyword = Record[Idx++];
3708 TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
3709 return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
3710 }
3711
3712 case TemplateName::DependentTemplate: {
3713 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3714 if (Record[Idx++]) // isIdentifier
3715 return Context->getDependentTemplateName(NNS,
3716 GetIdentifierInfo(Record, Idx));
3717 return Context->getDependentTemplateName(NNS,
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003718 (OverloadedOperatorKind)Record[Idx++]);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003719 }
3720 }
3721
3722 assert(0 && "Unhandled template name kind!");
3723 return TemplateName();
3724}
3725
3726TemplateArgument
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003727ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00003728 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003729 switch ((TemplateArgument::ArgKind)Record[Idx++]) {
3730 case TemplateArgument::Null:
3731 return TemplateArgument();
3732 case TemplateArgument::Type:
3733 return TemplateArgument(GetType(Record[Idx++]));
3734 case TemplateArgument::Declaration:
3735 return TemplateArgument(GetDecl(Record[Idx++]));
Argyrios Kyrtzidisdc767e32010-06-28 09:31:34 +00003736 case TemplateArgument::Integral: {
3737 llvm::APSInt Value = ReadAPSInt(Record, Idx);
3738 QualType T = GetType(Record[Idx++]);
3739 return TemplateArgument(Value, T);
3740 }
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003741 case TemplateArgument::Template:
3742 return TemplateArgument(ReadTemplateName(Record, Idx));
3743 case TemplateArgument::Expression:
Sebastian Redl577d4792010-07-22 22:43:28 +00003744 return TemplateArgument(ReadExpr(DeclsCursor));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003745 case TemplateArgument::Pack: {
3746 unsigned NumArgs = Record[Idx++];
3747 llvm::SmallVector<TemplateArgument, 8> Args;
3748 Args.reserve(NumArgs);
3749 while (NumArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00003750 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003751 TemplateArgument TemplArg;
3752 TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
3753 return TemplArg;
3754 }
3755 }
3756
3757 assert(0 && "Unhandled template argument kind!");
3758 return TemplateArgument();
3759}
3760
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003761TemplateParameterList *
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003762ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003763 SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
3764 SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
3765 SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
3766
3767 unsigned NumParams = Record[Idx++];
3768 llvm::SmallVector<NamedDecl *, 16> Params;
3769 Params.reserve(NumParams);
3770 while (NumParams--)
3771 Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
3772
3773 TemplateParameterList* TemplateParams =
3774 TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
3775 Params.data(), Params.size(), RAngleLoc);
3776 return TemplateParams;
3777}
3778
3779void
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003780ASTReader::
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003781ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
Sebastian Redl577d4792010-07-22 22:43:28 +00003782 llvm::BitstreamCursor &DeclsCursor,
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003783 const RecordData &Record, unsigned &Idx) {
3784 unsigned NumTemplateArgs = Record[Idx++];
3785 TemplArgs.reserve(NumTemplateArgs);
3786 while (NumTemplateArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00003787 TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003788}
3789
Argyrios Kyrtzidis37ffed32010-07-02 11:55:32 +00003790/// \brief Read a UnresolvedSet structure.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003791void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
Argyrios Kyrtzidis37ffed32010-07-02 11:55:32 +00003792 const RecordData &Record, unsigned &Idx) {
3793 unsigned NumDecls = Record[Idx++];
3794 while (NumDecls--) {
3795 NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
3796 AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
3797 Set.addDecl(D, AS);
3798 }
3799}
3800
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003801CXXBaseSpecifier
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003802ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
Nick Lewycky56062202010-07-26 16:56:01 +00003803 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003804 bool isVirtual = static_cast<bool>(Record[Idx++]);
3805 bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
3806 AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
Nick Lewycky56062202010-07-26 16:56:01 +00003807 TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003808 SourceRange Range = ReadSourceRange(Record, Idx);
Nick Lewycky56062202010-07-26 16:56:01 +00003809 return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003810}
3811
Argyrios Kyrtzidis8e706f42010-08-09 10:54:12 +00003812std::pair<CXXBaseOrMemberInitializer **, unsigned>
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003813ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
Argyrios Kyrtzidis8e706f42010-08-09 10:54:12 +00003814 const RecordData &Record,
3815 unsigned &Idx) {
3816 CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
3817 unsigned NumInitializers = Record[Idx++];
3818 if (NumInitializers) {
3819 ASTContext &C = *getContext();
3820
3821 BaseOrMemberInitializers
3822 = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
3823 for (unsigned i=0; i != NumInitializers; ++i) {
3824 TypeSourceInfo *BaseClassInfo = 0;
3825 bool IsBaseVirtual = false;
3826 FieldDecl *Member = 0;
3827
3828 bool IsBaseInitializer = Record[Idx++];
3829 if (IsBaseInitializer) {
3830 BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
3831 IsBaseVirtual = Record[Idx++];
3832 } else {
3833 Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
3834 }
3835 SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
3836 Expr *Init = ReadExpr(Cursor);
3837 FieldDecl *AnonUnionMember
3838 = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
3839 SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
3840 SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
3841 bool IsWritten = Record[Idx++];
3842 unsigned SourceOrderOrNumArrayIndices;
3843 llvm::SmallVector<VarDecl *, 8> Indices;
3844 if (IsWritten) {
3845 SourceOrderOrNumArrayIndices = Record[Idx++];
3846 } else {
3847 SourceOrderOrNumArrayIndices = Record[Idx++];
3848 Indices.reserve(SourceOrderOrNumArrayIndices);
3849 for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
3850 Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
3851 }
3852
3853 CXXBaseOrMemberInitializer *BOMInit;
3854 if (IsBaseInitializer) {
3855 BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
3856 IsBaseVirtual, LParenLoc,
3857 Init, RParenLoc);
3858 } else if (IsWritten) {
3859 BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
3860 LParenLoc, Init, RParenLoc);
3861 } else {
3862 BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
3863 LParenLoc, Init, RParenLoc,
3864 Indices.data(),
3865 Indices.size());
3866 }
3867
3868 BOMInit->setAnonUnionMember(AnonUnionMember);
3869 BaseOrMemberInitializers[i] = BOMInit;
3870 }
3871 }
3872
3873 return std::make_pair(BaseOrMemberInitializers, NumInitializers);
3874}
3875
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003876NestedNameSpecifier *
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003877ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003878 unsigned N = Record[Idx++];
3879 NestedNameSpecifier *NNS = 0, *Prev = 0;
3880 for (unsigned I = 0; I != N; ++I) {
3881 NestedNameSpecifier::SpecifierKind Kind
3882 = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
3883 switch (Kind) {
3884 case NestedNameSpecifier::Identifier: {
3885 IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
3886 NNS = NestedNameSpecifier::Create(*Context, Prev, II);
3887 break;
3888 }
3889
3890 case NestedNameSpecifier::Namespace: {
3891 NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
3892 NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
3893 break;
3894 }
3895
3896 case NestedNameSpecifier::TypeSpec:
3897 case NestedNameSpecifier::TypeSpecWithTemplate: {
3898 Type *T = GetType(Record[Idx++]).getTypePtr();
3899 bool Template = Record[Idx++];
3900 NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
3901 break;
3902 }
3903
3904 case NestedNameSpecifier::Global: {
3905 NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
3906 // No associated value, and there can't be a prefix.
3907 break;
3908 }
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003909 }
Argyrios Kyrtzidisd2bb2c02010-07-07 15:46:30 +00003910 Prev = NNS;
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003911 }
3912 return NNS;
3913}
3914
3915SourceRange
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003916ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
Daniel Dunbar8ee59392010-06-02 15:47:10 +00003917 SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
3918 SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
3919 return SourceRange(beg, end);
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003920}
3921
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003922/// \brief Read an integral value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003923llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003924 unsigned BitWidth = Record[Idx++];
3925 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
3926 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
3927 Idx += NumWords;
3928 return Result;
3929}
3930
3931/// \brief Read a signed integral value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003932llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003933 bool isUnsigned = Record[Idx++];
3934 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
3935}
3936
Douglas Gregor17fc2232009-04-14 21:55:33 +00003937/// \brief Read a floating-point value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003938llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregor17fc2232009-04-14 21:55:33 +00003939 return llvm::APFloat(ReadAPInt(Record, Idx));
3940}
3941
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003942// \brief Read a string
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003943std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003944 unsigned Len = Record[Idx++];
Jay Foadbeaaccd2009-05-21 09:52:38 +00003945 std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003946 Idx += Len;
3947 return Result;
3948}
3949
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003950CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
Chris Lattnerd2598362010-05-10 00:25:06 +00003951 unsigned &Idx) {
3952 CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
3953 return CXXTemporary::Create(*Context, Decl);
3954}
3955
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003956DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00003957 return Diag(SourceLocation(), DiagID);
3958}
3959
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003960DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003961 return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
Douglas Gregor0a0428e2009-04-10 20:39:37 +00003962}
Douglas Gregor025452f2009-04-17 00:04:06 +00003963
Douglas Gregor668c1a42009-04-21 22:25:48 +00003964/// \brief Retrieve the identifier table associated with the
3965/// preprocessor.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003966IdentifierTable &ASTReader::getIdentifierTable() {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003967 assert(PP && "Forgot to set Preprocessor ?");
3968 return PP->getIdentifierTable();
Douglas Gregor668c1a42009-04-21 22:25:48 +00003969}
3970
Douglas Gregor025452f2009-04-17 00:04:06 +00003971/// \brief Record that the given ID maps to the given switch-case
3972/// statement.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003973void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Douglas Gregor025452f2009-04-17 00:04:06 +00003974 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
3975 SwitchCaseStmts[ID] = SC;
3976}
3977
3978/// \brief Retrieve the switch-case statement with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003979SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
Douglas Gregor025452f2009-04-17 00:04:06 +00003980 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
3981 return SwitchCaseStmts[ID];
3982}
Douglas Gregor1de05fe2009-04-17 18:18:49 +00003983
3984/// \brief Record that the given label statement has been
3985/// deserialized and has the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003986void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
Mike Stump1eb44332009-09-09 15:08:12 +00003987 assert(LabelStmts.find(ID) == LabelStmts.end() &&
Douglas Gregor1de05fe2009-04-17 18:18:49 +00003988 "Deserialized label twice");
3989 LabelStmts[ID] = S;
3990
3991 // If we've already seen any goto statements that point to this
3992 // label, resolve them now.
3993 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
3994 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
3995 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
3996 Goto->second->setLabel(S);
3997 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00003998
3999 // If we've already seen any address-label statements that point to
4000 // this label, resolve them now.
4001 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
Mike Stump1eb44332009-09-09 15:08:12 +00004002 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004003 = UnresolvedAddrLabelExprs.equal_range(ID);
Mike Stump1eb44332009-09-09 15:08:12 +00004004 for (AddrLabelIter AddrLabel = AddrLabels.first;
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004005 AddrLabel != AddrLabels.second; ++AddrLabel)
4006 AddrLabel->second->setLabel(S);
4007 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor1de05fe2009-04-17 18:18:49 +00004008}
4009
4010/// \brief Set the label of the given statement to the label
4011/// identified by ID.
4012///
4013/// Depending on the order in which the label and other statements
4014/// referencing that label occur, this operation may complete
4015/// immediately (updating the statement) or it may queue the
4016/// statement to be back-patched later.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004017void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
Douglas Gregor1de05fe2009-04-17 18:18:49 +00004018 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4019 if (Label != LabelStmts.end()) {
4020 // We've already seen this label, so set the label of the goto and
4021 // we're done.
4022 S->setLabel(Label->second);
4023 } else {
4024 // We haven't seen this label yet, so add this goto to the set of
4025 // unresolved goto statements.
4026 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
4027 }
4028}
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004029
4030/// \brief Set the label of the given expression to the label
4031/// identified by ID.
4032///
4033/// Depending on the order in which the label and other statements
4034/// referencing that label occur, this operation may complete
4035/// immediately (updating the statement) or it may queue the
4036/// statement to be back-patched later.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004037void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004038 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4039 if (Label != LabelStmts.end()) {
4040 // We've already seen this label, so set the label of the
4041 // label-address expression and we're done.
4042 S->setLabel(Label->second);
4043 } else {
4044 // We haven't seen this label yet, so add this label-address
4045 // expression to the set of unresolved label-address expressions.
4046 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
4047 }
4048}
Douglas Gregord89275b2009-07-06 18:54:52 +00004049
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004050void ASTReader::FinishedDeserializing() {
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004051 assert(NumCurrentElementsDeserializing &&
4052 "FinishedDeserializing not paired with StartedDeserializing");
4053 if (NumCurrentElementsDeserializing == 1) {
Douglas Gregord89275b2009-07-06 18:54:52 +00004054 // If any identifiers with corresponding top-level declarations have
4055 // been loaded, load those declarations now.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004056 while (!PendingIdentifierInfos.empty()) {
4057 SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
4058 PendingIdentifierInfos.front().DeclIDs, true);
4059 PendingIdentifierInfos.pop_front();
Douglas Gregord89275b2009-07-06 18:54:52 +00004060 }
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00004061
4062 // We are not in recursive loading, so it's safe to pass the "interesting"
4063 // decls to the consumer.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004064 if (Consumer)
4065 PassInterestingDeclsToConsumer();
Douglas Gregord89275b2009-07-06 18:54:52 +00004066 }
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004067 --NumCurrentElementsDeserializing;
Douglas Gregord89275b2009-07-06 18:54:52 +00004068}
Douglas Gregor501c1032010-08-19 00:28:17 +00004069
Sebastian Redle1dde812010-08-24 00:50:04 +00004070ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
4071 const char *isysroot, bool DisableValidation)
4072 : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
4073 SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
4074 Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
4075 Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
4076 NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
4077 TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
4078 NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
4079 NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
4080 TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
4081 TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
4082 TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
4083 RelocatablePCH = false;
4084}
4085
4086ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
4087 Diagnostic &Diags, const char *isysroot,
4088 bool DisableValidation)
4089 : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
4090 Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
4091 isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
4092 NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
4093 NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
4094 TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
4095 NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
4096 NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
4097 NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
4098 NumCurrentElementsDeserializing(0) {
4099 RelocatablePCH = false;
4100}
4101
4102ASTReader::~ASTReader() {
4103 for (unsigned i = 0, e = Chain.size(); i != e; ++i)
4104 delete Chain[e - i - 1];
4105 // Delete all visible decl lookup tables
4106 for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
4107 E = DeclContextOffsets.end();
4108 I != E; ++I) {
4109 for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
4110 J != F; ++J) {
4111 if (J->NameLookupTableData)
4112 delete static_cast<ASTDeclContextNameLookupTable*>(
4113 J->NameLookupTableData);
4114 }
4115 }
4116 for (DeclContextVisibleUpdatesPending::iterator
4117 I = PendingVisibleUpdates.begin(),
4118 E = PendingVisibleUpdates.end();
4119 I != E; ++I) {
4120 for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
4121 F = I->second.end();
4122 J != F; ++J)
4123 delete static_cast<ASTDeclContextNameLookupTable*>(*J);
4124 }
4125}
4126
Douglas Gregor501c1032010-08-19 00:28:17 +00004127ASTReader::PerFileData::PerFileData()
4128 : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
4129 LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
4130 IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0),
4131 LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
4132 NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0),
4133 SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0)
4134{}
4135
4136ASTReader::PerFileData::~PerFileData() {
4137 delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
4138 delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
4139}
4140