blob: abe9b16a1a6f5b65e1d74248a0682c27eae9c0c9 [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"
John McCall2a7fb272010-08-25 05:32:35 +000023#include "clang/AST/DeclTemplate.h"
Douglas Gregor0b748912009-04-14 21:18:50 +000024#include "clang/AST/Expr.h"
John McCall7a1fad32010-08-24 07:32:53 +000025#include "clang/AST/ExprCXX.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000026#include "clang/AST/Type.h"
John McCalla1ee0c52009-10-16 21:56:05 +000027#include "clang/AST/TypeLocVisitor.h"
Chris Lattner42d42b52009-04-10 21:41:48 +000028#include "clang/Lex/MacroInfo.h"
Douglas Gregor6a5a23f2010-03-19 21:51:54 +000029#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000030#include "clang/Lex/Preprocessor.h"
Steve Naroff83d63c72009-04-24 20:03:17 +000031#include "clang/Lex/HeaderSearch.h"
Douglas Gregor668c1a42009-04-21 22:25:48 +000032#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000033#include "clang/Basic/SourceManager.h"
Douglas Gregorbd945002009-04-13 16:31:14 +000034#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000035#include "clang/Basic/FileManager.h"
Douglas Gregor2bec0412009-04-10 21:16:55 +000036#include "clang/Basic/TargetInfo.h"
Douglas Gregor445e23e2009-10-05 21:07:28 +000037#include "clang/Basic/Version.h"
Daniel Dunbar2596e422009-10-17 23:52:28 +000038#include "llvm/ADT/StringExtras.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000039#include "llvm/Bitcode/BitstreamReader.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000040#include "llvm/Support/MemoryBuffer.h"
John McCall833ca992009-10-29 08:12:44 +000041#include "llvm/Support/ErrorHandling.h"
Daniel Dunbard5b21972009-11-18 19:50:41 +000042#include "llvm/System/Path.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000043#include <algorithm>
Douglas Gregore721f952009-04-28 18:58:38 +000044#include <iterator>
Douglas Gregor2cf26342009-04-09 22:27:44 +000045#include <cstdio>
Douglas Gregor4fed3f42009-04-27 18:38:38 +000046#include <sys/stat.h>
Douglas Gregor2cf26342009-04-09 22:27:44 +000047using namespace clang;
Sebastian Redl8538e8d2010-08-18 23:57:32 +000048using namespace clang::serialization;
Douglas Gregor2cf26342009-04-09 22:27:44 +000049
50//===----------------------------------------------------------------------===//
Sebastian Redl3c7f4132010-08-18 23:57:06 +000051// PCH validator implementation
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000052//===----------------------------------------------------------------------===//
53
Sebastian Redl571db7f2010-08-18 23:56:56 +000054ASTReaderListener::~ASTReaderListener() {}
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000055
56bool
57PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
58 const LangOptions &PPLangOpts = PP.getLangOptions();
59#define PARSE_LANGOPT_BENIGN(Option)
60#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
61 if (PPLangOpts.Option != LangOpts.Option) { \
62 Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
63 return true; \
64 }
65
66 PARSE_LANGOPT_BENIGN(Trigraphs);
67 PARSE_LANGOPT_BENIGN(BCPLComment);
68 PARSE_LANGOPT_BENIGN(DollarIdents);
69 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
70 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
Chandler Carrutheb5d7b72010-04-17 20:17:31 +000071 PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000072 PARSE_LANGOPT_BENIGN(ImplicitInt);
73 PARSE_LANGOPT_BENIGN(Digraphs);
74 PARSE_LANGOPT_BENIGN(HexFloats);
75 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
76 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
77 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
78 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
79 PARSE_LANGOPT_BENIGN(CXXOperatorName);
80 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
81 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
82 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
Fariborz Jahanian412e7982010-02-09 19:31:38 +000083 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
Fariborz Jahanian4c9d8d02010-04-22 21:01:59 +000084 PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
85 diag::warn_pch_no_constant_cfstrings);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000086 PARSE_LANGOPT_BENIGN(PascalStrings);
87 PARSE_LANGOPT_BENIGN(WritableStrings);
Mike Stump1eb44332009-09-09 15:08:12 +000088 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000089 diag::warn_pch_lax_vector_conversions);
Nate Begeman69cfb9b2009-06-25 22:57:40 +000090 PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000091 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
Daniel Dunbar73482882010-02-10 18:48:44 +000092 PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000093 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
94 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
95 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
Mike Stump1eb44332009-09-09 15:08:12 +000096 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000097 diag::warn_pch_thread_safe_statics);
Daniel Dunbar5345c392009-09-03 04:54:28 +000098 PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +000099 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
100 PARSE_LANGOPT_BENIGN(EmitAllDecls);
101 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
Chris Lattnera4d71452010-06-26 21:25:03 +0000102 PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
Mike Stump1eb44332009-09-09 15:08:12 +0000103 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000104 diag::warn_pch_heinous_extensions);
105 // FIXME: Most of the options below are benign if the macro wasn't
106 // used. Unfortunately, this means that a PCH compiled without
107 // optimization can't be used with optimization turned on, even
108 // though the only thing that changes is whether __OPTIMIZE__ was
109 // defined... but if __OPTIMIZE__ never showed up in the header, it
110 // doesn't matter. We could consider making this some special kind
111 // of check.
112 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
113 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
114 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
115 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
116 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
117 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
118 PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
119 PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
John Thompsona6fda122009-11-05 20:14:16 +0000120 PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000121 if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000122 Reader.Diag(diag::warn_pch_gc_mode)
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000123 << LangOpts.getGCMode() << PPLangOpts.getGCMode();
124 return true;
125 }
126 PARSE_LANGOPT_BENIGN(getVisibilityMode());
Daniel Dunbarab8e2812009-09-21 04:16:19 +0000127 PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
128 diag::warn_pch_stack_protector);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000129 PARSE_LANGOPT_BENIGN(InstantiationDepth);
Nate Begeman69cfb9b2009-06-25 22:57:40 +0000130 PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
Mike Stump9c276ae2009-12-12 01:27:46 +0000131 PARSE_LANGOPT_BENIGN(CatchUndefined);
Daniel Dunbarab8e2812009-09-21 04:16:19 +0000132 PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
Douglas Gregora0068fc2010-07-09 17:35:33 +0000133 PARSE_LANGOPT_BENIGN(SpellChecking);
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +0000134#undef PARSE_LANGOPT_IMPORTANT
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000135#undef PARSE_LANGOPT_BENIGN
136
137 return false;
138}
139
Daniel Dunbardc3c0d22009-11-11 00:52:11 +0000140bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
141 if (Triple == PP.getTargetInfo().getTriple().str())
142 return false;
143
144 Reader.Diag(diag::warn_pch_target_triple)
145 << Triple << PP.getTargetInfo().getTriple().str();
146 return true;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000147}
148
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000149struct EmptyStringRef {
Benjamin Kramerec1b1cc2010-07-14 23:19:41 +0000150 bool operator ()(llvm::StringRef r) const { return r.empty(); }
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000151};
152struct EmptyBlock {
153 bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); }
154};
155
156static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
157 PCHPredefinesBlocks R) {
158 // First, sum up the lengths.
159 unsigned LL = 0, RL = 0;
160 for (unsigned I = 0, N = L.size(); I != N; ++I) {
161 LL += L[I].size();
162 }
163 for (unsigned I = 0, N = R.size(); I != N; ++I) {
164 RL += R[I].Data.size();
165 }
166 if (LL != RL)
167 return false;
168 if (LL == 0 && RL == 0)
169 return true;
170
171 // Kick out empty parts, they confuse the algorithm below.
172 L.erase(std::remove_if(L.begin(), L.end(), EmptyStringRef()), L.end());
173 R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
174
175 // Do it the hard way. At this point, both vectors must be non-empty.
176 llvm::StringRef LR = L[0], RR = R[0].Data;
177 unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
Daniel Dunbarc76c9e02010-07-16 00:00:11 +0000178 (void) RN;
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000179 for (;;) {
180 // Compare the current pieces.
181 if (LR.size() == RR.size()) {
182 // If they're the same length, it's pretty easy.
183 if (LR != RR)
184 return false;
185 // Both pieces are done, advance.
186 ++LI;
187 ++RI;
188 // If either string is done, they're both done, since they're the same
189 // length.
190 if (LI == LN) {
191 assert(RI == RN && "Strings not the same length after all?");
192 return true;
193 }
194 LR = L[LI];
195 RR = R[RI].Data;
196 } else if (LR.size() < RR.size()) {
197 // Right piece is longer.
198 if (!RR.startswith(LR))
199 return false;
200 ++LI;
201 assert(LI != LN && "Strings not the same length after all?");
202 RR = RR.substr(LR.size());
203 LR = L[LI];
204 } else {
205 // Left piece is longer.
206 if (!LR.startswith(RR))
207 return false;
208 ++RI;
209 assert(RI != RN && "Strings not the same length after all?");
210 LR = LR.substr(RR.size());
211 RR = R[RI].Data;
212 }
213 }
214}
215
216static std::pair<FileID, llvm::StringRef::size_type>
217FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
218 std::pair<FileID, llvm::StringRef::size_type> Res;
219 for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
220 Res.second = Buffers[I].Data.find(MacroDef);
221 if (Res.second != llvm::StringRef::npos) {
222 Res.first = Buffers[I].BufferID;
223 break;
224 }
225 }
226 return Res;
227}
228
229bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000230 llvm::StringRef OriginalFileName,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000231 std::string &SuggestedPredefines) {
Daniel Dunbarc7162932009-11-11 23:58:53 +0000232 // We are in the context of an implicit include, so the predefines buffer will
233 // have a #include entry for the PCH file itself (as normalized by the
234 // preprocessor initialization). Find it and skip over it in the checking
235 // below.
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000236 llvm::SmallString<256> PCHInclude;
237 PCHInclude += "#include \"";
Daniel Dunbarc7162932009-11-11 23:58:53 +0000238 PCHInclude += NormalizeDashIncludePath(OriginalFileName);
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000239 PCHInclude += "\"\n";
240 std::pair<llvm::StringRef,llvm::StringRef> Split =
241 llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
242 llvm::StringRef Left = Split.first, Right = Split.second;
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +0000243 if (Left == PP.getPredefines()) {
244 Error("Missing PCH include entry!");
245 return true;
246 }
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000247
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000248 // If the concatenation of all the PCH buffers is equal to the adjusted
249 // command line, we're done.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000250 llvm::SmallVector<llvm::StringRef, 2> CommandLine;
251 CommandLine.push_back(Left);
252 CommandLine.push_back(Right);
253 if (EqualConcatenations(CommandLine, Buffers))
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000254 return false;
255
256 SourceManager &SourceMgr = PP.getSourceManager();
Mike Stump1eb44332009-09-09 15:08:12 +0000257
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000258 // The predefines buffers are different. Determine what the differences are,
259 // and whether they require us to reject the PCH file.
Daniel Dunbare6750492009-11-13 16:46:11 +0000260 llvm::SmallVector<llvm::StringRef, 8> PCHLines;
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000261 for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
262 Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Daniel Dunbare6750492009-11-13 16:46:11 +0000263
264 llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
265 Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
266 Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000267
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000268 // Sort both sets of predefined buffer lines, since we allow some extra
269 // definitions and they may appear at any point in the output.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000270 std::sort(CmdLineLines.begin(), CmdLineLines.end());
271 std::sort(PCHLines.begin(), PCHLines.end());
272
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000273 // Determine which predefines that were used to build the PCH file are missing
274 // from the command line.
275 std::vector<llvm::StringRef> MissingPredefines;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000276 std::set_difference(PCHLines.begin(), PCHLines.end(),
277 CmdLineLines.begin(), CmdLineLines.end(),
278 std::back_inserter(MissingPredefines));
279
280 bool MissingDefines = false;
281 bool ConflictingDefines = false;
282 for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000283 llvm::StringRef Missing = MissingPredefines[I];
284 if (!Missing.startswith("#define ")) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000285 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
286 return true;
287 }
Mike Stump1eb44332009-09-09 15:08:12 +0000288
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000289 // This is a macro definition. Determine the name of the macro we're
290 // defining.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000291 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump1eb44332009-09-09 15:08:12 +0000292 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000293 = Missing.find_first_of("( \n\r", StartOfMacroName);
294 assert(EndOfMacroName != std::string::npos &&
295 "Couldn't find the end of the macro name");
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000296 llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000297
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000298 // Determine whether this macro was given a different definition on the
299 // command line.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000300 std::string MacroDefStart = "#define " + MacroName.str();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000301 std::string::size_type MacroDefLen = MacroDefStart.size();
Daniel Dunbare6750492009-11-13 16:46:11 +0000302 llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000303 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
304 MacroDefStart);
305 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000306 if (!ConflictPos->startswith(MacroDefStart)) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000307 // Different macro; we're done.
308 ConflictPos = CmdLineLines.end();
Mike Stump1eb44332009-09-09 15:08:12 +0000309 break;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000310 }
Mike Stump1eb44332009-09-09 15:08:12 +0000311
312 assert(ConflictPos->size() > MacroDefLen &&
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000313 "Invalid #define in predefines buffer?");
Mike Stump1eb44332009-09-09 15:08:12 +0000314 if ((*ConflictPos)[MacroDefLen] != ' ' &&
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000315 (*ConflictPos)[MacroDefLen] != '(')
316 continue; // Longer macro name; keep trying.
Mike Stump1eb44332009-09-09 15:08:12 +0000317
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000318 // We found a conflicting macro definition.
319 break;
320 }
Mike Stump1eb44332009-09-09 15:08:12 +0000321
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000322 if (ConflictPos != CmdLineLines.end()) {
323 Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
324 << MacroName;
325
326 // Show the definition of this macro within the PCH file.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000327 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
328 FindMacro(Buffers, Missing);
329 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
330 SourceLocation PCHMissingLoc =
331 SourceMgr.getLocForStartOfFile(MacroLoc.first)
332 .getFileLocWithOffset(MacroLoc.second);
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000333 Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000334
335 ConflictingDefines = true;
336 continue;
337 }
Mike Stump1eb44332009-09-09 15:08:12 +0000338
Daniel Dunbar10014aa2009-11-11 03:45:59 +0000339 // If the macro doesn't conflict, then we'll just pick up the macro
340 // definition from the PCH file. Warn the user that they made a mistake.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000341 if (ConflictingDefines)
342 continue; // Don't complain if there are already conflicting defs
Mike Stump1eb44332009-09-09 15:08:12 +0000343
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000344 if (!MissingDefines) {
345 Reader.Diag(diag::warn_cmdline_missing_macro_defs);
346 MissingDefines = true;
347 }
348
349 // Show the definition of this macro within the PCH file.
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000350 std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
351 FindMacro(Buffers, Missing);
352 assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
353 SourceLocation PCHMissingLoc =
354 SourceMgr.getLocForStartOfFile(MacroLoc.first)
355 .getFileLocWithOffset(MacroLoc.second);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000356 Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
357 }
Mike Stump1eb44332009-09-09 15:08:12 +0000358
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000359 if (ConflictingDefines)
360 return true;
Mike Stump1eb44332009-09-09 15:08:12 +0000361
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000362 // Determine what predefines were introduced based on command-line
363 // parameters that were not present when building the PCH
364 // file. Extra #defines are okay, so long as the identifiers being
365 // defined were not used within the precompiled header.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000366 std::vector<llvm::StringRef> ExtraPredefines;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000367 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
368 PCHLines.begin(), PCHLines.end(),
Mike Stump1eb44332009-09-09 15:08:12 +0000369 std::back_inserter(ExtraPredefines));
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000370 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000371 llvm::StringRef &Extra = ExtraPredefines[I];
372 if (!Extra.startswith("#define ")) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000373 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
374 return true;
375 }
376
377 // This is an extra macro definition. Determine the name of the
378 // macro we're defining.
379 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump1eb44332009-09-09 15:08:12 +0000380 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000381 = Extra.find_first_of("( \n\r", StartOfMacroName);
382 assert(EndOfMacroName != std::string::npos &&
383 "Couldn't find the end of the macro name");
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000384 llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000385
386 // Check whether this name was used somewhere in the PCH file. If
387 // so, defining it as a macro could change behavior, so we reject
388 // the PCH file.
Daniel Dunbar4d5936a2009-11-11 05:26:28 +0000389 if (IdentifierInfo *II = Reader.get(MacroName)) {
Daniel Dunbar4fda42e2009-11-11 00:52:00 +0000390 Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000391 return true;
392 }
393
394 // Add this definition to the suggested predefines buffer.
395 SuggestedPredefines += Extra;
396 SuggestedPredefines += '\n';
397 }
398
399 // If we get here, it's because the predefines buffer had compatible
400 // contents. Accept the PCH file.
401 return false;
402}
403
Douglas Gregor12fab312010-03-16 16:35:32 +0000404void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
405 unsigned ID) {
406 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
407 ++NumHeaderInfos;
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000408}
409
410void PCHValidator::ReadCounter(unsigned Value) {
411 PP.setCounterValue(Value);
412}
413
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000414//===----------------------------------------------------------------------===//
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000415// AST reader implementation
Douglas Gregor668c1a42009-04-21 22:25:48 +0000416//===----------------------------------------------------------------------===//
417
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000418void
Sebastian Redl571db7f2010-08-18 23:56:56 +0000419ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000420 DeserializationListener = Listener;
421 if (DeserializationListener)
422 DeserializationListener->SetReader(this);
423}
424
Chris Lattner4c6f9522009-04-27 05:14:47 +0000425
Douglas Gregor668c1a42009-04-21 22:25:48 +0000426namespace {
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000427class ASTSelectorLookupTrait {
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000428 ASTReader &Reader;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000429
430public:
Sebastian Redl5d050072010-08-04 17:20:04 +0000431 struct data_type {
Sebastian Redl8538e8d2010-08-18 23:57:32 +0000432 SelectorID ID;
Sebastian Redl5d050072010-08-04 17:20:04 +0000433 ObjCMethodList Instance, Factory;
434 };
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000435
436 typedef Selector external_key_type;
437 typedef external_key_type internal_key_type;
438
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000439 explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000440
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000441 static bool EqualKey(const internal_key_type& a,
442 const internal_key_type& b) {
443 return a == b;
444 }
Mike Stump1eb44332009-09-09 15:08:12 +0000445
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000446 static unsigned ComputeHash(Selector Sel) {
Argyrios Kyrtzidis0eca89e2010-08-20 16:03:52 +0000447 return serialization::ComputeHash(Sel);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000448 }
Mike Stump1eb44332009-09-09 15:08:12 +0000449
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000450 // This hopefully will just get inlined and removed by the optimizer.
451 static const internal_key_type&
452 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump1eb44332009-09-09 15:08:12 +0000453
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000454 static std::pair<unsigned, unsigned>
455 ReadKeyDataLength(const unsigned char*& d) {
456 using namespace clang::io;
457 unsigned KeyLen = ReadUnalignedLE16(d);
458 unsigned DataLen = ReadUnalignedLE16(d);
459 return std::make_pair(KeyLen, DataLen);
460 }
Mike Stump1eb44332009-09-09 15:08:12 +0000461
Douglas Gregor83941df2009-04-25 17:48:32 +0000462 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000463 using namespace clang::io;
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000464 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000465 unsigned N = ReadUnalignedLE16(d);
Mike Stump1eb44332009-09-09 15:08:12 +0000466 IdentifierInfo *FirstII
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000467 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
468 if (N == 0)
469 return SelTable.getNullarySelector(FirstII);
470 else if (N == 1)
471 return SelTable.getUnarySelector(FirstII);
472
473 llvm::SmallVector<IdentifierInfo *, 16> Args;
474 Args.push_back(FirstII);
475 for (unsigned I = 1; I != N; ++I)
476 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
477
Douglas Gregor75fdb232009-05-22 22:45:36 +0000478 return SelTable.getSelector(N, Args.data());
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000479 }
Mike Stump1eb44332009-09-09 15:08:12 +0000480
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000481 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
482 using namespace clang::io;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000483
484 data_type Result;
485
Sebastian Redl5d050072010-08-04 17:20:04 +0000486 Result.ID = ReadUnalignedLE32(d);
487 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
488 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
489
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000490 // Load instance methods
491 ObjCMethodList *Prev = 0;
492 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +0000493 ObjCMethodDecl *Method
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000494 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl5d050072010-08-04 17:20:04 +0000495 if (!Result.Instance.Method) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000496 // This is the first method, which is the easy case.
Sebastian Redl5d050072010-08-04 17:20:04 +0000497 Result.Instance.Method = Method;
498 Prev = &Result.Instance;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000499 continue;
500 }
501
Ted Kremenek298ed872010-02-11 00:53:01 +0000502 ObjCMethodList *Mem =
503 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
504 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000505 Prev = Prev->Next;
506 }
507
508 // Load factory methods
509 Prev = 0;
510 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +0000511 ObjCMethodDecl *Method
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000512 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl5d050072010-08-04 17:20:04 +0000513 if (!Result.Factory.Method) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000514 // This is the first method, which is the easy case.
Sebastian Redl5d050072010-08-04 17:20:04 +0000515 Result.Factory.Method = Method;
516 Prev = &Result.Factory;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000517 continue;
518 }
519
Ted Kremenek298ed872010-02-11 00:53:01 +0000520 ObjCMethodList *Mem =
521 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
522 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000523 Prev = Prev->Next;
524 }
525
526 return Result;
527 }
528};
Mike Stump1eb44332009-09-09 15:08:12 +0000529
530} // end anonymous namespace
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000531
532/// \brief The on-disk hash table used for the global method pool.
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000533typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
534 ASTSelectorLookupTable;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000535
536namespace {
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000537class ASTIdentifierLookupTrait {
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000538 ASTReader &Reader;
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000539 llvm::BitstreamCursor &Stream;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000540
541 // If we know the IdentifierInfo in advance, it is here and we will
542 // not build a new one. Used when deserializing information about an
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000543 // identifier that was constructed before the AST file was read.
Douglas Gregor668c1a42009-04-21 22:25:48 +0000544 IdentifierInfo *KnownII;
545
546public:
547 typedef IdentifierInfo * data_type;
548
549 typedef const std::pair<const char*, unsigned> external_key_type;
550
551 typedef external_key_type internal_key_type;
552
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000553 ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000554 IdentifierInfo *II = 0)
555 : Reader(Reader), Stream(Stream), KnownII(II) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000556
Douglas Gregor668c1a42009-04-21 22:25:48 +0000557 static bool EqualKey(const internal_key_type& a,
558 const internal_key_type& b) {
559 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
560 : false;
561 }
Mike Stump1eb44332009-09-09 15:08:12 +0000562
Douglas Gregor668c1a42009-04-21 22:25:48 +0000563 static unsigned ComputeHash(const internal_key_type& a) {
Daniel Dunbar2596e422009-10-17 23:52:28 +0000564 return llvm::HashString(llvm::StringRef(a.first, a.second));
Douglas Gregor668c1a42009-04-21 22:25:48 +0000565 }
Mike Stump1eb44332009-09-09 15:08:12 +0000566
Douglas Gregor668c1a42009-04-21 22:25:48 +0000567 // This hopefully will just get inlined and removed by the optimizer.
568 static const internal_key_type&
569 GetInternalKey(const external_key_type& x) { return x; }
Mike Stump1eb44332009-09-09 15:08:12 +0000570
Douglas Gregor668c1a42009-04-21 22:25:48 +0000571 static std::pair<unsigned, unsigned>
572 ReadKeyDataLength(const unsigned char*& d) {
573 using namespace clang::io;
Douglas Gregor5f8e3302009-04-25 20:26:24 +0000574 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregord6595a42009-04-25 21:04:17 +0000575 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000576 return std::make_pair(KeyLen, DataLen);
577 }
Mike Stump1eb44332009-09-09 15:08:12 +0000578
Douglas Gregor668c1a42009-04-21 22:25:48 +0000579 static std::pair<const char*, unsigned>
580 ReadKey(const unsigned char* d, unsigned n) {
581 assert(n >= 2 && d[n-1] == '\0');
582 return std::make_pair((const char*) d, n-1);
583 }
Mike Stump1eb44332009-09-09 15:08:12 +0000584
585 IdentifierInfo *ReadData(const internal_key_type& k,
Douglas Gregor668c1a42009-04-21 22:25:48 +0000586 const unsigned char* d,
587 unsigned DataLen) {
588 using namespace clang::io;
Sebastian Redl8538e8d2010-08-18 23:57:32 +0000589 IdentID ID = ReadUnalignedLE32(d);
Douglas Gregora92193e2009-04-28 21:18:29 +0000590 bool IsInteresting = ID & 0x01;
591
592 // Wipe out the "is interesting" bit.
593 ID = ID >> 1;
594
595 if (!IsInteresting) {
Sebastian Redl083abdf2010-07-27 23:01:28 +0000596 // For uninteresting identifiers, just build the IdentifierInfo
Douglas Gregora92193e2009-04-28 21:18:29 +0000597 // and associate it with the persistent ID.
598 IdentifierInfo *II = KnownII;
599 if (!II)
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000600 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregora92193e2009-04-28 21:18:29 +0000601 Reader.SetIdentifierInfo(ID, II);
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000602 II->setIsFromAST();
Douglas Gregora92193e2009-04-28 21:18:29 +0000603 return II;
604 }
605
Douglas Gregor5998da52009-04-28 21:32:13 +0000606 unsigned Bits = ReadUnalignedLE16(d);
Douglas Gregor2deaea32009-04-22 18:49:13 +0000607 bool CPlusPlusOperatorKeyword = Bits & 0x01;
608 Bits >>= 1;
Argyrios Kyrtzidis646395b2010-08-11 22:55:12 +0000609 bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
610 Bits >>= 1;
Douglas Gregor2deaea32009-04-22 18:49:13 +0000611 bool Poisoned = Bits & 0x01;
612 Bits >>= 1;
613 bool ExtensionToken = Bits & 0x01;
614 Bits >>= 1;
615 bool hasMacroDefinition = Bits & 0x01;
616 Bits >>= 1;
617 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
618 Bits >>= 10;
Mike Stump1eb44332009-09-09 15:08:12 +0000619
Douglas Gregor2deaea32009-04-22 18:49:13 +0000620 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregor5998da52009-04-28 21:32:13 +0000621 DataLen -= 6;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000622
623 // Build the IdentifierInfo itself and link the identifier ID with
624 // the new IdentifierInfo.
625 IdentifierInfo *II = KnownII;
626 if (!II)
Sebastian Redlffaab3e2010-07-30 00:29:29 +0000627 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000628 Reader.SetIdentifierInfo(ID, II);
629
Douglas Gregor2deaea32009-04-22 18:49:13 +0000630 // Set or check the various bits in the IdentifierInfo structure.
Argyrios Kyrtzidis646395b2010-08-11 22:55:12 +0000631 // Token IDs are read-only.
632 if (HasRevertedTokenIDToIdentifier)
633 II->RevertTokenIDToIdentifier();
Douglas Gregor2deaea32009-04-22 18:49:13 +0000634 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
Mike Stump1eb44332009-09-09 15:08:12 +0000635 assert(II->isExtensionToken() == ExtensionToken &&
Douglas Gregor2deaea32009-04-22 18:49:13 +0000636 "Incorrect extension token flag");
637 (void)ExtensionToken;
638 II->setIsPoisoned(Poisoned);
639 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
640 "Incorrect C++ operator keyword flag");
641 (void)CPlusPlusOperatorKeyword;
642
Douglas Gregor37e26842009-04-21 23:56:24 +0000643 // If this identifier is a macro, deserialize the macro
644 // definition.
645 if (hasMacroDefinition) {
Douglas Gregor5998da52009-04-28 21:32:13 +0000646 uint32_t Offset = ReadUnalignedLE32(d);
Sebastian Redld27d3fc2010-07-21 22:31:37 +0000647 Reader.ReadMacroRecord(Stream, Offset);
Douglas Gregor5998da52009-04-28 21:32:13 +0000648 DataLen -= 4;
Douglas Gregor37e26842009-04-21 23:56:24 +0000649 }
Douglas Gregor668c1a42009-04-21 22:25:48 +0000650
651 // Read all of the declarations visible at global scope with this
652 // name.
Chris Lattner6bf690f2009-04-27 22:17:41 +0000653 if (Reader.getContext() == 0) return II;
Douglas Gregord89275b2009-07-06 18:54:52 +0000654 if (DataLen > 0) {
655 llvm::SmallVector<uint32_t, 4> DeclIDs;
656 for (; DataLen > 0; DataLen -= 4)
657 DeclIDs.push_back(ReadUnalignedLE32(d));
658 Reader.SetGloballyVisibleDecls(II, DeclIDs);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000659 }
Mike Stump1eb44332009-09-09 15:08:12 +0000660
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000661 II->setIsFromAST();
Douglas Gregor668c1a42009-04-21 22:25:48 +0000662 return II;
663 }
664};
Mike Stump1eb44332009-09-09 15:08:12 +0000665
666} // end anonymous namespace
Douglas Gregor668c1a42009-04-21 22:25:48 +0000667
668/// \brief The on-disk hash table used to contain information about
669/// all of the identifiers in the program.
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000670typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
671 ASTIdentifierLookupTable;
Douglas Gregor668c1a42009-04-21 22:25:48 +0000672
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +0000673namespace {
674class ASTDeclContextNameLookupTrait {
675 ASTReader &Reader;
676
677public:
678 /// \brief Pair of begin/end iterators for DeclIDs.
679 typedef std::pair<DeclID *, DeclID *> data_type;
680
681 /// \brief Special internal key for declaration names.
682 /// The hash table creates keys for comparison; we do not create
683 /// a DeclarationName for the internal key to avoid deserializing types.
684 struct DeclNameKey {
685 DeclarationName::NameKind Kind;
686 uint64_t Data;
687 DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
688 };
689
690 typedef DeclarationName external_key_type;
691 typedef DeclNameKey internal_key_type;
692
693 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
694
695 static bool EqualKey(const internal_key_type& a,
696 const internal_key_type& b) {
697 return a.Kind == b.Kind && a.Data == b.Data;
698 }
699
700 unsigned ComputeHash(const DeclNameKey &Key) const {
701 llvm::FoldingSetNodeID ID;
702 ID.AddInteger(Key.Kind);
703
704 switch (Key.Kind) {
705 case DeclarationName::Identifier:
706 case DeclarationName::CXXLiteralOperatorName:
707 ID.AddString(((IdentifierInfo*)Key.Data)->getName());
708 break;
709 case DeclarationName::ObjCZeroArgSelector:
710 case DeclarationName::ObjCOneArgSelector:
711 case DeclarationName::ObjCMultiArgSelector:
712 ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
713 break;
714 case DeclarationName::CXXConstructorName:
715 case DeclarationName::CXXDestructorName:
716 case DeclarationName::CXXConversionFunctionName:
717 ID.AddInteger((TypeID)Key.Data);
718 break;
719 case DeclarationName::CXXOperatorName:
720 ID.AddInteger((OverloadedOperatorKind)Key.Data);
721 break;
722 case DeclarationName::CXXUsingDirective:
723 break;
724 }
725
726 return ID.ComputeHash();
727 }
728
729 internal_key_type GetInternalKey(const external_key_type& Name) const {
730 DeclNameKey Key;
731 Key.Kind = Name.getNameKind();
732 switch (Name.getNameKind()) {
733 case DeclarationName::Identifier:
734 Key.Data = (uint64_t)Name.getAsIdentifierInfo();
735 break;
736 case DeclarationName::ObjCZeroArgSelector:
737 case DeclarationName::ObjCOneArgSelector:
738 case DeclarationName::ObjCMultiArgSelector:
739 Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
740 break;
741 case DeclarationName::CXXConstructorName:
742 case DeclarationName::CXXDestructorName:
743 case DeclarationName::CXXConversionFunctionName:
744 Key.Data = Reader.GetTypeID(Name.getCXXNameType());
745 break;
746 case DeclarationName::CXXOperatorName:
747 Key.Data = Name.getCXXOverloadedOperator();
748 break;
749 case DeclarationName::CXXLiteralOperatorName:
750 Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
751 break;
752 case DeclarationName::CXXUsingDirective:
753 break;
754 }
755
756 return Key;
757 }
758
Argyrios Kyrtzidisa60786b2010-08-20 23:35:55 +0000759 external_key_type GetExternalKey(const internal_key_type& Key) const {
760 ASTContext *Context = Reader.getContext();
761 switch (Key.Kind) {
762 case DeclarationName::Identifier:
763 return DeclarationName((IdentifierInfo*)Key.Data);
764
765 case DeclarationName::ObjCZeroArgSelector:
766 case DeclarationName::ObjCOneArgSelector:
767 case DeclarationName::ObjCMultiArgSelector:
768 return DeclarationName(Selector(Key.Data));
769
770 case DeclarationName::CXXConstructorName:
771 return Context->DeclarationNames.getCXXConstructorName(
772 Context->getCanonicalType(Reader.GetType(Key.Data)));
773
774 case DeclarationName::CXXDestructorName:
775 return Context->DeclarationNames.getCXXDestructorName(
776 Context->getCanonicalType(Reader.GetType(Key.Data)));
777
778 case DeclarationName::CXXConversionFunctionName:
779 return Context->DeclarationNames.getCXXConversionFunctionName(
780 Context->getCanonicalType(Reader.GetType(Key.Data)));
781
782 case DeclarationName::CXXOperatorName:
783 return Context->DeclarationNames.getCXXOperatorName(
784 (OverloadedOperatorKind)Key.Data);
785
786 case DeclarationName::CXXLiteralOperatorName:
787 return Context->DeclarationNames.getCXXLiteralOperatorName(
788 (IdentifierInfo*)Key.Data);
789
790 case DeclarationName::CXXUsingDirective:
791 return DeclarationName::getUsingDirectiveName();
792 }
793
794 llvm_unreachable("Invalid Name Kind ?");
795 }
796
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +0000797 static std::pair<unsigned, unsigned>
798 ReadKeyDataLength(const unsigned char*& d) {
799 using namespace clang::io;
800 unsigned KeyLen = ReadUnalignedLE16(d);
801 unsigned DataLen = ReadUnalignedLE16(d);
802 return std::make_pair(KeyLen, DataLen);
803 }
804
805 internal_key_type ReadKey(const unsigned char* d, unsigned) {
806 using namespace clang::io;
807
808 DeclNameKey Key;
809 Key.Kind = (DeclarationName::NameKind)*d++;
810 switch (Key.Kind) {
811 case DeclarationName::Identifier:
812 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
813 break;
814 case DeclarationName::ObjCZeroArgSelector:
815 case DeclarationName::ObjCOneArgSelector:
816 case DeclarationName::ObjCMultiArgSelector:
817 Key.Data =
818 (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
819 break;
820 case DeclarationName::CXXConstructorName:
821 case DeclarationName::CXXDestructorName:
822 case DeclarationName::CXXConversionFunctionName:
823 Key.Data = ReadUnalignedLE32(d); // TypeID
824 break;
825 case DeclarationName::CXXOperatorName:
826 Key.Data = *d++; // OverloadedOperatorKind
827 break;
828 case DeclarationName::CXXLiteralOperatorName:
829 Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
830 break;
831 case DeclarationName::CXXUsingDirective:
832 break;
833 }
834
835 return Key;
836 }
837
838 data_type ReadData(internal_key_type, const unsigned char* d,
839 unsigned DataLen) {
840 using namespace clang::io;
841 unsigned NumDecls = ReadUnalignedLE16(d);
842 DeclID *Start = (DeclID *)d;
843 return std::make_pair(Start, Start + NumDecls);
844 }
845};
846
847} // end anonymous namespace
848
849/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
850typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
851 ASTDeclContextNameLookupTable;
852
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +0000853bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
854 const std::pair<uint64_t, uint64_t> &Offsets,
855 DeclContextInfo &Info) {
856 SavedStreamPosition SavedPosition(Cursor);
857 // First the lexical decls.
858 if (Offsets.first != 0) {
859 Cursor.JumpToBit(Offsets.first);
860
861 RecordData Record;
862 const char *Blob;
863 unsigned BlobLen;
864 unsigned Code = Cursor.ReadCode();
865 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
866 if (RecCode != DECL_CONTEXT_LEXICAL) {
867 Error("Expected lexical block");
868 return true;
869 }
870
871 Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
872 Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
873 } else {
874 Info.LexicalDecls = 0;
875 Info.NumLexicalDecls = 0;
876 }
877
878 // Now the lookup table.
879 if (Offsets.second != 0) {
880 Cursor.JumpToBit(Offsets.second);
881
882 RecordData Record;
883 const char *Blob;
884 unsigned BlobLen;
885 unsigned Code = Cursor.ReadCode();
886 unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
887 if (RecCode != DECL_CONTEXT_VISIBLE) {
888 Error("Expected visible lookup table block");
889 return true;
890 }
891 Info.NameLookupTableData
892 = ASTDeclContextNameLookupTable::Create(
893 (const unsigned char *)Blob + Record[0],
894 (const unsigned char *)Blob,
895 ASTDeclContextNameLookupTrait(*this));
Sebastian Redl0ea8f7f2010-08-24 00:50:00 +0000896 } else {
897 Info.NameLookupTableData = 0;
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +0000898 }
899
900 return false;
901}
902
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000903void ASTReader::Error(const char *Msg) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +0000904 Diag(diag::err_fe_pch_malformed) << Msg;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000905}
906
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000907/// \brief Tell the AST listener about the predefines buffers in the chain.
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000908bool ASTReader::CheckPredefinesBuffers() {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000909 if (Listener)
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +0000910 return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
Daniel Dunbar7b5a1212009-11-11 05:29:04 +0000911 ActualOriginalFileName,
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +0000912 SuggestedPredefines);
Douglas Gregore721f952009-04-28 18:58:38 +0000913 return false;
Douglas Gregore1d918e2009-04-10 23:10:45 +0000914}
915
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000916//===----------------------------------------------------------------------===//
917// Source Manager Deserialization
918//===----------------------------------------------------------------------===//
919
Douglas Gregorbd945002009-04-13 16:31:14 +0000920/// \brief Read the line table in the source manager block.
921/// \returns true if ther was an error.
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000922bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000923 unsigned Idx = 0;
924 LineTableInfo &LineTable = SourceMgr.getLineTable();
925
926 // Parse the file names
Douglas Gregorff0a9872009-04-13 17:12:42 +0000927 std::map<int, int> FileIDs;
928 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000929 // Extract the file name
930 unsigned FilenameLen = Record[Idx++];
931 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
932 Idx += FilenameLen;
Douglas Gregore650c8c2009-07-07 00:12:59 +0000933 MaybeAddSystemRootToFilename(Filename);
Mike Stump1eb44332009-09-09 15:08:12 +0000934 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Douglas Gregorff0a9872009-04-13 17:12:42 +0000935 Filename.size());
Douglas Gregorbd945002009-04-13 16:31:14 +0000936 }
937
938 // Parse the line entries
939 std::vector<LineEntry> Entries;
940 while (Idx < Record.size()) {
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000941 int FID = Record[Idx++];
Douglas Gregorbd945002009-04-13 16:31:14 +0000942
943 // Extract the line entries
944 unsigned NumEntries = Record[Idx++];
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000945 assert(NumEntries && "Numentries is 00000");
Douglas Gregorbd945002009-04-13 16:31:14 +0000946 Entries.clear();
947 Entries.reserve(NumEntries);
948 for (unsigned I = 0; I != NumEntries; ++I) {
949 unsigned FileOffset = Record[Idx++];
950 unsigned LineNo = Record[Idx++];
Argyrios Kyrtzidisf52a5d22010-07-02 11:55:05 +0000951 int FilenameID = FileIDs[Record[Idx++]];
Mike Stump1eb44332009-09-09 15:08:12 +0000952 SrcMgr::CharacteristicKind FileKind
Douglas Gregorbd945002009-04-13 16:31:14 +0000953 = (SrcMgr::CharacteristicKind)Record[Idx++];
954 unsigned IncludeOffset = Record[Idx++];
955 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
956 FileKind, IncludeOffset));
957 }
958 LineTable.AddEntry(FID, Entries);
959 }
960
961 return false;
962}
963
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000964namespace {
965
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000966class ASTStatData {
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000967public:
968 const bool hasStat;
969 const ino_t ino;
970 const dev_t dev;
971 const mode_t mode;
972 const time_t mtime;
973 const off_t size;
Mike Stump1eb44332009-09-09 15:08:12 +0000974
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000975 ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
Mike Stump1eb44332009-09-09 15:08:12 +0000976 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
977
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000978 ASTStatData()
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000979 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
980};
981
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000982class ASTStatLookupTrait {
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000983 public:
984 typedef const char *external_key_type;
985 typedef const char *internal_key_type;
986
Sebastian Redl3c7f4132010-08-18 23:57:06 +0000987 typedef ASTStatData data_type;
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000988
989 static unsigned ComputeHash(const char *path) {
Daniel Dunbar2596e422009-10-17 23:52:28 +0000990 return llvm::HashString(path);
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000991 }
992
993 static internal_key_type GetInternalKey(const char *path) { return path; }
994
995 static bool EqualKey(internal_key_type a, internal_key_type b) {
996 return strcmp(a, b) == 0;
997 }
998
999 static std::pair<unsigned, unsigned>
1000 ReadKeyDataLength(const unsigned char*& d) {
1001 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
1002 unsigned DataLen = (unsigned) *d++;
1003 return std::make_pair(KeyLen + 1, DataLen);
1004 }
1005
1006 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
1007 return (const char *)d;
1008 }
1009
1010 static data_type ReadData(const internal_key_type, const unsigned char *d,
1011 unsigned /*DataLen*/) {
1012 using namespace clang::io;
1013
1014 if (*d++ == 1)
1015 return data_type();
1016
1017 ino_t ino = (ino_t) ReadUnalignedLE32(d);
1018 dev_t dev = (dev_t) ReadUnalignedLE32(d);
1019 mode_t mode = (mode_t) ReadUnalignedLE16(d);
Mike Stump1eb44332009-09-09 15:08:12 +00001020 time_t mtime = (time_t) ReadUnalignedLE64(d);
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001021 off_t size = (off_t) ReadUnalignedLE64(d);
1022 return data_type(ino, dev, mode, mtime, size);
1023 }
1024};
1025
1026/// \brief stat() cache for precompiled headers.
1027///
1028/// This cache is very similar to the stat cache used by pretokenized
1029/// headers.
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001030class ASTStatCache : public StatSysCallCache {
1031 typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001032 CacheTy *Cache;
1033
1034 unsigned &NumStatHits, &NumStatMisses;
Mike Stump1eb44332009-09-09 15:08:12 +00001035public:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001036 ASTStatCache(const unsigned char *Buckets,
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001037 const unsigned char *Base,
1038 unsigned &NumStatHits,
Mike Stump1eb44332009-09-09 15:08:12 +00001039 unsigned &NumStatMisses)
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001040 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
1041 Cache = CacheTy::Create(Buckets, Base);
1042 }
1043
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001044 ~ASTStatCache() { delete Cache; }
Mike Stump1eb44332009-09-09 15:08:12 +00001045
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001046 int stat(const char *path, struct stat *buf) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001047 // Do the lookup for the file's data in the AST file.
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001048 CacheTy::iterator I = Cache->find(path);
1049
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001050 // If we don't get a hit in the AST file just forward to 'stat'.
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001051 if (I == Cache->end()) {
1052 ++NumStatMisses;
Douglas Gregor52e71082009-10-16 18:18:30 +00001053 return StatSysCallCache::stat(path, buf);
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001054 }
Mike Stump1eb44332009-09-09 15:08:12 +00001055
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001056 ++NumStatHits;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001057 ASTStatData Data = *I;
Mike Stump1eb44332009-09-09 15:08:12 +00001058
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001059 if (!Data.hasStat)
1060 return 1;
1061
1062 buf->st_ino = Data.ino;
1063 buf->st_dev = Data.dev;
1064 buf->st_mtime = Data.mtime;
1065 buf->st_mode = Data.mode;
1066 buf->st_size = Data.size;
1067 return 0;
1068 }
1069};
1070} // end anonymous namespace
1071
1072
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001073/// \brief Read a source manager block
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001074ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
Douglas Gregor14f79002009-04-10 03:52:48 +00001075 using namespace SrcMgr;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001076
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001077 llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
Sebastian Redl9137a522010-07-16 17:50:48 +00001078
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001079 // Set the source-location entry cursor to the current position in
1080 // the stream. This cursor will be used to read the contents of the
1081 // source manager block initially, and then lazily read
1082 // source-location entries as needed.
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001083 SLocEntryCursor = F.Stream;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001084
1085 // The stream itself is going to skip over the source manager block.
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001086 if (F.Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001087 Error("malformed block record in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001088 return Failure;
1089 }
1090
1091 // Enter the source manager block.
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001092 if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001093 Error("malformed source manager block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001094 return Failure;
1095 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001096
Douglas Gregor14f79002009-04-10 03:52:48 +00001097 RecordData Record;
1098 while (true) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001099 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregor14f79002009-04-10 03:52:48 +00001100 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001101 if (SLocEntryCursor.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001102 Error("error at end of Source Manager block in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001103 return Failure;
1104 }
Douglas Gregore1d918e2009-04-10 23:10:45 +00001105 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +00001106 }
Mike Stump1eb44332009-09-09 15:08:12 +00001107
Douglas Gregor14f79002009-04-10 03:52:48 +00001108 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1109 // No known subblocks, always skip them.
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001110 SLocEntryCursor.ReadSubBlockID();
1111 if (SLocEntryCursor.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001112 Error("malformed block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00001113 return Failure;
1114 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001115 continue;
1116 }
Mike Stump1eb44332009-09-09 15:08:12 +00001117
Douglas Gregor14f79002009-04-10 03:52:48 +00001118 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001119 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregor14f79002009-04-10 03:52:48 +00001120 continue;
1121 }
Mike Stump1eb44332009-09-09 15:08:12 +00001122
Douglas Gregor14f79002009-04-10 03:52:48 +00001123 // Read a record.
1124 const char *BlobStart;
1125 unsigned BlobLen;
1126 Record.clear();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001127 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregor14f79002009-04-10 03:52:48 +00001128 default: // Default behavior: ignore.
1129 break;
1130
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001131 case SM_LINE_TABLE:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001132 if (ParseLineTable(Record))
Douglas Gregorbd945002009-04-13 16:31:14 +00001133 return Failure;
Chris Lattner2c78b872009-04-14 23:22:57 +00001134 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001135
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001136 case SM_SLOC_FILE_ENTRY:
1137 case SM_SLOC_BUFFER_ENTRY:
1138 case SM_SLOC_INSTANTIATION_ENTRY:
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001139 // Once we hit one of the source location entries, we're done.
1140 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +00001141 }
1142 }
1143}
1144
Sebastian Redl190faf72010-07-20 21:50:20 +00001145/// \brief Get a cursor that's correctly positioned for reading the source
1146/// location entry with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001147llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
Sebastian Redl190faf72010-07-20 21:50:20 +00001148 assert(ID != 0 && ID <= TotalNumSLocEntries &&
1149 "SLocCursorForID should only be called for real IDs.");
1150
1151 ID -= 1;
1152 PerFileData *F = 0;
1153 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1154 F = Chain[N - I - 1];
1155 if (ID < F->LocalNumSLocEntries)
1156 break;
1157 ID -= F->LocalNumSLocEntries;
1158 }
1159 assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
1160
1161 F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
1162 return F->SLocEntryCursor;
1163}
1164
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001165/// \brief Read in the source location entry with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001166ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001167 if (ID == 0)
1168 return Success;
1169
1170 if (ID > TotalNumSLocEntries) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001171 Error("source location entry ID out-of-range for AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001172 return Failure;
1173 }
1174
Sebastian Redl190faf72010-07-20 21:50:20 +00001175 llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
Sebastian Redl9137a522010-07-16 17:50:48 +00001176
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001177 ++NumSLocEntriesRead;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001178 unsigned Code = SLocEntryCursor.ReadCode();
1179 if (Code == llvm::bitc::END_BLOCK ||
1180 Code == llvm::bitc::ENTER_SUBBLOCK ||
1181 Code == llvm::bitc::DEFINE_ABBREV) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001182 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001183 return Failure;
1184 }
1185
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001186 RecordData Record;
1187 const char *BlobStart;
1188 unsigned BlobLen;
1189 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1190 default:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001191 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001192 return Failure;
1193
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001194 case SM_SLOC_FILE_ENTRY: {
Douglas Gregore650c8c2009-07-07 00:12:59 +00001195 std::string Filename(BlobStart, BlobStart + BlobLen);
1196 MaybeAddSystemRootToFilename(Filename);
1197 const FileEntry *File = FileMgr.getFile(Filename);
Chris Lattnerd3555ae2009-06-15 04:35:16 +00001198 if (File == 0) {
1199 std::string ErrorStr = "could not find file '";
Douglas Gregore650c8c2009-07-07 00:12:59 +00001200 ErrorStr += Filename;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001201 ErrorStr += "' referenced by AST file";
Chris Lattnerd3555ae2009-06-15 04:35:16 +00001202 Error(ErrorStr.c_str());
1203 return Failure;
1204 }
Mike Stump1eb44332009-09-09 15:08:12 +00001205
Douglas Gregor2d52be52010-03-21 22:49:54 +00001206 if (Record.size() < 10) {
Ted Kremenek1857f622010-03-18 21:23:05 +00001207 Error("source location entry is incorrect");
1208 return Failure;
1209 }
1210
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001211 if (!DisableValidation &&
1212 ((off_t)Record[4] != File->getSize()
Douglas Gregor9f692a02010-04-09 15:54:22 +00001213#if !defined(LLVM_ON_WIN32)
1214 // In our regression testing, the Windows file system seems to
1215 // have inconsistent modification times that sometimes
1216 // erroneously trigger this error-handling path.
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001217 || (time_t)Record[5] != File->getModificationTime()
Douglas Gregor9f692a02010-04-09 15:54:22 +00001218#endif
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001219 )) {
Douglas Gregor2d52be52010-03-21 22:49:54 +00001220 Diag(diag::err_fe_pch_file_modified)
1221 << Filename;
1222 return Failure;
1223 }
1224
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001225 FileID FID = SourceMgr.createFileID(File,
1226 SourceLocation::getFromRawEncoding(Record[1]),
1227 (SrcMgr::CharacteristicKind)Record[2],
1228 ID, Record[0]);
1229 if (Record[3])
1230 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
1231 .setHasLineDirectives();
1232
Douglas Gregor12fab312010-03-16 16:35:32 +00001233 // Reconstruct header-search information for this file.
1234 HeaderFileInfo HFI;
Douglas Gregor2d52be52010-03-21 22:49:54 +00001235 HFI.isImport = Record[6];
1236 HFI.DirInfo = Record[7];
1237 HFI.NumIncludes = Record[8];
1238 HFI.ControllingMacroID = Record[9];
Douglas Gregor12fab312010-03-16 16:35:32 +00001239 if (Listener)
1240 Listener->ReadHeaderFileInfo(HFI, File->getUID());
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001241 break;
1242 }
1243
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001244 case SM_SLOC_BUFFER_ENTRY: {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001245 const char *Name = BlobStart;
1246 unsigned Offset = Record[0];
1247 unsigned Code = SLocEntryCursor.ReadCode();
1248 Record.clear();
Mike Stump1eb44332009-09-09 15:08:12 +00001249 unsigned RecCode
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001250 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00001251
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001252 if (RecCode != SM_SLOC_BUFFER_BLOB) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001253 Error("AST record has invalid code");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00001254 return Failure;
1255 }
1256
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001257 llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00001258 = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
1259 Name);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001260 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
Mike Stump1eb44332009-09-09 15:08:12 +00001261
Douglas Gregor92b059e2009-04-28 20:33:11 +00001262 if (strcmp(Name, "<built-in>") == 0) {
Sebastian Redl7e9ad8b2010-07-14 17:49:11 +00001263 PCHPredefinesBlock Block = {
1264 BufferID,
1265 llvm::StringRef(BlobStart, BlobLen - 1)
1266 };
1267 PCHPredefinesBuffers.push_back(Block);
Douglas Gregor92b059e2009-04-28 20:33:11 +00001268 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001269
1270 break;
1271 }
1272
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001273 case SM_SLOC_INSTANTIATION_ENTRY: {
Mike Stump1eb44332009-09-09 15:08:12 +00001274 SourceLocation SpellingLoc
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001275 = SourceLocation::getFromRawEncoding(Record[1]);
1276 SourceMgr.createInstantiationLoc(SpellingLoc,
1277 SourceLocation::getFromRawEncoding(Record[2]),
1278 SourceLocation::getFromRawEncoding(Record[3]),
1279 Record[4],
1280 ID,
1281 Record[0]);
1282 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001283 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001284 }
1285
1286 return Success;
1287}
1288
Chris Lattner6367f6d2009-04-27 01:05:14 +00001289/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
1290/// specified cursor. Read the abbreviations that are at the top of the block
1291/// and then leave the cursor pointing into the block.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001292bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
Chris Lattner6367f6d2009-04-27 01:05:14 +00001293 unsigned BlockID) {
1294 if (Cursor.EnterSubBlock(BlockID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001295 Error("malformed block record in AST file");
Chris Lattner6367f6d2009-04-27 01:05:14 +00001296 return Failure;
1297 }
Mike Stump1eb44332009-09-09 15:08:12 +00001298
Chris Lattner6367f6d2009-04-27 01:05:14 +00001299 while (true) {
1300 unsigned Code = Cursor.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00001301
Chris Lattner6367f6d2009-04-27 01:05:14 +00001302 // We expect all abbrevs to be at the start of the block.
1303 if (Code != llvm::bitc::DEFINE_ABBREV)
1304 return false;
1305 Cursor.ReadAbbrevRecord();
1306 }
1307}
1308
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001309void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001310 assert(PP && "Forgot to set Preprocessor ?");
Mike Stump1eb44332009-09-09 15:08:12 +00001311
Douglas Gregor37e26842009-04-21 23:56:24 +00001312 // Keep track of where we are in the stream, then jump back there
1313 // after reading this macro.
1314 SavedStreamPosition SavedPosition(Stream);
1315
1316 Stream.JumpToBit(Offset);
1317 RecordData Record;
1318 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
1319 MacroInfo *Macro = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001320
Douglas Gregor37e26842009-04-21 23:56:24 +00001321 while (true) {
1322 unsigned Code = Stream.ReadCode();
1323 switch (Code) {
1324 case llvm::bitc::END_BLOCK:
1325 return;
1326
1327 case llvm::bitc::ENTER_SUBBLOCK:
1328 // No known subblocks, always skip them.
1329 Stream.ReadSubBlockID();
1330 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001331 Error("malformed block record in AST file");
Douglas Gregor37e26842009-04-21 23:56:24 +00001332 return;
1333 }
1334 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00001335
Douglas Gregor37e26842009-04-21 23:56:24 +00001336 case llvm::bitc::DEFINE_ABBREV:
1337 Stream.ReadAbbrevRecord();
1338 continue;
1339 default: break;
1340 }
1341
1342 // Read a record.
1343 Record.clear();
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001344 PreprocessorRecordTypes RecType =
1345 (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
Douglas Gregor37e26842009-04-21 23:56:24 +00001346 switch (RecType) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001347 case PP_MACRO_OBJECT_LIKE:
1348 case PP_MACRO_FUNCTION_LIKE: {
Douglas Gregor37e26842009-04-21 23:56:24 +00001349 // If we already have a macro, that means that we've hit the end
1350 // of the definition of the macro we were looking for. We're
1351 // done.
1352 if (Macro)
1353 return;
1354
1355 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
1356 if (II == 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001357 Error("macro must have a name in AST file");
Douglas Gregor37e26842009-04-21 23:56:24 +00001358 return;
1359 }
1360 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1361 bool isUsed = Record[2];
Mike Stump1eb44332009-09-09 15:08:12 +00001362
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001363 MacroInfo *MI = PP->AllocateMacroInfo(Loc);
Douglas Gregor37e26842009-04-21 23:56:24 +00001364 MI->setIsUsed(isUsed);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001365 MI->setIsFromAST();
Mike Stump1eb44332009-09-09 15:08:12 +00001366
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001367 unsigned NextIndex = 3;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001368 if (RecType == PP_MACRO_FUNCTION_LIKE) {
Douglas Gregor37e26842009-04-21 23:56:24 +00001369 // Decode function-like macro info.
1370 bool isC99VarArgs = Record[3];
1371 bool isGNUVarArgs = Record[4];
1372 MacroArgs.clear();
1373 unsigned NumArgs = Record[5];
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001374 NextIndex = 6 + NumArgs;
Douglas Gregor37e26842009-04-21 23:56:24 +00001375 for (unsigned i = 0; i != NumArgs; ++i)
1376 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
1377
1378 // Install function-like macro info.
1379 MI->setIsFunctionLike();
1380 if (isC99VarArgs) MI->setIsC99Varargs();
1381 if (isGNUVarArgs) MI->setIsGNUVarargs();
Douglas Gregor75fdb232009-05-22 22:45:36 +00001382 MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001383 PP->getPreprocessorAllocator());
Douglas Gregor37e26842009-04-21 23:56:24 +00001384 }
1385
1386 // Finally, install the macro.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001387 PP->setMacroInfo(II, MI);
Douglas Gregor37e26842009-04-21 23:56:24 +00001388
1389 // Remember that we saw this macro last so that we add the tokens that
1390 // form its body to it.
1391 Macro = MI;
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001392
1393 if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
1394 // We have a macro definition. Load it now.
1395 PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
1396 getMacroDefinition(Record[NextIndex]));
1397 }
1398
Douglas Gregor37e26842009-04-21 23:56:24 +00001399 ++NumMacrosRead;
1400 break;
1401 }
Mike Stump1eb44332009-09-09 15:08:12 +00001402
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001403 case PP_TOKEN: {
Douglas Gregor37e26842009-04-21 23:56:24 +00001404 // If we see a TOKEN before a PP_MACRO_*, then the file is
1405 // erroneous, just pretend we didn't see this.
1406 if (Macro == 0) break;
Mike Stump1eb44332009-09-09 15:08:12 +00001407
Douglas Gregor37e26842009-04-21 23:56:24 +00001408 Token Tok;
1409 Tok.startToken();
1410 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1411 Tok.setLength(Record[1]);
1412 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1413 Tok.setIdentifierInfo(II);
1414 Tok.setKind((tok::TokenKind)Record[3]);
1415 Tok.setFlag((Token::TokenFlags)Record[4]);
1416 Macro->AddTokenToBody(Tok);
1417 break;
1418 }
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001419
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001420 case PP_MACRO_INSTANTIATION: {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001421 // If we already have a macro, that means that we've hit the end
1422 // of the definition of the macro we were looking for. We're
1423 // done.
1424 if (Macro)
1425 return;
1426
1427 if (!PP->getPreprocessingRecord()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001428 Error("missing preprocessing record in AST file");
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001429 return;
1430 }
1431
1432 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1433 if (PPRec.getPreprocessedEntity(Record[0]))
1434 return;
1435
1436 MacroInstantiation *MI
1437 = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
1438 SourceRange(
1439 SourceLocation::getFromRawEncoding(Record[1]),
1440 SourceLocation::getFromRawEncoding(Record[2])),
1441 getMacroDefinition(Record[4]));
1442 PPRec.SetPreallocatedEntity(Record[0], MI);
1443 return;
1444 }
1445
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001446 case PP_MACRO_DEFINITION: {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001447 // If we already have a macro, that means that we've hit the end
1448 // of the definition of the macro we were looking for. We're
1449 // done.
1450 if (Macro)
1451 return;
1452
1453 if (!PP->getPreprocessingRecord()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001454 Error("missing preprocessing record in AST file");
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001455 return;
1456 }
1457
1458 PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
1459 if (PPRec.getPreprocessedEntity(Record[0]))
1460 return;
1461
1462 if (Record[1] >= MacroDefinitionsLoaded.size()) {
1463 Error("out-of-bounds macro definition record");
1464 return;
1465 }
1466
1467 MacroDefinition *MD
1468 = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
1469 SourceLocation::getFromRawEncoding(Record[5]),
1470 SourceRange(
1471 SourceLocation::getFromRawEncoding(Record[2]),
1472 SourceLocation::getFromRawEncoding(Record[3])));
1473 PPRec.SetPreallocatedEntity(Record[0], MD);
1474 MacroDefinitionsLoaded[Record[1]] = MD;
1475 return;
1476 }
Steve Naroff83d63c72009-04-24 20:03:17 +00001477 }
Douglas Gregor37e26842009-04-21 23:56:24 +00001478 }
1479}
1480
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001481void ASTReader::ReadDefinedMacros() {
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001482 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1483 llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
Sebastian Redl9137a522010-07-16 17:50:48 +00001484
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001485 // If there was no preprocessor block, skip this file.
1486 if (!MacroCursor.getBitStreamReader())
1487 continue;
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001488
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001489 llvm::BitstreamCursor Cursor = MacroCursor;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001490 if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001491 Error("malformed preprocessor block record in AST file");
Douglas Gregor88a35862010-01-04 19:18:44 +00001492 return;
1493 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001494
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001495 RecordData Record;
1496 while (true) {
1497 unsigned Code = Cursor.ReadCode();
1498 if (Code == llvm::bitc::END_BLOCK) {
1499 if (Cursor.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001500 Error("error at end of preprocessor block in AST file");
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001501 return;
1502 }
1503 break;
Douglas Gregor88a35862010-01-04 19:18:44 +00001504 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001505
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001506 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1507 // No known subblocks, always skip them.
1508 Cursor.ReadSubBlockID();
1509 if (Cursor.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001510 Error("malformed block record in AST file");
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001511 return;
1512 }
1513 continue;
1514 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001515
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001516 if (Code == llvm::bitc::DEFINE_ABBREV) {
1517 Cursor.ReadAbbrevRecord();
1518 continue;
1519 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001520
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001521 // Read a record.
1522 const char *BlobStart;
1523 unsigned BlobLen;
1524 Record.clear();
1525 switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1526 default: // Default behavior: ignore.
1527 break;
Douglas Gregor88a35862010-01-04 19:18:44 +00001528
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001529 case PP_MACRO_OBJECT_LIKE:
1530 case PP_MACRO_FUNCTION_LIKE:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001531 DecodeIdentifierInfo(Record[0]);
1532 break;
1533
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001534 case PP_TOKEN:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001535 // Ignore tokens.
1536 break;
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001537
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001538 case PP_MACRO_INSTANTIATION:
1539 case PP_MACRO_DEFINITION:
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001540 // Read the macro record.
1541 ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
1542 break;
1543 }
Douglas Gregor88a35862010-01-04 19:18:44 +00001544 }
1545 }
1546}
1547
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001548MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001549 if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
1550 return 0;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00001551
1552 if (!MacroDefinitionsLoaded[ID]) {
1553 unsigned Index = ID;
1554 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
1555 PerFileData &F = *Chain[N - I - 1];
1556 if (Index < F.LocalNumMacroDefinitions) {
1557 ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
1558 break;
1559 }
1560 Index -= F.LocalNumMacroDefinitions;
1561 }
1562 assert(MacroDefinitionsLoaded[ID] && "Broken chain");
1563 }
1564
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001565 return MacroDefinitionsLoaded[ID];
1566}
1567
Douglas Gregore650c8c2009-07-07 00:12:59 +00001568/// \brief If we are loading a relocatable PCH file, and the filename is
1569/// not an absolute path, add the system root to the beginning of the file
1570/// name.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001571void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
Douglas Gregore650c8c2009-07-07 00:12:59 +00001572 // If this is not a relocatable PCH file, there's nothing to do.
1573 if (!RelocatablePCH)
1574 return;
Mike Stump1eb44332009-09-09 15:08:12 +00001575
Daniel Dunbard5b21972009-11-18 19:50:41 +00001576 if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
Douglas Gregore650c8c2009-07-07 00:12:59 +00001577 return;
1578
Douglas Gregore650c8c2009-07-07 00:12:59 +00001579 if (isysroot == 0) {
1580 // If no system root was given, default to '/'
1581 Filename.insert(Filename.begin(), '/');
1582 return;
1583 }
Mike Stump1eb44332009-09-09 15:08:12 +00001584
Douglas Gregore650c8c2009-07-07 00:12:59 +00001585 unsigned Length = strlen(isysroot);
1586 if (isysroot[Length - 1] != '/')
1587 Filename.insert(Filename.begin(), '/');
Mike Stump1eb44332009-09-09 15:08:12 +00001588
Douglas Gregore650c8c2009-07-07 00:12:59 +00001589 Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1590}
1591
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001592ASTReader::ASTReadResult
Sebastian Redl571db7f2010-08-18 23:56:56 +00001593ASTReader::ReadASTBlock(PerFileData &F) {
Sebastian Redl9137a522010-07-16 17:50:48 +00001594 llvm::BitstreamCursor &Stream = F.Stream;
1595
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001596 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001597 Error("malformed block record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001598 return Failure;
1599 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001600
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001601 // Read all of the records and blocks for the ASt file.
Douglas Gregor8038d512009-04-10 17:25:41 +00001602 RecordData Record;
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001603 bool First = true;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001604 while (!Stream.AtEndOfStream()) {
1605 unsigned Code = Stream.ReadCode();
1606 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001607 if (Stream.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001608 Error("error at end of module block in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001609 return Failure;
1610 }
Chris Lattner7356a312009-04-11 21:15:38 +00001611
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001612 return Success;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001613 }
1614
1615 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1616 switch (Stream.ReadSubBlockID()) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001617 case DECLTYPES_BLOCK_ID:
Chris Lattner6367f6d2009-04-27 01:05:14 +00001618 // We lazily load the decls block, but we want to set up the
1619 // DeclsCursor cursor to point into it. Clone our current bitcode
1620 // cursor to it, enter the block and read the abbrevs in that block.
1621 // With the main cursor, we just skip over it.
Sebastian Redl9137a522010-07-16 17:50:48 +00001622 F.DeclsCursor = Stream;
Chris Lattner6367f6d2009-04-27 01:05:14 +00001623 if (Stream.SkipBlock() || // Skip with the main cursor.
1624 // Read the abbrevs.
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001625 ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001626 Error("malformed block record in AST file");
Chris Lattner6367f6d2009-04-27 01:05:14 +00001627 return Failure;
1628 }
1629 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001630
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001631 case PREPROCESSOR_BLOCK_ID:
Sebastian Redl9137a522010-07-16 17:50:48 +00001632 F.MacroCursor = Stream;
Douglas Gregor88a35862010-01-04 19:18:44 +00001633 if (PP)
1634 PP->setExternalSource(this);
1635
Chris Lattner7356a312009-04-11 21:15:38 +00001636 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001637 Error("malformed block record in AST file");
Chris Lattner7356a312009-04-11 21:15:38 +00001638 return Failure;
1639 }
1640 break;
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001641
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001642 case SOURCE_MANAGER_BLOCK_ID:
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001643 switch (ReadSourceManagerBlock(F)) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00001644 case Success:
1645 break;
1646
1647 case Failure:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001648 Error("malformed source manager block in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001649 return Failure;
Douglas Gregore1d918e2009-04-10 23:10:45 +00001650
1651 case IgnorePCH:
1652 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001653 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001654 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001655 }
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001656 First = false;
Douglas Gregor8038d512009-04-10 17:25:41 +00001657 continue;
1658 }
1659
1660 if (Code == llvm::bitc::DEFINE_ABBREV) {
1661 Stream.ReadAbbrevRecord();
1662 continue;
1663 }
1664
1665 // Read and process a record.
1666 Record.clear();
Douglas Gregor2bec0412009-04-10 21:16:55 +00001667 const char *BlobStart = 0;
1668 unsigned BlobLen = 0;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001669 switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
Douglas Gregor2bec0412009-04-10 21:16:55 +00001670 &BlobStart, &BlobLen)) {
Douglas Gregor8038d512009-04-10 17:25:41 +00001671 default: // Default behavior: ignore.
1672 break;
1673
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001674 case METADATA: {
1675 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1676 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001677 : diag::warn_pch_version_too_new);
1678 return IgnorePCH;
1679 }
1680
1681 RelocatablePCH = Record[4];
1682 if (Listener) {
1683 std::string TargetTriple(BlobStart, BlobLen);
1684 if (Listener->ReadTargetTriple(TargetTriple))
1685 return IgnorePCH;
1686 }
1687 break;
1688 }
1689
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001690 case CHAINED_METADATA: {
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001691 if (!First) {
1692 Error("CHAINED_METADATA is not first record in block");
1693 return Failure;
1694 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001695 if (Record[0] != VERSION_MAJOR && !DisableValidation) {
1696 Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001697 : diag::warn_pch_version_too_new);
1698 return IgnorePCH;
1699 }
1700
1701 // Load the chained file.
Sebastian Redl571db7f2010-08-18 23:56:56 +00001702 switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001703 case Failure: return Failure;
1704 // If we have to ignore the dependency, we'll have to ignore this too.
1705 case IgnorePCH: return IgnorePCH;
1706 case Success: break;
1707 }
1708 break;
1709 }
1710
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001711 case TYPE_OFFSET:
Sebastian Redl12d6da02010-07-19 22:06:55 +00001712 if (F.LocalNumTypes != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001713 Error("duplicate TYPE_OFFSET record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001714 return Failure;
1715 }
Sebastian Redl12d6da02010-07-19 22:06:55 +00001716 F.TypeOffsets = (const uint32_t *)BlobStart;
1717 F.LocalNumTypes = Record[0];
Douglas Gregor8038d512009-04-10 17:25:41 +00001718 break;
1719
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001720 case DECL_OFFSET:
Sebastian Redl12d6da02010-07-19 22:06:55 +00001721 if (F.LocalNumDecls != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001722 Error("duplicate DECL_OFFSET record in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001723 return Failure;
1724 }
Sebastian Redl12d6da02010-07-19 22:06:55 +00001725 F.DeclOffsets = (const uint32_t *)BlobStart;
1726 F.LocalNumDecls = Record[0];
Douglas Gregor8038d512009-04-10 17:25:41 +00001727 break;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001728
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001729 case TU_UPDATE_LEXICAL: {
Sebastian Redld692af72010-07-27 18:24:41 +00001730 DeclContextInfo Info = {
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00001731 /* No visible information */ 0,
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001732 reinterpret_cast<const DeclID *>(BlobStart),
1733 BlobLen / sizeof(DeclID)
Sebastian Redld692af72010-07-27 18:24:41 +00001734 };
1735 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1736 break;
1737 }
1738
Sebastian Redle1dde812010-08-24 00:50:04 +00001739 case UPDATE_VISIBLE: {
1740 serialization::DeclID ID = Record[0];
1741 void *Table = ASTDeclContextNameLookupTable::Create(
1742 (const unsigned char *)BlobStart + Record[1],
1743 (const unsigned char *)BlobStart,
1744 ASTDeclContextNameLookupTrait(*this));
1745 if (ID == 1) { // Is it the TU?
1746 DeclContextInfo Info = {
1747 Table, /* No lexical inforamtion */ 0, 0
1748 };
1749 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1750 } else
1751 PendingVisibleUpdates[ID].push_back(Table);
1752 break;
1753 }
1754
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001755 case REDECLS_UPDATE_LATEST: {
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00001756 assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
1757 for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001758 DeclID First = Record[i], Latest = Record[i+1];
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00001759 assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
1760 Latest > FirstLatestDeclIDs[First]) &&
1761 "The new latest is supposed to come after the previous latest");
1762 FirstLatestDeclIDs[First] = Latest;
1763 }
1764 break;
1765 }
1766
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001767 case LANGUAGE_OPTIONS:
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00001768 if (ParseLanguageOptions(Record) && !DisableValidation)
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001769 return IgnorePCH;
1770 break;
Douglas Gregor2bec0412009-04-10 21:16:55 +00001771
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001772 case IDENTIFIER_TABLE:
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001773 F.IdentifierTableData = BlobStart;
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001774 if (Record[0]) {
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001775 F.IdentifierLookupTable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001776 = ASTIdentifierLookupTable::Create(
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001777 (const unsigned char *)F.IdentifierTableData + Record[0],
1778 (const unsigned char *)F.IdentifierTableData,
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001779 ASTIdentifierLookupTrait(*this, F.Stream));
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001780 if (PP)
1781 PP->getIdentifierTable().setExternalIdentifierLookup(this);
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001782 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001783 break;
1784
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001785 case IDENTIFIER_OFFSET:
Sebastian Redl2da08f92010-07-19 22:28:42 +00001786 if (F.LocalNumIdentifiers != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001787 Error("duplicate IDENTIFIER_OFFSET record in AST file");
Douglas Gregorafaf3082009-04-11 00:14:32 +00001788 return Failure;
1789 }
Sebastian Redl2da08f92010-07-19 22:28:42 +00001790 F.IdentifierOffsets = (const uint32_t *)BlobStart;
1791 F.LocalNumIdentifiers = Record[0];
Douglas Gregorafaf3082009-04-11 00:14:32 +00001792 break;
Douglas Gregorfdd01722009-04-14 00:24:19 +00001793
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001794 case EXTERNAL_DEFINITIONS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001795 // Optimization for the first block.
1796 if (ExternalDefinitions.empty())
1797 ExternalDefinitions.swap(Record);
1798 else
1799 ExternalDefinitions.insert(ExternalDefinitions.end(),
1800 Record.begin(), Record.end());
Douglas Gregorfdd01722009-04-14 00:24:19 +00001801 break;
Douglas Gregor3e1af842009-04-17 22:13:46 +00001802
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001803 case SPECIAL_TYPES:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001804 // Optimization for the first block
1805 if (SpecialTypes.empty())
1806 SpecialTypes.swap(Record);
1807 else
1808 SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
Douglas Gregorad1de002009-04-18 05:55:16 +00001809 break;
1810
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001811 case STATISTICS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001812 TotalNumStatements += Record[0];
1813 TotalNumMacros += Record[1];
1814 TotalLexicalDeclContexts += Record[2];
1815 TotalVisibleDeclContexts += Record[3];
Douglas Gregor3e1af842009-04-17 22:13:46 +00001816 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001817
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001818 case TENTATIVE_DEFINITIONS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001819 // Optimization for the first block.
1820 if (TentativeDefinitions.empty())
1821 TentativeDefinitions.swap(Record);
1822 else
1823 TentativeDefinitions.insert(TentativeDefinitions.end(),
1824 Record.begin(), Record.end());
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00001825 break;
Douglas Gregor14c22f22009-04-22 22:18:58 +00001826
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001827 case UNUSED_FILESCOPED_DECLS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001828 // Optimization for the first block.
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00001829 if (UnusedFileScopedDecls.empty())
1830 UnusedFileScopedDecls.swap(Record);
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001831 else
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00001832 UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
1833 Record.begin(), Record.end());
Tanya Lattnere6bbc012010-02-12 00:07:30 +00001834 break;
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001835
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001836 case WEAK_UNDECLARED_IDENTIFIERS:
Sebastian Redl40566802010-08-05 18:21:25 +00001837 // Later blocks overwrite earlier ones.
1838 WeakUndeclaredIdentifiers.swap(Record);
Argyrios Kyrtzidis72b90572010-08-05 09:48:08 +00001839 break;
1840
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001841 case LOCALLY_SCOPED_EXTERNAL_DECLS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001842 // Optimization for the first block.
1843 if (LocallyScopedExternalDecls.empty())
1844 LocallyScopedExternalDecls.swap(Record);
1845 else
1846 LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
1847 Record.begin(), Record.end());
Douglas Gregor14c22f22009-04-22 22:18:58 +00001848 break;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001849
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001850 case SELECTOR_OFFSETS:
Sebastian Redl059612d2010-08-03 21:58:15 +00001851 F.SelectorOffsets = (const uint32_t *)BlobStart;
Sebastian Redl725cd962010-08-04 20:40:17 +00001852 F.LocalNumSelectors = Record[0];
Douglas Gregor83941df2009-04-25 17:48:32 +00001853 break;
1854
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001855 case METHOD_POOL:
Sebastian Redl725cd962010-08-04 20:40:17 +00001856 F.SelectorLookupTableData = (const unsigned char *)BlobStart;
Douglas Gregor83941df2009-04-25 17:48:32 +00001857 if (Record[0])
Sebastian Redl725cd962010-08-04 20:40:17 +00001858 F.SelectorLookupTable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001859 = ASTSelectorLookupTable::Create(
Sebastian Redl725cd962010-08-04 20:40:17 +00001860 F.SelectorLookupTableData + Record[0],
1861 F.SelectorLookupTableData,
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001862 ASTSelectorLookupTrait(*this));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00001863 TotalNumMethodPoolEntries += Record[1];
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001864 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001865
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001866 case REFERENCED_SELECTOR_POOL: {
Sebastian Redl725cd962010-08-04 20:40:17 +00001867 ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
1868 Record.begin(), Record.end());
Fariborz Jahanian32019832010-07-23 19:11:11 +00001869 break;
Sebastian Redl681d7232010-07-27 00:17:23 +00001870 }
Fariborz Jahanian32019832010-07-23 19:11:11 +00001871
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001872 case PP_COUNTER_VALUE:
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00001873 if (!Record.empty() && Listener)
1874 Listener->ReadCounter(Record[0]);
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001875 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001876
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001877 case SOURCE_LOCATION_OFFSETS:
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001878 F.SLocOffsets = (const uint32_t *)BlobStart;
1879 F.LocalNumSLocEntries = Record[0];
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001880 // We cannot delay this until the entire chain is loaded, because then
1881 // source location preloads would also have to be delayed.
1882 // FIXME: Is there a reason not to do that?
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001883 TotalNumSLocEntries += F.LocalNumSLocEntries;
Douglas Gregor445e23e2009-10-05 21:07:28 +00001884 SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001885 break;
1886
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001887 case SOURCE_LOCATION_PRELOADS:
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001888 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
Sebastian Redlc43b54c2010-08-18 23:56:43 +00001889 ASTReadResult Result = ReadSLocEntryRecord(Record[I]);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001890 if (Result != Success)
1891 return Result;
1892 }
1893 break;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001894
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001895 case STAT_CACHE: {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001896 ASTStatCache *MyStatCache =
1897 new ASTStatCache((const unsigned char *)BlobStart + Record[0],
Douglas Gregor52e71082009-10-16 18:18:30 +00001898 (const unsigned char *)BlobStart,
1899 NumStatHits, NumStatMisses);
1900 FileMgr.addStatCache(MyStatCache);
Sebastian Redl9137a522010-07-16 17:50:48 +00001901 F.StatCache = MyStatCache;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001902 break;
Douglas Gregor52e71082009-10-16 18:18:30 +00001903 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00001904
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001905 case EXT_VECTOR_DECLS:
Sebastian Redla9f23682010-07-28 21:38:49 +00001906 // Optimization for the first block.
1907 if (ExtVectorDecls.empty())
1908 ExtVectorDecls.swap(Record);
1909 else
1910 ExtVectorDecls.insert(ExtVectorDecls.end(),
1911 Record.begin(), Record.end());
Douglas Gregorb81c1702009-04-27 20:06:05 +00001912 break;
1913
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001914 case VTABLE_USES:
Sebastian Redl40566802010-08-05 18:21:25 +00001915 // Later tables overwrite earlier ones.
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00001916 VTableUses.swap(Record);
1917 break;
1918
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001919 case DYNAMIC_CLASSES:
Sebastian Redl40566802010-08-05 18:21:25 +00001920 // Optimization for the first block.
1921 if (DynamicClasses.empty())
1922 DynamicClasses.swap(Record);
1923 else
1924 DynamicClasses.insert(DynamicClasses.end(),
1925 Record.begin(), Record.end());
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00001926 break;
1927
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001928 case PENDING_IMPLICIT_INSTANTIATIONS:
Argyrios Kyrtzidis0e036382010-08-05 09:48:16 +00001929 // Optimization for the first block.
1930 if (PendingImplicitInstantiations.empty())
1931 PendingImplicitInstantiations.swap(Record);
1932 else
1933 PendingImplicitInstantiations.insert(
1934 PendingImplicitInstantiations.end(), Record.begin(), Record.end());
1935 break;
1936
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001937 case SEMA_DECL_REFS:
Sebastian Redl40566802010-08-05 18:21:25 +00001938 // Later tables overwrite earlier ones.
Argyrios Kyrtzidis76c38d32010-08-02 07:14:54 +00001939 SemaDeclRefs.swap(Record);
1940 break;
1941
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001942 case ORIGINAL_FILE_NAME:
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001943 // The primary AST will be the last to get here, so it will be the one
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001944 // that's used.
Daniel Dunbar7b5a1212009-11-11 05:29:04 +00001945 ActualOriginalFileName.assign(BlobStart, BlobLen);
1946 OriginalFileName = ActualOriginalFileName;
Douglas Gregore650c8c2009-07-07 00:12:59 +00001947 MaybeAddSystemRootToFilename(OriginalFileName);
Douglas Gregorb64c1932009-05-12 01:31:05 +00001948 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001949
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001950 case VERSION_CONTROL_BRANCH_REVISION: {
Ted Kremenek974be4d2010-02-12 23:31:14 +00001951 const std::string &CurBranch = getClangFullRepositoryVersion();
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001952 llvm::StringRef ASTBranch(BlobStart, BlobLen);
1953 if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
1954 Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
Douglas Gregor445e23e2009-10-05 21:07:28 +00001955 return IgnorePCH;
1956 }
1957 break;
1958 }
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001959
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001960 case MACRO_DEFINITION_OFFSETS:
Sebastian Redl04e6fd42010-07-21 20:07:32 +00001961 F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
1962 F.NumPreallocatedPreprocessingEntities = Record[0];
1963 F.LocalNumMacroDefinitions = Record[1];
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00001964 break;
Sebastian Redl0b17c612010-08-13 00:28:03 +00001965
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001966 case DECL_REPLACEMENTS: {
Sebastian Redl0b17c612010-08-13 00:28:03 +00001967 if (Record.size() % 2 != 0) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001968 Error("invalid DECL_REPLACEMENTS block in AST file");
Sebastian Redl0b17c612010-08-13 00:28:03 +00001969 return Failure;
1970 }
1971 for (unsigned I = 0, N = Record.size(); I != N; I += 2)
Sebastian Redl8538e8d2010-08-18 23:57:32 +00001972 ReplacedDecls[static_cast<DeclID>(Record[I])] =
Sebastian Redl0b17c612010-08-13 00:28:03 +00001973 std::make_pair(&F, Record[I+1]);
1974 break;
1975 }
Sebastian Redl6e50e002010-08-24 22:50:19 +00001976
1977 case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: {
1978 AdditionalTemplateSpecializations &ATS =
1979 AdditionalTemplateSpecializationsPending[Record[0]];
1980 ATS.insert(ATS.end(), Record.begin()+1, Record.end());
1981 break;
1982 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001983 }
Sebastian Redl93fb9ed2010-07-19 20:52:06 +00001984 First = false;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001985 }
Sebastian Redl3c7f4132010-08-18 23:57:06 +00001986 Error("premature end of bitstream in AST file");
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001987 return Failure;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001988}
1989
Sebastian Redl571db7f2010-08-18 23:56:56 +00001990ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
1991 switch(ReadASTCore(FileName)) {
Sebastian Redlcdf3b832010-07-16 20:41:52 +00001992 case Failure: return Failure;
1993 case IgnorePCH: return IgnorePCH;
1994 case Success: break;
1995 }
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00001996
1997 // Here comes stuff that we only do once the entire chain is loaded.
1998
Sebastian Redl518d8cb2010-07-20 21:20:32 +00001999 // Allocate space for loaded identifiers, decls and types.
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002000 unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
Sebastian Redl725cd962010-08-04 20:40:17 +00002001 TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
2002 TotalNumSelectors = 0;
Sebastian Redl12d6da02010-07-19 22:06:55 +00002003 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redl2da08f92010-07-19 22:28:42 +00002004 TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
Sebastian Redl12d6da02010-07-19 22:06:55 +00002005 TotalNumTypes += Chain[I]->LocalNumTypes;
2006 TotalNumDecls += Chain[I]->LocalNumDecls;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002007 TotalNumPreallocatedPreprocessingEntities +=
2008 Chain[I]->NumPreallocatedPreprocessingEntities;
2009 TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
Sebastian Redl725cd962010-08-04 20:40:17 +00002010 TotalNumSelectors += Chain[I]->LocalNumSelectors;
Sebastian Redl12d6da02010-07-19 22:06:55 +00002011 }
Sebastian Redl2da08f92010-07-19 22:28:42 +00002012 IdentifiersLoaded.resize(TotalNumIdentifiers);
Sebastian Redl12d6da02010-07-19 22:06:55 +00002013 TypesLoaded.resize(TotalNumTypes);
2014 DeclsLoaded.resize(TotalNumDecls);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002015 MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
2016 if (PP) {
2017 if (TotalNumIdentifiers > 0)
2018 PP->getHeaderSearchInfo().SetExternalLookup(this);
2019 if (TotalNumPreallocatedPreprocessingEntities > 0) {
2020 if (!PP->getPreprocessingRecord())
2021 PP->createPreprocessingRecord();
2022 PP->getPreprocessingRecord()->SetExternalSource(*this,
2023 TotalNumPreallocatedPreprocessingEntities);
2024 }
2025 }
Sebastian Redl725cd962010-08-04 20:40:17 +00002026 SelectorsLoaded.resize(TotalNumSelectors);
Sebastian Redl12d6da02010-07-19 22:06:55 +00002027
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002028 // Check the predefines buffers.
Douglas Gregorfae3b2f2010-07-27 00:27:13 +00002029 if (!DisableValidation && CheckPredefinesBuffers())
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002030 return IgnorePCH;
2031
2032 if (PP) {
2033 // Initialization of keywords and pragmas occurs before the
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002034 // AST file is read, so there may be some identifiers that were
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002035 // loaded into the IdentifierTable before we intercepted the
2036 // creation of identifiers. Iterate through the list of known
2037 // identifiers and determine whether we have to establish
2038 // preprocessor definitions or top-level identifier declaration
2039 // chains for those identifiers.
2040 //
2041 // We copy the IdentifierInfo pointers to a small vector first,
2042 // since de-serializing declarations or macro definitions can add
2043 // new entries into the identifier table, invalidating the
2044 // iterators.
2045 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
2046 for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
2047 IdEnd = PP->getIdentifierTable().end();
2048 Id != IdEnd; ++Id)
2049 Identifiers.push_back(Id->second);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002050 // We need to search the tables in all files.
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002051 for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002052 ASTIdentifierLookupTable *IdTable
2053 = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
2054 // Not all AST files necessarily have identifier tables, only the useful
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00002055 // ones.
2056 if (!IdTable)
2057 continue;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002058 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
2059 IdentifierInfo *II = Identifiers[I];
2060 // Look in the on-disk hash tables for an entry for this identifier
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002061 ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002062 std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002063 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
Sebastian Redl518d8cb2010-07-20 21:20:32 +00002064 if (Pos == IdTable->end())
2065 continue;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002066
Sebastian Redl518d8cb2010-07-20 21:20:32 +00002067 // Dereferencing the iterator has the effect of populating the
2068 // IdentifierInfo node with the various declarations it needs.
2069 (void)*Pos;
2070 }
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002071 }
2072 }
2073
2074 if (Context)
2075 InitializeContext(*Context);
2076
2077 return Success;
2078}
2079
Sebastian Redl571db7f2010-08-18 23:56:56 +00002080ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002081 Chain.push_back(new PerFileData());
Sebastian Redl9137a522010-07-16 17:50:48 +00002082 PerFileData &F = *Chain.back();
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002083
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002084 // Set the AST file name.
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002085 F.FileName = FileName;
2086
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002087 // Open the AST file.
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002088 //
2089 // FIXME: This shouldn't be here, we should just take a raw_ostream.
2090 std::string ErrStr;
2091 F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
2092 if (!F.Buffer) {
2093 Error(ErrStr.c_str());
2094 return IgnorePCH;
2095 }
2096
2097 // Initialize the stream
2098 F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
2099 (const unsigned char *)F.Buffer->getBufferEnd());
Sebastian Redl9137a522010-07-16 17:50:48 +00002100 llvm::BitstreamCursor &Stream = F.Stream;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002101 Stream.init(F.StreamFile);
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002102 F.SizeInBits = F.Buffer->getBufferSize() * 8;
Sebastian Redlfbd4bf12010-07-17 00:12:06 +00002103
2104 // Sniff for the signature.
2105 if (Stream.Read(8) != 'C' ||
2106 Stream.Read(8) != 'P' ||
2107 Stream.Read(8) != 'C' ||
2108 Stream.Read(8) != 'H') {
2109 Diag(diag::err_not_a_pch_file) << FileName;
2110 return Failure;
2111 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002112
Douglas Gregor2cf26342009-04-09 22:27:44 +00002113 while (!Stream.AtEndOfStream()) {
2114 unsigned Code = Stream.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00002115
Douglas Gregore1d918e2009-04-10 23:10:45 +00002116 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002117 Error("invalid record at top-level of AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002118 return Failure;
2119 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002120
2121 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregor668c1a42009-04-21 22:25:48 +00002122
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002123 // We only know the AST subblock ID.
Douglas Gregor2cf26342009-04-09 22:27:44 +00002124 switch (BlockID) {
2125 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002126 if (Stream.ReadBlockInfoBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002127 Error("malformed BlockInfoBlock in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002128 return Failure;
2129 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002130 break;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002131 case AST_BLOCK_ID:
Sebastian Redl571db7f2010-08-18 23:56:56 +00002132 switch (ReadASTBlock(F)) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002133 case Success:
2134 break;
2135
2136 case Failure:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002137 return Failure;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002138
2139 case IgnorePCH:
Douglas Gregor2bec0412009-04-10 21:16:55 +00002140 // FIXME: We could consider reading through to the end of this
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002141 // AST block, skipping subblocks, to see if there are other
2142 // AST blocks elsewhere.
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002143
2144 // Clear out any preallocated source location entries, so that
2145 // the source manager does not try to resolve them later.
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002146 SourceMgr.ClearPreallocatedSLocEntries();
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002147
2148 // Remove the stat cache.
Sebastian Redl9137a522010-07-16 17:50:48 +00002149 if (F.StatCache)
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002150 FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00002151
Douglas Gregore1d918e2009-04-10 23:10:45 +00002152 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002153 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002154 break;
2155 default:
Douglas Gregore1d918e2009-04-10 23:10:45 +00002156 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002157 Error("malformed block record in AST file");
Douglas Gregore1d918e2009-04-10 23:10:45 +00002158 return Failure;
2159 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002160 break;
2161 }
Mike Stump1eb44332009-09-09 15:08:12 +00002162 }
2163
Sebastian Redlcdf3b832010-07-16 20:41:52 +00002164 return Success;
2165}
2166
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002167void ASTReader::setPreprocessor(Preprocessor &pp) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002168 PP = &pp;
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002169
2170 unsigned TotalNum = 0;
2171 for (unsigned I = 0, N = Chain.size(); I != N; ++I)
2172 TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
2173 if (TotalNum) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002174 if (!PP->getPreprocessingRecord())
2175 PP->createPreprocessingRecord();
Sebastian Redl04e6fd42010-07-21 20:07:32 +00002176 PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002177 }
2178}
2179
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002180void ASTReader::InitializeContext(ASTContext &Ctx) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002181 Context = &Ctx;
2182 assert(Context && "Passed null context!");
2183
2184 assert(PP && "Forgot to set Preprocessor ?");
2185 PP->getIdentifierTable().setExternalIdentifierLookup(this);
2186 PP->getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor88a35862010-01-04 19:18:44 +00002187 PP->setExternalSource(this);
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00002188
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002189 // Load the translation unit declaration
Argyrios Kyrtzidis8871a442010-07-08 17:13:02 +00002190 GetTranslationUnitDecl();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002191
2192 // Load the special types.
2193 Context->setBuiltinVaListType(
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002194 GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
2195 if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002196 Context->setObjCIdType(GetType(Id));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002197 if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002198 Context->setObjCSelType(GetType(Sel));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002199 if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002200 Context->setObjCProtoType(GetType(Proto));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002201 if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002202 Context->setObjCClassType(GetType(Class));
Steve Naroff14108da2009-07-10 23:34:53 +00002203
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002204 if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002205 Context->setCFConstantStringType(GetType(String));
Mike Stump1eb44332009-09-09 15:08:12 +00002206 if (unsigned FastEnum
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002207 = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002208 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002209 if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002210 QualType FileType = GetType(File);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002211 if (FileType.isNull()) {
2212 Error("FILE type is NULL");
2213 return;
2214 }
John McCall183700f2009-09-21 23:43:11 +00002215 if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002216 Context->setFILEDecl(Typedef->getDecl());
2217 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002218 const TagType *Tag = FileType->getAs<TagType>();
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002219 if (!Tag) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002220 Error("Invalid FILE type in AST file");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002221 return;
2222 }
Douglas Gregorc29f77b2009-07-07 16:35:42 +00002223 Context->setFILEDecl(Tag->getDecl());
2224 }
2225 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002226 if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
Mike Stump782fa302009-07-28 02:25:19 +00002227 QualType Jmp_bufType = GetType(Jmp_buf);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002228 if (Jmp_bufType.isNull()) {
2229 Error("jmp_bug type is NULL");
2230 return;
2231 }
John McCall183700f2009-09-21 23:43:11 +00002232 if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
Mike Stump782fa302009-07-28 02:25:19 +00002233 Context->setjmp_bufDecl(Typedef->getDecl());
2234 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002235 const TagType *Tag = Jmp_bufType->getAs<TagType>();
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002236 if (!Tag) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002237 Error("Invalid jmp_buf type in AST file");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002238 return;
2239 }
Mike Stump782fa302009-07-28 02:25:19 +00002240 Context->setjmp_bufDecl(Tag->getDecl());
2241 }
2242 }
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002243 if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
Mike Stump782fa302009-07-28 02:25:19 +00002244 QualType Sigjmp_bufType = GetType(Sigjmp_buf);
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002245 if (Sigjmp_bufType.isNull()) {
2246 Error("sigjmp_buf type is NULL");
2247 return;
2248 }
John McCall183700f2009-09-21 23:43:11 +00002249 if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
Mike Stump782fa302009-07-28 02:25:19 +00002250 Context->setsigjmp_bufDecl(Typedef->getDecl());
2251 else {
Ted Kremenek6217b802009-07-29 21:53:49 +00002252 const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002253 assert(Tag && "Invalid sigjmp_buf type in AST file");
Mike Stump782fa302009-07-28 02:25:19 +00002254 Context->setsigjmp_bufDecl(Tag->getDecl());
2255 }
2256 }
Mike Stump1eb44332009-09-09 15:08:12 +00002257 if (unsigned ObjCIdRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002258 = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
Douglas Gregord1571ac2009-08-21 00:27:50 +00002259 Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
Mike Stump1eb44332009-09-09 15:08:12 +00002260 if (unsigned ObjCClassRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002261 = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Douglas Gregord1571ac2009-08-21 00:27:50 +00002262 Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002263 if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Mike Stumpadaaad32009-10-20 02:12:22 +00002264 Context->setBlockDescriptorType(GetType(String));
Mike Stump083c25e2009-10-22 00:49:09 +00002265 if (unsigned String
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002266 = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Mike Stump083c25e2009-10-22 00:49:09 +00002267 Context->setBlockDescriptorExtendedType(GetType(String));
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002268 if (unsigned ObjCSelRedef
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002269 = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002270 Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002271 if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
Fariborz Jahanian2bb5dda2010-04-23 17:41:07 +00002272 Context->setNSConstantStringType(GetType(String));
Argyrios Kyrtzidis00611382010-07-04 21:44:19 +00002273
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002274 if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
Argyrios Kyrtzidis00611382010-07-04 21:44:19 +00002275 Context->setInt128Installed();
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002276}
2277
Douglas Gregorb64c1932009-05-12 01:31:05 +00002278/// \brief Retrieve the name of the original source file name
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002279/// directly from the AST file, without actually loading the AST
Douglas Gregorb64c1932009-05-12 01:31:05 +00002280/// file.
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002281std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
Daniel Dunbar93ebb1b2009-12-03 09:13:06 +00002282 Diagnostic &Diags) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002283 // Open the AST file.
Douglas Gregorb64c1932009-05-12 01:31:05 +00002284 std::string ErrStr;
2285 llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002286 Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr));
Douglas Gregorb64c1932009-05-12 01:31:05 +00002287 if (!Buffer) {
Daniel Dunbar93ebb1b2009-12-03 09:13:06 +00002288 Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002289 return std::string();
2290 }
2291
2292 // Initialize the stream
2293 llvm::BitstreamReader StreamFile;
2294 llvm::BitstreamCursor Stream;
Mike Stump1eb44332009-09-09 15:08:12 +00002295 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
Douglas Gregorb64c1932009-05-12 01:31:05 +00002296 (const unsigned char *)Buffer->getBufferEnd());
2297 Stream.init(StreamFile);
2298
2299 // Sniff for the signature.
2300 if (Stream.Read(8) != 'C' ||
2301 Stream.Read(8) != 'P' ||
2302 Stream.Read(8) != 'C' ||
2303 Stream.Read(8) != 'H') {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002304 Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002305 return std::string();
2306 }
2307
2308 RecordData Record;
2309 while (!Stream.AtEndOfStream()) {
2310 unsigned Code = Stream.ReadCode();
Mike Stump1eb44332009-09-09 15:08:12 +00002311
Douglas Gregorb64c1932009-05-12 01:31:05 +00002312 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2313 unsigned BlockID = Stream.ReadSubBlockID();
Mike Stump1eb44332009-09-09 15:08:12 +00002314
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002315 // We only know the AST subblock ID.
Douglas Gregorb64c1932009-05-12 01:31:05 +00002316 switch (BlockID) {
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002317 case AST_BLOCK_ID:
2318 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002319 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002320 return std::string();
2321 }
2322 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002323
Douglas Gregorb64c1932009-05-12 01:31:05 +00002324 default:
2325 if (Stream.SkipBlock()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002326 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002327 return std::string();
2328 }
2329 break;
2330 }
2331 continue;
2332 }
2333
2334 if (Code == llvm::bitc::END_BLOCK) {
2335 if (Stream.ReadBlockEnd()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002336 Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
Douglas Gregorb64c1932009-05-12 01:31:05 +00002337 return std::string();
2338 }
2339 continue;
2340 }
2341
2342 if (Code == llvm::bitc::DEFINE_ABBREV) {
2343 Stream.ReadAbbrevRecord();
2344 continue;
2345 }
2346
2347 Record.clear();
2348 const char *BlobStart = 0;
2349 unsigned BlobLen = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00002350 if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002351 == ORIGINAL_FILE_NAME)
Douglas Gregorb64c1932009-05-12 01:31:05 +00002352 return std::string(BlobStart, BlobLen);
Mike Stump1eb44332009-09-09 15:08:12 +00002353 }
Douglas Gregorb64c1932009-05-12 01:31:05 +00002354
2355 return std::string();
2356}
2357
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002358/// \brief Parse the record that corresponds to a LangOptions data
2359/// structure.
2360///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002361/// This routine parses the language options from the AST file and then gives
2362/// them to the AST listener if one is set.
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002363///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002364/// \returns true if the listener deems the file unacceptable, false otherwise.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002365bool ASTReader::ParseLanguageOptions(
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002366 const llvm::SmallVectorImpl<uint64_t> &Record) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002367 if (Listener) {
2368 LangOptions LangOpts;
Mike Stump1eb44332009-09-09 15:08:12 +00002369
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002370 #define PARSE_LANGOPT(Option) \
2371 LangOpts.Option = Record[Idx]; \
2372 ++Idx
Mike Stump1eb44332009-09-09 15:08:12 +00002373
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002374 unsigned Idx = 0;
2375 PARSE_LANGOPT(Trigraphs);
2376 PARSE_LANGOPT(BCPLComment);
2377 PARSE_LANGOPT(DollarIdents);
2378 PARSE_LANGOPT(AsmPreprocessor);
2379 PARSE_LANGOPT(GNUMode);
Chandler Carrutheb5d7b72010-04-17 20:17:31 +00002380 PARSE_LANGOPT(GNUKeywords);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002381 PARSE_LANGOPT(ImplicitInt);
2382 PARSE_LANGOPT(Digraphs);
2383 PARSE_LANGOPT(HexFloats);
2384 PARSE_LANGOPT(C99);
2385 PARSE_LANGOPT(Microsoft);
2386 PARSE_LANGOPT(CPlusPlus);
2387 PARSE_LANGOPT(CPlusPlus0x);
2388 PARSE_LANGOPT(CXXOperatorNames);
2389 PARSE_LANGOPT(ObjC1);
2390 PARSE_LANGOPT(ObjC2);
2391 PARSE_LANGOPT(ObjCNonFragileABI);
Fariborz Jahanian412e7982010-02-09 19:31:38 +00002392 PARSE_LANGOPT(ObjCNonFragileABI2);
Fariborz Jahanian4c9d8d02010-04-22 21:01:59 +00002393 PARSE_LANGOPT(NoConstantCFStrings);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002394 PARSE_LANGOPT(PascalStrings);
2395 PARSE_LANGOPT(WritableStrings);
2396 PARSE_LANGOPT(LaxVectorConversions);
Nate Begemanb9e7e632009-06-25 23:01:11 +00002397 PARSE_LANGOPT(AltiVec);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002398 PARSE_LANGOPT(Exceptions);
Daniel Dunbar73482882010-02-10 18:48:44 +00002399 PARSE_LANGOPT(SjLjExceptions);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002400 PARSE_LANGOPT(NeXTRuntime);
2401 PARSE_LANGOPT(Freestanding);
2402 PARSE_LANGOPT(NoBuiltin);
2403 PARSE_LANGOPT(ThreadsafeStatics);
Douglas Gregor972d9542009-09-03 14:36:33 +00002404 PARSE_LANGOPT(POSIXThreads);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002405 PARSE_LANGOPT(Blocks);
2406 PARSE_LANGOPT(EmitAllDecls);
2407 PARSE_LANGOPT(MathErrno);
Chris Lattnera4d71452010-06-26 21:25:03 +00002408 LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
2409 Record[Idx++]);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002410 PARSE_LANGOPT(HeinousExtensions);
2411 PARSE_LANGOPT(Optimize);
2412 PARSE_LANGOPT(OptimizeSize);
2413 PARSE_LANGOPT(Static);
2414 PARSE_LANGOPT(PICLevel);
2415 PARSE_LANGOPT(GNUInline);
2416 PARSE_LANGOPT(NoInline);
2417 PARSE_LANGOPT(AccessControl);
2418 PARSE_LANGOPT(CharIsSigned);
John Thompsona6fda122009-11-05 20:14:16 +00002419 PARSE_LANGOPT(ShortWChar);
Chris Lattnera4d71452010-06-26 21:25:03 +00002420 LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
2421 LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
Daniel Dunbarab8e2812009-09-21 04:16:19 +00002422 LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Chris Lattnera4d71452010-06-26 21:25:03 +00002423 Record[Idx++]);
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002424 PARSE_LANGOPT(InstantiationDepth);
Nate Begemanb9e7e632009-06-25 23:01:11 +00002425 PARSE_LANGOPT(OpenCL);
Mike Stump9c276ae2009-12-12 01:27:46 +00002426 PARSE_LANGOPT(CatchUndefined);
2427 // FIXME: Missing ElideConstructors?!
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002428 #undef PARSE_LANGOPT
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002429
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00002430 return Listener->ReadLanguageOptions(LangOpts);
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002431 }
Douglas Gregor0a0428e2009-04-10 20:39:37 +00002432
2433 return false;
2434}
2435
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002436void ASTReader::ReadPreprocessedEntities() {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +00002437 ReadDefinedMacros();
2438}
2439
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002440/// \brief Get the correct cursor and offset for loading a type.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002441ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002442 PerFileData *F = 0;
2443 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
2444 F = Chain[N - I - 1];
2445 if (Index < F->LocalNumTypes)
2446 break;
2447 Index -= F->LocalNumTypes;
2448 }
2449 assert(F && F->LocalNumTypes > Index && "Broken chain");
Sebastian Redl971dd442010-07-20 22:55:31 +00002450 return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002451}
2452
2453/// \brief Read and return the type with the given index..
Douglas Gregor2cf26342009-04-09 22:27:44 +00002454///
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002455/// The index is the type ID, shifted and minus the number of predefs. This
2456/// routine actually reads the record corresponding to the type at the given
2457/// location. It is a helper routine for GetType, which deals with reading type
2458/// IDs.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002459QualType ASTReader::ReadTypeRecord(unsigned Index) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002460 RecordLocation Loc = TypeCursorForIndex(Index);
Sebastian Redl971dd442010-07-20 22:55:31 +00002461 llvm::BitstreamCursor &DeclsCursor = *Loc.first;
Sebastian Redl9137a522010-07-16 17:50:48 +00002462
Douglas Gregor0b748912009-04-14 21:18:50 +00002463 // Keep track of where we are in the stream, then jump back there
2464 // after reading this type.
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002465 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00002466
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00002467 ReadingKindTracker ReadingKind(Read_Type, *this);
Sebastian Redl27372b42010-08-11 18:52:41 +00002468
Douglas Gregord89275b2009-07-06 18:54:52 +00002469 // Note that we are loading a type record.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00002470 Deserializing AType(this);
Mike Stump1eb44332009-09-09 15:08:12 +00002471
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00002472 DeclsCursor.JumpToBit(Loc.second);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002473 RecordData Record;
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002474 unsigned Code = DeclsCursor.ReadCode();
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002475 switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
2476 case TYPE_EXT_QUAL: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002477 if (Record.size() != 2) {
2478 Error("Incorrect encoding of extended qualifier type");
2479 return QualType();
2480 }
Douglas Gregor6d473962009-04-15 22:00:08 +00002481 QualType Base = GetType(Record[0]);
John McCall0953e762009-09-24 19:53:00 +00002482 Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
2483 return Context->getQualifiedType(Base, Quals);
Douglas Gregor6d473962009-04-15 22:00:08 +00002484 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002485
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002486 case TYPE_COMPLEX: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002487 if (Record.size() != 1) {
2488 Error("Incorrect encoding of complex type");
2489 return QualType();
2490 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002491 QualType ElemType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002492 return Context->getComplexType(ElemType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002493 }
2494
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002495 case TYPE_POINTER: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002496 if (Record.size() != 1) {
2497 Error("Incorrect encoding of pointer type");
2498 return QualType();
2499 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002500 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002501 return Context->getPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002502 }
2503
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002504 case TYPE_BLOCK_POINTER: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002505 if (Record.size() != 1) {
2506 Error("Incorrect encoding of block pointer type");
2507 return QualType();
2508 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002509 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002510 return Context->getBlockPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002511 }
2512
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002513 case TYPE_LVALUE_REFERENCE: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002514 if (Record.size() != 1) {
2515 Error("Incorrect encoding of lvalue reference type");
2516 return QualType();
2517 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002518 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002519 return Context->getLValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002520 }
2521
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002522 case TYPE_RVALUE_REFERENCE: {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002523 if (Record.size() != 1) {
2524 Error("Incorrect encoding of rvalue reference type");
2525 return QualType();
2526 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002527 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002528 return Context->getRValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00002529 }
2530
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002531 case TYPE_MEMBER_POINTER: {
Argyrios Kyrtzidis240437b2010-07-02 11:55:15 +00002532 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002533 Error("Incorrect encoding of member pointer type");
2534 return QualType();
2535 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002536 QualType PointeeType = GetType(Record[0]);
2537 QualType ClassType = GetType(Record[1]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002538 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregor2cf26342009-04-09 22:27:44 +00002539 }
2540
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002541 case TYPE_CONSTANT_ARRAY: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002542 QualType ElementType = GetType(Record[0]);
2543 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2544 unsigned IndexTypeQuals = Record[2];
2545 unsigned Idx = 3;
2546 llvm::APInt Size = ReadAPInt(Record, Idx);
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002547 return Context->getConstantArrayType(ElementType, Size,
2548 ASM, IndexTypeQuals);
2549 }
2550
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002551 case TYPE_INCOMPLETE_ARRAY: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002552 QualType ElementType = GetType(Record[0]);
2553 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2554 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002555 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002556 }
2557
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002558 case TYPE_VARIABLE_ARRAY: {
Douglas Gregor0b748912009-04-14 21:18:50 +00002559 QualType ElementType = GetType(Record[0]);
2560 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2561 unsigned IndexTypeQuals = Record[2];
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002562 SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
2563 SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
Sebastian Redl577d4792010-07-22 22:43:28 +00002564 return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor),
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00002565 ASM, IndexTypeQuals,
2566 SourceRange(LBLoc, RBLoc));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002567 }
2568
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002569 case TYPE_VECTOR: {
Chris Lattner788b0fd2010-06-23 06:00:24 +00002570 if (Record.size() != 3) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002571 Error("incorrect encoding of vector type in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002572 return QualType();
2573 }
2574
2575 QualType ElementType = GetType(Record[0]);
2576 unsigned NumElements = Record[1];
Chris Lattner788b0fd2010-06-23 06:00:24 +00002577 unsigned AltiVecSpec = Record[2];
2578 return Context->getVectorType(ElementType, NumElements,
2579 (VectorType::AltiVecSpecific)AltiVecSpec);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002580 }
2581
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002582 case TYPE_EXT_VECTOR: {
Chris Lattner788b0fd2010-06-23 06:00:24 +00002583 if (Record.size() != 3) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002584 Error("incorrect encoding of extended vector type in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002585 return QualType();
2586 }
2587
2588 QualType ElementType = GetType(Record[0]);
2589 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002590 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002591 }
2592
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002593 case TYPE_FUNCTION_NO_PROTO: {
Rafael Espindola425ef722010-03-30 22:15:11 +00002594 if (Record.size() != 4) {
Douglas Gregora02b1472009-04-28 21:53:25 +00002595 Error("incorrect encoding of no-proto function type");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002596 return QualType();
2597 }
2598 QualType ResultType = GetType(Record[0]);
Rafael Espindola425ef722010-03-30 22:15:11 +00002599 FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
Rafael Espindola264ba482010-03-30 20:24:48 +00002600 return Context->getFunctionNoProtoType(ResultType, Info);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002601 }
2602
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002603 case TYPE_FUNCTION_PROTO: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002604 QualType ResultType = GetType(Record[0]);
Douglas Gregor91236662009-12-22 18:11:50 +00002605 bool NoReturn = Record[1];
Rafael Espindola425ef722010-03-30 22:15:11 +00002606 unsigned RegParm = Record[2];
2607 CallingConv CallConv = (CallingConv)Record[3];
2608 unsigned Idx = 4;
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002609 unsigned NumParams = Record[Idx++];
2610 llvm::SmallVector<QualType, 16> ParamTypes;
2611 for (unsigned I = 0; I != NumParams; ++I)
2612 ParamTypes.push_back(GetType(Record[Idx++]));
2613 bool isVariadic = Record[Idx++];
2614 unsigned Quals = Record[Idx++];
Sebastian Redl465226e2009-05-27 22:11:52 +00002615 bool hasExceptionSpec = Record[Idx++];
2616 bool hasAnyExceptionSpec = Record[Idx++];
2617 unsigned NumExceptions = Record[Idx++];
2618 llvm::SmallVector<QualType, 2> Exceptions;
2619 for (unsigned I = 0; I != NumExceptions; ++I)
2620 Exceptions.push_back(GetType(Record[Idx++]));
Jay Foadbeaaccd2009-05-21 09:52:38 +00002621 return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
Sebastian Redl465226e2009-05-27 22:11:52 +00002622 isVariadic, Quals, hasExceptionSpec,
2623 hasAnyExceptionSpec, NumExceptions,
Rafael Espindola264ba482010-03-30 20:24:48 +00002624 Exceptions.data(),
Rafael Espindola425ef722010-03-30 22:15:11 +00002625 FunctionType::ExtInfo(NoReturn, RegParm,
2626 CallConv));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002627 }
2628
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002629 case TYPE_UNRESOLVED_USING:
John McCalled976492009-12-04 22:46:56 +00002630 return Context->getTypeDeclType(
2631 cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
2632
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002633 case TYPE_TYPEDEF: {
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002634 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002635 Error("incorrect encoding of typedef type");
2636 return QualType();
2637 }
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002638 TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
2639 QualType Canonical = GetType(Record[1]);
2640 return Context->getTypedefType(Decl, Canonical);
2641 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002642
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002643 case TYPE_TYPEOF_EXPR:
Sebastian Redl577d4792010-07-22 22:43:28 +00002644 return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002645
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002646 case TYPE_TYPEOF: {
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002647 if (Record.size() != 1) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002648 Error("incorrect encoding of typeof(type) in AST file");
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002649 return QualType();
2650 }
2651 QualType UnderlyingType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00002652 return Context->getTypeOfType(UnderlyingType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002653 }
Mike Stump1eb44332009-09-09 15:08:12 +00002654
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002655 case TYPE_DECLTYPE:
Sebastian Redl577d4792010-07-22 22:43:28 +00002656 return Context->getDecltypeType(ReadExpr(DeclsCursor));
Anders Carlsson395b4752009-06-24 19:06:50 +00002657
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002658 case TYPE_RECORD: {
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002659 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002660 Error("incorrect encoding of record type");
2661 return QualType();
2662 }
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002663 bool IsDependent = Record[0];
2664 QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
2665 T->Dependent = IsDependent;
2666 return T;
2667 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002668
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002669 case TYPE_ENUM: {
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002670 if (Record.size() != 2) {
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00002671 Error("incorrect encoding of enum type");
2672 return QualType();
2673 }
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002674 bool IsDependent = Record[0];
2675 QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
2676 T->Dependent = IsDependent;
2677 return T;
2678 }
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00002679
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002680 case TYPE_ELABORATED: {
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002681 unsigned Idx = 0;
2682 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2683 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2684 QualType NamedType = GetType(Record[Idx++]);
2685 return Context->getElaboratedType(Keyword, NNS, NamedType);
John McCall7da24312009-09-05 00:15:47 +00002686 }
2687
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002688 case TYPE_OBJC_INTERFACE: {
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002689 unsigned Idx = 0;
2690 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
John McCallc12c5bb2010-05-15 11:32:37 +00002691 return Context->getObjCInterfaceType(ItfD);
2692 }
2693
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002694 case TYPE_OBJC_OBJECT: {
John McCallc12c5bb2010-05-15 11:32:37 +00002695 unsigned Idx = 0;
2696 QualType Base = GetType(Record[Idx++]);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002697 unsigned NumProtos = Record[Idx++];
2698 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
2699 for (unsigned I = 0; I != NumProtos; ++I)
2700 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
John McCallc12c5bb2010-05-15 11:32:37 +00002701 return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00002702 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00002703
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002704 case TYPE_OBJC_OBJECT_POINTER: {
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00002705 unsigned Idx = 0;
John McCallc12c5bb2010-05-15 11:32:37 +00002706 QualType Pointee = GetType(Record[Idx++]);
2707 return Context->getObjCObjectPointerType(Pointee);
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00002708 }
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002709
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002710 case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
John McCall49a832b2009-10-18 09:09:24 +00002711 unsigned Idx = 0;
2712 QualType Parm = GetType(Record[Idx++]);
2713 QualType Replacement = GetType(Record[Idx++]);
2714 return
2715 Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2716 Replacement);
2717 }
John McCall3cb0ebd2010-03-10 03:28:59 +00002718
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002719 case TYPE_INJECTED_CLASS_NAME: {
John McCall3cb0ebd2010-03-10 03:28:59 +00002720 CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
2721 QualType TST = GetType(Record[1]); // probably derivable
Argyrios Kyrtzidis43921b52010-07-02 11:55:20 +00002722 // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
Sebastian Redl3c7f4132010-08-18 23:57:06 +00002723 // for AST reading, too much interdependencies.
Argyrios Kyrtzidis43921b52010-07-02 11:55:20 +00002724 return
2725 QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
John McCall3cb0ebd2010-03-10 03:28:59 +00002726 }
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +00002727
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002728 case TYPE_TEMPLATE_TYPE_PARM: {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002729 unsigned Idx = 0;
2730 unsigned Depth = Record[Idx++];
2731 unsigned Index = Record[Idx++];
2732 bool Pack = Record[Idx++];
2733 IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
2734 return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
2735 }
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002736
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002737 case TYPE_DEPENDENT_NAME: {
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002738 unsigned Idx = 0;
2739 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2740 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2741 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
Argyrios Kyrtzidisf48d45e2010-07-02 11:55:24 +00002742 QualType Canon = GetType(Record[Idx++]);
2743 return Context->getDependentNameType(Keyword, NNS, Name, Canon);
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +00002744 }
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002745
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002746 case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002747 unsigned Idx = 0;
2748 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2749 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2750 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
2751 unsigned NumArgs = Record[Idx++];
2752 llvm::SmallVector<TemplateArgument, 8> Args;
2753 Args.reserve(NumArgs);
2754 while (NumArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00002755 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis3acad622010-06-25 16:24:58 +00002756 return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
2757 Args.size(), Args.data());
2758 }
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002759
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002760 case TYPE_DEPENDENT_SIZED_ARRAY: {
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002761 unsigned Idx = 0;
2762
2763 // ArrayType
2764 QualType ElementType = GetType(Record[Idx++]);
2765 ArrayType::ArraySizeModifier ASM
2766 = (ArrayType::ArraySizeModifier)Record[Idx++];
2767 unsigned IndexTypeQuals = Record[Idx++];
2768
2769 // DependentSizedArrayType
Sebastian Redl577d4792010-07-22 22:43:28 +00002770 Expr *NumElts = ReadExpr(DeclsCursor);
Argyrios Kyrtzidisae8b17f2010-06-30 08:49:25 +00002771 SourceRange Brackets = ReadSourceRange(Record, Idx);
2772
2773 return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
2774 IndexTypeQuals, Brackets);
2775 }
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +00002776
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002777 case TYPE_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002778 unsigned Idx = 0;
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002779 bool IsDependent = Record[Idx++];
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002780 TemplateName Name = ReadTemplateName(Record, Idx);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002781 llvm::SmallVector<TemplateArgument, 8> Args;
Sebastian Redl577d4792010-07-22 22:43:28 +00002782 ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00002783 QualType Canon = GetType(Record[Idx++]);
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002784 QualType T;
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002785 if (Canon.isNull())
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002786 T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
2787 Args.size());
Argyrios Kyrtzidis9763e222010-07-02 11:55:11 +00002788 else
Argyrios Kyrtzidisbe191102010-07-08 13:09:53 +00002789 T = Context->getTemplateSpecializationType(Name, Args.data(),
2790 Args.size(), Canon);
2791 T->Dependent = IsDependent;
2792 return T;
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00002793 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002794 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00002795 // Suppress a GCC warning
2796 return QualType();
2797}
2798
John McCalla1ee0c52009-10-16 21:56:05 +00002799namespace {
2800
2801class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002802 ASTReader &Reader;
Sebastian Redl577d4792010-07-22 22:43:28 +00002803 llvm::BitstreamCursor &DeclsCursor;
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002804 const ASTReader::RecordData &Record;
John McCalla1ee0c52009-10-16 21:56:05 +00002805 unsigned &Idx;
2806
2807public:
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002808 TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
2809 const ASTReader::RecordData &Record, unsigned &Idx)
Sebastian Redl577d4792010-07-22 22:43:28 +00002810 : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
John McCalla1ee0c52009-10-16 21:56:05 +00002811
John McCall51bd8032009-10-18 01:05:36 +00002812 // We want compile-time assurance that we've enumerated all of
2813 // these, so unfortunately we have to declare them first, then
2814 // define them out-of-line.
2815#define ABSTRACT_TYPELOC(CLASS, PARENT)
John McCalla1ee0c52009-10-16 21:56:05 +00002816#define TYPELOC(CLASS, PARENT) \
John McCall51bd8032009-10-18 01:05:36 +00002817 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
John McCalla1ee0c52009-10-16 21:56:05 +00002818#include "clang/AST/TypeLocNodes.def"
2819
John McCall51bd8032009-10-18 01:05:36 +00002820 void VisitFunctionTypeLoc(FunctionTypeLoc);
2821 void VisitArrayTypeLoc(ArrayTypeLoc);
John McCalla1ee0c52009-10-16 21:56:05 +00002822};
2823
2824}
2825
John McCall51bd8032009-10-18 01:05:36 +00002826void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
John McCalla1ee0c52009-10-16 21:56:05 +00002827 // nothing to do
2828}
John McCall51bd8032009-10-18 01:05:36 +00002829void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Douglas Gregorddf889a2010-01-18 18:04:31 +00002830 TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2831 if (TL.needsExtraLocalData()) {
2832 TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2833 TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2834 TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2835 TL.setModeAttr(Record[Idx++]);
2836 }
John McCalla1ee0c52009-10-16 21:56:05 +00002837}
John McCall51bd8032009-10-18 01:05:36 +00002838void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2839 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002840}
John McCall51bd8032009-10-18 01:05:36 +00002841void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2842 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002843}
John McCall51bd8032009-10-18 01:05:36 +00002844void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2845 TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002846}
John McCall51bd8032009-10-18 01:05:36 +00002847void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2848 TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002849}
John McCall51bd8032009-10-18 01:05:36 +00002850void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2851 TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002852}
John McCall51bd8032009-10-18 01:05:36 +00002853void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2854 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002855}
John McCall51bd8032009-10-18 01:05:36 +00002856void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2857 TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2858 TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002859 if (Record[Idx++])
Sebastian Redl577d4792010-07-22 22:43:28 +00002860 TL.setSizeExpr(Reader.ReadExpr(DeclsCursor));
Douglas Gregor61d60ee2009-10-17 00:13:19 +00002861 else
John McCall51bd8032009-10-18 01:05:36 +00002862 TL.setSizeExpr(0);
2863}
2864void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2865 VisitArrayTypeLoc(TL);
2866}
2867void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2868 VisitArrayTypeLoc(TL);
2869}
2870void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2871 VisitArrayTypeLoc(TL);
2872}
2873void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2874 DependentSizedArrayTypeLoc TL) {
2875 VisitArrayTypeLoc(TL);
2876}
2877void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2878 DependentSizedExtVectorTypeLoc TL) {
2879 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2880}
2881void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2882 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2883}
2884void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2885 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2886}
2887void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2888 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2889 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2890 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
John McCall86acc2a2009-10-23 01:28:53 +00002891 TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
John McCall51bd8032009-10-18 01:05:36 +00002892 }
2893}
2894void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2895 VisitFunctionTypeLoc(TL);
2896}
2897void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2898 VisitFunctionTypeLoc(TL);
2899}
John McCalled976492009-12-04 22:46:56 +00002900void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2901 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2902}
John McCall51bd8032009-10-18 01:05:36 +00002903void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2904 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2905}
2906void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
John McCallcfb708c2010-01-13 20:03:27 +00002907 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2908 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2909 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall51bd8032009-10-18 01:05:36 +00002910}
2911void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
John McCallcfb708c2010-01-13 20:03:27 +00002912 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2913 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2914 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Sebastian Redl577d4792010-07-22 22:43:28 +00002915 TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002916}
2917void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2918 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2919}
2920void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2921 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2922}
2923void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2924 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2925}
John McCall51bd8032009-10-18 01:05:36 +00002926void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2927 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2928}
John McCall49a832b2009-10-18 09:09:24 +00002929void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2930 SubstTemplateTypeParmTypeLoc TL) {
2931 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2932}
John McCall51bd8032009-10-18 01:05:36 +00002933void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2934 TemplateSpecializationTypeLoc TL) {
John McCall833ca992009-10-29 08:12:44 +00002935 TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2936 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2937 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2938 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2939 TL.setArgLocInfo(i,
2940 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00002941 DeclsCursor, Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002942}
Abramo Bagnara465d41b2010-05-11 21:36:43 +00002943void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00002944 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2945 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002946}
John McCall3cb0ebd2010-03-10 03:28:59 +00002947void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
2948 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2949}
Douglas Gregor4714c122010-03-31 17:34:00 +00002950void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00002951 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2952 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall51bd8032009-10-18 01:05:36 +00002953 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2954}
John McCall33500952010-06-11 00:33:02 +00002955void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
2956 DependentTemplateSpecializationTypeLoc TL) {
2957 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2958 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
2959 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2960 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2961 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2962 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
2963 TL.setArgLocInfo(I,
2964 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00002965 DeclsCursor, Record, Idx));
John McCall33500952010-06-11 00:33:02 +00002966}
John McCall51bd8032009-10-18 01:05:36 +00002967void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2968 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCallc12c5bb2010-05-15 11:32:37 +00002969}
2970void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
2971 TL.setHasBaseTypeAsWritten(Record[Idx++]);
John McCall51bd8032009-10-18 01:05:36 +00002972 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2973 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2974 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2975 TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCalla1ee0c52009-10-16 21:56:05 +00002976}
John McCall54e14c42009-10-22 22:37:11 +00002977void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2978 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall54e14c42009-10-22 22:37:11 +00002979}
John McCalla1ee0c52009-10-16 21:56:05 +00002980
Sebastian Redlc43b54c2010-08-18 23:56:43 +00002981TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00002982 const RecordData &Record,
John McCalla1ee0c52009-10-16 21:56:05 +00002983 unsigned &Idx) {
2984 QualType InfoTy = GetType(Record[Idx++]);
2985 if (InfoTy.isNull())
2986 return 0;
2987
John McCalla93c9342009-12-07 02:54:59 +00002988 TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
Sebastian Redl577d4792010-07-22 22:43:28 +00002989 TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
John McCalla93c9342009-12-07 02:54:59 +00002990 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
John McCalla1ee0c52009-10-16 21:56:05 +00002991 TLR.Visit(TL);
John McCalla93c9342009-12-07 02:54:59 +00002992 return TInfo;
John McCalla1ee0c52009-10-16 21:56:05 +00002993}
Douglas Gregor2cf26342009-04-09 22:27:44 +00002994
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002995QualType ASTReader::GetType(TypeID ID) {
John McCall0953e762009-09-24 19:53:00 +00002996 unsigned FastQuals = ID & Qualifiers::FastMask;
2997 unsigned Index = ID >> Qualifiers::FastWidth;
Douglas Gregor2cf26342009-04-09 22:27:44 +00002998
Sebastian Redl8538e8d2010-08-18 23:57:32 +00002999 if (Index < NUM_PREDEF_TYPE_IDS) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00003000 QualType T;
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003001 switch ((PredefinedTypeIDs)Index) {
3002 case PREDEF_TYPE_NULL_ID: return QualType();
3003 case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
3004 case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003005
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003006 case PREDEF_TYPE_CHAR_U_ID:
3007 case PREDEF_TYPE_CHAR_S_ID:
Douglas Gregor2cf26342009-04-09 22:27:44 +00003008 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003009 T = Context->CharTy;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003010 break;
3011
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003012 case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
3013 case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
3014 case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
3015 case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
3016 case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
3017 case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
3018 case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
3019 case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
3020 case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
3021 case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
3022 case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
3023 case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
3024 case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
3025 case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
3026 case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
3027 case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
3028 case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
3029 case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
3030 case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
3031 case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
3032 case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
3033 case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
3034 case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
3035 case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003036 }
3037
3038 assert(!T.isNull() && "Unknown predefined type");
John McCall0953e762009-09-24 19:53:00 +00003039 return T.withFastQualifiers(FastQuals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003040 }
3041
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003042 Index -= NUM_PREDEF_TYPE_IDS;
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00003043 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Sebastian Redl07a353c2010-07-14 20:26:45 +00003044 if (TypesLoaded[Index].isNull()) {
Sebastian Redlaaec0aa2010-07-20 22:37:49 +00003045 TypesLoaded[Index] = ReadTypeRecord(Index);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003046 TypesLoaded[Index]->setFromAST();
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +00003047 TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003048 if (DeserializationListener)
Argyrios Kyrtzidisc8e5d512010-08-20 16:03:59 +00003049 DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
Sebastian Redl1476ed42010-07-16 16:36:56 +00003050 TypesLoaded[Index]);
Sebastian Redl07a353c2010-07-14 20:26:45 +00003051 }
Mike Stump1eb44332009-09-09 15:08:12 +00003052
John McCall0953e762009-09-24 19:53:00 +00003053 return TypesLoaded[Index].withFastQualifiers(FastQuals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003054}
3055
Argyrios Kyrtzidis5d267682010-08-20 16:04:27 +00003056TypeID ASTReader::GetTypeID(QualType T) const {
3057 return MakeTypeID(T,
3058 std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
3059}
3060
3061TypeIdx ASTReader::GetTypeIdx(QualType T) const {
3062 if (T.isNull())
3063 return TypeIdx();
3064 assert(!T.getLocalFastQualifiers());
3065
3066 TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3067 // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
3068 // comparing keys of ASTDeclContextNameLookupTable.
3069 // If the type didn't come from the AST file use a specially marked index
3070 // so that any hash/key comparison fail since no such index is stored
3071 // in a AST file.
3072 if (I == TypeIdxs.end())
3073 return TypeIdx(-1);
3074 return I->second;
3075}
3076
John McCall833ca992009-10-29 08:12:44 +00003077TemplateArgumentLocInfo
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003078ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
Sebastian Redl577d4792010-07-22 22:43:28 +00003079 llvm::BitstreamCursor &DeclsCursor,
John McCall833ca992009-10-29 08:12:44 +00003080 const RecordData &Record,
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00003081 unsigned &Index) {
John McCall833ca992009-10-29 08:12:44 +00003082 switch (Kind) {
3083 case TemplateArgument::Expression:
Sebastian Redl577d4792010-07-22 22:43:28 +00003084 return ReadExpr(DeclsCursor);
John McCall833ca992009-10-29 08:12:44 +00003085 case TemplateArgument::Type:
Sebastian Redl577d4792010-07-22 22:43:28 +00003086 return GetTypeSourceInfo(DeclsCursor, Record, Index);
Douglas Gregor788cd062009-11-11 01:00:40 +00003087 case TemplateArgument::Template: {
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003088 SourceRange QualifierRange = ReadSourceRange(Record, Index);
3089 SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
3090 return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
Douglas Gregor788cd062009-11-11 01:00:40 +00003091 }
John McCall833ca992009-10-29 08:12:44 +00003092 case TemplateArgument::Null:
3093 case TemplateArgument::Integral:
3094 case TemplateArgument::Declaration:
3095 case TemplateArgument::Pack:
3096 return TemplateArgumentLocInfo();
3097 }
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +00003098 llvm_unreachable("unexpected template argument loc");
John McCall833ca992009-10-29 08:12:44 +00003099 return TemplateArgumentLocInfo();
3100}
3101
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003102TemplateArgumentLoc
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003103ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00003104 const RecordData &Record, unsigned &Index) {
3105 TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003106
3107 if (Arg.getKind() == TemplateArgument::Expression) {
3108 if (Record[Index++]) // bool InfoHasSameExpr.
3109 return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
3110 }
3111 return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Sebastian Redl577d4792010-07-22 22:43:28 +00003112 DeclsCursor,
Argyrios Kyrtzidis919e6932010-06-28 22:28:35 +00003113 Record, Index));
Argyrios Kyrtzidis44f8c372010-06-22 09:54:59 +00003114}
3115
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003116Decl *ASTReader::GetExternalDecl(uint32_t ID) {
John McCall76bd1f32010-06-01 09:23:16 +00003117 return GetDecl(ID);
3118}
3119
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003120TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
Sebastian Redl30c514c2010-07-14 23:45:08 +00003121 if (!DeclsLoaded[0]) {
Sebastian Redle1dde812010-08-24 00:50:04 +00003122 ReadDeclRecord(0, 1);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003123 if (DeserializationListener)
Sebastian Redl1476ed42010-07-16 16:36:56 +00003124 DeserializationListener->DeclRead(1, DeclsLoaded[0]);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003125 }
Argyrios Kyrtzidis8871a442010-07-08 17:13:02 +00003126
3127 return cast<TranslationUnitDecl>(DeclsLoaded[0]);
3128}
3129
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003130Decl *ASTReader::GetDecl(DeclID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00003131 if (ID == 0)
3132 return 0;
3133
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003134 if (ID > DeclsLoaded.size()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003135 Error("declaration ID out-of-range for AST file");
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003136 return 0;
3137 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003138
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003139 unsigned Index = ID - 1;
Sebastian Redl30c514c2010-07-14 23:45:08 +00003140 if (!DeclsLoaded[Index]) {
Argyrios Kyrtzidisa8650052010-08-03 17:30:10 +00003141 ReadDeclRecord(Index, ID);
Sebastian Redl30c514c2010-07-14 23:45:08 +00003142 if (DeserializationListener)
3143 DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
3144 }
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003145
3146 return DeclsLoaded[Index];
Douglas Gregor2cf26342009-04-09 22:27:44 +00003147}
3148
Chris Lattner887e2b32009-04-27 05:46:25 +00003149/// \brief Resolve the offset of a statement into a statement.
3150///
3151/// This operation will read a new statement from the external
3152/// source each time it is called, and is meant to be used via a
3153/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003154Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003155 // Offset here is a global offset across the entire chain.
3156 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3157 PerFileData &F = *Chain[N - I - 1];
3158 if (Offset < F.SizeInBits) {
3159 // Since we know that this statement is part of a decl, make sure to use
3160 // the decl cursor to read it.
3161 F.DeclsCursor.JumpToBit(Offset);
3162 return ReadStmtFromStream(F.DeclsCursor);
3163 }
3164 Offset -= F.SizeInBits;
3165 }
3166 llvm_unreachable("Broken chain");
Douglas Gregor250fc9c2009-04-18 00:07:54 +00003167}
3168
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003169bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
John McCall76bd1f32010-06-01 09:23:16 +00003170 llvm::SmallVectorImpl<Decl*> &Decls) {
Mike Stump1eb44332009-09-09 15:08:12 +00003171 assert(DC->hasExternalLexicalStorage() &&
Douglas Gregor2cf26342009-04-09 22:27:44 +00003172 "DeclContext has no lexical decls in storage");
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003173
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003174 // There might be lexical decls in multiple parts of the chain, for the TU
3175 // at least.
3176 DeclContextInfos &Infos = DeclContextOffsets[DC];
3177 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3178 I != E; ++I) {
Sebastian Redl681d7232010-07-27 00:17:23 +00003179 // IDs can be 0 if this context doesn't contain declarations.
3180 if (!I->LexicalDecls)
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003181 continue;
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003182
3183 // Load all of the declaration IDs
Sebastian Redl8538e8d2010-08-18 23:57:32 +00003184 for (const DeclID *ID = I->LexicalDecls,
Sebastian Redl681d7232010-07-27 00:17:23 +00003185 *IDE = ID + I->NumLexicalDecls;
3186 ID != IDE; ++ID)
3187 Decls.push_back(GetDecl(*ID));
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003188 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003189
Douglas Gregor25123082009-04-22 22:34:57 +00003190 ++NumLexicalDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003191 return false;
3192}
3193
John McCall76bd1f32010-06-01 09:23:16 +00003194DeclContext::lookup_result
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003195ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
John McCall76bd1f32010-06-01 09:23:16 +00003196 DeclarationName Name) {
Mike Stump1eb44332009-09-09 15:08:12 +00003197 assert(DC->hasExternalVisibleStorage() &&
Douglas Gregor2cf26342009-04-09 22:27:44 +00003198 "DeclContext has no visible decls in storage");
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003199 if (!Name)
3200 return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
3201 DeclContext::lookup_iterator(0));
Ted Kremenekd5d7b3f2010-03-18 00:56:54 +00003202
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003203 llvm::SmallVector<NamedDecl *, 64> Decls;
Sebastian Redl8b122732010-08-24 00:49:55 +00003204 // There might be visible decls in multiple parts of the chain, for the TU
Sebastian Redl5967d622010-08-24 00:50:16 +00003205 // and namespaces. For any given name, the last available results replace
3206 // all earlier ones. For this reason, we walk in reverse.
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003207 DeclContextInfos &Infos = DeclContextOffsets[DC];
Sebastian Redl5967d622010-08-24 00:50:16 +00003208 for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003209 I != E; ++I) {
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003210 if (!I->NameLookupTableData)
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003211 continue;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003212
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003213 ASTDeclContextNameLookupTable *LookupTable =
3214 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3215 ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
3216 if (Pos == LookupTable->end())
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003217 continue;
3218
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003219 ASTDeclContextNameLookupTrait::data_type Data = *Pos;
3220 for (; Data.first != Data.second; ++Data.first)
3221 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
Sebastian Redl5967d622010-08-24 00:50:16 +00003222 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00003223 }
3224
Douglas Gregor25123082009-04-22 22:34:57 +00003225 ++NumVisibleDeclContextsRead;
John McCall76bd1f32010-06-01 09:23:16 +00003226
Argyrios Kyrtzidis074dcc82010-08-20 16:04:35 +00003227 SetExternalVisibleDeclsForName(DC, Name, Decls);
John McCall76bd1f32010-06-01 09:23:16 +00003228 return const_cast<DeclContext*>(DC)->lookup(Name);
Douglas Gregor2cf26342009-04-09 22:27:44 +00003229}
3230
Argyrios Kyrtzidisa60786b2010-08-20 23:35:55 +00003231void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
3232 assert(DC->hasExternalVisibleStorage() &&
3233 "DeclContext has no visible decls in storage");
3234
3235 llvm::SmallVector<NamedDecl *, 64> Decls;
3236 // There might be visible decls in multiple parts of the chain, for the TU
3237 // and namespaces.
3238 DeclContextInfos &Infos = DeclContextOffsets[DC];
3239 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3240 I != E; ++I) {
3241 if (!I->NameLookupTableData)
3242 continue;
3243
3244 ASTDeclContextNameLookupTable *LookupTable =
3245 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3246 for (ASTDeclContextNameLookupTable::item_iterator
3247 ItemI = LookupTable->item_begin(),
3248 ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
3249 ASTDeclContextNameLookupTable::item_iterator::value_type Val
3250 = *ItemI;
3251 ASTDeclContextNameLookupTrait::data_type Data = Val.second;
3252 Decls.clear();
3253 for (; Data.first != Data.second; ++Data.first)
3254 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
3255 MaterializeVisibleDeclsForName(DC, Val.first, Decls);
3256 }
3257 }
3258}
3259
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003260void ASTReader::PassInterestingDeclsToConsumer() {
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003261 assert(Consumer);
3262 while (!InterestingDecls.empty()) {
3263 DeclGroupRef DG(InterestingDecls.front());
3264 InterestingDecls.pop_front();
Sebastian Redl27372b42010-08-11 18:52:41 +00003265 Consumer->HandleInterestingDecl(DG);
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003266 }
3267}
3268
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003269void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregor0af2ca42009-04-22 19:09:20 +00003270 this->Consumer = Consumer;
3271
Douglas Gregorfdd01722009-04-14 00:24:19 +00003272 if (!Consumer)
3273 return;
3274
3275 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003276 // Force deserialization of this decl, which will cause it to be queued for
3277 // passing to the consumer.
Daniel Dunbar04a0b502009-09-17 03:06:44 +00003278 GetDecl(ExternalDefinitions[I]);
Douglas Gregorfdd01722009-04-14 00:24:19 +00003279 }
Douglas Gregorc62a2fe2009-04-25 00:41:30 +00003280
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00003281 PassInterestingDeclsToConsumer();
Douglas Gregorfdd01722009-04-14 00:24:19 +00003282}
3283
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003284void ASTReader::PrintStats() {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003285 std::fprintf(stderr, "*** AST File Statistics:\n");
Douglas Gregor2cf26342009-04-09 22:27:44 +00003286
Mike Stump1eb44332009-09-09 15:08:12 +00003287 unsigned NumTypesLoaded
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003288 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
John McCall0953e762009-09-24 19:53:00 +00003289 QualType());
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003290 unsigned NumDeclsLoaded
3291 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
3292 (Decl *)0);
3293 unsigned NumIdentifiersLoaded
3294 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
3295 IdentifiersLoaded.end(),
3296 (IdentifierInfo *)0);
Mike Stump1eb44332009-09-09 15:08:12 +00003297 unsigned NumSelectorsLoaded
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003298 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
3299 SelectorsLoaded.end(),
3300 Selector());
Douglas Gregor2d41cc12009-04-13 20:50:16 +00003301
Douglas Gregor4fed3f42009-04-27 18:38:38 +00003302 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
3303 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00003304 if (TotalNumSLocEntries)
3305 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
3306 NumSLocEntriesRead, TotalNumSLocEntries,
3307 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003308 if (!TypesLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003309 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003310 NumTypesLoaded, (unsigned)TypesLoaded.size(),
3311 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
3312 if (!DeclsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003313 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00003314 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
3315 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003316 if (!IdentifiersLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003317 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003318 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
3319 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Sebastian Redl725cd962010-08-04 20:40:17 +00003320 if (!SelectorsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00003321 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
Sebastian Redl725cd962010-08-04 20:40:17 +00003322 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
3323 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
Douglas Gregor83941df2009-04-25 17:48:32 +00003324 if (TotalNumStatements)
3325 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
3326 NumStatementsRead, TotalNumStatements,
3327 ((float)NumStatementsRead/TotalNumStatements * 100));
3328 if (TotalNumMacros)
3329 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
3330 NumMacrosRead, TotalNumMacros,
3331 ((float)NumMacrosRead/TotalNumMacros * 100));
3332 if (TotalLexicalDeclContexts)
3333 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
3334 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
3335 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
3336 * 100));
3337 if (TotalVisibleDeclContexts)
3338 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
3339 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
3340 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
3341 * 100));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003342 if (TotalNumMethodPoolEntries) {
Douglas Gregor83941df2009-04-25 17:48:32 +00003343 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003344 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
3345 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
Douglas Gregor83941df2009-04-25 17:48:32 +00003346 * 100));
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003347 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
Douglas Gregor83941df2009-04-25 17:48:32 +00003348 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00003349 std::fprintf(stderr, "\n");
3350}
3351
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003352void ASTReader::InitializeSema(Sema &S) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00003353 SemaObj = &S;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003354 S.ExternalSource = this;
3355
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00003356 // Makes sure any declarations that were deserialized "too early"
3357 // still get added to the identifier's declaration chains.
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003358 if (SemaObj->TUScope) {
3359 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
John McCalld226f652010-08-21 09:40:31 +00003360 SemaObj->TUScope->AddDecl(PreloadedDecls[I]);
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003361 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
3362 }
Douglas Gregor668c1a42009-04-21 22:25:48 +00003363 }
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00003364 PreloadedDecls.clear();
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003365
3366 // If there were any tentative definitions, deserialize them and add
Sebastian Redle9d12b62010-01-31 22:27:38 +00003367 // them to Sema's list of tentative definitions.
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003368 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
3369 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
Sebastian Redle9d12b62010-01-31 22:27:38 +00003370 SemaObj->TentativeDefinitions.push_back(Var);
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00003371 }
Kovarththanan Rajaratnam6b82f642010-03-07 19:10:13 +00003372
Argyrios Kyrtzidis49b96d12010-08-13 18:42:17 +00003373 // If there were any unused file scoped decls, deserialize them and add to
3374 // Sema's list of unused file scoped decls.
3375 for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
3376 DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
3377 SemaObj->UnusedFileScopedDecls.push_back(D);
Tanya Lattnere6bbc012010-02-12 00:07:30 +00003378 }
Douglas Gregor14c22f22009-04-22 22:18:58 +00003379
Argyrios Kyrtzidis72b90572010-08-05 09:48:08 +00003380 // If there were any weak undeclared identifiers, deserialize them and add to
3381 // Sema's list of weak undeclared identifiers.
3382 if (!WeakUndeclaredIdentifiers.empty()) {
3383 unsigned Idx = 0;
3384 for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
3385 IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3386 IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3387 SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
3388 bool Used = WeakUndeclaredIdentifiers[Idx++];
3389 Sema::WeakInfo WI(AliasId, Loc);
3390 WI.setUsed(Used);
3391 SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
3392 }
3393 }
3394
Douglas Gregor14c22f22009-04-22 22:18:58 +00003395 // If there were any locally-scoped external declarations,
3396 // deserialize them and add them to Sema's table of locally-scoped
3397 // external declarations.
3398 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
3399 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
3400 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
3401 }
Douglas Gregorb81c1702009-04-27 20:06:05 +00003402
3403 // If there were any ext_vector type declarations, deserialize them
3404 // and add them to Sema's vector of such declarations.
3405 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
3406 SemaObj->ExtVectorDecls.push_back(
3407 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00003408
3409 // FIXME: Do VTable uses and dynamic classes deserialize too much ?
3410 // Can we cut them down before writing them ?
3411
3412 // If there were any VTable uses, deserialize the information and add it
3413 // to Sema's vector and map of VTable uses.
Argyrios Kyrtzidisbe4ebcd2010-08-03 17:29:52 +00003414 if (!VTableUses.empty()) {
3415 unsigned Idx = 0;
3416 for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
3417 CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
3418 SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
3419 bool DefinitionRequired = VTableUses[Idx++];
3420 SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
3421 SemaObj->VTablesUsed[Class] = DefinitionRequired;
3422 }
Argyrios Kyrtzidisd455add2010-07-06 15:37:04 +00003423 }
3424
3425 // If there were any dynamic classes declarations, deserialize them
3426 // and add them to Sema's vector of such declarations.
3427 for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
3428 SemaObj->DynamicClasses.push_back(
3429 cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
Fariborz Jahanian32019832010-07-23 19:11:11 +00003430
Argyrios Kyrtzidis0e036382010-08-05 09:48:16 +00003431 // If there were any pending implicit instantiations, deserialize them
3432 // and add them to Sema's queue of such instantiations.
3433 assert(PendingImplicitInstantiations.size() % 2 == 0 &&
3434 "Expected pairs of entries");
3435 for (unsigned Idx = 0, N = PendingImplicitInstantiations.size(); Idx < N;) {
3436 ValueDecl *D=cast<ValueDecl>(GetDecl(PendingImplicitInstantiations[Idx++]));
3437 SourceLocation Loc = ReadSourceLocation(PendingImplicitInstantiations, Idx);
3438 SemaObj->PendingImplicitInstantiations.push_back(std::make_pair(D, Loc));
3439 }
3440
Argyrios Kyrtzidis76c38d32010-08-02 07:14:54 +00003441 // Load the offsets of the declarations that Sema references.
3442 // They will be lazily deserialized when needed.
3443 if (!SemaDeclRefs.empty()) {
3444 assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
3445 SemaObj->StdNamespace = SemaDeclRefs[0];
3446 SemaObj->StdBadAlloc = SemaDeclRefs[1];
3447 }
3448
Fariborz Jahanian32019832010-07-23 19:11:11 +00003449 // If there are @selector references added them to its pool. This is for
3450 // implementation of -Wselector.
Sebastian Redl725cd962010-08-04 20:40:17 +00003451 if (!ReferencedSelectorsData.empty()) {
3452 unsigned int DataSize = ReferencedSelectorsData.size()-1;
Fariborz Jahanian32019832010-07-23 19:11:11 +00003453 unsigned I = 0;
3454 while (I < DataSize) {
Sebastian Redl725cd962010-08-04 20:40:17 +00003455 Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
Fariborz Jahanian32019832010-07-23 19:11:11 +00003456 SourceLocation SelLoc =
Sebastian Redl725cd962010-08-04 20:40:17 +00003457 SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
Fariborz Jahanian32019832010-07-23 19:11:11 +00003458 SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
3459 }
3460 }
Douglas Gregor668c1a42009-04-21 22:25:48 +00003461}
3462
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003463IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003464 // Try to find this name within our on-disk hash tables. We start with the
3465 // most recent one, since that one contains the most up-to-date info.
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003466 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003467 ASTIdentifierLookupTable *IdTable
3468 = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
Sebastian Redl0fa7d0b2010-07-22 17:01:13 +00003469 if (!IdTable)
3470 continue;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003471 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003472 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003473 if (Pos == IdTable->end())
3474 continue;
Douglas Gregor668c1a42009-04-21 22:25:48 +00003475
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003476 // Dereferencing the iterator has the effect of building the
3477 // IdentifierInfo node and populating it with the various
3478 // declarations it needs.
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003479 return *Pos;
Sebastian Redld27d3fc2010-07-21 22:31:37 +00003480 }
Sebastian Redld8c5abb2010-08-02 18:30:12 +00003481 return 0;
Douglas Gregor668c1a42009-04-21 22:25:48 +00003482}
3483
Mike Stump1eb44332009-09-09 15:08:12 +00003484std::pair<ObjCMethodList, ObjCMethodList>
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003485ASTReader::ReadMethodPool(Selector Sel) {
Sebastian Redl725cd962010-08-04 20:40:17 +00003486 // Find this selector in a hash table. We want to find the most recent entry.
3487 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3488 PerFileData &F = *Chain[I];
3489 if (!F.SelectorLookupTable)
3490 continue;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003491
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003492 ASTSelectorLookupTable *PoolTable
3493 = (ASTSelectorLookupTable*)F.SelectorLookupTable;
3494 ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
Sebastian Redl725cd962010-08-04 20:40:17 +00003495 if (Pos != PoolTable->end()) {
3496 ++NumSelectorsRead;
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003497 // FIXME: Not quite happy with the statistics here. We probably should
3498 // disable this tracking when called via LoadSelector.
3499 // Also, should entries without methods count as misses?
3500 ++NumMethodPoolEntriesRead;
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003501 ASTSelectorLookupTrait::data_type Data = *Pos;
Sebastian Redl725cd962010-08-04 20:40:17 +00003502 if (DeserializationListener)
3503 DeserializationListener->SelectorRead(Data.ID, Sel);
3504 return std::make_pair(Data.Instance, Data.Factory);
3505 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003506 }
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003507
Sebastian Redlfa78dec2010-08-04 21:22:45 +00003508 ++NumMethodPoolMisses;
Sebastian Redl725cd962010-08-04 20:40:17 +00003509 return std::pair<ObjCMethodList, ObjCMethodList>();
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00003510}
3511
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003512void ASTReader::LoadSelector(Selector Sel) {
Sebastian Redle58aa892010-08-04 18:21:41 +00003513 // It would be complicated to avoid reading the methods anyway. So don't.
3514 ReadMethodPool(Sel);
3515}
3516
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003517void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00003518 assert(ID && "Non-zero identifier ID required");
Douglas Gregora02b1472009-04-28 21:53:25 +00003519 assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00003520 IdentifiersLoaded[ID - 1] = II;
Sebastian Redlf2f0f032010-07-23 23:49:55 +00003521 if (DeserializationListener)
3522 DeserializationListener->IdentifierRead(ID, II);
Douglas Gregor668c1a42009-04-21 22:25:48 +00003523}
3524
Douglas Gregord89275b2009-07-06 18:54:52 +00003525/// \brief Set the globally-visible declarations associated with the given
3526/// identifier.
3527///
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003528/// If the AST reader is currently in a state where the given declaration IDs
Mike Stump1eb44332009-09-09 15:08:12 +00003529/// cannot safely be resolved, they are queued until it is safe to resolve
Douglas Gregord89275b2009-07-06 18:54:52 +00003530/// them.
3531///
3532/// \param II an IdentifierInfo that refers to one or more globally-visible
3533/// declarations.
3534///
3535/// \param DeclIDs the set of declaration IDs with the name @p II that are
3536/// visible at global scope.
3537///
3538/// \param Nonrecursive should be true to indicate that the caller knows that
3539/// this call is non-recursive, and therefore the globally-visible declarations
3540/// will not be placed onto the pending queue.
Mike Stump1eb44332009-09-09 15:08:12 +00003541void
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003542ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
Douglas Gregord89275b2009-07-06 18:54:52 +00003543 const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
3544 bool Nonrecursive) {
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00003545 if (NumCurrentElementsDeserializing && !Nonrecursive) {
Douglas Gregord89275b2009-07-06 18:54:52 +00003546 PendingIdentifierInfos.push_back(PendingIdentifierInfo());
3547 PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
3548 PII.II = II;
3549 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
3550 PII.DeclIDs.push_back(DeclIDs[I]);
3551 return;
3552 }
Mike Stump1eb44332009-09-09 15:08:12 +00003553
Douglas Gregord89275b2009-07-06 18:54:52 +00003554 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
3555 NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
3556 if (SemaObj) {
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003557 if (SemaObj->TUScope) {
3558 // Introduce this declaration into the translation-unit scope
3559 // and add it to the declaration chain for this identifier, so
3560 // that (unqualified) name lookup will find it.
John McCalld226f652010-08-21 09:40:31 +00003561 SemaObj->TUScope->AddDecl(D);
Douglas Gregor914ed9d2010-08-13 03:15:25 +00003562 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
3563 }
Douglas Gregord89275b2009-07-06 18:54:52 +00003564 } else {
3565 // Queue this declaration so that it will be added to the
3566 // translation unit scope and identifier's declaration chain
3567 // once a Sema object is known.
3568 PreloadedDecls.push_back(D);
3569 }
3570 }
3571}
3572
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003573IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00003574 if (ID == 0)
3575 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003576
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003577 if (IdentifiersLoaded.empty()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003578 Error("no identifier table in AST file");
Douglas Gregorafaf3082009-04-11 00:14:32 +00003579 return 0;
3580 }
Mike Stump1eb44332009-09-09 15:08:12 +00003581
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003582 assert(PP && "Forgot to set Preprocessor ?");
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003583 ID -= 1;
3584 if (!IdentifiersLoaded[ID]) {
3585 unsigned Index = ID;
3586 const char *Str = 0;
3587 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3588 PerFileData *F = Chain[N - I - 1];
3589 if (Index < F->LocalNumIdentifiers) {
3590 uint32_t Offset = F->IdentifierOffsets[Index];
3591 Str = F->IdentifierTableData + Offset;
3592 break;
3593 }
3594 Index -= F->LocalNumIdentifiers;
3595 }
3596 assert(Str && "Broken Chain");
Douglas Gregord6595a42009-04-25 21:04:17 +00003597
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003598 // All of the strings in the AST file are preceded by a 16-bit length.
3599 // Extract that 16-bit length to avoid having to execute strlen().
Ted Kremenek231bc0b2009-10-23 04:45:31 +00003600 // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
3601 // unsigned integers. This is important to avoid integer overflow when
3602 // we cast them to 'unsigned'.
Ted Kremenekff1ea462009-10-23 03:57:22 +00003603 const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
Douglas Gregor02fc7512009-04-28 20:01:51 +00003604 unsigned StrLen = (((unsigned) StrLenPtr[0])
3605 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003606 IdentifiersLoaded[ID]
Kovarththanan Rajaratnam811f4262010-03-12 10:32:27 +00003607 = &PP->getIdentifierTable().get(Str, StrLen);
Sebastian Redlf2f0f032010-07-23 23:49:55 +00003608 if (DeserializationListener)
3609 DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
Douglas Gregorafaf3082009-04-11 00:14:32 +00003610 }
Mike Stump1eb44332009-09-09 15:08:12 +00003611
Sebastian Redl11f5ccf2010-07-21 00:46:22 +00003612 return IdentifiersLoaded[ID];
Douglas Gregor2cf26342009-04-09 22:27:44 +00003613}
3614
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003615void ASTReader::ReadSLocEntry(unsigned ID) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00003616 ReadSLocEntryRecord(ID);
3617}
3618
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003619Selector ASTReader::DecodeSelector(unsigned ID) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003620 if (ID == 0)
3621 return Selector();
Mike Stump1eb44332009-09-09 15:08:12 +00003622
Sebastian Redl725cd962010-08-04 20:40:17 +00003623 if (ID > SelectorsLoaded.size()) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003624 Error("selector ID out of range in AST file");
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003625 return Selector();
3626 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003627
Sebastian Redl725cd962010-08-04 20:40:17 +00003628 if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
Douglas Gregor83941df2009-04-25 17:48:32 +00003629 // Load this selector from the selector table.
Sebastian Redl725cd962010-08-04 20:40:17 +00003630 unsigned Idx = ID - 1;
3631 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3632 PerFileData &F = *Chain[N - I - 1];
3633 if (Idx < F.LocalNumSelectors) {
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003634 ASTSelectorLookupTrait Trait(*this);
Sebastian Redl725cd962010-08-04 20:40:17 +00003635 SelectorsLoaded[ID - 1] =
3636 Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
3637 if (DeserializationListener)
3638 DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
3639 break;
3640 }
3641 Idx -= F.LocalNumSelectors;
3642 }
Douglas Gregor83941df2009-04-25 17:48:32 +00003643 }
3644
Sebastian Redl725cd962010-08-04 20:40:17 +00003645 return SelectorsLoaded[ID - 1];
Steve Naroff90cd1bb2009-04-23 10:39:46 +00003646}
3647
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003648Selector ASTReader::GetExternalSelector(uint32_t ID) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003649 return DecodeSelector(ID);
3650}
3651
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003652uint32_t ASTReader::GetNumExternalSelectors() {
Sebastian Redl725cd962010-08-04 20:40:17 +00003653 // ID 0 (the null selector) is considered an external selector.
3654 return getTotalNumSelectors() + 1;
Douglas Gregor719770d2010-04-06 17:30:22 +00003655}
3656
Mike Stump1eb44332009-09-09 15:08:12 +00003657DeclarationName
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003658ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00003659 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
3660 switch (Kind) {
3661 case DeclarationName::Identifier:
3662 return DeclarationName(GetIdentifierInfo(Record, Idx));
3663
3664 case DeclarationName::ObjCZeroArgSelector:
3665 case DeclarationName::ObjCOneArgSelector:
3666 case DeclarationName::ObjCMultiArgSelector:
Steve Naroffa7503a72009-04-23 15:15:40 +00003667 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003668
3669 case DeclarationName::CXXConstructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003670 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003671 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003672
3673 case DeclarationName::CXXDestructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003674 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003675 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003676
3677 case DeclarationName::CXXConversionFunctionName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003678 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor50d62d12009-08-05 05:36:45 +00003679 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregor2cf26342009-04-09 22:27:44 +00003680
3681 case DeclarationName::CXXOperatorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00003682 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00003683 (OverloadedOperatorKind)Record[Idx++]);
3684
Sean Hunt3e518bd2009-11-29 07:34:05 +00003685 case DeclarationName::CXXLiteralOperatorName:
3686 return Context->DeclarationNames.getCXXLiteralOperatorName(
3687 GetIdentifierInfo(Record, Idx));
3688
Douglas Gregor2cf26342009-04-09 22:27:44 +00003689 case DeclarationName::CXXUsingDirective:
3690 return DeclarationName::getUsingDirectiveName();
3691 }
3692
3693 // Required to silence GCC warning
3694 return DeclarationName();
3695}
Douglas Gregor0a0428e2009-04-10 20:39:37 +00003696
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003697TemplateName
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003698ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003699 TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
3700 switch (Kind) {
3701 case TemplateName::Template:
3702 return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
3703
3704 case TemplateName::OverloadedTemplate: {
3705 unsigned size = Record[Idx++];
3706 UnresolvedSet<8> Decls;
3707 while (size--)
3708 Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
3709
3710 return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
3711 }
3712
3713 case TemplateName::QualifiedTemplate: {
3714 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3715 bool hasTemplKeyword = Record[Idx++];
3716 TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
3717 return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
3718 }
3719
3720 case TemplateName::DependentTemplate: {
3721 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3722 if (Record[Idx++]) // isIdentifier
3723 return Context->getDependentTemplateName(NNS,
3724 GetIdentifierInfo(Record, Idx));
3725 return Context->getDependentTemplateName(NNS,
Argyrios Kyrtzidis17cfded2010-06-28 09:31:42 +00003726 (OverloadedOperatorKind)Record[Idx++]);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003727 }
3728 }
3729
3730 assert(0 && "Unhandled template name kind!");
3731 return TemplateName();
3732}
3733
3734TemplateArgument
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003735ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redl577d4792010-07-22 22:43:28 +00003736 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003737 switch ((TemplateArgument::ArgKind)Record[Idx++]) {
3738 case TemplateArgument::Null:
3739 return TemplateArgument();
3740 case TemplateArgument::Type:
3741 return TemplateArgument(GetType(Record[Idx++]));
3742 case TemplateArgument::Declaration:
3743 return TemplateArgument(GetDecl(Record[Idx++]));
Argyrios Kyrtzidisdc767e32010-06-28 09:31:34 +00003744 case TemplateArgument::Integral: {
3745 llvm::APSInt Value = ReadAPSInt(Record, Idx);
3746 QualType T = GetType(Record[Idx++]);
3747 return TemplateArgument(Value, T);
3748 }
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003749 case TemplateArgument::Template:
3750 return TemplateArgument(ReadTemplateName(Record, Idx));
3751 case TemplateArgument::Expression:
Sebastian Redl577d4792010-07-22 22:43:28 +00003752 return TemplateArgument(ReadExpr(DeclsCursor));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003753 case TemplateArgument::Pack: {
3754 unsigned NumArgs = Record[Idx++];
3755 llvm::SmallVector<TemplateArgument, 8> Args;
3756 Args.reserve(NumArgs);
3757 while (NumArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00003758 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +00003759 TemplateArgument TemplArg;
3760 TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
3761 return TemplArg;
3762 }
3763 }
3764
3765 assert(0 && "Unhandled template argument kind!");
3766 return TemplateArgument();
3767}
3768
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003769TemplateParameterList *
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003770ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003771 SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
3772 SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
3773 SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
3774
3775 unsigned NumParams = Record[Idx++];
3776 llvm::SmallVector<NamedDecl *, 16> Params;
3777 Params.reserve(NumParams);
3778 while (NumParams--)
3779 Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
3780
3781 TemplateParameterList* TemplateParams =
3782 TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
3783 Params.data(), Params.size(), RAngleLoc);
3784 return TemplateParams;
3785}
3786
3787void
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003788ASTReader::
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003789ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
Sebastian Redl577d4792010-07-22 22:43:28 +00003790 llvm::BitstreamCursor &DeclsCursor,
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003791 const RecordData &Record, unsigned &Idx) {
3792 unsigned NumTemplateArgs = Record[Idx++];
3793 TemplArgs.reserve(NumTemplateArgs);
3794 while (NumTemplateArgs--)
Sebastian Redl577d4792010-07-22 22:43:28 +00003795 TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidisdd41c142010-06-23 13:48:30 +00003796}
3797
Argyrios Kyrtzidis37ffed32010-07-02 11:55:32 +00003798/// \brief Read a UnresolvedSet structure.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003799void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
Argyrios Kyrtzidis37ffed32010-07-02 11:55:32 +00003800 const RecordData &Record, unsigned &Idx) {
3801 unsigned NumDecls = Record[Idx++];
3802 while (NumDecls--) {
3803 NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
3804 AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
3805 Set.addDecl(D, AS);
3806 }
3807}
3808
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003809CXXBaseSpecifier
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003810ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
Nick Lewycky56062202010-07-26 16:56:01 +00003811 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003812 bool isVirtual = static_cast<bool>(Record[Idx++]);
3813 bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
3814 AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
Nick Lewycky56062202010-07-26 16:56:01 +00003815 TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003816 SourceRange Range = ReadSourceRange(Record, Idx);
Nick Lewycky56062202010-07-26 16:56:01 +00003817 return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
Argyrios Kyrtzidis0745d0a2010-07-02 23:30:27 +00003818}
3819
Argyrios Kyrtzidis8e706f42010-08-09 10:54:12 +00003820std::pair<CXXBaseOrMemberInitializer **, unsigned>
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003821ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
Argyrios Kyrtzidis8e706f42010-08-09 10:54:12 +00003822 const RecordData &Record,
3823 unsigned &Idx) {
3824 CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
3825 unsigned NumInitializers = Record[Idx++];
3826 if (NumInitializers) {
3827 ASTContext &C = *getContext();
3828
3829 BaseOrMemberInitializers
3830 = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
3831 for (unsigned i=0; i != NumInitializers; ++i) {
3832 TypeSourceInfo *BaseClassInfo = 0;
3833 bool IsBaseVirtual = false;
3834 FieldDecl *Member = 0;
3835
3836 bool IsBaseInitializer = Record[Idx++];
3837 if (IsBaseInitializer) {
3838 BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
3839 IsBaseVirtual = Record[Idx++];
3840 } else {
3841 Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
3842 }
3843 SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
3844 Expr *Init = ReadExpr(Cursor);
3845 FieldDecl *AnonUnionMember
3846 = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
3847 SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
3848 SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
3849 bool IsWritten = Record[Idx++];
3850 unsigned SourceOrderOrNumArrayIndices;
3851 llvm::SmallVector<VarDecl *, 8> Indices;
3852 if (IsWritten) {
3853 SourceOrderOrNumArrayIndices = Record[Idx++];
3854 } else {
3855 SourceOrderOrNumArrayIndices = Record[Idx++];
3856 Indices.reserve(SourceOrderOrNumArrayIndices);
3857 for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
3858 Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
3859 }
3860
3861 CXXBaseOrMemberInitializer *BOMInit;
3862 if (IsBaseInitializer) {
3863 BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
3864 IsBaseVirtual, LParenLoc,
3865 Init, RParenLoc);
3866 } else if (IsWritten) {
3867 BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
3868 LParenLoc, Init, RParenLoc);
3869 } else {
3870 BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
3871 LParenLoc, Init, RParenLoc,
3872 Indices.data(),
3873 Indices.size());
3874 }
3875
3876 BOMInit->setAnonUnionMember(AnonUnionMember);
3877 BaseOrMemberInitializers[i] = BOMInit;
3878 }
3879 }
3880
3881 return std::make_pair(BaseOrMemberInitializers, NumInitializers);
3882}
3883
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003884NestedNameSpecifier *
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003885ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003886 unsigned N = Record[Idx++];
3887 NestedNameSpecifier *NNS = 0, *Prev = 0;
3888 for (unsigned I = 0; I != N; ++I) {
3889 NestedNameSpecifier::SpecifierKind Kind
3890 = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
3891 switch (Kind) {
3892 case NestedNameSpecifier::Identifier: {
3893 IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
3894 NNS = NestedNameSpecifier::Create(*Context, Prev, II);
3895 break;
3896 }
3897
3898 case NestedNameSpecifier::Namespace: {
3899 NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
3900 NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
3901 break;
3902 }
3903
3904 case NestedNameSpecifier::TypeSpec:
3905 case NestedNameSpecifier::TypeSpecWithTemplate: {
3906 Type *T = GetType(Record[Idx++]).getTypePtr();
3907 bool Template = Record[Idx++];
3908 NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
3909 break;
3910 }
3911
3912 case NestedNameSpecifier::Global: {
3913 NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
3914 // No associated value, and there can't be a prefix.
3915 break;
3916 }
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003917 }
Argyrios Kyrtzidisd2bb2c02010-07-07 15:46:30 +00003918 Prev = NNS;
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003919 }
3920 return NNS;
3921}
3922
3923SourceRange
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003924ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
Daniel Dunbar8ee59392010-06-02 15:47:10 +00003925 SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
3926 SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
3927 return SourceRange(beg, end);
Chris Lattner6ad9ac02010-05-07 21:43:38 +00003928}
3929
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003930/// \brief Read an integral value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003931llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003932 unsigned BitWidth = Record[Idx++];
3933 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
3934 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
3935 Idx += NumWords;
3936 return Result;
3937}
3938
3939/// \brief Read a signed integral value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003940llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00003941 bool isUnsigned = Record[Idx++];
3942 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
3943}
3944
Douglas Gregor17fc2232009-04-14 21:55:33 +00003945/// \brief Read a floating-point value
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003946llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregor17fc2232009-04-14 21:55:33 +00003947 return llvm::APFloat(ReadAPInt(Record, Idx));
3948}
3949
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003950// \brief Read a string
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003951std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003952 unsigned Len = Record[Idx++];
Jay Foadbeaaccd2009-05-21 09:52:38 +00003953 std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
Douglas Gregor68a2eb02009-04-15 21:30:51 +00003954 Idx += Len;
3955 return Result;
3956}
3957
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003958CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
Chris Lattnerd2598362010-05-10 00:25:06 +00003959 unsigned &Idx) {
3960 CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
3961 return CXXTemporary::Create(*Context, Decl);
3962}
3963
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003964DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00003965 return Diag(SourceLocation(), DiagID);
3966}
3967
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003968DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003969 return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
Douglas Gregor0a0428e2009-04-10 20:39:37 +00003970}
Douglas Gregor025452f2009-04-17 00:04:06 +00003971
Douglas Gregor668c1a42009-04-21 22:25:48 +00003972/// \brief Retrieve the identifier table associated with the
3973/// preprocessor.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003974IdentifierTable &ASTReader::getIdentifierTable() {
Argyrios Kyrtzidis11e51102009-06-19 00:03:23 +00003975 assert(PP && "Forgot to set Preprocessor ?");
3976 return PP->getIdentifierTable();
Douglas Gregor668c1a42009-04-21 22:25:48 +00003977}
3978
Douglas Gregor025452f2009-04-17 00:04:06 +00003979/// \brief Record that the given ID maps to the given switch-case
3980/// statement.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003981void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Douglas Gregor025452f2009-04-17 00:04:06 +00003982 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
3983 SwitchCaseStmts[ID] = SC;
3984}
3985
3986/// \brief Retrieve the switch-case statement with the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003987SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
Douglas Gregor025452f2009-04-17 00:04:06 +00003988 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
3989 return SwitchCaseStmts[ID];
3990}
Douglas Gregor1de05fe2009-04-17 18:18:49 +00003991
3992/// \brief Record that the given label statement has been
3993/// deserialized and has the given ID.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00003994void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
Mike Stump1eb44332009-09-09 15:08:12 +00003995 assert(LabelStmts.find(ID) == LabelStmts.end() &&
Douglas Gregor1de05fe2009-04-17 18:18:49 +00003996 "Deserialized label twice");
3997 LabelStmts[ID] = S;
3998
3999 // If we've already seen any goto statements that point to this
4000 // label, resolve them now.
4001 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
4002 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
4003 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
4004 Goto->second->setLabel(S);
4005 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004006
4007 // If we've already seen any address-label statements that point to
4008 // this label, resolve them now.
4009 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
Mike Stump1eb44332009-09-09 15:08:12 +00004010 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004011 = UnresolvedAddrLabelExprs.equal_range(ID);
Mike Stump1eb44332009-09-09 15:08:12 +00004012 for (AddrLabelIter AddrLabel = AddrLabels.first;
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004013 AddrLabel != AddrLabels.second; ++AddrLabel)
4014 AddrLabel->second->setLabel(S);
4015 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor1de05fe2009-04-17 18:18:49 +00004016}
4017
4018/// \brief Set the label of the given statement to the label
4019/// identified by ID.
4020///
4021/// Depending on the order in which the label and other statements
4022/// referencing that label occur, this operation may complete
4023/// immediately (updating the statement) or it may queue the
4024/// statement to be back-patched later.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004025void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
Douglas Gregor1de05fe2009-04-17 18:18:49 +00004026 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4027 if (Label != LabelStmts.end()) {
4028 // We've already seen this label, so set the label of the goto and
4029 // we're done.
4030 S->setLabel(Label->second);
4031 } else {
4032 // We haven't seen this label yet, so add this goto to the set of
4033 // unresolved goto statements.
4034 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
4035 }
4036}
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004037
4038/// \brief Set the label of the given expression to the label
4039/// identified by ID.
4040///
4041/// Depending on the order in which the label and other statements
4042/// referencing that label occur, this operation may complete
4043/// immediately (updating the statement) or it may queue the
4044/// statement to be back-patched later.
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004045void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00004046 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4047 if (Label != LabelStmts.end()) {
4048 // We've already seen this label, so set the label of the
4049 // label-address expression and we're done.
4050 S->setLabel(Label->second);
4051 } else {
4052 // We haven't seen this label yet, so add this label-address
4053 // expression to the set of unresolved label-address expressions.
4054 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
4055 }
4056}
Douglas Gregord89275b2009-07-06 18:54:52 +00004057
Sebastian Redlc43b54c2010-08-18 23:56:43 +00004058void ASTReader::FinishedDeserializing() {
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004059 assert(NumCurrentElementsDeserializing &&
4060 "FinishedDeserializing not paired with StartedDeserializing");
4061 if (NumCurrentElementsDeserializing == 1) {
Douglas Gregord89275b2009-07-06 18:54:52 +00004062 // If any identifiers with corresponding top-level declarations have
4063 // been loaded, load those declarations now.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004064 while (!PendingIdentifierInfos.empty()) {
4065 SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
4066 PendingIdentifierInfos.front().DeclIDs, true);
4067 PendingIdentifierInfos.pop_front();
Douglas Gregord89275b2009-07-06 18:54:52 +00004068 }
Argyrios Kyrtzidisbb80a8e2010-07-07 15:46:26 +00004069
4070 // We are not in recursive loading, so it's safe to pass the "interesting"
4071 // decls to the consumer.
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004072 if (Consumer)
4073 PassInterestingDeclsToConsumer();
Douglas Gregord89275b2009-07-06 18:54:52 +00004074 }
Argyrios Kyrtzidis29ee3a22010-07-30 10:03:16 +00004075 --NumCurrentElementsDeserializing;
Douglas Gregord89275b2009-07-06 18:54:52 +00004076}
Douglas Gregor501c1032010-08-19 00:28:17 +00004077
Sebastian Redle1dde812010-08-24 00:50:04 +00004078ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
4079 const char *isysroot, bool DisableValidation)
4080 : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
4081 SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
4082 Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
4083 Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
4084 NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
4085 TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
4086 NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
4087 NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
4088 TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
4089 TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
4090 TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
4091 RelocatablePCH = false;
4092}
4093
4094ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
4095 Diagnostic &Diags, const char *isysroot,
4096 bool DisableValidation)
4097 : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
4098 Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
4099 isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
4100 NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
4101 NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
4102 TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
4103 NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
4104 NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
4105 NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
4106 NumCurrentElementsDeserializing(0) {
4107 RelocatablePCH = false;
4108}
4109
4110ASTReader::~ASTReader() {
4111 for (unsigned i = 0, e = Chain.size(); i != e; ++i)
4112 delete Chain[e - i - 1];
4113 // Delete all visible decl lookup tables
4114 for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
4115 E = DeclContextOffsets.end();
4116 I != E; ++I) {
4117 for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
4118 J != F; ++J) {
4119 if (J->NameLookupTableData)
4120 delete static_cast<ASTDeclContextNameLookupTable*>(
4121 J->NameLookupTableData);
4122 }
4123 }
4124 for (DeclContextVisibleUpdatesPending::iterator
4125 I = PendingVisibleUpdates.begin(),
4126 E = PendingVisibleUpdates.end();
4127 I != E; ++I) {
4128 for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
4129 F = I->second.end();
4130 J != F; ++J)
4131 delete static_cast<ASTDeclContextNameLookupTable*>(*J);
4132 }
4133}
4134
Douglas Gregor501c1032010-08-19 00:28:17 +00004135ASTReader::PerFileData::PerFileData()
4136 : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
4137 LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
4138 IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0),
4139 LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
4140 NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0),
4141 SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0)
4142{}
4143
4144ASTReader::PerFileData::~PerFileData() {
4145 delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
4146 delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
4147}
4148