blob: 672e912dc62553fa69aac883d894fca28ea77a2d [file] [log] [blame]
Sebastian Redl3b3c8742010-08-18 23:57:11 +00001//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Sebastian Redl2c499f62010-08-18 23:56:43 +000010// This file defines the ASTReader class, which reads AST files.
Douglas Gregoref84c4b2009-04-09 22:27:44 +000011//
12//===----------------------------------------------------------------------===//
Chris Lattner92ba5ff2009-04-27 05:14:47 +000013
Sebastian Redlf5b13462010-08-18 23:57:17 +000014#include "clang/Serialization/ASTReader.h"
15#include "clang/Serialization/ASTDeserializationListener.h"
Argyrios Kyrtzidis4bd97102010-08-20 16:03:52 +000016#include "ASTCommon.h"
Douglas Gregor55abb232009-04-10 20:39:37 +000017#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbar732ef8a2009-11-11 23:58:53 +000018#include "clang/Frontend/Utils.h"
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000019#include "clang/Sema/Sema.h"
John McCallcc14d1f2010-08-24 08:50:51 +000020#include "clang/Sema/Scope.h"
Douglas Gregor1a0d0b92009-04-14 00:24:19 +000021#include "clang/AST/ASTConsumer.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000022#include "clang/AST/ASTContext.h"
John McCall19c1bfd2010-08-25 05:32:35 +000023#include "clang/AST/DeclTemplate.h"
Douglas Gregorfeb84b02009-04-14 21:18:50 +000024#include "clang/AST/Expr.h"
John McCallbfd822c2010-08-24 07:32:53 +000025#include "clang/AST/ExprCXX.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000026#include "clang/AST/Type.h"
John McCall8f115c62009-10-16 21:56:05 +000027#include "clang/AST/TypeLocVisitor.h"
Chris Lattner34321bc2009-04-10 21:41:48 +000028#include "clang/Lex/MacroInfo.h"
Douglas Gregoraae92242010-03-19 21:51:54 +000029#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000030#include "clang/Lex/Preprocessor.h"
Steve Naroff3fa455a2009-04-24 20:03:17 +000031#include "clang/Lex/HeaderSearch.h"
Douglas Gregora868bbd2009-04-21 22:25:48 +000032#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000033#include "clang/Basic/SourceManager.h"
Douglas Gregor4c7626e2009-04-13 16:31:14 +000034#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregora7f71a92009-04-10 03:52:48 +000035#include "clang/Basic/FileManager.h"
Douglas Gregorbfbde532009-04-10 21:16:55 +000036#include "clang/Basic/TargetInfo.h"
Douglas Gregord54f3a12009-10-05 21:07:28 +000037#include "clang/Basic/Version.h"
Daniel Dunbarf8502d52009-10-17 23:52:28 +000038#include "llvm/ADT/StringExtras.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000039#include "llvm/Bitcode/BitstreamReader.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000040#include "llvm/Support/MemoryBuffer.h"
John McCall0ad16662009-10-29 08:12:44 +000041#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +000042#include "llvm/System/Path.h"
Douglas Gregoref84c4b2009-04-09 22:27:44 +000043#include <algorithm>
Douglas Gregorc379c072009-04-28 18:58:38 +000044#include <iterator>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000045#include <cstdio>
Douglas Gregorc5046832009-04-27 18:38:38 +000046#include <sys/stat.h>
Douglas Gregoref84c4b2009-04-09 22:27:44 +000047using namespace clang;
Sebastian Redl539c5062010-08-18 23:57:32 +000048using namespace clang::serialization;
Douglas Gregoref84c4b2009-04-09 22:27:44 +000049
50//===----------------------------------------------------------------------===//
Sebastian Redld44cd6a2010-08-18 23:57:06 +000051// PCH validator implementation
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000052//===----------------------------------------------------------------------===//
53
Sebastian Redl3e31c722010-08-18 23:56:56 +000054ASTReaderListener::~ASTReaderListener() {}
Argyrios Kyrtzidis366985d2009-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 Carruthe03aa552010-04-17 20:17:31 +000071 PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
Argyrios Kyrtzidis366985d2009-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 Jahanian45878032010-02-09 19:31:38 +000083 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +000084 PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
85 diag::warn_pch_no_constant_cfstrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000086 PARSE_LANGOPT_BENIGN(PascalStrings);
87 PARSE_LANGOPT_BENIGN(WritableStrings);
Mike Stump11289f42009-09-09 15:08:12 +000088 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000089 diag::warn_pch_lax_vector_conversions);
Nate Begeman9d905792009-06-25 22:57:40 +000090 PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000091 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +000092 PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
Argyrios Kyrtzidis366985d2009-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 Stump11289f42009-09-09 15:08:12 +000096 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +000097 diag::warn_pch_thread_safe_statics);
Daniel Dunbara77eaeb2009-09-03 04:54:28 +000098 PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
Argyrios Kyrtzidis366985d2009-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 Lattner51924e512010-06-26 21:25:03 +0000102 PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
Mike Stump11289f42009-09-09 15:08:12 +0000103 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
Argyrios Kyrtzidis366985d2009-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 Thompsoned4e2952009-11-05 20:14:16 +0000120 PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000121 if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
Mike Stump11289f42009-09-09 15:08:12 +0000122 Reader.Diag(diag::warn_pch_gc_mode)
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000123 << LangOpts.getGCMode() << PPLangOpts.getGCMode();
124 return true;
125 }
126 PARSE_LANGOPT_BENIGN(getVisibilityMode());
Daniel Dunbar143021e2009-09-21 04:16:19 +0000127 PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
128 diag::warn_pch_stack_protector);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000129 PARSE_LANGOPT_BENIGN(InstantiationDepth);
Nate Begeman9d905792009-06-25 22:57:40 +0000130 PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
Mike Stumpd9546382009-12-12 01:27:46 +0000131 PARSE_LANGOPT_BENIGN(CatchUndefined);
Daniel Dunbar143021e2009-09-21 04:16:19 +0000132 PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
Douglas Gregor8ed0c0b2010-07-09 17:35:33 +0000133 PARSE_LANGOPT_BENIGN(SpellChecking);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +0000134#undef PARSE_LANGOPT_IMPORTANT
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000135#undef PARSE_LANGOPT_BENIGN
136
137 return false;
138}
139
Daniel Dunbar20a682d2009-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000147}
148
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000149struct EmptyStringRef {
Benjamin Kramer8d5609b2010-07-14 23:19:41 +0000150 bool operator ()(llvm::StringRef r) const { return r.empty(); }
Sebastian Redl75fbb3b2010-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 Dunbar01ad0a72010-07-16 00:00:11 +0000178 (void) RN;
Sebastian Redl75fbb3b2010-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 Dunbar000c4ff2009-11-11 05:29:04 +0000230 llvm::StringRef OriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000231 std::string &SuggestedPredefines) {
Daniel Dunbar732ef8a2009-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 Dunbar000c4ff2009-11-11 05:29:04 +0000236 llvm::SmallString<256> PCHInclude;
237 PCHInclude += "#include \"";
Daniel Dunbar732ef8a2009-11-11 23:58:53 +0000238 PCHInclude += NormalizeDashIncludePath(OriginalFileName);
Daniel Dunbar000c4ff2009-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 Kremenek1ff615c2010-03-18 00:56:54 +0000243 if (Left == PP.getPredefines()) {
244 Error("Missing PCH include entry!");
245 return true;
246 }
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000247
Sebastian Redl75fbb3b2010-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 Redl75fbb3b2010-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000254 return false;
255
256 SourceManager &SourceMgr = PP.getSourceManager();
Mike Stump11289f42009-09-09 15:08:12 +0000257
Daniel Dunbar8665c7e2009-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 Dunbar045f917e2009-11-13 16:46:11 +0000260 llvm::SmallVector<llvm::StringRef, 8> PCHLines;
Sebastian Redl75fbb3b2010-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 Dunbar045f917e2009-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000267
Daniel Dunbar499baed2009-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000270 std::sort(CmdLineLines.begin(), CmdLineLines.end());
271 std::sort(PCHLines.begin(), PCHLines.end());
272
Daniel Dunbar499baed2009-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 Kyrtzidis366985d2009-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 Dunbar499baed2009-11-11 05:26:28 +0000283 llvm::StringRef Missing = MissingPredefines[I];
284 if (!Missing.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000285 Reader.Diag(diag::warn_pch_compiler_options_mismatch);
286 return true;
287 }
Mike Stump11289f42009-09-09 15:08:12 +0000288
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000289 // This is a macro definition. Determine the name of the macro we're
290 // defining.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000291 std::string::size_type StartOfMacroName = strlen("#define ");
Mike Stump11289f42009-09-09 15:08:12 +0000292 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-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 Dunbar499baed2009-11-11 05:26:28 +0000296 llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000297
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000298 // Determine whether this macro was given a different definition on the
299 // command line.
Daniel Dunbar499baed2009-11-11 05:26:28 +0000300 std::string MacroDefStart = "#define " + MacroName.str();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000301 std::string::size_type MacroDefLen = MacroDefStart.size();
Daniel Dunbar045f917e2009-11-13 16:46:11 +0000302 llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000303 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
304 MacroDefStart);
305 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
Daniel Dunbar8665c7e2009-11-11 03:45:59 +0000306 if (!ConflictPos->startswith(MacroDefStart)) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000307 // Different macro; we're done.
308 ConflictPos = CmdLineLines.end();
Mike Stump11289f42009-09-09 15:08:12 +0000309 break;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000310 }
Mike Stump11289f42009-09-09 15:08:12 +0000311
312 assert(ConflictPos->size() > MacroDefLen &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000313 "Invalid #define in predefines buffer?");
Mike Stump11289f42009-09-09 15:08:12 +0000314 if ((*ConflictPos)[MacroDefLen] != ' ' &&
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000315 (*ConflictPos)[MacroDefLen] != '(')
316 continue; // Longer macro name; keep trying.
Mike Stump11289f42009-09-09 15:08:12 +0000317
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000318 // We found a conflicting macro definition.
319 break;
320 }
Mike Stump11289f42009-09-09 15:08:12 +0000321
Argyrios Kyrtzidis366985d2009-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 Redl75fbb3b2010-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 Dunbar499baed2009-11-11 05:26:28 +0000333 Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000334
335 ConflictingDefines = true;
336 continue;
337 }
Mike Stump11289f42009-09-09 15:08:12 +0000338
Daniel Dunbar8665c7e2009-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000341 if (ConflictingDefines)
342 continue; // Don't complain if there are already conflicting defs
Mike Stump11289f42009-09-09 15:08:12 +0000343
Argyrios Kyrtzidis366985d2009-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 Redl75fbb3b2010-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 Kyrtzidis366985d2009-06-19 00:03:23 +0000356 Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
357 }
Mike Stump11289f42009-09-09 15:08:12 +0000358
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000359 if (ConflictingDefines)
360 return true;
Mike Stump11289f42009-09-09 15:08:12 +0000361
Argyrios Kyrtzidis366985d2009-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 Dunbar499baed2009-11-11 05:26:28 +0000366 std::vector<llvm::StringRef> ExtraPredefines;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000367 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
368 PCHLines.begin(), PCHLines.end(),
Mike Stump11289f42009-09-09 15:08:12 +0000369 std::back_inserter(ExtraPredefines));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000370 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
Daniel Dunbar499baed2009-11-11 05:26:28 +0000371 llvm::StringRef &Extra = ExtraPredefines[I];
372 if (!Extra.startswith("#define ")) {
Argyrios Kyrtzidis366985d2009-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 Stump11289f42009-09-09 15:08:12 +0000380 std::string::size_type EndOfMacroName
Argyrios Kyrtzidis366985d2009-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 Dunbar499baed2009-11-11 05:26:28 +0000384 llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
Argyrios Kyrtzidis366985d2009-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 Dunbar499baed2009-11-11 05:26:28 +0000389 if (IdentifierInfo *II = Reader.get(MacroName)) {
Daniel Dunbar045c92f2009-11-11 00:52:00 +0000390 Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
Argyrios Kyrtzidis366985d2009-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 Gregor5712ebc2010-03-16 16:35:32 +0000404void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
405 unsigned ID) {
406 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
407 ++NumHeaderInfos;
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000408}
409
410void PCHValidator::ReadCounter(unsigned Value) {
411 PP.setCounterValue(Value);
412}
413
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000414//===----------------------------------------------------------------------===//
Sebastian Redl2c499f62010-08-18 23:56:43 +0000415// AST reader implementation
Douglas Gregora868bbd2009-04-21 22:25:48 +0000416//===----------------------------------------------------------------------===//
417
Sebastian Redl07a89a82010-07-30 00:29:29 +0000418void
Sebastian Redl3e31c722010-08-18 23:56:56 +0000419ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
Sebastian Redl07a89a82010-07-30 00:29:29 +0000420 DeserializationListener = Listener;
421 if (DeserializationListener)
422 DeserializationListener->SetReader(this);
423}
424
Chris Lattner92ba5ff2009-04-27 05:14:47 +0000425
Douglas Gregora868bbd2009-04-21 22:25:48 +0000426namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000427class ASTSelectorLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000428 ASTReader &Reader;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000429
430public:
Sebastian Redl834bb972010-08-04 17:20:04 +0000431 struct data_type {
Sebastian Redl539c5062010-08-18 23:57:32 +0000432 SelectorID ID;
Sebastian Redl834bb972010-08-04 17:20:04 +0000433 ObjCMethodList Instance, Factory;
434 };
Douglas Gregorc78d3462009-04-24 21:10:55 +0000435
436 typedef Selector external_key_type;
437 typedef external_key_type internal_key_type;
438
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000439 explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
Mike Stump11289f42009-09-09 15:08:12 +0000440
Douglas Gregorc78d3462009-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 Stump11289f42009-09-09 15:08:12 +0000445
Douglas Gregorc78d3462009-04-24 21:10:55 +0000446 static unsigned ComputeHash(Selector Sel) {
Argyrios Kyrtzidis4bd97102010-08-20 16:03:52 +0000447 return serialization::ComputeHash(Sel);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000448 }
Mike Stump11289f42009-09-09 15:08:12 +0000449
Douglas Gregorc78d3462009-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 Stump11289f42009-09-09 15:08:12 +0000453
Douglas Gregorc78d3462009-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 Stump11289f42009-09-09 15:08:12 +0000461
Douglas Gregor95c13f52009-04-25 17:48:32 +0000462 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000463 using namespace clang::io;
Chris Lattner8575daa2009-04-27 21:45:14 +0000464 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000465 unsigned N = ReadUnalignedLE16(d);
Mike Stump11289f42009-09-09 15:08:12 +0000466 IdentifierInfo *FirstII
Douglas Gregorc78d3462009-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 Gregor038c3382009-05-22 22:45:36 +0000478 return SelTable.getSelector(N, Args.data());
Douglas Gregorc78d3462009-04-24 21:10:55 +0000479 }
Mike Stump11289f42009-09-09 15:08:12 +0000480
Douglas Gregorc78d3462009-04-24 21:10:55 +0000481 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
482 using namespace clang::io;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000483
484 data_type Result;
485
Sebastian Redl834bb972010-08-04 17:20:04 +0000486 Result.ID = ReadUnalignedLE32(d);
487 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
488 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
489
Douglas Gregorc78d3462009-04-24 21:10:55 +0000490 // Load instance methods
491 ObjCMethodList *Prev = 0;
492 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +0000493 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000494 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000495 if (!Result.Instance.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000496 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000497 Result.Instance.Method = Method;
498 Prev = &Result.Instance;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000499 continue;
500 }
501
Ted Kremenekda4abf12010-02-11 00:53:01 +0000502 ObjCMethodList *Mem =
503 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
504 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-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 Stump11289f42009-09-09 15:08:12 +0000511 ObjCMethodDecl *Method
Douglas Gregorc78d3462009-04-24 21:10:55 +0000512 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Sebastian Redl834bb972010-08-04 17:20:04 +0000513 if (!Result.Factory.Method) {
Douglas Gregorc78d3462009-04-24 21:10:55 +0000514 // This is the first method, which is the easy case.
Sebastian Redl834bb972010-08-04 17:20:04 +0000515 Result.Factory.Method = Method;
516 Prev = &Result.Factory;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000517 continue;
518 }
519
Ted Kremenekda4abf12010-02-11 00:53:01 +0000520 ObjCMethodList *Mem =
521 Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
522 Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Douglas Gregorc78d3462009-04-24 21:10:55 +0000523 Prev = Prev->Next;
524 }
525
526 return Result;
527 }
528};
Mike Stump11289f42009-09-09 15:08:12 +0000529
530} // end anonymous namespace
Douglas Gregorc78d3462009-04-24 21:10:55 +0000531
532/// \brief The on-disk hash table used for the global method pool.
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000533typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
534 ASTSelectorLookupTable;
Douglas Gregorc78d3462009-04-24 21:10:55 +0000535
536namespace {
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000537class ASTIdentifierLookupTrait {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000538 ASTReader &Reader;
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000539 llvm::BitstreamCursor &Stream;
Douglas Gregora868bbd2009-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 Redld44cd6a2010-08-18 23:57:06 +0000543 // identifier that was constructed before the AST file was read.
Douglas Gregora868bbd2009-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 Redld44cd6a2010-08-18 23:57:06 +0000553 ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000554 IdentifierInfo *II = 0)
555 : Reader(Reader), Stream(Stream), KnownII(II) { }
Mike Stump11289f42009-09-09 15:08:12 +0000556
Douglas Gregora868bbd2009-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 Stump11289f42009-09-09 15:08:12 +0000562
Douglas Gregora868bbd2009-04-21 22:25:48 +0000563 static unsigned ComputeHash(const internal_key_type& a) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000564 return llvm::HashString(llvm::StringRef(a.first, a.second));
Douglas Gregora868bbd2009-04-21 22:25:48 +0000565 }
Mike Stump11289f42009-09-09 15:08:12 +0000566
Douglas Gregora868bbd2009-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 Stump11289f42009-09-09 15:08:12 +0000570
Douglas Gregora868bbd2009-04-21 22:25:48 +0000571 static std::pair<unsigned, unsigned>
572 ReadKeyDataLength(const unsigned char*& d) {
573 using namespace clang::io;
Douglas Gregor6b7bf5a2009-04-25 20:26:24 +0000574 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregor5287b4e2009-04-25 21:04:17 +0000575 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000576 return std::make_pair(KeyLen, DataLen);
577 }
Mike Stump11289f42009-09-09 15:08:12 +0000578
Douglas Gregora868bbd2009-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 Stump11289f42009-09-09 15:08:12 +0000584
585 IdentifierInfo *ReadData(const internal_key_type& k,
Douglas Gregora868bbd2009-04-21 22:25:48 +0000586 const unsigned char* d,
587 unsigned DataLen) {
588 using namespace clang::io;
Sebastian Redl539c5062010-08-18 23:57:32 +0000589 IdentID ID = ReadUnalignedLE32(d);
Douglas Gregor1d583f22009-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 Redl98912122010-07-27 23:01:28 +0000596 // For uninteresting identifiers, just build the IdentifierInfo
Douglas Gregor1d583f22009-04-28 21:18:29 +0000597 // and associate it with the persistent ID.
598 IdentifierInfo *II = KnownII;
599 if (!II)
Sebastian Redl07a89a82010-07-30 00:29:29 +0000600 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregor1d583f22009-04-28 21:18:29 +0000601 Reader.SetIdentifierInfo(ID, II);
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000602 II->setIsFromAST();
Douglas Gregor1d583f22009-04-28 21:18:29 +0000603 return II;
604 }
605
Douglas Gregorb9256522009-04-28 21:32:13 +0000606 unsigned Bits = ReadUnalignedLE16(d);
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000607 bool CPlusPlusOperatorKeyword = Bits & 0x01;
608 Bits >>= 1;
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000609 bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
610 Bits >>= 1;
Douglas Gregor4621c6a2009-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 Stump11289f42009-09-09 15:08:12 +0000619
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000620 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregorb9256522009-04-28 21:32:13 +0000621 DataLen -= 6;
Douglas Gregora868bbd2009-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 Redl07a89a82010-07-30 00:29:29 +0000627 II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Douglas Gregora868bbd2009-04-21 22:25:48 +0000628 Reader.SetIdentifierInfo(ID, II);
629
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000630 // Set or check the various bits in the IdentifierInfo structure.
Argyrios Kyrtzidis3084a612010-08-11 22:55:12 +0000631 // Token IDs are read-only.
632 if (HasRevertedTokenIDToIdentifier)
633 II->RevertTokenIDToIdentifier();
Douglas Gregor4621c6a2009-04-22 18:49:13 +0000634 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
Mike Stump11289f42009-09-09 15:08:12 +0000635 assert(II->isExtensionToken() == ExtensionToken &&
Douglas Gregor4621c6a2009-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 Gregorc3366a52009-04-21 23:56:24 +0000643 // If this identifier is a macro, deserialize the macro
644 // definition.
645 if (hasMacroDefinition) {
Douglas Gregorb9256522009-04-28 21:32:13 +0000646 uint32_t Offset = ReadUnalignedLE32(d);
Sebastian Redl4e6c5672010-07-21 22:31:37 +0000647 Reader.ReadMacroRecord(Stream, Offset);
Douglas Gregorb9256522009-04-28 21:32:13 +0000648 DataLen -= 4;
Douglas Gregorc3366a52009-04-21 23:56:24 +0000649 }
Douglas Gregora868bbd2009-04-21 22:25:48 +0000650
651 // Read all of the declarations visible at global scope with this
652 // name.
Chris Lattner1d728882009-04-27 22:17:41 +0000653 if (Reader.getContext() == 0) return II;
Douglas Gregor1342e842009-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 Gregora868bbd2009-04-21 22:25:48 +0000659 }
Mike Stump11289f42009-09-09 15:08:12 +0000660
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000661 II->setIsFromAST();
Douglas Gregora868bbd2009-04-21 22:25:48 +0000662 return II;
663 }
664};
Mike Stump11289f42009-09-09 15:08:12 +0000665
666} // end anonymous namespace
Douglas Gregora868bbd2009-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 Redld44cd6a2010-08-18 23:57:06 +0000670typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
671 ASTIdentifierLookupTable;
Douglas Gregora868bbd2009-04-21 22:25:48 +0000672
Argyrios Kyrtzidis07347322010-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 Kyrtzidisd32ee892010-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 Kyrtzidis07347322010-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 Kyrtzidisba88bfa2010-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 Redl9d8f58b2010-08-24 00:50:00 +0000896 } else {
897 Info.NameLookupTableData = 0;
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +0000898 }
899
900 return false;
901}
902
Sebastian Redl2c499f62010-08-18 23:56:43 +0000903void ASTReader::Error(const char *Msg) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +0000904 Diag(diag::err_fe_pch_malformed) << Msg;
Douglas Gregoref84c4b2009-04-09 22:27:44 +0000905}
906
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000907/// \brief Tell the AST listener about the predefines buffers in the chain.
Sebastian Redl2c499f62010-08-18 23:56:43 +0000908bool ASTReader::CheckPredefinesBuffers() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000909 if (Listener)
Sebastian Redl75fbb3b2010-07-14 17:49:11 +0000910 return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
Daniel Dunbar000c4ff2009-11-11 05:29:04 +0000911 ActualOriginalFileName,
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +0000912 SuggestedPredefines);
Douglas Gregorc379c072009-04-28 18:58:38 +0000913 return false;
Douglas Gregor92863e42009-04-10 23:10:45 +0000914}
915
Douglas Gregorc5046832009-04-27 18:38:38 +0000916//===----------------------------------------------------------------------===//
917// Source Manager Deserialization
918//===----------------------------------------------------------------------===//
919
Douglas Gregor4c7626e2009-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 Redl2c499f62010-08-18 23:56:43 +0000922bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000923 unsigned Idx = 0;
924 LineTableInfo &LineTable = SourceMgr.getLineTable();
925
926 // Parse the file names
Douglas Gregora8854652009-04-13 17:12:42 +0000927 std::map<int, int> FileIDs;
928 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregor4c7626e2009-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 Gregor0086a5a2009-07-07 00:12:59 +0000933 MaybeAddSystemRootToFilename(Filename);
Mike Stump11289f42009-09-09 15:08:12 +0000934 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Douglas Gregora8854652009-04-13 17:12:42 +0000935 Filename.size());
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000936 }
937
938 // Parse the line entries
939 std::vector<LineEntry> Entries;
940 while (Idx < Record.size()) {
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000941 int FID = Record[Idx++];
Douglas Gregor4c7626e2009-04-13 16:31:14 +0000942
943 // Extract the line entries
944 unsigned NumEntries = Record[Idx++];
Argyrios Kyrtzidise3029a72010-07-02 11:55:05 +0000945 assert(NumEntries && "Numentries is 00000");
Douglas Gregor4c7626e2009-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 Kyrtzidise3029a72010-07-02 11:55:05 +0000951 int FilenameID = FileIDs[Record[Idx++]];
Mike Stump11289f42009-09-09 15:08:12 +0000952 SrcMgr::CharacteristicKind FileKind
Douglas Gregor4c7626e2009-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 Gregorc5046832009-04-27 18:38:38 +0000964namespace {
965
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000966class ASTStatData {
Douglas Gregorc5046832009-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 Stump11289f42009-09-09 15:08:12 +0000974
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000975 ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
Mike Stump11289f42009-09-09 15:08:12 +0000976 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
977
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000978 ASTStatData()
Douglas Gregorc5046832009-04-27 18:38:38 +0000979 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
980};
981
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000982class ASTStatLookupTrait {
Douglas Gregorc5046832009-04-27 18:38:38 +0000983 public:
984 typedef const char *external_key_type;
985 typedef const char *internal_key_type;
986
Sebastian Redld44cd6a2010-08-18 23:57:06 +0000987 typedef ASTStatData data_type;
Douglas Gregorc5046832009-04-27 18:38:38 +0000988
989 static unsigned ComputeHash(const char *path) {
Daniel Dunbarf8502d52009-10-17 23:52:28 +0000990 return llvm::HashString(path);
Douglas Gregorc5046832009-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 Stump11289f42009-09-09 15:08:12 +00001020 time_t mtime = (time_t) ReadUnalignedLE64(d);
Douglas Gregorc5046832009-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 Redld44cd6a2010-08-18 23:57:06 +00001030class ASTStatCache : public StatSysCallCache {
1031 typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
Douglas Gregorc5046832009-04-27 18:38:38 +00001032 CacheTy *Cache;
1033
1034 unsigned &NumStatHits, &NumStatMisses;
Mike Stump11289f42009-09-09 15:08:12 +00001035public:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001036 ASTStatCache(const unsigned char *Buckets,
Douglas Gregorc5046832009-04-27 18:38:38 +00001037 const unsigned char *Base,
1038 unsigned &NumStatHits,
Mike Stump11289f42009-09-09 15:08:12 +00001039 unsigned &NumStatMisses)
Douglas Gregorc5046832009-04-27 18:38:38 +00001040 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
1041 Cache = CacheTy::Create(Buckets, Base);
1042 }
1043
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001044 ~ASTStatCache() { delete Cache; }
Mike Stump11289f42009-09-09 15:08:12 +00001045
Douglas Gregorc5046832009-04-27 18:38:38 +00001046 int stat(const char *path, struct stat *buf) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001047 // Do the lookup for the file's data in the AST file.
Douglas Gregorc5046832009-04-27 18:38:38 +00001048 CacheTy::iterator I = Cache->find(path);
1049
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001050 // If we don't get a hit in the AST file just forward to 'stat'.
Douglas Gregorc5046832009-04-27 18:38:38 +00001051 if (I == Cache->end()) {
1052 ++NumStatMisses;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001053 return StatSysCallCache::stat(path, buf);
Douglas Gregorc5046832009-04-27 18:38:38 +00001054 }
Mike Stump11289f42009-09-09 15:08:12 +00001055
Douglas Gregorc5046832009-04-27 18:38:38 +00001056 ++NumStatHits;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001057 ASTStatData Data = *I;
Mike Stump11289f42009-09-09 15:08:12 +00001058
Douglas Gregorc5046832009-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 Redl393f8b72010-07-19 20:52:06 +00001073/// \brief Read a source manager block
Sebastian Redl2c499f62010-08-18 23:56:43 +00001074ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001075 using namespace SrcMgr;
Douglas Gregor258ae542009-04-27 06:38:32 +00001076
Sebastian Redl393f8b72010-07-19 20:52:06 +00001077 llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
Sebastian Redl34522812010-07-16 17:50:48 +00001078
Douglas Gregor258ae542009-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 Redl393f8b72010-07-19 20:52:06 +00001083 SLocEntryCursor = F.Stream;
Douglas Gregor258ae542009-04-27 06:38:32 +00001084
1085 // The stream itself is going to skip over the source manager block.
Sebastian Redl393f8b72010-07-19 20:52:06 +00001086 if (F.Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001087 Error("malformed block record in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001088 return Failure;
1089 }
1090
1091 // Enter the source manager block.
Sebastian Redl539c5062010-08-18 23:57:32 +00001092 if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001093 Error("malformed source manager block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001094 return Failure;
1095 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001096
Douglas Gregora7f71a92009-04-10 03:52:48 +00001097 RecordData Record;
1098 while (true) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001099 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001100 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001101 if (SLocEntryCursor.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001102 Error("error at end of Source Manager block in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001103 return Failure;
1104 }
Douglas Gregor92863e42009-04-10 23:10:45 +00001105 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001106 }
Mike Stump11289f42009-09-09 15:08:12 +00001107
Douglas Gregora7f71a92009-04-10 03:52:48 +00001108 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1109 // No known subblocks, always skip them.
Douglas Gregor258ae542009-04-27 06:38:32 +00001110 SLocEntryCursor.ReadSubBlockID();
1111 if (SLocEntryCursor.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001112 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00001113 return Failure;
1114 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001115 continue;
1116 }
Mike Stump11289f42009-09-09 15:08:12 +00001117
Douglas Gregora7f71a92009-04-10 03:52:48 +00001118 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001119 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregora7f71a92009-04-10 03:52:48 +00001120 continue;
1121 }
Mike Stump11289f42009-09-09 15:08:12 +00001122
Douglas Gregora7f71a92009-04-10 03:52:48 +00001123 // Read a record.
1124 const char *BlobStart;
1125 unsigned BlobLen;
1126 Record.clear();
Douglas Gregor258ae542009-04-27 06:38:32 +00001127 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregora7f71a92009-04-10 03:52:48 +00001128 default: // Default behavior: ignore.
1129 break;
1130
Sebastian Redl539c5062010-08-18 23:57:32 +00001131 case SM_LINE_TABLE:
Sebastian Redlb293a452010-07-20 21:20:32 +00001132 if (ParseLineTable(Record))
Douglas Gregor4c7626e2009-04-13 16:31:14 +00001133 return Failure;
Chris Lattner184e65d2009-04-14 23:22:57 +00001134 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001135
Sebastian Redl539c5062010-08-18 23:57:32 +00001136 case SM_SLOC_FILE_ENTRY:
1137 case SM_SLOC_BUFFER_ENTRY:
1138 case SM_SLOC_INSTANTIATION_ENTRY:
Douglas Gregor258ae542009-04-27 06:38:32 +00001139 // Once we hit one of the source location entries, we're done.
1140 return Success;
Douglas Gregora7f71a92009-04-10 03:52:48 +00001141 }
1142 }
1143}
1144
Sebastian Redl06750302010-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 Redl2c499f62010-08-18 23:56:43 +00001147llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
Sebastian Redl06750302010-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 Gregor258ae542009-04-27 06:38:32 +00001165/// \brief Read in the source location entry with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00001166ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00001167 if (ID == 0)
1168 return Success;
1169
1170 if (ID > TotalNumSLocEntries) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001171 Error("source location entry ID out-of-range for AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001172 return Failure;
1173 }
1174
Sebastian Redl06750302010-07-20 21:50:20 +00001175 llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
Sebastian Redl34522812010-07-16 17:50:48 +00001176
Douglas Gregor258ae542009-04-27 06:38:32 +00001177 ++NumSLocEntriesRead;
Douglas Gregor258ae542009-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 Redld44cd6a2010-08-18 23:57:06 +00001182 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001183 return Failure;
1184 }
1185
Douglas Gregor258ae542009-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 Redld44cd6a2010-08-18 23:57:06 +00001191 Error("incorrectly-formatted source location entry in AST file");
Douglas Gregor258ae542009-04-27 06:38:32 +00001192 return Failure;
1193
Sebastian Redl539c5062010-08-18 23:57:32 +00001194 case SM_SLOC_FILE_ENTRY: {
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001195 std::string Filename(BlobStart, BlobStart + BlobLen);
1196 MaybeAddSystemRootToFilename(Filename);
1197 const FileEntry *File = FileMgr.getFile(Filename);
Chris Lattnerd20dc872009-06-15 04:35:16 +00001198 if (File == 0) {
1199 std::string ErrorStr = "could not find file '";
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001200 ErrorStr += Filename;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001201 ErrorStr += "' referenced by AST file";
Chris Lattnerd20dc872009-06-15 04:35:16 +00001202 Error(ErrorStr.c_str());
1203 return Failure;
1204 }
Mike Stump11289f42009-09-09 15:08:12 +00001205
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001206 if (Record.size() < 10) {
Ted Kremenekabb1ddd2010-03-18 21:23:05 +00001207 Error("source location entry is incorrect");
1208 return Failure;
1209 }
1210
Douglas Gregorce3a8292010-07-27 00:27:13 +00001211 if (!DisableValidation &&
1212 ((off_t)Record[4] != File->getSize()
Douglas Gregor08288f22010-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 Gregorce3a8292010-07-27 00:27:13 +00001217 || (time_t)Record[5] != File->getModificationTime()
Douglas Gregor08288f22010-04-09 15:54:22 +00001218#endif
Douglas Gregorce3a8292010-07-27 00:27:13 +00001219 )) {
Douglas Gregorb41ca8f2010-03-21 22:49:54 +00001220 Diag(diag::err_fe_pch_file_modified)
1221 << Filename;
1222 return Failure;
1223 }
1224
Douglas Gregor258ae542009-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 Gregor5712ebc2010-03-16 16:35:32 +00001233 // Reconstruct header-search information for this file.
1234 HeaderFileInfo HFI;
Douglas Gregorb41ca8f2010-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 Gregor5712ebc2010-03-16 16:35:32 +00001239 if (Listener)
1240 Listener->ReadHeaderFileInfo(HFI, File->getUID());
Douglas Gregor258ae542009-04-27 06:38:32 +00001241 break;
1242 }
1243
Sebastian Redl539c5062010-08-18 23:57:32 +00001244 case SM_SLOC_BUFFER_ENTRY: {
Douglas Gregor258ae542009-04-27 06:38:32 +00001245 const char *Name = BlobStart;
1246 unsigned Offset = Record[0];
1247 unsigned Code = SLocEntryCursor.ReadCode();
1248 Record.clear();
Mike Stump11289f42009-09-09 15:08:12 +00001249 unsigned RecCode
Douglas Gregor258ae542009-04-27 06:38:32 +00001250 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001251
Sebastian Redl539c5062010-08-18 23:57:32 +00001252 if (RecCode != SM_SLOC_BUFFER_BLOB) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001253 Error("AST record has invalid code");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00001254 return Failure;
1255 }
1256
Douglas Gregor258ae542009-04-27 06:38:32 +00001257 llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00001258 = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
1259 Name);
Douglas Gregor258ae542009-04-27 06:38:32 +00001260 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
Mike Stump11289f42009-09-09 15:08:12 +00001261
Douglas Gregore6648fb2009-04-28 20:33:11 +00001262 if (strcmp(Name, "<built-in>") == 0) {
Sebastian Redl75fbb3b2010-07-14 17:49:11 +00001263 PCHPredefinesBlock Block = {
1264 BufferID,
1265 llvm::StringRef(BlobStart, BlobLen - 1)
1266 };
1267 PCHPredefinesBuffers.push_back(Block);
Douglas Gregore6648fb2009-04-28 20:33:11 +00001268 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001269
1270 break;
1271 }
1272
Sebastian Redl539c5062010-08-18 23:57:32 +00001273 case SM_SLOC_INSTANTIATION_ENTRY: {
Mike Stump11289f42009-09-09 15:08:12 +00001274 SourceLocation SpellingLoc
Douglas Gregor258ae542009-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 Stump11289f42009-09-09 15:08:12 +00001283 }
Douglas Gregor258ae542009-04-27 06:38:32 +00001284 }
1285
1286 return Success;
1287}
1288
Chris Lattnere78a6be2009-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 Redl2c499f62010-08-18 23:56:43 +00001292bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
Chris Lattnere78a6be2009-04-27 01:05:14 +00001293 unsigned BlockID) {
1294 if (Cursor.EnterSubBlock(BlockID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001295 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001296 return Failure;
1297 }
Mike Stump11289f42009-09-09 15:08:12 +00001298
Chris Lattnere78a6be2009-04-27 01:05:14 +00001299 while (true) {
1300 unsigned Code = Cursor.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00001301
Chris Lattnere78a6be2009-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 Redl2c499f62010-08-18 23:56:43 +00001309void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001310 assert(PP && "Forgot to set Preprocessor ?");
Mike Stump11289f42009-09-09 15:08:12 +00001311
Douglas Gregorc3366a52009-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 Stump11289f42009-09-09 15:08:12 +00001320
Douglas Gregorc3366a52009-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 Redld44cd6a2010-08-18 23:57:06 +00001331 Error("malformed block record in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001332 return;
1333 }
1334 continue;
Mike Stump11289f42009-09-09 15:08:12 +00001335
Douglas Gregorc3366a52009-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 Redl539c5062010-08-18 23:57:32 +00001344 PreprocessorRecordTypes RecType =
1345 (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001346 switch (RecType) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001347 case PP_MACRO_OBJECT_LIKE:
1348 case PP_MACRO_FUNCTION_LIKE: {
Douglas Gregorc3366a52009-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 Redld44cd6a2010-08-18 23:57:06 +00001357 Error("macro must have a name in AST file");
Douglas Gregorc3366a52009-04-21 23:56:24 +00001358 return;
1359 }
1360 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1361 bool isUsed = Record[2];
Mike Stump11289f42009-09-09 15:08:12 +00001362
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001363 MacroInfo *MI = PP->AllocateMacroInfo(Loc);
Douglas Gregorc3366a52009-04-21 23:56:24 +00001364 MI->setIsUsed(isUsed);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001365 MI->setIsFromAST();
Mike Stump11289f42009-09-09 15:08:12 +00001366
Douglas Gregoraae92242010-03-19 21:51:54 +00001367 unsigned NextIndex = 3;
Sebastian Redl539c5062010-08-18 23:57:32 +00001368 if (RecType == PP_MACRO_FUNCTION_LIKE) {
Douglas Gregorc3366a52009-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 Gregoraae92242010-03-19 21:51:54 +00001374 NextIndex = 6 + NumArgs;
Douglas Gregorc3366a52009-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 Gregor038c3382009-05-22 22:45:36 +00001382 MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001383 PP->getPreprocessorAllocator());
Douglas Gregorc3366a52009-04-21 23:56:24 +00001384 }
1385
1386 // Finally, install the macro.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001387 PP->setMacroInfo(II, MI);
Douglas Gregorc3366a52009-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 Gregoraae92242010-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 Gregorc3366a52009-04-21 23:56:24 +00001399 ++NumMacrosRead;
1400 break;
1401 }
Mike Stump11289f42009-09-09 15:08:12 +00001402
Sebastian Redl539c5062010-08-18 23:57:32 +00001403 case PP_TOKEN: {
Douglas Gregorc3366a52009-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 Stump11289f42009-09-09 15:08:12 +00001407
Douglas Gregorc3366a52009-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 Gregoraae92242010-03-19 21:51:54 +00001419
Sebastian Redl539c5062010-08-18 23:57:32 +00001420 case PP_MACRO_INSTANTIATION: {
Douglas Gregoraae92242010-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 Redld44cd6a2010-08-18 23:57:06 +00001428 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-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 Redl539c5062010-08-18 23:57:32 +00001446 case PP_MACRO_DEFINITION: {
Douglas Gregoraae92242010-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 Redld44cd6a2010-08-18 23:57:06 +00001454 Error("missing preprocessing record in AST file");
Douglas Gregoraae92242010-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 Naroff3fa455a2009-04-24 20:03:17 +00001477 }
Douglas Gregorc3366a52009-04-21 23:56:24 +00001478 }
1479}
1480
Sebastian Redl2c499f62010-08-18 23:56:43 +00001481void ASTReader::ReadDefinedMacros() {
Sebastian Redl4e6c5672010-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 Redl34522812010-07-16 17:50:48 +00001484
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001485 // If there was no preprocessor block, skip this file.
1486 if (!MacroCursor.getBitStreamReader())
1487 continue;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001488
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001489 llvm::BitstreamCursor Cursor = MacroCursor;
Sebastian Redl539c5062010-08-18 23:57:32 +00001490 if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001491 Error("malformed preprocessor block record in AST file");
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001492 return;
1493 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001494
Sebastian Redl4e6c5672010-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 Redld44cd6a2010-08-18 23:57:06 +00001500 Error("error at end of preprocessor block in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001501 return;
1502 }
1503 break;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001504 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001505
Sebastian Redl4e6c5672010-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 Redld44cd6a2010-08-18 23:57:06 +00001510 Error("malformed block record in AST file");
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001511 return;
1512 }
1513 continue;
1514 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001515
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001516 if (Code == llvm::bitc::DEFINE_ABBREV) {
1517 Cursor.ReadAbbrevRecord();
1518 continue;
1519 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001520
Sebastian Redl4e6c5672010-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 Gregor9882a5a2010-01-04 19:18:44 +00001528
Sebastian Redl539c5062010-08-18 23:57:32 +00001529 case PP_MACRO_OBJECT_LIKE:
1530 case PP_MACRO_FUNCTION_LIKE:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001531 DecodeIdentifierInfo(Record[0]);
1532 break;
1533
Sebastian Redl539c5062010-08-18 23:57:32 +00001534 case PP_TOKEN:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001535 // Ignore tokens.
1536 break;
Douglas Gregoraae92242010-03-19 21:51:54 +00001537
Sebastian Redl539c5062010-08-18 23:57:32 +00001538 case PP_MACRO_INSTANTIATION:
1539 case PP_MACRO_DEFINITION:
Sebastian Redl4e6c5672010-07-21 22:31:37 +00001540 // Read the macro record.
1541 ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
1542 break;
1543 }
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001544 }
1545 }
1546}
1547
Sebastian Redl50e26582010-09-15 19:54:06 +00001548MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {
Douglas Gregoraae92242010-03-19 21:51:54 +00001549 if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
1550 return 0;
Sebastian Redl4e6c5672010-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 Gregoraae92242010-03-19 21:51:54 +00001565 return MacroDefinitionsLoaded[ID];
1566}
1567
Douglas Gregor0086a5a2009-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 Redl2c499f62010-08-18 23:56:43 +00001571void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
Douglas Gregor0086a5a2009-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 Stump11289f42009-09-09 15:08:12 +00001575
Daniel Dunbarf2ce9a22009-11-18 19:50:41 +00001576 if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001577 return;
1578
Douglas Gregor0086a5a2009-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 Stump11289f42009-09-09 15:08:12 +00001584
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001585 unsigned Length = strlen(isysroot);
1586 if (isysroot[Length - 1] != '/')
1587 Filename.insert(Filename.begin(), '/');
Mike Stump11289f42009-09-09 15:08:12 +00001588
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001589 Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1590}
1591
Sebastian Redl2c499f62010-08-18 23:56:43 +00001592ASTReader::ASTReadResult
Sebastian Redl3e31c722010-08-18 23:56:56 +00001593ASTReader::ReadASTBlock(PerFileData &F) {
Sebastian Redl34522812010-07-16 17:50:48 +00001594 llvm::BitstreamCursor &Stream = F.Stream;
1595
Sebastian Redl539c5062010-08-18 23:57:32 +00001596 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001597 Error("malformed block record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001598 return Failure;
1599 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001600
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001601 // Read all of the records and blocks for the ASt file.
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001602 RecordData Record;
Sebastian Redl393f8b72010-07-19 20:52:06 +00001603 bool First = true;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001604 while (!Stream.AtEndOfStream()) {
1605 unsigned Code = Stream.ReadCode();
1606 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor55abb232009-04-10 20:39:37 +00001607 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001608 Error("error at end of module block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001609 return Failure;
1610 }
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001611
Douglas Gregor55abb232009-04-10 20:39:37 +00001612 return Success;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001613 }
1614
1615 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1616 switch (Stream.ReadSubBlockID()) {
Sebastian Redl539c5062010-08-18 23:57:32 +00001617 case DECLTYPES_BLOCK_ID:
Chris Lattnere78a6be2009-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 Redl34522812010-07-16 17:50:48 +00001622 F.DeclsCursor = Stream;
Chris Lattnere78a6be2009-04-27 01:05:14 +00001623 if (Stream.SkipBlock() || // Skip with the main cursor.
1624 // Read the abbrevs.
Sebastian Redl539c5062010-08-18 23:57:32 +00001625 ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001626 Error("malformed block record in AST file");
Chris Lattnere78a6be2009-04-27 01:05:14 +00001627 return Failure;
1628 }
1629 break;
Mike Stump11289f42009-09-09 15:08:12 +00001630
Sebastian Redl539c5062010-08-18 23:57:32 +00001631 case PREPROCESSOR_BLOCK_ID:
Sebastian Redl34522812010-07-16 17:50:48 +00001632 F.MacroCursor = Stream;
Douglas Gregor9882a5a2010-01-04 19:18:44 +00001633 if (PP)
1634 PP->setExternalSource(this);
1635
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001636 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001637 Error("malformed block record in AST file");
Chris Lattnerc523d8e2009-04-11 21:15:38 +00001638 return Failure;
1639 }
1640 break;
Steve Naroff2ddea052009-04-23 10:39:46 +00001641
Sebastian Redl539c5062010-08-18 23:57:32 +00001642 case SOURCE_MANAGER_BLOCK_ID:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001643 switch (ReadSourceManagerBlock(F)) {
Douglas Gregor92863e42009-04-10 23:10:45 +00001644 case Success:
1645 break;
1646
1647 case Failure:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001648 Error("malformed source manager block in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001649 return Failure;
Douglas Gregor92863e42009-04-10 23:10:45 +00001650
1651 case IgnorePCH:
1652 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00001653 }
Douglas Gregora7f71a92009-04-10 03:52:48 +00001654 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001655 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001656 First = false;
Douglas Gregor1e9bf3b2009-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 Gregorbfbde532009-04-10 21:16:55 +00001667 const char *BlobStart = 0;
1668 unsigned BlobLen = 0;
Sebastian Redl539c5062010-08-18 23:57:32 +00001669 switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
Douglas Gregorbfbde532009-04-10 21:16:55 +00001670 &BlobStart, &BlobLen)) {
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001671 default: // Default behavior: ignore.
1672 break;
1673
Sebastian Redl539c5062010-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 Redlc2e6dbf2010-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 Redl539c5062010-08-18 23:57:32 +00001690 case CHAINED_METADATA: {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001691 if (!First) {
1692 Error("CHAINED_METADATA is not first record in block");
1693 return Failure;
1694 }
Sebastian Redl539c5062010-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 Redlc2e6dbf2010-07-17 00:12:06 +00001697 : diag::warn_pch_version_too_new);
1698 return IgnorePCH;
1699 }
1700
1701 // Load the chained file.
Sebastian Redl3e31c722010-08-18 23:56:56 +00001702 switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
Sebastian Redlc2e6dbf2010-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 Redl539c5062010-08-18 23:57:32 +00001711 case TYPE_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001712 if (F.LocalNumTypes != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001713 Error("duplicate TYPE_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001714 return Failure;
1715 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001716 F.TypeOffsets = (const uint32_t *)BlobStart;
1717 F.LocalNumTypes = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001718 break;
1719
Sebastian Redl539c5062010-08-18 23:57:32 +00001720 case DECL_OFFSET:
Sebastian Redl9e687992010-07-19 22:06:55 +00001721 if (F.LocalNumDecls != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001722 Error("duplicate DECL_OFFSET record in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001723 return Failure;
1724 }
Sebastian Redl9e687992010-07-19 22:06:55 +00001725 F.DeclOffsets = (const uint32_t *)BlobStart;
1726 F.LocalNumDecls = Record[0];
Douglas Gregor1e9bf3b2009-04-10 17:25:41 +00001727 break;
Douglas Gregor55abb232009-04-10 20:39:37 +00001728
Sebastian Redl539c5062010-08-18 23:57:32 +00001729 case TU_UPDATE_LEXICAL: {
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001730 DeclContextInfo Info = {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00001731 /* No visible information */ 0,
Sebastian Redl539c5062010-08-18 23:57:32 +00001732 reinterpret_cast<const DeclID *>(BlobStart),
1733 BlobLen / sizeof(DeclID)
Sebastian Redl4b1f4902010-07-27 18:24:41 +00001734 };
1735 DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
1736 break;
1737 }
1738
Sebastian Redld7dce0a2010-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 Redl539c5062010-08-18 23:57:32 +00001755 case REDECLS_UPDATE_LATEST: {
Argyrios Kyrtzidis839bbac2010-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 Redl539c5062010-08-18 23:57:32 +00001758 DeclID First = Record[i], Latest = Record[i+1];
Argyrios Kyrtzidis839bbac2010-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 Redl539c5062010-08-18 23:57:32 +00001767 case LANGUAGE_OPTIONS:
Douglas Gregorce3a8292010-07-27 00:27:13 +00001768 if (ParseLanguageOptions(Record) && !DisableValidation)
Douglas Gregor55abb232009-04-10 20:39:37 +00001769 return IgnorePCH;
1770 break;
Douglas Gregorbfbde532009-04-10 21:16:55 +00001771
Sebastian Redl539c5062010-08-18 23:57:32 +00001772 case IDENTIFIER_TABLE:
Sebastian Redl393f8b72010-07-19 20:52:06 +00001773 F.IdentifierTableData = BlobStart;
Douglas Gregor0e149972009-04-25 19:10:14 +00001774 if (Record[0]) {
Sebastian Redl393f8b72010-07-19 20:52:06 +00001775 F.IdentifierLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001776 = ASTIdentifierLookupTable::Create(
Sebastian Redl393f8b72010-07-19 20:52:06 +00001777 (const unsigned char *)F.IdentifierTableData + Record[0],
1778 (const unsigned char *)F.IdentifierTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001779 ASTIdentifierLookupTrait(*this, F.Stream));
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001780 if (PP)
1781 PP->getIdentifierTable().setExternalIdentifierLookup(this);
Douglas Gregor0e149972009-04-25 19:10:14 +00001782 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001783 break;
1784
Sebastian Redl539c5062010-08-18 23:57:32 +00001785 case IDENTIFIER_OFFSET:
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001786 if (F.LocalNumIdentifiers != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001787 Error("duplicate IDENTIFIER_OFFSET record in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001788 return Failure;
1789 }
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00001790 F.IdentifierOffsets = (const uint32_t *)BlobStart;
1791 F.LocalNumIdentifiers = Record[0];
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001792 break;
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00001793
Sebastian Redl539c5062010-08-18 23:57:32 +00001794 case EXTERNAL_DEFINITIONS:
Sebastian Redlb293a452010-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 Gregor1a0d0b92009-04-14 00:24:19 +00001801 break;
Douglas Gregor08f01292009-04-17 22:13:46 +00001802
Sebastian Redl539c5062010-08-18 23:57:32 +00001803 case SPECIAL_TYPES:
Sebastian Redlb293a452010-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 Gregor652d82a2009-04-18 05:55:16 +00001809 break;
1810
Sebastian Redl539c5062010-08-18 23:57:32 +00001811 case STATISTICS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001812 TotalNumStatements += Record[0];
1813 TotalNumMacros += Record[1];
1814 TotalLexicalDeclContexts += Record[2];
1815 TotalVisibleDeclContexts += Record[3];
Douglas Gregor08f01292009-04-17 22:13:46 +00001816 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001817
Sebastian Redl539c5062010-08-18 23:57:32 +00001818 case TENTATIVE_DEFINITIONS:
Sebastian Redlb293a452010-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 Gregord4df8652009-04-22 22:02:47 +00001825 break;
Douglas Gregoracfc76c2009-04-22 22:18:58 +00001826
Sebastian Redl539c5062010-08-18 23:57:32 +00001827 case UNUSED_FILESCOPED_DECLS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001828 // Optimization for the first block.
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001829 if (UnusedFileScopedDecls.empty())
1830 UnusedFileScopedDecls.swap(Record);
Sebastian Redlb293a452010-07-20 21:20:32 +00001831 else
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00001832 UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
1833 Record.begin(), Record.end());
Tanya Lattner90073802010-02-12 00:07:30 +00001834 break;
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001835
Sebastian Redl539c5062010-08-18 23:57:32 +00001836 case WEAK_UNDECLARED_IDENTIFIERS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001837 // Later blocks overwrite earlier ones.
1838 WeakUndeclaredIdentifiers.swap(Record);
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00001839 break;
1840
Sebastian Redl539c5062010-08-18 23:57:32 +00001841 case LOCALLY_SCOPED_EXTERNAL_DECLS:
Sebastian Redlb293a452010-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 Gregoracfc76c2009-04-22 22:18:58 +00001848 break;
Douglas Gregorc78d3462009-04-24 21:10:55 +00001849
Sebastian Redl539c5062010-08-18 23:57:32 +00001850 case SELECTOR_OFFSETS:
Sebastian Redla19a67f2010-08-03 21:58:15 +00001851 F.SelectorOffsets = (const uint32_t *)BlobStart;
Sebastian Redlada023c2010-08-04 20:40:17 +00001852 F.LocalNumSelectors = Record[0];
Douglas Gregor95c13f52009-04-25 17:48:32 +00001853 break;
1854
Sebastian Redl539c5062010-08-18 23:57:32 +00001855 case METHOD_POOL:
Sebastian Redlada023c2010-08-04 20:40:17 +00001856 F.SelectorLookupTableData = (const unsigned char *)BlobStart;
Douglas Gregor95c13f52009-04-25 17:48:32 +00001857 if (Record[0])
Sebastian Redlada023c2010-08-04 20:40:17 +00001858 F.SelectorLookupTable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001859 = ASTSelectorLookupTable::Create(
Sebastian Redlada023c2010-08-04 20:40:17 +00001860 F.SelectorLookupTableData + Record[0],
1861 F.SelectorLookupTableData,
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001862 ASTSelectorLookupTrait(*this));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00001863 TotalNumMethodPoolEntries += Record[1];
Douglas Gregorc78d3462009-04-24 21:10:55 +00001864 break;
Douglas Gregoreda6a892009-04-26 00:07:37 +00001865
Sebastian Redl96371b42010-09-22 00:42:30 +00001866 case REFERENCED_SELECTOR_POOL:
1867 if (ReferencedSelectorsData.empty())
1868 ReferencedSelectorsData.swap(Record);
1869 else
1870 ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
1871 Record.begin(), Record.end());
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00001872 break;
1873
Sebastian Redl539c5062010-08-18 23:57:32 +00001874 case PP_COUNTER_VALUE:
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00001875 if (!Record.empty() && Listener)
1876 Listener->ReadCounter(Record[0]);
Douglas Gregoreda6a892009-04-26 00:07:37 +00001877 break;
Douglas Gregor258ae542009-04-27 06:38:32 +00001878
Sebastian Redl539c5062010-08-18 23:57:32 +00001879 case SOURCE_LOCATION_OFFSETS:
Sebastian Redlb293a452010-07-20 21:20:32 +00001880 F.SLocOffsets = (const uint32_t *)BlobStart;
1881 F.LocalNumSLocEntries = Record[0];
Sebastian Redl96371b42010-09-22 00:42:30 +00001882 F.NextOffset = Record[1];
Douglas Gregor258ae542009-04-27 06:38:32 +00001883 break;
1884
Sebastian Redl539c5062010-08-18 23:57:32 +00001885 case SOURCE_LOCATION_PRELOADS:
Sebastian Redl96371b42010-09-22 00:42:30 +00001886 if (PreloadSLocEntries.empty())
1887 PreloadSLocEntries.swap(Record);
1888 else
1889 PreloadSLocEntries.insert(PreloadSLocEntries.end(),
1890 Record.begin(), Record.end());
Douglas Gregor258ae542009-04-27 06:38:32 +00001891 break;
Douglas Gregorc5046832009-04-27 18:38:38 +00001892
Sebastian Redl539c5062010-08-18 23:57:32 +00001893 case STAT_CACHE: {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001894 ASTStatCache *MyStatCache =
1895 new ASTStatCache((const unsigned char *)BlobStart + Record[0],
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001896 (const unsigned char *)BlobStart,
1897 NumStatHits, NumStatMisses);
1898 FileMgr.addStatCache(MyStatCache);
Sebastian Redl34522812010-07-16 17:50:48 +00001899 F.StatCache = MyStatCache;
Douglas Gregorc5046832009-04-27 18:38:38 +00001900 break;
Douglas Gregord2eb58a2009-10-16 18:18:30 +00001901 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00001902
Sebastian Redl539c5062010-08-18 23:57:32 +00001903 case EXT_VECTOR_DECLS:
Sebastian Redl04f5c312010-07-28 21:38:49 +00001904 // Optimization for the first block.
1905 if (ExtVectorDecls.empty())
1906 ExtVectorDecls.swap(Record);
1907 else
1908 ExtVectorDecls.insert(ExtVectorDecls.end(),
1909 Record.begin(), Record.end());
Douglas Gregor61cac2b2009-04-27 20:06:05 +00001910 break;
1911
Sebastian Redl539c5062010-08-18 23:57:32 +00001912 case VTABLE_USES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001913 // Later tables overwrite earlier ones.
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001914 VTableUses.swap(Record);
1915 break;
1916
Sebastian Redl539c5062010-08-18 23:57:32 +00001917 case DYNAMIC_CLASSES:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001918 // Optimization for the first block.
1919 if (DynamicClasses.empty())
1920 DynamicClasses.swap(Record);
1921 else
1922 DynamicClasses.insert(DynamicClasses.end(),
1923 Record.begin(), Record.end());
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00001924 break;
1925
Sebastian Redl539c5062010-08-18 23:57:32 +00001926 case PENDING_IMPLICIT_INSTANTIATIONS:
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00001927 // Optimization for the first block.
Chandler Carruth54080172010-08-25 08:44:16 +00001928 if (PendingInstantiations.empty())
1929 PendingInstantiations.swap(Record);
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00001930 else
Chandler Carruth54080172010-08-25 08:44:16 +00001931 PendingInstantiations.insert(PendingInstantiations.end(),
1932 Record.begin(), Record.end());
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00001933 break;
1934
Sebastian Redl539c5062010-08-18 23:57:32 +00001935 case SEMA_DECL_REFS:
Sebastian Redl08aca90252010-08-05 18:21:25 +00001936 // Later tables overwrite earlier ones.
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00001937 SemaDeclRefs.swap(Record);
1938 break;
1939
Sebastian Redl539c5062010-08-18 23:57:32 +00001940 case ORIGINAL_FILE_NAME:
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001941 // The primary AST will be the last to get here, so it will be the one
Sebastian Redlb293a452010-07-20 21:20:32 +00001942 // that's used.
Daniel Dunbar000c4ff2009-11-11 05:29:04 +00001943 ActualOriginalFileName.assign(BlobStart, BlobLen);
1944 OriginalFileName = ActualOriginalFileName;
Douglas Gregor0086a5a2009-07-07 00:12:59 +00001945 MaybeAddSystemRootToFilename(OriginalFileName);
Douglas Gregor45fe0362009-05-12 01:31:05 +00001946 break;
Mike Stump11289f42009-09-09 15:08:12 +00001947
Sebastian Redl539c5062010-08-18 23:57:32 +00001948 case VERSION_CONTROL_BRANCH_REVISION: {
Ted Kremenek8bd09292010-02-12 23:31:14 +00001949 const std::string &CurBranch = getClangFullRepositoryVersion();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001950 llvm::StringRef ASTBranch(BlobStart, BlobLen);
1951 if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
1952 Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
Douglas Gregord54f3a12009-10-05 21:07:28 +00001953 return IgnorePCH;
1954 }
1955 break;
1956 }
Sebastian Redlfa061442010-07-21 20:07:32 +00001957
Sebastian Redl539c5062010-08-18 23:57:32 +00001958 case MACRO_DEFINITION_OFFSETS:
Sebastian Redlfa061442010-07-21 20:07:32 +00001959 F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
1960 F.NumPreallocatedPreprocessingEntities = Record[0];
1961 F.LocalNumMacroDefinitions = Record[1];
Douglas Gregoraae92242010-03-19 21:51:54 +00001962 break;
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001963
Sebastian Redl539c5062010-08-18 23:57:32 +00001964 case DECL_REPLACEMENTS: {
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001965 if (Record.size() % 2 != 0) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001966 Error("invalid DECL_REPLACEMENTS block in AST file");
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001967 return Failure;
1968 }
1969 for (unsigned I = 0, N = Record.size(); I != N; I += 2)
Sebastian Redl539c5062010-08-18 23:57:32 +00001970 ReplacedDecls[static_cast<DeclID>(Record[I])] =
Sebastian Redle7c1fe62010-08-13 00:28:03 +00001971 std::make_pair(&F, Record[I+1]);
1972 break;
1973 }
Sebastian Redlaba202b2010-08-24 22:50:19 +00001974
1975 case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: {
1976 AdditionalTemplateSpecializations &ATS =
1977 AdditionalTemplateSpecializationsPending[Record[0]];
1978 ATS.insert(ATS.end(), Record.begin()+1, Record.end());
1979 break;
1980 }
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00001981 }
Sebastian Redl393f8b72010-07-19 20:52:06 +00001982 First = false;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001983 }
Sebastian Redld44cd6a2010-08-18 23:57:06 +00001984 Error("premature end of bitstream in AST file");
Douglas Gregor55abb232009-04-10 20:39:37 +00001985 return Failure;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00001986}
1987
Sebastian Redl3e31c722010-08-18 23:56:56 +00001988ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
1989 switch(ReadASTCore(FileName)) {
Sebastian Redl2abc0382010-07-16 20:41:52 +00001990 case Failure: return Failure;
1991 case IgnorePCH: return IgnorePCH;
1992 case Success: break;
1993 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00001994
1995 // Here comes stuff that we only do once the entire chain is loaded.
1996
Sebastian Redl96371b42010-09-22 00:42:30 +00001997 // Allocate space for loaded slocentries, identifiers, decls and types.
Sebastian Redlfa061442010-07-21 20:07:32 +00001998 unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
Sebastian Redlada023c2010-08-04 20:40:17 +00001999 TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
2000 TotalNumSelectors = 0;
Sebastian Redl9e687992010-07-19 22:06:55 +00002001 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redl96371b42010-09-22 00:42:30 +00002002 TotalNumSLocEntries += Chain[I]->LocalNumSLocEntries;
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00002003 TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
Sebastian Redl9e687992010-07-19 22:06:55 +00002004 TotalNumTypes += Chain[I]->LocalNumTypes;
2005 TotalNumDecls += Chain[I]->LocalNumDecls;
Sebastian Redlfa061442010-07-21 20:07:32 +00002006 TotalNumPreallocatedPreprocessingEntities +=
2007 Chain[I]->NumPreallocatedPreprocessingEntities;
2008 TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
Sebastian Redlada023c2010-08-04 20:40:17 +00002009 TotalNumSelectors += Chain[I]->LocalNumSelectors;
Sebastian Redl9e687992010-07-19 22:06:55 +00002010 }
Sebastian Redl96371b42010-09-22 00:42:30 +00002011 SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries,
2012 Chain.front()->NextOffset);
Sebastian Redlbd1b5be2010-07-19 22:28:42 +00002013 IdentifiersLoaded.resize(TotalNumIdentifiers);
Sebastian Redl9e687992010-07-19 22:06:55 +00002014 TypesLoaded.resize(TotalNumTypes);
2015 DeclsLoaded.resize(TotalNumDecls);
Sebastian Redlfa061442010-07-21 20:07:32 +00002016 MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
2017 if (PP) {
2018 if (TotalNumIdentifiers > 0)
2019 PP->getHeaderSearchInfo().SetExternalLookup(this);
2020 if (TotalNumPreallocatedPreprocessingEntities > 0) {
2021 if (!PP->getPreprocessingRecord())
2022 PP->createPreprocessingRecord();
2023 PP->getPreprocessingRecord()->SetExternalSource(*this,
2024 TotalNumPreallocatedPreprocessingEntities);
2025 }
2026 }
Sebastian Redlada023c2010-08-04 20:40:17 +00002027 SelectorsLoaded.resize(TotalNumSelectors);
Sebastian Redl96371b42010-09-22 00:42:30 +00002028 // Preload SLocEntries.
2029 for (unsigned I = 0, N = PreloadSLocEntries.size(); I != N; ++I) {
2030 ASTReadResult Result = ReadSLocEntryRecord(PreloadSLocEntries[I]);
2031 if (Result != Success)
2032 return Result;
2033 }
Sebastian Redl9e687992010-07-19 22:06:55 +00002034
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002035 // Check the predefines buffers.
Douglas Gregorce3a8292010-07-27 00:27:13 +00002036 if (!DisableValidation && CheckPredefinesBuffers())
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002037 return IgnorePCH;
2038
2039 if (PP) {
2040 // Initialization of keywords and pragmas occurs before the
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002041 // AST file is read, so there may be some identifiers that were
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002042 // loaded into the IdentifierTable before we intercepted the
2043 // creation of identifiers. Iterate through the list of known
2044 // identifiers and determine whether we have to establish
2045 // preprocessor definitions or top-level identifier declaration
2046 // chains for those identifiers.
2047 //
2048 // We copy the IdentifierInfo pointers to a small vector first,
2049 // since de-serializing declarations or macro definitions can add
2050 // new entries into the identifier table, invalidating the
2051 // iterators.
2052 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
2053 for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
2054 IdEnd = PP->getIdentifierTable().end();
2055 Id != IdEnd; ++Id)
2056 Identifiers.push_back(Id->second);
Sebastian Redlfa061442010-07-21 20:07:32 +00002057 // We need to search the tables in all files.
Sebastian Redlfa061442010-07-21 20:07:32 +00002058 for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002059 ASTIdentifierLookupTable *IdTable
2060 = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
2061 // Not all AST files necessarily have identifier tables, only the useful
Sebastian Redl5c415f32010-07-22 17:01:13 +00002062 // ones.
2063 if (!IdTable)
2064 continue;
Sebastian Redlfa061442010-07-21 20:07:32 +00002065 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
2066 IdentifierInfo *II = Identifiers[I];
2067 // Look in the on-disk hash tables for an entry for this identifier
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002068 ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
Sebastian Redlfa061442010-07-21 20:07:32 +00002069 std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002070 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
Sebastian Redlb293a452010-07-20 21:20:32 +00002071 if (Pos == IdTable->end())
2072 continue;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002073
Sebastian Redlb293a452010-07-20 21:20:32 +00002074 // Dereferencing the iterator has the effect of populating the
2075 // IdentifierInfo node with the various declarations it needs.
2076 (void)*Pos;
2077 }
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002078 }
2079 }
2080
2081 if (Context)
2082 InitializeContext(*Context);
2083
2084 return Success;
2085}
2086
Sebastian Redl3e31c722010-08-18 23:56:56 +00002087ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002088 Chain.push_back(new PerFileData());
Sebastian Redl34522812010-07-16 17:50:48 +00002089 PerFileData &F = *Chain.back();
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002090
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002091 // Set the AST file name.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002092 F.FileName = FileName;
2093
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002094 // Open the AST file.
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002095 //
2096 // FIXME: This shouldn't be here, we should just take a raw_ostream.
2097 std::string ErrStr;
2098 F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
2099 if (!F.Buffer) {
2100 Error(ErrStr.c_str());
2101 return IgnorePCH;
2102 }
2103
2104 // Initialize the stream
2105 F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
2106 (const unsigned char *)F.Buffer->getBufferEnd());
Sebastian Redl34522812010-07-16 17:50:48 +00002107 llvm::BitstreamCursor &Stream = F.Stream;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002108 Stream.init(F.StreamFile);
Sebastian Redlfa061442010-07-21 20:07:32 +00002109 F.SizeInBits = F.Buffer->getBufferSize() * 8;
Sebastian Redlc2e6dbf2010-07-17 00:12:06 +00002110
2111 // Sniff for the signature.
2112 if (Stream.Read(8) != 'C' ||
2113 Stream.Read(8) != 'P' ||
2114 Stream.Read(8) != 'C' ||
2115 Stream.Read(8) != 'H') {
2116 Diag(diag::err_not_a_pch_file) << FileName;
2117 return Failure;
2118 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002119
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002120 while (!Stream.AtEndOfStream()) {
2121 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002122
Douglas Gregor92863e42009-04-10 23:10:45 +00002123 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002124 Error("invalid record at top-level of AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002125 return Failure;
2126 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002127
2128 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregora868bbd2009-04-21 22:25:48 +00002129
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002130 // We only know the AST subblock ID.
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002131 switch (BlockID) {
2132 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregor92863e42009-04-10 23:10:45 +00002133 if (Stream.ReadBlockInfoBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002134 Error("malformed BlockInfoBlock in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002135 return Failure;
2136 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002137 break;
Sebastian Redl539c5062010-08-18 23:57:32 +00002138 case AST_BLOCK_ID:
Sebastian Redl3e31c722010-08-18 23:56:56 +00002139 switch (ReadASTBlock(F)) {
Douglas Gregor55abb232009-04-10 20:39:37 +00002140 case Success:
2141 break;
2142
2143 case Failure:
Douglas Gregor92863e42009-04-10 23:10:45 +00002144 return Failure;
Douglas Gregor55abb232009-04-10 20:39:37 +00002145
2146 case IgnorePCH:
Douglas Gregorbfbde532009-04-10 21:16:55 +00002147 // FIXME: We could consider reading through to the end of this
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002148 // AST block, skipping subblocks, to see if there are other
2149 // AST blocks elsewhere.
Douglas Gregor0bc12932009-04-27 21:28:04 +00002150
2151 // Clear out any preallocated source location entries, so that
2152 // the source manager does not try to resolve them later.
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002153 SourceMgr.ClearPreallocatedSLocEntries();
Douglas Gregor0bc12932009-04-27 21:28:04 +00002154
2155 // Remove the stat cache.
Sebastian Redl34522812010-07-16 17:50:48 +00002156 if (F.StatCache)
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002157 FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
Douglas Gregor0bc12932009-04-27 21:28:04 +00002158
Douglas Gregor92863e42009-04-10 23:10:45 +00002159 return IgnorePCH;
Douglas Gregor55abb232009-04-10 20:39:37 +00002160 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002161 break;
2162 default:
Douglas Gregor92863e42009-04-10 23:10:45 +00002163 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002164 Error("malformed block record in AST file");
Douglas Gregor92863e42009-04-10 23:10:45 +00002165 return Failure;
2166 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002167 break;
2168 }
Mike Stump11289f42009-09-09 15:08:12 +00002169 }
2170
Sebastian Redl2abc0382010-07-16 20:41:52 +00002171 return Success;
2172}
2173
Sebastian Redl2c499f62010-08-18 23:56:43 +00002174void ASTReader::setPreprocessor(Preprocessor &pp) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002175 PP = &pp;
Sebastian Redlfa061442010-07-21 20:07:32 +00002176
2177 unsigned TotalNum = 0;
2178 for (unsigned I = 0, N = Chain.size(); I != N; ++I)
2179 TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
2180 if (TotalNum) {
Douglas Gregoraae92242010-03-19 21:51:54 +00002181 if (!PP->getPreprocessingRecord())
2182 PP->createPreprocessingRecord();
Sebastian Redlfa061442010-07-21 20:07:32 +00002183 PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
Douglas Gregoraae92242010-03-19 21:51:54 +00002184 }
2185}
2186
Sebastian Redl2c499f62010-08-18 23:56:43 +00002187void ASTReader::InitializeContext(ASTContext &Ctx) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002188 Context = &Ctx;
2189 assert(Context && "Passed null context!");
2190
2191 assert(PP && "Forgot to set Preprocessor ?");
2192 PP->getIdentifierTable().setExternalIdentifierLookup(this);
2193 PP->getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor9882a5a2010-01-04 19:18:44 +00002194 PP->setExternalSource(this);
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00002195
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002196 // Load the translation unit declaration
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00002197 GetTranslationUnitDecl();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002198
2199 // Load the special types.
2200 Context->setBuiltinVaListType(
Sebastian Redl539c5062010-08-18 23:57:32 +00002201 GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
2202 if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002203 Context->setObjCIdType(GetType(Id));
Sebastian Redl539c5062010-08-18 23:57:32 +00002204 if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002205 Context->setObjCSelType(GetType(Sel));
Sebastian Redl539c5062010-08-18 23:57:32 +00002206 if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002207 Context->setObjCProtoType(GetType(Proto));
Sebastian Redl539c5062010-08-18 23:57:32 +00002208 if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002209 Context->setObjCClassType(GetType(Class));
Steve Naroff7cae42b2009-07-10 23:34:53 +00002210
Sebastian Redl539c5062010-08-18 23:57:32 +00002211 if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002212 Context->setCFConstantStringType(GetType(String));
Mike Stump11289f42009-09-09 15:08:12 +00002213 if (unsigned FastEnum
Sebastian Redl539c5062010-08-18 23:57:32 +00002214 = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002215 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
Sebastian Redl539c5062010-08-18 23:57:32 +00002216 if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
Douglas Gregor27821ce2009-07-07 16:35:42 +00002217 QualType FileType = GetType(File);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002218 if (FileType.isNull()) {
2219 Error("FILE type is NULL");
2220 return;
2221 }
John McCall9dd450b2009-09-21 23:43:11 +00002222 if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
Douglas Gregor27821ce2009-07-07 16:35:42 +00002223 Context->setFILEDecl(Typedef->getDecl());
2224 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002225 const TagType *Tag = FileType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002226 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002227 Error("Invalid FILE type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002228 return;
2229 }
Douglas Gregor27821ce2009-07-07 16:35:42 +00002230 Context->setFILEDecl(Tag->getDecl());
2231 }
2232 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002233 if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002234 QualType Jmp_bufType = GetType(Jmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002235 if (Jmp_bufType.isNull()) {
2236 Error("jmp_bug type is NULL");
2237 return;
2238 }
John McCall9dd450b2009-09-21 23:43:11 +00002239 if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002240 Context->setjmp_bufDecl(Typedef->getDecl());
2241 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002242 const TagType *Tag = Jmp_bufType->getAs<TagType>();
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002243 if (!Tag) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002244 Error("Invalid jmp_buf type in AST file");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002245 return;
2246 }
Mike Stumpa4de80b2009-07-28 02:25:19 +00002247 Context->setjmp_bufDecl(Tag->getDecl());
2248 }
2249 }
Sebastian Redl539c5062010-08-18 23:57:32 +00002250 if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
Mike Stumpa4de80b2009-07-28 02:25:19 +00002251 QualType Sigjmp_bufType = GetType(Sigjmp_buf);
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002252 if (Sigjmp_bufType.isNull()) {
2253 Error("sigjmp_buf type is NULL");
2254 return;
2255 }
John McCall9dd450b2009-09-21 23:43:11 +00002256 if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
Mike Stumpa4de80b2009-07-28 02:25:19 +00002257 Context->setsigjmp_bufDecl(Typedef->getDecl());
2258 else {
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002259 const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002260 assert(Tag && "Invalid sigjmp_buf type in AST file");
Mike Stumpa4de80b2009-07-28 02:25:19 +00002261 Context->setsigjmp_bufDecl(Tag->getDecl());
2262 }
2263 }
Mike Stump11289f42009-09-09 15:08:12 +00002264 if (unsigned ObjCIdRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002265 = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002266 Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
Mike Stump11289f42009-09-09 15:08:12 +00002267 if (unsigned ObjCClassRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002268 = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Douglas Gregora8eed7d2009-08-21 00:27:50 +00002269 Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002270 if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Mike Stumpd0153282009-10-20 02:12:22 +00002271 Context->setBlockDescriptorType(GetType(String));
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002272 if (unsigned String
Sebastian Redl539c5062010-08-18 23:57:32 +00002273 = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Mike Stumpe1b19ba2009-10-22 00:49:09 +00002274 Context->setBlockDescriptorExtendedType(GetType(String));
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002275 if (unsigned ObjCSelRedef
Sebastian Redl539c5062010-08-18 23:57:32 +00002276 = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002277 Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
Sebastian Redl539c5062010-08-18 23:57:32 +00002278 if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
Fariborz Jahaniane804c282010-04-23 17:41:07 +00002279 Context->setNSConstantStringType(GetType(String));
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002280
Sebastian Redl539c5062010-08-18 23:57:32 +00002281 if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
Argyrios Kyrtzidise862cbc2010-07-04 21:44:19 +00002282 Context->setInt128Installed();
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002283}
2284
Douglas Gregor45fe0362009-05-12 01:31:05 +00002285/// \brief Retrieve the name of the original source file name
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002286/// directly from the AST file, without actually loading the AST
Douglas Gregor45fe0362009-05-12 01:31:05 +00002287/// file.
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002288std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
Daniel Dunbar3b951482009-12-03 09:13:06 +00002289 Diagnostic &Diags) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002290 // Open the AST file.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002291 std::string ErrStr;
2292 llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002293 Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr));
Douglas Gregor45fe0362009-05-12 01:31:05 +00002294 if (!Buffer) {
Daniel Dunbar3b951482009-12-03 09:13:06 +00002295 Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002296 return std::string();
2297 }
2298
2299 // Initialize the stream
2300 llvm::BitstreamReader StreamFile;
2301 llvm::BitstreamCursor Stream;
Mike Stump11289f42009-09-09 15:08:12 +00002302 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
Douglas Gregor45fe0362009-05-12 01:31:05 +00002303 (const unsigned char *)Buffer->getBufferEnd());
2304 Stream.init(StreamFile);
2305
2306 // Sniff for the signature.
2307 if (Stream.Read(8) != 'C' ||
2308 Stream.Read(8) != 'P' ||
2309 Stream.Read(8) != 'C' ||
2310 Stream.Read(8) != 'H') {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002311 Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002312 return std::string();
2313 }
2314
2315 RecordData Record;
2316 while (!Stream.AtEndOfStream()) {
2317 unsigned Code = Stream.ReadCode();
Mike Stump11289f42009-09-09 15:08:12 +00002318
Douglas Gregor45fe0362009-05-12 01:31:05 +00002319 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2320 unsigned BlockID = Stream.ReadSubBlockID();
Mike Stump11289f42009-09-09 15:08:12 +00002321
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002322 // We only know the AST subblock ID.
Douglas Gregor45fe0362009-05-12 01:31:05 +00002323 switch (BlockID) {
Sebastian Redl539c5062010-08-18 23:57:32 +00002324 case AST_BLOCK_ID:
2325 if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002326 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002327 return std::string();
2328 }
2329 break;
Mike Stump11289f42009-09-09 15:08:12 +00002330
Douglas Gregor45fe0362009-05-12 01:31:05 +00002331 default:
2332 if (Stream.SkipBlock()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002333 Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002334 return std::string();
2335 }
2336 break;
2337 }
2338 continue;
2339 }
2340
2341 if (Code == llvm::bitc::END_BLOCK) {
2342 if (Stream.ReadBlockEnd()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002343 Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
Douglas Gregor45fe0362009-05-12 01:31:05 +00002344 return std::string();
2345 }
2346 continue;
2347 }
2348
2349 if (Code == llvm::bitc::DEFINE_ABBREV) {
2350 Stream.ReadAbbrevRecord();
2351 continue;
2352 }
2353
2354 Record.clear();
2355 const char *BlobStart = 0;
2356 unsigned BlobLen = 0;
Mike Stump11289f42009-09-09 15:08:12 +00002357 if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
Sebastian Redl539c5062010-08-18 23:57:32 +00002358 == ORIGINAL_FILE_NAME)
Douglas Gregor45fe0362009-05-12 01:31:05 +00002359 return std::string(BlobStart, BlobLen);
Mike Stump11289f42009-09-09 15:08:12 +00002360 }
Douglas Gregor45fe0362009-05-12 01:31:05 +00002361
2362 return std::string();
2363}
2364
Douglas Gregor55abb232009-04-10 20:39:37 +00002365/// \brief Parse the record that corresponds to a LangOptions data
2366/// structure.
2367///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002368/// This routine parses the language options from the AST file and then gives
2369/// them to the AST listener if one is set.
Douglas Gregor55abb232009-04-10 20:39:37 +00002370///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002371/// \returns true if the listener deems the file unacceptable, false otherwise.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002372bool ASTReader::ParseLanguageOptions(
Douglas Gregor55abb232009-04-10 20:39:37 +00002373 const llvm::SmallVectorImpl<uint64_t> &Record) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002374 if (Listener) {
2375 LangOptions LangOpts;
Mike Stump11289f42009-09-09 15:08:12 +00002376
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002377 #define PARSE_LANGOPT(Option) \
2378 LangOpts.Option = Record[Idx]; \
2379 ++Idx
Mike Stump11289f42009-09-09 15:08:12 +00002380
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002381 unsigned Idx = 0;
2382 PARSE_LANGOPT(Trigraphs);
2383 PARSE_LANGOPT(BCPLComment);
2384 PARSE_LANGOPT(DollarIdents);
2385 PARSE_LANGOPT(AsmPreprocessor);
2386 PARSE_LANGOPT(GNUMode);
Chandler Carruthe03aa552010-04-17 20:17:31 +00002387 PARSE_LANGOPT(GNUKeywords);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002388 PARSE_LANGOPT(ImplicitInt);
2389 PARSE_LANGOPT(Digraphs);
2390 PARSE_LANGOPT(HexFloats);
2391 PARSE_LANGOPT(C99);
2392 PARSE_LANGOPT(Microsoft);
2393 PARSE_LANGOPT(CPlusPlus);
2394 PARSE_LANGOPT(CPlusPlus0x);
2395 PARSE_LANGOPT(CXXOperatorNames);
2396 PARSE_LANGOPT(ObjC1);
2397 PARSE_LANGOPT(ObjC2);
2398 PARSE_LANGOPT(ObjCNonFragileABI);
Fariborz Jahanian45878032010-02-09 19:31:38 +00002399 PARSE_LANGOPT(ObjCNonFragileABI2);
Fariborz Jahanian62c56022010-04-22 21:01:59 +00002400 PARSE_LANGOPT(NoConstantCFStrings);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002401 PARSE_LANGOPT(PascalStrings);
2402 PARSE_LANGOPT(WritableStrings);
2403 PARSE_LANGOPT(LaxVectorConversions);
Nate Begemanf2911662009-06-25 23:01:11 +00002404 PARSE_LANGOPT(AltiVec);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002405 PARSE_LANGOPT(Exceptions);
Daniel Dunbar925152c2010-02-10 18:48:44 +00002406 PARSE_LANGOPT(SjLjExceptions);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002407 PARSE_LANGOPT(NeXTRuntime);
2408 PARSE_LANGOPT(Freestanding);
2409 PARSE_LANGOPT(NoBuiltin);
2410 PARSE_LANGOPT(ThreadsafeStatics);
Douglas Gregorb3286fe2009-09-03 14:36:33 +00002411 PARSE_LANGOPT(POSIXThreads);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002412 PARSE_LANGOPT(Blocks);
2413 PARSE_LANGOPT(EmitAllDecls);
2414 PARSE_LANGOPT(MathErrno);
Chris Lattner51924e512010-06-26 21:25:03 +00002415 LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
2416 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002417 PARSE_LANGOPT(HeinousExtensions);
2418 PARSE_LANGOPT(Optimize);
2419 PARSE_LANGOPT(OptimizeSize);
2420 PARSE_LANGOPT(Static);
2421 PARSE_LANGOPT(PICLevel);
2422 PARSE_LANGOPT(GNUInline);
2423 PARSE_LANGOPT(NoInline);
2424 PARSE_LANGOPT(AccessControl);
2425 PARSE_LANGOPT(CharIsSigned);
John Thompsoned4e2952009-11-05 20:14:16 +00002426 PARSE_LANGOPT(ShortWChar);
Chris Lattner51924e512010-06-26 21:25:03 +00002427 LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
2428 LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
Daniel Dunbar143021e2009-09-21 04:16:19 +00002429 LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Chris Lattner51924e512010-06-26 21:25:03 +00002430 Record[Idx++]);
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002431 PARSE_LANGOPT(InstantiationDepth);
Nate Begemanf2911662009-06-25 23:01:11 +00002432 PARSE_LANGOPT(OpenCL);
Mike Stumpd9546382009-12-12 01:27:46 +00002433 PARSE_LANGOPT(CatchUndefined);
2434 // FIXME: Missing ElideConstructors?!
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002435 #undef PARSE_LANGOPT
Douglas Gregor55abb232009-04-10 20:39:37 +00002436
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00002437 return Listener->ReadLanguageOptions(LangOpts);
Douglas Gregor55abb232009-04-10 20:39:37 +00002438 }
Douglas Gregor55abb232009-04-10 20:39:37 +00002439
2440 return false;
2441}
2442
Sebastian Redl2c499f62010-08-18 23:56:43 +00002443void ASTReader::ReadPreprocessedEntities() {
Douglas Gregoraae92242010-03-19 21:51:54 +00002444 ReadDefinedMacros();
2445}
2446
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002447/// \brief Get the correct cursor and offset for loading a type.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002448ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002449 PerFileData *F = 0;
2450 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
2451 F = Chain[N - I - 1];
2452 if (Index < F->LocalNumTypes)
2453 break;
2454 Index -= F->LocalNumTypes;
2455 }
2456 assert(F && F->LocalNumTypes > Index && "Broken chain");
Sebastian Redlb2831db2010-07-20 22:55:31 +00002457 return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002458}
2459
2460/// \brief Read and return the type with the given index..
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002461///
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002462/// The index is the type ID, shifted and minus the number of predefs. This
2463/// routine actually reads the record corresponding to the type at the given
2464/// location. It is a helper routine for GetType, which deals with reading type
2465/// IDs.
Sebastian Redl2c499f62010-08-18 23:56:43 +00002466QualType ASTReader::ReadTypeRecord(unsigned Index) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002467 RecordLocation Loc = TypeCursorForIndex(Index);
Sebastian Redlb2831db2010-07-20 22:55:31 +00002468 llvm::BitstreamCursor &DeclsCursor = *Loc.first;
Sebastian Redl34522812010-07-16 17:50:48 +00002469
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002470 // Keep track of where we are in the stream, then jump back there
2471 // after reading this type.
Douglas Gregor12bfa382009-10-17 00:13:19 +00002472 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002473
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00002474 ReadingKindTracker ReadingKind(Read_Type, *this);
Sebastian Redleaa4ade2010-08-11 18:52:41 +00002475
Douglas Gregor1342e842009-07-06 18:54:52 +00002476 // Note that we are loading a type record.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00002477 Deserializing AType(this);
Mike Stump11289f42009-09-09 15:08:12 +00002478
Sebastian Redl837a6cb2010-07-20 22:37:49 +00002479 DeclsCursor.JumpToBit(Loc.second);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002480 RecordData Record;
Douglas Gregor12bfa382009-10-17 00:13:19 +00002481 unsigned Code = DeclsCursor.ReadCode();
Sebastian Redl539c5062010-08-18 23:57:32 +00002482 switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
2483 case TYPE_EXT_QUAL: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002484 if (Record.size() != 2) {
2485 Error("Incorrect encoding of extended qualifier type");
2486 return QualType();
2487 }
Douglas Gregor455b8f42009-04-15 22:00:08 +00002488 QualType Base = GetType(Record[0]);
John McCall8ccfcb52009-09-24 19:53:00 +00002489 Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
2490 return Context->getQualifiedType(Base, Quals);
Douglas Gregor455b8f42009-04-15 22:00:08 +00002491 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002492
Sebastian Redl539c5062010-08-18 23:57:32 +00002493 case TYPE_COMPLEX: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002494 if (Record.size() != 1) {
2495 Error("Incorrect encoding of complex type");
2496 return QualType();
2497 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002498 QualType ElemType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002499 return Context->getComplexType(ElemType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002500 }
2501
Sebastian Redl539c5062010-08-18 23:57:32 +00002502 case TYPE_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002503 if (Record.size() != 1) {
2504 Error("Incorrect encoding of pointer type");
2505 return QualType();
2506 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002507 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002508 return Context->getPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002509 }
2510
Sebastian Redl539c5062010-08-18 23:57:32 +00002511 case TYPE_BLOCK_POINTER: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002512 if (Record.size() != 1) {
2513 Error("Incorrect encoding of block pointer type");
2514 return QualType();
2515 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002516 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002517 return Context->getBlockPointerType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002518 }
2519
Sebastian Redl539c5062010-08-18 23:57:32 +00002520 case TYPE_LVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002521 if (Record.size() != 1) {
2522 Error("Incorrect encoding of lvalue reference type");
2523 return QualType();
2524 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002525 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002526 return Context->getLValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002527 }
2528
Sebastian Redl539c5062010-08-18 23:57:32 +00002529 case TYPE_RVALUE_REFERENCE: {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002530 if (Record.size() != 1) {
2531 Error("Incorrect encoding of rvalue reference type");
2532 return QualType();
2533 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002534 QualType PointeeType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002535 return Context->getRValueReferenceType(PointeeType);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002536 }
2537
Sebastian Redl539c5062010-08-18 23:57:32 +00002538 case TYPE_MEMBER_POINTER: {
Argyrios Kyrtzidisee776bc2010-07-02 11:55:15 +00002539 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002540 Error("Incorrect encoding of member pointer type");
2541 return QualType();
2542 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002543 QualType PointeeType = GetType(Record[0]);
2544 QualType ClassType = GetType(Record[1]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002545 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002546 }
2547
Sebastian Redl539c5062010-08-18 23:57:32 +00002548 case TYPE_CONSTANT_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002549 QualType ElementType = GetType(Record[0]);
2550 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2551 unsigned IndexTypeQuals = Record[2];
2552 unsigned Idx = 3;
2553 llvm::APInt Size = ReadAPInt(Record, Idx);
Douglas Gregor04318252009-07-06 15:59:29 +00002554 return Context->getConstantArrayType(ElementType, Size,
2555 ASM, IndexTypeQuals);
2556 }
2557
Sebastian Redl539c5062010-08-18 23:57:32 +00002558 case TYPE_INCOMPLETE_ARRAY: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002559 QualType ElementType = GetType(Record[0]);
2560 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2561 unsigned IndexTypeQuals = Record[2];
Chris Lattner8575daa2009-04-27 21:45:14 +00002562 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002563 }
2564
Sebastian Redl539c5062010-08-18 23:57:32 +00002565 case TYPE_VARIABLE_ARRAY: {
Douglas Gregorfeb84b02009-04-14 21:18:50 +00002566 QualType ElementType = GetType(Record[0]);
2567 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
2568 unsigned IndexTypeQuals = Record[2];
Douglas Gregor04318252009-07-06 15:59:29 +00002569 SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
2570 SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002571 return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor),
Douglas Gregor04318252009-07-06 15:59:29 +00002572 ASM, IndexTypeQuals,
2573 SourceRange(LBLoc, RBLoc));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002574 }
2575
Sebastian Redl539c5062010-08-18 23:57:32 +00002576 case TYPE_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002577 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002578 Error("incorrect encoding of vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002579 return QualType();
2580 }
2581
2582 QualType ElementType = GetType(Record[0]);
2583 unsigned NumElements = Record[1];
Chris Lattner37141f42010-06-23 06:00:24 +00002584 unsigned AltiVecSpec = Record[2];
2585 return Context->getVectorType(ElementType, NumElements,
2586 (VectorType::AltiVecSpecific)AltiVecSpec);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002587 }
2588
Sebastian Redl539c5062010-08-18 23:57:32 +00002589 case TYPE_EXT_VECTOR: {
Chris Lattner37141f42010-06-23 06:00:24 +00002590 if (Record.size() != 3) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002591 Error("incorrect encoding of extended vector type in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002592 return QualType();
2593 }
2594
2595 QualType ElementType = GetType(Record[0]);
2596 unsigned NumElements = Record[1];
Chris Lattner8575daa2009-04-27 21:45:14 +00002597 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002598 }
2599
Sebastian Redl539c5062010-08-18 23:57:32 +00002600 case TYPE_FUNCTION_NO_PROTO: {
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002601 if (Record.size() != 4) {
Douglas Gregor6f00bf82009-04-28 21:53:25 +00002602 Error("incorrect encoding of no-proto function type");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002603 return QualType();
2604 }
2605 QualType ResultType = GetType(Record[0]);
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002606 FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002607 return Context->getFunctionNoProtoType(ResultType, Info);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002608 }
2609
Sebastian Redl539c5062010-08-18 23:57:32 +00002610 case TYPE_FUNCTION_PROTO: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002611 QualType ResultType = GetType(Record[0]);
Douglas Gregordc728752009-12-22 18:11:50 +00002612 bool NoReturn = Record[1];
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002613 unsigned RegParm = Record[2];
2614 CallingConv CallConv = (CallingConv)Record[3];
2615 unsigned Idx = 4;
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002616 unsigned NumParams = Record[Idx++];
2617 llvm::SmallVector<QualType, 16> ParamTypes;
2618 for (unsigned I = 0; I != NumParams; ++I)
2619 ParamTypes.push_back(GetType(Record[Idx++]));
2620 bool isVariadic = Record[Idx++];
2621 unsigned Quals = Record[Idx++];
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002622 bool hasExceptionSpec = Record[Idx++];
2623 bool hasAnyExceptionSpec = Record[Idx++];
2624 unsigned NumExceptions = Record[Idx++];
2625 llvm::SmallVector<QualType, 2> Exceptions;
2626 for (unsigned I = 0; I != NumExceptions; ++I)
2627 Exceptions.push_back(GetType(Record[Idx++]));
Jay Foad7d0479f2009-05-21 09:52:38 +00002628 return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
Sebastian Redl5068f77ac2009-05-27 22:11:52 +00002629 isVariadic, Quals, hasExceptionSpec,
2630 hasAnyExceptionSpec, NumExceptions,
Rafael Espindolac50c27c2010-03-30 20:24:48 +00002631 Exceptions.data(),
Rafael Espindola49b85ab2010-03-30 22:15:11 +00002632 FunctionType::ExtInfo(NoReturn, RegParm,
2633 CallConv));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002634 }
2635
Sebastian Redl539c5062010-08-18 23:57:32 +00002636 case TYPE_UNRESOLVED_USING:
John McCallb96ec562009-12-04 22:46:56 +00002637 return Context->getTypeDeclType(
2638 cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
2639
Sebastian Redl539c5062010-08-18 23:57:32 +00002640 case TYPE_TYPEDEF: {
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002641 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002642 Error("incorrect encoding of typedef type");
2643 return QualType();
2644 }
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002645 TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
2646 QualType Canonical = GetType(Record[1]);
2647 return Context->getTypedefType(Decl, Canonical);
2648 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002649
Sebastian Redl539c5062010-08-18 23:57:32 +00002650 case TYPE_TYPEOF_EXPR:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002651 return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002652
Sebastian Redl539c5062010-08-18 23:57:32 +00002653 case TYPE_TYPEOF: {
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002654 if (Record.size() != 1) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002655 Error("incorrect encoding of typeof(type) in AST file");
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002656 return QualType();
2657 }
2658 QualType UnderlyingType = GetType(Record[0]);
Chris Lattner8575daa2009-04-27 21:45:14 +00002659 return Context->getTypeOfType(UnderlyingType);
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002660 }
Mike Stump11289f42009-09-09 15:08:12 +00002661
Sebastian Redl539c5062010-08-18 23:57:32 +00002662 case TYPE_DECLTYPE:
Sebastian Redlc67764e2010-07-22 22:43:28 +00002663 return Context->getDecltypeType(ReadExpr(DeclsCursor));
Anders Carlsson81df7b82009-06-24 19:06:50 +00002664
Sebastian Redl539c5062010-08-18 23:57:32 +00002665 case TYPE_RECORD: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002666 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002667 Error("incorrect encoding of record type");
2668 return QualType();
2669 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002670 bool IsDependent = Record[0];
2671 QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
2672 T->Dependent = IsDependent;
2673 return T;
2674 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002675
Sebastian Redl539c5062010-08-18 23:57:32 +00002676 case TYPE_ENUM: {
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002677 if (Record.size() != 2) {
Ted Kremenek1ff615c2010-03-18 00:56:54 +00002678 Error("incorrect encoding of enum type");
2679 return QualType();
2680 }
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002681 bool IsDependent = Record[0];
2682 QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
2683 T->Dependent = IsDependent;
2684 return T;
2685 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00002686
Sebastian Redl539c5062010-08-18 23:57:32 +00002687 case TYPE_ELABORATED: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002688 unsigned Idx = 0;
2689 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2690 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2691 QualType NamedType = GetType(Record[Idx++]);
2692 return Context->getElaboratedType(Keyword, NNS, NamedType);
John McCallfcc33b02009-09-05 00:15:47 +00002693 }
2694
Sebastian Redl539c5062010-08-18 23:57:32 +00002695 case TYPE_OBJC_INTERFACE: {
Chris Lattner587cbe12009-04-22 06:45:28 +00002696 unsigned Idx = 0;
2697 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002698 return Context->getObjCInterfaceType(ItfD);
2699 }
2700
Sebastian Redl539c5062010-08-18 23:57:32 +00002701 case TYPE_OBJC_OBJECT: {
John McCall8b07ec22010-05-15 11:32:37 +00002702 unsigned Idx = 0;
2703 QualType Base = GetType(Record[Idx++]);
Chris Lattner587cbe12009-04-22 06:45:28 +00002704 unsigned NumProtos = Record[Idx++];
2705 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
2706 for (unsigned I = 0; I != NumProtos; ++I)
2707 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
John McCall8b07ec22010-05-15 11:32:37 +00002708 return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
Chris Lattner587cbe12009-04-22 06:45:28 +00002709 }
Douglas Gregor85c0fcd2009-04-13 20:46:52 +00002710
Sebastian Redl539c5062010-08-18 23:57:32 +00002711 case TYPE_OBJC_OBJECT_POINTER: {
Chris Lattner6e054af2009-04-22 06:40:03 +00002712 unsigned Idx = 0;
John McCall8b07ec22010-05-15 11:32:37 +00002713 QualType Pointee = GetType(Record[Idx++]);
2714 return Context->getObjCObjectPointerType(Pointee);
Chris Lattner6e054af2009-04-22 06:40:03 +00002715 }
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002716
Sebastian Redl539c5062010-08-18 23:57:32 +00002717 case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
John McCallcebee162009-10-18 09:09:24 +00002718 unsigned Idx = 0;
2719 QualType Parm = GetType(Record[Idx++]);
2720 QualType Replacement = GetType(Record[Idx++]);
2721 return
2722 Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2723 Replacement);
2724 }
John McCalle78aac42010-03-10 03:28:59 +00002725
Sebastian Redl539c5062010-08-18 23:57:32 +00002726 case TYPE_INJECTED_CLASS_NAME: {
John McCalle78aac42010-03-10 03:28:59 +00002727 CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
2728 QualType TST = GetType(Record[1]); // probably derivable
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002729 // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
Sebastian Redld44cd6a2010-08-18 23:57:06 +00002730 // for AST reading, too much interdependencies.
Argyrios Kyrtzidisdab33c52010-07-02 11:55:20 +00002731 return
2732 QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
John McCalle78aac42010-03-10 03:28:59 +00002733 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002734
Sebastian Redl539c5062010-08-18 23:57:32 +00002735 case TYPE_TEMPLATE_TYPE_PARM: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002736 unsigned Idx = 0;
2737 unsigned Depth = Record[Idx++];
2738 unsigned Index = Record[Idx++];
2739 bool Pack = Record[Idx++];
2740 IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
2741 return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
2742 }
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002743
Sebastian Redl539c5062010-08-18 23:57:32 +00002744 case TYPE_DEPENDENT_NAME: {
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002745 unsigned Idx = 0;
2746 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2747 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2748 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
Argyrios Kyrtzidise9290952010-07-02 11:55:24 +00002749 QualType Canon = GetType(Record[Idx++]);
2750 return Context->getDependentNameType(Keyword, NNS, Name, Canon);
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +00002751 }
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002752
Sebastian Redl539c5062010-08-18 23:57:32 +00002753 case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002754 unsigned Idx = 0;
2755 ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
2756 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
2757 const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
2758 unsigned NumArgs = Record[Idx++];
2759 llvm::SmallVector<TemplateArgument, 8> Args;
2760 Args.reserve(NumArgs);
2761 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002762 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidisf0f7a792010-06-25 16:24:58 +00002763 return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
2764 Args.size(), Args.data());
2765 }
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002766
Sebastian Redl539c5062010-08-18 23:57:32 +00002767 case TYPE_DEPENDENT_SIZED_ARRAY: {
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002768 unsigned Idx = 0;
2769
2770 // ArrayType
2771 QualType ElementType = GetType(Record[Idx++]);
2772 ArrayType::ArraySizeModifier ASM
2773 = (ArrayType::ArraySizeModifier)Record[Idx++];
2774 unsigned IndexTypeQuals = Record[Idx++];
2775
2776 // DependentSizedArrayType
Sebastian Redlc67764e2010-07-22 22:43:28 +00002777 Expr *NumElts = ReadExpr(DeclsCursor);
Argyrios Kyrtzidis4a57bd02010-06-30 08:49:25 +00002778 SourceRange Brackets = ReadSourceRange(Record, Idx);
2779
2780 return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
2781 IndexTypeQuals, Brackets);
2782 }
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +00002783
Sebastian Redl539c5062010-08-18 23:57:32 +00002784 case TYPE_TEMPLATE_SPECIALIZATION: {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002785 unsigned Idx = 0;
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002786 bool IsDependent = Record[Idx++];
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002787 TemplateName Name = ReadTemplateName(Record, Idx);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002788 llvm::SmallVector<TemplateArgument, 8> Args;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002789 ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00002790 QualType Canon = GetType(Record[Idx++]);
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002791 QualType T;
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002792 if (Canon.isNull())
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002793 T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
2794 Args.size());
Argyrios Kyrtzidis45a83f92010-07-02 11:55:11 +00002795 else
Argyrios Kyrtzidisa4ed1812010-07-08 13:09:53 +00002796 T = Context->getTemplateSpecializationType(Name, Args.data(),
2797 Args.size(), Canon);
2798 T->Dependent = IsDependent;
2799 return T;
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00002800 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002801 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00002802 // Suppress a GCC warning
2803 return QualType();
2804}
2805
John McCall8f115c62009-10-16 21:56:05 +00002806namespace {
2807
2808class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
Sebastian Redl2c499f62010-08-18 23:56:43 +00002809 ASTReader &Reader;
Sebastian Redlc67764e2010-07-22 22:43:28 +00002810 llvm::BitstreamCursor &DeclsCursor;
Sebastian Redl2c499f62010-08-18 23:56:43 +00002811 const ASTReader::RecordData &Record;
John McCall8f115c62009-10-16 21:56:05 +00002812 unsigned &Idx;
2813
2814public:
Sebastian Redl2c499f62010-08-18 23:56:43 +00002815 TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
2816 const ASTReader::RecordData &Record, unsigned &Idx)
Sebastian Redlc67764e2010-07-22 22:43:28 +00002817 : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
John McCall8f115c62009-10-16 21:56:05 +00002818
John McCall17001972009-10-18 01:05:36 +00002819 // We want compile-time assurance that we've enumerated all of
2820 // these, so unfortunately we have to declare them first, then
2821 // define them out-of-line.
2822#define ABSTRACT_TYPELOC(CLASS, PARENT)
John McCall8f115c62009-10-16 21:56:05 +00002823#define TYPELOC(CLASS, PARENT) \
John McCall17001972009-10-18 01:05:36 +00002824 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
John McCall8f115c62009-10-16 21:56:05 +00002825#include "clang/AST/TypeLocNodes.def"
2826
John McCall17001972009-10-18 01:05:36 +00002827 void VisitFunctionTypeLoc(FunctionTypeLoc);
2828 void VisitArrayTypeLoc(ArrayTypeLoc);
John McCall8f115c62009-10-16 21:56:05 +00002829};
2830
2831}
2832
John McCall17001972009-10-18 01:05:36 +00002833void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
John McCall8f115c62009-10-16 21:56:05 +00002834 // nothing to do
2835}
John McCall17001972009-10-18 01:05:36 +00002836void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Douglas Gregorc9b7a592010-01-18 18:04:31 +00002837 TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2838 if (TL.needsExtraLocalData()) {
2839 TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2840 TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2841 TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2842 TL.setModeAttr(Record[Idx++]);
2843 }
John McCall8f115c62009-10-16 21:56:05 +00002844}
John McCall17001972009-10-18 01:05:36 +00002845void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2846 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002847}
John McCall17001972009-10-18 01:05:36 +00002848void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2849 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002850}
John McCall17001972009-10-18 01:05:36 +00002851void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2852 TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002853}
John McCall17001972009-10-18 01:05:36 +00002854void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2855 TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002856}
John McCall17001972009-10-18 01:05:36 +00002857void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2858 TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002859}
John McCall17001972009-10-18 01:05:36 +00002860void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2861 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002862}
John McCall17001972009-10-18 01:05:36 +00002863void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2864 TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2865 TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002866 if (Record[Idx++])
Sebastian Redlc67764e2010-07-22 22:43:28 +00002867 TL.setSizeExpr(Reader.ReadExpr(DeclsCursor));
Douglas Gregor12bfa382009-10-17 00:13:19 +00002868 else
John McCall17001972009-10-18 01:05:36 +00002869 TL.setSizeExpr(0);
2870}
2871void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2872 VisitArrayTypeLoc(TL);
2873}
2874void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2875 VisitArrayTypeLoc(TL);
2876}
2877void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2878 VisitArrayTypeLoc(TL);
2879}
2880void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2881 DependentSizedArrayTypeLoc TL) {
2882 VisitArrayTypeLoc(TL);
2883}
2884void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2885 DependentSizedExtVectorTypeLoc TL) {
2886 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2887}
2888void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2889 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2890}
2891void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2892 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2893}
2894void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2895 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2896 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2897 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
John McCalle6347002009-10-23 01:28:53 +00002898 TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
John McCall17001972009-10-18 01:05:36 +00002899 }
2900}
2901void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2902 VisitFunctionTypeLoc(TL);
2903}
2904void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2905 VisitFunctionTypeLoc(TL);
2906}
John McCallb96ec562009-12-04 22:46:56 +00002907void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2908 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2909}
John McCall17001972009-10-18 01:05:36 +00002910void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2911 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2912}
2913void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002914 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2915 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2916 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall17001972009-10-18 01:05:36 +00002917}
2918void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
John McCalle8595032010-01-13 20:03:27 +00002919 TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2920 TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2921 TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Sebastian Redlc67764e2010-07-22 22:43:28 +00002922 TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002923}
2924void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2925 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2926}
2927void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2928 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2929}
2930void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2931 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2932}
John McCall17001972009-10-18 01:05:36 +00002933void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2934 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2935}
John McCallcebee162009-10-18 09:09:24 +00002936void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2937 SubstTemplateTypeParmTypeLoc TL) {
2938 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2939}
John McCall17001972009-10-18 01:05:36 +00002940void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2941 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002942 TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2943 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2944 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2945 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2946 TL.setArgLocInfo(i,
2947 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002948 DeclsCursor, Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002949}
Abramo Bagnara6150c882010-05-11 21:36:43 +00002950void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002951 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2952 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002953}
John McCalle78aac42010-03-10 03:28:59 +00002954void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
2955 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2956}
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +00002957void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Abramo Bagnarad7548482010-05-19 21:37:53 +00002958 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2959 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
John McCall17001972009-10-18 01:05:36 +00002960 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2961}
John McCallc392f372010-06-11 00:33:02 +00002962void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
2963 DependentTemplateSpecializationTypeLoc TL) {
2964 TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2965 TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
2966 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2967 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2968 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2969 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
2970 TL.setArgLocInfo(I,
2971 Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00002972 DeclsCursor, Record, Idx));
John McCallc392f372010-06-11 00:33:02 +00002973}
John McCall17001972009-10-18 01:05:36 +00002974void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2975 TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8b07ec22010-05-15 11:32:37 +00002976}
2977void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
2978 TL.setHasBaseTypeAsWritten(Record[Idx++]);
John McCall17001972009-10-18 01:05:36 +00002979 TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2980 TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2981 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2982 TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCall8f115c62009-10-16 21:56:05 +00002983}
John McCallfc93cf92009-10-22 22:37:11 +00002984void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2985 TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
John McCallfc93cf92009-10-22 22:37:11 +00002986}
John McCall8f115c62009-10-16 21:56:05 +00002987
Sebastian Redl2c499f62010-08-18 23:56:43 +00002988TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00002989 const RecordData &Record,
John McCall8f115c62009-10-16 21:56:05 +00002990 unsigned &Idx) {
2991 QualType InfoTy = GetType(Record[Idx++]);
2992 if (InfoTy.isNull())
2993 return 0;
2994
John McCallbcd03502009-12-07 02:54:59 +00002995 TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
Sebastian Redlc67764e2010-07-22 22:43:28 +00002996 TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
John McCallbcd03502009-12-07 02:54:59 +00002997 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
John McCall8f115c62009-10-16 21:56:05 +00002998 TLR.Visit(TL);
John McCallbcd03502009-12-07 02:54:59 +00002999 return TInfo;
John McCall8f115c62009-10-16 21:56:05 +00003000}
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003001
Sebastian Redl539c5062010-08-18 23:57:32 +00003002QualType ASTReader::GetType(TypeID ID) {
John McCall8ccfcb52009-09-24 19:53:00 +00003003 unsigned FastQuals = ID & Qualifiers::FastMask;
3004 unsigned Index = ID >> Qualifiers::FastWidth;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003005
Sebastian Redl539c5062010-08-18 23:57:32 +00003006 if (Index < NUM_PREDEF_TYPE_IDS) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003007 QualType T;
Sebastian Redl539c5062010-08-18 23:57:32 +00003008 switch ((PredefinedTypeIDs)Index) {
3009 case PREDEF_TYPE_NULL_ID: return QualType();
3010 case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
3011 case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003012
Sebastian Redl539c5062010-08-18 23:57:32 +00003013 case PREDEF_TYPE_CHAR_U_ID:
3014 case PREDEF_TYPE_CHAR_S_ID:
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003015 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattner8575daa2009-04-27 21:45:14 +00003016 T = Context->CharTy;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003017 break;
3018
Sebastian Redl539c5062010-08-18 23:57:32 +00003019 case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
3020 case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
3021 case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
3022 case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
3023 case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
3024 case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
3025 case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
3026 case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
3027 case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
3028 case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
3029 case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
3030 case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
3031 case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
3032 case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
3033 case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
3034 case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
3035 case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
3036 case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
3037 case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
3038 case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
3039 case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
3040 case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
3041 case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
3042 case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003043 }
3044
3045 assert(!T.isNull() && "Unknown predefined type");
John McCall8ccfcb52009-09-24 19:53:00 +00003046 return T.withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003047 }
3048
Sebastian Redl539c5062010-08-18 23:57:32 +00003049 Index -= NUM_PREDEF_TYPE_IDS;
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003050 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Sebastian Redl409183f2010-07-14 20:26:45 +00003051 if (TypesLoaded[Index].isNull()) {
Sebastian Redl837a6cb2010-07-20 22:37:49 +00003052 TypesLoaded[Index] = ReadTypeRecord(Index);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003053 TypesLoaded[Index]->setFromAST();
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003054 TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003055 if (DeserializationListener)
Argyrios Kyrtzidisbb5c7eae2010-08-20 16:03:59 +00003056 DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003057 TypesLoaded[Index]);
Sebastian Redl409183f2010-07-14 20:26:45 +00003058 }
Mike Stump11289f42009-09-09 15:08:12 +00003059
John McCall8ccfcb52009-09-24 19:53:00 +00003060 return TypesLoaded[Index].withFastQualifiers(FastQuals);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003061}
3062
Argyrios Kyrtzidis07347322010-08-20 16:04:27 +00003063TypeID ASTReader::GetTypeID(QualType T) const {
3064 return MakeTypeID(T,
3065 std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
3066}
3067
3068TypeIdx ASTReader::GetTypeIdx(QualType T) const {
3069 if (T.isNull())
3070 return TypeIdx();
3071 assert(!T.getLocalFastQualifiers());
3072
3073 TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3074 // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
3075 // comparing keys of ASTDeclContextNameLookupTable.
3076 // If the type didn't come from the AST file use a specially marked index
3077 // so that any hash/key comparison fail since no such index is stored
3078 // in a AST file.
3079 if (I == TypeIdxs.end())
3080 return TypeIdx(-1);
3081 return I->second;
3082}
3083
John McCall0ad16662009-10-29 08:12:44 +00003084TemplateArgumentLocInfo
Sebastian Redl2c499f62010-08-18 23:56:43 +00003085ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003086 llvm::BitstreamCursor &DeclsCursor,
John McCall0ad16662009-10-29 08:12:44 +00003087 const RecordData &Record,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003088 unsigned &Index) {
John McCall0ad16662009-10-29 08:12:44 +00003089 switch (Kind) {
3090 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003091 return ReadExpr(DeclsCursor);
John McCall0ad16662009-10-29 08:12:44 +00003092 case TemplateArgument::Type:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003093 return GetTypeSourceInfo(DeclsCursor, Record, Index);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003094 case TemplateArgument::Template: {
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003095 SourceRange QualifierRange = ReadSourceRange(Record, Index);
3096 SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
3097 return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
Douglas Gregor9167f8b2009-11-11 01:00:40 +00003098 }
John McCall0ad16662009-10-29 08:12:44 +00003099 case TemplateArgument::Null:
3100 case TemplateArgument::Integral:
3101 case TemplateArgument::Declaration:
3102 case TemplateArgument::Pack:
3103 return TemplateArgumentLocInfo();
3104 }
Jeffrey Yasskin1615d452009-12-12 05:05:38 +00003105 llvm_unreachable("unexpected template argument loc");
John McCall0ad16662009-10-29 08:12:44 +00003106 return TemplateArgumentLocInfo();
3107}
3108
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003109TemplateArgumentLoc
Sebastian Redl2c499f62010-08-18 23:56:43 +00003110ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003111 const RecordData &Record, unsigned &Index) {
3112 TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003113
3114 if (Arg.getKind() == TemplateArgument::Expression) {
3115 if (Record[Index++]) // bool InfoHasSameExpr.
3116 return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
3117 }
3118 return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Sebastian Redlc67764e2010-07-22 22:43:28 +00003119 DeclsCursor,
Argyrios Kyrtzidisd0795b22010-06-28 22:28:35 +00003120 Record, Index));
Argyrios Kyrtzidisae85e242010-06-22 09:54:59 +00003121}
3122
Sebastian Redl2c499f62010-08-18 23:56:43 +00003123Decl *ASTReader::GetExternalDecl(uint32_t ID) {
John McCall75b960e2010-06-01 09:23:16 +00003124 return GetDecl(ID);
3125}
3126
Sebastian Redl2c499f62010-08-18 23:56:43 +00003127TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003128 if (!DeclsLoaded[0]) {
Sebastian Redld7dce0a2010-08-24 00:50:04 +00003129 ReadDeclRecord(0, 1);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003130 if (DeserializationListener)
Sebastian Redl1ea025b2010-07-16 16:36:56 +00003131 DeserializationListener->DeclRead(1, DeclsLoaded[0]);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003132 }
Argyrios Kyrtzidis7e8996c2010-07-08 17:13:02 +00003133
3134 return cast<TranslationUnitDecl>(DeclsLoaded[0]);
3135}
3136
Sebastian Redl539c5062010-08-18 23:57:32 +00003137Decl *ASTReader::GetDecl(DeclID ID) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003138 if (ID == 0)
3139 return 0;
3140
Douglas Gregor745ed142009-04-25 18:35:21 +00003141 if (ID > DeclsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003142 Error("declaration ID out-of-range for AST file");
Douglas Gregor745ed142009-04-25 18:35:21 +00003143 return 0;
3144 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003145
Douglas Gregor745ed142009-04-25 18:35:21 +00003146 unsigned Index = ID - 1;
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003147 if (!DeclsLoaded[Index]) {
Argyrios Kyrtzidis839bbac2010-08-03 17:30:10 +00003148 ReadDeclRecord(Index, ID);
Sebastian Redl85b2a6a2010-07-14 23:45:08 +00003149 if (DeserializationListener)
3150 DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
3151 }
Douglas Gregor745ed142009-04-25 18:35:21 +00003152
3153 return DeclsLoaded[Index];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003154}
3155
Chris Lattner9c28af02009-04-27 05:46:25 +00003156/// \brief Resolve the offset of a statement into a statement.
3157///
3158/// This operation will read a new statement from the external
3159/// source each time it is called, and is meant to be used via a
3160/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Sebastian Redl2c499f62010-08-18 23:56:43 +00003161Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
Sebastian Redl5c415f32010-07-22 17:01:13 +00003162 // Offset here is a global offset across the entire chain.
3163 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3164 PerFileData &F = *Chain[N - I - 1];
3165 if (Offset < F.SizeInBits) {
3166 // Since we know that this statement is part of a decl, make sure to use
3167 // the decl cursor to read it.
3168 F.DeclsCursor.JumpToBit(Offset);
3169 return ReadStmtFromStream(F.DeclsCursor);
3170 }
3171 Offset -= F.SizeInBits;
3172 }
3173 llvm_unreachable("Broken chain");
Douglas Gregor3c3aa612009-04-18 00:07:54 +00003174}
3175
Sebastian Redl2c499f62010-08-18 23:56:43 +00003176bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003177 llvm::SmallVectorImpl<Decl*> &Decls) {
Mike Stump11289f42009-09-09 15:08:12 +00003178 assert(DC->hasExternalLexicalStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003179 "DeclContext has no lexical decls in storage");
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003180
Sebastian Redl5c415f32010-07-22 17:01:13 +00003181 // There might be lexical decls in multiple parts of the chain, for the TU
3182 // at least.
3183 DeclContextInfos &Infos = DeclContextOffsets[DC];
3184 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3185 I != E; ++I) {
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003186 // IDs can be 0 if this context doesn't contain declarations.
3187 if (!I->LexicalDecls)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003188 continue;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003189
3190 // Load all of the declaration IDs
Sebastian Redl539c5062010-08-18 23:57:32 +00003191 for (const DeclID *ID = I->LexicalDecls,
Sebastian Redl66c5eef2010-07-27 00:17:23 +00003192 *IDE = ID + I->NumLexicalDecls;
3193 ID != IDE; ++ID)
3194 Decls.push_back(GetDecl(*ID));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003195 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003196
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003197 ++NumLexicalDeclContextsRead;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003198 return false;
3199}
3200
John McCall75b960e2010-06-01 09:23:16 +00003201DeclContext::lookup_result
Sebastian Redl2c499f62010-08-18 23:56:43 +00003202ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
John McCall75b960e2010-06-01 09:23:16 +00003203 DeclarationName Name) {
Mike Stump11289f42009-09-09 15:08:12 +00003204 assert(DC->hasExternalVisibleStorage() &&
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003205 "DeclContext has no visible decls in storage");
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003206 if (!Name)
3207 return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
3208 DeclContext::lookup_iterator(0));
Ted Kremenek1ff615c2010-03-18 00:56:54 +00003209
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003210 llvm::SmallVector<NamedDecl *, 64> Decls;
Sebastian Redl471ac2f2010-08-24 00:49:55 +00003211 // There might be visible decls in multiple parts of the chain, for the TU
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003212 // and namespaces. For any given name, the last available results replace
3213 // all earlier ones. For this reason, we walk in reverse.
Sebastian Redl5c415f32010-07-22 17:01:13 +00003214 DeclContextInfos &Infos = DeclContextOffsets[DC];
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003215 for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
Sebastian Redl5c415f32010-07-22 17:01:13 +00003216 I != E; ++I) {
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003217 if (!I->NameLookupTableData)
Sebastian Redl5c415f32010-07-22 17:01:13 +00003218 continue;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003219
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003220 ASTDeclContextNameLookupTable *LookupTable =
3221 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3222 ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
3223 if (Pos == LookupTable->end())
Sebastian Redl5c415f32010-07-22 17:01:13 +00003224 continue;
3225
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003226 ASTDeclContextNameLookupTrait::data_type Data = *Pos;
3227 for (; Data.first != Data.second; ++Data.first)
3228 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
Sebastian Redl9617e7e2010-08-24 00:50:16 +00003229 break;
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003230 }
3231
Douglas Gregora57c3ab2009-04-22 22:34:57 +00003232 ++NumVisibleDeclContextsRead;
John McCall75b960e2010-06-01 09:23:16 +00003233
Argyrios Kyrtzidisba88bfa2010-08-20 16:04:35 +00003234 SetExternalVisibleDeclsForName(DC, Name, Decls);
John McCall75b960e2010-06-01 09:23:16 +00003235 return const_cast<DeclContext*>(DC)->lookup(Name);
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003236}
3237
Argyrios Kyrtzidisd32ee892010-08-20 23:35:55 +00003238void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
3239 assert(DC->hasExternalVisibleStorage() &&
3240 "DeclContext has no visible decls in storage");
3241
3242 llvm::SmallVector<NamedDecl *, 64> Decls;
3243 // There might be visible decls in multiple parts of the chain, for the TU
3244 // and namespaces.
3245 DeclContextInfos &Infos = DeclContextOffsets[DC];
3246 for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
3247 I != E; ++I) {
3248 if (!I->NameLookupTableData)
3249 continue;
3250
3251 ASTDeclContextNameLookupTable *LookupTable =
3252 (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
3253 for (ASTDeclContextNameLookupTable::item_iterator
3254 ItemI = LookupTable->item_begin(),
3255 ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
3256 ASTDeclContextNameLookupTable::item_iterator::value_type Val
3257 = *ItemI;
3258 ASTDeclContextNameLookupTrait::data_type Data = Val.second;
3259 Decls.clear();
3260 for (; Data.first != Data.second; ++Data.first)
3261 Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
3262 MaterializeVisibleDeclsForName(DC, Val.first, Decls);
3263 }
3264 }
3265}
3266
Sebastian Redl2c499f62010-08-18 23:56:43 +00003267void ASTReader::PassInterestingDeclsToConsumer() {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003268 assert(Consumer);
3269 while (!InterestingDecls.empty()) {
3270 DeclGroupRef DG(InterestingDecls.front());
3271 InterestingDecls.pop_front();
Sebastian Redleaa4ade2010-08-11 18:52:41 +00003272 Consumer->HandleInterestingDecl(DG);
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003273 }
3274}
3275
Sebastian Redl2c499f62010-08-18 23:56:43 +00003276void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregorb985eeb2009-04-22 19:09:20 +00003277 this->Consumer = Consumer;
3278
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003279 if (!Consumer)
3280 return;
3281
3282 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003283 // Force deserialization of this decl, which will cause it to be queued for
3284 // passing to the consumer.
Daniel Dunbar865c2a72009-09-17 03:06:44 +00003285 GetDecl(ExternalDefinitions[I]);
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003286 }
Douglas Gregorf005eac2009-04-25 00:41:30 +00003287
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00003288 PassInterestingDeclsToConsumer();
Douglas Gregor1a0d0b92009-04-14 00:24:19 +00003289}
3290
Sebastian Redl2c499f62010-08-18 23:56:43 +00003291void ASTReader::PrintStats() {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003292 std::fprintf(stderr, "*** AST File Statistics:\n");
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003293
Mike Stump11289f42009-09-09 15:08:12 +00003294 unsigned NumTypesLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003295 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
John McCall8ccfcb52009-09-24 19:53:00 +00003296 QualType());
Douglas Gregor0e149972009-04-25 19:10:14 +00003297 unsigned NumDeclsLoaded
3298 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
3299 (Decl *)0);
3300 unsigned NumIdentifiersLoaded
3301 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
3302 IdentifiersLoaded.end(),
3303 (IdentifierInfo *)0);
Mike Stump11289f42009-09-09 15:08:12 +00003304 unsigned NumSelectorsLoaded
Douglas Gregor0e149972009-04-25 19:10:14 +00003305 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
3306 SelectorsLoaded.end(),
3307 Selector());
Douglas Gregorc3b1dd12009-04-13 20:50:16 +00003308
Douglas Gregorc5046832009-04-27 18:38:38 +00003309 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
3310 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor258ae542009-04-27 06:38:32 +00003311 if (TotalNumSLocEntries)
3312 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
3313 NumSLocEntriesRead, TotalNumSLocEntries,
3314 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor745ed142009-04-25 18:35:21 +00003315 if (!TypesLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003316 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003317 NumTypesLoaded, (unsigned)TypesLoaded.size(),
3318 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
3319 if (!DeclsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003320 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor745ed142009-04-25 18:35:21 +00003321 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
3322 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor0e149972009-04-25 19:10:14 +00003323 if (!IdentifiersLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003324 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor0e149972009-04-25 19:10:14 +00003325 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
3326 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Sebastian Redlada023c2010-08-04 20:40:17 +00003327 if (!SelectorsLoaded.empty())
Douglas Gregor95c13f52009-04-25 17:48:32 +00003328 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
Sebastian Redlada023c2010-08-04 20:40:17 +00003329 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
3330 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
Douglas Gregor95c13f52009-04-25 17:48:32 +00003331 if (TotalNumStatements)
3332 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
3333 NumStatementsRead, TotalNumStatements,
3334 ((float)NumStatementsRead/TotalNumStatements * 100));
3335 if (TotalNumMacros)
3336 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
3337 NumMacrosRead, TotalNumMacros,
3338 ((float)NumMacrosRead/TotalNumMacros * 100));
3339 if (TotalLexicalDeclContexts)
3340 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
3341 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
3342 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
3343 * 100));
3344 if (TotalVisibleDeclContexts)
3345 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
3346 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
3347 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
3348 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003349 if (TotalNumMethodPoolEntries) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003350 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003351 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
3352 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
Douglas Gregor95c13f52009-04-25 17:48:32 +00003353 * 100));
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003354 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
Douglas Gregor95c13f52009-04-25 17:48:32 +00003355 }
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003356 std::fprintf(stderr, "\n");
3357}
3358
Sebastian Redl2c499f62010-08-18 23:56:43 +00003359void ASTReader::InitializeSema(Sema &S) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003360 SemaObj = &S;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003361 S.ExternalSource = this;
3362
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003363 // Makes sure any declarations that were deserialized "too early"
3364 // still get added to the identifier's declaration chains.
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003365 if (SemaObj->TUScope) {
3366 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
John McCall48871652010-08-21 09:40:31 +00003367 SemaObj->TUScope->AddDecl(PreloadedDecls[I]);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003368 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
3369 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003370 }
Douglas Gregor7cd60f72009-04-22 21:15:06 +00003371 PreloadedDecls.clear();
Douglas Gregord4df8652009-04-22 22:02:47 +00003372
3373 // If there were any tentative definitions, deserialize them and add
Sebastian Redl35351a92010-01-31 22:27:38 +00003374 // them to Sema's list of tentative definitions.
Douglas Gregord4df8652009-04-22 22:02:47 +00003375 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
3376 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
Sebastian Redl35351a92010-01-31 22:27:38 +00003377 SemaObj->TentativeDefinitions.push_back(Var);
Douglas Gregord4df8652009-04-22 22:02:47 +00003378 }
Kovarththanan Rajaratnam39f2fbd12010-03-07 19:10:13 +00003379
Argyrios Kyrtzidis35672e72010-08-13 18:42:17 +00003380 // If there were any unused file scoped decls, deserialize them and add to
3381 // Sema's list of unused file scoped decls.
3382 for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
3383 DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
3384 SemaObj->UnusedFileScopedDecls.push_back(D);
Tanya Lattner90073802010-02-12 00:07:30 +00003385 }
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003386
Argyrios Kyrtzidisee1afa32010-08-05 09:48:08 +00003387 // If there were any weak undeclared identifiers, deserialize them and add to
3388 // Sema's list of weak undeclared identifiers.
3389 if (!WeakUndeclaredIdentifiers.empty()) {
3390 unsigned Idx = 0;
3391 for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
3392 IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3393 IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
3394 SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
3395 bool Used = WeakUndeclaredIdentifiers[Idx++];
3396 Sema::WeakInfo WI(AliasId, Loc);
3397 WI.setUsed(Used);
3398 SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
3399 }
3400 }
3401
Douglas Gregoracfc76c2009-04-22 22:18:58 +00003402 // If there were any locally-scoped external declarations,
3403 // deserialize them and add them to Sema's table of locally-scoped
3404 // external declarations.
3405 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
3406 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
3407 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
3408 }
Douglas Gregor61cac2b2009-04-27 20:06:05 +00003409
3410 // If there were any ext_vector type declarations, deserialize them
3411 // and add them to Sema's vector of such declarations.
3412 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
3413 SemaObj->ExtVectorDecls.push_back(
3414 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003415
3416 // FIXME: Do VTable uses and dynamic classes deserialize too much ?
3417 // Can we cut them down before writing them ?
3418
3419 // If there were any VTable uses, deserialize the information and add it
3420 // to Sema's vector and map of VTable uses.
Argyrios Kyrtzidisedee67f2010-08-03 17:29:52 +00003421 if (!VTableUses.empty()) {
3422 unsigned Idx = 0;
3423 for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
3424 CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
3425 SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
3426 bool DefinitionRequired = VTableUses[Idx++];
3427 SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
3428 SemaObj->VTablesUsed[Class] = DefinitionRequired;
3429 }
Argyrios Kyrtzidisaf2eac22010-07-06 15:37:04 +00003430 }
3431
3432 // If there were any dynamic classes declarations, deserialize them
3433 // and add them to Sema's vector of such declarations.
3434 for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
3435 SemaObj->DynamicClasses.push_back(
3436 cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003437
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00003438 // If there were any pending implicit instantiations, deserialize them
3439 // and add them to Sema's queue of such instantiations.
Chandler Carruth54080172010-08-25 08:44:16 +00003440 assert(PendingInstantiations.size() % 2 == 0 && "Expected pairs of entries");
3441 for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
3442 ValueDecl *D=cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
3443 SourceLocation Loc = ReadSourceLocation(PendingInstantiations, Idx);
3444 SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc));
Argyrios Kyrtzidis7f76d112010-08-05 09:48:16 +00003445 }
3446
Argyrios Kyrtzidis2d688102010-08-02 07:14:54 +00003447 // Load the offsets of the declarations that Sema references.
3448 // They will be lazily deserialized when needed.
3449 if (!SemaDeclRefs.empty()) {
3450 assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
3451 SemaObj->StdNamespace = SemaDeclRefs[0];
3452 SemaObj->StdBadAlloc = SemaDeclRefs[1];
3453 }
3454
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003455 // If there are @selector references added them to its pool. This is for
3456 // implementation of -Wselector.
Sebastian Redlada023c2010-08-04 20:40:17 +00003457 if (!ReferencedSelectorsData.empty()) {
3458 unsigned int DataSize = ReferencedSelectorsData.size()-1;
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003459 unsigned I = 0;
3460 while (I < DataSize) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003461 Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003462 SourceLocation SelLoc =
Sebastian Redlada023c2010-08-04 20:40:17 +00003463 SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
Fariborz Jahanianc51609a2010-07-23 19:11:11 +00003464 SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
3465 }
3466 }
Douglas Gregora868bbd2009-04-21 22:25:48 +00003467}
3468
Sebastian Redl2c499f62010-08-18 23:56:43 +00003469IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Sebastian Redl78f51772010-08-02 18:30:12 +00003470 // Try to find this name within our on-disk hash tables. We start with the
3471 // most recent one, since that one contains the most up-to-date info.
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003472 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003473 ASTIdentifierLookupTable *IdTable
3474 = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
Sebastian Redl5c415f32010-07-22 17:01:13 +00003475 if (!IdTable)
3476 continue;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003477 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003478 ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003479 if (Pos == IdTable->end())
3480 continue;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003481
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003482 // Dereferencing the iterator has the effect of building the
3483 // IdentifierInfo node and populating it with the various
3484 // declarations it needs.
Sebastian Redl78f51772010-08-02 18:30:12 +00003485 return *Pos;
Sebastian Redl4e6c5672010-07-21 22:31:37 +00003486 }
Sebastian Redl78f51772010-08-02 18:30:12 +00003487 return 0;
Douglas Gregora868bbd2009-04-21 22:25:48 +00003488}
3489
Mike Stump11289f42009-09-09 15:08:12 +00003490std::pair<ObjCMethodList, ObjCMethodList>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003491ASTReader::ReadMethodPool(Selector Sel) {
Sebastian Redlada023c2010-08-04 20:40:17 +00003492 // Find this selector in a hash table. We want to find the most recent entry.
3493 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3494 PerFileData &F = *Chain[I];
3495 if (!F.SelectorLookupTable)
3496 continue;
Douglas Gregorc78d3462009-04-24 21:10:55 +00003497
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003498 ASTSelectorLookupTable *PoolTable
3499 = (ASTSelectorLookupTable*)F.SelectorLookupTable;
3500 ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
Sebastian Redlada023c2010-08-04 20:40:17 +00003501 if (Pos != PoolTable->end()) {
3502 ++NumSelectorsRead;
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003503 // FIXME: Not quite happy with the statistics here. We probably should
3504 // disable this tracking when called via LoadSelector.
3505 // Also, should entries without methods count as misses?
3506 ++NumMethodPoolEntriesRead;
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003507 ASTSelectorLookupTrait::data_type Data = *Pos;
Sebastian Redlada023c2010-08-04 20:40:17 +00003508 if (DeserializationListener)
3509 DeserializationListener->SelectorRead(Data.ID, Sel);
3510 return std::make_pair(Data.Instance, Data.Factory);
3511 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003512 }
Douglas Gregorc78d3462009-04-24 21:10:55 +00003513
Sebastian Redl6e1a2a02010-08-04 21:22:45 +00003514 ++NumMethodPoolMisses;
Sebastian Redlada023c2010-08-04 20:40:17 +00003515 return std::pair<ObjCMethodList, ObjCMethodList>();
Douglas Gregorc78d3462009-04-24 21:10:55 +00003516}
3517
Sebastian Redl2c499f62010-08-18 23:56:43 +00003518void ASTReader::LoadSelector(Selector Sel) {
Sebastian Redld95a56e2010-08-04 18:21:41 +00003519 // It would be complicated to avoid reading the methods anyway. So don't.
3520 ReadMethodPool(Sel);
3521}
3522
Sebastian Redl2c499f62010-08-18 23:56:43 +00003523void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregora868bbd2009-04-21 22:25:48 +00003524 assert(ID && "Non-zero identifier ID required");
Douglas Gregor6f00bf82009-04-28 21:53:25 +00003525 assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
Douglas Gregor0e149972009-04-25 19:10:14 +00003526 IdentifiersLoaded[ID - 1] = II;
Sebastian Redlff4a2952010-07-23 23:49:55 +00003527 if (DeserializationListener)
3528 DeserializationListener->IdentifierRead(ID, II);
Douglas Gregora868bbd2009-04-21 22:25:48 +00003529}
3530
Douglas Gregor1342e842009-07-06 18:54:52 +00003531/// \brief Set the globally-visible declarations associated with the given
3532/// identifier.
3533///
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003534/// If the AST reader is currently in a state where the given declaration IDs
Mike Stump11289f42009-09-09 15:08:12 +00003535/// cannot safely be resolved, they are queued until it is safe to resolve
Douglas Gregor1342e842009-07-06 18:54:52 +00003536/// them.
3537///
3538/// \param II an IdentifierInfo that refers to one or more globally-visible
3539/// declarations.
3540///
3541/// \param DeclIDs the set of declaration IDs with the name @p II that are
3542/// visible at global scope.
3543///
3544/// \param Nonrecursive should be true to indicate that the caller knows that
3545/// this call is non-recursive, and therefore the globally-visible declarations
3546/// will not be placed onto the pending queue.
Mike Stump11289f42009-09-09 15:08:12 +00003547void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003548ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
Douglas Gregor1342e842009-07-06 18:54:52 +00003549 const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
3550 bool Nonrecursive) {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00003551 if (NumCurrentElementsDeserializing && !Nonrecursive) {
Douglas Gregor1342e842009-07-06 18:54:52 +00003552 PendingIdentifierInfos.push_back(PendingIdentifierInfo());
3553 PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
3554 PII.II = II;
Benjamin Kramer25f9ea62010-09-06 23:43:28 +00003555 PII.DeclIDs.append(DeclIDs.begin(), DeclIDs.end());
Douglas Gregor1342e842009-07-06 18:54:52 +00003556 return;
3557 }
Mike Stump11289f42009-09-09 15:08:12 +00003558
Douglas Gregor1342e842009-07-06 18:54:52 +00003559 for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
3560 NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
3561 if (SemaObj) {
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003562 if (SemaObj->TUScope) {
3563 // Introduce this declaration into the translation-unit scope
3564 // and add it to the declaration chain for this identifier, so
3565 // that (unqualified) name lookup will find it.
John McCall48871652010-08-21 09:40:31 +00003566 SemaObj->TUScope->AddDecl(D);
Douglas Gregor6fd55e02010-08-13 03:15:25 +00003567 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
3568 }
Douglas Gregor1342e842009-07-06 18:54:52 +00003569 } else {
3570 // Queue this declaration so that it will be added to the
3571 // translation unit scope and identifier's declaration chain
3572 // once a Sema object is known.
3573 PreloadedDecls.push_back(D);
3574 }
3575 }
3576}
3577
Sebastian Redl2c499f62010-08-18 23:56:43 +00003578IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003579 if (ID == 0)
3580 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00003581
Sebastian Redlc713b962010-07-21 00:46:22 +00003582 if (IdentifiersLoaded.empty()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003583 Error("no identifier table in AST file");
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003584 return 0;
3585 }
Mike Stump11289f42009-09-09 15:08:12 +00003586
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003587 assert(PP && "Forgot to set Preprocessor ?");
Sebastian Redlc713b962010-07-21 00:46:22 +00003588 ID -= 1;
3589 if (!IdentifiersLoaded[ID]) {
3590 unsigned Index = ID;
3591 const char *Str = 0;
3592 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3593 PerFileData *F = Chain[N - I - 1];
3594 if (Index < F->LocalNumIdentifiers) {
3595 uint32_t Offset = F->IdentifierOffsets[Index];
3596 Str = F->IdentifierTableData + Offset;
3597 break;
3598 }
3599 Index -= F->LocalNumIdentifiers;
3600 }
3601 assert(Str && "Broken Chain");
Douglas Gregor5287b4e2009-04-25 21:04:17 +00003602
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003603 // All of the strings in the AST file are preceded by a 16-bit length.
3604 // Extract that 16-bit length to avoid having to execute strlen().
Ted Kremenekca42a512009-10-23 04:45:31 +00003605 // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
3606 // unsigned integers. This is important to avoid integer overflow when
3607 // we cast them to 'unsigned'.
Ted Kremenek49c52322009-10-23 03:57:22 +00003608 const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
Douglas Gregorab4df582009-04-28 20:01:51 +00003609 unsigned StrLen = (((unsigned) StrLenPtr[0])
3610 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Sebastian Redlc713b962010-07-21 00:46:22 +00003611 IdentifiersLoaded[ID]
Kovarththanan Rajaratnama3b09592010-03-12 10:32:27 +00003612 = &PP->getIdentifierTable().get(Str, StrLen);
Sebastian Redlff4a2952010-07-23 23:49:55 +00003613 if (DeserializationListener)
3614 DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
Douglas Gregor3ed42cb2009-04-11 00:14:32 +00003615 }
Mike Stump11289f42009-09-09 15:08:12 +00003616
Sebastian Redlc713b962010-07-21 00:46:22 +00003617 return IdentifiersLoaded[ID];
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003618}
3619
Sebastian Redl2c499f62010-08-18 23:56:43 +00003620void ASTReader::ReadSLocEntry(unsigned ID) {
Douglas Gregor258ae542009-04-27 06:38:32 +00003621 ReadSLocEntryRecord(ID);
3622}
3623
Sebastian Redl2c499f62010-08-18 23:56:43 +00003624Selector ASTReader::DecodeSelector(unsigned ID) {
Steve Naroff2ddea052009-04-23 10:39:46 +00003625 if (ID == 0)
3626 return Selector();
Mike Stump11289f42009-09-09 15:08:12 +00003627
Sebastian Redlada023c2010-08-04 20:40:17 +00003628 if (ID > SelectorsLoaded.size()) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003629 Error("selector ID out of range in AST file");
Steve Naroff2ddea052009-04-23 10:39:46 +00003630 return Selector();
3631 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003632
Sebastian Redlada023c2010-08-04 20:40:17 +00003633 if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
Douglas Gregor95c13f52009-04-25 17:48:32 +00003634 // Load this selector from the selector table.
Sebastian Redlada023c2010-08-04 20:40:17 +00003635 unsigned Idx = ID - 1;
3636 for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3637 PerFileData &F = *Chain[N - I - 1];
3638 if (Idx < F.LocalNumSelectors) {
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003639 ASTSelectorLookupTrait Trait(*this);
Sebastian Redlada023c2010-08-04 20:40:17 +00003640 SelectorsLoaded[ID - 1] =
3641 Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
3642 if (DeserializationListener)
3643 DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
3644 break;
3645 }
3646 Idx -= F.LocalNumSelectors;
3647 }
Douglas Gregor95c13f52009-04-25 17:48:32 +00003648 }
3649
Sebastian Redlada023c2010-08-04 20:40:17 +00003650 return SelectorsLoaded[ID - 1];
Steve Naroff2ddea052009-04-23 10:39:46 +00003651}
3652
Sebastian Redl2c499f62010-08-18 23:56:43 +00003653Selector ASTReader::GetExternalSelector(uint32_t ID) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003654 return DecodeSelector(ID);
3655}
3656
Sebastian Redl2c499f62010-08-18 23:56:43 +00003657uint32_t ASTReader::GetNumExternalSelectors() {
Sebastian Redlada023c2010-08-04 20:40:17 +00003658 // ID 0 (the null selector) is considered an external selector.
3659 return getTotalNumSelectors() + 1;
Douglas Gregord720daf2010-04-06 17:30:22 +00003660}
3661
Mike Stump11289f42009-09-09 15:08:12 +00003662DeclarationName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003663ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003664 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
3665 switch (Kind) {
3666 case DeclarationName::Identifier:
3667 return DeclarationName(GetIdentifierInfo(Record, Idx));
3668
3669 case DeclarationName::ObjCZeroArgSelector:
3670 case DeclarationName::ObjCOneArgSelector:
3671 case DeclarationName::ObjCMultiArgSelector:
Steve Naroff3c301dc2009-04-23 15:15:40 +00003672 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003673
3674 case DeclarationName::CXXConstructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003675 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003676 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003677
3678 case DeclarationName::CXXDestructorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003679 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003680 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003681
3682 case DeclarationName::CXXConversionFunctionName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003683 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor2211d342009-08-05 05:36:45 +00003684 Context->getCanonicalType(GetType(Record[Idx++])));
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003685
3686 case DeclarationName::CXXOperatorName:
Chris Lattner8575daa2009-04-27 21:45:14 +00003687 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003688 (OverloadedOperatorKind)Record[Idx++]);
3689
Alexis Hunt3d221f22009-11-29 07:34:05 +00003690 case DeclarationName::CXXLiteralOperatorName:
3691 return Context->DeclarationNames.getCXXLiteralOperatorName(
3692 GetIdentifierInfo(Record, Idx));
3693
Douglas Gregoref84c4b2009-04-09 22:27:44 +00003694 case DeclarationName::CXXUsingDirective:
3695 return DeclarationName::getUsingDirectiveName();
3696 }
3697
3698 // Required to silence GCC warning
3699 return DeclarationName();
3700}
Douglas Gregor55abb232009-04-10 20:39:37 +00003701
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003702TemplateName
Sebastian Redl2c499f62010-08-18 23:56:43 +00003703ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003704 TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
3705 switch (Kind) {
3706 case TemplateName::Template:
3707 return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
3708
3709 case TemplateName::OverloadedTemplate: {
3710 unsigned size = Record[Idx++];
3711 UnresolvedSet<8> Decls;
3712 while (size--)
3713 Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
3714
3715 return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
3716 }
3717
3718 case TemplateName::QualifiedTemplate: {
3719 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3720 bool hasTemplKeyword = Record[Idx++];
3721 TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
3722 return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
3723 }
3724
3725 case TemplateName::DependentTemplate: {
3726 NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
3727 if (Record[Idx++]) // isIdentifier
3728 return Context->getDependentTemplateName(NNS,
3729 GetIdentifierInfo(Record, Idx));
3730 return Context->getDependentTemplateName(NNS,
Argyrios Kyrtzidisddf5f212010-06-28 09:31:42 +00003731 (OverloadedOperatorKind)Record[Idx++]);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003732 }
3733 }
3734
3735 assert(0 && "Unhandled template name kind!");
3736 return TemplateName();
3737}
3738
3739TemplateArgument
Sebastian Redl2c499f62010-08-18 23:56:43 +00003740ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003741 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003742 switch ((TemplateArgument::ArgKind)Record[Idx++]) {
3743 case TemplateArgument::Null:
3744 return TemplateArgument();
3745 case TemplateArgument::Type:
3746 return TemplateArgument(GetType(Record[Idx++]));
3747 case TemplateArgument::Declaration:
3748 return TemplateArgument(GetDecl(Record[Idx++]));
Argyrios Kyrtzidis0b0369a2010-06-28 09:31:34 +00003749 case TemplateArgument::Integral: {
3750 llvm::APSInt Value = ReadAPSInt(Record, Idx);
3751 QualType T = GetType(Record[Idx++]);
3752 return TemplateArgument(Value, T);
3753 }
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003754 case TemplateArgument::Template:
3755 return TemplateArgument(ReadTemplateName(Record, Idx));
3756 case TemplateArgument::Expression:
Sebastian Redlc67764e2010-07-22 22:43:28 +00003757 return TemplateArgument(ReadExpr(DeclsCursor));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003758 case TemplateArgument::Pack: {
3759 unsigned NumArgs = Record[Idx++];
3760 llvm::SmallVector<TemplateArgument, 8> Args;
3761 Args.reserve(NumArgs);
3762 while (NumArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003763 Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +00003764 TemplateArgument TemplArg;
3765 TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
3766 return TemplArg;
3767 }
3768 }
3769
3770 assert(0 && "Unhandled template argument kind!");
3771 return TemplateArgument();
3772}
3773
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003774TemplateParameterList *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003775ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003776 SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
3777 SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
3778 SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
3779
3780 unsigned NumParams = Record[Idx++];
3781 llvm::SmallVector<NamedDecl *, 16> Params;
3782 Params.reserve(NumParams);
3783 while (NumParams--)
3784 Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
3785
3786 TemplateParameterList* TemplateParams =
3787 TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
3788 Params.data(), Params.size(), RAngleLoc);
3789 return TemplateParams;
3790}
3791
3792void
Sebastian Redl2c499f62010-08-18 23:56:43 +00003793ASTReader::
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003794ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
Sebastian Redlc67764e2010-07-22 22:43:28 +00003795 llvm::BitstreamCursor &DeclsCursor,
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003796 const RecordData &Record, unsigned &Idx) {
3797 unsigned NumTemplateArgs = Record[Idx++];
3798 TemplArgs.reserve(NumTemplateArgs);
3799 while (NumTemplateArgs--)
Sebastian Redlc67764e2010-07-22 22:43:28 +00003800 TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
Argyrios Kyrtzidis818c5db2010-06-23 13:48:30 +00003801}
3802
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003803/// \brief Read a UnresolvedSet structure.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003804void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
Argyrios Kyrtzidis2c2167a2010-07-02 11:55:32 +00003805 const RecordData &Record, unsigned &Idx) {
3806 unsigned NumDecls = Record[Idx++];
3807 while (NumDecls--) {
3808 NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
3809 AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
3810 Set.addDecl(D, AS);
3811 }
3812}
3813
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003814CXXBaseSpecifier
Sebastian Redl2c499f62010-08-18 23:56:43 +00003815ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
Nick Lewycky19b9f952010-07-26 16:56:01 +00003816 const RecordData &Record, unsigned &Idx) {
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003817 bool isVirtual = static_cast<bool>(Record[Idx++]);
3818 bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
3819 AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003820 TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003821 SourceRange Range = ReadSourceRange(Record, Idx);
Nick Lewycky19b9f952010-07-26 16:56:01 +00003822 return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
Argyrios Kyrtzidis3701fcd2010-07-02 23:30:27 +00003823}
3824
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003825std::pair<CXXBaseOrMemberInitializer **, unsigned>
Sebastian Redl2c499f62010-08-18 23:56:43 +00003826ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003827 const RecordData &Record,
3828 unsigned &Idx) {
3829 CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
3830 unsigned NumInitializers = Record[Idx++];
3831 if (NumInitializers) {
3832 ASTContext &C = *getContext();
3833
3834 BaseOrMemberInitializers
3835 = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
3836 for (unsigned i=0; i != NumInitializers; ++i) {
3837 TypeSourceInfo *BaseClassInfo = 0;
3838 bool IsBaseVirtual = false;
3839 FieldDecl *Member = 0;
3840
3841 bool IsBaseInitializer = Record[Idx++];
3842 if (IsBaseInitializer) {
3843 BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
3844 IsBaseVirtual = Record[Idx++];
3845 } else {
3846 Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
3847 }
3848 SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
3849 Expr *Init = ReadExpr(Cursor);
3850 FieldDecl *AnonUnionMember
3851 = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
3852 SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
3853 SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
3854 bool IsWritten = Record[Idx++];
3855 unsigned SourceOrderOrNumArrayIndices;
3856 llvm::SmallVector<VarDecl *, 8> Indices;
3857 if (IsWritten) {
3858 SourceOrderOrNumArrayIndices = Record[Idx++];
3859 } else {
3860 SourceOrderOrNumArrayIndices = Record[Idx++];
3861 Indices.reserve(SourceOrderOrNumArrayIndices);
3862 for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
3863 Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
3864 }
3865
3866 CXXBaseOrMemberInitializer *BOMInit;
3867 if (IsBaseInitializer) {
3868 BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
3869 IsBaseVirtual, LParenLoc,
3870 Init, RParenLoc);
3871 } else if (IsWritten) {
3872 BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
3873 LParenLoc, Init, RParenLoc);
3874 } else {
3875 BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
3876 LParenLoc, Init, RParenLoc,
3877 Indices.data(),
3878 Indices.size());
3879 }
3880
Argyrios Kyrtzidisd05f3e32010-09-06 19:04:27 +00003881 if (IsWritten)
3882 BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);
Argyrios Kyrtzidis5b6a03f2010-08-09 10:54:12 +00003883 BOMInit->setAnonUnionMember(AnonUnionMember);
3884 BaseOrMemberInitializers[i] = BOMInit;
3885 }
3886 }
3887
3888 return std::make_pair(BaseOrMemberInitializers, NumInitializers);
3889}
3890
Chris Lattnerca025db2010-05-07 21:43:38 +00003891NestedNameSpecifier *
Sebastian Redl2c499f62010-08-18 23:56:43 +00003892ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
Chris Lattnerca025db2010-05-07 21:43:38 +00003893 unsigned N = Record[Idx++];
3894 NestedNameSpecifier *NNS = 0, *Prev = 0;
3895 for (unsigned I = 0; I != N; ++I) {
3896 NestedNameSpecifier::SpecifierKind Kind
3897 = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
3898 switch (Kind) {
3899 case NestedNameSpecifier::Identifier: {
3900 IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
3901 NNS = NestedNameSpecifier::Create(*Context, Prev, II);
3902 break;
3903 }
3904
3905 case NestedNameSpecifier::Namespace: {
3906 NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
3907 NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
3908 break;
3909 }
3910
3911 case NestedNameSpecifier::TypeSpec:
3912 case NestedNameSpecifier::TypeSpecWithTemplate: {
3913 Type *T = GetType(Record[Idx++]).getTypePtr();
3914 bool Template = Record[Idx++];
3915 NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
3916 break;
3917 }
3918
3919 case NestedNameSpecifier::Global: {
3920 NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
3921 // No associated value, and there can't be a prefix.
3922 break;
3923 }
Chris Lattnerca025db2010-05-07 21:43:38 +00003924 }
Argyrios Kyrtzidisad65c692010-07-07 15:46:30 +00003925 Prev = NNS;
Chris Lattnerca025db2010-05-07 21:43:38 +00003926 }
3927 return NNS;
3928}
3929
3930SourceRange
Sebastian Redl2c499f62010-08-18 23:56:43 +00003931ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
Daniel Dunbar6d3bc082010-06-02 15:47:10 +00003932 SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
3933 SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
3934 return SourceRange(beg, end);
Chris Lattnerca025db2010-05-07 21:43:38 +00003935}
3936
Douglas Gregor1daeb692009-04-13 18:14:40 +00003937/// \brief Read an integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003938llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003939 unsigned BitWidth = Record[Idx++];
3940 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
3941 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
3942 Idx += NumWords;
3943 return Result;
3944}
3945
3946/// \brief Read a signed integral value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003947llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
Douglas Gregor1daeb692009-04-13 18:14:40 +00003948 bool isUnsigned = Record[Idx++];
3949 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
3950}
3951
Douglas Gregore0a3a512009-04-14 21:55:33 +00003952/// \brief Read a floating-point value
Sebastian Redl2c499f62010-08-18 23:56:43 +00003953llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregore0a3a512009-04-14 21:55:33 +00003954 return llvm::APFloat(ReadAPInt(Record, Idx));
3955}
3956
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003957// \brief Read a string
Sebastian Redl2c499f62010-08-18 23:56:43 +00003958std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003959 unsigned Len = Record[Idx++];
Jay Foad7d0479f2009-05-21 09:52:38 +00003960 std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
Douglas Gregorbc8a78d52009-04-15 21:30:51 +00003961 Idx += Len;
3962 return Result;
3963}
3964
Sebastian Redl2c499f62010-08-18 23:56:43 +00003965CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
Chris Lattnercba86142010-05-10 00:25:06 +00003966 unsigned &Idx) {
3967 CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
3968 return CXXTemporary::Create(*Context, Decl);
3969}
3970
Sebastian Redl2c499f62010-08-18 23:56:43 +00003971DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
Douglas Gregor92863e42009-04-10 23:10:45 +00003972 return Diag(SourceLocation(), DiagID);
3973}
3974
Sebastian Redl2c499f62010-08-18 23:56:43 +00003975DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003976 return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
Douglas Gregor55abb232009-04-10 20:39:37 +00003977}
Douglas Gregora9af1d12009-04-17 00:04:06 +00003978
Douglas Gregora868bbd2009-04-21 22:25:48 +00003979/// \brief Retrieve the identifier table associated with the
3980/// preprocessor.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003981IdentifierTable &ASTReader::getIdentifierTable() {
Argyrios Kyrtzidis366985d2009-06-19 00:03:23 +00003982 assert(PP && "Forgot to set Preprocessor ?");
3983 return PP->getIdentifierTable();
Douglas Gregora868bbd2009-04-21 22:25:48 +00003984}
3985
Douglas Gregora9af1d12009-04-17 00:04:06 +00003986/// \brief Record that the given ID maps to the given switch-case
3987/// statement.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003988void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003989 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
3990 SwitchCaseStmts[ID] = SC;
3991}
3992
3993/// \brief Retrieve the switch-case statement with the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00003994SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
Douglas Gregora9af1d12009-04-17 00:04:06 +00003995 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
3996 return SwitchCaseStmts[ID];
3997}
Douglas Gregor6cc68a42009-04-17 18:18:49 +00003998
3999/// \brief Record that the given label statement has been
4000/// deserialized and has the given ID.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004001void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
Mike Stump11289f42009-09-09 15:08:12 +00004002 assert(LabelStmts.find(ID) == LabelStmts.end() &&
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004003 "Deserialized label twice");
4004 LabelStmts[ID] = S;
4005
4006 // If we've already seen any goto statements that point to this
4007 // label, resolve them now.
4008 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
4009 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
4010 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
4011 Goto->second->setLabel(S);
4012 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor779d8652009-04-17 18:58:21 +00004013
4014 // If we've already seen any address-label statements that point to
4015 // this label, resolve them now.
4016 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
Mike Stump11289f42009-09-09 15:08:12 +00004017 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
Douglas Gregor779d8652009-04-17 18:58:21 +00004018 = UnresolvedAddrLabelExprs.equal_range(ID);
Mike Stump11289f42009-09-09 15:08:12 +00004019 for (AddrLabelIter AddrLabel = AddrLabels.first;
Douglas Gregor779d8652009-04-17 18:58:21 +00004020 AddrLabel != AddrLabels.second; ++AddrLabel)
4021 AddrLabel->second->setLabel(S);
4022 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004023}
4024
4025/// \brief Set the label of the given statement to the label
4026/// identified by ID.
4027///
4028/// Depending on the order in which the label and other statements
4029/// referencing that label occur, this operation may complete
4030/// immediately (updating the statement) or it may queue the
4031/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004032void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
Douglas Gregor6cc68a42009-04-17 18:18:49 +00004033 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4034 if (Label != LabelStmts.end()) {
4035 // We've already seen this label, so set the label of the goto and
4036 // we're done.
4037 S->setLabel(Label->second);
4038 } else {
4039 // We haven't seen this label yet, so add this goto to the set of
4040 // unresolved goto statements.
4041 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
4042 }
4043}
Douglas Gregor779d8652009-04-17 18:58:21 +00004044
4045/// \brief Set the label of the given expression to the label
4046/// identified by ID.
4047///
4048/// Depending on the order in which the label and other statements
4049/// referencing that label occur, this operation may complete
4050/// immediately (updating the statement) or it may queue the
4051/// statement to be back-patched later.
Sebastian Redl2c499f62010-08-18 23:56:43 +00004052void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
Douglas Gregor779d8652009-04-17 18:58:21 +00004053 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
4054 if (Label != LabelStmts.end()) {
4055 // We've already seen this label, so set the label of the
4056 // label-address expression and we're done.
4057 S->setLabel(Label->second);
4058 } else {
4059 // We haven't seen this label yet, so add this label-address
4060 // expression to the set of unresolved label-address expressions.
4061 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
4062 }
4063}
Douglas Gregor1342e842009-07-06 18:54:52 +00004064
Sebastian Redl2c499f62010-08-18 23:56:43 +00004065void ASTReader::FinishedDeserializing() {
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004066 assert(NumCurrentElementsDeserializing &&
4067 "FinishedDeserializing not paired with StartedDeserializing");
4068 if (NumCurrentElementsDeserializing == 1) {
Douglas Gregor1342e842009-07-06 18:54:52 +00004069 // If any identifiers with corresponding top-level declarations have
4070 // been loaded, load those declarations now.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004071 while (!PendingIdentifierInfos.empty()) {
4072 SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
4073 PendingIdentifierInfos.front().DeclIDs, true);
4074 PendingIdentifierInfos.pop_front();
Douglas Gregor1342e842009-07-06 18:54:52 +00004075 }
Argyrios Kyrtzidis903ccd62010-07-07 15:46:26 +00004076
4077 // We are not in recursive loading, so it's safe to pass the "interesting"
4078 // decls to the consumer.
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004079 if (Consumer)
4080 PassInterestingDeclsToConsumer();
Douglas Gregor1342e842009-07-06 18:54:52 +00004081 }
Argyrios Kyrtzidisb24355a2010-07-30 10:03:16 +00004082 --NumCurrentElementsDeserializing;
Douglas Gregor1342e842009-07-06 18:54:52 +00004083}
Douglas Gregorb473b072010-08-19 00:28:17 +00004084
Sebastian Redld7dce0a2010-08-24 00:50:04 +00004085ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
4086 const char *isysroot, bool DisableValidation)
4087 : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
4088 SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
4089 Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
4090 Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
4091 NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
4092 TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
4093 NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
4094 NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
4095 TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
4096 TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
4097 TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
4098 RelocatablePCH = false;
4099}
4100
4101ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
4102 Diagnostic &Diags, const char *isysroot,
4103 bool DisableValidation)
4104 : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
4105 Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
4106 isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
4107 NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
4108 NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
4109 TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
4110 NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
4111 NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
4112 NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
4113 NumCurrentElementsDeserializing(0) {
4114 RelocatablePCH = false;
4115}
4116
4117ASTReader::~ASTReader() {
4118 for (unsigned i = 0, e = Chain.size(); i != e; ++i)
4119 delete Chain[e - i - 1];
4120 // Delete all visible decl lookup tables
4121 for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
4122 E = DeclContextOffsets.end();
4123 I != E; ++I) {
4124 for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
4125 J != F; ++J) {
4126 if (J->NameLookupTableData)
4127 delete static_cast<ASTDeclContextNameLookupTable*>(
4128 J->NameLookupTableData);
4129 }
4130 }
4131 for (DeclContextVisibleUpdatesPending::iterator
4132 I = PendingVisibleUpdates.begin(),
4133 E = PendingVisibleUpdates.end();
4134 I != E; ++I) {
4135 for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
4136 F = I->second.end();
4137 J != F; ++J)
4138 delete static_cast<ASTDeclContextNameLookupTable*>(*J);
4139 }
4140}
4141
Douglas Gregorb473b072010-08-19 00:28:17 +00004142ASTReader::PerFileData::PerFileData()
Sebastian Redl949fe9e2010-09-22 00:42:27 +00004143 : SizeInBits(0), LocalNumSLocEntries(0), SLocOffsets(0),
4144 LocalNumIdentifiers(0), IdentifierOffsets(0), IdentifierTableData(0),
4145 IdentifierLookupTable(0), LocalNumMacroDefinitions(0),
4146 MacroDefinitionOffsets(0), LocalNumSelectors(0), SelectorOffsets(0),
4147 SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
4148 DeclOffsets(0), LocalNumTypes(0), TypeOffsets(0), StatCache(0),
4149 NumPreallocatedPreprocessingEntities(0)
Douglas Gregorb473b072010-08-19 00:28:17 +00004150{}
4151
4152ASTReader::PerFileData::~PerFileData() {
4153 delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
4154 delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
4155}
4156