1f4a2713aSLionel Sambuc //===--- ASTReader.cpp - AST File Reader ----------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file defines the ASTReader class, which reads AST files.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc
14f4a2713aSLionel Sambuc #include "clang/Serialization/ASTReader.h"
15f4a2713aSLionel Sambuc #include "ASTCommon.h"
16f4a2713aSLionel Sambuc #include "ASTReaderInternals.h"
17f4a2713aSLionel Sambuc #include "clang/AST/ASTConsumer.h"
18f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
20f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
21f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h"
22f4a2713aSLionel Sambuc #include "clang/AST/NestedNameSpecifier.h"
23f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
24f4a2713aSLionel Sambuc #include "clang/AST/TypeLocVisitor.h"
25*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h"
26f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
27f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
28f4a2713aSLionel Sambuc #include "clang/Basic/SourceManagerInternals.h"
29f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
30f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h"
31f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
32f4a2713aSLionel Sambuc #include "clang/Basic/VersionTuple.h"
33*0a6a1f1dSLionel Sambuc #include "clang/Frontend/Utils.h"
34f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
35f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearchOptions.h"
36f4a2713aSLionel Sambuc #include "clang/Lex/MacroInfo.h"
37f4a2713aSLionel Sambuc #include "clang/Lex/PreprocessingRecord.h"
38f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
39f4a2713aSLionel Sambuc #include "clang/Lex/PreprocessorOptions.h"
40f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
41f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
42f4a2713aSLionel Sambuc #include "clang/Serialization/ASTDeserializationListener.h"
43f4a2713aSLionel Sambuc #include "clang/Serialization/GlobalModuleIndex.h"
44f4a2713aSLionel Sambuc #include "clang/Serialization/ModuleManager.h"
45f4a2713aSLionel Sambuc #include "clang/Serialization/SerializationDiagnostic.h"
46f4a2713aSLionel Sambuc #include "llvm/ADT/Hashing.h"
47f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
48f4a2713aSLionel Sambuc #include "llvm/Bitcode/BitstreamReader.h"
49f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
50f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
51f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
52f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
53f4a2713aSLionel Sambuc #include "llvm/Support/SaveAndRestore.h"
54*0a6a1f1dSLionel Sambuc #include "llvm/Support/raw_ostream.h"
55f4a2713aSLionel Sambuc #include <algorithm>
56f4a2713aSLionel Sambuc #include <cstdio>
57f4a2713aSLionel Sambuc #include <iterator>
58*0a6a1f1dSLionel Sambuc #include <system_error>
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc using namespace clang;
61f4a2713aSLionel Sambuc using namespace clang::serialization;
62f4a2713aSLionel Sambuc using namespace clang::serialization::reader;
63f4a2713aSLionel Sambuc using llvm::BitstreamCursor;
64f4a2713aSLionel Sambuc
65*0a6a1f1dSLionel Sambuc
66*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
67*0a6a1f1dSLionel Sambuc // ChainedASTReaderListener implementation
68*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
69*0a6a1f1dSLionel Sambuc
70*0a6a1f1dSLionel Sambuc bool
ReadFullVersionInformation(StringRef FullVersion)71*0a6a1f1dSLionel Sambuc ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) {
72*0a6a1f1dSLionel Sambuc return First->ReadFullVersionInformation(FullVersion) ||
73*0a6a1f1dSLionel Sambuc Second->ReadFullVersionInformation(FullVersion);
74*0a6a1f1dSLionel Sambuc }
ReadModuleName(StringRef ModuleName)75*0a6a1f1dSLionel Sambuc void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) {
76*0a6a1f1dSLionel Sambuc First->ReadModuleName(ModuleName);
77*0a6a1f1dSLionel Sambuc Second->ReadModuleName(ModuleName);
78*0a6a1f1dSLionel Sambuc }
ReadModuleMapFile(StringRef ModuleMapPath)79*0a6a1f1dSLionel Sambuc void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) {
80*0a6a1f1dSLionel Sambuc First->ReadModuleMapFile(ModuleMapPath);
81*0a6a1f1dSLionel Sambuc Second->ReadModuleMapFile(ModuleMapPath);
82*0a6a1f1dSLionel Sambuc }
83*0a6a1f1dSLionel Sambuc bool
ReadLanguageOptions(const LangOptions & LangOpts,bool Complain,bool AllowCompatibleDifferences)84*0a6a1f1dSLionel Sambuc ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
85*0a6a1f1dSLionel Sambuc bool Complain,
86*0a6a1f1dSLionel Sambuc bool AllowCompatibleDifferences) {
87*0a6a1f1dSLionel Sambuc return First->ReadLanguageOptions(LangOpts, Complain,
88*0a6a1f1dSLionel Sambuc AllowCompatibleDifferences) ||
89*0a6a1f1dSLionel Sambuc Second->ReadLanguageOptions(LangOpts, Complain,
90*0a6a1f1dSLionel Sambuc AllowCompatibleDifferences);
91*0a6a1f1dSLionel Sambuc }
92*0a6a1f1dSLionel Sambuc bool
ReadTargetOptions(const TargetOptions & TargetOpts,bool Complain)93*0a6a1f1dSLionel Sambuc ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts,
94*0a6a1f1dSLionel Sambuc bool Complain) {
95*0a6a1f1dSLionel Sambuc return First->ReadTargetOptions(TargetOpts, Complain) ||
96*0a6a1f1dSLionel Sambuc Second->ReadTargetOptions(TargetOpts, Complain);
97*0a6a1f1dSLionel Sambuc }
ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,bool Complain)98*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::ReadDiagnosticOptions(
99*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
100*0a6a1f1dSLionel Sambuc return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
101*0a6a1f1dSLionel Sambuc Second->ReadDiagnosticOptions(DiagOpts, Complain);
102*0a6a1f1dSLionel Sambuc }
103*0a6a1f1dSLionel Sambuc bool
ReadFileSystemOptions(const FileSystemOptions & FSOpts,bool Complain)104*0a6a1f1dSLionel Sambuc ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts,
105*0a6a1f1dSLionel Sambuc bool Complain) {
106*0a6a1f1dSLionel Sambuc return First->ReadFileSystemOptions(FSOpts, Complain) ||
107*0a6a1f1dSLionel Sambuc Second->ReadFileSystemOptions(FSOpts, Complain);
108*0a6a1f1dSLionel Sambuc }
109*0a6a1f1dSLionel Sambuc
ReadHeaderSearchOptions(const HeaderSearchOptions & HSOpts,bool Complain)110*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::ReadHeaderSearchOptions(
111*0a6a1f1dSLionel Sambuc const HeaderSearchOptions &HSOpts, bool Complain) {
112*0a6a1f1dSLionel Sambuc return First->ReadHeaderSearchOptions(HSOpts, Complain) ||
113*0a6a1f1dSLionel Sambuc Second->ReadHeaderSearchOptions(HSOpts, Complain);
114*0a6a1f1dSLionel Sambuc }
ReadPreprocessorOptions(const PreprocessorOptions & PPOpts,bool Complain,std::string & SuggestedPredefines)115*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::ReadPreprocessorOptions(
116*0a6a1f1dSLionel Sambuc const PreprocessorOptions &PPOpts, bool Complain,
117*0a6a1f1dSLionel Sambuc std::string &SuggestedPredefines) {
118*0a6a1f1dSLionel Sambuc return First->ReadPreprocessorOptions(PPOpts, Complain,
119*0a6a1f1dSLionel Sambuc SuggestedPredefines) ||
120*0a6a1f1dSLionel Sambuc Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines);
121*0a6a1f1dSLionel Sambuc }
ReadCounter(const serialization::ModuleFile & M,unsigned Value)122*0a6a1f1dSLionel Sambuc void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M,
123*0a6a1f1dSLionel Sambuc unsigned Value) {
124*0a6a1f1dSLionel Sambuc First->ReadCounter(M, Value);
125*0a6a1f1dSLionel Sambuc Second->ReadCounter(M, Value);
126*0a6a1f1dSLionel Sambuc }
needsInputFileVisitation()127*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::needsInputFileVisitation() {
128*0a6a1f1dSLionel Sambuc return First->needsInputFileVisitation() ||
129*0a6a1f1dSLionel Sambuc Second->needsInputFileVisitation();
130*0a6a1f1dSLionel Sambuc }
needsSystemInputFileVisitation()131*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::needsSystemInputFileVisitation() {
132*0a6a1f1dSLionel Sambuc return First->needsSystemInputFileVisitation() ||
133*0a6a1f1dSLionel Sambuc Second->needsSystemInputFileVisitation();
134*0a6a1f1dSLionel Sambuc }
visitModuleFile(StringRef Filename)135*0a6a1f1dSLionel Sambuc void ChainedASTReaderListener::visitModuleFile(StringRef Filename) {
136*0a6a1f1dSLionel Sambuc First->visitModuleFile(Filename);
137*0a6a1f1dSLionel Sambuc Second->visitModuleFile(Filename);
138*0a6a1f1dSLionel Sambuc }
visitInputFile(StringRef Filename,bool isSystem,bool isOverridden)139*0a6a1f1dSLionel Sambuc bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
140*0a6a1f1dSLionel Sambuc bool isSystem,
141*0a6a1f1dSLionel Sambuc bool isOverridden) {
142*0a6a1f1dSLionel Sambuc bool Continue = false;
143*0a6a1f1dSLionel Sambuc if (First->needsInputFileVisitation() &&
144*0a6a1f1dSLionel Sambuc (!isSystem || First->needsSystemInputFileVisitation()))
145*0a6a1f1dSLionel Sambuc Continue |= First->visitInputFile(Filename, isSystem, isOverridden);
146*0a6a1f1dSLionel Sambuc if (Second->needsInputFileVisitation() &&
147*0a6a1f1dSLionel Sambuc (!isSystem || Second->needsSystemInputFileVisitation()))
148*0a6a1f1dSLionel Sambuc Continue |= Second->visitInputFile(Filename, isSystem, isOverridden);
149*0a6a1f1dSLionel Sambuc return Continue;
150*0a6a1f1dSLionel Sambuc }
151*0a6a1f1dSLionel Sambuc
152f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
153f4a2713aSLionel Sambuc // PCH validator implementation
154f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
155f4a2713aSLionel Sambuc
~ASTReaderListener()156f4a2713aSLionel Sambuc ASTReaderListener::~ASTReaderListener() {}
157f4a2713aSLionel Sambuc
158f4a2713aSLionel Sambuc /// \brief Compare the given set of language options against an existing set of
159f4a2713aSLionel Sambuc /// language options.
160f4a2713aSLionel Sambuc ///
161f4a2713aSLionel Sambuc /// \param Diags If non-NULL, diagnostics will be emitted via this engine.
162*0a6a1f1dSLionel Sambuc /// \param AllowCompatibleDifferences If true, differences between compatible
163*0a6a1f1dSLionel Sambuc /// language options will be permitted.
164f4a2713aSLionel Sambuc ///
165f4a2713aSLionel Sambuc /// \returns true if the languagae options mis-match, false otherwise.
checkLanguageOptions(const LangOptions & LangOpts,const LangOptions & ExistingLangOpts,DiagnosticsEngine * Diags,bool AllowCompatibleDifferences=true)166f4a2713aSLionel Sambuc static bool checkLanguageOptions(const LangOptions &LangOpts,
167f4a2713aSLionel Sambuc const LangOptions &ExistingLangOpts,
168*0a6a1f1dSLionel Sambuc DiagnosticsEngine *Diags,
169*0a6a1f1dSLionel Sambuc bool AllowCompatibleDifferences = true) {
170f4a2713aSLionel Sambuc #define LANGOPT(Name, Bits, Default, Description) \
171f4a2713aSLionel Sambuc if (ExistingLangOpts.Name != LangOpts.Name) { \
172f4a2713aSLionel Sambuc if (Diags) \
173f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_langopt_mismatch) \
174f4a2713aSLionel Sambuc << Description << LangOpts.Name << ExistingLangOpts.Name; \
175f4a2713aSLionel Sambuc return true; \
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc
178f4a2713aSLionel Sambuc #define VALUE_LANGOPT(Name, Bits, Default, Description) \
179f4a2713aSLionel Sambuc if (ExistingLangOpts.Name != LangOpts.Name) { \
180f4a2713aSLionel Sambuc if (Diags) \
181f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_langopt_value_mismatch) \
182f4a2713aSLionel Sambuc << Description; \
183f4a2713aSLionel Sambuc return true; \
184f4a2713aSLionel Sambuc }
185f4a2713aSLionel Sambuc
186f4a2713aSLionel Sambuc #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
187f4a2713aSLionel Sambuc if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) { \
188f4a2713aSLionel Sambuc if (Diags) \
189f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_langopt_value_mismatch) \
190f4a2713aSLionel Sambuc << Description; \
191f4a2713aSLionel Sambuc return true; \
192f4a2713aSLionel Sambuc }
193f4a2713aSLionel Sambuc
194*0a6a1f1dSLionel Sambuc #define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \
195*0a6a1f1dSLionel Sambuc if (!AllowCompatibleDifferences) \
196*0a6a1f1dSLionel Sambuc LANGOPT(Name, Bits, Default, Description)
197*0a6a1f1dSLionel Sambuc
198*0a6a1f1dSLionel Sambuc #define COMPATIBLE_ENUM_LANGOPT(Name, Bits, Default, Description) \
199*0a6a1f1dSLionel Sambuc if (!AllowCompatibleDifferences) \
200*0a6a1f1dSLionel Sambuc ENUM_LANGOPT(Name, Bits, Default, Description)
201*0a6a1f1dSLionel Sambuc
202f4a2713aSLionel Sambuc #define BENIGN_LANGOPT(Name, Bits, Default, Description)
203f4a2713aSLionel Sambuc #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
204f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.def"
205f4a2713aSLionel Sambuc
206f4a2713aSLionel Sambuc if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
207f4a2713aSLionel Sambuc if (Diags)
208f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_langopt_value_mismatch)
209f4a2713aSLionel Sambuc << "target Objective-C runtime";
210f4a2713aSLionel Sambuc return true;
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc
213f4a2713aSLionel Sambuc if (ExistingLangOpts.CommentOpts.BlockCommandNames !=
214f4a2713aSLionel Sambuc LangOpts.CommentOpts.BlockCommandNames) {
215f4a2713aSLionel Sambuc if (Diags)
216f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_langopt_value_mismatch)
217f4a2713aSLionel Sambuc << "block command names";
218f4a2713aSLionel Sambuc return true;
219f4a2713aSLionel Sambuc }
220f4a2713aSLionel Sambuc
221f4a2713aSLionel Sambuc return false;
222f4a2713aSLionel Sambuc }
223f4a2713aSLionel Sambuc
224f4a2713aSLionel Sambuc /// \brief Compare the given set of target options against an existing set of
225f4a2713aSLionel Sambuc /// target options.
226f4a2713aSLionel Sambuc ///
227f4a2713aSLionel Sambuc /// \param Diags If non-NULL, diagnostics will be emitted via this engine.
228f4a2713aSLionel Sambuc ///
229f4a2713aSLionel Sambuc /// \returns true if the target options mis-match, false otherwise.
checkTargetOptions(const TargetOptions & TargetOpts,const TargetOptions & ExistingTargetOpts,DiagnosticsEngine * Diags)230f4a2713aSLionel Sambuc static bool checkTargetOptions(const TargetOptions &TargetOpts,
231f4a2713aSLionel Sambuc const TargetOptions &ExistingTargetOpts,
232f4a2713aSLionel Sambuc DiagnosticsEngine *Diags) {
233f4a2713aSLionel Sambuc #define CHECK_TARGET_OPT(Field, Name) \
234f4a2713aSLionel Sambuc if (TargetOpts.Field != ExistingTargetOpts.Field) { \
235f4a2713aSLionel Sambuc if (Diags) \
236f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_targetopt_mismatch) \
237f4a2713aSLionel Sambuc << Name << TargetOpts.Field << ExistingTargetOpts.Field; \
238f4a2713aSLionel Sambuc return true; \
239f4a2713aSLionel Sambuc }
240f4a2713aSLionel Sambuc
241f4a2713aSLionel Sambuc CHECK_TARGET_OPT(Triple, "target");
242f4a2713aSLionel Sambuc CHECK_TARGET_OPT(CPU, "target CPU");
243f4a2713aSLionel Sambuc CHECK_TARGET_OPT(ABI, "target ABI");
244f4a2713aSLionel Sambuc #undef CHECK_TARGET_OPT
245f4a2713aSLionel Sambuc
246f4a2713aSLionel Sambuc // Compare feature sets.
247f4a2713aSLionel Sambuc SmallVector<StringRef, 4> ExistingFeatures(
248f4a2713aSLionel Sambuc ExistingTargetOpts.FeaturesAsWritten.begin(),
249f4a2713aSLionel Sambuc ExistingTargetOpts.FeaturesAsWritten.end());
250f4a2713aSLionel Sambuc SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(),
251f4a2713aSLionel Sambuc TargetOpts.FeaturesAsWritten.end());
252f4a2713aSLionel Sambuc std::sort(ExistingFeatures.begin(), ExistingFeatures.end());
253f4a2713aSLionel Sambuc std::sort(ReadFeatures.begin(), ReadFeatures.end());
254f4a2713aSLionel Sambuc
255f4a2713aSLionel Sambuc unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size();
256f4a2713aSLionel Sambuc unsigned ReadIdx = 0, ReadN = ReadFeatures.size();
257f4a2713aSLionel Sambuc while (ExistingIdx < ExistingN && ReadIdx < ReadN) {
258f4a2713aSLionel Sambuc if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) {
259f4a2713aSLionel Sambuc ++ExistingIdx;
260f4a2713aSLionel Sambuc ++ReadIdx;
261f4a2713aSLionel Sambuc continue;
262f4a2713aSLionel Sambuc }
263f4a2713aSLionel Sambuc
264f4a2713aSLionel Sambuc if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) {
265f4a2713aSLionel Sambuc if (Diags)
266f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_targetopt_feature_mismatch)
267f4a2713aSLionel Sambuc << false << ReadFeatures[ReadIdx];
268f4a2713aSLionel Sambuc return true;
269f4a2713aSLionel Sambuc }
270f4a2713aSLionel Sambuc
271f4a2713aSLionel Sambuc if (Diags)
272f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_targetopt_feature_mismatch)
273f4a2713aSLionel Sambuc << true << ExistingFeatures[ExistingIdx];
274f4a2713aSLionel Sambuc return true;
275f4a2713aSLionel Sambuc }
276f4a2713aSLionel Sambuc
277f4a2713aSLionel Sambuc if (ExistingIdx < ExistingN) {
278f4a2713aSLionel Sambuc if (Diags)
279f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_targetopt_feature_mismatch)
280f4a2713aSLionel Sambuc << true << ExistingFeatures[ExistingIdx];
281f4a2713aSLionel Sambuc return true;
282f4a2713aSLionel Sambuc }
283f4a2713aSLionel Sambuc
284f4a2713aSLionel Sambuc if (ReadIdx < ReadN) {
285f4a2713aSLionel Sambuc if (Diags)
286f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_targetopt_feature_mismatch)
287f4a2713aSLionel Sambuc << false << ReadFeatures[ReadIdx];
288f4a2713aSLionel Sambuc return true;
289f4a2713aSLionel Sambuc }
290f4a2713aSLionel Sambuc
291f4a2713aSLionel Sambuc return false;
292f4a2713aSLionel Sambuc }
293f4a2713aSLionel Sambuc
294f4a2713aSLionel Sambuc bool
ReadLanguageOptions(const LangOptions & LangOpts,bool Complain,bool AllowCompatibleDifferences)295f4a2713aSLionel Sambuc PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,
296*0a6a1f1dSLionel Sambuc bool Complain,
297*0a6a1f1dSLionel Sambuc bool AllowCompatibleDifferences) {
298f4a2713aSLionel Sambuc const LangOptions &ExistingLangOpts = PP.getLangOpts();
299f4a2713aSLionel Sambuc return checkLanguageOptions(LangOpts, ExistingLangOpts,
300*0a6a1f1dSLionel Sambuc Complain ? &Reader.Diags : nullptr,
301*0a6a1f1dSLionel Sambuc AllowCompatibleDifferences);
302f4a2713aSLionel Sambuc }
303f4a2713aSLionel Sambuc
ReadTargetOptions(const TargetOptions & TargetOpts,bool Complain)304f4a2713aSLionel Sambuc bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
305f4a2713aSLionel Sambuc bool Complain) {
306f4a2713aSLionel Sambuc const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
307f4a2713aSLionel Sambuc return checkTargetOptions(TargetOpts, ExistingTargetOpts,
308*0a6a1f1dSLionel Sambuc Complain? &Reader.Diags : nullptr);
309f4a2713aSLionel Sambuc }
310f4a2713aSLionel Sambuc
311f4a2713aSLionel Sambuc namespace {
312f4a2713aSLionel Sambuc typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >
313f4a2713aSLionel Sambuc MacroDefinitionsMap;
314f4a2713aSLionel Sambuc typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> >
315f4a2713aSLionel Sambuc DeclsMap;
316f4a2713aSLionel Sambuc }
317f4a2713aSLionel Sambuc
checkDiagnosticGroupMappings(DiagnosticsEngine & StoredDiags,DiagnosticsEngine & Diags,bool Complain)318*0a6a1f1dSLionel Sambuc static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
319*0a6a1f1dSLionel Sambuc DiagnosticsEngine &Diags,
320*0a6a1f1dSLionel Sambuc bool Complain) {
321*0a6a1f1dSLionel Sambuc typedef DiagnosticsEngine::Level Level;
322*0a6a1f1dSLionel Sambuc
323*0a6a1f1dSLionel Sambuc // Check current mappings for new -Werror mappings, and the stored mappings
324*0a6a1f1dSLionel Sambuc // for cases that were explicitly mapped to *not* be errors that are now
325*0a6a1f1dSLionel Sambuc // errors because of options like -Werror.
326*0a6a1f1dSLionel Sambuc DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
327*0a6a1f1dSLionel Sambuc
328*0a6a1f1dSLionel Sambuc for (DiagnosticsEngine *MappingSource : MappingSources) {
329*0a6a1f1dSLionel Sambuc for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
330*0a6a1f1dSLionel Sambuc diag::kind DiagID = DiagIDMappingPair.first;
331*0a6a1f1dSLionel Sambuc Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
332*0a6a1f1dSLionel Sambuc if (CurLevel < DiagnosticsEngine::Error)
333*0a6a1f1dSLionel Sambuc continue; // not significant
334*0a6a1f1dSLionel Sambuc Level StoredLevel =
335*0a6a1f1dSLionel Sambuc StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
336*0a6a1f1dSLionel Sambuc if (StoredLevel < DiagnosticsEngine::Error) {
337*0a6a1f1dSLionel Sambuc if (Complain)
338*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
339*0a6a1f1dSLionel Sambuc Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
340*0a6a1f1dSLionel Sambuc return true;
341*0a6a1f1dSLionel Sambuc }
342*0a6a1f1dSLionel Sambuc }
343*0a6a1f1dSLionel Sambuc }
344*0a6a1f1dSLionel Sambuc
345*0a6a1f1dSLionel Sambuc return false;
346*0a6a1f1dSLionel Sambuc }
347*0a6a1f1dSLionel Sambuc
isExtHandlingFromDiagsError(DiagnosticsEngine & Diags)348*0a6a1f1dSLionel Sambuc static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
349*0a6a1f1dSLionel Sambuc diag::Severity Ext = Diags.getExtensionHandlingBehavior();
350*0a6a1f1dSLionel Sambuc if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors())
351*0a6a1f1dSLionel Sambuc return true;
352*0a6a1f1dSLionel Sambuc return Ext >= diag::Severity::Error;
353*0a6a1f1dSLionel Sambuc }
354*0a6a1f1dSLionel Sambuc
checkDiagnosticMappings(DiagnosticsEngine & StoredDiags,DiagnosticsEngine & Diags,bool IsSystem,bool Complain)355*0a6a1f1dSLionel Sambuc static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
356*0a6a1f1dSLionel Sambuc DiagnosticsEngine &Diags,
357*0a6a1f1dSLionel Sambuc bool IsSystem, bool Complain) {
358*0a6a1f1dSLionel Sambuc // Top-level options
359*0a6a1f1dSLionel Sambuc if (IsSystem) {
360*0a6a1f1dSLionel Sambuc if (Diags.getSuppressSystemWarnings())
361*0a6a1f1dSLionel Sambuc return false;
362*0a6a1f1dSLionel Sambuc // If -Wsystem-headers was not enabled before, be conservative
363*0a6a1f1dSLionel Sambuc if (StoredDiags.getSuppressSystemWarnings()) {
364*0a6a1f1dSLionel Sambuc if (Complain)
365*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
366*0a6a1f1dSLionel Sambuc return true;
367*0a6a1f1dSLionel Sambuc }
368*0a6a1f1dSLionel Sambuc }
369*0a6a1f1dSLionel Sambuc
370*0a6a1f1dSLionel Sambuc if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
371*0a6a1f1dSLionel Sambuc if (Complain)
372*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
373*0a6a1f1dSLionel Sambuc return true;
374*0a6a1f1dSLionel Sambuc }
375*0a6a1f1dSLionel Sambuc
376*0a6a1f1dSLionel Sambuc if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
377*0a6a1f1dSLionel Sambuc !StoredDiags.getEnableAllWarnings()) {
378*0a6a1f1dSLionel Sambuc if (Complain)
379*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
380*0a6a1f1dSLionel Sambuc return true;
381*0a6a1f1dSLionel Sambuc }
382*0a6a1f1dSLionel Sambuc
383*0a6a1f1dSLionel Sambuc if (isExtHandlingFromDiagsError(Diags) &&
384*0a6a1f1dSLionel Sambuc !isExtHandlingFromDiagsError(StoredDiags)) {
385*0a6a1f1dSLionel Sambuc if (Complain)
386*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
387*0a6a1f1dSLionel Sambuc return true;
388*0a6a1f1dSLionel Sambuc }
389*0a6a1f1dSLionel Sambuc
390*0a6a1f1dSLionel Sambuc return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
391*0a6a1f1dSLionel Sambuc }
392*0a6a1f1dSLionel Sambuc
ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,bool Complain)393*0a6a1f1dSLionel Sambuc bool PCHValidator::ReadDiagnosticOptions(
394*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
395*0a6a1f1dSLionel Sambuc DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
396*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
397*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
398*0a6a1f1dSLionel Sambuc new DiagnosticsEngine(DiagIDs, DiagOpts.get()));
399*0a6a1f1dSLionel Sambuc // This should never fail, because we would have processed these options
400*0a6a1f1dSLionel Sambuc // before writing them to an ASTFile.
401*0a6a1f1dSLionel Sambuc ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
402*0a6a1f1dSLionel Sambuc
403*0a6a1f1dSLionel Sambuc ModuleManager &ModuleMgr = Reader.getModuleManager();
404*0a6a1f1dSLionel Sambuc assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
405*0a6a1f1dSLionel Sambuc
406*0a6a1f1dSLionel Sambuc // If the original import came from a file explicitly generated by the user,
407*0a6a1f1dSLionel Sambuc // don't check the diagnostic mappings.
408*0a6a1f1dSLionel Sambuc // FIXME: currently this is approximated by checking whether this is not a
409*0a6a1f1dSLionel Sambuc // module import of an implicitly-loaded module file.
410*0a6a1f1dSLionel Sambuc // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
411*0a6a1f1dSLionel Sambuc // the transitive closure of its imports, since unrelated modules cannot be
412*0a6a1f1dSLionel Sambuc // imported until after this module finishes validation.
413*0a6a1f1dSLionel Sambuc ModuleFile *TopImport = *ModuleMgr.rbegin();
414*0a6a1f1dSLionel Sambuc while (!TopImport->ImportedBy.empty())
415*0a6a1f1dSLionel Sambuc TopImport = TopImport->ImportedBy[0];
416*0a6a1f1dSLionel Sambuc if (TopImport->Kind != MK_ImplicitModule)
417*0a6a1f1dSLionel Sambuc return false;
418*0a6a1f1dSLionel Sambuc
419*0a6a1f1dSLionel Sambuc StringRef ModuleName = TopImport->ModuleName;
420*0a6a1f1dSLionel Sambuc assert(!ModuleName.empty() && "diagnostic options read before module name");
421*0a6a1f1dSLionel Sambuc
422*0a6a1f1dSLionel Sambuc Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
423*0a6a1f1dSLionel Sambuc assert(M && "missing module");
424*0a6a1f1dSLionel Sambuc
425*0a6a1f1dSLionel Sambuc // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
426*0a6a1f1dSLionel Sambuc // contains the union of their flags.
427*0a6a1f1dSLionel Sambuc return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
428*0a6a1f1dSLionel Sambuc }
429*0a6a1f1dSLionel Sambuc
430f4a2713aSLionel Sambuc /// \brief Collect the macro definitions provided by the given preprocessor
431f4a2713aSLionel Sambuc /// options.
432*0a6a1f1dSLionel Sambuc static void
collectMacroDefinitions(const PreprocessorOptions & PPOpts,MacroDefinitionsMap & Macros,SmallVectorImpl<StringRef> * MacroNames=nullptr)433*0a6a1f1dSLionel Sambuc collectMacroDefinitions(const PreprocessorOptions &PPOpts,
434f4a2713aSLionel Sambuc MacroDefinitionsMap &Macros,
435*0a6a1f1dSLionel Sambuc SmallVectorImpl<StringRef> *MacroNames = nullptr) {
436f4a2713aSLionel Sambuc for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
437f4a2713aSLionel Sambuc StringRef Macro = PPOpts.Macros[I].first;
438f4a2713aSLionel Sambuc bool IsUndef = PPOpts.Macros[I].second;
439f4a2713aSLionel Sambuc
440f4a2713aSLionel Sambuc std::pair<StringRef, StringRef> MacroPair = Macro.split('=');
441f4a2713aSLionel Sambuc StringRef MacroName = MacroPair.first;
442f4a2713aSLionel Sambuc StringRef MacroBody = MacroPair.second;
443f4a2713aSLionel Sambuc
444f4a2713aSLionel Sambuc // For an #undef'd macro, we only care about the name.
445f4a2713aSLionel Sambuc if (IsUndef) {
446f4a2713aSLionel Sambuc if (MacroNames && !Macros.count(MacroName))
447f4a2713aSLionel Sambuc MacroNames->push_back(MacroName);
448f4a2713aSLionel Sambuc
449f4a2713aSLionel Sambuc Macros[MacroName] = std::make_pair("", true);
450f4a2713aSLionel Sambuc continue;
451f4a2713aSLionel Sambuc }
452f4a2713aSLionel Sambuc
453f4a2713aSLionel Sambuc // For a #define'd macro, figure out the actual definition.
454f4a2713aSLionel Sambuc if (MacroName.size() == Macro.size())
455f4a2713aSLionel Sambuc MacroBody = "1";
456f4a2713aSLionel Sambuc else {
457f4a2713aSLionel Sambuc // Note: GCC drops anything following an end-of-line character.
458f4a2713aSLionel Sambuc StringRef::size_type End = MacroBody.find_first_of("\n\r");
459f4a2713aSLionel Sambuc MacroBody = MacroBody.substr(0, End);
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc
462f4a2713aSLionel Sambuc if (MacroNames && !Macros.count(MacroName))
463f4a2713aSLionel Sambuc MacroNames->push_back(MacroName);
464f4a2713aSLionel Sambuc Macros[MacroName] = std::make_pair(MacroBody, false);
465f4a2713aSLionel Sambuc }
466f4a2713aSLionel Sambuc }
467f4a2713aSLionel Sambuc
468f4a2713aSLionel Sambuc /// \brief Check the preprocessor options deserialized from the control block
469f4a2713aSLionel Sambuc /// against the preprocessor options in an existing preprocessor.
470f4a2713aSLionel Sambuc ///
471f4a2713aSLionel Sambuc /// \param Diags If non-null, produce diagnostics for any mismatches incurred.
checkPreprocessorOptions(const PreprocessorOptions & PPOpts,const PreprocessorOptions & ExistingPPOpts,DiagnosticsEngine * Diags,FileManager & FileMgr,std::string & SuggestedPredefines,const LangOptions & LangOpts)472f4a2713aSLionel Sambuc static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
473f4a2713aSLionel Sambuc const PreprocessorOptions &ExistingPPOpts,
474f4a2713aSLionel Sambuc DiagnosticsEngine *Diags,
475f4a2713aSLionel Sambuc FileManager &FileMgr,
476f4a2713aSLionel Sambuc std::string &SuggestedPredefines,
477f4a2713aSLionel Sambuc const LangOptions &LangOpts) {
478f4a2713aSLionel Sambuc // Check macro definitions.
479f4a2713aSLionel Sambuc MacroDefinitionsMap ASTFileMacros;
480f4a2713aSLionel Sambuc collectMacroDefinitions(PPOpts, ASTFileMacros);
481f4a2713aSLionel Sambuc MacroDefinitionsMap ExistingMacros;
482f4a2713aSLionel Sambuc SmallVector<StringRef, 4> ExistingMacroNames;
483f4a2713aSLionel Sambuc collectMacroDefinitions(ExistingPPOpts, ExistingMacros, &ExistingMacroNames);
484f4a2713aSLionel Sambuc
485f4a2713aSLionel Sambuc for (unsigned I = 0, N = ExistingMacroNames.size(); I != N; ++I) {
486f4a2713aSLionel Sambuc // Dig out the macro definition in the existing preprocessor options.
487f4a2713aSLionel Sambuc StringRef MacroName = ExistingMacroNames[I];
488f4a2713aSLionel Sambuc std::pair<StringRef, bool> Existing = ExistingMacros[MacroName];
489f4a2713aSLionel Sambuc
490f4a2713aSLionel Sambuc // Check whether we know anything about this macro name or not.
491f4a2713aSLionel Sambuc llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known
492f4a2713aSLionel Sambuc = ASTFileMacros.find(MacroName);
493f4a2713aSLionel Sambuc if (Known == ASTFileMacros.end()) {
494f4a2713aSLionel Sambuc // FIXME: Check whether this identifier was referenced anywhere in the
495f4a2713aSLionel Sambuc // AST file. If so, we should reject the AST file. Unfortunately, this
496f4a2713aSLionel Sambuc // information isn't in the control block. What shall we do about it?
497f4a2713aSLionel Sambuc
498f4a2713aSLionel Sambuc if (Existing.second) {
499f4a2713aSLionel Sambuc SuggestedPredefines += "#undef ";
500f4a2713aSLionel Sambuc SuggestedPredefines += MacroName.str();
501f4a2713aSLionel Sambuc SuggestedPredefines += '\n';
502f4a2713aSLionel Sambuc } else {
503f4a2713aSLionel Sambuc SuggestedPredefines += "#define ";
504f4a2713aSLionel Sambuc SuggestedPredefines += MacroName.str();
505f4a2713aSLionel Sambuc SuggestedPredefines += ' ';
506f4a2713aSLionel Sambuc SuggestedPredefines += Existing.first.str();
507f4a2713aSLionel Sambuc SuggestedPredefines += '\n';
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc continue;
510f4a2713aSLionel Sambuc }
511f4a2713aSLionel Sambuc
512f4a2713aSLionel Sambuc // If the macro was defined in one but undef'd in the other, we have a
513f4a2713aSLionel Sambuc // conflict.
514f4a2713aSLionel Sambuc if (Existing.second != Known->second.second) {
515f4a2713aSLionel Sambuc if (Diags) {
516f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_macro_def_undef)
517f4a2713aSLionel Sambuc << MacroName << Known->second.second;
518f4a2713aSLionel Sambuc }
519f4a2713aSLionel Sambuc return true;
520f4a2713aSLionel Sambuc }
521f4a2713aSLionel Sambuc
522f4a2713aSLionel Sambuc // If the macro was #undef'd in both, or if the macro bodies are identical,
523f4a2713aSLionel Sambuc // it's fine.
524f4a2713aSLionel Sambuc if (Existing.second || Existing.first == Known->second.first)
525f4a2713aSLionel Sambuc continue;
526f4a2713aSLionel Sambuc
527f4a2713aSLionel Sambuc // The macro bodies differ; complain.
528f4a2713aSLionel Sambuc if (Diags) {
529f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_macro_def_conflict)
530f4a2713aSLionel Sambuc << MacroName << Known->second.first << Existing.first;
531f4a2713aSLionel Sambuc }
532f4a2713aSLionel Sambuc return true;
533f4a2713aSLionel Sambuc }
534f4a2713aSLionel Sambuc
535f4a2713aSLionel Sambuc // Check whether we're using predefines.
536f4a2713aSLionel Sambuc if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines) {
537f4a2713aSLionel Sambuc if (Diags) {
538f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;
539f4a2713aSLionel Sambuc }
540f4a2713aSLionel Sambuc return true;
541f4a2713aSLionel Sambuc }
542f4a2713aSLionel Sambuc
543f4a2713aSLionel Sambuc // Detailed record is important since it is used for the module cache hash.
544f4a2713aSLionel Sambuc if (LangOpts.Modules &&
545f4a2713aSLionel Sambuc PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) {
546f4a2713aSLionel Sambuc if (Diags) {
547f4a2713aSLionel Sambuc Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
548f4a2713aSLionel Sambuc }
549f4a2713aSLionel Sambuc return true;
550f4a2713aSLionel Sambuc }
551f4a2713aSLionel Sambuc
552f4a2713aSLionel Sambuc // Compute the #include and #include_macros lines we need.
553f4a2713aSLionel Sambuc for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {
554f4a2713aSLionel Sambuc StringRef File = ExistingPPOpts.Includes[I];
555f4a2713aSLionel Sambuc if (File == ExistingPPOpts.ImplicitPCHInclude)
556f4a2713aSLionel Sambuc continue;
557f4a2713aSLionel Sambuc
558f4a2713aSLionel Sambuc if (std::find(PPOpts.Includes.begin(), PPOpts.Includes.end(), File)
559f4a2713aSLionel Sambuc != PPOpts.Includes.end())
560f4a2713aSLionel Sambuc continue;
561f4a2713aSLionel Sambuc
562f4a2713aSLionel Sambuc SuggestedPredefines += "#include \"";
563*0a6a1f1dSLionel Sambuc SuggestedPredefines += File;
564f4a2713aSLionel Sambuc SuggestedPredefines += "\"\n";
565f4a2713aSLionel Sambuc }
566f4a2713aSLionel Sambuc
567f4a2713aSLionel Sambuc for (unsigned I = 0, N = ExistingPPOpts.MacroIncludes.size(); I != N; ++I) {
568f4a2713aSLionel Sambuc StringRef File = ExistingPPOpts.MacroIncludes[I];
569f4a2713aSLionel Sambuc if (std::find(PPOpts.MacroIncludes.begin(), PPOpts.MacroIncludes.end(),
570f4a2713aSLionel Sambuc File)
571f4a2713aSLionel Sambuc != PPOpts.MacroIncludes.end())
572f4a2713aSLionel Sambuc continue;
573f4a2713aSLionel Sambuc
574f4a2713aSLionel Sambuc SuggestedPredefines += "#__include_macros \"";
575*0a6a1f1dSLionel Sambuc SuggestedPredefines += File;
576f4a2713aSLionel Sambuc SuggestedPredefines += "\"\n##\n";
577f4a2713aSLionel Sambuc }
578f4a2713aSLionel Sambuc
579f4a2713aSLionel Sambuc return false;
580f4a2713aSLionel Sambuc }
581f4a2713aSLionel Sambuc
ReadPreprocessorOptions(const PreprocessorOptions & PPOpts,bool Complain,std::string & SuggestedPredefines)582f4a2713aSLionel Sambuc bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
583f4a2713aSLionel Sambuc bool Complain,
584f4a2713aSLionel Sambuc std::string &SuggestedPredefines) {
585f4a2713aSLionel Sambuc const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();
586f4a2713aSLionel Sambuc
587f4a2713aSLionel Sambuc return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
588*0a6a1f1dSLionel Sambuc Complain? &Reader.Diags : nullptr,
589f4a2713aSLionel Sambuc PP.getFileManager(),
590f4a2713aSLionel Sambuc SuggestedPredefines,
591f4a2713aSLionel Sambuc PP.getLangOpts());
592f4a2713aSLionel Sambuc }
593f4a2713aSLionel Sambuc
ReadCounter(const ModuleFile & M,unsigned Value)594f4a2713aSLionel Sambuc void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {
595f4a2713aSLionel Sambuc PP.setCounterValue(Value);
596f4a2713aSLionel Sambuc }
597f4a2713aSLionel Sambuc
598f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
599f4a2713aSLionel Sambuc // AST reader implementation
600f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
601f4a2713aSLionel Sambuc
setDeserializationListener(ASTDeserializationListener * Listener,bool TakeOwnership)602*0a6a1f1dSLionel Sambuc void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
603*0a6a1f1dSLionel Sambuc bool TakeOwnership) {
604f4a2713aSLionel Sambuc DeserializationListener = Listener;
605*0a6a1f1dSLionel Sambuc OwnsDeserializationListener = TakeOwnership;
606f4a2713aSLionel Sambuc }
607f4a2713aSLionel Sambuc
608f4a2713aSLionel Sambuc
609f4a2713aSLionel Sambuc
ComputeHash(Selector Sel)610f4a2713aSLionel Sambuc unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
611f4a2713aSLionel Sambuc return serialization::ComputeHash(Sel);
612f4a2713aSLionel Sambuc }
613f4a2713aSLionel Sambuc
614f4a2713aSLionel Sambuc
615f4a2713aSLionel Sambuc std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char * & d)616f4a2713aSLionel Sambuc ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
617*0a6a1f1dSLionel Sambuc using namespace llvm::support;
618*0a6a1f1dSLionel Sambuc unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
619*0a6a1f1dSLionel Sambuc unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
620f4a2713aSLionel Sambuc return std::make_pair(KeyLen, DataLen);
621f4a2713aSLionel Sambuc }
622f4a2713aSLionel Sambuc
623f4a2713aSLionel Sambuc ASTSelectorLookupTrait::internal_key_type
ReadKey(const unsigned char * d,unsigned)624f4a2713aSLionel Sambuc ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
625*0a6a1f1dSLionel Sambuc using namespace llvm::support;
626f4a2713aSLionel Sambuc SelectorTable &SelTable = Reader.getContext().Selectors;
627*0a6a1f1dSLionel Sambuc unsigned N = endian::readNext<uint16_t, little, unaligned>(d);
628*0a6a1f1dSLionel Sambuc IdentifierInfo *FirstII = Reader.getLocalIdentifier(
629*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d));
630f4a2713aSLionel Sambuc if (N == 0)
631f4a2713aSLionel Sambuc return SelTable.getNullarySelector(FirstII);
632f4a2713aSLionel Sambuc else if (N == 1)
633f4a2713aSLionel Sambuc return SelTable.getUnarySelector(FirstII);
634f4a2713aSLionel Sambuc
635f4a2713aSLionel Sambuc SmallVector<IdentifierInfo *, 16> Args;
636f4a2713aSLionel Sambuc Args.push_back(FirstII);
637f4a2713aSLionel Sambuc for (unsigned I = 1; I != N; ++I)
638*0a6a1f1dSLionel Sambuc Args.push_back(Reader.getLocalIdentifier(
639*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d)));
640f4a2713aSLionel Sambuc
641f4a2713aSLionel Sambuc return SelTable.getSelector(N, Args.data());
642f4a2713aSLionel Sambuc }
643f4a2713aSLionel Sambuc
644f4a2713aSLionel Sambuc ASTSelectorLookupTrait::data_type
ReadData(Selector,const unsigned char * d,unsigned DataLen)645f4a2713aSLionel Sambuc ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
646f4a2713aSLionel Sambuc unsigned DataLen) {
647*0a6a1f1dSLionel Sambuc using namespace llvm::support;
648f4a2713aSLionel Sambuc
649f4a2713aSLionel Sambuc data_type Result;
650f4a2713aSLionel Sambuc
651*0a6a1f1dSLionel Sambuc Result.ID = Reader.getGlobalSelectorID(
652*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d));
653*0a6a1f1dSLionel Sambuc unsigned FullInstanceBits = endian::readNext<uint16_t, little, unaligned>(d);
654*0a6a1f1dSLionel Sambuc unsigned FullFactoryBits = endian::readNext<uint16_t, little, unaligned>(d);
655*0a6a1f1dSLionel Sambuc Result.InstanceBits = FullInstanceBits & 0x3;
656*0a6a1f1dSLionel Sambuc Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1;
657*0a6a1f1dSLionel Sambuc Result.FactoryBits = FullFactoryBits & 0x3;
658*0a6a1f1dSLionel Sambuc Result.FactoryHasMoreThanOneDecl = (FullFactoryBits >> 2) & 0x1;
659*0a6a1f1dSLionel Sambuc unsigned NumInstanceMethods = FullInstanceBits >> 3;
660*0a6a1f1dSLionel Sambuc unsigned NumFactoryMethods = FullFactoryBits >> 3;
661f4a2713aSLionel Sambuc
662f4a2713aSLionel Sambuc // Load instance methods
663f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumInstanceMethods; ++I) {
664*0a6a1f1dSLionel Sambuc if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
665*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d)))
666f4a2713aSLionel Sambuc Result.Instance.push_back(Method);
667f4a2713aSLionel Sambuc }
668f4a2713aSLionel Sambuc
669f4a2713aSLionel Sambuc // Load factory methods
670f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumFactoryMethods; ++I) {
671*0a6a1f1dSLionel Sambuc if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
672*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d)))
673f4a2713aSLionel Sambuc Result.Factory.push_back(Method);
674f4a2713aSLionel Sambuc }
675f4a2713aSLionel Sambuc
676f4a2713aSLionel Sambuc return Result;
677f4a2713aSLionel Sambuc }
678f4a2713aSLionel Sambuc
ComputeHash(const internal_key_type & a)679f4a2713aSLionel Sambuc unsigned ASTIdentifierLookupTraitBase::ComputeHash(const internal_key_type& a) {
680f4a2713aSLionel Sambuc return llvm::HashString(a);
681f4a2713aSLionel Sambuc }
682f4a2713aSLionel Sambuc
683f4a2713aSLionel Sambuc std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char * & d)684f4a2713aSLionel Sambuc ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) {
685*0a6a1f1dSLionel Sambuc using namespace llvm::support;
686*0a6a1f1dSLionel Sambuc unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
687*0a6a1f1dSLionel Sambuc unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
688f4a2713aSLionel Sambuc return std::make_pair(KeyLen, DataLen);
689f4a2713aSLionel Sambuc }
690f4a2713aSLionel Sambuc
691f4a2713aSLionel Sambuc ASTIdentifierLookupTraitBase::internal_key_type
ReadKey(const unsigned char * d,unsigned n)692f4a2713aSLionel Sambuc ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
693f4a2713aSLionel Sambuc assert(n >= 2 && d[n-1] == '\0');
694f4a2713aSLionel Sambuc return StringRef((const char*) d, n-1);
695f4a2713aSLionel Sambuc }
696f4a2713aSLionel Sambuc
697f4a2713aSLionel Sambuc /// \brief Whether the given identifier is "interesting".
isInterestingIdentifier(IdentifierInfo & II)698f4a2713aSLionel Sambuc static bool isInterestingIdentifier(IdentifierInfo &II) {
699f4a2713aSLionel Sambuc return II.isPoisoned() ||
700f4a2713aSLionel Sambuc II.isExtensionToken() ||
701f4a2713aSLionel Sambuc II.getObjCOrBuiltinID() ||
702f4a2713aSLionel Sambuc II.hasRevertedTokenIDToIdentifier() ||
703f4a2713aSLionel Sambuc II.hadMacroDefinition() ||
704f4a2713aSLionel Sambuc II.getFETokenInfo<void>();
705f4a2713aSLionel Sambuc }
706f4a2713aSLionel Sambuc
ReadData(const internal_key_type & k,const unsigned char * d,unsigned DataLen)707f4a2713aSLionel Sambuc IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
708f4a2713aSLionel Sambuc const unsigned char* d,
709f4a2713aSLionel Sambuc unsigned DataLen) {
710*0a6a1f1dSLionel Sambuc using namespace llvm::support;
711*0a6a1f1dSLionel Sambuc unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
712f4a2713aSLionel Sambuc bool IsInteresting = RawID & 0x01;
713f4a2713aSLionel Sambuc
714f4a2713aSLionel Sambuc // Wipe out the "is interesting" bit.
715f4a2713aSLionel Sambuc RawID = RawID >> 1;
716f4a2713aSLionel Sambuc
717f4a2713aSLionel Sambuc IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
718f4a2713aSLionel Sambuc if (!IsInteresting) {
719f4a2713aSLionel Sambuc // For uninteresting identifiers, just build the IdentifierInfo
720f4a2713aSLionel Sambuc // and associate it with the persistent ID.
721f4a2713aSLionel Sambuc IdentifierInfo *II = KnownII;
722f4a2713aSLionel Sambuc if (!II) {
723f4a2713aSLionel Sambuc II = &Reader.getIdentifierTable().getOwn(k);
724f4a2713aSLionel Sambuc KnownII = II;
725f4a2713aSLionel Sambuc }
726f4a2713aSLionel Sambuc Reader.SetIdentifierInfo(ID, II);
727f4a2713aSLionel Sambuc if (!II->isFromAST()) {
728f4a2713aSLionel Sambuc bool WasInteresting = isInterestingIdentifier(*II);
729f4a2713aSLionel Sambuc II->setIsFromAST();
730f4a2713aSLionel Sambuc if (WasInteresting)
731f4a2713aSLionel Sambuc II->setChangedSinceDeserialization();
732f4a2713aSLionel Sambuc }
733f4a2713aSLionel Sambuc Reader.markIdentifierUpToDate(II);
734f4a2713aSLionel Sambuc return II;
735f4a2713aSLionel Sambuc }
736f4a2713aSLionel Sambuc
737*0a6a1f1dSLionel Sambuc unsigned ObjCOrBuiltinID = endian::readNext<uint16_t, little, unaligned>(d);
738*0a6a1f1dSLionel Sambuc unsigned Bits = endian::readNext<uint16_t, little, unaligned>(d);
739f4a2713aSLionel Sambuc bool CPlusPlusOperatorKeyword = Bits & 0x01;
740f4a2713aSLionel Sambuc Bits >>= 1;
741f4a2713aSLionel Sambuc bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
742f4a2713aSLionel Sambuc Bits >>= 1;
743f4a2713aSLionel Sambuc bool Poisoned = Bits & 0x01;
744f4a2713aSLionel Sambuc Bits >>= 1;
745f4a2713aSLionel Sambuc bool ExtensionToken = Bits & 0x01;
746f4a2713aSLionel Sambuc Bits >>= 1;
747f4a2713aSLionel Sambuc bool hasSubmoduleMacros = Bits & 0x01;
748f4a2713aSLionel Sambuc Bits >>= 1;
749f4a2713aSLionel Sambuc bool hadMacroDefinition = Bits & 0x01;
750f4a2713aSLionel Sambuc Bits >>= 1;
751f4a2713aSLionel Sambuc
752f4a2713aSLionel Sambuc assert(Bits == 0 && "Extra bits in the identifier?");
753f4a2713aSLionel Sambuc DataLen -= 8;
754f4a2713aSLionel Sambuc
755f4a2713aSLionel Sambuc // Build the IdentifierInfo itself and link the identifier ID with
756f4a2713aSLionel Sambuc // the new IdentifierInfo.
757f4a2713aSLionel Sambuc IdentifierInfo *II = KnownII;
758f4a2713aSLionel Sambuc if (!II) {
759f4a2713aSLionel Sambuc II = &Reader.getIdentifierTable().getOwn(StringRef(k));
760f4a2713aSLionel Sambuc KnownII = II;
761f4a2713aSLionel Sambuc }
762f4a2713aSLionel Sambuc Reader.markIdentifierUpToDate(II);
763f4a2713aSLionel Sambuc if (!II->isFromAST()) {
764f4a2713aSLionel Sambuc bool WasInteresting = isInterestingIdentifier(*II);
765f4a2713aSLionel Sambuc II->setIsFromAST();
766f4a2713aSLionel Sambuc if (WasInteresting)
767f4a2713aSLionel Sambuc II->setChangedSinceDeserialization();
768f4a2713aSLionel Sambuc }
769f4a2713aSLionel Sambuc
770f4a2713aSLionel Sambuc // Set or check the various bits in the IdentifierInfo structure.
771f4a2713aSLionel Sambuc // Token IDs are read-only.
772f4a2713aSLionel Sambuc if (HasRevertedTokenIDToIdentifier && II->getTokenID() != tok::identifier)
773f4a2713aSLionel Sambuc II->RevertTokenIDToIdentifier();
774f4a2713aSLionel Sambuc II->setObjCOrBuiltinID(ObjCOrBuiltinID);
775f4a2713aSLionel Sambuc assert(II->isExtensionToken() == ExtensionToken &&
776f4a2713aSLionel Sambuc "Incorrect extension token flag");
777f4a2713aSLionel Sambuc (void)ExtensionToken;
778f4a2713aSLionel Sambuc if (Poisoned)
779f4a2713aSLionel Sambuc II->setIsPoisoned(true);
780f4a2713aSLionel Sambuc assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
781f4a2713aSLionel Sambuc "Incorrect C++ operator keyword flag");
782f4a2713aSLionel Sambuc (void)CPlusPlusOperatorKeyword;
783f4a2713aSLionel Sambuc
784f4a2713aSLionel Sambuc // If this identifier is a macro, deserialize the macro
785f4a2713aSLionel Sambuc // definition.
786f4a2713aSLionel Sambuc if (hadMacroDefinition) {
787*0a6a1f1dSLionel Sambuc uint32_t MacroDirectivesOffset =
788*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(d);
789f4a2713aSLionel Sambuc DataLen -= 4;
790f4a2713aSLionel Sambuc SmallVector<uint32_t, 8> LocalMacroIDs;
791f4a2713aSLionel Sambuc if (hasSubmoduleMacros) {
792*0a6a1f1dSLionel Sambuc while (true) {
793*0a6a1f1dSLionel Sambuc uint32_t LocalMacroID =
794*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(d);
795f4a2713aSLionel Sambuc DataLen -= 4;
796*0a6a1f1dSLionel Sambuc if (LocalMacroID == 0xdeadbeef) break;
797f4a2713aSLionel Sambuc LocalMacroIDs.push_back(LocalMacroID);
798f4a2713aSLionel Sambuc }
799f4a2713aSLionel Sambuc }
800f4a2713aSLionel Sambuc
801*0a6a1f1dSLionel Sambuc if (F.Kind == MK_ImplicitModule || F.Kind == MK_ExplicitModule) {
802*0a6a1f1dSLionel Sambuc // Macro definitions are stored from newest to oldest, so reverse them
803*0a6a1f1dSLionel Sambuc // before registering them.
804*0a6a1f1dSLionel Sambuc llvm::SmallVector<unsigned, 8> MacroSizes;
805f4a2713aSLionel Sambuc for (SmallVectorImpl<uint32_t>::iterator
806*0a6a1f1dSLionel Sambuc I = LocalMacroIDs.begin(), E = LocalMacroIDs.end(); I != E; /**/) {
807*0a6a1f1dSLionel Sambuc unsigned Size = 1;
808*0a6a1f1dSLionel Sambuc
809*0a6a1f1dSLionel Sambuc static const uint32_t HasOverridesFlag = 0x80000000U;
810*0a6a1f1dSLionel Sambuc if (I + 1 != E && (I[1] & HasOverridesFlag))
811*0a6a1f1dSLionel Sambuc Size += 1 + (I[1] & ~HasOverridesFlag);
812*0a6a1f1dSLionel Sambuc
813*0a6a1f1dSLionel Sambuc MacroSizes.push_back(Size);
814*0a6a1f1dSLionel Sambuc I += Size;
815f4a2713aSLionel Sambuc }
816*0a6a1f1dSLionel Sambuc
817*0a6a1f1dSLionel Sambuc SmallVectorImpl<uint32_t>::iterator I = LocalMacroIDs.end();
818*0a6a1f1dSLionel Sambuc for (SmallVectorImpl<unsigned>::reverse_iterator SI = MacroSizes.rbegin(),
819*0a6a1f1dSLionel Sambuc SE = MacroSizes.rend();
820*0a6a1f1dSLionel Sambuc SI != SE; ++SI) {
821*0a6a1f1dSLionel Sambuc I -= *SI;
822*0a6a1f1dSLionel Sambuc
823*0a6a1f1dSLionel Sambuc uint32_t LocalMacroID = *I;
824*0a6a1f1dSLionel Sambuc ArrayRef<uint32_t> Overrides;
825*0a6a1f1dSLionel Sambuc if (*SI != 1)
826*0a6a1f1dSLionel Sambuc Overrides = llvm::makeArrayRef(&I[2], *SI - 2);
827*0a6a1f1dSLionel Sambuc Reader.addPendingMacroFromModule(II, &F, LocalMacroID, Overrides);
828*0a6a1f1dSLionel Sambuc }
829*0a6a1f1dSLionel Sambuc assert(I == LocalMacroIDs.begin());
830f4a2713aSLionel Sambuc } else {
831f4a2713aSLionel Sambuc Reader.addPendingMacroFromPCH(II, &F, MacroDirectivesOffset);
832f4a2713aSLionel Sambuc }
833f4a2713aSLionel Sambuc }
834f4a2713aSLionel Sambuc
835f4a2713aSLionel Sambuc Reader.SetIdentifierInfo(ID, II);
836f4a2713aSLionel Sambuc
837f4a2713aSLionel Sambuc // Read all of the declarations visible at global scope with this
838f4a2713aSLionel Sambuc // name.
839f4a2713aSLionel Sambuc if (DataLen > 0) {
840f4a2713aSLionel Sambuc SmallVector<uint32_t, 4> DeclIDs;
841f4a2713aSLionel Sambuc for (; DataLen > 0; DataLen -= 4)
842*0a6a1f1dSLionel Sambuc DeclIDs.push_back(Reader.getGlobalDeclID(
843*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d)));
844f4a2713aSLionel Sambuc Reader.SetGloballyVisibleDecls(II, DeclIDs);
845f4a2713aSLionel Sambuc }
846f4a2713aSLionel Sambuc
847f4a2713aSLionel Sambuc return II;
848f4a2713aSLionel Sambuc }
849f4a2713aSLionel Sambuc
850f4a2713aSLionel Sambuc unsigned
ComputeHash(const DeclNameKey & Key) const851f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
852f4a2713aSLionel Sambuc llvm::FoldingSetNodeID ID;
853f4a2713aSLionel Sambuc ID.AddInteger(Key.Kind);
854f4a2713aSLionel Sambuc
855f4a2713aSLionel Sambuc switch (Key.Kind) {
856f4a2713aSLionel Sambuc case DeclarationName::Identifier:
857f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
858f4a2713aSLionel Sambuc ID.AddString(((IdentifierInfo*)Key.Data)->getName());
859f4a2713aSLionel Sambuc break;
860f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
861f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
862f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
863f4a2713aSLionel Sambuc ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
864f4a2713aSLionel Sambuc break;
865f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
866f4a2713aSLionel Sambuc ID.AddInteger((OverloadedOperatorKind)Key.Data);
867f4a2713aSLionel Sambuc break;
868f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
869f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
870f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
871f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
872f4a2713aSLionel Sambuc break;
873f4a2713aSLionel Sambuc }
874f4a2713aSLionel Sambuc
875f4a2713aSLionel Sambuc return ID.ComputeHash();
876f4a2713aSLionel Sambuc }
877f4a2713aSLionel Sambuc
878f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::internal_key_type
GetInternalKey(const external_key_type & Name) const879f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::GetInternalKey(
880f4a2713aSLionel Sambuc const external_key_type& Name) const {
881f4a2713aSLionel Sambuc DeclNameKey Key;
882f4a2713aSLionel Sambuc Key.Kind = Name.getNameKind();
883f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
884f4a2713aSLionel Sambuc case DeclarationName::Identifier:
885f4a2713aSLionel Sambuc Key.Data = (uint64_t)Name.getAsIdentifierInfo();
886f4a2713aSLionel Sambuc break;
887f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
888f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
889f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
890f4a2713aSLionel Sambuc Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
891f4a2713aSLionel Sambuc break;
892f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
893f4a2713aSLionel Sambuc Key.Data = Name.getCXXOverloadedOperator();
894f4a2713aSLionel Sambuc break;
895f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
896f4a2713aSLionel Sambuc Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
897f4a2713aSLionel Sambuc break;
898f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
899f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
900f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
901f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
902f4a2713aSLionel Sambuc Key.Data = 0;
903f4a2713aSLionel Sambuc break;
904f4a2713aSLionel Sambuc }
905f4a2713aSLionel Sambuc
906f4a2713aSLionel Sambuc return Key;
907f4a2713aSLionel Sambuc }
908f4a2713aSLionel Sambuc
909f4a2713aSLionel Sambuc std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char * & d)910f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
911*0a6a1f1dSLionel Sambuc using namespace llvm::support;
912*0a6a1f1dSLionel Sambuc unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
913*0a6a1f1dSLionel Sambuc unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
914f4a2713aSLionel Sambuc return std::make_pair(KeyLen, DataLen);
915f4a2713aSLionel Sambuc }
916f4a2713aSLionel Sambuc
917f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::internal_key_type
ReadKey(const unsigned char * d,unsigned)918f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {
919*0a6a1f1dSLionel Sambuc using namespace llvm::support;
920f4a2713aSLionel Sambuc
921f4a2713aSLionel Sambuc DeclNameKey Key;
922f4a2713aSLionel Sambuc Key.Kind = (DeclarationName::NameKind)*d++;
923f4a2713aSLionel Sambuc switch (Key.Kind) {
924f4a2713aSLionel Sambuc case DeclarationName::Identifier:
925*0a6a1f1dSLionel Sambuc Key.Data = (uint64_t)Reader.getLocalIdentifier(
926*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d));
927f4a2713aSLionel Sambuc break;
928f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
929f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
930f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
931f4a2713aSLionel Sambuc Key.Data =
932*0a6a1f1dSLionel Sambuc (uint64_t)Reader.getLocalSelector(
933*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(
934*0a6a1f1dSLionel Sambuc d)).getAsOpaquePtr();
935f4a2713aSLionel Sambuc break;
936f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
937f4a2713aSLionel Sambuc Key.Data = *d++; // OverloadedOperatorKind
938f4a2713aSLionel Sambuc break;
939f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
940*0a6a1f1dSLionel Sambuc Key.Data = (uint64_t)Reader.getLocalIdentifier(
941*0a6a1f1dSLionel Sambuc F, endian::readNext<uint32_t, little, unaligned>(d));
942f4a2713aSLionel Sambuc break;
943f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
944f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
945f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
946f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
947f4a2713aSLionel Sambuc Key.Data = 0;
948f4a2713aSLionel Sambuc break;
949f4a2713aSLionel Sambuc }
950f4a2713aSLionel Sambuc
951f4a2713aSLionel Sambuc return Key;
952f4a2713aSLionel Sambuc }
953f4a2713aSLionel Sambuc
954f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::data_type
ReadData(internal_key_type,const unsigned char * d,unsigned DataLen)955f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::ReadData(internal_key_type,
956f4a2713aSLionel Sambuc const unsigned char* d,
957f4a2713aSLionel Sambuc unsigned DataLen) {
958*0a6a1f1dSLionel Sambuc using namespace llvm::support;
959*0a6a1f1dSLionel Sambuc unsigned NumDecls = endian::readNext<uint16_t, little, unaligned>(d);
960f4a2713aSLionel Sambuc LE32DeclID *Start = reinterpret_cast<LE32DeclID *>(
961f4a2713aSLionel Sambuc const_cast<unsigned char *>(d));
962f4a2713aSLionel Sambuc return std::make_pair(Start, Start + NumDecls);
963f4a2713aSLionel Sambuc }
964f4a2713aSLionel Sambuc
ReadDeclContextStorage(ModuleFile & M,BitstreamCursor & Cursor,const std::pair<uint64_t,uint64_t> & Offsets,DeclContextInfo & Info)965f4a2713aSLionel Sambuc bool ASTReader::ReadDeclContextStorage(ModuleFile &M,
966f4a2713aSLionel Sambuc BitstreamCursor &Cursor,
967f4a2713aSLionel Sambuc const std::pair<uint64_t, uint64_t> &Offsets,
968f4a2713aSLionel Sambuc DeclContextInfo &Info) {
969f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
970f4a2713aSLionel Sambuc // First the lexical decls.
971f4a2713aSLionel Sambuc if (Offsets.first != 0) {
972f4a2713aSLionel Sambuc Cursor.JumpToBit(Offsets.first);
973f4a2713aSLionel Sambuc
974f4a2713aSLionel Sambuc RecordData Record;
975f4a2713aSLionel Sambuc StringRef Blob;
976f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
977f4a2713aSLionel Sambuc unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
978f4a2713aSLionel Sambuc if (RecCode != DECL_CONTEXT_LEXICAL) {
979f4a2713aSLionel Sambuc Error("Expected lexical block");
980f4a2713aSLionel Sambuc return true;
981f4a2713aSLionel Sambuc }
982f4a2713aSLionel Sambuc
983f4a2713aSLionel Sambuc Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob.data());
984f4a2713aSLionel Sambuc Info.NumLexicalDecls = Blob.size() / sizeof(KindDeclIDPair);
985f4a2713aSLionel Sambuc }
986f4a2713aSLionel Sambuc
987f4a2713aSLionel Sambuc // Now the lookup table.
988f4a2713aSLionel Sambuc if (Offsets.second != 0) {
989f4a2713aSLionel Sambuc Cursor.JumpToBit(Offsets.second);
990f4a2713aSLionel Sambuc
991f4a2713aSLionel Sambuc RecordData Record;
992f4a2713aSLionel Sambuc StringRef Blob;
993f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
994f4a2713aSLionel Sambuc unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
995f4a2713aSLionel Sambuc if (RecCode != DECL_CONTEXT_VISIBLE) {
996f4a2713aSLionel Sambuc Error("Expected visible lookup table block");
997f4a2713aSLionel Sambuc return true;
998f4a2713aSLionel Sambuc }
999*0a6a1f1dSLionel Sambuc Info.NameLookupTableData = ASTDeclContextNameLookupTable::Create(
1000f4a2713aSLionel Sambuc (const unsigned char *)Blob.data() + Record[0],
1001*0a6a1f1dSLionel Sambuc (const unsigned char *)Blob.data() + sizeof(uint32_t),
1002f4a2713aSLionel Sambuc (const unsigned char *)Blob.data(),
1003f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait(*this, M));
1004f4a2713aSLionel Sambuc }
1005f4a2713aSLionel Sambuc
1006f4a2713aSLionel Sambuc return false;
1007f4a2713aSLionel Sambuc }
1008f4a2713aSLionel Sambuc
Error(StringRef Msg)1009f4a2713aSLionel Sambuc void ASTReader::Error(StringRef Msg) {
1010f4a2713aSLionel Sambuc Error(diag::err_fe_pch_malformed, Msg);
1011f4a2713aSLionel Sambuc if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) {
1012f4a2713aSLionel Sambuc Diag(diag::note_module_cache_path)
1013f4a2713aSLionel Sambuc << PP.getHeaderSearchInfo().getModuleCachePath();
1014f4a2713aSLionel Sambuc }
1015f4a2713aSLionel Sambuc }
1016f4a2713aSLionel Sambuc
Error(unsigned DiagID,StringRef Arg1,StringRef Arg2)1017f4a2713aSLionel Sambuc void ASTReader::Error(unsigned DiagID,
1018f4a2713aSLionel Sambuc StringRef Arg1, StringRef Arg2) {
1019f4a2713aSLionel Sambuc if (Diags.isDiagnosticInFlight())
1020f4a2713aSLionel Sambuc Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
1021f4a2713aSLionel Sambuc else
1022f4a2713aSLionel Sambuc Diag(DiagID) << Arg1 << Arg2;
1023f4a2713aSLionel Sambuc }
1024f4a2713aSLionel Sambuc
1025f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1026f4a2713aSLionel Sambuc // Source Manager Deserialization
1027f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1028f4a2713aSLionel Sambuc
1029f4a2713aSLionel Sambuc /// \brief Read the line table in the source manager block.
1030f4a2713aSLionel Sambuc /// \returns true if there was an error.
ParseLineTable(ModuleFile & F,const RecordData & Record)1031f4a2713aSLionel Sambuc bool ASTReader::ParseLineTable(ModuleFile &F,
1032*0a6a1f1dSLionel Sambuc const RecordData &Record) {
1033f4a2713aSLionel Sambuc unsigned Idx = 0;
1034f4a2713aSLionel Sambuc LineTableInfo &LineTable = SourceMgr.getLineTable();
1035f4a2713aSLionel Sambuc
1036f4a2713aSLionel Sambuc // Parse the file names
1037f4a2713aSLionel Sambuc std::map<int, int> FileIDs;
1038f4a2713aSLionel Sambuc for (int I = 0, N = Record[Idx++]; I != N; ++I) {
1039f4a2713aSLionel Sambuc // Extract the file name
1040*0a6a1f1dSLionel Sambuc auto Filename = ReadPath(F, Record, Idx);
1041f4a2713aSLionel Sambuc FileIDs[I] = LineTable.getLineTableFilenameID(Filename);
1042f4a2713aSLionel Sambuc }
1043f4a2713aSLionel Sambuc
1044f4a2713aSLionel Sambuc // Parse the line entries
1045f4a2713aSLionel Sambuc std::vector<LineEntry> Entries;
1046f4a2713aSLionel Sambuc while (Idx < Record.size()) {
1047f4a2713aSLionel Sambuc int FID = Record[Idx++];
1048f4a2713aSLionel Sambuc assert(FID >= 0 && "Serialized line entries for non-local file.");
1049f4a2713aSLionel Sambuc // Remap FileID from 1-based old view.
1050f4a2713aSLionel Sambuc FID += F.SLocEntryBaseID - 1;
1051f4a2713aSLionel Sambuc
1052f4a2713aSLionel Sambuc // Extract the line entries
1053f4a2713aSLionel Sambuc unsigned NumEntries = Record[Idx++];
1054f4a2713aSLionel Sambuc assert(NumEntries && "Numentries is 00000");
1055f4a2713aSLionel Sambuc Entries.clear();
1056f4a2713aSLionel Sambuc Entries.reserve(NumEntries);
1057f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumEntries; ++I) {
1058f4a2713aSLionel Sambuc unsigned FileOffset = Record[Idx++];
1059f4a2713aSLionel Sambuc unsigned LineNo = Record[Idx++];
1060f4a2713aSLionel Sambuc int FilenameID = FileIDs[Record[Idx++]];
1061f4a2713aSLionel Sambuc SrcMgr::CharacteristicKind FileKind
1062f4a2713aSLionel Sambuc = (SrcMgr::CharacteristicKind)Record[Idx++];
1063f4a2713aSLionel Sambuc unsigned IncludeOffset = Record[Idx++];
1064f4a2713aSLionel Sambuc Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
1065f4a2713aSLionel Sambuc FileKind, IncludeOffset));
1066f4a2713aSLionel Sambuc }
1067f4a2713aSLionel Sambuc LineTable.AddEntry(FileID::get(FID), Entries);
1068f4a2713aSLionel Sambuc }
1069f4a2713aSLionel Sambuc
1070f4a2713aSLionel Sambuc return false;
1071f4a2713aSLionel Sambuc }
1072f4a2713aSLionel Sambuc
1073f4a2713aSLionel Sambuc /// \brief Read a source manager block
ReadSourceManagerBlock(ModuleFile & F)1074f4a2713aSLionel Sambuc bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
1075f4a2713aSLionel Sambuc using namespace SrcMgr;
1076f4a2713aSLionel Sambuc
1077f4a2713aSLionel Sambuc BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
1078f4a2713aSLionel Sambuc
1079f4a2713aSLionel Sambuc // Set the source-location entry cursor to the current position in
1080f4a2713aSLionel Sambuc // the stream. This cursor will be used to read the contents of the
1081f4a2713aSLionel Sambuc // source manager block initially, and then lazily read
1082f4a2713aSLionel Sambuc // source-location entries as needed.
1083f4a2713aSLionel Sambuc SLocEntryCursor = F.Stream;
1084f4a2713aSLionel Sambuc
1085f4a2713aSLionel Sambuc // The stream itself is going to skip over the source manager block.
1086f4a2713aSLionel Sambuc if (F.Stream.SkipBlock()) {
1087f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1088f4a2713aSLionel Sambuc return true;
1089f4a2713aSLionel Sambuc }
1090f4a2713aSLionel Sambuc
1091f4a2713aSLionel Sambuc // Enter the source manager block.
1092f4a2713aSLionel Sambuc if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
1093f4a2713aSLionel Sambuc Error("malformed source manager block record in AST file");
1094f4a2713aSLionel Sambuc return true;
1095f4a2713aSLionel Sambuc }
1096f4a2713aSLionel Sambuc
1097f4a2713aSLionel Sambuc RecordData Record;
1098f4a2713aSLionel Sambuc while (true) {
1099f4a2713aSLionel Sambuc llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks();
1100f4a2713aSLionel Sambuc
1101f4a2713aSLionel Sambuc switch (E.Kind) {
1102f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock: // Handled for us already.
1103f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
1104f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1105f4a2713aSLionel Sambuc return true;
1106f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
1107f4a2713aSLionel Sambuc return false;
1108f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
1109f4a2713aSLionel Sambuc // The interesting case.
1110f4a2713aSLionel Sambuc break;
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc
1113f4a2713aSLionel Sambuc // Read a record.
1114f4a2713aSLionel Sambuc Record.clear();
1115f4a2713aSLionel Sambuc StringRef Blob;
1116f4a2713aSLionel Sambuc switch (SLocEntryCursor.readRecord(E.ID, Record, &Blob)) {
1117f4a2713aSLionel Sambuc default: // Default behavior: ignore.
1118f4a2713aSLionel Sambuc break;
1119f4a2713aSLionel Sambuc
1120f4a2713aSLionel Sambuc case SM_SLOC_FILE_ENTRY:
1121f4a2713aSLionel Sambuc case SM_SLOC_BUFFER_ENTRY:
1122f4a2713aSLionel Sambuc case SM_SLOC_EXPANSION_ENTRY:
1123f4a2713aSLionel Sambuc // Once we hit one of the source location entries, we're done.
1124f4a2713aSLionel Sambuc return false;
1125f4a2713aSLionel Sambuc }
1126f4a2713aSLionel Sambuc }
1127f4a2713aSLionel Sambuc }
1128f4a2713aSLionel Sambuc
1129f4a2713aSLionel Sambuc /// \brief If a header file is not found at the path that we expect it to be
1130f4a2713aSLionel Sambuc /// and the PCH file was moved from its original location, try to resolve the
1131f4a2713aSLionel Sambuc /// file by assuming that header+PCH were moved together and the header is in
1132f4a2713aSLionel Sambuc /// the same place relative to the PCH.
1133f4a2713aSLionel Sambuc static std::string
resolveFileRelativeToOriginalDir(const std::string & Filename,const std::string & OriginalDir,const std::string & CurrDir)1134f4a2713aSLionel Sambuc resolveFileRelativeToOriginalDir(const std::string &Filename,
1135f4a2713aSLionel Sambuc const std::string &OriginalDir,
1136f4a2713aSLionel Sambuc const std::string &CurrDir) {
1137f4a2713aSLionel Sambuc assert(OriginalDir != CurrDir &&
1138f4a2713aSLionel Sambuc "No point trying to resolve the file if the PCH dir didn't change");
1139f4a2713aSLionel Sambuc using namespace llvm::sys;
1140f4a2713aSLionel Sambuc SmallString<128> filePath(Filename);
1141f4a2713aSLionel Sambuc fs::make_absolute(filePath);
1142f4a2713aSLionel Sambuc assert(path::is_absolute(OriginalDir));
1143f4a2713aSLionel Sambuc SmallString<128> currPCHPath(CurrDir);
1144f4a2713aSLionel Sambuc
1145f4a2713aSLionel Sambuc path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),
1146f4a2713aSLionel Sambuc fileDirE = path::end(path::parent_path(filePath));
1147f4a2713aSLionel Sambuc path::const_iterator origDirI = path::begin(OriginalDir),
1148f4a2713aSLionel Sambuc origDirE = path::end(OriginalDir);
1149f4a2713aSLionel Sambuc // Skip the common path components from filePath and OriginalDir.
1150f4a2713aSLionel Sambuc while (fileDirI != fileDirE && origDirI != origDirE &&
1151f4a2713aSLionel Sambuc *fileDirI == *origDirI) {
1152f4a2713aSLionel Sambuc ++fileDirI;
1153f4a2713aSLionel Sambuc ++origDirI;
1154f4a2713aSLionel Sambuc }
1155f4a2713aSLionel Sambuc for (; origDirI != origDirE; ++origDirI)
1156f4a2713aSLionel Sambuc path::append(currPCHPath, "..");
1157f4a2713aSLionel Sambuc path::append(currPCHPath, fileDirI, fileDirE);
1158f4a2713aSLionel Sambuc path::append(currPCHPath, path::filename(Filename));
1159f4a2713aSLionel Sambuc return currPCHPath.str();
1160f4a2713aSLionel Sambuc }
1161f4a2713aSLionel Sambuc
ReadSLocEntry(int ID)1162f4a2713aSLionel Sambuc bool ASTReader::ReadSLocEntry(int ID) {
1163f4a2713aSLionel Sambuc if (ID == 0)
1164f4a2713aSLionel Sambuc return false;
1165f4a2713aSLionel Sambuc
1166f4a2713aSLionel Sambuc if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
1167f4a2713aSLionel Sambuc Error("source location entry ID out-of-range for AST file");
1168f4a2713aSLionel Sambuc return true;
1169f4a2713aSLionel Sambuc }
1170f4a2713aSLionel Sambuc
1171f4a2713aSLionel Sambuc ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;
1172f4a2713aSLionel Sambuc F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
1173f4a2713aSLionel Sambuc BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
1174f4a2713aSLionel Sambuc unsigned BaseOffset = F->SLocEntryBaseOffset;
1175f4a2713aSLionel Sambuc
1176f4a2713aSLionel Sambuc ++NumSLocEntriesRead;
1177f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = SLocEntryCursor.advance();
1178f4a2713aSLionel Sambuc if (Entry.Kind != llvm::BitstreamEntry::Record) {
1179f4a2713aSLionel Sambuc Error("incorrectly-formatted source location entry in AST file");
1180f4a2713aSLionel Sambuc return true;
1181f4a2713aSLionel Sambuc }
1182f4a2713aSLionel Sambuc
1183f4a2713aSLionel Sambuc RecordData Record;
1184f4a2713aSLionel Sambuc StringRef Blob;
1185f4a2713aSLionel Sambuc switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) {
1186f4a2713aSLionel Sambuc default:
1187f4a2713aSLionel Sambuc Error("incorrectly-formatted source location entry in AST file");
1188f4a2713aSLionel Sambuc return true;
1189f4a2713aSLionel Sambuc
1190f4a2713aSLionel Sambuc case SM_SLOC_FILE_ENTRY: {
1191f4a2713aSLionel Sambuc // We will detect whether a file changed and return 'Failure' for it, but
1192f4a2713aSLionel Sambuc // we will also try to fail gracefully by setting up the SLocEntry.
1193f4a2713aSLionel Sambuc unsigned InputID = Record[4];
1194f4a2713aSLionel Sambuc InputFile IF = getInputFile(*F, InputID);
1195f4a2713aSLionel Sambuc const FileEntry *File = IF.getFile();
1196f4a2713aSLionel Sambuc bool OverriddenBuffer = IF.isOverridden();
1197f4a2713aSLionel Sambuc
1198f4a2713aSLionel Sambuc // Note that we only check if a File was returned. If it was out-of-date
1199f4a2713aSLionel Sambuc // we have complained but we will continue creating a FileID to recover
1200f4a2713aSLionel Sambuc // gracefully.
1201f4a2713aSLionel Sambuc if (!File)
1202f4a2713aSLionel Sambuc return true;
1203f4a2713aSLionel Sambuc
1204f4a2713aSLionel Sambuc SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
1205f4a2713aSLionel Sambuc if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile) {
1206f4a2713aSLionel Sambuc // This is the module's main file.
1207f4a2713aSLionel Sambuc IncludeLoc = getImportLocation(F);
1208f4a2713aSLionel Sambuc }
1209f4a2713aSLionel Sambuc SrcMgr::CharacteristicKind
1210f4a2713aSLionel Sambuc FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
1211f4a2713aSLionel Sambuc FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter,
1212f4a2713aSLionel Sambuc ID, BaseOffset + Record[0]);
1213f4a2713aSLionel Sambuc SrcMgr::FileInfo &FileInfo =
1214f4a2713aSLionel Sambuc const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
1215f4a2713aSLionel Sambuc FileInfo.NumCreatedFIDs = Record[5];
1216f4a2713aSLionel Sambuc if (Record[3])
1217f4a2713aSLionel Sambuc FileInfo.setHasLineDirectives();
1218f4a2713aSLionel Sambuc
1219f4a2713aSLionel Sambuc const DeclID *FirstDecl = F->FileSortedDecls + Record[6];
1220f4a2713aSLionel Sambuc unsigned NumFileDecls = Record[7];
1221f4a2713aSLionel Sambuc if (NumFileDecls) {
1222f4a2713aSLionel Sambuc assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
1223f4a2713aSLionel Sambuc FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,
1224f4a2713aSLionel Sambuc NumFileDecls));
1225f4a2713aSLionel Sambuc }
1226f4a2713aSLionel Sambuc
1227f4a2713aSLionel Sambuc const SrcMgr::ContentCache *ContentCache
1228f4a2713aSLionel Sambuc = SourceMgr.getOrCreateContentCache(File,
1229f4a2713aSLionel Sambuc /*isSystemFile=*/FileCharacter != SrcMgr::C_User);
1230f4a2713aSLionel Sambuc if (OverriddenBuffer && !ContentCache->BufferOverridden &&
1231f4a2713aSLionel Sambuc ContentCache->ContentsEntry == ContentCache->OrigEntry) {
1232f4a2713aSLionel Sambuc unsigned Code = SLocEntryCursor.ReadCode();
1233f4a2713aSLionel Sambuc Record.clear();
1234f4a2713aSLionel Sambuc unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
1235f4a2713aSLionel Sambuc
1236f4a2713aSLionel Sambuc if (RecCode != SM_SLOC_BUFFER_BLOB) {
1237f4a2713aSLionel Sambuc Error("AST record has invalid code");
1238f4a2713aSLionel Sambuc return true;
1239f4a2713aSLionel Sambuc }
1240f4a2713aSLionel Sambuc
1241*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> Buffer
1242f4a2713aSLionel Sambuc = llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), File->getName());
1243*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(File, std::move(Buffer));
1244f4a2713aSLionel Sambuc }
1245f4a2713aSLionel Sambuc
1246f4a2713aSLionel Sambuc break;
1247f4a2713aSLionel Sambuc }
1248f4a2713aSLionel Sambuc
1249f4a2713aSLionel Sambuc case SM_SLOC_BUFFER_ENTRY: {
1250f4a2713aSLionel Sambuc const char *Name = Blob.data();
1251f4a2713aSLionel Sambuc unsigned Offset = Record[0];
1252f4a2713aSLionel Sambuc SrcMgr::CharacteristicKind
1253f4a2713aSLionel Sambuc FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
1254f4a2713aSLionel Sambuc SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
1255*0a6a1f1dSLionel Sambuc if (IncludeLoc.isInvalid() &&
1256*0a6a1f1dSLionel Sambuc (F->Kind == MK_ImplicitModule || F->Kind == MK_ExplicitModule)) {
1257f4a2713aSLionel Sambuc IncludeLoc = getImportLocation(F);
1258f4a2713aSLionel Sambuc }
1259f4a2713aSLionel Sambuc unsigned Code = SLocEntryCursor.ReadCode();
1260f4a2713aSLionel Sambuc Record.clear();
1261f4a2713aSLionel Sambuc unsigned RecCode
1262f4a2713aSLionel Sambuc = SLocEntryCursor.readRecord(Code, Record, &Blob);
1263f4a2713aSLionel Sambuc
1264f4a2713aSLionel Sambuc if (RecCode != SM_SLOC_BUFFER_BLOB) {
1265f4a2713aSLionel Sambuc Error("AST record has invalid code");
1266f4a2713aSLionel Sambuc return true;
1267f4a2713aSLionel Sambuc }
1268f4a2713aSLionel Sambuc
1269*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> Buffer =
1270*0a6a1f1dSLionel Sambuc llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name);
1271*0a6a1f1dSLionel Sambuc SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID,
1272f4a2713aSLionel Sambuc BaseOffset + Offset, IncludeLoc);
1273f4a2713aSLionel Sambuc break;
1274f4a2713aSLionel Sambuc }
1275f4a2713aSLionel Sambuc
1276f4a2713aSLionel Sambuc case SM_SLOC_EXPANSION_ENTRY: {
1277f4a2713aSLionel Sambuc SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]);
1278f4a2713aSLionel Sambuc SourceMgr.createExpansionLoc(SpellingLoc,
1279f4a2713aSLionel Sambuc ReadSourceLocation(*F, Record[2]),
1280f4a2713aSLionel Sambuc ReadSourceLocation(*F, Record[3]),
1281f4a2713aSLionel Sambuc Record[4],
1282f4a2713aSLionel Sambuc ID,
1283f4a2713aSLionel Sambuc BaseOffset + Record[0]);
1284f4a2713aSLionel Sambuc break;
1285f4a2713aSLionel Sambuc }
1286f4a2713aSLionel Sambuc }
1287f4a2713aSLionel Sambuc
1288f4a2713aSLionel Sambuc return false;
1289f4a2713aSLionel Sambuc }
1290f4a2713aSLionel Sambuc
getModuleImportLoc(int ID)1291f4a2713aSLionel Sambuc std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {
1292f4a2713aSLionel Sambuc if (ID == 0)
1293f4a2713aSLionel Sambuc return std::make_pair(SourceLocation(), "");
1294f4a2713aSLionel Sambuc
1295f4a2713aSLionel Sambuc if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
1296f4a2713aSLionel Sambuc Error("source location entry ID out-of-range for AST file");
1297f4a2713aSLionel Sambuc return std::make_pair(SourceLocation(), "");
1298f4a2713aSLionel Sambuc }
1299f4a2713aSLionel Sambuc
1300f4a2713aSLionel Sambuc // Find which module file this entry lands in.
1301f4a2713aSLionel Sambuc ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second;
1302*0a6a1f1dSLionel Sambuc if (M->Kind != MK_ImplicitModule && M->Kind != MK_ExplicitModule)
1303f4a2713aSLionel Sambuc return std::make_pair(SourceLocation(), "");
1304f4a2713aSLionel Sambuc
1305f4a2713aSLionel Sambuc // FIXME: Can we map this down to a particular submodule? That would be
1306f4a2713aSLionel Sambuc // ideal.
1307*0a6a1f1dSLionel Sambuc return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
1308f4a2713aSLionel Sambuc }
1309f4a2713aSLionel Sambuc
1310f4a2713aSLionel Sambuc /// \brief Find the location where the module F is imported.
getImportLocation(ModuleFile * F)1311f4a2713aSLionel Sambuc SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
1312f4a2713aSLionel Sambuc if (F->ImportLoc.isValid())
1313f4a2713aSLionel Sambuc return F->ImportLoc;
1314f4a2713aSLionel Sambuc
1315f4a2713aSLionel Sambuc // Otherwise we have a PCH. It's considered to be "imported" at the first
1316f4a2713aSLionel Sambuc // location of its includer.
1317f4a2713aSLionel Sambuc if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
1318*0a6a1f1dSLionel Sambuc // Main file is the importer.
1319*0a6a1f1dSLionel Sambuc assert(!SourceMgr.getMainFileID().isInvalid() && "missing main file");
1320*0a6a1f1dSLionel Sambuc return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1321f4a2713aSLionel Sambuc }
1322f4a2713aSLionel Sambuc return F->ImportedBy[0]->FirstLoc;
1323f4a2713aSLionel Sambuc }
1324f4a2713aSLionel Sambuc
1325f4a2713aSLionel Sambuc /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
1326f4a2713aSLionel Sambuc /// specified cursor. Read the abbreviations that are at the top of the block
1327f4a2713aSLionel Sambuc /// and then leave the cursor pointing into the block.
ReadBlockAbbrevs(BitstreamCursor & Cursor,unsigned BlockID)1328f4a2713aSLionel Sambuc bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) {
1329f4a2713aSLionel Sambuc if (Cursor.EnterSubBlock(BlockID)) {
1330f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1331f4a2713aSLionel Sambuc return Failure;
1332f4a2713aSLionel Sambuc }
1333f4a2713aSLionel Sambuc
1334f4a2713aSLionel Sambuc while (true) {
1335f4a2713aSLionel Sambuc uint64_t Offset = Cursor.GetCurrentBitNo();
1336f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
1337f4a2713aSLionel Sambuc
1338f4a2713aSLionel Sambuc // We expect all abbrevs to be at the start of the block.
1339f4a2713aSLionel Sambuc if (Code != llvm::bitc::DEFINE_ABBREV) {
1340f4a2713aSLionel Sambuc Cursor.JumpToBit(Offset);
1341f4a2713aSLionel Sambuc return false;
1342f4a2713aSLionel Sambuc }
1343f4a2713aSLionel Sambuc Cursor.ReadAbbrevRecord();
1344f4a2713aSLionel Sambuc }
1345f4a2713aSLionel Sambuc }
1346f4a2713aSLionel Sambuc
ReadToken(ModuleFile & F,const RecordDataImpl & Record,unsigned & Idx)1347f4a2713aSLionel Sambuc Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record,
1348f4a2713aSLionel Sambuc unsigned &Idx) {
1349f4a2713aSLionel Sambuc Token Tok;
1350f4a2713aSLionel Sambuc Tok.startToken();
1351f4a2713aSLionel Sambuc Tok.setLocation(ReadSourceLocation(F, Record, Idx));
1352f4a2713aSLionel Sambuc Tok.setLength(Record[Idx++]);
1353f4a2713aSLionel Sambuc if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++]))
1354f4a2713aSLionel Sambuc Tok.setIdentifierInfo(II);
1355f4a2713aSLionel Sambuc Tok.setKind((tok::TokenKind)Record[Idx++]);
1356f4a2713aSLionel Sambuc Tok.setFlag((Token::TokenFlags)Record[Idx++]);
1357f4a2713aSLionel Sambuc return Tok;
1358f4a2713aSLionel Sambuc }
1359f4a2713aSLionel Sambuc
ReadMacroRecord(ModuleFile & F,uint64_t Offset)1360f4a2713aSLionel Sambuc MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
1361f4a2713aSLionel Sambuc BitstreamCursor &Stream = F.MacroCursor;
1362f4a2713aSLionel Sambuc
1363f4a2713aSLionel Sambuc // Keep track of where we are in the stream, then jump back there
1364f4a2713aSLionel Sambuc // after reading this macro.
1365f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Stream);
1366f4a2713aSLionel Sambuc
1367f4a2713aSLionel Sambuc Stream.JumpToBit(Offset);
1368f4a2713aSLionel Sambuc RecordData Record;
1369f4a2713aSLionel Sambuc SmallVector<IdentifierInfo*, 16> MacroArgs;
1370*0a6a1f1dSLionel Sambuc MacroInfo *Macro = nullptr;
1371f4a2713aSLionel Sambuc
1372f4a2713aSLionel Sambuc while (true) {
1373f4a2713aSLionel Sambuc // Advance to the next record, but if we get to the end of the block, don't
1374f4a2713aSLionel Sambuc // pop it (removing all the abbreviations from the cursor) since we want to
1375f4a2713aSLionel Sambuc // be able to reseek within the block and read entries.
1376f4a2713aSLionel Sambuc unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd;
1377f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags);
1378f4a2713aSLionel Sambuc
1379f4a2713aSLionel Sambuc switch (Entry.Kind) {
1380f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock: // Handled for us already.
1381f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
1382f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1383f4a2713aSLionel Sambuc return Macro;
1384f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
1385f4a2713aSLionel Sambuc return Macro;
1386f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
1387f4a2713aSLionel Sambuc // The interesting case.
1388f4a2713aSLionel Sambuc break;
1389f4a2713aSLionel Sambuc }
1390f4a2713aSLionel Sambuc
1391f4a2713aSLionel Sambuc // Read a record.
1392f4a2713aSLionel Sambuc Record.clear();
1393f4a2713aSLionel Sambuc PreprocessorRecordTypes RecType =
1394f4a2713aSLionel Sambuc (PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record);
1395f4a2713aSLionel Sambuc switch (RecType) {
1396f4a2713aSLionel Sambuc case PP_MACRO_DIRECTIVE_HISTORY:
1397f4a2713aSLionel Sambuc return Macro;
1398f4a2713aSLionel Sambuc
1399f4a2713aSLionel Sambuc case PP_MACRO_OBJECT_LIKE:
1400f4a2713aSLionel Sambuc case PP_MACRO_FUNCTION_LIKE: {
1401f4a2713aSLionel Sambuc // If we already have a macro, that means that we've hit the end
1402f4a2713aSLionel Sambuc // of the definition of the macro we were looking for. We're
1403f4a2713aSLionel Sambuc // done.
1404f4a2713aSLionel Sambuc if (Macro)
1405f4a2713aSLionel Sambuc return Macro;
1406f4a2713aSLionel Sambuc
1407f4a2713aSLionel Sambuc unsigned NextIndex = 1; // Skip identifier ID.
1408f4a2713aSLionel Sambuc SubmoduleID SubModID = getGlobalSubmoduleID(F, Record[NextIndex++]);
1409f4a2713aSLionel Sambuc SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
1410f4a2713aSLionel Sambuc MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID);
1411f4a2713aSLionel Sambuc MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
1412f4a2713aSLionel Sambuc MI->setIsUsed(Record[NextIndex++]);
1413*0a6a1f1dSLionel Sambuc MI->setUsedForHeaderGuard(Record[NextIndex++]);
1414f4a2713aSLionel Sambuc
1415f4a2713aSLionel Sambuc if (RecType == PP_MACRO_FUNCTION_LIKE) {
1416f4a2713aSLionel Sambuc // Decode function-like macro info.
1417f4a2713aSLionel Sambuc bool isC99VarArgs = Record[NextIndex++];
1418f4a2713aSLionel Sambuc bool isGNUVarArgs = Record[NextIndex++];
1419f4a2713aSLionel Sambuc bool hasCommaPasting = Record[NextIndex++];
1420f4a2713aSLionel Sambuc MacroArgs.clear();
1421f4a2713aSLionel Sambuc unsigned NumArgs = Record[NextIndex++];
1422f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumArgs; ++i)
1423f4a2713aSLionel Sambuc MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));
1424f4a2713aSLionel Sambuc
1425f4a2713aSLionel Sambuc // Install function-like macro info.
1426f4a2713aSLionel Sambuc MI->setIsFunctionLike();
1427f4a2713aSLionel Sambuc if (isC99VarArgs) MI->setIsC99Varargs();
1428f4a2713aSLionel Sambuc if (isGNUVarArgs) MI->setIsGNUVarargs();
1429f4a2713aSLionel Sambuc if (hasCommaPasting) MI->setHasCommaPasting();
1430f4a2713aSLionel Sambuc MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
1431f4a2713aSLionel Sambuc PP.getPreprocessorAllocator());
1432f4a2713aSLionel Sambuc }
1433f4a2713aSLionel Sambuc
1434f4a2713aSLionel Sambuc // Remember that we saw this macro last so that we add the tokens that
1435f4a2713aSLionel Sambuc // form its body to it.
1436f4a2713aSLionel Sambuc Macro = MI;
1437f4a2713aSLionel Sambuc
1438f4a2713aSLionel Sambuc if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord() &&
1439f4a2713aSLionel Sambuc Record[NextIndex]) {
1440f4a2713aSLionel Sambuc // We have a macro definition. Register the association
1441f4a2713aSLionel Sambuc PreprocessedEntityID
1442f4a2713aSLionel Sambuc GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);
1443f4a2713aSLionel Sambuc PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
1444f4a2713aSLionel Sambuc PreprocessingRecord::PPEntityID
1445f4a2713aSLionel Sambuc PPID = PPRec.getPPEntityID(GlobalID-1, /*isLoaded=*/true);
1446f4a2713aSLionel Sambuc MacroDefinition *PPDef =
1447f4a2713aSLionel Sambuc cast_or_null<MacroDefinition>(PPRec.getPreprocessedEntity(PPID));
1448f4a2713aSLionel Sambuc if (PPDef)
1449f4a2713aSLionel Sambuc PPRec.RegisterMacroDefinition(Macro, PPDef);
1450f4a2713aSLionel Sambuc }
1451f4a2713aSLionel Sambuc
1452f4a2713aSLionel Sambuc ++NumMacrosRead;
1453f4a2713aSLionel Sambuc break;
1454f4a2713aSLionel Sambuc }
1455f4a2713aSLionel Sambuc
1456f4a2713aSLionel Sambuc case PP_TOKEN: {
1457f4a2713aSLionel Sambuc // If we see a TOKEN before a PP_MACRO_*, then the file is
1458f4a2713aSLionel Sambuc // erroneous, just pretend we didn't see this.
1459*0a6a1f1dSLionel Sambuc if (!Macro) break;
1460f4a2713aSLionel Sambuc
1461f4a2713aSLionel Sambuc unsigned Idx = 0;
1462f4a2713aSLionel Sambuc Token Tok = ReadToken(F, Record, Idx);
1463f4a2713aSLionel Sambuc Macro->AddTokenToBody(Tok);
1464f4a2713aSLionel Sambuc break;
1465f4a2713aSLionel Sambuc }
1466f4a2713aSLionel Sambuc }
1467f4a2713aSLionel Sambuc }
1468f4a2713aSLionel Sambuc }
1469f4a2713aSLionel Sambuc
1470f4a2713aSLionel Sambuc PreprocessedEntityID
getGlobalPreprocessedEntityID(ModuleFile & M,unsigned LocalID) const1471f4a2713aSLionel Sambuc ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const {
1472f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::const_iterator
1473f4a2713aSLionel Sambuc I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
1474f4a2713aSLionel Sambuc assert(I != M.PreprocessedEntityRemap.end()
1475f4a2713aSLionel Sambuc && "Invalid index into preprocessed entity index remap");
1476f4a2713aSLionel Sambuc
1477f4a2713aSLionel Sambuc return LocalID + I->second;
1478f4a2713aSLionel Sambuc }
1479f4a2713aSLionel Sambuc
ComputeHash(internal_key_ref ikey)1480f4a2713aSLionel Sambuc unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) {
1481f4a2713aSLionel Sambuc return llvm::hash_combine(ikey.Size, ikey.ModTime);
1482f4a2713aSLionel Sambuc }
1483f4a2713aSLionel Sambuc
1484f4a2713aSLionel Sambuc HeaderFileInfoTrait::internal_key_type
GetInternalKey(const FileEntry * FE)1485f4a2713aSLionel Sambuc HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) {
1486f4a2713aSLionel Sambuc internal_key_type ikey = { FE->getSize(), FE->getModificationTime(),
1487*0a6a1f1dSLionel Sambuc FE->getName(), /*Imported*/false };
1488f4a2713aSLionel Sambuc return ikey;
1489f4a2713aSLionel Sambuc }
1490f4a2713aSLionel Sambuc
EqualKey(internal_key_ref a,internal_key_ref b)1491f4a2713aSLionel Sambuc bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) {
1492f4a2713aSLionel Sambuc if (a.Size != b.Size || a.ModTime != b.ModTime)
1493f4a2713aSLionel Sambuc return false;
1494f4a2713aSLionel Sambuc
1495*0a6a1f1dSLionel Sambuc if (llvm::sys::path::is_absolute(a.Filename) &&
1496*0a6a1f1dSLionel Sambuc strcmp(a.Filename, b.Filename) == 0)
1497f4a2713aSLionel Sambuc return true;
1498f4a2713aSLionel Sambuc
1499f4a2713aSLionel Sambuc // Determine whether the actual files are equivalent.
1500f4a2713aSLionel Sambuc FileManager &FileMgr = Reader.getFileManager();
1501*0a6a1f1dSLionel Sambuc auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* {
1502*0a6a1f1dSLionel Sambuc if (!Key.Imported)
1503*0a6a1f1dSLionel Sambuc return FileMgr.getFile(Key.Filename);
1504*0a6a1f1dSLionel Sambuc
1505*0a6a1f1dSLionel Sambuc std::string Resolved = Key.Filename;
1506*0a6a1f1dSLionel Sambuc Reader.ResolveImportedPath(M, Resolved);
1507*0a6a1f1dSLionel Sambuc return FileMgr.getFile(Resolved);
1508*0a6a1f1dSLionel Sambuc };
1509*0a6a1f1dSLionel Sambuc
1510*0a6a1f1dSLionel Sambuc const FileEntry *FEA = GetFile(a);
1511*0a6a1f1dSLionel Sambuc const FileEntry *FEB = GetFile(b);
1512*0a6a1f1dSLionel Sambuc return FEA && FEA == FEB;
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc
1515f4a2713aSLionel Sambuc std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char * & d)1516f4a2713aSLionel Sambuc HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
1517*0a6a1f1dSLionel Sambuc using namespace llvm::support;
1518*0a6a1f1dSLionel Sambuc unsigned KeyLen = (unsigned) endian::readNext<uint16_t, little, unaligned>(d);
1519f4a2713aSLionel Sambuc unsigned DataLen = (unsigned) *d++;
1520f4a2713aSLionel Sambuc return std::make_pair(KeyLen, DataLen);
1521f4a2713aSLionel Sambuc }
1522f4a2713aSLionel Sambuc
1523f4a2713aSLionel Sambuc HeaderFileInfoTrait::internal_key_type
ReadKey(const unsigned char * d,unsigned)1524f4a2713aSLionel Sambuc HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
1525*0a6a1f1dSLionel Sambuc using namespace llvm::support;
1526f4a2713aSLionel Sambuc internal_key_type ikey;
1527*0a6a1f1dSLionel Sambuc ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d));
1528*0a6a1f1dSLionel Sambuc ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d));
1529f4a2713aSLionel Sambuc ikey.Filename = (const char *)d;
1530*0a6a1f1dSLionel Sambuc ikey.Imported = true;
1531f4a2713aSLionel Sambuc return ikey;
1532f4a2713aSLionel Sambuc }
1533f4a2713aSLionel Sambuc
1534f4a2713aSLionel Sambuc HeaderFileInfoTrait::data_type
ReadData(internal_key_ref key,const unsigned char * d,unsigned DataLen)1535f4a2713aSLionel Sambuc HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
1536f4a2713aSLionel Sambuc unsigned DataLen) {
1537f4a2713aSLionel Sambuc const unsigned char *End = d + DataLen;
1538*0a6a1f1dSLionel Sambuc using namespace llvm::support;
1539f4a2713aSLionel Sambuc HeaderFileInfo HFI;
1540f4a2713aSLionel Sambuc unsigned Flags = *d++;
1541f4a2713aSLionel Sambuc HFI.HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>
1542f4a2713aSLionel Sambuc ((Flags >> 6) & 0x03);
1543f4a2713aSLionel Sambuc HFI.isImport = (Flags >> 5) & 0x01;
1544f4a2713aSLionel Sambuc HFI.isPragmaOnce = (Flags >> 4) & 0x01;
1545f4a2713aSLionel Sambuc HFI.DirInfo = (Flags >> 2) & 0x03;
1546f4a2713aSLionel Sambuc HFI.Resolved = (Flags >> 1) & 0x01;
1547f4a2713aSLionel Sambuc HFI.IndexHeaderMapHeader = Flags & 0x01;
1548*0a6a1f1dSLionel Sambuc HFI.NumIncludes = endian::readNext<uint16_t, little, unaligned>(d);
1549*0a6a1f1dSLionel Sambuc HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
1550*0a6a1f1dSLionel Sambuc M, endian::readNext<uint32_t, little, unaligned>(d));
1551*0a6a1f1dSLionel Sambuc if (unsigned FrameworkOffset =
1552*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(d)) {
1553f4a2713aSLionel Sambuc // The framework offset is 1 greater than the actual offset,
1554f4a2713aSLionel Sambuc // since 0 is used as an indicator for "no framework name".
1555f4a2713aSLionel Sambuc StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
1556f4a2713aSLionel Sambuc HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
1557f4a2713aSLionel Sambuc }
1558f4a2713aSLionel Sambuc
1559f4a2713aSLionel Sambuc if (d != End) {
1560*0a6a1f1dSLionel Sambuc uint32_t LocalSMID = endian::readNext<uint32_t, little, unaligned>(d);
1561f4a2713aSLionel Sambuc if (LocalSMID) {
1562f4a2713aSLionel Sambuc // This header is part of a module. Associate it with the module to enable
1563f4a2713aSLionel Sambuc // implicit module import.
1564f4a2713aSLionel Sambuc SubmoduleID GlobalSMID = Reader.getGlobalSubmoduleID(M, LocalSMID);
1565f4a2713aSLionel Sambuc Module *Mod = Reader.getSubmodule(GlobalSMID);
1566f4a2713aSLionel Sambuc HFI.isModuleHeader = true;
1567f4a2713aSLionel Sambuc FileManager &FileMgr = Reader.getFileManager();
1568f4a2713aSLionel Sambuc ModuleMap &ModMap =
1569f4a2713aSLionel Sambuc Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap();
1570*0a6a1f1dSLionel Sambuc // FIXME: This information should be propagated through the
1571*0a6a1f1dSLionel Sambuc // SUBMODULE_HEADER etc records rather than from here.
1572*0a6a1f1dSLionel Sambuc // FIXME: We don't ever mark excluded headers.
1573*0a6a1f1dSLionel Sambuc std::string Filename = key.Filename;
1574*0a6a1f1dSLionel Sambuc if (key.Imported)
1575*0a6a1f1dSLionel Sambuc Reader.ResolveImportedPath(M, Filename);
1576*0a6a1f1dSLionel Sambuc Module::Header H = { key.Filename, FileMgr.getFile(Filename) };
1577*0a6a1f1dSLionel Sambuc ModMap.addHeader(Mod, H, HFI.getHeaderRole());
1578f4a2713aSLionel Sambuc }
1579f4a2713aSLionel Sambuc }
1580f4a2713aSLionel Sambuc
1581f4a2713aSLionel Sambuc assert(End == d && "Wrong data length in HeaderFileInfo deserialization");
1582f4a2713aSLionel Sambuc (void)End;
1583f4a2713aSLionel Sambuc
1584f4a2713aSLionel Sambuc // This HeaderFileInfo was externally loaded.
1585f4a2713aSLionel Sambuc HFI.External = true;
1586f4a2713aSLionel Sambuc return HFI;
1587f4a2713aSLionel Sambuc }
1588f4a2713aSLionel Sambuc
1589*0a6a1f1dSLionel Sambuc void
addPendingMacroFromModule(IdentifierInfo * II,ModuleFile * M,GlobalMacroID GMacID,ArrayRef<SubmoduleID> Overrides)1590*0a6a1f1dSLionel Sambuc ASTReader::addPendingMacroFromModule(IdentifierInfo *II, ModuleFile *M,
1591f4a2713aSLionel Sambuc GlobalMacroID GMacID,
1592*0a6a1f1dSLionel Sambuc ArrayRef<SubmoduleID> Overrides) {
1593f4a2713aSLionel Sambuc assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
1594*0a6a1f1dSLionel Sambuc SubmoduleID *OverrideData = nullptr;
1595*0a6a1f1dSLionel Sambuc if (!Overrides.empty()) {
1596*0a6a1f1dSLionel Sambuc OverrideData = new (Context) SubmoduleID[Overrides.size() + 1];
1597*0a6a1f1dSLionel Sambuc OverrideData[0] = Overrides.size();
1598*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I != Overrides.size(); ++I)
1599*0a6a1f1dSLionel Sambuc OverrideData[I + 1] = getGlobalSubmoduleID(*M, Overrides[I]);
1600*0a6a1f1dSLionel Sambuc }
1601*0a6a1f1dSLionel Sambuc PendingMacroIDs[II].push_back(PendingMacroInfo(M, GMacID, OverrideData));
1602f4a2713aSLionel Sambuc }
1603f4a2713aSLionel Sambuc
addPendingMacroFromPCH(IdentifierInfo * II,ModuleFile * M,uint64_t MacroDirectivesOffset)1604f4a2713aSLionel Sambuc void ASTReader::addPendingMacroFromPCH(IdentifierInfo *II,
1605f4a2713aSLionel Sambuc ModuleFile *M,
1606f4a2713aSLionel Sambuc uint64_t MacroDirectivesOffset) {
1607f4a2713aSLionel Sambuc assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
1608f4a2713aSLionel Sambuc PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset));
1609f4a2713aSLionel Sambuc }
1610f4a2713aSLionel Sambuc
ReadDefinedMacros()1611f4a2713aSLionel Sambuc void ASTReader::ReadDefinedMacros() {
1612f4a2713aSLionel Sambuc // Note that we are loading defined macros.
1613f4a2713aSLionel Sambuc Deserializing Macros(this);
1614f4a2713aSLionel Sambuc
1615f4a2713aSLionel Sambuc for (ModuleReverseIterator I = ModuleMgr.rbegin(),
1616f4a2713aSLionel Sambuc E = ModuleMgr.rend(); I != E; ++I) {
1617f4a2713aSLionel Sambuc BitstreamCursor &MacroCursor = (*I)->MacroCursor;
1618f4a2713aSLionel Sambuc
1619f4a2713aSLionel Sambuc // If there was no preprocessor block, skip this file.
1620f4a2713aSLionel Sambuc if (!MacroCursor.getBitStreamReader())
1621f4a2713aSLionel Sambuc continue;
1622f4a2713aSLionel Sambuc
1623f4a2713aSLionel Sambuc BitstreamCursor Cursor = MacroCursor;
1624f4a2713aSLionel Sambuc Cursor.JumpToBit((*I)->MacroStartOffset);
1625f4a2713aSLionel Sambuc
1626f4a2713aSLionel Sambuc RecordData Record;
1627f4a2713aSLionel Sambuc while (true) {
1628f4a2713aSLionel Sambuc llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks();
1629f4a2713aSLionel Sambuc
1630f4a2713aSLionel Sambuc switch (E.Kind) {
1631f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock: // Handled for us already.
1632f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
1633f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1634f4a2713aSLionel Sambuc return;
1635f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
1636f4a2713aSLionel Sambuc goto NextCursor;
1637f4a2713aSLionel Sambuc
1638f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
1639f4a2713aSLionel Sambuc Record.clear();
1640f4a2713aSLionel Sambuc switch (Cursor.readRecord(E.ID, Record)) {
1641f4a2713aSLionel Sambuc default: // Default behavior: ignore.
1642f4a2713aSLionel Sambuc break;
1643f4a2713aSLionel Sambuc
1644f4a2713aSLionel Sambuc case PP_MACRO_OBJECT_LIKE:
1645f4a2713aSLionel Sambuc case PP_MACRO_FUNCTION_LIKE:
1646f4a2713aSLionel Sambuc getLocalIdentifier(**I, Record[0]);
1647f4a2713aSLionel Sambuc break;
1648f4a2713aSLionel Sambuc
1649f4a2713aSLionel Sambuc case PP_TOKEN:
1650f4a2713aSLionel Sambuc // Ignore tokens.
1651f4a2713aSLionel Sambuc break;
1652f4a2713aSLionel Sambuc }
1653f4a2713aSLionel Sambuc break;
1654f4a2713aSLionel Sambuc }
1655f4a2713aSLionel Sambuc }
1656f4a2713aSLionel Sambuc NextCursor: ;
1657f4a2713aSLionel Sambuc }
1658f4a2713aSLionel Sambuc }
1659f4a2713aSLionel Sambuc
1660f4a2713aSLionel Sambuc namespace {
1661f4a2713aSLionel Sambuc /// \brief Visitor class used to look up identifirs in an AST file.
1662f4a2713aSLionel Sambuc class IdentifierLookupVisitor {
1663f4a2713aSLionel Sambuc StringRef Name;
1664f4a2713aSLionel Sambuc unsigned PriorGeneration;
1665f4a2713aSLionel Sambuc unsigned &NumIdentifierLookups;
1666f4a2713aSLionel Sambuc unsigned &NumIdentifierLookupHits;
1667f4a2713aSLionel Sambuc IdentifierInfo *Found;
1668f4a2713aSLionel Sambuc
1669f4a2713aSLionel Sambuc public:
IdentifierLookupVisitor(StringRef Name,unsigned PriorGeneration,unsigned & NumIdentifierLookups,unsigned & NumIdentifierLookupHits)1670f4a2713aSLionel Sambuc IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
1671f4a2713aSLionel Sambuc unsigned &NumIdentifierLookups,
1672f4a2713aSLionel Sambuc unsigned &NumIdentifierLookupHits)
1673f4a2713aSLionel Sambuc : Name(Name), PriorGeneration(PriorGeneration),
1674f4a2713aSLionel Sambuc NumIdentifierLookups(NumIdentifierLookups),
1675f4a2713aSLionel Sambuc NumIdentifierLookupHits(NumIdentifierLookupHits),
1676f4a2713aSLionel Sambuc Found()
1677f4a2713aSLionel Sambuc {
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)1680f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
1681f4a2713aSLionel Sambuc IdentifierLookupVisitor *This
1682f4a2713aSLionel Sambuc = static_cast<IdentifierLookupVisitor *>(UserData);
1683f4a2713aSLionel Sambuc
1684f4a2713aSLionel Sambuc // If we've already searched this module file, skip it now.
1685f4a2713aSLionel Sambuc if (M.Generation <= This->PriorGeneration)
1686f4a2713aSLionel Sambuc return true;
1687f4a2713aSLionel Sambuc
1688f4a2713aSLionel Sambuc ASTIdentifierLookupTable *IdTable
1689f4a2713aSLionel Sambuc = (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
1690f4a2713aSLionel Sambuc if (!IdTable)
1691f4a2713aSLionel Sambuc return false;
1692f4a2713aSLionel Sambuc
1693f4a2713aSLionel Sambuc ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(),
1694f4a2713aSLionel Sambuc M, This->Found);
1695f4a2713aSLionel Sambuc ++This->NumIdentifierLookups;
1696f4a2713aSLionel Sambuc ASTIdentifierLookupTable::iterator Pos = IdTable->find(This->Name,&Trait);
1697f4a2713aSLionel Sambuc if (Pos == IdTable->end())
1698f4a2713aSLionel Sambuc return false;
1699f4a2713aSLionel Sambuc
1700f4a2713aSLionel Sambuc // Dereferencing the iterator has the effect of building the
1701f4a2713aSLionel Sambuc // IdentifierInfo node and populating it with the various
1702f4a2713aSLionel Sambuc // declarations it needs.
1703f4a2713aSLionel Sambuc ++This->NumIdentifierLookupHits;
1704f4a2713aSLionel Sambuc This->Found = *Pos;
1705f4a2713aSLionel Sambuc return true;
1706f4a2713aSLionel Sambuc }
1707f4a2713aSLionel Sambuc
1708f4a2713aSLionel Sambuc // \brief Retrieve the identifier info found within the module
1709f4a2713aSLionel Sambuc // files.
getIdentifierInfo() const1710f4a2713aSLionel Sambuc IdentifierInfo *getIdentifierInfo() const { return Found; }
1711f4a2713aSLionel Sambuc };
1712f4a2713aSLionel Sambuc }
1713f4a2713aSLionel Sambuc
updateOutOfDateIdentifier(IdentifierInfo & II)1714f4a2713aSLionel Sambuc void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
1715f4a2713aSLionel Sambuc // Note that we are loading an identifier.
1716f4a2713aSLionel Sambuc Deserializing AnIdentifier(this);
1717f4a2713aSLionel Sambuc
1718f4a2713aSLionel Sambuc unsigned PriorGeneration = 0;
1719f4a2713aSLionel Sambuc if (getContext().getLangOpts().Modules)
1720f4a2713aSLionel Sambuc PriorGeneration = IdentifierGeneration[&II];
1721f4a2713aSLionel Sambuc
1722f4a2713aSLionel Sambuc // If there is a global index, look there first to determine which modules
1723f4a2713aSLionel Sambuc // provably do not have any results for this identifier.
1724f4a2713aSLionel Sambuc GlobalModuleIndex::HitSet Hits;
1725*0a6a1f1dSLionel Sambuc GlobalModuleIndex::HitSet *HitsPtr = nullptr;
1726f4a2713aSLionel Sambuc if (!loadGlobalIndex()) {
1727f4a2713aSLionel Sambuc if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) {
1728f4a2713aSLionel Sambuc HitsPtr = &Hits;
1729f4a2713aSLionel Sambuc }
1730f4a2713aSLionel Sambuc }
1731f4a2713aSLionel Sambuc
1732f4a2713aSLionel Sambuc IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration,
1733f4a2713aSLionel Sambuc NumIdentifierLookups,
1734f4a2713aSLionel Sambuc NumIdentifierLookupHits);
1735f4a2713aSLionel Sambuc ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);
1736f4a2713aSLionel Sambuc markIdentifierUpToDate(&II);
1737f4a2713aSLionel Sambuc }
1738f4a2713aSLionel Sambuc
markIdentifierUpToDate(IdentifierInfo * II)1739f4a2713aSLionel Sambuc void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
1740f4a2713aSLionel Sambuc if (!II)
1741f4a2713aSLionel Sambuc return;
1742f4a2713aSLionel Sambuc
1743f4a2713aSLionel Sambuc II->setOutOfDate(false);
1744f4a2713aSLionel Sambuc
1745f4a2713aSLionel Sambuc // Update the generation for this identifier.
1746f4a2713aSLionel Sambuc if (getContext().getLangOpts().Modules)
1747*0a6a1f1dSLionel Sambuc IdentifierGeneration[II] = getGeneration();
1748*0a6a1f1dSLionel Sambuc }
1749*0a6a1f1dSLionel Sambuc
1750*0a6a1f1dSLionel Sambuc struct ASTReader::ModuleMacroInfo {
1751*0a6a1f1dSLionel Sambuc SubmoduleID SubModID;
1752*0a6a1f1dSLionel Sambuc MacroInfo *MI;
1753*0a6a1f1dSLionel Sambuc SubmoduleID *Overrides;
1754*0a6a1f1dSLionel Sambuc // FIXME: Remove this.
1755*0a6a1f1dSLionel Sambuc ModuleFile *F;
1756*0a6a1f1dSLionel Sambuc
isDefineASTReader::ModuleMacroInfo1757*0a6a1f1dSLionel Sambuc bool isDefine() const { return MI; }
1758*0a6a1f1dSLionel Sambuc
getSubmoduleIDASTReader::ModuleMacroInfo1759*0a6a1f1dSLionel Sambuc SubmoduleID getSubmoduleID() const { return SubModID; }
1760*0a6a1f1dSLionel Sambuc
getOverriddenSubmodulesASTReader::ModuleMacroInfo1761*0a6a1f1dSLionel Sambuc ArrayRef<SubmoduleID> getOverriddenSubmodules() const {
1762*0a6a1f1dSLionel Sambuc if (!Overrides)
1763*0a6a1f1dSLionel Sambuc return None;
1764*0a6a1f1dSLionel Sambuc return llvm::makeArrayRef(Overrides + 1, *Overrides);
1765*0a6a1f1dSLionel Sambuc }
1766*0a6a1f1dSLionel Sambuc
importASTReader::ModuleMacroInfo1767*0a6a1f1dSLionel Sambuc MacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {
1768*0a6a1f1dSLionel Sambuc if (!MI)
1769*0a6a1f1dSLionel Sambuc return PP.AllocateUndefMacroDirective(ImportLoc, SubModID,
1770*0a6a1f1dSLionel Sambuc getOverriddenSubmodules());
1771*0a6a1f1dSLionel Sambuc return PP.AllocateDefMacroDirective(MI, ImportLoc, SubModID,
1772*0a6a1f1dSLionel Sambuc getOverriddenSubmodules());
1773*0a6a1f1dSLionel Sambuc }
1774*0a6a1f1dSLionel Sambuc };
1775*0a6a1f1dSLionel Sambuc
1776*0a6a1f1dSLionel Sambuc ASTReader::ModuleMacroInfo *
getModuleMacro(const PendingMacroInfo & PMInfo)1777*0a6a1f1dSLionel Sambuc ASTReader::getModuleMacro(const PendingMacroInfo &PMInfo) {
1778*0a6a1f1dSLionel Sambuc ModuleMacroInfo Info;
1779*0a6a1f1dSLionel Sambuc
1780*0a6a1f1dSLionel Sambuc uint32_t ID = PMInfo.ModuleMacroData.MacID;
1781*0a6a1f1dSLionel Sambuc if (ID & 1) {
1782*0a6a1f1dSLionel Sambuc // Macro undefinition.
1783*0a6a1f1dSLionel Sambuc Info.SubModID = getGlobalSubmoduleID(*PMInfo.M, ID >> 1);
1784*0a6a1f1dSLionel Sambuc Info.MI = nullptr;
1785*0a6a1f1dSLionel Sambuc } else {
1786*0a6a1f1dSLionel Sambuc // Macro definition.
1787*0a6a1f1dSLionel Sambuc GlobalMacroID GMacID = getGlobalMacroID(*PMInfo.M, ID >> 1);
1788*0a6a1f1dSLionel Sambuc assert(GMacID);
1789*0a6a1f1dSLionel Sambuc
1790*0a6a1f1dSLionel Sambuc // If this macro has already been loaded, don't do so again.
1791*0a6a1f1dSLionel Sambuc // FIXME: This is highly dubious. Multiple macro definitions can have the
1792*0a6a1f1dSLionel Sambuc // same MacroInfo (and hence the same GMacID) due to #pragma push_macro etc.
1793*0a6a1f1dSLionel Sambuc if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS])
1794*0a6a1f1dSLionel Sambuc return nullptr;
1795*0a6a1f1dSLionel Sambuc
1796*0a6a1f1dSLionel Sambuc Info.MI = getMacro(GMacID);
1797*0a6a1f1dSLionel Sambuc Info.SubModID = Info.MI->getOwningModuleID();
1798*0a6a1f1dSLionel Sambuc }
1799*0a6a1f1dSLionel Sambuc Info.Overrides = PMInfo.ModuleMacroData.Overrides;
1800*0a6a1f1dSLionel Sambuc Info.F = PMInfo.M;
1801*0a6a1f1dSLionel Sambuc
1802*0a6a1f1dSLionel Sambuc return new (Context) ModuleMacroInfo(Info);
1803f4a2713aSLionel Sambuc }
1804f4a2713aSLionel Sambuc
resolvePendingMacro(IdentifierInfo * II,const PendingMacroInfo & PMInfo)1805f4a2713aSLionel Sambuc void ASTReader::resolvePendingMacro(IdentifierInfo *II,
1806f4a2713aSLionel Sambuc const PendingMacroInfo &PMInfo) {
1807f4a2713aSLionel Sambuc assert(II);
1808f4a2713aSLionel Sambuc
1809*0a6a1f1dSLionel Sambuc if (PMInfo.M->Kind != MK_ImplicitModule &&
1810*0a6a1f1dSLionel Sambuc PMInfo.M->Kind != MK_ExplicitModule) {
1811f4a2713aSLionel Sambuc installPCHMacroDirectives(II, *PMInfo.M,
1812f4a2713aSLionel Sambuc PMInfo.PCHMacroData.MacroDirectivesOffset);
1813f4a2713aSLionel Sambuc return;
1814f4a2713aSLionel Sambuc }
1815f4a2713aSLionel Sambuc
1816f4a2713aSLionel Sambuc // Module Macro.
1817f4a2713aSLionel Sambuc
1818*0a6a1f1dSLionel Sambuc ModuleMacroInfo *MMI = getModuleMacro(PMInfo);
1819*0a6a1f1dSLionel Sambuc if (!MMI)
1820f4a2713aSLionel Sambuc return;
1821f4a2713aSLionel Sambuc
1822*0a6a1f1dSLionel Sambuc Module *Owner = getSubmodule(MMI->getSubmoduleID());
1823*0a6a1f1dSLionel Sambuc if (Owner && Owner->NameVisibility == Module::Hidden) {
1824*0a6a1f1dSLionel Sambuc // Macros in the owning module are hidden. Just remember this macro to
1825*0a6a1f1dSLionel Sambuc // install if we make this module visible.
1826*0a6a1f1dSLionel Sambuc HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI));
1827*0a6a1f1dSLionel Sambuc } else {
1828*0a6a1f1dSLionel Sambuc installImportedMacro(II, MMI, Owner);
1829f4a2713aSLionel Sambuc }
1830f4a2713aSLionel Sambuc }
1831f4a2713aSLionel Sambuc
installPCHMacroDirectives(IdentifierInfo * II,ModuleFile & M,uint64_t Offset)1832f4a2713aSLionel Sambuc void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
1833f4a2713aSLionel Sambuc ModuleFile &M, uint64_t Offset) {
1834*0a6a1f1dSLionel Sambuc assert(M.Kind != MK_ImplicitModule && M.Kind != MK_ExplicitModule);
1835f4a2713aSLionel Sambuc
1836f4a2713aSLionel Sambuc BitstreamCursor &Cursor = M.MacroCursor;
1837f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
1838f4a2713aSLionel Sambuc Cursor.JumpToBit(Offset);
1839f4a2713aSLionel Sambuc
1840f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry =
1841f4a2713aSLionel Sambuc Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
1842f4a2713aSLionel Sambuc if (Entry.Kind != llvm::BitstreamEntry::Record) {
1843f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1844f4a2713aSLionel Sambuc return;
1845f4a2713aSLionel Sambuc }
1846f4a2713aSLionel Sambuc
1847f4a2713aSLionel Sambuc RecordData Record;
1848f4a2713aSLionel Sambuc PreprocessorRecordTypes RecType =
1849f4a2713aSLionel Sambuc (PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record);
1850f4a2713aSLionel Sambuc if (RecType != PP_MACRO_DIRECTIVE_HISTORY) {
1851f4a2713aSLionel Sambuc Error("malformed block record in AST file");
1852f4a2713aSLionel Sambuc return;
1853f4a2713aSLionel Sambuc }
1854f4a2713aSLionel Sambuc
1855f4a2713aSLionel Sambuc // Deserialize the macro directives history in reverse source-order.
1856*0a6a1f1dSLionel Sambuc MacroDirective *Latest = nullptr, *Earliest = nullptr;
1857f4a2713aSLionel Sambuc unsigned Idx = 0, N = Record.size();
1858f4a2713aSLionel Sambuc while (Idx < N) {
1859*0a6a1f1dSLionel Sambuc MacroDirective *MD = nullptr;
1860f4a2713aSLionel Sambuc SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
1861f4a2713aSLionel Sambuc MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
1862f4a2713aSLionel Sambuc switch (K) {
1863f4a2713aSLionel Sambuc case MacroDirective::MD_Define: {
1864f4a2713aSLionel Sambuc GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
1865f4a2713aSLionel Sambuc MacroInfo *MI = getMacro(GMacID);
1866*0a6a1f1dSLionel Sambuc SubmoduleID ImportedFrom = Record[Idx++];
1867*0a6a1f1dSLionel Sambuc bool IsAmbiguous = Record[Idx++];
1868*0a6a1f1dSLionel Sambuc llvm::SmallVector<unsigned, 4> Overrides;
1869*0a6a1f1dSLionel Sambuc if (ImportedFrom) {
1870*0a6a1f1dSLionel Sambuc Overrides.insert(Overrides.end(),
1871*0a6a1f1dSLionel Sambuc &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]);
1872*0a6a1f1dSLionel Sambuc Idx += Overrides.size() + 1;
1873*0a6a1f1dSLionel Sambuc }
1874f4a2713aSLionel Sambuc DefMacroDirective *DefMD =
1875*0a6a1f1dSLionel Sambuc PP.AllocateDefMacroDirective(MI, Loc, ImportedFrom, Overrides);
1876*0a6a1f1dSLionel Sambuc DefMD->setAmbiguous(IsAmbiguous);
1877f4a2713aSLionel Sambuc MD = DefMD;
1878f4a2713aSLionel Sambuc break;
1879f4a2713aSLionel Sambuc }
1880*0a6a1f1dSLionel Sambuc case MacroDirective::MD_Undefine: {
1881*0a6a1f1dSLionel Sambuc SubmoduleID ImportedFrom = Record[Idx++];
1882*0a6a1f1dSLionel Sambuc llvm::SmallVector<unsigned, 4> Overrides;
1883*0a6a1f1dSLionel Sambuc if (ImportedFrom) {
1884*0a6a1f1dSLionel Sambuc Overrides.insert(Overrides.end(),
1885*0a6a1f1dSLionel Sambuc &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]);
1886*0a6a1f1dSLionel Sambuc Idx += Overrides.size() + 1;
1887*0a6a1f1dSLionel Sambuc }
1888*0a6a1f1dSLionel Sambuc MD = PP.AllocateUndefMacroDirective(Loc, ImportedFrom, Overrides);
1889f4a2713aSLionel Sambuc break;
1890*0a6a1f1dSLionel Sambuc }
1891*0a6a1f1dSLionel Sambuc case MacroDirective::MD_Visibility:
1892f4a2713aSLionel Sambuc bool isPublic = Record[Idx++];
1893f4a2713aSLionel Sambuc MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);
1894f4a2713aSLionel Sambuc break;
1895f4a2713aSLionel Sambuc }
1896f4a2713aSLionel Sambuc
1897f4a2713aSLionel Sambuc if (!Latest)
1898f4a2713aSLionel Sambuc Latest = MD;
1899f4a2713aSLionel Sambuc if (Earliest)
1900f4a2713aSLionel Sambuc Earliest->setPrevious(MD);
1901f4a2713aSLionel Sambuc Earliest = MD;
1902f4a2713aSLionel Sambuc }
1903f4a2713aSLionel Sambuc
1904f4a2713aSLionel Sambuc PP.setLoadedMacroDirective(II, Latest);
1905f4a2713aSLionel Sambuc }
1906f4a2713aSLionel Sambuc
1907f4a2713aSLionel Sambuc /// \brief For the given macro definitions, check if they are both in system
1908f4a2713aSLionel Sambuc /// modules.
areDefinedInSystemModules(MacroInfo * PrevMI,MacroInfo * NewMI,Module * NewOwner,ASTReader & Reader)1909f4a2713aSLionel Sambuc static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,
1910f4a2713aSLionel Sambuc Module *NewOwner, ASTReader &Reader) {
1911f4a2713aSLionel Sambuc assert(PrevMI && NewMI);
1912*0a6a1f1dSLionel Sambuc Module *PrevOwner = nullptr;
1913f4a2713aSLionel Sambuc if (SubmoduleID PrevModID = PrevMI->getOwningModuleID())
1914f4a2713aSLionel Sambuc PrevOwner = Reader.getSubmodule(PrevModID);
1915f4a2713aSLionel Sambuc SourceManager &SrcMgr = Reader.getSourceManager();
1916f4a2713aSLionel Sambuc bool PrevInSystem
1917f4a2713aSLionel Sambuc = PrevOwner? PrevOwner->IsSystem
1918f4a2713aSLionel Sambuc : SrcMgr.isInSystemHeader(PrevMI->getDefinitionLoc());
1919f4a2713aSLionel Sambuc bool NewInSystem
1920f4a2713aSLionel Sambuc = NewOwner? NewOwner->IsSystem
1921f4a2713aSLionel Sambuc : SrcMgr.isInSystemHeader(NewMI->getDefinitionLoc());
1922f4a2713aSLionel Sambuc if (PrevOwner && PrevOwner == NewOwner)
1923f4a2713aSLionel Sambuc return false;
1924f4a2713aSLionel Sambuc return PrevInSystem && NewInSystem;
1925f4a2713aSLionel Sambuc }
1926f4a2713aSLionel Sambuc
removeOverriddenMacros(IdentifierInfo * II,SourceLocation ImportLoc,AmbiguousMacros & Ambig,ArrayRef<SubmoduleID> Overrides)1927*0a6a1f1dSLionel Sambuc void ASTReader::removeOverriddenMacros(IdentifierInfo *II,
1928*0a6a1f1dSLionel Sambuc SourceLocation ImportLoc,
1929*0a6a1f1dSLionel Sambuc AmbiguousMacros &Ambig,
1930*0a6a1f1dSLionel Sambuc ArrayRef<SubmoduleID> Overrides) {
1931*0a6a1f1dSLionel Sambuc for (unsigned OI = 0, ON = Overrides.size(); OI != ON; ++OI) {
1932*0a6a1f1dSLionel Sambuc SubmoduleID OwnerID = Overrides[OI];
1933f4a2713aSLionel Sambuc
1934*0a6a1f1dSLionel Sambuc // If this macro is not yet visible, remove it from the hidden names list.
1935*0a6a1f1dSLionel Sambuc // It won't be there if we're in the middle of making the owner visible.
1936*0a6a1f1dSLionel Sambuc Module *Owner = getSubmodule(OwnerID);
1937*0a6a1f1dSLionel Sambuc auto HiddenIt = HiddenNamesMap.find(Owner);
1938*0a6a1f1dSLionel Sambuc if (HiddenIt != HiddenNamesMap.end()) {
1939*0a6a1f1dSLionel Sambuc HiddenNames &Hidden = HiddenIt->second;
1940*0a6a1f1dSLionel Sambuc HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II);
1941*0a6a1f1dSLionel Sambuc if (HI != Hidden.HiddenMacros.end()) {
1942*0a6a1f1dSLionel Sambuc // Register the macro now so we don't lose it when we re-export.
1943*0a6a1f1dSLionel Sambuc PP.appendMacroDirective(II, HI->second->import(PP, ImportLoc));
1944*0a6a1f1dSLionel Sambuc
1945*0a6a1f1dSLionel Sambuc auto SubOverrides = HI->second->getOverriddenSubmodules();
1946*0a6a1f1dSLionel Sambuc Hidden.HiddenMacros.erase(HI);
1947*0a6a1f1dSLionel Sambuc removeOverriddenMacros(II, ImportLoc, Ambig, SubOverrides);
1948*0a6a1f1dSLionel Sambuc }
1949*0a6a1f1dSLionel Sambuc }
1950*0a6a1f1dSLionel Sambuc
1951*0a6a1f1dSLionel Sambuc // If this macro is already in our list of conflicts, remove it from there.
1952*0a6a1f1dSLionel Sambuc Ambig.erase(
1953*0a6a1f1dSLionel Sambuc std::remove_if(Ambig.begin(), Ambig.end(), [&](DefMacroDirective *MD) {
1954*0a6a1f1dSLionel Sambuc return MD->getInfo()->getOwningModuleID() == OwnerID;
1955*0a6a1f1dSLionel Sambuc }),
1956*0a6a1f1dSLionel Sambuc Ambig.end());
1957*0a6a1f1dSLionel Sambuc }
1958*0a6a1f1dSLionel Sambuc }
1959*0a6a1f1dSLionel Sambuc
1960*0a6a1f1dSLionel Sambuc ASTReader::AmbiguousMacros *
removeOverriddenMacros(IdentifierInfo * II,SourceLocation ImportLoc,ArrayRef<SubmoduleID> Overrides)1961*0a6a1f1dSLionel Sambuc ASTReader::removeOverriddenMacros(IdentifierInfo *II,
1962*0a6a1f1dSLionel Sambuc SourceLocation ImportLoc,
1963*0a6a1f1dSLionel Sambuc ArrayRef<SubmoduleID> Overrides) {
1964f4a2713aSLionel Sambuc MacroDirective *Prev = PP.getMacroDirective(II);
1965*0a6a1f1dSLionel Sambuc if (!Prev && Overrides.empty())
1966*0a6a1f1dSLionel Sambuc return nullptr;
1967*0a6a1f1dSLionel Sambuc
1968*0a6a1f1dSLionel Sambuc DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective()
1969*0a6a1f1dSLionel Sambuc : nullptr;
1970*0a6a1f1dSLionel Sambuc if (PrevDef && PrevDef->isAmbiguous()) {
1971*0a6a1f1dSLionel Sambuc // We had a prior ambiguity. Check whether we resolve it (or make it worse).
1972*0a6a1f1dSLionel Sambuc AmbiguousMacros &Ambig = AmbiguousMacroDefs[II];
1973*0a6a1f1dSLionel Sambuc Ambig.push_back(PrevDef);
1974*0a6a1f1dSLionel Sambuc
1975*0a6a1f1dSLionel Sambuc removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);
1976*0a6a1f1dSLionel Sambuc
1977*0a6a1f1dSLionel Sambuc if (!Ambig.empty())
1978*0a6a1f1dSLionel Sambuc return &Ambig;
1979*0a6a1f1dSLionel Sambuc
1980*0a6a1f1dSLionel Sambuc AmbiguousMacroDefs.erase(II);
1981*0a6a1f1dSLionel Sambuc } else {
1982*0a6a1f1dSLionel Sambuc // There's no ambiguity yet. Maybe we're introducing one.
1983*0a6a1f1dSLionel Sambuc AmbiguousMacros Ambig;
1984*0a6a1f1dSLionel Sambuc if (PrevDef)
1985*0a6a1f1dSLionel Sambuc Ambig.push_back(PrevDef);
1986*0a6a1f1dSLionel Sambuc
1987*0a6a1f1dSLionel Sambuc removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);
1988*0a6a1f1dSLionel Sambuc
1989*0a6a1f1dSLionel Sambuc if (!Ambig.empty()) {
1990*0a6a1f1dSLionel Sambuc AmbiguousMacros &Result = AmbiguousMacroDefs[II];
1991*0a6a1f1dSLionel Sambuc std::swap(Result, Ambig);
1992*0a6a1f1dSLionel Sambuc return &Result;
1993*0a6a1f1dSLionel Sambuc }
1994*0a6a1f1dSLionel Sambuc }
1995*0a6a1f1dSLionel Sambuc
1996*0a6a1f1dSLionel Sambuc // We ended up with no ambiguity.
1997*0a6a1f1dSLionel Sambuc return nullptr;
1998*0a6a1f1dSLionel Sambuc }
1999*0a6a1f1dSLionel Sambuc
installImportedMacro(IdentifierInfo * II,ModuleMacroInfo * MMI,Module * Owner)2000*0a6a1f1dSLionel Sambuc void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
2001*0a6a1f1dSLionel Sambuc Module *Owner) {
2002*0a6a1f1dSLionel Sambuc assert(II && Owner);
2003*0a6a1f1dSLionel Sambuc
2004*0a6a1f1dSLionel Sambuc SourceLocation ImportLoc = Owner->MacroVisibilityLoc;
2005*0a6a1f1dSLionel Sambuc if (ImportLoc.isInvalid()) {
2006*0a6a1f1dSLionel Sambuc // FIXME: If we made macros from this module visible but didn't provide a
2007*0a6a1f1dSLionel Sambuc // source location for the import, we don't have a location for the macro.
2008*0a6a1f1dSLionel Sambuc // Use the location at which the containing module file was first imported
2009*0a6a1f1dSLionel Sambuc // for now.
2010*0a6a1f1dSLionel Sambuc ImportLoc = MMI->F->DirectImportLoc;
2011*0a6a1f1dSLionel Sambuc assert(ImportLoc.isValid() && "no import location for a visible macro?");
2012*0a6a1f1dSLionel Sambuc }
2013*0a6a1f1dSLionel Sambuc
2014*0a6a1f1dSLionel Sambuc AmbiguousMacros *Prev =
2015*0a6a1f1dSLionel Sambuc removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules());
2016*0a6a1f1dSLionel Sambuc
2017*0a6a1f1dSLionel Sambuc // Create a synthetic macro definition corresponding to the import (or null
2018*0a6a1f1dSLionel Sambuc // if this was an undefinition of the macro).
2019*0a6a1f1dSLionel Sambuc MacroDirective *Imported = MMI->import(PP, ImportLoc);
2020*0a6a1f1dSLionel Sambuc DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported);
2021*0a6a1f1dSLionel Sambuc
2022*0a6a1f1dSLionel Sambuc // If there's no ambiguity, just install the macro.
2023*0a6a1f1dSLionel Sambuc if (!Prev) {
2024*0a6a1f1dSLionel Sambuc PP.appendMacroDirective(II, Imported);
2025*0a6a1f1dSLionel Sambuc return;
2026*0a6a1f1dSLionel Sambuc }
2027*0a6a1f1dSLionel Sambuc assert(!Prev->empty());
2028*0a6a1f1dSLionel Sambuc
2029*0a6a1f1dSLionel Sambuc if (!MD) {
2030*0a6a1f1dSLionel Sambuc // We imported a #undef that didn't remove all prior definitions. The most
2031*0a6a1f1dSLionel Sambuc // recent prior definition remains, and we install it in the place of the
2032*0a6a1f1dSLionel Sambuc // imported directive, as if by a local #pragma pop_macro.
2033*0a6a1f1dSLionel Sambuc MacroInfo *NewMI = Prev->back()->getInfo();
2034*0a6a1f1dSLionel Sambuc Prev->pop_back();
2035*0a6a1f1dSLionel Sambuc MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc);
2036*0a6a1f1dSLionel Sambuc
2037*0a6a1f1dSLionel Sambuc // Install our #undef first so that we don't lose track of it. We'll replace
2038*0a6a1f1dSLionel Sambuc // this with whichever macro definition ends up winning.
2039*0a6a1f1dSLionel Sambuc PP.appendMacroDirective(II, Imported);
2040*0a6a1f1dSLionel Sambuc }
2041*0a6a1f1dSLionel Sambuc
2042*0a6a1f1dSLionel Sambuc // We're introducing a macro definition that creates or adds to an ambiguity.
2043*0a6a1f1dSLionel Sambuc // We can resolve that ambiguity if this macro is token-for-token identical to
2044*0a6a1f1dSLionel Sambuc // all of the existing definitions.
2045*0a6a1f1dSLionel Sambuc MacroInfo *NewMI = MD->getInfo();
2046*0a6a1f1dSLionel Sambuc assert(NewMI && "macro definition with no MacroInfo?");
2047*0a6a1f1dSLionel Sambuc while (!Prev->empty()) {
2048*0a6a1f1dSLionel Sambuc MacroInfo *PrevMI = Prev->back()->getInfo();
2049*0a6a1f1dSLionel Sambuc assert(PrevMI && "macro definition with no MacroInfo?");
2050*0a6a1f1dSLionel Sambuc
2051f4a2713aSLionel Sambuc // Before marking the macros as ambiguous, check if this is a case where
2052f4a2713aSLionel Sambuc // both macros are in system headers. If so, we trust that the system
2053f4a2713aSLionel Sambuc // did not get it wrong. This also handles cases where Clang's own
2054f4a2713aSLionel Sambuc // headers have a different spelling of certain system macros:
2055f4a2713aSLionel Sambuc // #define LONG_MAX __LONG_MAX__ (clang's limits.h)
2056f4a2713aSLionel Sambuc // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
2057*0a6a1f1dSLionel Sambuc //
2058*0a6a1f1dSLionel Sambuc // FIXME: Remove the defined-in-system-headers check. clang's limits.h
2059*0a6a1f1dSLionel Sambuc // overrides the system limits.h's macros, so there's no conflict here.
2060*0a6a1f1dSLionel Sambuc if (NewMI != PrevMI &&
2061*0a6a1f1dSLionel Sambuc !PrevMI->isIdenticalTo(*NewMI, PP, /*Syntactically=*/true) &&
2062*0a6a1f1dSLionel Sambuc !areDefinedInSystemModules(PrevMI, NewMI, Owner, *this))
2063*0a6a1f1dSLionel Sambuc break;
2064*0a6a1f1dSLionel Sambuc
2065*0a6a1f1dSLionel Sambuc // The previous definition is the same as this one (or both are defined in
2066*0a6a1f1dSLionel Sambuc // system modules so we can assume they're equivalent); we don't need to
2067*0a6a1f1dSLionel Sambuc // track it any more.
2068*0a6a1f1dSLionel Sambuc Prev->pop_back();
2069f4a2713aSLionel Sambuc }
2070f4a2713aSLionel Sambuc
2071*0a6a1f1dSLionel Sambuc if (!Prev->empty())
2072*0a6a1f1dSLionel Sambuc MD->setAmbiguous(true);
2073*0a6a1f1dSLionel Sambuc
2074f4a2713aSLionel Sambuc PP.appendMacroDirective(II, MD);
2075f4a2713aSLionel Sambuc }
2076f4a2713aSLionel Sambuc
2077*0a6a1f1dSLionel Sambuc ASTReader::InputFileInfo
readInputFileInfo(ModuleFile & F,unsigned ID)2078*0a6a1f1dSLionel Sambuc ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
2079*0a6a1f1dSLionel Sambuc // Go find this input file.
2080*0a6a1f1dSLionel Sambuc BitstreamCursor &Cursor = F.InputFilesCursor;
2081*0a6a1f1dSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
2082*0a6a1f1dSLionel Sambuc Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
2083*0a6a1f1dSLionel Sambuc
2084*0a6a1f1dSLionel Sambuc unsigned Code = Cursor.ReadCode();
2085*0a6a1f1dSLionel Sambuc RecordData Record;
2086*0a6a1f1dSLionel Sambuc StringRef Blob;
2087*0a6a1f1dSLionel Sambuc
2088*0a6a1f1dSLionel Sambuc unsigned Result = Cursor.readRecord(Code, Record, &Blob);
2089*0a6a1f1dSLionel Sambuc assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE &&
2090*0a6a1f1dSLionel Sambuc "invalid record type for input file");
2091*0a6a1f1dSLionel Sambuc (void)Result;
2092*0a6a1f1dSLionel Sambuc
2093*0a6a1f1dSLionel Sambuc std::string Filename;
2094*0a6a1f1dSLionel Sambuc off_t StoredSize;
2095*0a6a1f1dSLionel Sambuc time_t StoredTime;
2096*0a6a1f1dSLionel Sambuc bool Overridden;
2097*0a6a1f1dSLionel Sambuc
2098*0a6a1f1dSLionel Sambuc assert(Record[0] == ID && "Bogus stored ID or offset");
2099*0a6a1f1dSLionel Sambuc StoredSize = static_cast<off_t>(Record[1]);
2100*0a6a1f1dSLionel Sambuc StoredTime = static_cast<time_t>(Record[2]);
2101*0a6a1f1dSLionel Sambuc Overridden = static_cast<bool>(Record[3]);
2102*0a6a1f1dSLionel Sambuc Filename = Blob;
2103*0a6a1f1dSLionel Sambuc ResolveImportedPath(F, Filename);
2104*0a6a1f1dSLionel Sambuc
2105*0a6a1f1dSLionel Sambuc InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden };
2106*0a6a1f1dSLionel Sambuc return R;
2107*0a6a1f1dSLionel Sambuc }
2108*0a6a1f1dSLionel Sambuc
getInputFileName(ModuleFile & F,unsigned int ID)2109*0a6a1f1dSLionel Sambuc std::string ASTReader::getInputFileName(ModuleFile &F, unsigned int ID) {
2110*0a6a1f1dSLionel Sambuc return readInputFileInfo(F, ID).Filename;
2111*0a6a1f1dSLionel Sambuc }
2112*0a6a1f1dSLionel Sambuc
getInputFile(ModuleFile & F,unsigned ID,bool Complain)2113f4a2713aSLionel Sambuc InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
2114f4a2713aSLionel Sambuc // If this ID is bogus, just return an empty input file.
2115f4a2713aSLionel Sambuc if (ID == 0 || ID > F.InputFilesLoaded.size())
2116f4a2713aSLionel Sambuc return InputFile();
2117f4a2713aSLionel Sambuc
2118f4a2713aSLionel Sambuc // If we've already loaded this input file, return it.
2119f4a2713aSLionel Sambuc if (F.InputFilesLoaded[ID-1].getFile())
2120f4a2713aSLionel Sambuc return F.InputFilesLoaded[ID-1];
2121f4a2713aSLionel Sambuc
2122*0a6a1f1dSLionel Sambuc if (F.InputFilesLoaded[ID-1].isNotFound())
2123*0a6a1f1dSLionel Sambuc return InputFile();
2124*0a6a1f1dSLionel Sambuc
2125f4a2713aSLionel Sambuc // Go find this input file.
2126f4a2713aSLionel Sambuc BitstreamCursor &Cursor = F.InputFilesCursor;
2127f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
2128f4a2713aSLionel Sambuc Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
2129f4a2713aSLionel Sambuc
2130*0a6a1f1dSLionel Sambuc InputFileInfo FI = readInputFileInfo(F, ID);
2131*0a6a1f1dSLionel Sambuc off_t StoredSize = FI.StoredSize;
2132*0a6a1f1dSLionel Sambuc time_t StoredTime = FI.StoredTime;
2133*0a6a1f1dSLionel Sambuc bool Overridden = FI.Overridden;
2134*0a6a1f1dSLionel Sambuc StringRef Filename = FI.Filename;
2135f4a2713aSLionel Sambuc
2136f4a2713aSLionel Sambuc const FileEntry *File
2137f4a2713aSLionel Sambuc = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
2138f4a2713aSLionel Sambuc : FileMgr.getFile(Filename, /*OpenFile=*/false);
2139f4a2713aSLionel Sambuc
2140f4a2713aSLionel Sambuc // If we didn't find the file, resolve it relative to the
2141f4a2713aSLionel Sambuc // original directory from which this AST file was created.
2142*0a6a1f1dSLionel Sambuc if (File == nullptr && !F.OriginalDir.empty() && !CurrentDir.empty() &&
2143f4a2713aSLionel Sambuc F.OriginalDir != CurrentDir) {
2144f4a2713aSLionel Sambuc std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
2145f4a2713aSLionel Sambuc F.OriginalDir,
2146f4a2713aSLionel Sambuc CurrentDir);
2147f4a2713aSLionel Sambuc if (!Resolved.empty())
2148f4a2713aSLionel Sambuc File = FileMgr.getFile(Resolved);
2149f4a2713aSLionel Sambuc }
2150f4a2713aSLionel Sambuc
2151f4a2713aSLionel Sambuc // For an overridden file, create a virtual file with the stored
2152f4a2713aSLionel Sambuc // size/timestamp.
2153*0a6a1f1dSLionel Sambuc if (Overridden && File == nullptr) {
2154f4a2713aSLionel Sambuc File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
2155f4a2713aSLionel Sambuc }
2156f4a2713aSLionel Sambuc
2157*0a6a1f1dSLionel Sambuc if (File == nullptr) {
2158f4a2713aSLionel Sambuc if (Complain) {
2159f4a2713aSLionel Sambuc std::string ErrorStr = "could not find file '";
2160f4a2713aSLionel Sambuc ErrorStr += Filename;
2161f4a2713aSLionel Sambuc ErrorStr += "' referenced by AST file";
2162f4a2713aSLionel Sambuc Error(ErrorStr.c_str());
2163f4a2713aSLionel Sambuc }
2164*0a6a1f1dSLionel Sambuc // Record that we didn't find the file.
2165*0a6a1f1dSLionel Sambuc F.InputFilesLoaded[ID-1] = InputFile::getNotFound();
2166f4a2713aSLionel Sambuc return InputFile();
2167f4a2713aSLionel Sambuc }
2168f4a2713aSLionel Sambuc
2169f4a2713aSLionel Sambuc // Check if there was a request to override the contents of the file
2170f4a2713aSLionel Sambuc // that was part of the precompiled header. Overridding such a file
2171f4a2713aSLionel Sambuc // can lead to problems when lexing using the source locations from the
2172f4a2713aSLionel Sambuc // PCH.
2173f4a2713aSLionel Sambuc SourceManager &SM = getSourceManager();
2174f4a2713aSLionel Sambuc if (!Overridden && SM.isFileOverridden(File)) {
2175f4a2713aSLionel Sambuc if (Complain)
2176f4a2713aSLionel Sambuc Error(diag::err_fe_pch_file_overridden, Filename);
2177f4a2713aSLionel Sambuc // After emitting the diagnostic, recover by disabling the override so
2178f4a2713aSLionel Sambuc // that the original file will be used.
2179f4a2713aSLionel Sambuc SM.disableFileContentsOverride(File);
2180f4a2713aSLionel Sambuc // The FileEntry is a virtual file entry with the size of the contents
2181f4a2713aSLionel Sambuc // that would override the original contents. Set it to the original's
2182f4a2713aSLionel Sambuc // size/time.
2183f4a2713aSLionel Sambuc FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
2184f4a2713aSLionel Sambuc StoredSize, StoredTime);
2185f4a2713aSLionel Sambuc }
2186f4a2713aSLionel Sambuc
2187f4a2713aSLionel Sambuc bool IsOutOfDate = false;
2188f4a2713aSLionel Sambuc
2189f4a2713aSLionel Sambuc // For an overridden file, there is nothing to validate.
2190*0a6a1f1dSLionel Sambuc if (!Overridden && //
2191*0a6a1f1dSLionel Sambuc (StoredSize != File->getSize() ||
2192*0a6a1f1dSLionel Sambuc #if defined(LLVM_ON_WIN32)
2193*0a6a1f1dSLionel Sambuc false
2194*0a6a1f1dSLionel Sambuc #else
2195f4a2713aSLionel Sambuc // In our regression testing, the Windows file system seems to
2196f4a2713aSLionel Sambuc // have inconsistent modification times that sometimes
2197f4a2713aSLionel Sambuc // erroneously trigger this error-handling path.
2198*0a6a1f1dSLionel Sambuc //
2199*0a6a1f1dSLionel Sambuc // This also happens in networked file systems, so disable this
2200*0a6a1f1dSLionel Sambuc // check if validation is disabled or if we have an explicitly
2201*0a6a1f1dSLionel Sambuc // built PCM file.
2202*0a6a1f1dSLionel Sambuc //
2203*0a6a1f1dSLionel Sambuc // FIXME: Should we also do this for PCH files? They could also
2204*0a6a1f1dSLionel Sambuc // reasonably get shared across a network during a distributed build.
2205*0a6a1f1dSLionel Sambuc (StoredTime != File->getModificationTime() && !DisableValidation &&
2206*0a6a1f1dSLionel Sambuc F.Kind != MK_ExplicitModule)
2207f4a2713aSLionel Sambuc #endif
2208f4a2713aSLionel Sambuc )) {
2209f4a2713aSLionel Sambuc if (Complain) {
2210*0a6a1f1dSLionel Sambuc // Build a list of the PCH imports that got us here (in reverse).
2211*0a6a1f1dSLionel Sambuc SmallVector<ModuleFile *, 4> ImportStack(1, &F);
2212*0a6a1f1dSLionel Sambuc while (ImportStack.back()->ImportedBy.size() > 0)
2213*0a6a1f1dSLionel Sambuc ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
2214*0a6a1f1dSLionel Sambuc
2215*0a6a1f1dSLionel Sambuc // The top-level PCH is stale.
2216*0a6a1f1dSLionel Sambuc StringRef TopLevelPCHName(ImportStack.back()->FileName);
2217*0a6a1f1dSLionel Sambuc Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName);
2218*0a6a1f1dSLionel Sambuc
2219*0a6a1f1dSLionel Sambuc // Print the import stack.
2220*0a6a1f1dSLionel Sambuc if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
2221*0a6a1f1dSLionel Sambuc Diag(diag::note_pch_required_by)
2222*0a6a1f1dSLionel Sambuc << Filename << ImportStack[0]->FileName;
2223*0a6a1f1dSLionel Sambuc for (unsigned I = 1; I < ImportStack.size(); ++I)
2224*0a6a1f1dSLionel Sambuc Diag(diag::note_pch_required_by)
2225*0a6a1f1dSLionel Sambuc << ImportStack[I-1]->FileName << ImportStack[I]->FileName;
2226f4a2713aSLionel Sambuc }
2227*0a6a1f1dSLionel Sambuc
2228*0a6a1f1dSLionel Sambuc if (!Diags.isDiagnosticInFlight())
2229*0a6a1f1dSLionel Sambuc Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
2230f4a2713aSLionel Sambuc }
2231f4a2713aSLionel Sambuc
2232f4a2713aSLionel Sambuc IsOutOfDate = true;
2233f4a2713aSLionel Sambuc }
2234f4a2713aSLionel Sambuc
2235f4a2713aSLionel Sambuc InputFile IF = InputFile(File, Overridden, IsOutOfDate);
2236f4a2713aSLionel Sambuc
2237f4a2713aSLionel Sambuc // Note that we've loaded this input file.
2238f4a2713aSLionel Sambuc F.InputFilesLoaded[ID-1] = IF;
2239f4a2713aSLionel Sambuc return IF;
2240f4a2713aSLionel Sambuc }
2241*0a6a1f1dSLionel Sambuc
2242*0a6a1f1dSLionel Sambuc /// \brief If we are loading a relocatable PCH or module file, and the filename
2243*0a6a1f1dSLionel Sambuc /// is not an absolute path, add the system or module root to the beginning of
2244*0a6a1f1dSLionel Sambuc /// the file name.
ResolveImportedPath(ModuleFile & M,std::string & Filename)2245*0a6a1f1dSLionel Sambuc void ASTReader::ResolveImportedPath(ModuleFile &M, std::string &Filename) {
2246*0a6a1f1dSLionel Sambuc // Resolve relative to the base directory, if we have one.
2247*0a6a1f1dSLionel Sambuc if (!M.BaseDirectory.empty())
2248*0a6a1f1dSLionel Sambuc return ResolveImportedPath(Filename, M.BaseDirectory);
2249f4a2713aSLionel Sambuc }
2250f4a2713aSLionel Sambuc
ResolveImportedPath(std::string & Filename,StringRef Prefix)2251*0a6a1f1dSLionel Sambuc void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) {
2252f4a2713aSLionel Sambuc if (Filename.empty() || llvm::sys::path::is_absolute(Filename))
2253f4a2713aSLionel Sambuc return;
2254f4a2713aSLionel Sambuc
2255*0a6a1f1dSLionel Sambuc SmallString<128> Buffer;
2256*0a6a1f1dSLionel Sambuc llvm::sys::path::append(Buffer, Prefix, Filename);
2257*0a6a1f1dSLionel Sambuc Filename.assign(Buffer.begin(), Buffer.end());
2258f4a2713aSLionel Sambuc }
2259f4a2713aSLionel Sambuc
2260f4a2713aSLionel Sambuc ASTReader::ASTReadResult
ReadControlBlock(ModuleFile & F,SmallVectorImpl<ImportedModule> & Loaded,const ModuleFile * ImportedBy,unsigned ClientLoadCapabilities)2261f4a2713aSLionel Sambuc ASTReader::ReadControlBlock(ModuleFile &F,
2262f4a2713aSLionel Sambuc SmallVectorImpl<ImportedModule> &Loaded,
2263*0a6a1f1dSLionel Sambuc const ModuleFile *ImportedBy,
2264f4a2713aSLionel Sambuc unsigned ClientLoadCapabilities) {
2265f4a2713aSLionel Sambuc BitstreamCursor &Stream = F.Stream;
2266f4a2713aSLionel Sambuc
2267f4a2713aSLionel Sambuc if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
2268f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2269f4a2713aSLionel Sambuc return Failure;
2270f4a2713aSLionel Sambuc }
2271f4a2713aSLionel Sambuc
2272*0a6a1f1dSLionel Sambuc // Should we allow the configuration of the module file to differ from the
2273*0a6a1f1dSLionel Sambuc // configuration of the current translation unit in a compatible way?
2274*0a6a1f1dSLionel Sambuc //
2275*0a6a1f1dSLionel Sambuc // FIXME: Allow this for files explicitly specified with -include-pch too.
2276*0a6a1f1dSLionel Sambuc bool AllowCompatibleConfigurationMismatch = F.Kind == MK_ExplicitModule;
2277*0a6a1f1dSLionel Sambuc
2278f4a2713aSLionel Sambuc // Read all of the records and blocks in the control block.
2279f4a2713aSLionel Sambuc RecordData Record;
2280*0a6a1f1dSLionel Sambuc unsigned NumInputs = 0;
2281*0a6a1f1dSLionel Sambuc unsigned NumUserInputs = 0;
2282f4a2713aSLionel Sambuc while (1) {
2283f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advance();
2284f4a2713aSLionel Sambuc
2285f4a2713aSLionel Sambuc switch (Entry.Kind) {
2286f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
2287f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2288f4a2713aSLionel Sambuc return Failure;
2289*0a6a1f1dSLionel Sambuc case llvm::BitstreamEntry::EndBlock: {
2290*0a6a1f1dSLionel Sambuc // Validate input files.
2291*0a6a1f1dSLionel Sambuc const HeaderSearchOptions &HSOpts =
2292*0a6a1f1dSLionel Sambuc PP.getHeaderSearchInfo().getHeaderSearchOpts();
2293*0a6a1f1dSLionel Sambuc
2294*0a6a1f1dSLionel Sambuc // All user input files reside at the index range [0, NumUserInputs), and
2295*0a6a1f1dSLionel Sambuc // system input files reside at [NumUserInputs, NumInputs).
2296f4a2713aSLionel Sambuc if (!DisableValidation) {
2297f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
2298*0a6a1f1dSLionel Sambuc
2299*0a6a1f1dSLionel Sambuc // If we are reading a module, we will create a verification timestamp,
2300*0a6a1f1dSLionel Sambuc // so we verify all input files. Otherwise, verify only user input
2301*0a6a1f1dSLionel Sambuc // files.
2302*0a6a1f1dSLionel Sambuc
2303*0a6a1f1dSLionel Sambuc unsigned N = NumUserInputs;
2304*0a6a1f1dSLionel Sambuc if (ValidateSystemInputs ||
2305*0a6a1f1dSLionel Sambuc (HSOpts.ModulesValidateOncePerBuildSession &&
2306*0a6a1f1dSLionel Sambuc F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp &&
2307*0a6a1f1dSLionel Sambuc F.Kind == MK_ImplicitModule))
2308*0a6a1f1dSLionel Sambuc N = NumInputs;
2309*0a6a1f1dSLionel Sambuc
2310*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I < N; ++I) {
2311f4a2713aSLionel Sambuc InputFile IF = getInputFile(F, I+1, Complain);
2312f4a2713aSLionel Sambuc if (!IF.getFile() || IF.isOutOfDate())
2313f4a2713aSLionel Sambuc return OutOfDate;
2314f4a2713aSLionel Sambuc }
2315f4a2713aSLionel Sambuc }
2316*0a6a1f1dSLionel Sambuc
2317*0a6a1f1dSLionel Sambuc if (Listener)
2318*0a6a1f1dSLionel Sambuc Listener->visitModuleFile(F.FileName);
2319*0a6a1f1dSLionel Sambuc
2320*0a6a1f1dSLionel Sambuc if (Listener && Listener->needsInputFileVisitation()) {
2321*0a6a1f1dSLionel Sambuc unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs
2322*0a6a1f1dSLionel Sambuc : NumUserInputs;
2323*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I < N; ++I) {
2324*0a6a1f1dSLionel Sambuc bool IsSystem = I >= NumUserInputs;
2325*0a6a1f1dSLionel Sambuc InputFileInfo FI = readInputFileInfo(F, I+1);
2326*0a6a1f1dSLionel Sambuc Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden);
2327*0a6a1f1dSLionel Sambuc }
2328*0a6a1f1dSLionel Sambuc }
2329*0a6a1f1dSLionel Sambuc
2330f4a2713aSLionel Sambuc return Success;
2331*0a6a1f1dSLionel Sambuc }
2332f4a2713aSLionel Sambuc
2333f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock:
2334f4a2713aSLionel Sambuc switch (Entry.ID) {
2335f4a2713aSLionel Sambuc case INPUT_FILES_BLOCK_ID:
2336f4a2713aSLionel Sambuc F.InputFilesCursor = Stream;
2337f4a2713aSLionel Sambuc if (Stream.SkipBlock() || // Skip with the main cursor
2338f4a2713aSLionel Sambuc // Read the abbreviations
2339f4a2713aSLionel Sambuc ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {
2340f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2341f4a2713aSLionel Sambuc return Failure;
2342f4a2713aSLionel Sambuc }
2343f4a2713aSLionel Sambuc continue;
2344f4a2713aSLionel Sambuc
2345f4a2713aSLionel Sambuc default:
2346f4a2713aSLionel Sambuc if (Stream.SkipBlock()) {
2347f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2348f4a2713aSLionel Sambuc return Failure;
2349f4a2713aSLionel Sambuc }
2350f4a2713aSLionel Sambuc continue;
2351f4a2713aSLionel Sambuc }
2352f4a2713aSLionel Sambuc
2353f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
2354f4a2713aSLionel Sambuc // The interesting case.
2355f4a2713aSLionel Sambuc break;
2356f4a2713aSLionel Sambuc }
2357f4a2713aSLionel Sambuc
2358f4a2713aSLionel Sambuc // Read and process a record.
2359f4a2713aSLionel Sambuc Record.clear();
2360f4a2713aSLionel Sambuc StringRef Blob;
2361f4a2713aSLionel Sambuc switch ((ControlRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob)) {
2362f4a2713aSLionel Sambuc case METADATA: {
2363f4a2713aSLionel Sambuc if (Record[0] != VERSION_MAJOR && !DisableValidation) {
2364f4a2713aSLionel Sambuc if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
2365*0a6a1f1dSLionel Sambuc Diag(Record[0] < VERSION_MAJOR? diag::err_pch_version_too_old
2366*0a6a1f1dSLionel Sambuc : diag::err_pch_version_too_new);
2367f4a2713aSLionel Sambuc return VersionMismatch;
2368f4a2713aSLionel Sambuc }
2369f4a2713aSLionel Sambuc
2370f4a2713aSLionel Sambuc bool hasErrors = Record[5];
2371f4a2713aSLionel Sambuc if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
2372f4a2713aSLionel Sambuc Diag(diag::err_pch_with_compiler_errors);
2373f4a2713aSLionel Sambuc return HadErrors;
2374f4a2713aSLionel Sambuc }
2375f4a2713aSLionel Sambuc
2376f4a2713aSLionel Sambuc F.RelocatablePCH = Record[4];
2377*0a6a1f1dSLionel Sambuc // Relative paths in a relocatable PCH are relative to our sysroot.
2378*0a6a1f1dSLionel Sambuc if (F.RelocatablePCH)
2379*0a6a1f1dSLionel Sambuc F.BaseDirectory = isysroot.empty() ? "/" : isysroot;
2380f4a2713aSLionel Sambuc
2381f4a2713aSLionel Sambuc const std::string &CurBranch = getClangFullRepositoryVersion();
2382f4a2713aSLionel Sambuc StringRef ASTBranch = Blob;
2383f4a2713aSLionel Sambuc if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
2384f4a2713aSLionel Sambuc if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
2385*0a6a1f1dSLionel Sambuc Diag(diag::err_pch_different_branch) << ASTBranch << CurBranch;
2386f4a2713aSLionel Sambuc return VersionMismatch;
2387f4a2713aSLionel Sambuc }
2388f4a2713aSLionel Sambuc break;
2389f4a2713aSLionel Sambuc }
2390f4a2713aSLionel Sambuc
2391*0a6a1f1dSLionel Sambuc case SIGNATURE:
2392*0a6a1f1dSLionel Sambuc assert((!F.Signature || F.Signature == Record[0]) && "signature changed");
2393*0a6a1f1dSLionel Sambuc F.Signature = Record[0];
2394*0a6a1f1dSLionel Sambuc break;
2395*0a6a1f1dSLionel Sambuc
2396f4a2713aSLionel Sambuc case IMPORTS: {
2397f4a2713aSLionel Sambuc // Load each of the imported PCH files.
2398f4a2713aSLionel Sambuc unsigned Idx = 0, N = Record.size();
2399f4a2713aSLionel Sambuc while (Idx < N) {
2400f4a2713aSLionel Sambuc // Read information about the AST file.
2401f4a2713aSLionel Sambuc ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
2402f4a2713aSLionel Sambuc // The import location will be the local one for now; we will adjust
2403f4a2713aSLionel Sambuc // all import locations of module imports after the global source
2404f4a2713aSLionel Sambuc // location info are setup.
2405f4a2713aSLionel Sambuc SourceLocation ImportLoc =
2406f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(Record[Idx++]);
2407f4a2713aSLionel Sambuc off_t StoredSize = (off_t)Record[Idx++];
2408f4a2713aSLionel Sambuc time_t StoredModTime = (time_t)Record[Idx++];
2409*0a6a1f1dSLionel Sambuc ASTFileSignature StoredSignature = Record[Idx++];
2410*0a6a1f1dSLionel Sambuc auto ImportedFile = ReadPath(F, Record, Idx);
2411f4a2713aSLionel Sambuc
2412f4a2713aSLionel Sambuc // Load the AST file.
2413f4a2713aSLionel Sambuc switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded,
2414*0a6a1f1dSLionel Sambuc StoredSize, StoredModTime, StoredSignature,
2415f4a2713aSLionel Sambuc ClientLoadCapabilities)) {
2416f4a2713aSLionel Sambuc case Failure: return Failure;
2417f4a2713aSLionel Sambuc // If we have to ignore the dependency, we'll have to ignore this too.
2418f4a2713aSLionel Sambuc case Missing:
2419f4a2713aSLionel Sambuc case OutOfDate: return OutOfDate;
2420f4a2713aSLionel Sambuc case VersionMismatch: return VersionMismatch;
2421f4a2713aSLionel Sambuc case ConfigurationMismatch: return ConfigurationMismatch;
2422f4a2713aSLionel Sambuc case HadErrors: return HadErrors;
2423f4a2713aSLionel Sambuc case Success: break;
2424f4a2713aSLionel Sambuc }
2425f4a2713aSLionel Sambuc }
2426f4a2713aSLionel Sambuc break;
2427f4a2713aSLionel Sambuc }
2428f4a2713aSLionel Sambuc
2429f4a2713aSLionel Sambuc case LANGUAGE_OPTIONS: {
2430f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
2431*0a6a1f1dSLionel Sambuc // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules.
2432f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2433*0a6a1f1dSLionel Sambuc ParseLanguageOptions(Record, Complain, *Listener,
2434*0a6a1f1dSLionel Sambuc AllowCompatibleConfigurationMismatch) &&
2435*0a6a1f1dSLionel Sambuc !DisableValidation && !AllowConfigurationMismatch)
2436f4a2713aSLionel Sambuc return ConfigurationMismatch;
2437f4a2713aSLionel Sambuc break;
2438f4a2713aSLionel Sambuc }
2439f4a2713aSLionel Sambuc
2440f4a2713aSLionel Sambuc case TARGET_OPTIONS: {
2441f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
2442f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2443f4a2713aSLionel Sambuc ParseTargetOptions(Record, Complain, *Listener) &&
2444*0a6a1f1dSLionel Sambuc !DisableValidation && !AllowConfigurationMismatch)
2445f4a2713aSLionel Sambuc return ConfigurationMismatch;
2446f4a2713aSLionel Sambuc break;
2447f4a2713aSLionel Sambuc }
2448f4a2713aSLionel Sambuc
2449f4a2713aSLionel Sambuc case DIAGNOSTIC_OPTIONS: {
2450*0a6a1f1dSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
2451f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2452*0a6a1f1dSLionel Sambuc !AllowCompatibleConfigurationMismatch &&
2453f4a2713aSLionel Sambuc ParseDiagnosticOptions(Record, Complain, *Listener) &&
2454f4a2713aSLionel Sambuc !DisableValidation)
2455*0a6a1f1dSLionel Sambuc return OutOfDate;
2456f4a2713aSLionel Sambuc break;
2457f4a2713aSLionel Sambuc }
2458f4a2713aSLionel Sambuc
2459f4a2713aSLionel Sambuc case FILE_SYSTEM_OPTIONS: {
2460f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
2461f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2462*0a6a1f1dSLionel Sambuc !AllowCompatibleConfigurationMismatch &&
2463f4a2713aSLionel Sambuc ParseFileSystemOptions(Record, Complain, *Listener) &&
2464*0a6a1f1dSLionel Sambuc !DisableValidation && !AllowConfigurationMismatch)
2465f4a2713aSLionel Sambuc return ConfigurationMismatch;
2466f4a2713aSLionel Sambuc break;
2467f4a2713aSLionel Sambuc }
2468f4a2713aSLionel Sambuc
2469f4a2713aSLionel Sambuc case HEADER_SEARCH_OPTIONS: {
2470f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
2471f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2472*0a6a1f1dSLionel Sambuc !AllowCompatibleConfigurationMismatch &&
2473f4a2713aSLionel Sambuc ParseHeaderSearchOptions(Record, Complain, *Listener) &&
2474*0a6a1f1dSLionel Sambuc !DisableValidation && !AllowConfigurationMismatch)
2475f4a2713aSLionel Sambuc return ConfigurationMismatch;
2476f4a2713aSLionel Sambuc break;
2477f4a2713aSLionel Sambuc }
2478f4a2713aSLionel Sambuc
2479f4a2713aSLionel Sambuc case PREPROCESSOR_OPTIONS: {
2480f4a2713aSLionel Sambuc bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
2481f4a2713aSLionel Sambuc if (Listener && &F == *ModuleMgr.begin() &&
2482*0a6a1f1dSLionel Sambuc !AllowCompatibleConfigurationMismatch &&
2483f4a2713aSLionel Sambuc ParsePreprocessorOptions(Record, Complain, *Listener,
2484f4a2713aSLionel Sambuc SuggestedPredefines) &&
2485*0a6a1f1dSLionel Sambuc !DisableValidation && !AllowConfigurationMismatch)
2486f4a2713aSLionel Sambuc return ConfigurationMismatch;
2487f4a2713aSLionel Sambuc break;
2488f4a2713aSLionel Sambuc }
2489f4a2713aSLionel Sambuc
2490f4a2713aSLionel Sambuc case ORIGINAL_FILE:
2491f4a2713aSLionel Sambuc F.OriginalSourceFileID = FileID::get(Record[0]);
2492f4a2713aSLionel Sambuc F.ActualOriginalSourceFileName = Blob;
2493f4a2713aSLionel Sambuc F.OriginalSourceFileName = F.ActualOriginalSourceFileName;
2494*0a6a1f1dSLionel Sambuc ResolveImportedPath(F, F.OriginalSourceFileName);
2495f4a2713aSLionel Sambuc break;
2496f4a2713aSLionel Sambuc
2497f4a2713aSLionel Sambuc case ORIGINAL_FILE_ID:
2498f4a2713aSLionel Sambuc F.OriginalSourceFileID = FileID::get(Record[0]);
2499f4a2713aSLionel Sambuc break;
2500f4a2713aSLionel Sambuc
2501f4a2713aSLionel Sambuc case ORIGINAL_PCH_DIR:
2502f4a2713aSLionel Sambuc F.OriginalDir = Blob;
2503f4a2713aSLionel Sambuc break;
2504f4a2713aSLionel Sambuc
2505*0a6a1f1dSLionel Sambuc case MODULE_NAME:
2506*0a6a1f1dSLionel Sambuc F.ModuleName = Blob;
2507*0a6a1f1dSLionel Sambuc if (Listener)
2508*0a6a1f1dSLionel Sambuc Listener->ReadModuleName(F.ModuleName);
2509*0a6a1f1dSLionel Sambuc break;
2510*0a6a1f1dSLionel Sambuc
2511*0a6a1f1dSLionel Sambuc case MODULE_DIRECTORY: {
2512*0a6a1f1dSLionel Sambuc assert(!F.ModuleName.empty() &&
2513*0a6a1f1dSLionel Sambuc "MODULE_DIRECTORY found before MODULE_NAME");
2514*0a6a1f1dSLionel Sambuc // If we've already loaded a module map file covering this module, we may
2515*0a6a1f1dSLionel Sambuc // have a better path for it (relative to the current build).
2516*0a6a1f1dSLionel Sambuc Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
2517*0a6a1f1dSLionel Sambuc if (M && M->Directory) {
2518*0a6a1f1dSLionel Sambuc // If we're implicitly loading a module, the base directory can't
2519*0a6a1f1dSLionel Sambuc // change between the build and use.
2520*0a6a1f1dSLionel Sambuc if (F.Kind != MK_ExplicitModule) {
2521*0a6a1f1dSLionel Sambuc const DirectoryEntry *BuildDir =
2522*0a6a1f1dSLionel Sambuc PP.getFileManager().getDirectory(Blob);
2523*0a6a1f1dSLionel Sambuc if (!BuildDir || BuildDir != M->Directory) {
2524*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
2525*0a6a1f1dSLionel Sambuc Diag(diag::err_imported_module_relocated)
2526*0a6a1f1dSLionel Sambuc << F.ModuleName << Blob << M->Directory->getName();
2527*0a6a1f1dSLionel Sambuc return OutOfDate;
2528*0a6a1f1dSLionel Sambuc }
2529*0a6a1f1dSLionel Sambuc }
2530*0a6a1f1dSLionel Sambuc F.BaseDirectory = M->Directory->getName();
2531*0a6a1f1dSLionel Sambuc } else {
2532*0a6a1f1dSLionel Sambuc F.BaseDirectory = Blob;
2533*0a6a1f1dSLionel Sambuc }
2534*0a6a1f1dSLionel Sambuc break;
2535*0a6a1f1dSLionel Sambuc }
2536*0a6a1f1dSLionel Sambuc
2537*0a6a1f1dSLionel Sambuc case MODULE_MAP_FILE:
2538*0a6a1f1dSLionel Sambuc if (ASTReadResult Result =
2539*0a6a1f1dSLionel Sambuc ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities))
2540*0a6a1f1dSLionel Sambuc return Result;
2541*0a6a1f1dSLionel Sambuc break;
2542*0a6a1f1dSLionel Sambuc
2543f4a2713aSLionel Sambuc case INPUT_FILE_OFFSETS:
2544*0a6a1f1dSLionel Sambuc NumInputs = Record[0];
2545*0a6a1f1dSLionel Sambuc NumUserInputs = Record[1];
2546f4a2713aSLionel Sambuc F.InputFileOffsets = (const uint32_t *)Blob.data();
2547*0a6a1f1dSLionel Sambuc F.InputFilesLoaded.resize(NumInputs);
2548f4a2713aSLionel Sambuc break;
2549f4a2713aSLionel Sambuc }
2550f4a2713aSLionel Sambuc }
2551f4a2713aSLionel Sambuc }
2552f4a2713aSLionel Sambuc
2553*0a6a1f1dSLionel Sambuc ASTReader::ASTReadResult
ReadASTBlock(ModuleFile & F,unsigned ClientLoadCapabilities)2554*0a6a1f1dSLionel Sambuc ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
2555f4a2713aSLionel Sambuc BitstreamCursor &Stream = F.Stream;
2556f4a2713aSLionel Sambuc
2557f4a2713aSLionel Sambuc if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
2558f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2559*0a6a1f1dSLionel Sambuc return Failure;
2560f4a2713aSLionel Sambuc }
2561f4a2713aSLionel Sambuc
2562f4a2713aSLionel Sambuc // Read all of the records and blocks for the AST file.
2563f4a2713aSLionel Sambuc RecordData Record;
2564f4a2713aSLionel Sambuc while (1) {
2565f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advance();
2566f4a2713aSLionel Sambuc
2567f4a2713aSLionel Sambuc switch (Entry.Kind) {
2568f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
2569f4a2713aSLionel Sambuc Error("error at end of module block in AST file");
2570*0a6a1f1dSLionel Sambuc return Failure;
2571f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock: {
2572f4a2713aSLionel Sambuc // Outside of C++, we do not store a lookup map for the translation unit.
2573f4a2713aSLionel Sambuc // Instead, mark it as needing a lookup map to be built if this module
2574f4a2713aSLionel Sambuc // contains any declarations lexically within it (which it always does!).
2575f4a2713aSLionel Sambuc // This usually has no cost, since we very rarely need the lookup map for
2576f4a2713aSLionel Sambuc // the translation unit outside C++.
2577f4a2713aSLionel Sambuc DeclContext *DC = Context.getTranslationUnitDecl();
2578f4a2713aSLionel Sambuc if (DC->hasExternalLexicalStorage() &&
2579f4a2713aSLionel Sambuc !getContext().getLangOpts().CPlusPlus)
2580f4a2713aSLionel Sambuc DC->setMustBuildLookupTable();
2581f4a2713aSLionel Sambuc
2582*0a6a1f1dSLionel Sambuc return Success;
2583f4a2713aSLionel Sambuc }
2584f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock:
2585f4a2713aSLionel Sambuc switch (Entry.ID) {
2586f4a2713aSLionel Sambuc case DECLTYPES_BLOCK_ID:
2587f4a2713aSLionel Sambuc // We lazily load the decls block, but we want to set up the
2588f4a2713aSLionel Sambuc // DeclsCursor cursor to point into it. Clone our current bitcode
2589f4a2713aSLionel Sambuc // cursor to it, enter the block and read the abbrevs in that block.
2590f4a2713aSLionel Sambuc // With the main cursor, we just skip over it.
2591f4a2713aSLionel Sambuc F.DeclsCursor = Stream;
2592f4a2713aSLionel Sambuc if (Stream.SkipBlock() || // Skip with the main cursor.
2593f4a2713aSLionel Sambuc // Read the abbrevs.
2594f4a2713aSLionel Sambuc ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
2595f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2596*0a6a1f1dSLionel Sambuc return Failure;
2597f4a2713aSLionel Sambuc }
2598f4a2713aSLionel Sambuc break;
2599f4a2713aSLionel Sambuc
2600f4a2713aSLionel Sambuc case PREPROCESSOR_BLOCK_ID:
2601f4a2713aSLionel Sambuc F.MacroCursor = Stream;
2602f4a2713aSLionel Sambuc if (!PP.getExternalSource())
2603f4a2713aSLionel Sambuc PP.setExternalSource(this);
2604f4a2713aSLionel Sambuc
2605f4a2713aSLionel Sambuc if (Stream.SkipBlock() ||
2606f4a2713aSLionel Sambuc ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
2607f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2608*0a6a1f1dSLionel Sambuc return Failure;
2609f4a2713aSLionel Sambuc }
2610f4a2713aSLionel Sambuc F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
2611f4a2713aSLionel Sambuc break;
2612f4a2713aSLionel Sambuc
2613f4a2713aSLionel Sambuc case PREPROCESSOR_DETAIL_BLOCK_ID:
2614f4a2713aSLionel Sambuc F.PreprocessorDetailCursor = Stream;
2615f4a2713aSLionel Sambuc if (Stream.SkipBlock() ||
2616f4a2713aSLionel Sambuc ReadBlockAbbrevs(F.PreprocessorDetailCursor,
2617f4a2713aSLionel Sambuc PREPROCESSOR_DETAIL_BLOCK_ID)) {
2618f4a2713aSLionel Sambuc Error("malformed preprocessor detail record in AST file");
2619*0a6a1f1dSLionel Sambuc return Failure;
2620f4a2713aSLionel Sambuc }
2621f4a2713aSLionel Sambuc F.PreprocessorDetailStartOffset
2622f4a2713aSLionel Sambuc = F.PreprocessorDetailCursor.GetCurrentBitNo();
2623f4a2713aSLionel Sambuc
2624f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord())
2625f4a2713aSLionel Sambuc PP.createPreprocessingRecord();
2626f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord()->getExternalSource())
2627f4a2713aSLionel Sambuc PP.getPreprocessingRecord()->SetExternalSource(*this);
2628f4a2713aSLionel Sambuc break;
2629f4a2713aSLionel Sambuc
2630f4a2713aSLionel Sambuc case SOURCE_MANAGER_BLOCK_ID:
2631f4a2713aSLionel Sambuc if (ReadSourceManagerBlock(F))
2632*0a6a1f1dSLionel Sambuc return Failure;
2633f4a2713aSLionel Sambuc break;
2634f4a2713aSLionel Sambuc
2635f4a2713aSLionel Sambuc case SUBMODULE_BLOCK_ID:
2636*0a6a1f1dSLionel Sambuc if (ASTReadResult Result = ReadSubmoduleBlock(F, ClientLoadCapabilities))
2637*0a6a1f1dSLionel Sambuc return Result;
2638f4a2713aSLionel Sambuc break;
2639f4a2713aSLionel Sambuc
2640f4a2713aSLionel Sambuc case COMMENTS_BLOCK_ID: {
2641f4a2713aSLionel Sambuc BitstreamCursor C = Stream;
2642f4a2713aSLionel Sambuc if (Stream.SkipBlock() ||
2643f4a2713aSLionel Sambuc ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
2644f4a2713aSLionel Sambuc Error("malformed comments block in AST file");
2645*0a6a1f1dSLionel Sambuc return Failure;
2646f4a2713aSLionel Sambuc }
2647f4a2713aSLionel Sambuc CommentsCursors.push_back(std::make_pair(C, &F));
2648f4a2713aSLionel Sambuc break;
2649f4a2713aSLionel Sambuc }
2650f4a2713aSLionel Sambuc
2651f4a2713aSLionel Sambuc default:
2652f4a2713aSLionel Sambuc if (Stream.SkipBlock()) {
2653f4a2713aSLionel Sambuc Error("malformed block record in AST file");
2654*0a6a1f1dSLionel Sambuc return Failure;
2655f4a2713aSLionel Sambuc }
2656f4a2713aSLionel Sambuc break;
2657f4a2713aSLionel Sambuc }
2658f4a2713aSLionel Sambuc continue;
2659f4a2713aSLionel Sambuc
2660f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
2661f4a2713aSLionel Sambuc // The interesting case.
2662f4a2713aSLionel Sambuc break;
2663f4a2713aSLionel Sambuc }
2664f4a2713aSLionel Sambuc
2665f4a2713aSLionel Sambuc // Read and process a record.
2666f4a2713aSLionel Sambuc Record.clear();
2667f4a2713aSLionel Sambuc StringRef Blob;
2668f4a2713aSLionel Sambuc switch ((ASTRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob)) {
2669f4a2713aSLionel Sambuc default: // Default behavior: ignore.
2670f4a2713aSLionel Sambuc break;
2671f4a2713aSLionel Sambuc
2672f4a2713aSLionel Sambuc case TYPE_OFFSET: {
2673f4a2713aSLionel Sambuc if (F.LocalNumTypes != 0) {
2674f4a2713aSLionel Sambuc Error("duplicate TYPE_OFFSET record in AST file");
2675*0a6a1f1dSLionel Sambuc return Failure;
2676f4a2713aSLionel Sambuc }
2677f4a2713aSLionel Sambuc F.TypeOffsets = (const uint32_t *)Blob.data();
2678f4a2713aSLionel Sambuc F.LocalNumTypes = Record[0];
2679f4a2713aSLionel Sambuc unsigned LocalBaseTypeIndex = Record[1];
2680f4a2713aSLionel Sambuc F.BaseTypeIndex = getTotalNumTypes();
2681f4a2713aSLionel Sambuc
2682f4a2713aSLionel Sambuc if (F.LocalNumTypes > 0) {
2683f4a2713aSLionel Sambuc // Introduce the global -> local mapping for types within this module.
2684f4a2713aSLionel Sambuc GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
2685f4a2713aSLionel Sambuc
2686f4a2713aSLionel Sambuc // Introduce the local -> global mapping for types within this module.
2687f4a2713aSLionel Sambuc F.TypeRemap.insertOrReplace(
2688f4a2713aSLionel Sambuc std::make_pair(LocalBaseTypeIndex,
2689f4a2713aSLionel Sambuc F.BaseTypeIndex - LocalBaseTypeIndex));
2690f4a2713aSLionel Sambuc
2691f4a2713aSLionel Sambuc TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
2692f4a2713aSLionel Sambuc }
2693f4a2713aSLionel Sambuc break;
2694f4a2713aSLionel Sambuc }
2695f4a2713aSLionel Sambuc
2696f4a2713aSLionel Sambuc case DECL_OFFSET: {
2697f4a2713aSLionel Sambuc if (F.LocalNumDecls != 0) {
2698f4a2713aSLionel Sambuc Error("duplicate DECL_OFFSET record in AST file");
2699*0a6a1f1dSLionel Sambuc return Failure;
2700f4a2713aSLionel Sambuc }
2701f4a2713aSLionel Sambuc F.DeclOffsets = (const DeclOffset *)Blob.data();
2702f4a2713aSLionel Sambuc F.LocalNumDecls = Record[0];
2703f4a2713aSLionel Sambuc unsigned LocalBaseDeclID = Record[1];
2704f4a2713aSLionel Sambuc F.BaseDeclID = getTotalNumDecls();
2705f4a2713aSLionel Sambuc
2706f4a2713aSLionel Sambuc if (F.LocalNumDecls > 0) {
2707f4a2713aSLionel Sambuc // Introduce the global -> local mapping for declarations within this
2708f4a2713aSLionel Sambuc // module.
2709f4a2713aSLionel Sambuc GlobalDeclMap.insert(
2710f4a2713aSLionel Sambuc std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
2711f4a2713aSLionel Sambuc
2712f4a2713aSLionel Sambuc // Introduce the local -> global mapping for declarations within this
2713f4a2713aSLionel Sambuc // module.
2714f4a2713aSLionel Sambuc F.DeclRemap.insertOrReplace(
2715f4a2713aSLionel Sambuc std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));
2716f4a2713aSLionel Sambuc
2717f4a2713aSLionel Sambuc // Introduce the global -> local mapping for declarations within this
2718f4a2713aSLionel Sambuc // module.
2719f4a2713aSLionel Sambuc F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;
2720f4a2713aSLionel Sambuc
2721f4a2713aSLionel Sambuc DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);
2722f4a2713aSLionel Sambuc }
2723f4a2713aSLionel Sambuc break;
2724f4a2713aSLionel Sambuc }
2725f4a2713aSLionel Sambuc
2726f4a2713aSLionel Sambuc case TU_UPDATE_LEXICAL: {
2727f4a2713aSLionel Sambuc DeclContext *TU = Context.getTranslationUnitDecl();
2728f4a2713aSLionel Sambuc DeclContextInfo &Info = F.DeclContextInfos[TU];
2729f4a2713aSLionel Sambuc Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair *>(Blob.data());
2730f4a2713aSLionel Sambuc Info.NumLexicalDecls
2731f4a2713aSLionel Sambuc = static_cast<unsigned int>(Blob.size() / sizeof(KindDeclIDPair));
2732f4a2713aSLionel Sambuc TU->setHasExternalLexicalStorage(true);
2733f4a2713aSLionel Sambuc break;
2734f4a2713aSLionel Sambuc }
2735f4a2713aSLionel Sambuc
2736f4a2713aSLionel Sambuc case UPDATE_VISIBLE: {
2737f4a2713aSLionel Sambuc unsigned Idx = 0;
2738f4a2713aSLionel Sambuc serialization::DeclID ID = ReadDeclID(F, Record, Idx);
2739f4a2713aSLionel Sambuc ASTDeclContextNameLookupTable *Table =
2740f4a2713aSLionel Sambuc ASTDeclContextNameLookupTable::Create(
2741f4a2713aSLionel Sambuc (const unsigned char *)Blob.data() + Record[Idx++],
2742*0a6a1f1dSLionel Sambuc (const unsigned char *)Blob.data() + sizeof(uint32_t),
2743f4a2713aSLionel Sambuc (const unsigned char *)Blob.data(),
2744f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait(*this, F));
2745*0a6a1f1dSLionel Sambuc if (Decl *D = GetExistingDecl(ID)) {
2746*0a6a1f1dSLionel Sambuc auto *DC = cast<DeclContext>(D);
2747*0a6a1f1dSLionel Sambuc DC->getPrimaryContext()->setHasExternalVisibleStorage(true);
2748*0a6a1f1dSLionel Sambuc auto *&LookupTable = F.DeclContextInfos[DC].NameLookupTableData;
2749*0a6a1f1dSLionel Sambuc delete LookupTable;
2750*0a6a1f1dSLionel Sambuc LookupTable = Table;
2751f4a2713aSLionel Sambuc } else
2752f4a2713aSLionel Sambuc PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
2753f4a2713aSLionel Sambuc break;
2754f4a2713aSLionel Sambuc }
2755f4a2713aSLionel Sambuc
2756f4a2713aSLionel Sambuc case IDENTIFIER_TABLE:
2757f4a2713aSLionel Sambuc F.IdentifierTableData = Blob.data();
2758f4a2713aSLionel Sambuc if (Record[0]) {
2759*0a6a1f1dSLionel Sambuc F.IdentifierLookupTable = ASTIdentifierLookupTable::Create(
2760f4a2713aSLionel Sambuc (const unsigned char *)F.IdentifierTableData + Record[0],
2761*0a6a1f1dSLionel Sambuc (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
2762f4a2713aSLionel Sambuc (const unsigned char *)F.IdentifierTableData,
2763f4a2713aSLionel Sambuc ASTIdentifierLookupTrait(*this, F));
2764f4a2713aSLionel Sambuc
2765f4a2713aSLionel Sambuc PP.getIdentifierTable().setExternalIdentifierLookup(this);
2766f4a2713aSLionel Sambuc }
2767f4a2713aSLionel Sambuc break;
2768f4a2713aSLionel Sambuc
2769f4a2713aSLionel Sambuc case IDENTIFIER_OFFSET: {
2770f4a2713aSLionel Sambuc if (F.LocalNumIdentifiers != 0) {
2771f4a2713aSLionel Sambuc Error("duplicate IDENTIFIER_OFFSET record in AST file");
2772*0a6a1f1dSLionel Sambuc return Failure;
2773f4a2713aSLionel Sambuc }
2774f4a2713aSLionel Sambuc F.IdentifierOffsets = (const uint32_t *)Blob.data();
2775f4a2713aSLionel Sambuc F.LocalNumIdentifiers = Record[0];
2776f4a2713aSLionel Sambuc unsigned LocalBaseIdentifierID = Record[1];
2777f4a2713aSLionel Sambuc F.BaseIdentifierID = getTotalNumIdentifiers();
2778f4a2713aSLionel Sambuc
2779f4a2713aSLionel Sambuc if (F.LocalNumIdentifiers > 0) {
2780f4a2713aSLionel Sambuc // Introduce the global -> local mapping for identifiers within this
2781f4a2713aSLionel Sambuc // module.
2782f4a2713aSLionel Sambuc GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1,
2783f4a2713aSLionel Sambuc &F));
2784f4a2713aSLionel Sambuc
2785f4a2713aSLionel Sambuc // Introduce the local -> global mapping for identifiers within this
2786f4a2713aSLionel Sambuc // module.
2787f4a2713aSLionel Sambuc F.IdentifierRemap.insertOrReplace(
2788f4a2713aSLionel Sambuc std::make_pair(LocalBaseIdentifierID,
2789f4a2713aSLionel Sambuc F.BaseIdentifierID - LocalBaseIdentifierID));
2790f4a2713aSLionel Sambuc
2791f4a2713aSLionel Sambuc IdentifiersLoaded.resize(IdentifiersLoaded.size()
2792f4a2713aSLionel Sambuc + F.LocalNumIdentifiers);
2793f4a2713aSLionel Sambuc }
2794f4a2713aSLionel Sambuc break;
2795f4a2713aSLionel Sambuc }
2796f4a2713aSLionel Sambuc
2797*0a6a1f1dSLionel Sambuc case EAGERLY_DESERIALIZED_DECLS:
2798f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
2799*0a6a1f1dSLionel Sambuc EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
2800f4a2713aSLionel Sambuc break;
2801f4a2713aSLionel Sambuc
2802f4a2713aSLionel Sambuc case SPECIAL_TYPES:
2803f4a2713aSLionel Sambuc if (SpecialTypes.empty()) {
2804f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
2805f4a2713aSLionel Sambuc SpecialTypes.push_back(getGlobalTypeID(F, Record[I]));
2806f4a2713aSLionel Sambuc break;
2807f4a2713aSLionel Sambuc }
2808f4a2713aSLionel Sambuc
2809f4a2713aSLionel Sambuc if (SpecialTypes.size() != Record.size()) {
2810f4a2713aSLionel Sambuc Error("invalid special-types record");
2811*0a6a1f1dSLionel Sambuc return Failure;
2812f4a2713aSLionel Sambuc }
2813f4a2713aSLionel Sambuc
2814f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I) {
2815f4a2713aSLionel Sambuc serialization::TypeID ID = getGlobalTypeID(F, Record[I]);
2816f4a2713aSLionel Sambuc if (!SpecialTypes[I])
2817f4a2713aSLionel Sambuc SpecialTypes[I] = ID;
2818f4a2713aSLionel Sambuc // FIXME: If ID && SpecialTypes[I] != ID, do we need a separate
2819f4a2713aSLionel Sambuc // merge step?
2820f4a2713aSLionel Sambuc }
2821f4a2713aSLionel Sambuc break;
2822f4a2713aSLionel Sambuc
2823f4a2713aSLionel Sambuc case STATISTICS:
2824f4a2713aSLionel Sambuc TotalNumStatements += Record[0];
2825f4a2713aSLionel Sambuc TotalNumMacros += Record[1];
2826f4a2713aSLionel Sambuc TotalLexicalDeclContexts += Record[2];
2827f4a2713aSLionel Sambuc TotalVisibleDeclContexts += Record[3];
2828f4a2713aSLionel Sambuc break;
2829f4a2713aSLionel Sambuc
2830f4a2713aSLionel Sambuc case UNUSED_FILESCOPED_DECLS:
2831f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
2832f4a2713aSLionel Sambuc UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));
2833f4a2713aSLionel Sambuc break;
2834f4a2713aSLionel Sambuc
2835f4a2713aSLionel Sambuc case DELEGATING_CTORS:
2836f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
2837f4a2713aSLionel Sambuc DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));
2838f4a2713aSLionel Sambuc break;
2839f4a2713aSLionel Sambuc
2840f4a2713aSLionel Sambuc case WEAK_UNDECLARED_IDENTIFIERS:
2841f4a2713aSLionel Sambuc if (Record.size() % 4 != 0) {
2842f4a2713aSLionel Sambuc Error("invalid weak identifiers record");
2843*0a6a1f1dSLionel Sambuc return Failure;
2844f4a2713aSLionel Sambuc }
2845f4a2713aSLionel Sambuc
2846f4a2713aSLionel Sambuc // FIXME: Ignore weak undeclared identifiers from non-original PCH
2847f4a2713aSLionel Sambuc // files. This isn't the way to do it :)
2848f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.clear();
2849f4a2713aSLionel Sambuc
2850f4a2713aSLionel Sambuc // Translate the weak, undeclared identifiers into global IDs.
2851f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {
2852f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.push_back(
2853f4a2713aSLionel Sambuc getGlobalIdentifierID(F, Record[I++]));
2854f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.push_back(
2855f4a2713aSLionel Sambuc getGlobalIdentifierID(F, Record[I++]));
2856f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.push_back(
2857f4a2713aSLionel Sambuc ReadSourceLocation(F, Record, I).getRawEncoding());
2858f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.push_back(Record[I++]);
2859f4a2713aSLionel Sambuc }
2860f4a2713aSLionel Sambuc break;
2861f4a2713aSLionel Sambuc
2862f4a2713aSLionel Sambuc case LOCALLY_SCOPED_EXTERN_C_DECLS:
2863f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
2864f4a2713aSLionel Sambuc LocallyScopedExternCDecls.push_back(getGlobalDeclID(F, Record[I]));
2865f4a2713aSLionel Sambuc break;
2866f4a2713aSLionel Sambuc
2867f4a2713aSLionel Sambuc case SELECTOR_OFFSETS: {
2868f4a2713aSLionel Sambuc F.SelectorOffsets = (const uint32_t *)Blob.data();
2869f4a2713aSLionel Sambuc F.LocalNumSelectors = Record[0];
2870f4a2713aSLionel Sambuc unsigned LocalBaseSelectorID = Record[1];
2871f4a2713aSLionel Sambuc F.BaseSelectorID = getTotalNumSelectors();
2872f4a2713aSLionel Sambuc
2873f4a2713aSLionel Sambuc if (F.LocalNumSelectors > 0) {
2874f4a2713aSLionel Sambuc // Introduce the global -> local mapping for selectors within this
2875f4a2713aSLionel Sambuc // module.
2876f4a2713aSLionel Sambuc GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));
2877f4a2713aSLionel Sambuc
2878f4a2713aSLionel Sambuc // Introduce the local -> global mapping for selectors within this
2879f4a2713aSLionel Sambuc // module.
2880f4a2713aSLionel Sambuc F.SelectorRemap.insertOrReplace(
2881f4a2713aSLionel Sambuc std::make_pair(LocalBaseSelectorID,
2882f4a2713aSLionel Sambuc F.BaseSelectorID - LocalBaseSelectorID));
2883f4a2713aSLionel Sambuc
2884f4a2713aSLionel Sambuc SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);
2885f4a2713aSLionel Sambuc }
2886f4a2713aSLionel Sambuc break;
2887f4a2713aSLionel Sambuc }
2888f4a2713aSLionel Sambuc
2889f4a2713aSLionel Sambuc case METHOD_POOL:
2890f4a2713aSLionel Sambuc F.SelectorLookupTableData = (const unsigned char *)Blob.data();
2891f4a2713aSLionel Sambuc if (Record[0])
2892f4a2713aSLionel Sambuc F.SelectorLookupTable
2893f4a2713aSLionel Sambuc = ASTSelectorLookupTable::Create(
2894f4a2713aSLionel Sambuc F.SelectorLookupTableData + Record[0],
2895f4a2713aSLionel Sambuc F.SelectorLookupTableData,
2896f4a2713aSLionel Sambuc ASTSelectorLookupTrait(*this, F));
2897f4a2713aSLionel Sambuc TotalNumMethodPoolEntries += Record[1];
2898f4a2713aSLionel Sambuc break;
2899f4a2713aSLionel Sambuc
2900f4a2713aSLionel Sambuc case REFERENCED_SELECTOR_POOL:
2901f4a2713aSLionel Sambuc if (!Record.empty()) {
2902f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
2903f4a2713aSLionel Sambuc ReferencedSelectorsData.push_back(getGlobalSelectorID(F,
2904f4a2713aSLionel Sambuc Record[Idx++]));
2905f4a2713aSLionel Sambuc ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).
2906f4a2713aSLionel Sambuc getRawEncoding());
2907f4a2713aSLionel Sambuc }
2908f4a2713aSLionel Sambuc }
2909f4a2713aSLionel Sambuc break;
2910f4a2713aSLionel Sambuc
2911f4a2713aSLionel Sambuc case PP_COUNTER_VALUE:
2912f4a2713aSLionel Sambuc if (!Record.empty() && Listener)
2913f4a2713aSLionel Sambuc Listener->ReadCounter(F, Record[0]);
2914f4a2713aSLionel Sambuc break;
2915f4a2713aSLionel Sambuc
2916f4a2713aSLionel Sambuc case FILE_SORTED_DECLS:
2917f4a2713aSLionel Sambuc F.FileSortedDecls = (const DeclID *)Blob.data();
2918f4a2713aSLionel Sambuc F.NumFileSortedDecls = Record[0];
2919f4a2713aSLionel Sambuc break;
2920f4a2713aSLionel Sambuc
2921f4a2713aSLionel Sambuc case SOURCE_LOCATION_OFFSETS: {
2922f4a2713aSLionel Sambuc F.SLocEntryOffsets = (const uint32_t *)Blob.data();
2923f4a2713aSLionel Sambuc F.LocalNumSLocEntries = Record[0];
2924f4a2713aSLionel Sambuc unsigned SLocSpaceSize = Record[1];
2925*0a6a1f1dSLionel Sambuc std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
2926f4a2713aSLionel Sambuc SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
2927f4a2713aSLionel Sambuc SLocSpaceSize);
2928f4a2713aSLionel Sambuc // Make our entry in the range map. BaseID is negative and growing, so
2929f4a2713aSLionel Sambuc // we invert it. Because we invert it, though, we need the other end of
2930f4a2713aSLionel Sambuc // the range.
2931f4a2713aSLionel Sambuc unsigned RangeStart =
2932f4a2713aSLionel Sambuc unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1;
2933f4a2713aSLionel Sambuc GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));
2934f4a2713aSLionel Sambuc F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);
2935f4a2713aSLionel Sambuc
2936f4a2713aSLionel Sambuc // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.
2937f4a2713aSLionel Sambuc assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);
2938f4a2713aSLionel Sambuc GlobalSLocOffsetMap.insert(
2939f4a2713aSLionel Sambuc std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
2940f4a2713aSLionel Sambuc - SLocSpaceSize,&F));
2941f4a2713aSLionel Sambuc
2942f4a2713aSLionel Sambuc // Initialize the remapping table.
2943f4a2713aSLionel Sambuc // Invalid stays invalid.
2944*0a6a1f1dSLionel Sambuc F.SLocRemap.insertOrReplace(std::make_pair(0U, 0));
2945f4a2713aSLionel Sambuc // This module. Base was 2 when being compiled.
2946*0a6a1f1dSLionel Sambuc F.SLocRemap.insertOrReplace(std::make_pair(2U,
2947f4a2713aSLionel Sambuc static_cast<int>(F.SLocEntryBaseOffset - 2)));
2948f4a2713aSLionel Sambuc
2949f4a2713aSLionel Sambuc TotalNumSLocEntries += F.LocalNumSLocEntries;
2950f4a2713aSLionel Sambuc break;
2951f4a2713aSLionel Sambuc }
2952f4a2713aSLionel Sambuc
2953f4a2713aSLionel Sambuc case MODULE_OFFSET_MAP: {
2954f4a2713aSLionel Sambuc // Additional remapping information.
2955f4a2713aSLionel Sambuc const unsigned char *Data = (const unsigned char*)Blob.data();
2956f4a2713aSLionel Sambuc const unsigned char *DataEnd = Data + Blob.size();
2957f4a2713aSLionel Sambuc
2958*0a6a1f1dSLionel Sambuc // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders.
2959*0a6a1f1dSLionel Sambuc if (F.SLocRemap.find(0) == F.SLocRemap.end()) {
2960*0a6a1f1dSLionel Sambuc F.SLocRemap.insert(std::make_pair(0U, 0));
2961*0a6a1f1dSLionel Sambuc F.SLocRemap.insert(std::make_pair(2U, 1));
2962*0a6a1f1dSLionel Sambuc }
2963*0a6a1f1dSLionel Sambuc
2964f4a2713aSLionel Sambuc // Continuous range maps we may be updating in our module.
2965*0a6a1f1dSLionel Sambuc typedef ContinuousRangeMap<uint32_t, int, 2>::Builder
2966*0a6a1f1dSLionel Sambuc RemapBuilder;
2967*0a6a1f1dSLionel Sambuc RemapBuilder SLocRemap(F.SLocRemap);
2968*0a6a1f1dSLionel Sambuc RemapBuilder IdentifierRemap(F.IdentifierRemap);
2969*0a6a1f1dSLionel Sambuc RemapBuilder MacroRemap(F.MacroRemap);
2970*0a6a1f1dSLionel Sambuc RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
2971*0a6a1f1dSLionel Sambuc RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
2972*0a6a1f1dSLionel Sambuc RemapBuilder SelectorRemap(F.SelectorRemap);
2973*0a6a1f1dSLionel Sambuc RemapBuilder DeclRemap(F.DeclRemap);
2974*0a6a1f1dSLionel Sambuc RemapBuilder TypeRemap(F.TypeRemap);
2975f4a2713aSLionel Sambuc
2976f4a2713aSLionel Sambuc while(Data < DataEnd) {
2977*0a6a1f1dSLionel Sambuc using namespace llvm::support;
2978*0a6a1f1dSLionel Sambuc uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
2979f4a2713aSLionel Sambuc StringRef Name = StringRef((const char*)Data, Len);
2980f4a2713aSLionel Sambuc Data += Len;
2981f4a2713aSLionel Sambuc ModuleFile *OM = ModuleMgr.lookup(Name);
2982f4a2713aSLionel Sambuc if (!OM) {
2983f4a2713aSLionel Sambuc Error("SourceLocation remap refers to unknown module");
2984*0a6a1f1dSLionel Sambuc return Failure;
2985f4a2713aSLionel Sambuc }
2986f4a2713aSLionel Sambuc
2987*0a6a1f1dSLionel Sambuc uint32_t SLocOffset =
2988*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2989*0a6a1f1dSLionel Sambuc uint32_t IdentifierIDOffset =
2990*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2991*0a6a1f1dSLionel Sambuc uint32_t MacroIDOffset =
2992*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2993*0a6a1f1dSLionel Sambuc uint32_t PreprocessedEntityIDOffset =
2994*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2995*0a6a1f1dSLionel Sambuc uint32_t SubmoduleIDOffset =
2996*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2997*0a6a1f1dSLionel Sambuc uint32_t SelectorIDOffset =
2998*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
2999*0a6a1f1dSLionel Sambuc uint32_t DeclIDOffset =
3000*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
3001*0a6a1f1dSLionel Sambuc uint32_t TypeIndexOffset =
3002*0a6a1f1dSLionel Sambuc endian::readNext<uint32_t, little, unaligned>(Data);
3003f4a2713aSLionel Sambuc
3004*0a6a1f1dSLionel Sambuc uint32_t None = std::numeric_limits<uint32_t>::max();
3005f4a2713aSLionel Sambuc
3006*0a6a1f1dSLionel Sambuc auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset,
3007*0a6a1f1dSLionel Sambuc RemapBuilder &Remap) {
3008*0a6a1f1dSLionel Sambuc if (Offset != None)
3009*0a6a1f1dSLionel Sambuc Remap.insert(std::make_pair(Offset,
3010*0a6a1f1dSLionel Sambuc static_cast<int>(BaseOffset - Offset)));
3011*0a6a1f1dSLionel Sambuc };
3012*0a6a1f1dSLionel Sambuc mapOffset(SLocOffset, OM->SLocEntryBaseOffset, SLocRemap);
3013*0a6a1f1dSLionel Sambuc mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap);
3014*0a6a1f1dSLionel Sambuc mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
3015*0a6a1f1dSLionel Sambuc mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
3016*0a6a1f1dSLionel Sambuc PreprocessedEntityRemap);
3017*0a6a1f1dSLionel Sambuc mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
3018*0a6a1f1dSLionel Sambuc mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
3019*0a6a1f1dSLionel Sambuc mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap);
3020*0a6a1f1dSLionel Sambuc mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);
3021f4a2713aSLionel Sambuc
3022f4a2713aSLionel Sambuc // Global -> local mappings.
3023f4a2713aSLionel Sambuc F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
3024f4a2713aSLionel Sambuc }
3025f4a2713aSLionel Sambuc break;
3026f4a2713aSLionel Sambuc }
3027f4a2713aSLionel Sambuc
3028f4a2713aSLionel Sambuc case SOURCE_MANAGER_LINE_TABLE:
3029f4a2713aSLionel Sambuc if (ParseLineTable(F, Record))
3030*0a6a1f1dSLionel Sambuc return Failure;
3031f4a2713aSLionel Sambuc break;
3032f4a2713aSLionel Sambuc
3033f4a2713aSLionel Sambuc case SOURCE_LOCATION_PRELOADS: {
3034f4a2713aSLionel Sambuc // Need to transform from the local view (1-based IDs) to the global view,
3035f4a2713aSLionel Sambuc // which is based off F.SLocEntryBaseID.
3036f4a2713aSLionel Sambuc if (!F.PreloadSLocEntries.empty()) {
3037f4a2713aSLionel Sambuc Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
3038*0a6a1f1dSLionel Sambuc return Failure;
3039f4a2713aSLionel Sambuc }
3040f4a2713aSLionel Sambuc
3041f4a2713aSLionel Sambuc F.PreloadSLocEntries.swap(Record);
3042f4a2713aSLionel Sambuc break;
3043f4a2713aSLionel Sambuc }
3044f4a2713aSLionel Sambuc
3045f4a2713aSLionel Sambuc case EXT_VECTOR_DECLS:
3046f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3047f4a2713aSLionel Sambuc ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
3048f4a2713aSLionel Sambuc break;
3049f4a2713aSLionel Sambuc
3050f4a2713aSLionel Sambuc case VTABLE_USES:
3051f4a2713aSLionel Sambuc if (Record.size() % 3 != 0) {
3052f4a2713aSLionel Sambuc Error("Invalid VTABLE_USES record");
3053*0a6a1f1dSLionel Sambuc return Failure;
3054f4a2713aSLionel Sambuc }
3055f4a2713aSLionel Sambuc
3056f4a2713aSLionel Sambuc // Later tables overwrite earlier ones.
3057f4a2713aSLionel Sambuc // FIXME: Modules will have some trouble with this. This is clearly not
3058f4a2713aSLionel Sambuc // the right way to do this.
3059f4a2713aSLionel Sambuc VTableUses.clear();
3060f4a2713aSLionel Sambuc
3061f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
3062f4a2713aSLionel Sambuc VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
3063f4a2713aSLionel Sambuc VTableUses.push_back(
3064f4a2713aSLionel Sambuc ReadSourceLocation(F, Record, Idx).getRawEncoding());
3065f4a2713aSLionel Sambuc VTableUses.push_back(Record[Idx++]);
3066f4a2713aSLionel Sambuc }
3067f4a2713aSLionel Sambuc break;
3068f4a2713aSLionel Sambuc
3069f4a2713aSLionel Sambuc case DYNAMIC_CLASSES:
3070f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3071f4a2713aSLionel Sambuc DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));
3072f4a2713aSLionel Sambuc break;
3073f4a2713aSLionel Sambuc
3074f4a2713aSLionel Sambuc case PENDING_IMPLICIT_INSTANTIATIONS:
3075f4a2713aSLionel Sambuc if (PendingInstantiations.size() % 2 != 0) {
3076f4a2713aSLionel Sambuc Error("Invalid existing PendingInstantiations");
3077*0a6a1f1dSLionel Sambuc return Failure;
3078f4a2713aSLionel Sambuc }
3079f4a2713aSLionel Sambuc
3080f4a2713aSLionel Sambuc if (Record.size() % 2 != 0) {
3081f4a2713aSLionel Sambuc Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
3082*0a6a1f1dSLionel Sambuc return Failure;
3083f4a2713aSLionel Sambuc }
3084f4a2713aSLionel Sambuc
3085f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
3086f4a2713aSLionel Sambuc PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
3087f4a2713aSLionel Sambuc PendingInstantiations.push_back(
3088f4a2713aSLionel Sambuc ReadSourceLocation(F, Record, I).getRawEncoding());
3089f4a2713aSLionel Sambuc }
3090f4a2713aSLionel Sambuc break;
3091f4a2713aSLionel Sambuc
3092f4a2713aSLionel Sambuc case SEMA_DECL_REFS:
3093f4a2713aSLionel Sambuc if (Record.size() != 2) {
3094f4a2713aSLionel Sambuc Error("Invalid SEMA_DECL_REFS block");
3095*0a6a1f1dSLionel Sambuc return Failure;
3096f4a2713aSLionel Sambuc }
3097f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3098f4a2713aSLionel Sambuc SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
3099f4a2713aSLionel Sambuc break;
3100f4a2713aSLionel Sambuc
3101f4a2713aSLionel Sambuc case PPD_ENTITIES_OFFSETS: {
3102f4a2713aSLionel Sambuc F.PreprocessedEntityOffsets = (const PPEntityOffset *)Blob.data();
3103f4a2713aSLionel Sambuc assert(Blob.size() % sizeof(PPEntityOffset) == 0);
3104f4a2713aSLionel Sambuc F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset);
3105f4a2713aSLionel Sambuc
3106f4a2713aSLionel Sambuc unsigned LocalBasePreprocessedEntityID = Record[0];
3107f4a2713aSLionel Sambuc
3108f4a2713aSLionel Sambuc unsigned StartingID;
3109f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord())
3110f4a2713aSLionel Sambuc PP.createPreprocessingRecord();
3111f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord()->getExternalSource())
3112f4a2713aSLionel Sambuc PP.getPreprocessingRecord()->SetExternalSource(*this);
3113f4a2713aSLionel Sambuc StartingID
3114f4a2713aSLionel Sambuc = PP.getPreprocessingRecord()
3115f4a2713aSLionel Sambuc ->allocateLoadedEntities(F.NumPreprocessedEntities);
3116f4a2713aSLionel Sambuc F.BasePreprocessedEntityID = StartingID;
3117f4a2713aSLionel Sambuc
3118f4a2713aSLionel Sambuc if (F.NumPreprocessedEntities > 0) {
3119f4a2713aSLionel Sambuc // Introduce the global -> local mapping for preprocessed entities in
3120f4a2713aSLionel Sambuc // this module.
3121f4a2713aSLionel Sambuc GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
3122f4a2713aSLionel Sambuc
3123f4a2713aSLionel Sambuc // Introduce the local -> global mapping for preprocessed entities in
3124f4a2713aSLionel Sambuc // this module.
3125f4a2713aSLionel Sambuc F.PreprocessedEntityRemap.insertOrReplace(
3126f4a2713aSLionel Sambuc std::make_pair(LocalBasePreprocessedEntityID,
3127f4a2713aSLionel Sambuc F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));
3128f4a2713aSLionel Sambuc }
3129f4a2713aSLionel Sambuc
3130f4a2713aSLionel Sambuc break;
3131f4a2713aSLionel Sambuc }
3132f4a2713aSLionel Sambuc
3133f4a2713aSLionel Sambuc case DECL_UPDATE_OFFSETS: {
3134f4a2713aSLionel Sambuc if (Record.size() % 2 != 0) {
3135f4a2713aSLionel Sambuc Error("invalid DECL_UPDATE_OFFSETS block in AST file");
3136*0a6a1f1dSLionel Sambuc return Failure;
3137f4a2713aSLionel Sambuc }
3138*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
3139*0a6a1f1dSLionel Sambuc GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
3140*0a6a1f1dSLionel Sambuc DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
3141*0a6a1f1dSLionel Sambuc
3142*0a6a1f1dSLionel Sambuc // If we've already loaded the decl, perform the updates when we finish
3143*0a6a1f1dSLionel Sambuc // loading this block.
3144*0a6a1f1dSLionel Sambuc if (Decl *D = GetExistingDecl(ID))
3145*0a6a1f1dSLionel Sambuc PendingUpdateRecords.push_back(std::make_pair(ID, D));
3146*0a6a1f1dSLionel Sambuc }
3147f4a2713aSLionel Sambuc break;
3148f4a2713aSLionel Sambuc }
3149f4a2713aSLionel Sambuc
3150f4a2713aSLionel Sambuc case DECL_REPLACEMENTS: {
3151f4a2713aSLionel Sambuc if (Record.size() % 3 != 0) {
3152f4a2713aSLionel Sambuc Error("invalid DECL_REPLACEMENTS block in AST file");
3153*0a6a1f1dSLionel Sambuc return Failure;
3154f4a2713aSLionel Sambuc }
3155f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; I += 3)
3156f4a2713aSLionel Sambuc ReplacedDecls[getGlobalDeclID(F, Record[I])]
3157f4a2713aSLionel Sambuc = ReplacedDeclInfo(&F, Record[I+1], Record[I+2]);
3158f4a2713aSLionel Sambuc break;
3159f4a2713aSLionel Sambuc }
3160f4a2713aSLionel Sambuc
3161f4a2713aSLionel Sambuc case OBJC_CATEGORIES_MAP: {
3162f4a2713aSLionel Sambuc if (F.LocalNumObjCCategoriesInMap != 0) {
3163f4a2713aSLionel Sambuc Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
3164*0a6a1f1dSLionel Sambuc return Failure;
3165f4a2713aSLionel Sambuc }
3166f4a2713aSLionel Sambuc
3167f4a2713aSLionel Sambuc F.LocalNumObjCCategoriesInMap = Record[0];
3168f4a2713aSLionel Sambuc F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data();
3169f4a2713aSLionel Sambuc break;
3170f4a2713aSLionel Sambuc }
3171f4a2713aSLionel Sambuc
3172f4a2713aSLionel Sambuc case OBJC_CATEGORIES:
3173f4a2713aSLionel Sambuc F.ObjCCategories.swap(Record);
3174f4a2713aSLionel Sambuc break;
3175f4a2713aSLionel Sambuc
3176f4a2713aSLionel Sambuc case CXX_BASE_SPECIFIER_OFFSETS: {
3177f4a2713aSLionel Sambuc if (F.LocalNumCXXBaseSpecifiers != 0) {
3178f4a2713aSLionel Sambuc Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");
3179*0a6a1f1dSLionel Sambuc return Failure;
3180f4a2713aSLionel Sambuc }
3181f4a2713aSLionel Sambuc
3182f4a2713aSLionel Sambuc F.LocalNumCXXBaseSpecifiers = Record[0];
3183f4a2713aSLionel Sambuc F.CXXBaseSpecifiersOffsets = (const uint32_t *)Blob.data();
3184f4a2713aSLionel Sambuc NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers;
3185f4a2713aSLionel Sambuc break;
3186f4a2713aSLionel Sambuc }
3187f4a2713aSLionel Sambuc
3188f4a2713aSLionel Sambuc case DIAG_PRAGMA_MAPPINGS:
3189f4a2713aSLionel Sambuc if (F.PragmaDiagMappings.empty())
3190f4a2713aSLionel Sambuc F.PragmaDiagMappings.swap(Record);
3191f4a2713aSLionel Sambuc else
3192f4a2713aSLionel Sambuc F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
3193f4a2713aSLionel Sambuc Record.begin(), Record.end());
3194f4a2713aSLionel Sambuc break;
3195f4a2713aSLionel Sambuc
3196f4a2713aSLionel Sambuc case CUDA_SPECIAL_DECL_REFS:
3197f4a2713aSLionel Sambuc // Later tables overwrite earlier ones.
3198f4a2713aSLionel Sambuc // FIXME: Modules will have trouble with this.
3199f4a2713aSLionel Sambuc CUDASpecialDeclRefs.clear();
3200f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3201f4a2713aSLionel Sambuc CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
3202f4a2713aSLionel Sambuc break;
3203f4a2713aSLionel Sambuc
3204f4a2713aSLionel Sambuc case HEADER_SEARCH_TABLE: {
3205f4a2713aSLionel Sambuc F.HeaderFileInfoTableData = Blob.data();
3206f4a2713aSLionel Sambuc F.LocalNumHeaderFileInfos = Record[1];
3207f4a2713aSLionel Sambuc if (Record[0]) {
3208f4a2713aSLionel Sambuc F.HeaderFileInfoTable
3209f4a2713aSLionel Sambuc = HeaderFileInfoLookupTable::Create(
3210f4a2713aSLionel Sambuc (const unsigned char *)F.HeaderFileInfoTableData + Record[0],
3211f4a2713aSLionel Sambuc (const unsigned char *)F.HeaderFileInfoTableData,
3212f4a2713aSLionel Sambuc HeaderFileInfoTrait(*this, F,
3213f4a2713aSLionel Sambuc &PP.getHeaderSearchInfo(),
3214f4a2713aSLionel Sambuc Blob.data() + Record[2]));
3215f4a2713aSLionel Sambuc
3216f4a2713aSLionel Sambuc PP.getHeaderSearchInfo().SetExternalSource(this);
3217f4a2713aSLionel Sambuc if (!PP.getHeaderSearchInfo().getExternalLookup())
3218f4a2713aSLionel Sambuc PP.getHeaderSearchInfo().SetExternalLookup(this);
3219f4a2713aSLionel Sambuc }
3220f4a2713aSLionel Sambuc break;
3221f4a2713aSLionel Sambuc }
3222f4a2713aSLionel Sambuc
3223f4a2713aSLionel Sambuc case FP_PRAGMA_OPTIONS:
3224f4a2713aSLionel Sambuc // Later tables overwrite earlier ones.
3225f4a2713aSLionel Sambuc FPPragmaOptions.swap(Record);
3226f4a2713aSLionel Sambuc break;
3227f4a2713aSLionel Sambuc
3228f4a2713aSLionel Sambuc case OPENCL_EXTENSIONS:
3229f4a2713aSLionel Sambuc // Later tables overwrite earlier ones.
3230f4a2713aSLionel Sambuc OpenCLExtensions.swap(Record);
3231f4a2713aSLionel Sambuc break;
3232f4a2713aSLionel Sambuc
3233f4a2713aSLionel Sambuc case TENTATIVE_DEFINITIONS:
3234f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3235f4a2713aSLionel Sambuc TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
3236f4a2713aSLionel Sambuc break;
3237f4a2713aSLionel Sambuc
3238f4a2713aSLionel Sambuc case KNOWN_NAMESPACES:
3239f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3240f4a2713aSLionel Sambuc KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
3241f4a2713aSLionel Sambuc break;
3242f4a2713aSLionel Sambuc
3243f4a2713aSLionel Sambuc case UNDEFINED_BUT_USED:
3244f4a2713aSLionel Sambuc if (UndefinedButUsed.size() % 2 != 0) {
3245f4a2713aSLionel Sambuc Error("Invalid existing UndefinedButUsed");
3246*0a6a1f1dSLionel Sambuc return Failure;
3247f4a2713aSLionel Sambuc }
3248f4a2713aSLionel Sambuc
3249f4a2713aSLionel Sambuc if (Record.size() % 2 != 0) {
3250f4a2713aSLionel Sambuc Error("invalid undefined-but-used record");
3251*0a6a1f1dSLionel Sambuc return Failure;
3252f4a2713aSLionel Sambuc }
3253f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
3254f4a2713aSLionel Sambuc UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
3255f4a2713aSLionel Sambuc UndefinedButUsed.push_back(
3256f4a2713aSLionel Sambuc ReadSourceLocation(F, Record, I).getRawEncoding());
3257f4a2713aSLionel Sambuc }
3258f4a2713aSLionel Sambuc break;
3259f4a2713aSLionel Sambuc
3260f4a2713aSLionel Sambuc case IMPORTED_MODULES: {
3261*0a6a1f1dSLionel Sambuc if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) {
3262f4a2713aSLionel Sambuc // If we aren't loading a module (which has its own exports), make
3263f4a2713aSLionel Sambuc // all of the imported modules visible.
3264f4a2713aSLionel Sambuc // FIXME: Deal with macros-only imports.
3265*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; /**/) {
3266*0a6a1f1dSLionel Sambuc unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
3267*0a6a1f1dSLionel Sambuc SourceLocation Loc = ReadSourceLocation(F, Record, I);
3268*0a6a1f1dSLionel Sambuc if (GlobalID)
3269*0a6a1f1dSLionel Sambuc ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
3270f4a2713aSLionel Sambuc }
3271f4a2713aSLionel Sambuc }
3272f4a2713aSLionel Sambuc break;
3273f4a2713aSLionel Sambuc }
3274f4a2713aSLionel Sambuc
3275f4a2713aSLionel Sambuc case LOCAL_REDECLARATIONS: {
3276f4a2713aSLionel Sambuc F.RedeclarationChains.swap(Record);
3277f4a2713aSLionel Sambuc break;
3278f4a2713aSLionel Sambuc }
3279f4a2713aSLionel Sambuc
3280f4a2713aSLionel Sambuc case LOCAL_REDECLARATIONS_MAP: {
3281f4a2713aSLionel Sambuc if (F.LocalNumRedeclarationsInMap != 0) {
3282f4a2713aSLionel Sambuc Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file");
3283*0a6a1f1dSLionel Sambuc return Failure;
3284f4a2713aSLionel Sambuc }
3285f4a2713aSLionel Sambuc
3286f4a2713aSLionel Sambuc F.LocalNumRedeclarationsInMap = Record[0];
3287f4a2713aSLionel Sambuc F.RedeclarationsMap = (const LocalRedeclarationsInfo *)Blob.data();
3288f4a2713aSLionel Sambuc break;
3289f4a2713aSLionel Sambuc }
3290f4a2713aSLionel Sambuc
3291f4a2713aSLionel Sambuc case MERGED_DECLARATIONS: {
3292f4a2713aSLionel Sambuc for (unsigned Idx = 0; Idx < Record.size(); /* increment in loop */) {
3293f4a2713aSLionel Sambuc GlobalDeclID CanonID = getGlobalDeclID(F, Record[Idx++]);
3294f4a2713aSLionel Sambuc SmallVectorImpl<GlobalDeclID> &Decls = StoredMergedDecls[CanonID];
3295f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N > 0; --N)
3296f4a2713aSLionel Sambuc Decls.push_back(getGlobalDeclID(F, Record[Idx++]));
3297f4a2713aSLionel Sambuc }
3298f4a2713aSLionel Sambuc break;
3299f4a2713aSLionel Sambuc }
3300f4a2713aSLionel Sambuc
3301f4a2713aSLionel Sambuc case MACRO_OFFSET: {
3302f4a2713aSLionel Sambuc if (F.LocalNumMacros != 0) {
3303f4a2713aSLionel Sambuc Error("duplicate MACRO_OFFSET record in AST file");
3304*0a6a1f1dSLionel Sambuc return Failure;
3305f4a2713aSLionel Sambuc }
3306f4a2713aSLionel Sambuc F.MacroOffsets = (const uint32_t *)Blob.data();
3307f4a2713aSLionel Sambuc F.LocalNumMacros = Record[0];
3308f4a2713aSLionel Sambuc unsigned LocalBaseMacroID = Record[1];
3309f4a2713aSLionel Sambuc F.BaseMacroID = getTotalNumMacros();
3310f4a2713aSLionel Sambuc
3311f4a2713aSLionel Sambuc if (F.LocalNumMacros > 0) {
3312f4a2713aSLionel Sambuc // Introduce the global -> local mapping for macros within this module.
3313f4a2713aSLionel Sambuc GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F));
3314f4a2713aSLionel Sambuc
3315f4a2713aSLionel Sambuc // Introduce the local -> global mapping for macros within this module.
3316f4a2713aSLionel Sambuc F.MacroRemap.insertOrReplace(
3317f4a2713aSLionel Sambuc std::make_pair(LocalBaseMacroID,
3318f4a2713aSLionel Sambuc F.BaseMacroID - LocalBaseMacroID));
3319f4a2713aSLionel Sambuc
3320f4a2713aSLionel Sambuc MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);
3321f4a2713aSLionel Sambuc }
3322f4a2713aSLionel Sambuc break;
3323f4a2713aSLionel Sambuc }
3324f4a2713aSLionel Sambuc
3325f4a2713aSLionel Sambuc case MACRO_TABLE: {
3326f4a2713aSLionel Sambuc // FIXME: Not used yet.
3327f4a2713aSLionel Sambuc break;
3328f4a2713aSLionel Sambuc }
3329f4a2713aSLionel Sambuc
3330f4a2713aSLionel Sambuc case LATE_PARSED_TEMPLATE: {
3331f4a2713aSLionel Sambuc LateParsedTemplates.append(Record.begin(), Record.end());
3332f4a2713aSLionel Sambuc break;
3333f4a2713aSLionel Sambuc }
3334*0a6a1f1dSLionel Sambuc
3335*0a6a1f1dSLionel Sambuc case OPTIMIZE_PRAGMA_OPTIONS:
3336*0a6a1f1dSLionel Sambuc if (Record.size() != 1) {
3337*0a6a1f1dSLionel Sambuc Error("invalid pragma optimize record");
3338*0a6a1f1dSLionel Sambuc return Failure;
3339*0a6a1f1dSLionel Sambuc }
3340*0a6a1f1dSLionel Sambuc OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
3341*0a6a1f1dSLionel Sambuc break;
3342*0a6a1f1dSLionel Sambuc
3343*0a6a1f1dSLionel Sambuc case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES:
3344*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Record.size(); I != N; ++I)
3345*0a6a1f1dSLionel Sambuc UnusedLocalTypedefNameCandidates.push_back(
3346*0a6a1f1dSLionel Sambuc getGlobalDeclID(F, Record[I]));
3347*0a6a1f1dSLionel Sambuc break;
3348f4a2713aSLionel Sambuc }
3349f4a2713aSLionel Sambuc }
3350f4a2713aSLionel Sambuc }
3351f4a2713aSLionel Sambuc
3352*0a6a1f1dSLionel Sambuc ASTReader::ASTReadResult
ReadModuleMapFileBlock(RecordData & Record,ModuleFile & F,const ModuleFile * ImportedBy,unsigned ClientLoadCapabilities)3353*0a6a1f1dSLionel Sambuc ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
3354*0a6a1f1dSLionel Sambuc const ModuleFile *ImportedBy,
3355*0a6a1f1dSLionel Sambuc unsigned ClientLoadCapabilities) {
3356*0a6a1f1dSLionel Sambuc unsigned Idx = 0;
3357*0a6a1f1dSLionel Sambuc F.ModuleMapPath = ReadPath(F, Record, Idx);
3358*0a6a1f1dSLionel Sambuc
3359*0a6a1f1dSLionel Sambuc if (F.Kind == MK_ExplicitModule) {
3360*0a6a1f1dSLionel Sambuc // For an explicitly-loaded module, we don't care whether the original
3361*0a6a1f1dSLionel Sambuc // module map file exists or matches.
3362*0a6a1f1dSLionel Sambuc return Success;
3363*0a6a1f1dSLionel Sambuc }
3364*0a6a1f1dSLionel Sambuc
3365*0a6a1f1dSLionel Sambuc // Try to resolve ModuleName in the current header search context and
3366*0a6a1f1dSLionel Sambuc // verify that it is found in the same module map file as we saved. If the
3367*0a6a1f1dSLionel Sambuc // top-level AST file is a main file, skip this check because there is no
3368*0a6a1f1dSLionel Sambuc // usable header search context.
3369*0a6a1f1dSLionel Sambuc assert(!F.ModuleName.empty() &&
3370*0a6a1f1dSLionel Sambuc "MODULE_NAME should come before MODULE_MAP_FILE");
3371*0a6a1f1dSLionel Sambuc if (F.Kind == MK_ImplicitModule &&
3372*0a6a1f1dSLionel Sambuc (*ModuleMgr.begin())->Kind != MK_MainFile) {
3373*0a6a1f1dSLionel Sambuc // An implicitly-loaded module file should have its module listed in some
3374*0a6a1f1dSLionel Sambuc // module map file that we've already loaded.
3375*0a6a1f1dSLionel Sambuc Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
3376*0a6a1f1dSLionel Sambuc auto &Map = PP.getHeaderSearchInfo().getModuleMap();
3377*0a6a1f1dSLionel Sambuc const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
3378*0a6a1f1dSLionel Sambuc if (!ModMap) {
3379*0a6a1f1dSLionel Sambuc assert(ImportedBy && "top-level import should be verified");
3380*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_Missing) == 0)
3381*0a6a1f1dSLionel Sambuc Diag(diag::err_imported_module_not_found) << F.ModuleName << F.FileName
3382*0a6a1f1dSLionel Sambuc << ImportedBy->FileName
3383*0a6a1f1dSLionel Sambuc << F.ModuleMapPath;
3384*0a6a1f1dSLionel Sambuc return Missing;
3385*0a6a1f1dSLionel Sambuc }
3386*0a6a1f1dSLionel Sambuc
3387*0a6a1f1dSLionel Sambuc assert(M->Name == F.ModuleName && "found module with different name");
3388*0a6a1f1dSLionel Sambuc
3389*0a6a1f1dSLionel Sambuc // Check the primary module map file.
3390*0a6a1f1dSLionel Sambuc const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
3391*0a6a1f1dSLionel Sambuc if (StoredModMap == nullptr || StoredModMap != ModMap) {
3392*0a6a1f1dSLionel Sambuc assert(ModMap && "found module is missing module map file");
3393*0a6a1f1dSLionel Sambuc assert(ImportedBy && "top-level import should be verified");
3394*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
3395*0a6a1f1dSLionel Sambuc Diag(diag::err_imported_module_modmap_changed)
3396*0a6a1f1dSLionel Sambuc << F.ModuleName << ImportedBy->FileName
3397*0a6a1f1dSLionel Sambuc << ModMap->getName() << F.ModuleMapPath;
3398*0a6a1f1dSLionel Sambuc return OutOfDate;
3399*0a6a1f1dSLionel Sambuc }
3400*0a6a1f1dSLionel Sambuc
3401*0a6a1f1dSLionel Sambuc llvm::SmallPtrSet<const FileEntry *, 1> AdditionalStoredMaps;
3402*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) {
3403*0a6a1f1dSLionel Sambuc // FIXME: we should use input files rather than storing names.
3404*0a6a1f1dSLionel Sambuc std::string Filename = ReadPath(F, Record, Idx);
3405*0a6a1f1dSLionel Sambuc const FileEntry *F =
3406*0a6a1f1dSLionel Sambuc FileMgr.getFile(Filename, false, false);
3407*0a6a1f1dSLionel Sambuc if (F == nullptr) {
3408*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
3409*0a6a1f1dSLionel Sambuc Error("could not find file '" + Filename +"' referenced by AST file");
3410*0a6a1f1dSLionel Sambuc return OutOfDate;
3411*0a6a1f1dSLionel Sambuc }
3412*0a6a1f1dSLionel Sambuc AdditionalStoredMaps.insert(F);
3413*0a6a1f1dSLionel Sambuc }
3414*0a6a1f1dSLionel Sambuc
3415*0a6a1f1dSLionel Sambuc // Check any additional module map files (e.g. module.private.modulemap)
3416*0a6a1f1dSLionel Sambuc // that are not in the pcm.
3417*0a6a1f1dSLionel Sambuc if (auto *AdditionalModuleMaps = Map.getAdditionalModuleMapFiles(M)) {
3418*0a6a1f1dSLionel Sambuc for (const FileEntry *ModMap : *AdditionalModuleMaps) {
3419*0a6a1f1dSLionel Sambuc // Remove files that match
3420*0a6a1f1dSLionel Sambuc // Note: SmallPtrSet::erase is really remove
3421*0a6a1f1dSLionel Sambuc if (!AdditionalStoredMaps.erase(ModMap)) {
3422*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
3423*0a6a1f1dSLionel Sambuc Diag(diag::err_module_different_modmap)
3424*0a6a1f1dSLionel Sambuc << F.ModuleName << /*new*/0 << ModMap->getName();
3425*0a6a1f1dSLionel Sambuc return OutOfDate;
3426*0a6a1f1dSLionel Sambuc }
3427*0a6a1f1dSLionel Sambuc }
3428*0a6a1f1dSLionel Sambuc }
3429*0a6a1f1dSLionel Sambuc
3430*0a6a1f1dSLionel Sambuc // Check any additional module map files that are in the pcm, but not
3431*0a6a1f1dSLionel Sambuc // found in header search. Cases that match are already removed.
3432*0a6a1f1dSLionel Sambuc for (const FileEntry *ModMap : AdditionalStoredMaps) {
3433*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
3434*0a6a1f1dSLionel Sambuc Diag(diag::err_module_different_modmap)
3435*0a6a1f1dSLionel Sambuc << F.ModuleName << /*not new*/1 << ModMap->getName();
3436*0a6a1f1dSLionel Sambuc return OutOfDate;
3437*0a6a1f1dSLionel Sambuc }
3438*0a6a1f1dSLionel Sambuc }
3439*0a6a1f1dSLionel Sambuc
3440*0a6a1f1dSLionel Sambuc if (Listener)
3441*0a6a1f1dSLionel Sambuc Listener->ReadModuleMapFile(F.ModuleMapPath);
3442*0a6a1f1dSLionel Sambuc return Success;
3443*0a6a1f1dSLionel Sambuc }
3444*0a6a1f1dSLionel Sambuc
3445*0a6a1f1dSLionel Sambuc
3446f4a2713aSLionel Sambuc /// \brief Move the given method to the back of the global list of methods.
moveMethodToBackOfGlobalList(Sema & S,ObjCMethodDecl * Method)3447f4a2713aSLionel Sambuc static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
3448f4a2713aSLionel Sambuc // Find the entry for this selector in the method pool.
3449f4a2713aSLionel Sambuc Sema::GlobalMethodPool::iterator Known
3450f4a2713aSLionel Sambuc = S.MethodPool.find(Method->getSelector());
3451f4a2713aSLionel Sambuc if (Known == S.MethodPool.end())
3452f4a2713aSLionel Sambuc return;
3453f4a2713aSLionel Sambuc
3454f4a2713aSLionel Sambuc // Retrieve the appropriate method list.
3455f4a2713aSLionel Sambuc ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first
3456f4a2713aSLionel Sambuc : Known->second.second;
3457f4a2713aSLionel Sambuc bool Found = false;
3458f4a2713aSLionel Sambuc for (ObjCMethodList *List = &Start; List; List = List->getNext()) {
3459f4a2713aSLionel Sambuc if (!Found) {
3460*0a6a1f1dSLionel Sambuc if (List->getMethod() == Method) {
3461f4a2713aSLionel Sambuc Found = true;
3462f4a2713aSLionel Sambuc } else {
3463f4a2713aSLionel Sambuc // Keep searching.
3464f4a2713aSLionel Sambuc continue;
3465f4a2713aSLionel Sambuc }
3466f4a2713aSLionel Sambuc }
3467f4a2713aSLionel Sambuc
3468f4a2713aSLionel Sambuc if (List->getNext())
3469*0a6a1f1dSLionel Sambuc List->setMethod(List->getNext()->getMethod());
3470f4a2713aSLionel Sambuc else
3471*0a6a1f1dSLionel Sambuc List->setMethod(Method);
3472f4a2713aSLionel Sambuc }
3473f4a2713aSLionel Sambuc }
3474f4a2713aSLionel Sambuc
makeNamesVisible(const HiddenNames & Names,Module * Owner,bool FromFinalization)3475*0a6a1f1dSLionel Sambuc void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner,
3476*0a6a1f1dSLionel Sambuc bool FromFinalization) {
3477*0a6a1f1dSLionel Sambuc // FIXME: Only do this if Owner->NameVisibility == AllVisible.
3478*0a6a1f1dSLionel Sambuc for (Decl *D : Names.HiddenDecls) {
3479f4a2713aSLionel Sambuc bool wasHidden = D->Hidden;
3480f4a2713aSLionel Sambuc D->Hidden = false;
3481f4a2713aSLionel Sambuc
3482f4a2713aSLionel Sambuc if (wasHidden && SemaObj) {
3483f4a2713aSLionel Sambuc if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) {
3484f4a2713aSLionel Sambuc moveMethodToBackOfGlobalList(*SemaObj, Method);
3485f4a2713aSLionel Sambuc }
3486f4a2713aSLionel Sambuc }
3487f4a2713aSLionel Sambuc }
3488*0a6a1f1dSLionel Sambuc
3489*0a6a1f1dSLionel Sambuc assert((FromFinalization || Owner->NameVisibility >= Module::MacrosVisible) &&
3490*0a6a1f1dSLionel Sambuc "nothing to make visible?");
3491*0a6a1f1dSLionel Sambuc for (const auto &Macro : Names.HiddenMacros) {
3492*0a6a1f1dSLionel Sambuc if (FromFinalization)
3493*0a6a1f1dSLionel Sambuc PP.appendMacroDirective(Macro.first,
3494*0a6a1f1dSLionel Sambuc Macro.second->import(PP, SourceLocation()));
3495*0a6a1f1dSLionel Sambuc else
3496f4a2713aSLionel Sambuc installImportedMacro(Macro.first, Macro.second, Owner);
3497f4a2713aSLionel Sambuc }
3498f4a2713aSLionel Sambuc }
3499f4a2713aSLionel Sambuc
makeModuleVisible(Module * Mod,Module::NameVisibilityKind NameVisibility,SourceLocation ImportLoc,bool Complain)3500f4a2713aSLionel Sambuc void ASTReader::makeModuleVisible(Module *Mod,
3501f4a2713aSLionel Sambuc Module::NameVisibilityKind NameVisibility,
3502f4a2713aSLionel Sambuc SourceLocation ImportLoc,
3503f4a2713aSLionel Sambuc bool Complain) {
3504f4a2713aSLionel Sambuc llvm::SmallPtrSet<Module *, 4> Visited;
3505f4a2713aSLionel Sambuc SmallVector<Module *, 4> Stack;
3506f4a2713aSLionel Sambuc Stack.push_back(Mod);
3507f4a2713aSLionel Sambuc while (!Stack.empty()) {
3508f4a2713aSLionel Sambuc Mod = Stack.pop_back_val();
3509f4a2713aSLionel Sambuc
3510f4a2713aSLionel Sambuc if (NameVisibility <= Mod->NameVisibility) {
3511f4a2713aSLionel Sambuc // This module already has this level of visibility (or greater), so
3512f4a2713aSLionel Sambuc // there is nothing more to do.
3513f4a2713aSLionel Sambuc continue;
3514f4a2713aSLionel Sambuc }
3515f4a2713aSLionel Sambuc
3516f4a2713aSLionel Sambuc if (!Mod->isAvailable()) {
3517f4a2713aSLionel Sambuc // Modules that aren't available cannot be made visible.
3518f4a2713aSLionel Sambuc continue;
3519f4a2713aSLionel Sambuc }
3520f4a2713aSLionel Sambuc
3521f4a2713aSLionel Sambuc // Update the module's name visibility.
3522*0a6a1f1dSLionel Sambuc if (NameVisibility >= Module::MacrosVisible &&
3523*0a6a1f1dSLionel Sambuc Mod->NameVisibility < Module::MacrosVisible)
3524*0a6a1f1dSLionel Sambuc Mod->MacroVisibilityLoc = ImportLoc;
3525f4a2713aSLionel Sambuc Mod->NameVisibility = NameVisibility;
3526f4a2713aSLionel Sambuc
3527f4a2713aSLionel Sambuc // If we've already deserialized any names from this module,
3528f4a2713aSLionel Sambuc // mark them as visible.
3529f4a2713aSLionel Sambuc HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);
3530f4a2713aSLionel Sambuc if (Hidden != HiddenNamesMap.end()) {
3531*0a6a1f1dSLionel Sambuc auto HiddenNames = std::move(*Hidden);
3532f4a2713aSLionel Sambuc HiddenNamesMap.erase(Hidden);
3533*0a6a1f1dSLionel Sambuc makeNamesVisible(HiddenNames.second, HiddenNames.first,
3534*0a6a1f1dSLionel Sambuc /*FromFinalization*/false);
3535*0a6a1f1dSLionel Sambuc assert(HiddenNamesMap.find(Mod) == HiddenNamesMap.end() &&
3536*0a6a1f1dSLionel Sambuc "making names visible added hidden names");
3537f4a2713aSLionel Sambuc }
3538f4a2713aSLionel Sambuc
3539f4a2713aSLionel Sambuc // Push any exported modules onto the stack to be marked as visible.
3540f4a2713aSLionel Sambuc SmallVector<Module *, 16> Exports;
3541f4a2713aSLionel Sambuc Mod->getExportedModules(Exports);
3542f4a2713aSLionel Sambuc for (SmallVectorImpl<Module *>::iterator
3543f4a2713aSLionel Sambuc I = Exports.begin(), E = Exports.end(); I != E; ++I) {
3544f4a2713aSLionel Sambuc Module *Exported = *I;
3545*0a6a1f1dSLionel Sambuc if (Visited.insert(Exported).second)
3546f4a2713aSLionel Sambuc Stack.push_back(Exported);
3547f4a2713aSLionel Sambuc }
3548f4a2713aSLionel Sambuc
3549f4a2713aSLionel Sambuc // Detect any conflicts.
3550f4a2713aSLionel Sambuc if (Complain) {
3551f4a2713aSLionel Sambuc assert(ImportLoc.isValid() && "Missing import location");
3552f4a2713aSLionel Sambuc for (unsigned I = 0, N = Mod->Conflicts.size(); I != N; ++I) {
3553f4a2713aSLionel Sambuc if (Mod->Conflicts[I].Other->NameVisibility >= NameVisibility) {
3554f4a2713aSLionel Sambuc Diag(ImportLoc, diag::warn_module_conflict)
3555f4a2713aSLionel Sambuc << Mod->getFullModuleName()
3556f4a2713aSLionel Sambuc << Mod->Conflicts[I].Other->getFullModuleName()
3557f4a2713aSLionel Sambuc << Mod->Conflicts[I].Message;
3558f4a2713aSLionel Sambuc // FIXME: Need note where the other module was imported.
3559f4a2713aSLionel Sambuc }
3560f4a2713aSLionel Sambuc }
3561f4a2713aSLionel Sambuc }
3562f4a2713aSLionel Sambuc }
3563f4a2713aSLionel Sambuc }
3564f4a2713aSLionel Sambuc
loadGlobalIndex()3565f4a2713aSLionel Sambuc bool ASTReader::loadGlobalIndex() {
3566f4a2713aSLionel Sambuc if (GlobalIndex)
3567f4a2713aSLionel Sambuc return false;
3568f4a2713aSLionel Sambuc
3569f4a2713aSLionel Sambuc if (TriedLoadingGlobalIndex || !UseGlobalIndex ||
3570f4a2713aSLionel Sambuc !Context.getLangOpts().Modules)
3571f4a2713aSLionel Sambuc return true;
3572f4a2713aSLionel Sambuc
3573f4a2713aSLionel Sambuc // Try to load the global index.
3574f4a2713aSLionel Sambuc TriedLoadingGlobalIndex = true;
3575f4a2713aSLionel Sambuc StringRef ModuleCachePath
3576f4a2713aSLionel Sambuc = getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
3577f4a2713aSLionel Sambuc std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> Result
3578f4a2713aSLionel Sambuc = GlobalModuleIndex::readIndex(ModuleCachePath);
3579f4a2713aSLionel Sambuc if (!Result.first)
3580f4a2713aSLionel Sambuc return true;
3581f4a2713aSLionel Sambuc
3582f4a2713aSLionel Sambuc GlobalIndex.reset(Result.first);
3583f4a2713aSLionel Sambuc ModuleMgr.setGlobalIndex(GlobalIndex.get());
3584f4a2713aSLionel Sambuc return false;
3585f4a2713aSLionel Sambuc }
3586f4a2713aSLionel Sambuc
isGlobalIndexUnavailable() const3587f4a2713aSLionel Sambuc bool ASTReader::isGlobalIndexUnavailable() const {
3588f4a2713aSLionel Sambuc return Context.getLangOpts().Modules && UseGlobalIndex &&
3589f4a2713aSLionel Sambuc !hasGlobalIndex() && TriedLoadingGlobalIndex;
3590f4a2713aSLionel Sambuc }
3591f4a2713aSLionel Sambuc
updateModuleTimestamp(ModuleFile & MF)3592*0a6a1f1dSLionel Sambuc static void updateModuleTimestamp(ModuleFile &MF) {
3593*0a6a1f1dSLionel Sambuc // Overwrite the timestamp file contents so that file's mtime changes.
3594*0a6a1f1dSLionel Sambuc std::string TimestampFilename = MF.getTimestampFilename();
3595*0a6a1f1dSLionel Sambuc std::error_code EC;
3596*0a6a1f1dSLionel Sambuc llvm::raw_fd_ostream OS(TimestampFilename, EC, llvm::sys::fs::F_Text);
3597*0a6a1f1dSLionel Sambuc if (EC)
3598*0a6a1f1dSLionel Sambuc return;
3599*0a6a1f1dSLionel Sambuc OS << "Timestamp file\n";
3600*0a6a1f1dSLionel Sambuc }
3601*0a6a1f1dSLionel Sambuc
ReadAST(const std::string & FileName,ModuleKind Type,SourceLocation ImportLoc,unsigned ClientLoadCapabilities)3602f4a2713aSLionel Sambuc ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
3603f4a2713aSLionel Sambuc ModuleKind Type,
3604f4a2713aSLionel Sambuc SourceLocation ImportLoc,
3605f4a2713aSLionel Sambuc unsigned ClientLoadCapabilities) {
3606f4a2713aSLionel Sambuc llvm::SaveAndRestore<SourceLocation>
3607f4a2713aSLionel Sambuc SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
3608f4a2713aSLionel Sambuc
3609*0a6a1f1dSLionel Sambuc // Defer any pending actions until we get to the end of reading the AST file.
3610*0a6a1f1dSLionel Sambuc Deserializing AnASTFile(this);
3611*0a6a1f1dSLionel Sambuc
3612f4a2713aSLionel Sambuc // Bump the generation number.
3613*0a6a1f1dSLionel Sambuc unsigned PreviousGeneration = incrementGeneration(Context);
3614f4a2713aSLionel Sambuc
3615f4a2713aSLionel Sambuc unsigned NumModules = ModuleMgr.size();
3616f4a2713aSLionel Sambuc SmallVector<ImportedModule, 4> Loaded;
3617f4a2713aSLionel Sambuc switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
3618*0a6a1f1dSLionel Sambuc /*ImportedBy=*/nullptr, Loaded,
3619*0a6a1f1dSLionel Sambuc 0, 0, 0,
3620f4a2713aSLionel Sambuc ClientLoadCapabilities)) {
3621f4a2713aSLionel Sambuc case Failure:
3622f4a2713aSLionel Sambuc case Missing:
3623f4a2713aSLionel Sambuc case OutOfDate:
3624f4a2713aSLionel Sambuc case VersionMismatch:
3625f4a2713aSLionel Sambuc case ConfigurationMismatch:
3626*0a6a1f1dSLionel Sambuc case HadErrors: {
3627*0a6a1f1dSLionel Sambuc llvm::SmallPtrSet<ModuleFile *, 4> LoadedSet;
3628*0a6a1f1dSLionel Sambuc for (const ImportedModule &IM : Loaded)
3629*0a6a1f1dSLionel Sambuc LoadedSet.insert(IM.Mod);
3630*0a6a1f1dSLionel Sambuc
3631f4a2713aSLionel Sambuc ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
3632*0a6a1f1dSLionel Sambuc LoadedSet,
3633f4a2713aSLionel Sambuc Context.getLangOpts().Modules
3634f4a2713aSLionel Sambuc ? &PP.getHeaderSearchInfo().getModuleMap()
3635*0a6a1f1dSLionel Sambuc : nullptr);
3636f4a2713aSLionel Sambuc
3637f4a2713aSLionel Sambuc // If we find that any modules are unusable, the global index is going
3638f4a2713aSLionel Sambuc // to be out-of-date. Just remove it.
3639f4a2713aSLionel Sambuc GlobalIndex.reset();
3640*0a6a1f1dSLionel Sambuc ModuleMgr.setGlobalIndex(nullptr);
3641f4a2713aSLionel Sambuc return ReadResult;
3642*0a6a1f1dSLionel Sambuc }
3643f4a2713aSLionel Sambuc case Success:
3644f4a2713aSLionel Sambuc break;
3645f4a2713aSLionel Sambuc }
3646f4a2713aSLionel Sambuc
3647f4a2713aSLionel Sambuc // Here comes stuff that we only do once the entire chain is loaded.
3648f4a2713aSLionel Sambuc
3649f4a2713aSLionel Sambuc // Load the AST blocks of all of the modules that we loaded.
3650f4a2713aSLionel Sambuc for (SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
3651f4a2713aSLionel Sambuc MEnd = Loaded.end();
3652f4a2713aSLionel Sambuc M != MEnd; ++M) {
3653f4a2713aSLionel Sambuc ModuleFile &F = *M->Mod;
3654f4a2713aSLionel Sambuc
3655f4a2713aSLionel Sambuc // Read the AST block.
3656*0a6a1f1dSLionel Sambuc if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
3657*0a6a1f1dSLionel Sambuc return Result;
3658f4a2713aSLionel Sambuc
3659f4a2713aSLionel Sambuc // Once read, set the ModuleFile bit base offset and update the size in
3660f4a2713aSLionel Sambuc // bits of all files we've seen.
3661f4a2713aSLionel Sambuc F.GlobalBitOffset = TotalModulesSizeInBits;
3662f4a2713aSLionel Sambuc TotalModulesSizeInBits += F.SizeInBits;
3663f4a2713aSLionel Sambuc GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
3664f4a2713aSLionel Sambuc
3665f4a2713aSLionel Sambuc // Preload SLocEntries.
3666f4a2713aSLionel Sambuc for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {
3667f4a2713aSLionel Sambuc int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
3668f4a2713aSLionel Sambuc // Load it through the SourceManager and don't call ReadSLocEntry()
3669f4a2713aSLionel Sambuc // directly because the entry may have already been loaded in which case
3670f4a2713aSLionel Sambuc // calling ReadSLocEntry() directly would trigger an assertion in
3671f4a2713aSLionel Sambuc // SourceManager.
3672f4a2713aSLionel Sambuc SourceMgr.getLoadedSLocEntryByID(Index);
3673f4a2713aSLionel Sambuc }
3674f4a2713aSLionel Sambuc }
3675f4a2713aSLionel Sambuc
3676f4a2713aSLionel Sambuc // Setup the import locations and notify the module manager that we've
3677f4a2713aSLionel Sambuc // committed to these module files.
3678f4a2713aSLionel Sambuc for (SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
3679f4a2713aSLionel Sambuc MEnd = Loaded.end();
3680f4a2713aSLionel Sambuc M != MEnd; ++M) {
3681f4a2713aSLionel Sambuc ModuleFile &F = *M->Mod;
3682f4a2713aSLionel Sambuc
3683f4a2713aSLionel Sambuc ModuleMgr.moduleFileAccepted(&F);
3684f4a2713aSLionel Sambuc
3685f4a2713aSLionel Sambuc // Set the import location.
3686f4a2713aSLionel Sambuc F.DirectImportLoc = ImportLoc;
3687f4a2713aSLionel Sambuc if (!M->ImportedBy)
3688f4a2713aSLionel Sambuc F.ImportLoc = M->ImportLoc;
3689f4a2713aSLionel Sambuc else
3690f4a2713aSLionel Sambuc F.ImportLoc = ReadSourceLocation(*M->ImportedBy,
3691f4a2713aSLionel Sambuc M->ImportLoc.getRawEncoding());
3692f4a2713aSLionel Sambuc }
3693f4a2713aSLionel Sambuc
3694f4a2713aSLionel Sambuc // Mark all of the identifiers in the identifier table as being out of date,
3695f4a2713aSLionel Sambuc // so that various accessors know to check the loaded modules when the
3696f4a2713aSLionel Sambuc // identifier is used.
3697f4a2713aSLionel Sambuc for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
3698f4a2713aSLionel Sambuc IdEnd = PP.getIdentifierTable().end();
3699f4a2713aSLionel Sambuc Id != IdEnd; ++Id)
3700f4a2713aSLionel Sambuc Id->second->setOutOfDate(true);
3701f4a2713aSLionel Sambuc
3702f4a2713aSLionel Sambuc // Resolve any unresolved module exports.
3703f4a2713aSLionel Sambuc for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) {
3704f4a2713aSLionel Sambuc UnresolvedModuleRef &Unresolved = UnresolvedModuleRefs[I];
3705f4a2713aSLionel Sambuc SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);
3706f4a2713aSLionel Sambuc Module *ResolvedMod = getSubmodule(GlobalID);
3707f4a2713aSLionel Sambuc
3708f4a2713aSLionel Sambuc switch (Unresolved.Kind) {
3709f4a2713aSLionel Sambuc case UnresolvedModuleRef::Conflict:
3710f4a2713aSLionel Sambuc if (ResolvedMod) {
3711f4a2713aSLionel Sambuc Module::Conflict Conflict;
3712f4a2713aSLionel Sambuc Conflict.Other = ResolvedMod;
3713f4a2713aSLionel Sambuc Conflict.Message = Unresolved.String.str();
3714f4a2713aSLionel Sambuc Unresolved.Mod->Conflicts.push_back(Conflict);
3715f4a2713aSLionel Sambuc }
3716f4a2713aSLionel Sambuc continue;
3717f4a2713aSLionel Sambuc
3718f4a2713aSLionel Sambuc case UnresolvedModuleRef::Import:
3719f4a2713aSLionel Sambuc if (ResolvedMod)
3720f4a2713aSLionel Sambuc Unresolved.Mod->Imports.push_back(ResolvedMod);
3721f4a2713aSLionel Sambuc continue;
3722f4a2713aSLionel Sambuc
3723f4a2713aSLionel Sambuc case UnresolvedModuleRef::Export:
3724f4a2713aSLionel Sambuc if (ResolvedMod || Unresolved.IsWildcard)
3725f4a2713aSLionel Sambuc Unresolved.Mod->Exports.push_back(
3726f4a2713aSLionel Sambuc Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
3727f4a2713aSLionel Sambuc continue;
3728f4a2713aSLionel Sambuc }
3729f4a2713aSLionel Sambuc }
3730f4a2713aSLionel Sambuc UnresolvedModuleRefs.clear();
3731f4a2713aSLionel Sambuc
3732f4a2713aSLionel Sambuc // FIXME: How do we load the 'use'd modules? They may not be submodules.
3733f4a2713aSLionel Sambuc // Might be unnecessary as use declarations are only used to build the
3734f4a2713aSLionel Sambuc // module itself.
3735f4a2713aSLionel Sambuc
3736f4a2713aSLionel Sambuc InitializeContext();
3737f4a2713aSLionel Sambuc
3738f4a2713aSLionel Sambuc if (SemaObj)
3739f4a2713aSLionel Sambuc UpdateSema();
3740f4a2713aSLionel Sambuc
3741f4a2713aSLionel Sambuc if (DeserializationListener)
3742f4a2713aSLionel Sambuc DeserializationListener->ReaderInitialized(this);
3743f4a2713aSLionel Sambuc
3744f4a2713aSLionel Sambuc ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule();
3745f4a2713aSLionel Sambuc if (!PrimaryModule.OriginalSourceFileID.isInvalid()) {
3746f4a2713aSLionel Sambuc PrimaryModule.OriginalSourceFileID
3747f4a2713aSLionel Sambuc = FileID::get(PrimaryModule.SLocEntryBaseID
3748f4a2713aSLionel Sambuc + PrimaryModule.OriginalSourceFileID.getOpaqueValue() - 1);
3749f4a2713aSLionel Sambuc
3750f4a2713aSLionel Sambuc // If this AST file is a precompiled preamble, then set the
3751f4a2713aSLionel Sambuc // preamble file ID of the source manager to the file source file
3752f4a2713aSLionel Sambuc // from which the preamble was built.
3753f4a2713aSLionel Sambuc if (Type == MK_Preamble) {
3754f4a2713aSLionel Sambuc SourceMgr.setPreambleFileID(PrimaryModule.OriginalSourceFileID);
3755f4a2713aSLionel Sambuc } else if (Type == MK_MainFile) {
3756f4a2713aSLionel Sambuc SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID);
3757f4a2713aSLionel Sambuc }
3758f4a2713aSLionel Sambuc }
3759f4a2713aSLionel Sambuc
3760f4a2713aSLionel Sambuc // For any Objective-C class definitions we have already loaded, make sure
3761f4a2713aSLionel Sambuc // that we load any additional categories.
3762f4a2713aSLionel Sambuc for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {
3763f4a2713aSLionel Sambuc loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(),
3764f4a2713aSLionel Sambuc ObjCClassesLoaded[I],
3765f4a2713aSLionel Sambuc PreviousGeneration);
3766f4a2713aSLionel Sambuc }
3767f4a2713aSLionel Sambuc
3768*0a6a1f1dSLionel Sambuc if (PP.getHeaderSearchInfo()
3769*0a6a1f1dSLionel Sambuc .getHeaderSearchOpts()
3770*0a6a1f1dSLionel Sambuc .ModulesValidateOncePerBuildSession) {
3771*0a6a1f1dSLionel Sambuc // Now we are certain that the module and all modules it depends on are
3772*0a6a1f1dSLionel Sambuc // up to date. Create or update timestamp files for modules that are
3773*0a6a1f1dSLionel Sambuc // located in the module cache (not for PCH files that could be anywhere
3774*0a6a1f1dSLionel Sambuc // in the filesystem).
3775*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
3776*0a6a1f1dSLionel Sambuc ImportedModule &M = Loaded[I];
3777*0a6a1f1dSLionel Sambuc if (M.Mod->Kind == MK_ImplicitModule) {
3778*0a6a1f1dSLionel Sambuc updateModuleTimestamp(*M.Mod);
3779*0a6a1f1dSLionel Sambuc }
3780*0a6a1f1dSLionel Sambuc }
3781*0a6a1f1dSLionel Sambuc }
3782*0a6a1f1dSLionel Sambuc
3783f4a2713aSLionel Sambuc return Success;
3784f4a2713aSLionel Sambuc }
3785f4a2713aSLionel Sambuc
3786*0a6a1f1dSLionel Sambuc static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile);
3787*0a6a1f1dSLionel Sambuc
3788f4a2713aSLionel Sambuc ASTReader::ASTReadResult
ReadASTCore(StringRef FileName,ModuleKind Type,SourceLocation ImportLoc,ModuleFile * ImportedBy,SmallVectorImpl<ImportedModule> & Loaded,off_t ExpectedSize,time_t ExpectedModTime,ASTFileSignature ExpectedSignature,unsigned ClientLoadCapabilities)3789f4a2713aSLionel Sambuc ASTReader::ReadASTCore(StringRef FileName,
3790f4a2713aSLionel Sambuc ModuleKind Type,
3791f4a2713aSLionel Sambuc SourceLocation ImportLoc,
3792f4a2713aSLionel Sambuc ModuleFile *ImportedBy,
3793f4a2713aSLionel Sambuc SmallVectorImpl<ImportedModule> &Loaded,
3794f4a2713aSLionel Sambuc off_t ExpectedSize, time_t ExpectedModTime,
3795*0a6a1f1dSLionel Sambuc ASTFileSignature ExpectedSignature,
3796f4a2713aSLionel Sambuc unsigned ClientLoadCapabilities) {
3797f4a2713aSLionel Sambuc ModuleFile *M;
3798f4a2713aSLionel Sambuc std::string ErrorStr;
3799f4a2713aSLionel Sambuc ModuleManager::AddModuleResult AddResult
3800f4a2713aSLionel Sambuc = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
3801*0a6a1f1dSLionel Sambuc getGeneration(), ExpectedSize, ExpectedModTime,
3802*0a6a1f1dSLionel Sambuc ExpectedSignature, readASTFileSignature,
3803f4a2713aSLionel Sambuc M, ErrorStr);
3804f4a2713aSLionel Sambuc
3805f4a2713aSLionel Sambuc switch (AddResult) {
3806f4a2713aSLionel Sambuc case ModuleManager::AlreadyLoaded:
3807f4a2713aSLionel Sambuc return Success;
3808f4a2713aSLionel Sambuc
3809f4a2713aSLionel Sambuc case ModuleManager::NewlyLoaded:
3810f4a2713aSLionel Sambuc // Load module file below.
3811f4a2713aSLionel Sambuc break;
3812f4a2713aSLionel Sambuc
3813f4a2713aSLionel Sambuc case ModuleManager::Missing:
3814*0a6a1f1dSLionel Sambuc // The module file was missing; if the client can handle that, return
3815f4a2713aSLionel Sambuc // it.
3816f4a2713aSLionel Sambuc if (ClientLoadCapabilities & ARR_Missing)
3817f4a2713aSLionel Sambuc return Missing;
3818f4a2713aSLionel Sambuc
3819f4a2713aSLionel Sambuc // Otherwise, return an error.
3820f4a2713aSLionel Sambuc {
3821f4a2713aSLionel Sambuc std::string Msg = "Unable to load module \"" + FileName.str() + "\": "
3822f4a2713aSLionel Sambuc + ErrorStr;
3823f4a2713aSLionel Sambuc Error(Msg);
3824f4a2713aSLionel Sambuc }
3825f4a2713aSLionel Sambuc return Failure;
3826f4a2713aSLionel Sambuc
3827f4a2713aSLionel Sambuc case ModuleManager::OutOfDate:
3828f4a2713aSLionel Sambuc // We couldn't load the module file because it is out-of-date. If the
3829f4a2713aSLionel Sambuc // client can handle out-of-date, return it.
3830f4a2713aSLionel Sambuc if (ClientLoadCapabilities & ARR_OutOfDate)
3831f4a2713aSLionel Sambuc return OutOfDate;
3832f4a2713aSLionel Sambuc
3833f4a2713aSLionel Sambuc // Otherwise, return an error.
3834f4a2713aSLionel Sambuc {
3835f4a2713aSLionel Sambuc std::string Msg = "Unable to load module \"" + FileName.str() + "\": "
3836f4a2713aSLionel Sambuc + ErrorStr;
3837f4a2713aSLionel Sambuc Error(Msg);
3838f4a2713aSLionel Sambuc }
3839f4a2713aSLionel Sambuc return Failure;
3840f4a2713aSLionel Sambuc }
3841f4a2713aSLionel Sambuc
3842f4a2713aSLionel Sambuc assert(M && "Missing module file");
3843f4a2713aSLionel Sambuc
3844f4a2713aSLionel Sambuc // FIXME: This seems rather a hack. Should CurrentDir be part of the
3845f4a2713aSLionel Sambuc // module?
3846f4a2713aSLionel Sambuc if (FileName != "-") {
3847f4a2713aSLionel Sambuc CurrentDir = llvm::sys::path::parent_path(FileName);
3848f4a2713aSLionel Sambuc if (CurrentDir.empty()) CurrentDir = ".";
3849f4a2713aSLionel Sambuc }
3850f4a2713aSLionel Sambuc
3851f4a2713aSLionel Sambuc ModuleFile &F = *M;
3852f4a2713aSLionel Sambuc BitstreamCursor &Stream = F.Stream;
3853*0a6a1f1dSLionel Sambuc Stream.init(&F.StreamFile);
3854f4a2713aSLionel Sambuc F.SizeInBits = F.Buffer->getBufferSize() * 8;
3855f4a2713aSLionel Sambuc
3856f4a2713aSLionel Sambuc // Sniff for the signature.
3857f4a2713aSLionel Sambuc if (Stream.Read(8) != 'C' ||
3858f4a2713aSLionel Sambuc Stream.Read(8) != 'P' ||
3859f4a2713aSLionel Sambuc Stream.Read(8) != 'C' ||
3860f4a2713aSLionel Sambuc Stream.Read(8) != 'H') {
3861f4a2713aSLionel Sambuc Diag(diag::err_not_a_pch_file) << FileName;
3862f4a2713aSLionel Sambuc return Failure;
3863f4a2713aSLionel Sambuc }
3864f4a2713aSLionel Sambuc
3865f4a2713aSLionel Sambuc // This is used for compatibility with older PCH formats.
3866f4a2713aSLionel Sambuc bool HaveReadControlBlock = false;
3867f4a2713aSLionel Sambuc
3868f4a2713aSLionel Sambuc while (1) {
3869f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advance();
3870f4a2713aSLionel Sambuc
3871f4a2713aSLionel Sambuc switch (Entry.Kind) {
3872f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
3873f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
3874f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
3875f4a2713aSLionel Sambuc Error("invalid record at top-level of AST file");
3876f4a2713aSLionel Sambuc return Failure;
3877f4a2713aSLionel Sambuc
3878f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock:
3879f4a2713aSLionel Sambuc break;
3880f4a2713aSLionel Sambuc }
3881f4a2713aSLionel Sambuc
3882f4a2713aSLionel Sambuc // We only know the control subblock ID.
3883f4a2713aSLionel Sambuc switch (Entry.ID) {
3884f4a2713aSLionel Sambuc case llvm::bitc::BLOCKINFO_BLOCK_ID:
3885f4a2713aSLionel Sambuc if (Stream.ReadBlockInfoBlock()) {
3886f4a2713aSLionel Sambuc Error("malformed BlockInfoBlock in AST file");
3887f4a2713aSLionel Sambuc return Failure;
3888f4a2713aSLionel Sambuc }
3889f4a2713aSLionel Sambuc break;
3890f4a2713aSLionel Sambuc case CONTROL_BLOCK_ID:
3891f4a2713aSLionel Sambuc HaveReadControlBlock = true;
3892*0a6a1f1dSLionel Sambuc switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {
3893f4a2713aSLionel Sambuc case Success:
3894f4a2713aSLionel Sambuc break;
3895f4a2713aSLionel Sambuc
3896f4a2713aSLionel Sambuc case Failure: return Failure;
3897f4a2713aSLionel Sambuc case Missing: return Missing;
3898f4a2713aSLionel Sambuc case OutOfDate: return OutOfDate;
3899f4a2713aSLionel Sambuc case VersionMismatch: return VersionMismatch;
3900f4a2713aSLionel Sambuc case ConfigurationMismatch: return ConfigurationMismatch;
3901f4a2713aSLionel Sambuc case HadErrors: return HadErrors;
3902f4a2713aSLionel Sambuc }
3903f4a2713aSLionel Sambuc break;
3904f4a2713aSLionel Sambuc case AST_BLOCK_ID:
3905f4a2713aSLionel Sambuc if (!HaveReadControlBlock) {
3906f4a2713aSLionel Sambuc if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
3907*0a6a1f1dSLionel Sambuc Diag(diag::err_pch_version_too_old);
3908f4a2713aSLionel Sambuc return VersionMismatch;
3909f4a2713aSLionel Sambuc }
3910f4a2713aSLionel Sambuc
3911f4a2713aSLionel Sambuc // Record that we've loaded this module.
3912f4a2713aSLionel Sambuc Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
3913f4a2713aSLionel Sambuc return Success;
3914f4a2713aSLionel Sambuc
3915f4a2713aSLionel Sambuc default:
3916f4a2713aSLionel Sambuc if (Stream.SkipBlock()) {
3917f4a2713aSLionel Sambuc Error("malformed block record in AST file");
3918f4a2713aSLionel Sambuc return Failure;
3919f4a2713aSLionel Sambuc }
3920f4a2713aSLionel Sambuc break;
3921f4a2713aSLionel Sambuc }
3922f4a2713aSLionel Sambuc }
3923f4a2713aSLionel Sambuc
3924f4a2713aSLionel Sambuc return Success;
3925f4a2713aSLionel Sambuc }
3926f4a2713aSLionel Sambuc
InitializeContext()3927f4a2713aSLionel Sambuc void ASTReader::InitializeContext() {
3928f4a2713aSLionel Sambuc // If there's a listener, notify them that we "read" the translation unit.
3929f4a2713aSLionel Sambuc if (DeserializationListener)
3930f4a2713aSLionel Sambuc DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
3931f4a2713aSLionel Sambuc Context.getTranslationUnitDecl());
3932f4a2713aSLionel Sambuc
3933f4a2713aSLionel Sambuc // FIXME: Find a better way to deal with collisions between these
3934f4a2713aSLionel Sambuc // built-in types. Right now, we just ignore the problem.
3935f4a2713aSLionel Sambuc
3936f4a2713aSLionel Sambuc // Load the special types.
3937f4a2713aSLionel Sambuc if (SpecialTypes.size() >= NumSpecialTypeIDs) {
3938f4a2713aSLionel Sambuc if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
3939f4a2713aSLionel Sambuc if (!Context.CFConstantStringTypeDecl)
3940f4a2713aSLionel Sambuc Context.setCFConstantStringType(GetType(String));
3941f4a2713aSLionel Sambuc }
3942f4a2713aSLionel Sambuc
3943f4a2713aSLionel Sambuc if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
3944f4a2713aSLionel Sambuc QualType FileType = GetType(File);
3945f4a2713aSLionel Sambuc if (FileType.isNull()) {
3946f4a2713aSLionel Sambuc Error("FILE type is NULL");
3947f4a2713aSLionel Sambuc return;
3948f4a2713aSLionel Sambuc }
3949f4a2713aSLionel Sambuc
3950f4a2713aSLionel Sambuc if (!Context.FILEDecl) {
3951f4a2713aSLionel Sambuc if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
3952f4a2713aSLionel Sambuc Context.setFILEDecl(Typedef->getDecl());
3953f4a2713aSLionel Sambuc else {
3954f4a2713aSLionel Sambuc const TagType *Tag = FileType->getAs<TagType>();
3955f4a2713aSLionel Sambuc if (!Tag) {
3956f4a2713aSLionel Sambuc Error("Invalid FILE type in AST file");
3957f4a2713aSLionel Sambuc return;
3958f4a2713aSLionel Sambuc }
3959f4a2713aSLionel Sambuc Context.setFILEDecl(Tag->getDecl());
3960f4a2713aSLionel Sambuc }
3961f4a2713aSLionel Sambuc }
3962f4a2713aSLionel Sambuc }
3963f4a2713aSLionel Sambuc
3964f4a2713aSLionel Sambuc if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
3965f4a2713aSLionel Sambuc QualType Jmp_bufType = GetType(Jmp_buf);
3966f4a2713aSLionel Sambuc if (Jmp_bufType.isNull()) {
3967f4a2713aSLionel Sambuc Error("jmp_buf type is NULL");
3968f4a2713aSLionel Sambuc return;
3969f4a2713aSLionel Sambuc }
3970f4a2713aSLionel Sambuc
3971f4a2713aSLionel Sambuc if (!Context.jmp_bufDecl) {
3972f4a2713aSLionel Sambuc if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
3973f4a2713aSLionel Sambuc Context.setjmp_bufDecl(Typedef->getDecl());
3974f4a2713aSLionel Sambuc else {
3975f4a2713aSLionel Sambuc const TagType *Tag = Jmp_bufType->getAs<TagType>();
3976f4a2713aSLionel Sambuc if (!Tag) {
3977f4a2713aSLionel Sambuc Error("Invalid jmp_buf type in AST file");
3978f4a2713aSLionel Sambuc return;
3979f4a2713aSLionel Sambuc }
3980f4a2713aSLionel Sambuc Context.setjmp_bufDecl(Tag->getDecl());
3981f4a2713aSLionel Sambuc }
3982f4a2713aSLionel Sambuc }
3983f4a2713aSLionel Sambuc }
3984f4a2713aSLionel Sambuc
3985f4a2713aSLionel Sambuc if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
3986f4a2713aSLionel Sambuc QualType Sigjmp_bufType = GetType(Sigjmp_buf);
3987f4a2713aSLionel Sambuc if (Sigjmp_bufType.isNull()) {
3988f4a2713aSLionel Sambuc Error("sigjmp_buf type is NULL");
3989f4a2713aSLionel Sambuc return;
3990f4a2713aSLionel Sambuc }
3991f4a2713aSLionel Sambuc
3992f4a2713aSLionel Sambuc if (!Context.sigjmp_bufDecl) {
3993f4a2713aSLionel Sambuc if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
3994f4a2713aSLionel Sambuc Context.setsigjmp_bufDecl(Typedef->getDecl());
3995f4a2713aSLionel Sambuc else {
3996f4a2713aSLionel Sambuc const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
3997f4a2713aSLionel Sambuc assert(Tag && "Invalid sigjmp_buf type in AST file");
3998f4a2713aSLionel Sambuc Context.setsigjmp_bufDecl(Tag->getDecl());
3999f4a2713aSLionel Sambuc }
4000f4a2713aSLionel Sambuc }
4001f4a2713aSLionel Sambuc }
4002f4a2713aSLionel Sambuc
4003f4a2713aSLionel Sambuc if (unsigned ObjCIdRedef
4004f4a2713aSLionel Sambuc = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
4005f4a2713aSLionel Sambuc if (Context.ObjCIdRedefinitionType.isNull())
4006f4a2713aSLionel Sambuc Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);
4007f4a2713aSLionel Sambuc }
4008f4a2713aSLionel Sambuc
4009f4a2713aSLionel Sambuc if (unsigned ObjCClassRedef
4010f4a2713aSLionel Sambuc = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
4011f4a2713aSLionel Sambuc if (Context.ObjCClassRedefinitionType.isNull())
4012f4a2713aSLionel Sambuc Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);
4013f4a2713aSLionel Sambuc }
4014f4a2713aSLionel Sambuc
4015f4a2713aSLionel Sambuc if (unsigned ObjCSelRedef
4016f4a2713aSLionel Sambuc = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
4017f4a2713aSLionel Sambuc if (Context.ObjCSelRedefinitionType.isNull())
4018f4a2713aSLionel Sambuc Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);
4019f4a2713aSLionel Sambuc }
4020f4a2713aSLionel Sambuc
4021f4a2713aSLionel Sambuc if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {
4022f4a2713aSLionel Sambuc QualType Ucontext_tType = GetType(Ucontext_t);
4023f4a2713aSLionel Sambuc if (Ucontext_tType.isNull()) {
4024f4a2713aSLionel Sambuc Error("ucontext_t type is NULL");
4025f4a2713aSLionel Sambuc return;
4026f4a2713aSLionel Sambuc }
4027f4a2713aSLionel Sambuc
4028f4a2713aSLionel Sambuc if (!Context.ucontext_tDecl) {
4029f4a2713aSLionel Sambuc if (const TypedefType *Typedef = Ucontext_tType->getAs<TypedefType>())
4030f4a2713aSLionel Sambuc Context.setucontext_tDecl(Typedef->getDecl());
4031f4a2713aSLionel Sambuc else {
4032f4a2713aSLionel Sambuc const TagType *Tag = Ucontext_tType->getAs<TagType>();
4033f4a2713aSLionel Sambuc assert(Tag && "Invalid ucontext_t type in AST file");
4034f4a2713aSLionel Sambuc Context.setucontext_tDecl(Tag->getDecl());
4035f4a2713aSLionel Sambuc }
4036f4a2713aSLionel Sambuc }
4037f4a2713aSLionel Sambuc }
4038f4a2713aSLionel Sambuc }
4039f4a2713aSLionel Sambuc
4040f4a2713aSLionel Sambuc ReadPragmaDiagnosticMappings(Context.getDiagnostics());
4041f4a2713aSLionel Sambuc
4042f4a2713aSLionel Sambuc // If there were any CUDA special declarations, deserialize them.
4043f4a2713aSLionel Sambuc if (!CUDASpecialDeclRefs.empty()) {
4044f4a2713aSLionel Sambuc assert(CUDASpecialDeclRefs.size() == 1 && "More decl refs than expected!");
4045f4a2713aSLionel Sambuc Context.setcudaConfigureCallDecl(
4046f4a2713aSLionel Sambuc cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
4047f4a2713aSLionel Sambuc }
4048f4a2713aSLionel Sambuc
4049f4a2713aSLionel Sambuc // Re-export any modules that were imported by a non-module AST file.
4050*0a6a1f1dSLionel Sambuc // FIXME: This does not make macro-only imports visible again. It also doesn't
4051*0a6a1f1dSLionel Sambuc // make #includes mapped to module imports visible.
4052*0a6a1f1dSLionel Sambuc for (auto &Import : ImportedModules) {
4053*0a6a1f1dSLionel Sambuc if (Module *Imported = getSubmodule(Import.ID))
4054f4a2713aSLionel Sambuc makeModuleVisible(Imported, Module::AllVisible,
4055*0a6a1f1dSLionel Sambuc /*ImportLoc=*/Import.ImportLoc,
4056f4a2713aSLionel Sambuc /*Complain=*/false);
4057f4a2713aSLionel Sambuc }
4058f4a2713aSLionel Sambuc ImportedModules.clear();
4059f4a2713aSLionel Sambuc }
4060f4a2713aSLionel Sambuc
finalizeForWriting()4061f4a2713aSLionel Sambuc void ASTReader::finalizeForWriting() {
4062*0a6a1f1dSLionel Sambuc while (!HiddenNamesMap.empty()) {
4063*0a6a1f1dSLionel Sambuc auto HiddenNames = std::move(*HiddenNamesMap.begin());
4064*0a6a1f1dSLionel Sambuc HiddenNamesMap.erase(HiddenNamesMap.begin());
4065*0a6a1f1dSLionel Sambuc makeNamesVisible(HiddenNames.second, HiddenNames.first,
4066*0a6a1f1dSLionel Sambuc /*FromFinalization*/true);
4067f4a2713aSLionel Sambuc }
4068f4a2713aSLionel Sambuc }
4069f4a2713aSLionel Sambuc
4070f4a2713aSLionel Sambuc /// \brief Given a cursor at the start of an AST file, scan ahead and drop the
4071f4a2713aSLionel Sambuc /// cursor into the start of the given block ID, returning false on success and
4072f4a2713aSLionel Sambuc /// true on failure.
SkipCursorToBlock(BitstreamCursor & Cursor,unsigned BlockID)4073f4a2713aSLionel Sambuc static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) {
4074f4a2713aSLionel Sambuc while (1) {
4075f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Cursor.advance();
4076f4a2713aSLionel Sambuc switch (Entry.Kind) {
4077f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
4078f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
4079f4a2713aSLionel Sambuc return true;
4080f4a2713aSLionel Sambuc
4081f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
4082f4a2713aSLionel Sambuc // Ignore top-level records.
4083f4a2713aSLionel Sambuc Cursor.skipRecord(Entry.ID);
4084f4a2713aSLionel Sambuc break;
4085f4a2713aSLionel Sambuc
4086f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock:
4087f4a2713aSLionel Sambuc if (Entry.ID == BlockID) {
4088f4a2713aSLionel Sambuc if (Cursor.EnterSubBlock(BlockID))
4089f4a2713aSLionel Sambuc return true;
4090f4a2713aSLionel Sambuc // Found it!
4091f4a2713aSLionel Sambuc return false;
4092f4a2713aSLionel Sambuc }
4093f4a2713aSLionel Sambuc
4094f4a2713aSLionel Sambuc if (Cursor.SkipBlock())
4095f4a2713aSLionel Sambuc return true;
4096f4a2713aSLionel Sambuc }
4097f4a2713aSLionel Sambuc }
4098f4a2713aSLionel Sambuc }
4099f4a2713aSLionel Sambuc
readASTFileSignature(llvm::BitstreamReader & StreamFile)4100*0a6a1f1dSLionel Sambuc static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){
4101*0a6a1f1dSLionel Sambuc BitstreamCursor Stream(StreamFile);
4102*0a6a1f1dSLionel Sambuc if (Stream.Read(8) != 'C' ||
4103*0a6a1f1dSLionel Sambuc Stream.Read(8) != 'P' ||
4104*0a6a1f1dSLionel Sambuc Stream.Read(8) != 'C' ||
4105*0a6a1f1dSLionel Sambuc Stream.Read(8) != 'H') {
4106*0a6a1f1dSLionel Sambuc return 0;
4107*0a6a1f1dSLionel Sambuc }
4108*0a6a1f1dSLionel Sambuc
4109*0a6a1f1dSLionel Sambuc // Scan for the CONTROL_BLOCK_ID block.
4110*0a6a1f1dSLionel Sambuc if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
4111*0a6a1f1dSLionel Sambuc return 0;
4112*0a6a1f1dSLionel Sambuc
4113*0a6a1f1dSLionel Sambuc // Scan for SIGNATURE inside the control block.
4114*0a6a1f1dSLionel Sambuc ASTReader::RecordData Record;
4115*0a6a1f1dSLionel Sambuc while (1) {
4116*0a6a1f1dSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
4117*0a6a1f1dSLionel Sambuc if (Entry.Kind == llvm::BitstreamEntry::EndBlock ||
4118*0a6a1f1dSLionel Sambuc Entry.Kind != llvm::BitstreamEntry::Record)
4119*0a6a1f1dSLionel Sambuc return 0;
4120*0a6a1f1dSLionel Sambuc
4121*0a6a1f1dSLionel Sambuc Record.clear();
4122*0a6a1f1dSLionel Sambuc StringRef Blob;
4123*0a6a1f1dSLionel Sambuc if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
4124*0a6a1f1dSLionel Sambuc return Record[0];
4125*0a6a1f1dSLionel Sambuc }
4126*0a6a1f1dSLionel Sambuc }
4127*0a6a1f1dSLionel Sambuc
4128f4a2713aSLionel Sambuc /// \brief Retrieve the name of the original source file name
4129f4a2713aSLionel Sambuc /// directly from the AST file, without actually loading the AST
4130f4a2713aSLionel Sambuc /// file.
getOriginalSourceFile(const std::string & ASTFileName,FileManager & FileMgr,DiagnosticsEngine & Diags)4131f4a2713aSLionel Sambuc std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
4132f4a2713aSLionel Sambuc FileManager &FileMgr,
4133f4a2713aSLionel Sambuc DiagnosticsEngine &Diags) {
4134f4a2713aSLionel Sambuc // Open the AST file.
4135*0a6a1f1dSLionel Sambuc auto Buffer = FileMgr.getBufferForFile(ASTFileName);
4136f4a2713aSLionel Sambuc if (!Buffer) {
4137*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_fe_unable_to_read_pch_file)
4138*0a6a1f1dSLionel Sambuc << ASTFileName << Buffer.getError().message();
4139f4a2713aSLionel Sambuc return std::string();
4140f4a2713aSLionel Sambuc }
4141f4a2713aSLionel Sambuc
4142f4a2713aSLionel Sambuc // Initialize the stream
4143f4a2713aSLionel Sambuc llvm::BitstreamReader StreamFile;
4144*0a6a1f1dSLionel Sambuc StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
4145*0a6a1f1dSLionel Sambuc (const unsigned char *)(*Buffer)->getBufferEnd());
4146*0a6a1f1dSLionel Sambuc BitstreamCursor Stream(StreamFile);
4147f4a2713aSLionel Sambuc
4148f4a2713aSLionel Sambuc // Sniff for the signature.
4149f4a2713aSLionel Sambuc if (Stream.Read(8) != 'C' ||
4150f4a2713aSLionel Sambuc Stream.Read(8) != 'P' ||
4151f4a2713aSLionel Sambuc Stream.Read(8) != 'C' ||
4152f4a2713aSLionel Sambuc Stream.Read(8) != 'H') {
4153f4a2713aSLionel Sambuc Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
4154f4a2713aSLionel Sambuc return std::string();
4155f4a2713aSLionel Sambuc }
4156f4a2713aSLionel Sambuc
4157f4a2713aSLionel Sambuc // Scan for the CONTROL_BLOCK_ID block.
4158f4a2713aSLionel Sambuc if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) {
4159f4a2713aSLionel Sambuc Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
4160f4a2713aSLionel Sambuc return std::string();
4161f4a2713aSLionel Sambuc }
4162f4a2713aSLionel Sambuc
4163f4a2713aSLionel Sambuc // Scan for ORIGINAL_FILE inside the control block.
4164f4a2713aSLionel Sambuc RecordData Record;
4165f4a2713aSLionel Sambuc while (1) {
4166f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
4167f4a2713aSLionel Sambuc if (Entry.Kind == llvm::BitstreamEntry::EndBlock)
4168f4a2713aSLionel Sambuc return std::string();
4169f4a2713aSLionel Sambuc
4170f4a2713aSLionel Sambuc if (Entry.Kind != llvm::BitstreamEntry::Record) {
4171f4a2713aSLionel Sambuc Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
4172f4a2713aSLionel Sambuc return std::string();
4173f4a2713aSLionel Sambuc }
4174f4a2713aSLionel Sambuc
4175f4a2713aSLionel Sambuc Record.clear();
4176f4a2713aSLionel Sambuc StringRef Blob;
4177f4a2713aSLionel Sambuc if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE)
4178f4a2713aSLionel Sambuc return Blob.str();
4179f4a2713aSLionel Sambuc }
4180f4a2713aSLionel Sambuc }
4181f4a2713aSLionel Sambuc
4182f4a2713aSLionel Sambuc namespace {
4183f4a2713aSLionel Sambuc class SimplePCHValidator : public ASTReaderListener {
4184f4a2713aSLionel Sambuc const LangOptions &ExistingLangOpts;
4185f4a2713aSLionel Sambuc const TargetOptions &ExistingTargetOpts;
4186f4a2713aSLionel Sambuc const PreprocessorOptions &ExistingPPOpts;
4187f4a2713aSLionel Sambuc FileManager &FileMgr;
4188f4a2713aSLionel Sambuc
4189f4a2713aSLionel Sambuc public:
SimplePCHValidator(const LangOptions & ExistingLangOpts,const TargetOptions & ExistingTargetOpts,const PreprocessorOptions & ExistingPPOpts,FileManager & FileMgr)4190f4a2713aSLionel Sambuc SimplePCHValidator(const LangOptions &ExistingLangOpts,
4191f4a2713aSLionel Sambuc const TargetOptions &ExistingTargetOpts,
4192f4a2713aSLionel Sambuc const PreprocessorOptions &ExistingPPOpts,
4193f4a2713aSLionel Sambuc FileManager &FileMgr)
4194f4a2713aSLionel Sambuc : ExistingLangOpts(ExistingLangOpts),
4195f4a2713aSLionel Sambuc ExistingTargetOpts(ExistingTargetOpts),
4196f4a2713aSLionel Sambuc ExistingPPOpts(ExistingPPOpts),
4197f4a2713aSLionel Sambuc FileMgr(FileMgr)
4198f4a2713aSLionel Sambuc {
4199f4a2713aSLionel Sambuc }
4200f4a2713aSLionel Sambuc
ReadLanguageOptions(const LangOptions & LangOpts,bool Complain,bool AllowCompatibleDifferences)4201*0a6a1f1dSLionel Sambuc bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
4202*0a6a1f1dSLionel Sambuc bool AllowCompatibleDifferences) override {
4203*0a6a1f1dSLionel Sambuc return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr,
4204*0a6a1f1dSLionel Sambuc AllowCompatibleDifferences);
4205f4a2713aSLionel Sambuc }
ReadTargetOptions(const TargetOptions & TargetOpts,bool Complain)4206*0a6a1f1dSLionel Sambuc bool ReadTargetOptions(const TargetOptions &TargetOpts,
4207*0a6a1f1dSLionel Sambuc bool Complain) override {
4208*0a6a1f1dSLionel Sambuc return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr);
4209f4a2713aSLionel Sambuc }
ReadPreprocessorOptions(const PreprocessorOptions & PPOpts,bool Complain,std::string & SuggestedPredefines)4210*0a6a1f1dSLionel Sambuc bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
4211f4a2713aSLionel Sambuc bool Complain,
4212*0a6a1f1dSLionel Sambuc std::string &SuggestedPredefines) override {
4213*0a6a1f1dSLionel Sambuc return checkPreprocessorOptions(ExistingPPOpts, PPOpts, nullptr, FileMgr,
4214f4a2713aSLionel Sambuc SuggestedPredefines, ExistingLangOpts);
4215f4a2713aSLionel Sambuc }
4216f4a2713aSLionel Sambuc };
4217f4a2713aSLionel Sambuc }
4218f4a2713aSLionel Sambuc
readASTFileControlBlock(StringRef Filename,FileManager & FileMgr,ASTReaderListener & Listener)4219f4a2713aSLionel Sambuc bool ASTReader::readASTFileControlBlock(StringRef Filename,
4220f4a2713aSLionel Sambuc FileManager &FileMgr,
4221f4a2713aSLionel Sambuc ASTReaderListener &Listener) {
4222f4a2713aSLionel Sambuc // Open the AST file.
4223*0a6a1f1dSLionel Sambuc auto Buffer = FileMgr.getBufferForFile(Filename);
4224f4a2713aSLionel Sambuc if (!Buffer) {
4225f4a2713aSLionel Sambuc return true;
4226f4a2713aSLionel Sambuc }
4227f4a2713aSLionel Sambuc
4228f4a2713aSLionel Sambuc // Initialize the stream
4229f4a2713aSLionel Sambuc llvm::BitstreamReader StreamFile;
4230*0a6a1f1dSLionel Sambuc StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
4231*0a6a1f1dSLionel Sambuc (const unsigned char *)(*Buffer)->getBufferEnd());
4232*0a6a1f1dSLionel Sambuc BitstreamCursor Stream(StreamFile);
4233f4a2713aSLionel Sambuc
4234f4a2713aSLionel Sambuc // Sniff for the signature.
4235f4a2713aSLionel Sambuc if (Stream.Read(8) != 'C' ||
4236f4a2713aSLionel Sambuc Stream.Read(8) != 'P' ||
4237f4a2713aSLionel Sambuc Stream.Read(8) != 'C' ||
4238f4a2713aSLionel Sambuc Stream.Read(8) != 'H') {
4239f4a2713aSLionel Sambuc return true;
4240f4a2713aSLionel Sambuc }
4241f4a2713aSLionel Sambuc
4242f4a2713aSLionel Sambuc // Scan for the CONTROL_BLOCK_ID block.
4243f4a2713aSLionel Sambuc if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
4244f4a2713aSLionel Sambuc return true;
4245f4a2713aSLionel Sambuc
4246f4a2713aSLionel Sambuc bool NeedsInputFiles = Listener.needsInputFileVisitation();
4247*0a6a1f1dSLionel Sambuc bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation();
4248*0a6a1f1dSLionel Sambuc bool NeedsImports = Listener.needsImportVisitation();
4249f4a2713aSLionel Sambuc BitstreamCursor InputFilesCursor;
4250f4a2713aSLionel Sambuc if (NeedsInputFiles) {
4251f4a2713aSLionel Sambuc InputFilesCursor = Stream;
4252f4a2713aSLionel Sambuc if (SkipCursorToBlock(InputFilesCursor, INPUT_FILES_BLOCK_ID))
4253f4a2713aSLionel Sambuc return true;
4254f4a2713aSLionel Sambuc
4255f4a2713aSLionel Sambuc // Read the abbreviations
4256f4a2713aSLionel Sambuc while (true) {
4257f4a2713aSLionel Sambuc uint64_t Offset = InputFilesCursor.GetCurrentBitNo();
4258f4a2713aSLionel Sambuc unsigned Code = InputFilesCursor.ReadCode();
4259f4a2713aSLionel Sambuc
4260f4a2713aSLionel Sambuc // We expect all abbrevs to be at the start of the block.
4261f4a2713aSLionel Sambuc if (Code != llvm::bitc::DEFINE_ABBREV) {
4262f4a2713aSLionel Sambuc InputFilesCursor.JumpToBit(Offset);
4263f4a2713aSLionel Sambuc break;
4264f4a2713aSLionel Sambuc }
4265f4a2713aSLionel Sambuc InputFilesCursor.ReadAbbrevRecord();
4266f4a2713aSLionel Sambuc }
4267f4a2713aSLionel Sambuc }
4268f4a2713aSLionel Sambuc
4269f4a2713aSLionel Sambuc // Scan for ORIGINAL_FILE inside the control block.
4270f4a2713aSLionel Sambuc RecordData Record;
4271*0a6a1f1dSLionel Sambuc std::string ModuleDir;
4272f4a2713aSLionel Sambuc while (1) {
4273f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
4274f4a2713aSLionel Sambuc if (Entry.Kind == llvm::BitstreamEntry::EndBlock)
4275f4a2713aSLionel Sambuc return false;
4276f4a2713aSLionel Sambuc
4277f4a2713aSLionel Sambuc if (Entry.Kind != llvm::BitstreamEntry::Record)
4278f4a2713aSLionel Sambuc return true;
4279f4a2713aSLionel Sambuc
4280f4a2713aSLionel Sambuc Record.clear();
4281f4a2713aSLionel Sambuc StringRef Blob;
4282f4a2713aSLionel Sambuc unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
4283f4a2713aSLionel Sambuc switch ((ControlRecordTypes)RecCode) {
4284f4a2713aSLionel Sambuc case METADATA: {
4285f4a2713aSLionel Sambuc if (Record[0] != VERSION_MAJOR)
4286f4a2713aSLionel Sambuc return true;
4287f4a2713aSLionel Sambuc
4288f4a2713aSLionel Sambuc if (Listener.ReadFullVersionInformation(Blob))
4289f4a2713aSLionel Sambuc return true;
4290f4a2713aSLionel Sambuc
4291f4a2713aSLionel Sambuc break;
4292f4a2713aSLionel Sambuc }
4293*0a6a1f1dSLionel Sambuc case MODULE_NAME:
4294*0a6a1f1dSLionel Sambuc Listener.ReadModuleName(Blob);
4295*0a6a1f1dSLionel Sambuc break;
4296*0a6a1f1dSLionel Sambuc case MODULE_DIRECTORY:
4297*0a6a1f1dSLionel Sambuc ModuleDir = Blob;
4298*0a6a1f1dSLionel Sambuc break;
4299*0a6a1f1dSLionel Sambuc case MODULE_MAP_FILE: {
4300*0a6a1f1dSLionel Sambuc unsigned Idx = 0;
4301*0a6a1f1dSLionel Sambuc auto Path = ReadString(Record, Idx);
4302*0a6a1f1dSLionel Sambuc ResolveImportedPath(Path, ModuleDir);
4303*0a6a1f1dSLionel Sambuc Listener.ReadModuleMapFile(Path);
4304*0a6a1f1dSLionel Sambuc break;
4305*0a6a1f1dSLionel Sambuc }
4306f4a2713aSLionel Sambuc case LANGUAGE_OPTIONS:
4307*0a6a1f1dSLionel Sambuc if (ParseLanguageOptions(Record, false, Listener,
4308*0a6a1f1dSLionel Sambuc /*AllowCompatibleConfigurationMismatch*/false))
4309f4a2713aSLionel Sambuc return true;
4310f4a2713aSLionel Sambuc break;
4311f4a2713aSLionel Sambuc
4312f4a2713aSLionel Sambuc case TARGET_OPTIONS:
4313f4a2713aSLionel Sambuc if (ParseTargetOptions(Record, false, Listener))
4314f4a2713aSLionel Sambuc return true;
4315f4a2713aSLionel Sambuc break;
4316f4a2713aSLionel Sambuc
4317f4a2713aSLionel Sambuc case DIAGNOSTIC_OPTIONS:
4318f4a2713aSLionel Sambuc if (ParseDiagnosticOptions(Record, false, Listener))
4319f4a2713aSLionel Sambuc return true;
4320f4a2713aSLionel Sambuc break;
4321f4a2713aSLionel Sambuc
4322f4a2713aSLionel Sambuc case FILE_SYSTEM_OPTIONS:
4323f4a2713aSLionel Sambuc if (ParseFileSystemOptions(Record, false, Listener))
4324f4a2713aSLionel Sambuc return true;
4325f4a2713aSLionel Sambuc break;
4326f4a2713aSLionel Sambuc
4327f4a2713aSLionel Sambuc case HEADER_SEARCH_OPTIONS:
4328f4a2713aSLionel Sambuc if (ParseHeaderSearchOptions(Record, false, Listener))
4329f4a2713aSLionel Sambuc return true;
4330f4a2713aSLionel Sambuc break;
4331f4a2713aSLionel Sambuc
4332f4a2713aSLionel Sambuc case PREPROCESSOR_OPTIONS: {
4333f4a2713aSLionel Sambuc std::string IgnoredSuggestedPredefines;
4334f4a2713aSLionel Sambuc if (ParsePreprocessorOptions(Record, false, Listener,
4335f4a2713aSLionel Sambuc IgnoredSuggestedPredefines))
4336f4a2713aSLionel Sambuc return true;
4337f4a2713aSLionel Sambuc break;
4338f4a2713aSLionel Sambuc }
4339f4a2713aSLionel Sambuc
4340f4a2713aSLionel Sambuc case INPUT_FILE_OFFSETS: {
4341f4a2713aSLionel Sambuc if (!NeedsInputFiles)
4342f4a2713aSLionel Sambuc break;
4343f4a2713aSLionel Sambuc
4344f4a2713aSLionel Sambuc unsigned NumInputFiles = Record[0];
4345f4a2713aSLionel Sambuc unsigned NumUserFiles = Record[1];
4346f4a2713aSLionel Sambuc const uint32_t *InputFileOffs = (const uint32_t *)Blob.data();
4347f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumInputFiles; ++I) {
4348f4a2713aSLionel Sambuc // Go find this input file.
4349f4a2713aSLionel Sambuc bool isSystemFile = I >= NumUserFiles;
4350*0a6a1f1dSLionel Sambuc
4351*0a6a1f1dSLionel Sambuc if (isSystemFile && !NeedsSystemInputFiles)
4352*0a6a1f1dSLionel Sambuc break; // the rest are system input files
4353*0a6a1f1dSLionel Sambuc
4354f4a2713aSLionel Sambuc BitstreamCursor &Cursor = InputFilesCursor;
4355f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
4356f4a2713aSLionel Sambuc Cursor.JumpToBit(InputFileOffs[I]);
4357f4a2713aSLionel Sambuc
4358f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
4359f4a2713aSLionel Sambuc RecordData Record;
4360f4a2713aSLionel Sambuc StringRef Blob;
4361f4a2713aSLionel Sambuc bool shouldContinue = false;
4362f4a2713aSLionel Sambuc switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
4363f4a2713aSLionel Sambuc case INPUT_FILE:
4364*0a6a1f1dSLionel Sambuc bool Overridden = static_cast<bool>(Record[3]);
4365*0a6a1f1dSLionel Sambuc std::string Filename = Blob;
4366*0a6a1f1dSLionel Sambuc ResolveImportedPath(Filename, ModuleDir);
4367*0a6a1f1dSLionel Sambuc shouldContinue =
4368*0a6a1f1dSLionel Sambuc Listener.visitInputFile(Filename, isSystemFile, Overridden);
4369f4a2713aSLionel Sambuc break;
4370f4a2713aSLionel Sambuc }
4371f4a2713aSLionel Sambuc if (!shouldContinue)
4372f4a2713aSLionel Sambuc break;
4373f4a2713aSLionel Sambuc }
4374f4a2713aSLionel Sambuc break;
4375f4a2713aSLionel Sambuc }
4376f4a2713aSLionel Sambuc
4377*0a6a1f1dSLionel Sambuc case IMPORTS: {
4378*0a6a1f1dSLionel Sambuc if (!NeedsImports)
4379*0a6a1f1dSLionel Sambuc break;
4380*0a6a1f1dSLionel Sambuc
4381*0a6a1f1dSLionel Sambuc unsigned Idx = 0, N = Record.size();
4382*0a6a1f1dSLionel Sambuc while (Idx < N) {
4383*0a6a1f1dSLionel Sambuc // Read information about the AST file.
4384*0a6a1f1dSLionel Sambuc Idx += 5; // ImportLoc, Size, ModTime, Signature
4385*0a6a1f1dSLionel Sambuc std::string Filename = ReadString(Record, Idx);
4386*0a6a1f1dSLionel Sambuc ResolveImportedPath(Filename, ModuleDir);
4387*0a6a1f1dSLionel Sambuc Listener.visitImport(Filename);
4388*0a6a1f1dSLionel Sambuc }
4389*0a6a1f1dSLionel Sambuc break;
4390*0a6a1f1dSLionel Sambuc }
4391*0a6a1f1dSLionel Sambuc
4392f4a2713aSLionel Sambuc default:
4393f4a2713aSLionel Sambuc // No other validation to perform.
4394f4a2713aSLionel Sambuc break;
4395f4a2713aSLionel Sambuc }
4396f4a2713aSLionel Sambuc }
4397f4a2713aSLionel Sambuc }
4398f4a2713aSLionel Sambuc
4399f4a2713aSLionel Sambuc
isAcceptableASTFile(StringRef Filename,FileManager & FileMgr,const LangOptions & LangOpts,const TargetOptions & TargetOpts,const PreprocessorOptions & PPOpts)4400f4a2713aSLionel Sambuc bool ASTReader::isAcceptableASTFile(StringRef Filename,
4401f4a2713aSLionel Sambuc FileManager &FileMgr,
4402f4a2713aSLionel Sambuc const LangOptions &LangOpts,
4403f4a2713aSLionel Sambuc const TargetOptions &TargetOpts,
4404f4a2713aSLionel Sambuc const PreprocessorOptions &PPOpts) {
4405f4a2713aSLionel Sambuc SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, FileMgr);
4406f4a2713aSLionel Sambuc return !readASTFileControlBlock(Filename, FileMgr, validator);
4407f4a2713aSLionel Sambuc }
4408f4a2713aSLionel Sambuc
4409*0a6a1f1dSLionel Sambuc ASTReader::ASTReadResult
ReadSubmoduleBlock(ModuleFile & F,unsigned ClientLoadCapabilities)4410*0a6a1f1dSLionel Sambuc ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
4411f4a2713aSLionel Sambuc // Enter the submodule block.
4412f4a2713aSLionel Sambuc if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
4413f4a2713aSLionel Sambuc Error("malformed submodule block record in AST file");
4414*0a6a1f1dSLionel Sambuc return Failure;
4415f4a2713aSLionel Sambuc }
4416f4a2713aSLionel Sambuc
4417f4a2713aSLionel Sambuc ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
4418f4a2713aSLionel Sambuc bool First = true;
4419*0a6a1f1dSLionel Sambuc Module *CurrentModule = nullptr;
4420f4a2713aSLionel Sambuc RecordData Record;
4421f4a2713aSLionel Sambuc while (true) {
4422f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
4423f4a2713aSLionel Sambuc
4424f4a2713aSLionel Sambuc switch (Entry.Kind) {
4425f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock: // Handled for us already.
4426f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
4427f4a2713aSLionel Sambuc Error("malformed block record in AST file");
4428*0a6a1f1dSLionel Sambuc return Failure;
4429f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
4430*0a6a1f1dSLionel Sambuc return Success;
4431f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
4432f4a2713aSLionel Sambuc // The interesting case.
4433f4a2713aSLionel Sambuc break;
4434f4a2713aSLionel Sambuc }
4435f4a2713aSLionel Sambuc
4436f4a2713aSLionel Sambuc // Read a record.
4437f4a2713aSLionel Sambuc StringRef Blob;
4438f4a2713aSLionel Sambuc Record.clear();
4439*0a6a1f1dSLionel Sambuc auto Kind = F.Stream.readRecord(Entry.ID, Record, &Blob);
4440*0a6a1f1dSLionel Sambuc
4441*0a6a1f1dSLionel Sambuc if ((Kind == SUBMODULE_METADATA) != First) {
4442*0a6a1f1dSLionel Sambuc Error("submodule metadata record should be at beginning of block");
4443*0a6a1f1dSLionel Sambuc return Failure;
4444*0a6a1f1dSLionel Sambuc }
4445*0a6a1f1dSLionel Sambuc First = false;
4446*0a6a1f1dSLionel Sambuc
4447*0a6a1f1dSLionel Sambuc // Submodule information is only valid if we have a current module.
4448*0a6a1f1dSLionel Sambuc // FIXME: Should we error on these cases?
4449*0a6a1f1dSLionel Sambuc if (!CurrentModule && Kind != SUBMODULE_METADATA &&
4450*0a6a1f1dSLionel Sambuc Kind != SUBMODULE_DEFINITION)
4451*0a6a1f1dSLionel Sambuc continue;
4452*0a6a1f1dSLionel Sambuc
4453*0a6a1f1dSLionel Sambuc switch (Kind) {
4454f4a2713aSLionel Sambuc default: // Default behavior: ignore.
4455f4a2713aSLionel Sambuc break;
4456f4a2713aSLionel Sambuc
4457f4a2713aSLionel Sambuc case SUBMODULE_DEFINITION: {
4458f4a2713aSLionel Sambuc if (Record.size() < 8) {
4459f4a2713aSLionel Sambuc Error("malformed module definition");
4460*0a6a1f1dSLionel Sambuc return Failure;
4461f4a2713aSLionel Sambuc }
4462f4a2713aSLionel Sambuc
4463f4a2713aSLionel Sambuc StringRef Name = Blob;
4464*0a6a1f1dSLionel Sambuc unsigned Idx = 0;
4465*0a6a1f1dSLionel Sambuc SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]);
4466*0a6a1f1dSLionel Sambuc SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
4467*0a6a1f1dSLionel Sambuc bool IsFramework = Record[Idx++];
4468*0a6a1f1dSLionel Sambuc bool IsExplicit = Record[Idx++];
4469*0a6a1f1dSLionel Sambuc bool IsSystem = Record[Idx++];
4470*0a6a1f1dSLionel Sambuc bool IsExternC = Record[Idx++];
4471*0a6a1f1dSLionel Sambuc bool InferSubmodules = Record[Idx++];
4472*0a6a1f1dSLionel Sambuc bool InferExplicitSubmodules = Record[Idx++];
4473*0a6a1f1dSLionel Sambuc bool InferExportWildcard = Record[Idx++];
4474*0a6a1f1dSLionel Sambuc bool ConfigMacrosExhaustive = Record[Idx++];
4475f4a2713aSLionel Sambuc
4476*0a6a1f1dSLionel Sambuc Module *ParentModule = nullptr;
4477f4a2713aSLionel Sambuc if (Parent)
4478f4a2713aSLionel Sambuc ParentModule = getSubmodule(Parent);
4479f4a2713aSLionel Sambuc
4480f4a2713aSLionel Sambuc // Retrieve this (sub)module from the module map, creating it if
4481f4a2713aSLionel Sambuc // necessary.
4482*0a6a1f1dSLionel Sambuc CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, IsFramework,
4483f4a2713aSLionel Sambuc IsExplicit).first;
4484*0a6a1f1dSLionel Sambuc
4485*0a6a1f1dSLionel Sambuc // FIXME: set the definition loc for CurrentModule, or call
4486*0a6a1f1dSLionel Sambuc // ModMap.setInferredModuleAllowedBy()
4487*0a6a1f1dSLionel Sambuc
4488f4a2713aSLionel Sambuc SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
4489f4a2713aSLionel Sambuc if (GlobalIndex >= SubmodulesLoaded.size() ||
4490f4a2713aSLionel Sambuc SubmodulesLoaded[GlobalIndex]) {
4491f4a2713aSLionel Sambuc Error("too many submodules");
4492*0a6a1f1dSLionel Sambuc return Failure;
4493f4a2713aSLionel Sambuc }
4494f4a2713aSLionel Sambuc
4495f4a2713aSLionel Sambuc if (!ParentModule) {
4496f4a2713aSLionel Sambuc if (const FileEntry *CurFile = CurrentModule->getASTFile()) {
4497f4a2713aSLionel Sambuc if (CurFile != F.File) {
4498f4a2713aSLionel Sambuc if (!Diags.isDiagnosticInFlight()) {
4499f4a2713aSLionel Sambuc Diag(diag::err_module_file_conflict)
4500f4a2713aSLionel Sambuc << CurrentModule->getTopLevelModuleName()
4501f4a2713aSLionel Sambuc << CurFile->getName()
4502f4a2713aSLionel Sambuc << F.File->getName();
4503f4a2713aSLionel Sambuc }
4504*0a6a1f1dSLionel Sambuc return Failure;
4505f4a2713aSLionel Sambuc }
4506f4a2713aSLionel Sambuc }
4507f4a2713aSLionel Sambuc
4508f4a2713aSLionel Sambuc CurrentModule->setASTFile(F.File);
4509f4a2713aSLionel Sambuc }
4510f4a2713aSLionel Sambuc
4511f4a2713aSLionel Sambuc CurrentModule->IsFromModuleFile = true;
4512f4a2713aSLionel Sambuc CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
4513*0a6a1f1dSLionel Sambuc CurrentModule->IsExternC = IsExternC;
4514f4a2713aSLionel Sambuc CurrentModule->InferSubmodules = InferSubmodules;
4515f4a2713aSLionel Sambuc CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
4516f4a2713aSLionel Sambuc CurrentModule->InferExportWildcard = InferExportWildcard;
4517f4a2713aSLionel Sambuc CurrentModule->ConfigMacrosExhaustive = ConfigMacrosExhaustive;
4518f4a2713aSLionel Sambuc if (DeserializationListener)
4519f4a2713aSLionel Sambuc DeserializationListener->ModuleRead(GlobalID, CurrentModule);
4520f4a2713aSLionel Sambuc
4521f4a2713aSLionel Sambuc SubmodulesLoaded[GlobalIndex] = CurrentModule;
4522f4a2713aSLionel Sambuc
4523f4a2713aSLionel Sambuc // Clear out data that will be replaced by what is the module file.
4524f4a2713aSLionel Sambuc CurrentModule->LinkLibraries.clear();
4525f4a2713aSLionel Sambuc CurrentModule->ConfigMacros.clear();
4526f4a2713aSLionel Sambuc CurrentModule->UnresolvedConflicts.clear();
4527f4a2713aSLionel Sambuc CurrentModule->Conflicts.clear();
4528f4a2713aSLionel Sambuc break;
4529f4a2713aSLionel Sambuc }
4530f4a2713aSLionel Sambuc
4531f4a2713aSLionel Sambuc case SUBMODULE_UMBRELLA_HEADER: {
4532f4a2713aSLionel Sambuc if (const FileEntry *Umbrella = PP.getFileManager().getFile(Blob)) {
4533f4a2713aSLionel Sambuc if (!CurrentModule->getUmbrellaHeader())
4534f4a2713aSLionel Sambuc ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
4535f4a2713aSLionel Sambuc else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
4536*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
4537f4a2713aSLionel Sambuc Error("mismatched umbrella headers in submodule");
4538*0a6a1f1dSLionel Sambuc return OutOfDate;
4539f4a2713aSLionel Sambuc }
4540f4a2713aSLionel Sambuc }
4541f4a2713aSLionel Sambuc break;
4542f4a2713aSLionel Sambuc }
4543f4a2713aSLionel Sambuc
4544*0a6a1f1dSLionel Sambuc case SUBMODULE_HEADER:
4545*0a6a1f1dSLionel Sambuc case SUBMODULE_EXCLUDED_HEADER:
4546*0a6a1f1dSLionel Sambuc case SUBMODULE_PRIVATE_HEADER:
4547*0a6a1f1dSLionel Sambuc // We lazily associate headers with their modules via the HeaderInfo table.
4548f4a2713aSLionel Sambuc // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead
4549f4a2713aSLionel Sambuc // of complete filenames or remove it entirely.
4550f4a2713aSLionel Sambuc break;
4551f4a2713aSLionel Sambuc
4552*0a6a1f1dSLionel Sambuc case SUBMODULE_TEXTUAL_HEADER:
4553*0a6a1f1dSLionel Sambuc case SUBMODULE_PRIVATE_TEXTUAL_HEADER:
4554*0a6a1f1dSLionel Sambuc // FIXME: Textual headers are not marked in the HeaderInfo table. Load
4555*0a6a1f1dSLionel Sambuc // them here.
4556f4a2713aSLionel Sambuc break;
4557f4a2713aSLionel Sambuc
4558f4a2713aSLionel Sambuc case SUBMODULE_TOPHEADER: {
4559f4a2713aSLionel Sambuc CurrentModule->addTopHeaderFilename(Blob);
4560f4a2713aSLionel Sambuc break;
4561f4a2713aSLionel Sambuc }
4562f4a2713aSLionel Sambuc
4563f4a2713aSLionel Sambuc case SUBMODULE_UMBRELLA_DIR: {
4564f4a2713aSLionel Sambuc if (const DirectoryEntry *Umbrella
4565f4a2713aSLionel Sambuc = PP.getFileManager().getDirectory(Blob)) {
4566f4a2713aSLionel Sambuc if (!CurrentModule->getUmbrellaDir())
4567f4a2713aSLionel Sambuc ModMap.setUmbrellaDir(CurrentModule, Umbrella);
4568f4a2713aSLionel Sambuc else if (CurrentModule->getUmbrellaDir() != Umbrella) {
4569*0a6a1f1dSLionel Sambuc if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
4570f4a2713aSLionel Sambuc Error("mismatched umbrella directories in submodule");
4571*0a6a1f1dSLionel Sambuc return OutOfDate;
4572f4a2713aSLionel Sambuc }
4573f4a2713aSLionel Sambuc }
4574f4a2713aSLionel Sambuc break;
4575f4a2713aSLionel Sambuc }
4576f4a2713aSLionel Sambuc
4577f4a2713aSLionel Sambuc case SUBMODULE_METADATA: {
4578f4a2713aSLionel Sambuc F.BaseSubmoduleID = getTotalNumSubmodules();
4579f4a2713aSLionel Sambuc F.LocalNumSubmodules = Record[0];
4580f4a2713aSLionel Sambuc unsigned LocalBaseSubmoduleID = Record[1];
4581f4a2713aSLionel Sambuc if (F.LocalNumSubmodules > 0) {
4582f4a2713aSLionel Sambuc // Introduce the global -> local mapping for submodules within this
4583f4a2713aSLionel Sambuc // module.
4584f4a2713aSLionel Sambuc GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));
4585f4a2713aSLionel Sambuc
4586f4a2713aSLionel Sambuc // Introduce the local -> global mapping for submodules within this
4587f4a2713aSLionel Sambuc // module.
4588f4a2713aSLionel Sambuc F.SubmoduleRemap.insertOrReplace(
4589f4a2713aSLionel Sambuc std::make_pair(LocalBaseSubmoduleID,
4590f4a2713aSLionel Sambuc F.BaseSubmoduleID - LocalBaseSubmoduleID));
4591f4a2713aSLionel Sambuc
4592f4a2713aSLionel Sambuc SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
4593f4a2713aSLionel Sambuc }
4594f4a2713aSLionel Sambuc break;
4595f4a2713aSLionel Sambuc }
4596f4a2713aSLionel Sambuc
4597f4a2713aSLionel Sambuc case SUBMODULE_IMPORTS: {
4598f4a2713aSLionel Sambuc for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
4599f4a2713aSLionel Sambuc UnresolvedModuleRef Unresolved;
4600f4a2713aSLionel Sambuc Unresolved.File = &F;
4601f4a2713aSLionel Sambuc Unresolved.Mod = CurrentModule;
4602f4a2713aSLionel Sambuc Unresolved.ID = Record[Idx];
4603f4a2713aSLionel Sambuc Unresolved.Kind = UnresolvedModuleRef::Import;
4604f4a2713aSLionel Sambuc Unresolved.IsWildcard = false;
4605f4a2713aSLionel Sambuc UnresolvedModuleRefs.push_back(Unresolved);
4606f4a2713aSLionel Sambuc }
4607f4a2713aSLionel Sambuc break;
4608f4a2713aSLionel Sambuc }
4609f4a2713aSLionel Sambuc
4610f4a2713aSLionel Sambuc case SUBMODULE_EXPORTS: {
4611f4a2713aSLionel Sambuc for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
4612f4a2713aSLionel Sambuc UnresolvedModuleRef Unresolved;
4613f4a2713aSLionel Sambuc Unresolved.File = &F;
4614f4a2713aSLionel Sambuc Unresolved.Mod = CurrentModule;
4615f4a2713aSLionel Sambuc Unresolved.ID = Record[Idx];
4616f4a2713aSLionel Sambuc Unresolved.Kind = UnresolvedModuleRef::Export;
4617f4a2713aSLionel Sambuc Unresolved.IsWildcard = Record[Idx + 1];
4618f4a2713aSLionel Sambuc UnresolvedModuleRefs.push_back(Unresolved);
4619f4a2713aSLionel Sambuc }
4620f4a2713aSLionel Sambuc
4621f4a2713aSLionel Sambuc // Once we've loaded the set of exports, there's no reason to keep
4622f4a2713aSLionel Sambuc // the parsed, unresolved exports around.
4623f4a2713aSLionel Sambuc CurrentModule->UnresolvedExports.clear();
4624f4a2713aSLionel Sambuc break;
4625f4a2713aSLionel Sambuc }
4626f4a2713aSLionel Sambuc case SUBMODULE_REQUIRES: {
4627f4a2713aSLionel Sambuc CurrentModule->addRequirement(Blob, Record[0], Context.getLangOpts(),
4628f4a2713aSLionel Sambuc Context.getTargetInfo());
4629f4a2713aSLionel Sambuc break;
4630f4a2713aSLionel Sambuc }
4631f4a2713aSLionel Sambuc
4632f4a2713aSLionel Sambuc case SUBMODULE_LINK_LIBRARY:
4633f4a2713aSLionel Sambuc CurrentModule->LinkLibraries.push_back(
4634f4a2713aSLionel Sambuc Module::LinkLibrary(Blob, Record[0]));
4635f4a2713aSLionel Sambuc break;
4636f4a2713aSLionel Sambuc
4637f4a2713aSLionel Sambuc case SUBMODULE_CONFIG_MACRO:
4638f4a2713aSLionel Sambuc CurrentModule->ConfigMacros.push_back(Blob.str());
4639f4a2713aSLionel Sambuc break;
4640f4a2713aSLionel Sambuc
4641f4a2713aSLionel Sambuc case SUBMODULE_CONFLICT: {
4642f4a2713aSLionel Sambuc UnresolvedModuleRef Unresolved;
4643f4a2713aSLionel Sambuc Unresolved.File = &F;
4644f4a2713aSLionel Sambuc Unresolved.Mod = CurrentModule;
4645f4a2713aSLionel Sambuc Unresolved.ID = Record[0];
4646f4a2713aSLionel Sambuc Unresolved.Kind = UnresolvedModuleRef::Conflict;
4647f4a2713aSLionel Sambuc Unresolved.IsWildcard = false;
4648f4a2713aSLionel Sambuc Unresolved.String = Blob;
4649f4a2713aSLionel Sambuc UnresolvedModuleRefs.push_back(Unresolved);
4650f4a2713aSLionel Sambuc break;
4651f4a2713aSLionel Sambuc }
4652f4a2713aSLionel Sambuc }
4653f4a2713aSLionel Sambuc }
4654f4a2713aSLionel Sambuc }
4655f4a2713aSLionel Sambuc
4656f4a2713aSLionel Sambuc /// \brief Parse the record that corresponds to a LangOptions data
4657f4a2713aSLionel Sambuc /// structure.
4658f4a2713aSLionel Sambuc ///
4659f4a2713aSLionel Sambuc /// This routine parses the language options from the AST file and then gives
4660f4a2713aSLionel Sambuc /// them to the AST listener if one is set.
4661f4a2713aSLionel Sambuc ///
4662f4a2713aSLionel Sambuc /// \returns true if the listener deems the file unacceptable, false otherwise.
ParseLanguageOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener,bool AllowCompatibleDifferences)4663f4a2713aSLionel Sambuc bool ASTReader::ParseLanguageOptions(const RecordData &Record,
4664f4a2713aSLionel Sambuc bool Complain,
4665*0a6a1f1dSLionel Sambuc ASTReaderListener &Listener,
4666*0a6a1f1dSLionel Sambuc bool AllowCompatibleDifferences) {
4667f4a2713aSLionel Sambuc LangOptions LangOpts;
4668f4a2713aSLionel Sambuc unsigned Idx = 0;
4669f4a2713aSLionel Sambuc #define LANGOPT(Name, Bits, Default, Description) \
4670f4a2713aSLionel Sambuc LangOpts.Name = Record[Idx++];
4671f4a2713aSLionel Sambuc #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
4672f4a2713aSLionel Sambuc LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
4673f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.def"
4674*0a6a1f1dSLionel Sambuc #define SANITIZER(NAME, ID) \
4675*0a6a1f1dSLionel Sambuc LangOpts.Sanitize.set(SanitizerKind::ID, Record[Idx++]);
4676f4a2713aSLionel Sambuc #include "clang/Basic/Sanitizers.def"
4677f4a2713aSLionel Sambuc
4678f4a2713aSLionel Sambuc ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];
4679f4a2713aSLionel Sambuc VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);
4680f4a2713aSLionel Sambuc LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);
4681f4a2713aSLionel Sambuc
4682f4a2713aSLionel Sambuc unsigned Length = Record[Idx++];
4683f4a2713aSLionel Sambuc LangOpts.CurrentModule.assign(Record.begin() + Idx,
4684f4a2713aSLionel Sambuc Record.begin() + Idx + Length);
4685f4a2713aSLionel Sambuc
4686f4a2713aSLionel Sambuc Idx += Length;
4687f4a2713aSLionel Sambuc
4688f4a2713aSLionel Sambuc // Comment options.
4689f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4690f4a2713aSLionel Sambuc LangOpts.CommentOpts.BlockCommandNames.push_back(
4691f4a2713aSLionel Sambuc ReadString(Record, Idx));
4692f4a2713aSLionel Sambuc }
4693f4a2713aSLionel Sambuc LangOpts.CommentOpts.ParseAllComments = Record[Idx++];
4694f4a2713aSLionel Sambuc
4695*0a6a1f1dSLionel Sambuc return Listener.ReadLanguageOptions(LangOpts, Complain,
4696*0a6a1f1dSLionel Sambuc AllowCompatibleDifferences);
4697f4a2713aSLionel Sambuc }
4698f4a2713aSLionel Sambuc
ParseTargetOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener)4699f4a2713aSLionel Sambuc bool ASTReader::ParseTargetOptions(const RecordData &Record,
4700f4a2713aSLionel Sambuc bool Complain,
4701f4a2713aSLionel Sambuc ASTReaderListener &Listener) {
4702f4a2713aSLionel Sambuc unsigned Idx = 0;
4703f4a2713aSLionel Sambuc TargetOptions TargetOpts;
4704f4a2713aSLionel Sambuc TargetOpts.Triple = ReadString(Record, Idx);
4705f4a2713aSLionel Sambuc TargetOpts.CPU = ReadString(Record, Idx);
4706f4a2713aSLionel Sambuc TargetOpts.ABI = ReadString(Record, Idx);
4707f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4708f4a2713aSLionel Sambuc TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
4709f4a2713aSLionel Sambuc }
4710f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4711f4a2713aSLionel Sambuc TargetOpts.Features.push_back(ReadString(Record, Idx));
4712f4a2713aSLionel Sambuc }
4713f4a2713aSLionel Sambuc
4714f4a2713aSLionel Sambuc return Listener.ReadTargetOptions(TargetOpts, Complain);
4715f4a2713aSLionel Sambuc }
4716f4a2713aSLionel Sambuc
ParseDiagnosticOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener)4717f4a2713aSLionel Sambuc bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
4718f4a2713aSLionel Sambuc ASTReaderListener &Listener) {
4719*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
4720f4a2713aSLionel Sambuc unsigned Idx = 0;
4721*0a6a1f1dSLionel Sambuc #define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
4722f4a2713aSLionel Sambuc #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
4723*0a6a1f1dSLionel Sambuc DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
4724f4a2713aSLionel Sambuc #include "clang/Basic/DiagnosticOptions.def"
4725f4a2713aSLionel Sambuc
4726*0a6a1f1dSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N)
4727*0a6a1f1dSLionel Sambuc DiagOpts->Warnings.push_back(ReadString(Record, Idx));
4728*0a6a1f1dSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N)
4729*0a6a1f1dSLionel Sambuc DiagOpts->Remarks.push_back(ReadString(Record, Idx));
4730f4a2713aSLionel Sambuc
4731f4a2713aSLionel Sambuc return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
4732f4a2713aSLionel Sambuc }
4733f4a2713aSLionel Sambuc
ParseFileSystemOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener)4734f4a2713aSLionel Sambuc bool ASTReader::ParseFileSystemOptions(const RecordData &Record, bool Complain,
4735f4a2713aSLionel Sambuc ASTReaderListener &Listener) {
4736f4a2713aSLionel Sambuc FileSystemOptions FSOpts;
4737f4a2713aSLionel Sambuc unsigned Idx = 0;
4738f4a2713aSLionel Sambuc FSOpts.WorkingDir = ReadString(Record, Idx);
4739f4a2713aSLionel Sambuc return Listener.ReadFileSystemOptions(FSOpts, Complain);
4740f4a2713aSLionel Sambuc }
4741f4a2713aSLionel Sambuc
ParseHeaderSearchOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener)4742f4a2713aSLionel Sambuc bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
4743f4a2713aSLionel Sambuc bool Complain,
4744f4a2713aSLionel Sambuc ASTReaderListener &Listener) {
4745f4a2713aSLionel Sambuc HeaderSearchOptions HSOpts;
4746f4a2713aSLionel Sambuc unsigned Idx = 0;
4747f4a2713aSLionel Sambuc HSOpts.Sysroot = ReadString(Record, Idx);
4748f4a2713aSLionel Sambuc
4749f4a2713aSLionel Sambuc // Include entries.
4750f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4751f4a2713aSLionel Sambuc std::string Path = ReadString(Record, Idx);
4752f4a2713aSLionel Sambuc frontend::IncludeDirGroup Group
4753f4a2713aSLionel Sambuc = static_cast<frontend::IncludeDirGroup>(Record[Idx++]);
4754f4a2713aSLionel Sambuc bool IsFramework = Record[Idx++];
4755f4a2713aSLionel Sambuc bool IgnoreSysRoot = Record[Idx++];
4756f4a2713aSLionel Sambuc HSOpts.UserEntries.push_back(
4757f4a2713aSLionel Sambuc HeaderSearchOptions::Entry(Path, Group, IsFramework, IgnoreSysRoot));
4758f4a2713aSLionel Sambuc }
4759f4a2713aSLionel Sambuc
4760f4a2713aSLionel Sambuc // System header prefixes.
4761f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4762f4a2713aSLionel Sambuc std::string Prefix = ReadString(Record, Idx);
4763f4a2713aSLionel Sambuc bool IsSystemHeader = Record[Idx++];
4764f4a2713aSLionel Sambuc HSOpts.SystemHeaderPrefixes.push_back(
4765f4a2713aSLionel Sambuc HeaderSearchOptions::SystemHeaderPrefix(Prefix, IsSystemHeader));
4766f4a2713aSLionel Sambuc }
4767f4a2713aSLionel Sambuc
4768f4a2713aSLionel Sambuc HSOpts.ResourceDir = ReadString(Record, Idx);
4769f4a2713aSLionel Sambuc HSOpts.ModuleCachePath = ReadString(Record, Idx);
4770*0a6a1f1dSLionel Sambuc HSOpts.ModuleUserBuildPath = ReadString(Record, Idx);
4771f4a2713aSLionel Sambuc HSOpts.DisableModuleHash = Record[Idx++];
4772f4a2713aSLionel Sambuc HSOpts.UseBuiltinIncludes = Record[Idx++];
4773f4a2713aSLionel Sambuc HSOpts.UseStandardSystemIncludes = Record[Idx++];
4774f4a2713aSLionel Sambuc HSOpts.UseStandardCXXIncludes = Record[Idx++];
4775f4a2713aSLionel Sambuc HSOpts.UseLibcxx = Record[Idx++];
4776f4a2713aSLionel Sambuc
4777f4a2713aSLionel Sambuc return Listener.ReadHeaderSearchOptions(HSOpts, Complain);
4778f4a2713aSLionel Sambuc }
4779f4a2713aSLionel Sambuc
ParsePreprocessorOptions(const RecordData & Record,bool Complain,ASTReaderListener & Listener,std::string & SuggestedPredefines)4780f4a2713aSLionel Sambuc bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
4781f4a2713aSLionel Sambuc bool Complain,
4782f4a2713aSLionel Sambuc ASTReaderListener &Listener,
4783f4a2713aSLionel Sambuc std::string &SuggestedPredefines) {
4784f4a2713aSLionel Sambuc PreprocessorOptions PPOpts;
4785f4a2713aSLionel Sambuc unsigned Idx = 0;
4786f4a2713aSLionel Sambuc
4787f4a2713aSLionel Sambuc // Macro definitions/undefs
4788f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4789f4a2713aSLionel Sambuc std::string Macro = ReadString(Record, Idx);
4790f4a2713aSLionel Sambuc bool IsUndef = Record[Idx++];
4791f4a2713aSLionel Sambuc PPOpts.Macros.push_back(std::make_pair(Macro, IsUndef));
4792f4a2713aSLionel Sambuc }
4793f4a2713aSLionel Sambuc
4794f4a2713aSLionel Sambuc // Includes
4795f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4796f4a2713aSLionel Sambuc PPOpts.Includes.push_back(ReadString(Record, Idx));
4797f4a2713aSLionel Sambuc }
4798f4a2713aSLionel Sambuc
4799f4a2713aSLionel Sambuc // Macro Includes
4800f4a2713aSLionel Sambuc for (unsigned N = Record[Idx++]; N; --N) {
4801f4a2713aSLionel Sambuc PPOpts.MacroIncludes.push_back(ReadString(Record, Idx));
4802f4a2713aSLionel Sambuc }
4803f4a2713aSLionel Sambuc
4804f4a2713aSLionel Sambuc PPOpts.UsePredefines = Record[Idx++];
4805f4a2713aSLionel Sambuc PPOpts.DetailedRecord = Record[Idx++];
4806f4a2713aSLionel Sambuc PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
4807f4a2713aSLionel Sambuc PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);
4808f4a2713aSLionel Sambuc PPOpts.ObjCXXARCStandardLibrary =
4809f4a2713aSLionel Sambuc static_cast<ObjCXXARCStandardLibraryKind>(Record[Idx++]);
4810f4a2713aSLionel Sambuc SuggestedPredefines.clear();
4811f4a2713aSLionel Sambuc return Listener.ReadPreprocessorOptions(PPOpts, Complain,
4812f4a2713aSLionel Sambuc SuggestedPredefines);
4813f4a2713aSLionel Sambuc }
4814f4a2713aSLionel Sambuc
4815f4a2713aSLionel Sambuc std::pair<ModuleFile *, unsigned>
getModulePreprocessedEntity(unsigned GlobalIndex)4816f4a2713aSLionel Sambuc ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
4817f4a2713aSLionel Sambuc GlobalPreprocessedEntityMapType::iterator
4818f4a2713aSLionel Sambuc I = GlobalPreprocessedEntityMap.find(GlobalIndex);
4819f4a2713aSLionel Sambuc assert(I != GlobalPreprocessedEntityMap.end() &&
4820f4a2713aSLionel Sambuc "Corrupted global preprocessed entity map");
4821f4a2713aSLionel Sambuc ModuleFile *M = I->second;
4822f4a2713aSLionel Sambuc unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID;
4823f4a2713aSLionel Sambuc return std::make_pair(M, LocalIndex);
4824f4a2713aSLionel Sambuc }
4825f4a2713aSLionel Sambuc
4826f4a2713aSLionel Sambuc std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
getModulePreprocessedEntities(ModuleFile & Mod) const4827f4a2713aSLionel Sambuc ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
4828f4a2713aSLionel Sambuc if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord())
4829f4a2713aSLionel Sambuc return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID,
4830f4a2713aSLionel Sambuc Mod.NumPreprocessedEntities);
4831f4a2713aSLionel Sambuc
4832f4a2713aSLionel Sambuc return std::make_pair(PreprocessingRecord::iterator(),
4833f4a2713aSLionel Sambuc PreprocessingRecord::iterator());
4834f4a2713aSLionel Sambuc }
4835f4a2713aSLionel Sambuc
4836f4a2713aSLionel Sambuc std::pair<ASTReader::ModuleDeclIterator, ASTReader::ModuleDeclIterator>
getModuleFileLevelDecls(ModuleFile & Mod)4837f4a2713aSLionel Sambuc ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) {
4838f4a2713aSLionel Sambuc return std::make_pair(ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls),
4839f4a2713aSLionel Sambuc ModuleDeclIterator(this, &Mod,
4840f4a2713aSLionel Sambuc Mod.FileSortedDecls + Mod.NumFileSortedDecls));
4841f4a2713aSLionel Sambuc }
4842f4a2713aSLionel Sambuc
ReadPreprocessedEntity(unsigned Index)4843f4a2713aSLionel Sambuc PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
4844f4a2713aSLionel Sambuc PreprocessedEntityID PPID = Index+1;
4845f4a2713aSLionel Sambuc std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
4846f4a2713aSLionel Sambuc ModuleFile &M = *PPInfo.first;
4847f4a2713aSLionel Sambuc unsigned LocalIndex = PPInfo.second;
4848f4a2713aSLionel Sambuc const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
4849f4a2713aSLionel Sambuc
4850f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord()) {
4851f4a2713aSLionel Sambuc Error("no preprocessing record");
4852*0a6a1f1dSLionel Sambuc return nullptr;
4853f4a2713aSLionel Sambuc }
4854f4a2713aSLionel Sambuc
4855f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
4856f4a2713aSLionel Sambuc M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
4857f4a2713aSLionel Sambuc
4858f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry =
4859f4a2713aSLionel Sambuc M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
4860f4a2713aSLionel Sambuc if (Entry.Kind != llvm::BitstreamEntry::Record)
4861*0a6a1f1dSLionel Sambuc return nullptr;
4862f4a2713aSLionel Sambuc
4863f4a2713aSLionel Sambuc // Read the record.
4864f4a2713aSLionel Sambuc SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),
4865f4a2713aSLionel Sambuc ReadSourceLocation(M, PPOffs.End));
4866f4a2713aSLionel Sambuc PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
4867f4a2713aSLionel Sambuc StringRef Blob;
4868f4a2713aSLionel Sambuc RecordData Record;
4869f4a2713aSLionel Sambuc PreprocessorDetailRecordTypes RecType =
4870f4a2713aSLionel Sambuc (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.readRecord(
4871f4a2713aSLionel Sambuc Entry.ID, Record, &Blob);
4872f4a2713aSLionel Sambuc switch (RecType) {
4873f4a2713aSLionel Sambuc case PPD_MACRO_EXPANSION: {
4874f4a2713aSLionel Sambuc bool isBuiltin = Record[0];
4875*0a6a1f1dSLionel Sambuc IdentifierInfo *Name = nullptr;
4876*0a6a1f1dSLionel Sambuc MacroDefinition *Def = nullptr;
4877f4a2713aSLionel Sambuc if (isBuiltin)
4878f4a2713aSLionel Sambuc Name = getLocalIdentifier(M, Record[1]);
4879f4a2713aSLionel Sambuc else {
4880f4a2713aSLionel Sambuc PreprocessedEntityID
4881f4a2713aSLionel Sambuc GlobalID = getGlobalPreprocessedEntityID(M, Record[1]);
4882f4a2713aSLionel Sambuc Def =cast<MacroDefinition>(PPRec.getLoadedPreprocessedEntity(GlobalID-1));
4883f4a2713aSLionel Sambuc }
4884f4a2713aSLionel Sambuc
4885f4a2713aSLionel Sambuc MacroExpansion *ME;
4886f4a2713aSLionel Sambuc if (isBuiltin)
4887f4a2713aSLionel Sambuc ME = new (PPRec) MacroExpansion(Name, Range);
4888f4a2713aSLionel Sambuc else
4889f4a2713aSLionel Sambuc ME = new (PPRec) MacroExpansion(Def, Range);
4890f4a2713aSLionel Sambuc
4891f4a2713aSLionel Sambuc return ME;
4892f4a2713aSLionel Sambuc }
4893f4a2713aSLionel Sambuc
4894f4a2713aSLionel Sambuc case PPD_MACRO_DEFINITION: {
4895f4a2713aSLionel Sambuc // Decode the identifier info and then check again; if the macro is
4896f4a2713aSLionel Sambuc // still defined and associated with the identifier,
4897f4a2713aSLionel Sambuc IdentifierInfo *II = getLocalIdentifier(M, Record[0]);
4898f4a2713aSLionel Sambuc MacroDefinition *MD
4899f4a2713aSLionel Sambuc = new (PPRec) MacroDefinition(II, Range);
4900f4a2713aSLionel Sambuc
4901f4a2713aSLionel Sambuc if (DeserializationListener)
4902f4a2713aSLionel Sambuc DeserializationListener->MacroDefinitionRead(PPID, MD);
4903f4a2713aSLionel Sambuc
4904f4a2713aSLionel Sambuc return MD;
4905f4a2713aSLionel Sambuc }
4906f4a2713aSLionel Sambuc
4907f4a2713aSLionel Sambuc case PPD_INCLUSION_DIRECTIVE: {
4908f4a2713aSLionel Sambuc const char *FullFileNameStart = Blob.data() + Record[0];
4909f4a2713aSLionel Sambuc StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
4910*0a6a1f1dSLionel Sambuc const FileEntry *File = nullptr;
4911f4a2713aSLionel Sambuc if (!FullFileName.empty())
4912f4a2713aSLionel Sambuc File = PP.getFileManager().getFile(FullFileName);
4913f4a2713aSLionel Sambuc
4914f4a2713aSLionel Sambuc // FIXME: Stable encoding
4915f4a2713aSLionel Sambuc InclusionDirective::InclusionKind Kind
4916f4a2713aSLionel Sambuc = static_cast<InclusionDirective::InclusionKind>(Record[2]);
4917f4a2713aSLionel Sambuc InclusionDirective *ID
4918f4a2713aSLionel Sambuc = new (PPRec) InclusionDirective(PPRec, Kind,
4919f4a2713aSLionel Sambuc StringRef(Blob.data(), Record[0]),
4920f4a2713aSLionel Sambuc Record[1], Record[3],
4921f4a2713aSLionel Sambuc File,
4922f4a2713aSLionel Sambuc Range);
4923f4a2713aSLionel Sambuc return ID;
4924f4a2713aSLionel Sambuc }
4925f4a2713aSLionel Sambuc }
4926f4a2713aSLionel Sambuc
4927f4a2713aSLionel Sambuc llvm_unreachable("Invalid PreprocessorDetailRecordTypes");
4928f4a2713aSLionel Sambuc }
4929f4a2713aSLionel Sambuc
4930f4a2713aSLionel Sambuc /// \brief \arg SLocMapI points at a chunk of a module that contains no
4931f4a2713aSLionel Sambuc /// preprocessed entities or the entities it contains are not the ones we are
4932f4a2713aSLionel Sambuc /// looking for. Find the next module that contains entities and return the ID
4933f4a2713aSLionel Sambuc /// of the first entry.
findNextPreprocessedEntity(GlobalSLocOffsetMapType::const_iterator SLocMapI) const4934f4a2713aSLionel Sambuc PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
4935f4a2713aSLionel Sambuc GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
4936f4a2713aSLionel Sambuc ++SLocMapI;
4937f4a2713aSLionel Sambuc for (GlobalSLocOffsetMapType::const_iterator
4938f4a2713aSLionel Sambuc EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
4939f4a2713aSLionel Sambuc ModuleFile &M = *SLocMapI->second;
4940f4a2713aSLionel Sambuc if (M.NumPreprocessedEntities)
4941f4a2713aSLionel Sambuc return M.BasePreprocessedEntityID;
4942f4a2713aSLionel Sambuc }
4943f4a2713aSLionel Sambuc
4944f4a2713aSLionel Sambuc return getTotalNumPreprocessedEntities();
4945f4a2713aSLionel Sambuc }
4946f4a2713aSLionel Sambuc
4947f4a2713aSLionel Sambuc namespace {
4948f4a2713aSLionel Sambuc
4949f4a2713aSLionel Sambuc template <unsigned PPEntityOffset::*PPLoc>
4950f4a2713aSLionel Sambuc struct PPEntityComp {
4951f4a2713aSLionel Sambuc const ASTReader &Reader;
4952f4a2713aSLionel Sambuc ModuleFile &M;
4953f4a2713aSLionel Sambuc
PPEntityComp__anon18a49ed50711::PPEntityComp4954f4a2713aSLionel Sambuc PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) { }
4955f4a2713aSLionel Sambuc
operator ()__anon18a49ed50711::PPEntityComp4956f4a2713aSLionel Sambuc bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {
4957f4a2713aSLionel Sambuc SourceLocation LHS = getLoc(L);
4958f4a2713aSLionel Sambuc SourceLocation RHS = getLoc(R);
4959f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
4960f4a2713aSLionel Sambuc }
4961f4a2713aSLionel Sambuc
operator ()__anon18a49ed50711::PPEntityComp4962f4a2713aSLionel Sambuc bool operator()(const PPEntityOffset &L, SourceLocation RHS) const {
4963f4a2713aSLionel Sambuc SourceLocation LHS = getLoc(L);
4964f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
4965f4a2713aSLionel Sambuc }
4966f4a2713aSLionel Sambuc
operator ()__anon18a49ed50711::PPEntityComp4967f4a2713aSLionel Sambuc bool operator()(SourceLocation LHS, const PPEntityOffset &R) const {
4968f4a2713aSLionel Sambuc SourceLocation RHS = getLoc(R);
4969f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
4970f4a2713aSLionel Sambuc }
4971f4a2713aSLionel Sambuc
getLoc__anon18a49ed50711::PPEntityComp4972f4a2713aSLionel Sambuc SourceLocation getLoc(const PPEntityOffset &PPE) const {
4973f4a2713aSLionel Sambuc return Reader.ReadSourceLocation(M, PPE.*PPLoc);
4974f4a2713aSLionel Sambuc }
4975f4a2713aSLionel Sambuc };
4976f4a2713aSLionel Sambuc
4977f4a2713aSLionel Sambuc }
4978f4a2713aSLionel Sambuc
findPreprocessedEntity(SourceLocation Loc,bool EndsAfter) const4979*0a6a1f1dSLionel Sambuc PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
4980*0a6a1f1dSLionel Sambuc bool EndsAfter) const {
4981*0a6a1f1dSLionel Sambuc if (SourceMgr.isLocalSourceLocation(Loc))
4982f4a2713aSLionel Sambuc return getTotalNumPreprocessedEntities();
4983f4a2713aSLionel Sambuc
4984*0a6a1f1dSLionel Sambuc GlobalSLocOffsetMapType::const_iterator SLocMapI = GlobalSLocOffsetMap.find(
4985*0a6a1f1dSLionel Sambuc SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
4986f4a2713aSLionel Sambuc assert(SLocMapI != GlobalSLocOffsetMap.end() &&
4987f4a2713aSLionel Sambuc "Corrupted global sloc offset map");
4988f4a2713aSLionel Sambuc
4989f4a2713aSLionel Sambuc if (SLocMapI->second->NumPreprocessedEntities == 0)
4990f4a2713aSLionel Sambuc return findNextPreprocessedEntity(SLocMapI);
4991f4a2713aSLionel Sambuc
4992f4a2713aSLionel Sambuc ModuleFile &M = *SLocMapI->second;
4993f4a2713aSLionel Sambuc typedef const PPEntityOffset *pp_iterator;
4994f4a2713aSLionel Sambuc pp_iterator pp_begin = M.PreprocessedEntityOffsets;
4995f4a2713aSLionel Sambuc pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
4996f4a2713aSLionel Sambuc
4997f4a2713aSLionel Sambuc size_t Count = M.NumPreprocessedEntities;
4998f4a2713aSLionel Sambuc size_t Half;
4999f4a2713aSLionel Sambuc pp_iterator First = pp_begin;
5000f4a2713aSLionel Sambuc pp_iterator PPI;
5001f4a2713aSLionel Sambuc
5002*0a6a1f1dSLionel Sambuc if (EndsAfter) {
5003*0a6a1f1dSLionel Sambuc PPI = std::upper_bound(pp_begin, pp_end, Loc,
5004*0a6a1f1dSLionel Sambuc PPEntityComp<&PPEntityOffset::Begin>(*this, M));
5005*0a6a1f1dSLionel Sambuc } else {
5006f4a2713aSLionel Sambuc // Do a binary search manually instead of using std::lower_bound because
5007f4a2713aSLionel Sambuc // The end locations of entities may be unordered (when a macro expansion
5008f4a2713aSLionel Sambuc // is inside another macro argument), but for this case it is not important
5009f4a2713aSLionel Sambuc // whether we get the first macro expansion or its containing macro.
5010f4a2713aSLionel Sambuc while (Count > 0) {
5011f4a2713aSLionel Sambuc Half = Count / 2;
5012f4a2713aSLionel Sambuc PPI = First;
5013f4a2713aSLionel Sambuc std::advance(PPI, Half);
5014f4a2713aSLionel Sambuc if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
5015*0a6a1f1dSLionel Sambuc Loc)) {
5016f4a2713aSLionel Sambuc First = PPI;
5017f4a2713aSLionel Sambuc ++First;
5018f4a2713aSLionel Sambuc Count = Count - Half - 1;
5019f4a2713aSLionel Sambuc } else
5020f4a2713aSLionel Sambuc Count = Half;
5021f4a2713aSLionel Sambuc }
5022f4a2713aSLionel Sambuc }
5023f4a2713aSLionel Sambuc
5024f4a2713aSLionel Sambuc if (PPI == pp_end)
5025f4a2713aSLionel Sambuc return findNextPreprocessedEntity(SLocMapI);
5026f4a2713aSLionel Sambuc
5027f4a2713aSLionel Sambuc return M.BasePreprocessedEntityID + (PPI - pp_begin);
5028f4a2713aSLionel Sambuc }
5029f4a2713aSLionel Sambuc
5030f4a2713aSLionel Sambuc /// \brief Returns a pair of [Begin, End) indices of preallocated
5031f4a2713aSLionel Sambuc /// preprocessed entities that \arg Range encompasses.
5032f4a2713aSLionel Sambuc std::pair<unsigned, unsigned>
findPreprocessedEntitiesInRange(SourceRange Range)5033f4a2713aSLionel Sambuc ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {
5034f4a2713aSLionel Sambuc if (Range.isInvalid())
5035f4a2713aSLionel Sambuc return std::make_pair(0,0);
5036f4a2713aSLionel Sambuc assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
5037f4a2713aSLionel Sambuc
5038*0a6a1f1dSLionel Sambuc PreprocessedEntityID BeginID =
5039*0a6a1f1dSLionel Sambuc findPreprocessedEntity(Range.getBegin(), false);
5040*0a6a1f1dSLionel Sambuc PreprocessedEntityID EndID = findPreprocessedEntity(Range.getEnd(), true);
5041f4a2713aSLionel Sambuc return std::make_pair(BeginID, EndID);
5042f4a2713aSLionel Sambuc }
5043f4a2713aSLionel Sambuc
5044f4a2713aSLionel Sambuc /// \brief Optionally returns true or false if the preallocated preprocessed
5045f4a2713aSLionel Sambuc /// entity with index \arg Index came from file \arg FID.
isPreprocessedEntityInFileID(unsigned Index,FileID FID)5046f4a2713aSLionel Sambuc Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
5047f4a2713aSLionel Sambuc FileID FID) {
5048f4a2713aSLionel Sambuc if (FID.isInvalid())
5049f4a2713aSLionel Sambuc return false;
5050f4a2713aSLionel Sambuc
5051f4a2713aSLionel Sambuc std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
5052f4a2713aSLionel Sambuc ModuleFile &M = *PPInfo.first;
5053f4a2713aSLionel Sambuc unsigned LocalIndex = PPInfo.second;
5054f4a2713aSLionel Sambuc const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
5055f4a2713aSLionel Sambuc
5056f4a2713aSLionel Sambuc SourceLocation Loc = ReadSourceLocation(M, PPOffs.Begin);
5057f4a2713aSLionel Sambuc if (Loc.isInvalid())
5058f4a2713aSLionel Sambuc return false;
5059f4a2713aSLionel Sambuc
5060f4a2713aSLionel Sambuc if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID))
5061f4a2713aSLionel Sambuc return true;
5062f4a2713aSLionel Sambuc else
5063f4a2713aSLionel Sambuc return false;
5064f4a2713aSLionel Sambuc }
5065f4a2713aSLionel Sambuc
5066f4a2713aSLionel Sambuc namespace {
5067f4a2713aSLionel Sambuc /// \brief Visitor used to search for information about a header file.
5068f4a2713aSLionel Sambuc class HeaderFileInfoVisitor {
5069f4a2713aSLionel Sambuc const FileEntry *FE;
5070f4a2713aSLionel Sambuc
5071f4a2713aSLionel Sambuc Optional<HeaderFileInfo> HFI;
5072f4a2713aSLionel Sambuc
5073f4a2713aSLionel Sambuc public:
HeaderFileInfoVisitor(const FileEntry * FE)5074f4a2713aSLionel Sambuc explicit HeaderFileInfoVisitor(const FileEntry *FE)
5075f4a2713aSLionel Sambuc : FE(FE) { }
5076f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)5077f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
5078f4a2713aSLionel Sambuc HeaderFileInfoVisitor *This
5079f4a2713aSLionel Sambuc = static_cast<HeaderFileInfoVisitor *>(UserData);
5080f4a2713aSLionel Sambuc
5081f4a2713aSLionel Sambuc HeaderFileInfoLookupTable *Table
5082f4a2713aSLionel Sambuc = static_cast<HeaderFileInfoLookupTable *>(M.HeaderFileInfoTable);
5083f4a2713aSLionel Sambuc if (!Table)
5084f4a2713aSLionel Sambuc return false;
5085f4a2713aSLionel Sambuc
5086f4a2713aSLionel Sambuc // Look in the on-disk hash table for an entry for this file name.
5087f4a2713aSLionel Sambuc HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE);
5088f4a2713aSLionel Sambuc if (Pos == Table->end())
5089f4a2713aSLionel Sambuc return false;
5090f4a2713aSLionel Sambuc
5091f4a2713aSLionel Sambuc This->HFI = *Pos;
5092f4a2713aSLionel Sambuc return true;
5093f4a2713aSLionel Sambuc }
5094f4a2713aSLionel Sambuc
getHeaderFileInfo() const5095f4a2713aSLionel Sambuc Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
5096f4a2713aSLionel Sambuc };
5097f4a2713aSLionel Sambuc }
5098f4a2713aSLionel Sambuc
GetHeaderFileInfo(const FileEntry * FE)5099f4a2713aSLionel Sambuc HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
5100f4a2713aSLionel Sambuc HeaderFileInfoVisitor Visitor(FE);
5101f4a2713aSLionel Sambuc ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor);
5102f4a2713aSLionel Sambuc if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo())
5103f4a2713aSLionel Sambuc return *HFI;
5104f4a2713aSLionel Sambuc
5105f4a2713aSLionel Sambuc return HeaderFileInfo();
5106f4a2713aSLionel Sambuc }
5107f4a2713aSLionel Sambuc
ReadPragmaDiagnosticMappings(DiagnosticsEngine & Diag)5108f4a2713aSLionel Sambuc void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
5109f4a2713aSLionel Sambuc // FIXME: Make it work properly with modules.
5110f4a2713aSLionel Sambuc SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;
5111f4a2713aSLionel Sambuc for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
5112f4a2713aSLionel Sambuc ModuleFile &F = *(*I);
5113f4a2713aSLionel Sambuc unsigned Idx = 0;
5114f4a2713aSLionel Sambuc DiagStates.clear();
5115f4a2713aSLionel Sambuc assert(!Diag.DiagStates.empty());
5116f4a2713aSLionel Sambuc DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.
5117f4a2713aSLionel Sambuc while (Idx < F.PragmaDiagMappings.size()) {
5118f4a2713aSLionel Sambuc SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
5119f4a2713aSLionel Sambuc unsigned DiagStateID = F.PragmaDiagMappings[Idx++];
5120f4a2713aSLionel Sambuc if (DiagStateID != 0) {
5121f4a2713aSLionel Sambuc Diag.DiagStatePoints.push_back(
5122f4a2713aSLionel Sambuc DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],
5123f4a2713aSLionel Sambuc FullSourceLoc(Loc, SourceMgr)));
5124f4a2713aSLionel Sambuc continue;
5125f4a2713aSLionel Sambuc }
5126f4a2713aSLionel Sambuc
5127f4a2713aSLionel Sambuc assert(DiagStateID == 0);
5128f4a2713aSLionel Sambuc // A new DiagState was created here.
5129f4a2713aSLionel Sambuc Diag.DiagStates.push_back(*Diag.GetCurDiagState());
5130f4a2713aSLionel Sambuc DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();
5131f4a2713aSLionel Sambuc DiagStates.push_back(NewState);
5132f4a2713aSLionel Sambuc Diag.DiagStatePoints.push_back(
5133f4a2713aSLionel Sambuc DiagnosticsEngine::DiagStatePoint(NewState,
5134f4a2713aSLionel Sambuc FullSourceLoc(Loc, SourceMgr)));
5135f4a2713aSLionel Sambuc while (1) {
5136f4a2713aSLionel Sambuc assert(Idx < F.PragmaDiagMappings.size() &&
5137f4a2713aSLionel Sambuc "Invalid data, didn't find '-1' marking end of diag/map pairs");
5138f4a2713aSLionel Sambuc if (Idx >= F.PragmaDiagMappings.size()) {
5139f4a2713aSLionel Sambuc break; // Something is messed up but at least avoid infinite loop in
5140f4a2713aSLionel Sambuc // release build.
5141f4a2713aSLionel Sambuc }
5142f4a2713aSLionel Sambuc unsigned DiagID = F.PragmaDiagMappings[Idx++];
5143f4a2713aSLionel Sambuc if (DiagID == (unsigned)-1) {
5144f4a2713aSLionel Sambuc break; // no more diag/map pairs for this location.
5145f4a2713aSLionel Sambuc }
5146*0a6a1f1dSLionel Sambuc diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
5147*0a6a1f1dSLionel Sambuc DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
5148*0a6a1f1dSLionel Sambuc Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
5149f4a2713aSLionel Sambuc }
5150f4a2713aSLionel Sambuc }
5151f4a2713aSLionel Sambuc }
5152f4a2713aSLionel Sambuc }
5153f4a2713aSLionel Sambuc
5154f4a2713aSLionel Sambuc /// \brief Get the correct cursor and offset for loading a type.
TypeCursorForIndex(unsigned Index)5155f4a2713aSLionel Sambuc ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
5156f4a2713aSLionel Sambuc GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);
5157f4a2713aSLionel Sambuc assert(I != GlobalTypeMap.end() && "Corrupted global type map");
5158f4a2713aSLionel Sambuc ModuleFile *M = I->second;
5159f4a2713aSLionel Sambuc return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]);
5160f4a2713aSLionel Sambuc }
5161f4a2713aSLionel Sambuc
5162f4a2713aSLionel Sambuc /// \brief Read and return the type with the given index..
5163f4a2713aSLionel Sambuc ///
5164f4a2713aSLionel Sambuc /// The index is the type ID, shifted and minus the number of predefs. This
5165f4a2713aSLionel Sambuc /// routine actually reads the record corresponding to the type at the given
5166f4a2713aSLionel Sambuc /// location. It is a helper routine for GetType, which deals with reading type
5167f4a2713aSLionel Sambuc /// IDs.
readTypeRecord(unsigned Index)5168f4a2713aSLionel Sambuc QualType ASTReader::readTypeRecord(unsigned Index) {
5169f4a2713aSLionel Sambuc RecordLocation Loc = TypeCursorForIndex(Index);
5170f4a2713aSLionel Sambuc BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
5171f4a2713aSLionel Sambuc
5172f4a2713aSLionel Sambuc // Keep track of where we are in the stream, then jump back there
5173f4a2713aSLionel Sambuc // after reading this type.
5174f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(DeclsCursor);
5175f4a2713aSLionel Sambuc
5176f4a2713aSLionel Sambuc ReadingKindTracker ReadingKind(Read_Type, *this);
5177f4a2713aSLionel Sambuc
5178f4a2713aSLionel Sambuc // Note that we are loading a type record.
5179f4a2713aSLionel Sambuc Deserializing AType(this);
5180f4a2713aSLionel Sambuc
5181f4a2713aSLionel Sambuc unsigned Idx = 0;
5182f4a2713aSLionel Sambuc DeclsCursor.JumpToBit(Loc.Offset);
5183f4a2713aSLionel Sambuc RecordData Record;
5184f4a2713aSLionel Sambuc unsigned Code = DeclsCursor.ReadCode();
5185f4a2713aSLionel Sambuc switch ((TypeCode)DeclsCursor.readRecord(Code, Record)) {
5186f4a2713aSLionel Sambuc case TYPE_EXT_QUAL: {
5187f4a2713aSLionel Sambuc if (Record.size() != 2) {
5188f4a2713aSLionel Sambuc Error("Incorrect encoding of extended qualifier type");
5189f4a2713aSLionel Sambuc return QualType();
5190f4a2713aSLionel Sambuc }
5191f4a2713aSLionel Sambuc QualType Base = readType(*Loc.F, Record, Idx);
5192f4a2713aSLionel Sambuc Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[Idx++]);
5193f4a2713aSLionel Sambuc return Context.getQualifiedType(Base, Quals);
5194f4a2713aSLionel Sambuc }
5195f4a2713aSLionel Sambuc
5196f4a2713aSLionel Sambuc case TYPE_COMPLEX: {
5197f4a2713aSLionel Sambuc if (Record.size() != 1) {
5198f4a2713aSLionel Sambuc Error("Incorrect encoding of complex type");
5199f4a2713aSLionel Sambuc return QualType();
5200f4a2713aSLionel Sambuc }
5201f4a2713aSLionel Sambuc QualType ElemType = readType(*Loc.F, Record, Idx);
5202f4a2713aSLionel Sambuc return Context.getComplexType(ElemType);
5203f4a2713aSLionel Sambuc }
5204f4a2713aSLionel Sambuc
5205f4a2713aSLionel Sambuc case TYPE_POINTER: {
5206f4a2713aSLionel Sambuc if (Record.size() != 1) {
5207f4a2713aSLionel Sambuc Error("Incorrect encoding of pointer type");
5208f4a2713aSLionel Sambuc return QualType();
5209f4a2713aSLionel Sambuc }
5210f4a2713aSLionel Sambuc QualType PointeeType = readType(*Loc.F, Record, Idx);
5211f4a2713aSLionel Sambuc return Context.getPointerType(PointeeType);
5212f4a2713aSLionel Sambuc }
5213f4a2713aSLionel Sambuc
5214f4a2713aSLionel Sambuc case TYPE_DECAYED: {
5215f4a2713aSLionel Sambuc if (Record.size() != 1) {
5216f4a2713aSLionel Sambuc Error("Incorrect encoding of decayed type");
5217f4a2713aSLionel Sambuc return QualType();
5218f4a2713aSLionel Sambuc }
5219f4a2713aSLionel Sambuc QualType OriginalType = readType(*Loc.F, Record, Idx);
5220f4a2713aSLionel Sambuc QualType DT = Context.getAdjustedParameterType(OriginalType);
5221f4a2713aSLionel Sambuc if (!isa<DecayedType>(DT))
5222f4a2713aSLionel Sambuc Error("Decayed type does not decay");
5223f4a2713aSLionel Sambuc return DT;
5224f4a2713aSLionel Sambuc }
5225f4a2713aSLionel Sambuc
5226*0a6a1f1dSLionel Sambuc case TYPE_ADJUSTED: {
5227*0a6a1f1dSLionel Sambuc if (Record.size() != 2) {
5228*0a6a1f1dSLionel Sambuc Error("Incorrect encoding of adjusted type");
5229*0a6a1f1dSLionel Sambuc return QualType();
5230*0a6a1f1dSLionel Sambuc }
5231*0a6a1f1dSLionel Sambuc QualType OriginalTy = readType(*Loc.F, Record, Idx);
5232*0a6a1f1dSLionel Sambuc QualType AdjustedTy = readType(*Loc.F, Record, Idx);
5233*0a6a1f1dSLionel Sambuc return Context.getAdjustedType(OriginalTy, AdjustedTy);
5234*0a6a1f1dSLionel Sambuc }
5235*0a6a1f1dSLionel Sambuc
5236f4a2713aSLionel Sambuc case TYPE_BLOCK_POINTER: {
5237f4a2713aSLionel Sambuc if (Record.size() != 1) {
5238f4a2713aSLionel Sambuc Error("Incorrect encoding of block pointer type");
5239f4a2713aSLionel Sambuc return QualType();
5240f4a2713aSLionel Sambuc }
5241f4a2713aSLionel Sambuc QualType PointeeType = readType(*Loc.F, Record, Idx);
5242f4a2713aSLionel Sambuc return Context.getBlockPointerType(PointeeType);
5243f4a2713aSLionel Sambuc }
5244f4a2713aSLionel Sambuc
5245f4a2713aSLionel Sambuc case TYPE_LVALUE_REFERENCE: {
5246f4a2713aSLionel Sambuc if (Record.size() != 2) {
5247f4a2713aSLionel Sambuc Error("Incorrect encoding of lvalue reference type");
5248f4a2713aSLionel Sambuc return QualType();
5249f4a2713aSLionel Sambuc }
5250f4a2713aSLionel Sambuc QualType PointeeType = readType(*Loc.F, Record, Idx);
5251f4a2713aSLionel Sambuc return Context.getLValueReferenceType(PointeeType, Record[1]);
5252f4a2713aSLionel Sambuc }
5253f4a2713aSLionel Sambuc
5254f4a2713aSLionel Sambuc case TYPE_RVALUE_REFERENCE: {
5255f4a2713aSLionel Sambuc if (Record.size() != 1) {
5256f4a2713aSLionel Sambuc Error("Incorrect encoding of rvalue reference type");
5257f4a2713aSLionel Sambuc return QualType();
5258f4a2713aSLionel Sambuc }
5259f4a2713aSLionel Sambuc QualType PointeeType = readType(*Loc.F, Record, Idx);
5260f4a2713aSLionel Sambuc return Context.getRValueReferenceType(PointeeType);
5261f4a2713aSLionel Sambuc }
5262f4a2713aSLionel Sambuc
5263f4a2713aSLionel Sambuc case TYPE_MEMBER_POINTER: {
5264f4a2713aSLionel Sambuc if (Record.size() != 2) {
5265f4a2713aSLionel Sambuc Error("Incorrect encoding of member pointer type");
5266f4a2713aSLionel Sambuc return QualType();
5267f4a2713aSLionel Sambuc }
5268f4a2713aSLionel Sambuc QualType PointeeType = readType(*Loc.F, Record, Idx);
5269f4a2713aSLionel Sambuc QualType ClassType = readType(*Loc.F, Record, Idx);
5270f4a2713aSLionel Sambuc if (PointeeType.isNull() || ClassType.isNull())
5271f4a2713aSLionel Sambuc return QualType();
5272f4a2713aSLionel Sambuc
5273f4a2713aSLionel Sambuc return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
5274f4a2713aSLionel Sambuc }
5275f4a2713aSLionel Sambuc
5276f4a2713aSLionel Sambuc case TYPE_CONSTANT_ARRAY: {
5277f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5278f4a2713aSLionel Sambuc ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
5279f4a2713aSLionel Sambuc unsigned IndexTypeQuals = Record[2];
5280f4a2713aSLionel Sambuc unsigned Idx = 3;
5281f4a2713aSLionel Sambuc llvm::APInt Size = ReadAPInt(Record, Idx);
5282f4a2713aSLionel Sambuc return Context.getConstantArrayType(ElementType, Size,
5283f4a2713aSLionel Sambuc ASM, IndexTypeQuals);
5284f4a2713aSLionel Sambuc }
5285f4a2713aSLionel Sambuc
5286f4a2713aSLionel Sambuc case TYPE_INCOMPLETE_ARRAY: {
5287f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5288f4a2713aSLionel Sambuc ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
5289f4a2713aSLionel Sambuc unsigned IndexTypeQuals = Record[2];
5290f4a2713aSLionel Sambuc return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
5291f4a2713aSLionel Sambuc }
5292f4a2713aSLionel Sambuc
5293f4a2713aSLionel Sambuc case TYPE_VARIABLE_ARRAY: {
5294f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5295f4a2713aSLionel Sambuc ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
5296f4a2713aSLionel Sambuc unsigned IndexTypeQuals = Record[2];
5297f4a2713aSLionel Sambuc SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]);
5298f4a2713aSLionel Sambuc SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]);
5299f4a2713aSLionel Sambuc return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F),
5300f4a2713aSLionel Sambuc ASM, IndexTypeQuals,
5301f4a2713aSLionel Sambuc SourceRange(LBLoc, RBLoc));
5302f4a2713aSLionel Sambuc }
5303f4a2713aSLionel Sambuc
5304f4a2713aSLionel Sambuc case TYPE_VECTOR: {
5305f4a2713aSLionel Sambuc if (Record.size() != 3) {
5306f4a2713aSLionel Sambuc Error("incorrect encoding of vector type in AST file");
5307f4a2713aSLionel Sambuc return QualType();
5308f4a2713aSLionel Sambuc }
5309f4a2713aSLionel Sambuc
5310f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5311f4a2713aSLionel Sambuc unsigned NumElements = Record[1];
5312f4a2713aSLionel Sambuc unsigned VecKind = Record[2];
5313f4a2713aSLionel Sambuc return Context.getVectorType(ElementType, NumElements,
5314f4a2713aSLionel Sambuc (VectorType::VectorKind)VecKind);
5315f4a2713aSLionel Sambuc }
5316f4a2713aSLionel Sambuc
5317f4a2713aSLionel Sambuc case TYPE_EXT_VECTOR: {
5318f4a2713aSLionel Sambuc if (Record.size() != 3) {
5319f4a2713aSLionel Sambuc Error("incorrect encoding of extended vector type in AST file");
5320f4a2713aSLionel Sambuc return QualType();
5321f4a2713aSLionel Sambuc }
5322f4a2713aSLionel Sambuc
5323f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5324f4a2713aSLionel Sambuc unsigned NumElements = Record[1];
5325f4a2713aSLionel Sambuc return Context.getExtVectorType(ElementType, NumElements);
5326f4a2713aSLionel Sambuc }
5327f4a2713aSLionel Sambuc
5328f4a2713aSLionel Sambuc case TYPE_FUNCTION_NO_PROTO: {
5329f4a2713aSLionel Sambuc if (Record.size() != 6) {
5330f4a2713aSLionel Sambuc Error("incorrect encoding of no-proto function type");
5331f4a2713aSLionel Sambuc return QualType();
5332f4a2713aSLionel Sambuc }
5333f4a2713aSLionel Sambuc QualType ResultType = readType(*Loc.F, Record, Idx);
5334f4a2713aSLionel Sambuc FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],
5335f4a2713aSLionel Sambuc (CallingConv)Record[4], Record[5]);
5336f4a2713aSLionel Sambuc return Context.getFunctionNoProtoType(ResultType, Info);
5337f4a2713aSLionel Sambuc }
5338f4a2713aSLionel Sambuc
5339f4a2713aSLionel Sambuc case TYPE_FUNCTION_PROTO: {
5340f4a2713aSLionel Sambuc QualType ResultType = readType(*Loc.F, Record, Idx);
5341f4a2713aSLionel Sambuc
5342f4a2713aSLionel Sambuc FunctionProtoType::ExtProtoInfo EPI;
5343f4a2713aSLionel Sambuc EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],
5344f4a2713aSLionel Sambuc /*hasregparm*/ Record[2],
5345f4a2713aSLionel Sambuc /*regparm*/ Record[3],
5346f4a2713aSLionel Sambuc static_cast<CallingConv>(Record[4]),
5347f4a2713aSLionel Sambuc /*produces*/ Record[5]);
5348f4a2713aSLionel Sambuc
5349f4a2713aSLionel Sambuc unsigned Idx = 6;
5350f4a2713aSLionel Sambuc
5351f4a2713aSLionel Sambuc EPI.Variadic = Record[Idx++];
5352f4a2713aSLionel Sambuc EPI.HasTrailingReturn = Record[Idx++];
5353f4a2713aSLionel Sambuc EPI.TypeQuals = Record[Idx++];
5354f4a2713aSLionel Sambuc EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
5355*0a6a1f1dSLionel Sambuc SmallVector<QualType, 8> ExceptionStorage;
5356*0a6a1f1dSLionel Sambuc readExceptionSpec(*Loc.F, ExceptionStorage, EPI.ExceptionSpec, Record, Idx);
5357*0a6a1f1dSLionel Sambuc
5358*0a6a1f1dSLionel Sambuc unsigned NumParams = Record[Idx++];
5359*0a6a1f1dSLionel Sambuc SmallVector<QualType, 16> ParamTypes;
5360*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I != NumParams; ++I)
5361*0a6a1f1dSLionel Sambuc ParamTypes.push_back(readType(*Loc.F, Record, Idx));
5362*0a6a1f1dSLionel Sambuc
5363f4a2713aSLionel Sambuc return Context.getFunctionType(ResultType, ParamTypes, EPI);
5364f4a2713aSLionel Sambuc }
5365f4a2713aSLionel Sambuc
5366f4a2713aSLionel Sambuc case TYPE_UNRESOLVED_USING: {
5367f4a2713aSLionel Sambuc unsigned Idx = 0;
5368f4a2713aSLionel Sambuc return Context.getTypeDeclType(
5369f4a2713aSLionel Sambuc ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));
5370f4a2713aSLionel Sambuc }
5371f4a2713aSLionel Sambuc
5372f4a2713aSLionel Sambuc case TYPE_TYPEDEF: {
5373f4a2713aSLionel Sambuc if (Record.size() != 2) {
5374f4a2713aSLionel Sambuc Error("incorrect encoding of typedef type");
5375f4a2713aSLionel Sambuc return QualType();
5376f4a2713aSLionel Sambuc }
5377f4a2713aSLionel Sambuc unsigned Idx = 0;
5378f4a2713aSLionel Sambuc TypedefNameDecl *Decl = ReadDeclAs<TypedefNameDecl>(*Loc.F, Record, Idx);
5379f4a2713aSLionel Sambuc QualType Canonical = readType(*Loc.F, Record, Idx);
5380f4a2713aSLionel Sambuc if (!Canonical.isNull())
5381f4a2713aSLionel Sambuc Canonical = Context.getCanonicalType(Canonical);
5382f4a2713aSLionel Sambuc return Context.getTypedefType(Decl, Canonical);
5383f4a2713aSLionel Sambuc }
5384f4a2713aSLionel Sambuc
5385f4a2713aSLionel Sambuc case TYPE_TYPEOF_EXPR:
5386f4a2713aSLionel Sambuc return Context.getTypeOfExprType(ReadExpr(*Loc.F));
5387f4a2713aSLionel Sambuc
5388f4a2713aSLionel Sambuc case TYPE_TYPEOF: {
5389f4a2713aSLionel Sambuc if (Record.size() != 1) {
5390f4a2713aSLionel Sambuc Error("incorrect encoding of typeof(type) in AST file");
5391f4a2713aSLionel Sambuc return QualType();
5392f4a2713aSLionel Sambuc }
5393f4a2713aSLionel Sambuc QualType UnderlyingType = readType(*Loc.F, Record, Idx);
5394f4a2713aSLionel Sambuc return Context.getTypeOfType(UnderlyingType);
5395f4a2713aSLionel Sambuc }
5396f4a2713aSLionel Sambuc
5397f4a2713aSLionel Sambuc case TYPE_DECLTYPE: {
5398f4a2713aSLionel Sambuc QualType UnderlyingType = readType(*Loc.F, Record, Idx);
5399f4a2713aSLionel Sambuc return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);
5400f4a2713aSLionel Sambuc }
5401f4a2713aSLionel Sambuc
5402f4a2713aSLionel Sambuc case TYPE_UNARY_TRANSFORM: {
5403f4a2713aSLionel Sambuc QualType BaseType = readType(*Loc.F, Record, Idx);
5404f4a2713aSLionel Sambuc QualType UnderlyingType = readType(*Loc.F, Record, Idx);
5405f4a2713aSLionel Sambuc UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2];
5406f4a2713aSLionel Sambuc return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);
5407f4a2713aSLionel Sambuc }
5408f4a2713aSLionel Sambuc
5409f4a2713aSLionel Sambuc case TYPE_AUTO: {
5410f4a2713aSLionel Sambuc QualType Deduced = readType(*Loc.F, Record, Idx);
5411f4a2713aSLionel Sambuc bool IsDecltypeAuto = Record[Idx++];
5412f4a2713aSLionel Sambuc bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
5413f4a2713aSLionel Sambuc return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent);
5414f4a2713aSLionel Sambuc }
5415f4a2713aSLionel Sambuc
5416f4a2713aSLionel Sambuc case TYPE_RECORD: {
5417f4a2713aSLionel Sambuc if (Record.size() != 2) {
5418f4a2713aSLionel Sambuc Error("incorrect encoding of record type");
5419f4a2713aSLionel Sambuc return QualType();
5420f4a2713aSLionel Sambuc }
5421f4a2713aSLionel Sambuc unsigned Idx = 0;
5422f4a2713aSLionel Sambuc bool IsDependent = Record[Idx++];
5423f4a2713aSLionel Sambuc RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);
5424f4a2713aSLionel Sambuc RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());
5425f4a2713aSLionel Sambuc QualType T = Context.getRecordType(RD);
5426f4a2713aSLionel Sambuc const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
5427f4a2713aSLionel Sambuc return T;
5428f4a2713aSLionel Sambuc }
5429f4a2713aSLionel Sambuc
5430f4a2713aSLionel Sambuc case TYPE_ENUM: {
5431f4a2713aSLionel Sambuc if (Record.size() != 2) {
5432f4a2713aSLionel Sambuc Error("incorrect encoding of enum type");
5433f4a2713aSLionel Sambuc return QualType();
5434f4a2713aSLionel Sambuc }
5435f4a2713aSLionel Sambuc unsigned Idx = 0;
5436f4a2713aSLionel Sambuc bool IsDependent = Record[Idx++];
5437f4a2713aSLionel Sambuc QualType T
5438f4a2713aSLionel Sambuc = Context.getEnumType(ReadDeclAs<EnumDecl>(*Loc.F, Record, Idx));
5439f4a2713aSLionel Sambuc const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
5440f4a2713aSLionel Sambuc return T;
5441f4a2713aSLionel Sambuc }
5442f4a2713aSLionel Sambuc
5443f4a2713aSLionel Sambuc case TYPE_ATTRIBUTED: {
5444f4a2713aSLionel Sambuc if (Record.size() != 3) {
5445f4a2713aSLionel Sambuc Error("incorrect encoding of attributed type");
5446f4a2713aSLionel Sambuc return QualType();
5447f4a2713aSLionel Sambuc }
5448f4a2713aSLionel Sambuc QualType modifiedType = readType(*Loc.F, Record, Idx);
5449f4a2713aSLionel Sambuc QualType equivalentType = readType(*Loc.F, Record, Idx);
5450f4a2713aSLionel Sambuc AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
5451f4a2713aSLionel Sambuc return Context.getAttributedType(kind, modifiedType, equivalentType);
5452f4a2713aSLionel Sambuc }
5453f4a2713aSLionel Sambuc
5454f4a2713aSLionel Sambuc case TYPE_PAREN: {
5455f4a2713aSLionel Sambuc if (Record.size() != 1) {
5456f4a2713aSLionel Sambuc Error("incorrect encoding of paren type");
5457f4a2713aSLionel Sambuc return QualType();
5458f4a2713aSLionel Sambuc }
5459f4a2713aSLionel Sambuc QualType InnerType = readType(*Loc.F, Record, Idx);
5460f4a2713aSLionel Sambuc return Context.getParenType(InnerType);
5461f4a2713aSLionel Sambuc }
5462f4a2713aSLionel Sambuc
5463f4a2713aSLionel Sambuc case TYPE_PACK_EXPANSION: {
5464f4a2713aSLionel Sambuc if (Record.size() != 2) {
5465f4a2713aSLionel Sambuc Error("incorrect encoding of pack expansion type");
5466f4a2713aSLionel Sambuc return QualType();
5467f4a2713aSLionel Sambuc }
5468f4a2713aSLionel Sambuc QualType Pattern = readType(*Loc.F, Record, Idx);
5469f4a2713aSLionel Sambuc if (Pattern.isNull())
5470f4a2713aSLionel Sambuc return QualType();
5471f4a2713aSLionel Sambuc Optional<unsigned> NumExpansions;
5472f4a2713aSLionel Sambuc if (Record[1])
5473f4a2713aSLionel Sambuc NumExpansions = Record[1] - 1;
5474f4a2713aSLionel Sambuc return Context.getPackExpansionType(Pattern, NumExpansions);
5475f4a2713aSLionel Sambuc }
5476f4a2713aSLionel Sambuc
5477f4a2713aSLionel Sambuc case TYPE_ELABORATED: {
5478f4a2713aSLionel Sambuc unsigned Idx = 0;
5479f4a2713aSLionel Sambuc ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
5480f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
5481f4a2713aSLionel Sambuc QualType NamedType = readType(*Loc.F, Record, Idx);
5482f4a2713aSLionel Sambuc return Context.getElaboratedType(Keyword, NNS, NamedType);
5483f4a2713aSLionel Sambuc }
5484f4a2713aSLionel Sambuc
5485f4a2713aSLionel Sambuc case TYPE_OBJC_INTERFACE: {
5486f4a2713aSLionel Sambuc unsigned Idx = 0;
5487f4a2713aSLionel Sambuc ObjCInterfaceDecl *ItfD
5488f4a2713aSLionel Sambuc = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
5489f4a2713aSLionel Sambuc return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
5490f4a2713aSLionel Sambuc }
5491f4a2713aSLionel Sambuc
5492f4a2713aSLionel Sambuc case TYPE_OBJC_OBJECT: {
5493f4a2713aSLionel Sambuc unsigned Idx = 0;
5494f4a2713aSLionel Sambuc QualType Base = readType(*Loc.F, Record, Idx);
5495f4a2713aSLionel Sambuc unsigned NumProtos = Record[Idx++];
5496f4a2713aSLionel Sambuc SmallVector<ObjCProtocolDecl*, 4> Protos;
5497f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtos; ++I)
5498f4a2713aSLionel Sambuc Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
5499f4a2713aSLionel Sambuc return Context.getObjCObjectType(Base, Protos.data(), NumProtos);
5500f4a2713aSLionel Sambuc }
5501f4a2713aSLionel Sambuc
5502f4a2713aSLionel Sambuc case TYPE_OBJC_OBJECT_POINTER: {
5503f4a2713aSLionel Sambuc unsigned Idx = 0;
5504f4a2713aSLionel Sambuc QualType Pointee = readType(*Loc.F, Record, Idx);
5505f4a2713aSLionel Sambuc return Context.getObjCObjectPointerType(Pointee);
5506f4a2713aSLionel Sambuc }
5507f4a2713aSLionel Sambuc
5508f4a2713aSLionel Sambuc case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
5509f4a2713aSLionel Sambuc unsigned Idx = 0;
5510f4a2713aSLionel Sambuc QualType Parm = readType(*Loc.F, Record, Idx);
5511f4a2713aSLionel Sambuc QualType Replacement = readType(*Loc.F, Record, Idx);
5512*0a6a1f1dSLionel Sambuc return Context.getSubstTemplateTypeParmType(
5513*0a6a1f1dSLionel Sambuc cast<TemplateTypeParmType>(Parm),
5514*0a6a1f1dSLionel Sambuc Context.getCanonicalType(Replacement));
5515f4a2713aSLionel Sambuc }
5516f4a2713aSLionel Sambuc
5517f4a2713aSLionel Sambuc case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
5518f4a2713aSLionel Sambuc unsigned Idx = 0;
5519f4a2713aSLionel Sambuc QualType Parm = readType(*Loc.F, Record, Idx);
5520f4a2713aSLionel Sambuc TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);
5521f4a2713aSLionel Sambuc return Context.getSubstTemplateTypeParmPackType(
5522f4a2713aSLionel Sambuc cast<TemplateTypeParmType>(Parm),
5523f4a2713aSLionel Sambuc ArgPack);
5524f4a2713aSLionel Sambuc }
5525f4a2713aSLionel Sambuc
5526f4a2713aSLionel Sambuc case TYPE_INJECTED_CLASS_NAME: {
5527f4a2713aSLionel Sambuc CXXRecordDecl *D = ReadDeclAs<CXXRecordDecl>(*Loc.F, Record, Idx);
5528f4a2713aSLionel Sambuc QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
5529f4a2713aSLionel Sambuc // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
5530f4a2713aSLionel Sambuc // for AST reading, too much interdependencies.
5531*0a6a1f1dSLionel Sambuc const Type *T = nullptr;
5532*0a6a1f1dSLionel Sambuc for (auto *DI = D; DI; DI = DI->getPreviousDecl()) {
5533*0a6a1f1dSLionel Sambuc if (const Type *Existing = DI->getTypeForDecl()) {
5534*0a6a1f1dSLionel Sambuc T = Existing;
5535*0a6a1f1dSLionel Sambuc break;
5536*0a6a1f1dSLionel Sambuc }
5537*0a6a1f1dSLionel Sambuc }
5538*0a6a1f1dSLionel Sambuc if (!T) {
5539*0a6a1f1dSLionel Sambuc T = new (Context, TypeAlignment) InjectedClassNameType(D, TST);
5540*0a6a1f1dSLionel Sambuc for (auto *DI = D; DI; DI = DI->getPreviousDecl())
5541*0a6a1f1dSLionel Sambuc DI->setTypeForDecl(T);
5542*0a6a1f1dSLionel Sambuc }
5543*0a6a1f1dSLionel Sambuc return QualType(T, 0);
5544f4a2713aSLionel Sambuc }
5545f4a2713aSLionel Sambuc
5546f4a2713aSLionel Sambuc case TYPE_TEMPLATE_TYPE_PARM: {
5547f4a2713aSLionel Sambuc unsigned Idx = 0;
5548f4a2713aSLionel Sambuc unsigned Depth = Record[Idx++];
5549f4a2713aSLionel Sambuc unsigned Index = Record[Idx++];
5550f4a2713aSLionel Sambuc bool Pack = Record[Idx++];
5551f4a2713aSLionel Sambuc TemplateTypeParmDecl *D
5552f4a2713aSLionel Sambuc = ReadDeclAs<TemplateTypeParmDecl>(*Loc.F, Record, Idx);
5553f4a2713aSLionel Sambuc return Context.getTemplateTypeParmType(Depth, Index, Pack, D);
5554f4a2713aSLionel Sambuc }
5555f4a2713aSLionel Sambuc
5556f4a2713aSLionel Sambuc case TYPE_DEPENDENT_NAME: {
5557f4a2713aSLionel Sambuc unsigned Idx = 0;
5558f4a2713aSLionel Sambuc ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
5559f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
5560f4a2713aSLionel Sambuc const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
5561f4a2713aSLionel Sambuc QualType Canon = readType(*Loc.F, Record, Idx);
5562f4a2713aSLionel Sambuc if (!Canon.isNull())
5563f4a2713aSLionel Sambuc Canon = Context.getCanonicalType(Canon);
5564f4a2713aSLionel Sambuc return Context.getDependentNameType(Keyword, NNS, Name, Canon);
5565f4a2713aSLionel Sambuc }
5566f4a2713aSLionel Sambuc
5567f4a2713aSLionel Sambuc case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
5568f4a2713aSLionel Sambuc unsigned Idx = 0;
5569f4a2713aSLionel Sambuc ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
5570f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
5571f4a2713aSLionel Sambuc const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
5572f4a2713aSLionel Sambuc unsigned NumArgs = Record[Idx++];
5573f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> Args;
5574f4a2713aSLionel Sambuc Args.reserve(NumArgs);
5575f4a2713aSLionel Sambuc while (NumArgs--)
5576f4a2713aSLionel Sambuc Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));
5577f4a2713aSLionel Sambuc return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name,
5578f4a2713aSLionel Sambuc Args.size(), Args.data());
5579f4a2713aSLionel Sambuc }
5580f4a2713aSLionel Sambuc
5581f4a2713aSLionel Sambuc case TYPE_DEPENDENT_SIZED_ARRAY: {
5582f4a2713aSLionel Sambuc unsigned Idx = 0;
5583f4a2713aSLionel Sambuc
5584f4a2713aSLionel Sambuc // ArrayType
5585f4a2713aSLionel Sambuc QualType ElementType = readType(*Loc.F, Record, Idx);
5586f4a2713aSLionel Sambuc ArrayType::ArraySizeModifier ASM
5587f4a2713aSLionel Sambuc = (ArrayType::ArraySizeModifier)Record[Idx++];
5588f4a2713aSLionel Sambuc unsigned IndexTypeQuals = Record[Idx++];
5589f4a2713aSLionel Sambuc
5590f4a2713aSLionel Sambuc // DependentSizedArrayType
5591f4a2713aSLionel Sambuc Expr *NumElts = ReadExpr(*Loc.F);
5592f4a2713aSLionel Sambuc SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx);
5593f4a2713aSLionel Sambuc
5594f4a2713aSLionel Sambuc return Context.getDependentSizedArrayType(ElementType, NumElts, ASM,
5595f4a2713aSLionel Sambuc IndexTypeQuals, Brackets);
5596f4a2713aSLionel Sambuc }
5597f4a2713aSLionel Sambuc
5598f4a2713aSLionel Sambuc case TYPE_TEMPLATE_SPECIALIZATION: {
5599f4a2713aSLionel Sambuc unsigned Idx = 0;
5600f4a2713aSLionel Sambuc bool IsDependent = Record[Idx++];
5601f4a2713aSLionel Sambuc TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
5602f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> Args;
5603f4a2713aSLionel Sambuc ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
5604f4a2713aSLionel Sambuc QualType Underlying = readType(*Loc.F, Record, Idx);
5605f4a2713aSLionel Sambuc QualType T;
5606f4a2713aSLionel Sambuc if (Underlying.isNull())
5607f4a2713aSLionel Sambuc T = Context.getCanonicalTemplateSpecializationType(Name, Args.data(),
5608f4a2713aSLionel Sambuc Args.size());
5609f4a2713aSLionel Sambuc else
5610f4a2713aSLionel Sambuc T = Context.getTemplateSpecializationType(Name, Args.data(),
5611f4a2713aSLionel Sambuc Args.size(), Underlying);
5612f4a2713aSLionel Sambuc const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
5613f4a2713aSLionel Sambuc return T;
5614f4a2713aSLionel Sambuc }
5615f4a2713aSLionel Sambuc
5616f4a2713aSLionel Sambuc case TYPE_ATOMIC: {
5617f4a2713aSLionel Sambuc if (Record.size() != 1) {
5618f4a2713aSLionel Sambuc Error("Incorrect encoding of atomic type");
5619f4a2713aSLionel Sambuc return QualType();
5620f4a2713aSLionel Sambuc }
5621f4a2713aSLionel Sambuc QualType ValueType = readType(*Loc.F, Record, Idx);
5622f4a2713aSLionel Sambuc return Context.getAtomicType(ValueType);
5623f4a2713aSLionel Sambuc }
5624f4a2713aSLionel Sambuc }
5625f4a2713aSLionel Sambuc llvm_unreachable("Invalid TypeCode!");
5626f4a2713aSLionel Sambuc }
5627f4a2713aSLionel Sambuc
readExceptionSpec(ModuleFile & ModuleFile,SmallVectorImpl<QualType> & Exceptions,FunctionProtoType::ExceptionSpecInfo & ESI,const RecordData & Record,unsigned & Idx)5628*0a6a1f1dSLionel Sambuc void ASTReader::readExceptionSpec(ModuleFile &ModuleFile,
5629*0a6a1f1dSLionel Sambuc SmallVectorImpl<QualType> &Exceptions,
5630*0a6a1f1dSLionel Sambuc FunctionProtoType::ExceptionSpecInfo &ESI,
5631*0a6a1f1dSLionel Sambuc const RecordData &Record, unsigned &Idx) {
5632*0a6a1f1dSLionel Sambuc ExceptionSpecificationType EST =
5633*0a6a1f1dSLionel Sambuc static_cast<ExceptionSpecificationType>(Record[Idx++]);
5634*0a6a1f1dSLionel Sambuc ESI.Type = EST;
5635*0a6a1f1dSLionel Sambuc if (EST == EST_Dynamic) {
5636*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Record[Idx++]; I != N; ++I)
5637*0a6a1f1dSLionel Sambuc Exceptions.push_back(readType(ModuleFile, Record, Idx));
5638*0a6a1f1dSLionel Sambuc ESI.Exceptions = Exceptions;
5639*0a6a1f1dSLionel Sambuc } else if (EST == EST_ComputedNoexcept) {
5640*0a6a1f1dSLionel Sambuc ESI.NoexceptExpr = ReadExpr(ModuleFile);
5641*0a6a1f1dSLionel Sambuc } else if (EST == EST_Uninstantiated) {
5642*0a6a1f1dSLionel Sambuc ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
5643*0a6a1f1dSLionel Sambuc ESI.SourceTemplate = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
5644*0a6a1f1dSLionel Sambuc } else if (EST == EST_Unevaluated) {
5645*0a6a1f1dSLionel Sambuc ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
5646*0a6a1f1dSLionel Sambuc }
5647*0a6a1f1dSLionel Sambuc }
5648*0a6a1f1dSLionel Sambuc
5649f4a2713aSLionel Sambuc class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
5650f4a2713aSLionel Sambuc ASTReader &Reader;
5651f4a2713aSLionel Sambuc ModuleFile &F;
5652f4a2713aSLionel Sambuc const ASTReader::RecordData &Record;
5653f4a2713aSLionel Sambuc unsigned &Idx;
5654f4a2713aSLionel Sambuc
ReadSourceLocation(const ASTReader::RecordData & R,unsigned & I)5655f4a2713aSLionel Sambuc SourceLocation ReadSourceLocation(const ASTReader::RecordData &R,
5656f4a2713aSLionel Sambuc unsigned &I) {
5657f4a2713aSLionel Sambuc return Reader.ReadSourceLocation(F, R, I);
5658f4a2713aSLionel Sambuc }
5659f4a2713aSLionel Sambuc
5660f4a2713aSLionel Sambuc template<typename T>
ReadDeclAs(const ASTReader::RecordData & Record,unsigned & Idx)5661f4a2713aSLionel Sambuc T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) {
5662f4a2713aSLionel Sambuc return Reader.ReadDeclAs<T>(F, Record, Idx);
5663f4a2713aSLionel Sambuc }
5664f4a2713aSLionel Sambuc
5665f4a2713aSLionel Sambuc public:
TypeLocReader(ASTReader & Reader,ModuleFile & F,const ASTReader::RecordData & Record,unsigned & Idx)5666f4a2713aSLionel Sambuc TypeLocReader(ASTReader &Reader, ModuleFile &F,
5667f4a2713aSLionel Sambuc const ASTReader::RecordData &Record, unsigned &Idx)
5668f4a2713aSLionel Sambuc : Reader(Reader), F(F), Record(Record), Idx(Idx)
5669f4a2713aSLionel Sambuc { }
5670f4a2713aSLionel Sambuc
5671f4a2713aSLionel Sambuc // We want compile-time assurance that we've enumerated all of
5672f4a2713aSLionel Sambuc // these, so unfortunately we have to declare them first, then
5673f4a2713aSLionel Sambuc // define them out-of-line.
5674f4a2713aSLionel Sambuc #define ABSTRACT_TYPELOC(CLASS, PARENT)
5675f4a2713aSLionel Sambuc #define TYPELOC(CLASS, PARENT) \
5676f4a2713aSLionel Sambuc void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
5677f4a2713aSLionel Sambuc #include "clang/AST/TypeLocNodes.def"
5678f4a2713aSLionel Sambuc
5679f4a2713aSLionel Sambuc void VisitFunctionTypeLoc(FunctionTypeLoc);
5680f4a2713aSLionel Sambuc void VisitArrayTypeLoc(ArrayTypeLoc);
5681f4a2713aSLionel Sambuc };
5682f4a2713aSLionel Sambuc
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)5683f4a2713aSLionel Sambuc void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
5684f4a2713aSLionel Sambuc // nothing to do
5685f4a2713aSLionel Sambuc }
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)5686f4a2713aSLionel Sambuc void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
5687f4a2713aSLionel Sambuc TL.setBuiltinLoc(ReadSourceLocation(Record, Idx));
5688f4a2713aSLionel Sambuc if (TL.needsExtraLocalData()) {
5689f4a2713aSLionel Sambuc TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
5690f4a2713aSLionel Sambuc TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
5691f4a2713aSLionel Sambuc TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
5692f4a2713aSLionel Sambuc TL.setModeAttr(Record[Idx++]);
5693f4a2713aSLionel Sambuc }
5694f4a2713aSLionel Sambuc }
VisitComplexTypeLoc(ComplexTypeLoc TL)5695f4a2713aSLionel Sambuc void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
5696f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5697f4a2713aSLionel Sambuc }
VisitPointerTypeLoc(PointerTypeLoc TL)5698f4a2713aSLionel Sambuc void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
5699f4a2713aSLionel Sambuc TL.setStarLoc(ReadSourceLocation(Record, Idx));
5700f4a2713aSLionel Sambuc }
VisitDecayedTypeLoc(DecayedTypeLoc TL)5701f4a2713aSLionel Sambuc void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
5702f4a2713aSLionel Sambuc // nothing to do
5703f4a2713aSLionel Sambuc }
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)5704*0a6a1f1dSLionel Sambuc void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
5705*0a6a1f1dSLionel Sambuc // nothing to do
5706*0a6a1f1dSLionel Sambuc }
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)5707f4a2713aSLionel Sambuc void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
5708f4a2713aSLionel Sambuc TL.setCaretLoc(ReadSourceLocation(Record, Idx));
5709f4a2713aSLionel Sambuc }
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)5710f4a2713aSLionel Sambuc void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
5711f4a2713aSLionel Sambuc TL.setAmpLoc(ReadSourceLocation(Record, Idx));
5712f4a2713aSLionel Sambuc }
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)5713f4a2713aSLionel Sambuc void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
5714f4a2713aSLionel Sambuc TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx));
5715f4a2713aSLionel Sambuc }
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)5716f4a2713aSLionel Sambuc void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
5717f4a2713aSLionel Sambuc TL.setStarLoc(ReadSourceLocation(Record, Idx));
5718f4a2713aSLionel Sambuc TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
5719f4a2713aSLionel Sambuc }
VisitArrayTypeLoc(ArrayTypeLoc TL)5720f4a2713aSLionel Sambuc void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
5721f4a2713aSLionel Sambuc TL.setLBracketLoc(ReadSourceLocation(Record, Idx));
5722f4a2713aSLionel Sambuc TL.setRBracketLoc(ReadSourceLocation(Record, Idx));
5723f4a2713aSLionel Sambuc if (Record[Idx++])
5724f4a2713aSLionel Sambuc TL.setSizeExpr(Reader.ReadExpr(F));
5725f4a2713aSLionel Sambuc else
5726*0a6a1f1dSLionel Sambuc TL.setSizeExpr(nullptr);
5727f4a2713aSLionel Sambuc }
VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL)5728f4a2713aSLionel Sambuc void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
5729f4a2713aSLionel Sambuc VisitArrayTypeLoc(TL);
5730f4a2713aSLionel Sambuc }
VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL)5731f4a2713aSLionel Sambuc void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
5732f4a2713aSLionel Sambuc VisitArrayTypeLoc(TL);
5733f4a2713aSLionel Sambuc }
VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL)5734f4a2713aSLionel Sambuc void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
5735f4a2713aSLionel Sambuc VisitArrayTypeLoc(TL);
5736f4a2713aSLionel Sambuc }
VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL)5737f4a2713aSLionel Sambuc void TypeLocReader::VisitDependentSizedArrayTypeLoc(
5738f4a2713aSLionel Sambuc DependentSizedArrayTypeLoc TL) {
5739f4a2713aSLionel Sambuc VisitArrayTypeLoc(TL);
5740f4a2713aSLionel Sambuc }
VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL)5741f4a2713aSLionel Sambuc void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
5742f4a2713aSLionel Sambuc DependentSizedExtVectorTypeLoc TL) {
5743f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5744f4a2713aSLionel Sambuc }
VisitVectorTypeLoc(VectorTypeLoc TL)5745f4a2713aSLionel Sambuc void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
5746f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5747f4a2713aSLionel Sambuc }
VisitExtVectorTypeLoc(ExtVectorTypeLoc TL)5748f4a2713aSLionel Sambuc void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
5749f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5750f4a2713aSLionel Sambuc }
VisitFunctionTypeLoc(FunctionTypeLoc TL)5751f4a2713aSLionel Sambuc void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
5752f4a2713aSLionel Sambuc TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx));
5753f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5754f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5755f4a2713aSLionel Sambuc TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));
5756*0a6a1f1dSLionel Sambuc for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) {
5757*0a6a1f1dSLionel Sambuc TL.setParam(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
5758f4a2713aSLionel Sambuc }
5759f4a2713aSLionel Sambuc }
VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL)5760f4a2713aSLionel Sambuc void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
5761f4a2713aSLionel Sambuc VisitFunctionTypeLoc(TL);
5762f4a2713aSLionel Sambuc }
VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL)5763f4a2713aSLionel Sambuc void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
5764f4a2713aSLionel Sambuc VisitFunctionTypeLoc(TL);
5765f4a2713aSLionel Sambuc }
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)5766f4a2713aSLionel Sambuc void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
5767f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5768f4a2713aSLionel Sambuc }
VisitTypedefTypeLoc(TypedefTypeLoc TL)5769f4a2713aSLionel Sambuc void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
5770f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5771f4a2713aSLionel Sambuc }
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)5772f4a2713aSLionel Sambuc void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
5773f4a2713aSLionel Sambuc TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
5774f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5775f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5776f4a2713aSLionel Sambuc }
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)5777f4a2713aSLionel Sambuc void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
5778f4a2713aSLionel Sambuc TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
5779f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5780f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5781f4a2713aSLionel Sambuc TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
5782f4a2713aSLionel Sambuc }
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)5783f4a2713aSLionel Sambuc void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
5784f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5785f4a2713aSLionel Sambuc }
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)5786f4a2713aSLionel Sambuc void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
5787f4a2713aSLionel Sambuc TL.setKWLoc(ReadSourceLocation(Record, Idx));
5788f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5789f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5790f4a2713aSLionel Sambuc TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
5791f4a2713aSLionel Sambuc }
VisitAutoTypeLoc(AutoTypeLoc TL)5792f4a2713aSLionel Sambuc void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
5793f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5794f4a2713aSLionel Sambuc }
VisitRecordTypeLoc(RecordTypeLoc TL)5795f4a2713aSLionel Sambuc void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
5796f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5797f4a2713aSLionel Sambuc }
VisitEnumTypeLoc(EnumTypeLoc TL)5798f4a2713aSLionel Sambuc void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
5799f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5800f4a2713aSLionel Sambuc }
VisitAttributedTypeLoc(AttributedTypeLoc TL)5801f4a2713aSLionel Sambuc void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
5802f4a2713aSLionel Sambuc TL.setAttrNameLoc(ReadSourceLocation(Record, Idx));
5803f4a2713aSLionel Sambuc if (TL.hasAttrOperand()) {
5804f4a2713aSLionel Sambuc SourceRange range;
5805f4a2713aSLionel Sambuc range.setBegin(ReadSourceLocation(Record, Idx));
5806f4a2713aSLionel Sambuc range.setEnd(ReadSourceLocation(Record, Idx));
5807f4a2713aSLionel Sambuc TL.setAttrOperandParensRange(range);
5808f4a2713aSLionel Sambuc }
5809f4a2713aSLionel Sambuc if (TL.hasAttrExprOperand()) {
5810f4a2713aSLionel Sambuc if (Record[Idx++])
5811f4a2713aSLionel Sambuc TL.setAttrExprOperand(Reader.ReadExpr(F));
5812f4a2713aSLionel Sambuc else
5813*0a6a1f1dSLionel Sambuc TL.setAttrExprOperand(nullptr);
5814f4a2713aSLionel Sambuc } else if (TL.hasAttrEnumOperand())
5815f4a2713aSLionel Sambuc TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));
5816f4a2713aSLionel Sambuc }
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)5817f4a2713aSLionel Sambuc void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
5818f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5819f4a2713aSLionel Sambuc }
VisitSubstTemplateTypeParmTypeLoc(SubstTemplateTypeParmTypeLoc TL)5820f4a2713aSLionel Sambuc void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
5821f4a2713aSLionel Sambuc SubstTemplateTypeParmTypeLoc TL) {
5822f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5823f4a2713aSLionel Sambuc }
VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc TL)5824f4a2713aSLionel Sambuc void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
5825f4a2713aSLionel Sambuc SubstTemplateTypeParmPackTypeLoc TL) {
5826f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5827f4a2713aSLionel Sambuc }
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)5828f4a2713aSLionel Sambuc void TypeLocReader::VisitTemplateSpecializationTypeLoc(
5829f4a2713aSLionel Sambuc TemplateSpecializationTypeLoc TL) {
5830f4a2713aSLionel Sambuc TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
5831f4a2713aSLionel Sambuc TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
5832f4a2713aSLionel Sambuc TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
5833f4a2713aSLionel Sambuc TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
5834f4a2713aSLionel Sambuc for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
5835f4a2713aSLionel Sambuc TL.setArgLocInfo(i,
5836f4a2713aSLionel Sambuc Reader.GetTemplateArgumentLocInfo(F,
5837f4a2713aSLionel Sambuc TL.getTypePtr()->getArg(i).getKind(),
5838f4a2713aSLionel Sambuc Record, Idx));
5839f4a2713aSLionel Sambuc }
VisitParenTypeLoc(ParenTypeLoc TL)5840f4a2713aSLionel Sambuc void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
5841f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5842f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5843f4a2713aSLionel Sambuc }
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)5844f4a2713aSLionel Sambuc void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
5845f4a2713aSLionel Sambuc TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
5846f4a2713aSLionel Sambuc TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
5847f4a2713aSLionel Sambuc }
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)5848f4a2713aSLionel Sambuc void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
5849f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5850f4a2713aSLionel Sambuc }
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)5851f4a2713aSLionel Sambuc void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
5852f4a2713aSLionel Sambuc TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
5853f4a2713aSLionel Sambuc TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
5854f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5855f4a2713aSLionel Sambuc }
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)5856f4a2713aSLionel Sambuc void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
5857f4a2713aSLionel Sambuc DependentTemplateSpecializationTypeLoc TL) {
5858f4a2713aSLionel Sambuc TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
5859f4a2713aSLionel Sambuc TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
5860f4a2713aSLionel Sambuc TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
5861f4a2713aSLionel Sambuc TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
5862f4a2713aSLionel Sambuc TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
5863f4a2713aSLionel Sambuc TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
5864f4a2713aSLionel Sambuc for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
5865f4a2713aSLionel Sambuc TL.setArgLocInfo(I,
5866f4a2713aSLionel Sambuc Reader.GetTemplateArgumentLocInfo(F,
5867f4a2713aSLionel Sambuc TL.getTypePtr()->getArg(I).getKind(),
5868f4a2713aSLionel Sambuc Record, Idx));
5869f4a2713aSLionel Sambuc }
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)5870f4a2713aSLionel Sambuc void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
5871f4a2713aSLionel Sambuc TL.setEllipsisLoc(ReadSourceLocation(Record, Idx));
5872f4a2713aSLionel Sambuc }
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)5873f4a2713aSLionel Sambuc void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
5874f4a2713aSLionel Sambuc TL.setNameLoc(ReadSourceLocation(Record, Idx));
5875f4a2713aSLionel Sambuc }
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)5876f4a2713aSLionel Sambuc void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
5877f4a2713aSLionel Sambuc TL.setHasBaseTypeAsWritten(Record[Idx++]);
5878f4a2713aSLionel Sambuc TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
5879f4a2713aSLionel Sambuc TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
5880f4a2713aSLionel Sambuc for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
5881f4a2713aSLionel Sambuc TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
5882f4a2713aSLionel Sambuc }
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)5883f4a2713aSLionel Sambuc void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
5884f4a2713aSLionel Sambuc TL.setStarLoc(ReadSourceLocation(Record, Idx));
5885f4a2713aSLionel Sambuc }
VisitAtomicTypeLoc(AtomicTypeLoc TL)5886f4a2713aSLionel Sambuc void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
5887f4a2713aSLionel Sambuc TL.setKWLoc(ReadSourceLocation(Record, Idx));
5888f4a2713aSLionel Sambuc TL.setLParenLoc(ReadSourceLocation(Record, Idx));
5889f4a2713aSLionel Sambuc TL.setRParenLoc(ReadSourceLocation(Record, Idx));
5890f4a2713aSLionel Sambuc }
5891f4a2713aSLionel Sambuc
GetTypeSourceInfo(ModuleFile & F,const RecordData & Record,unsigned & Idx)5892f4a2713aSLionel Sambuc TypeSourceInfo *ASTReader::GetTypeSourceInfo(ModuleFile &F,
5893f4a2713aSLionel Sambuc const RecordData &Record,
5894f4a2713aSLionel Sambuc unsigned &Idx) {
5895f4a2713aSLionel Sambuc QualType InfoTy = readType(F, Record, Idx);
5896f4a2713aSLionel Sambuc if (InfoTy.isNull())
5897*0a6a1f1dSLionel Sambuc return nullptr;
5898f4a2713aSLionel Sambuc
5899f4a2713aSLionel Sambuc TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
5900f4a2713aSLionel Sambuc TypeLocReader TLR(*this, F, Record, Idx);
5901f4a2713aSLionel Sambuc for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
5902f4a2713aSLionel Sambuc TLR.Visit(TL);
5903f4a2713aSLionel Sambuc return TInfo;
5904f4a2713aSLionel Sambuc }
5905f4a2713aSLionel Sambuc
GetType(TypeID ID)5906f4a2713aSLionel Sambuc QualType ASTReader::GetType(TypeID ID) {
5907f4a2713aSLionel Sambuc unsigned FastQuals = ID & Qualifiers::FastMask;
5908f4a2713aSLionel Sambuc unsigned Index = ID >> Qualifiers::FastWidth;
5909f4a2713aSLionel Sambuc
5910f4a2713aSLionel Sambuc if (Index < NUM_PREDEF_TYPE_IDS) {
5911f4a2713aSLionel Sambuc QualType T;
5912f4a2713aSLionel Sambuc switch ((PredefinedTypeIDs)Index) {
5913f4a2713aSLionel Sambuc case PREDEF_TYPE_NULL_ID: return QualType();
5914f4a2713aSLionel Sambuc case PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break;
5915f4a2713aSLionel Sambuc case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break;
5916f4a2713aSLionel Sambuc
5917f4a2713aSLionel Sambuc case PREDEF_TYPE_CHAR_U_ID:
5918f4a2713aSLionel Sambuc case PREDEF_TYPE_CHAR_S_ID:
5919f4a2713aSLionel Sambuc // FIXME: Check that the signedness of CharTy is correct!
5920f4a2713aSLionel Sambuc T = Context.CharTy;
5921f4a2713aSLionel Sambuc break;
5922f4a2713aSLionel Sambuc
5923f4a2713aSLionel Sambuc case PREDEF_TYPE_UCHAR_ID: T = Context.UnsignedCharTy; break;
5924f4a2713aSLionel Sambuc case PREDEF_TYPE_USHORT_ID: T = Context.UnsignedShortTy; break;
5925f4a2713aSLionel Sambuc case PREDEF_TYPE_UINT_ID: T = Context.UnsignedIntTy; break;
5926f4a2713aSLionel Sambuc case PREDEF_TYPE_ULONG_ID: T = Context.UnsignedLongTy; break;
5927f4a2713aSLionel Sambuc case PREDEF_TYPE_ULONGLONG_ID: T = Context.UnsignedLongLongTy; break;
5928f4a2713aSLionel Sambuc case PREDEF_TYPE_UINT128_ID: T = Context.UnsignedInt128Ty; break;
5929f4a2713aSLionel Sambuc case PREDEF_TYPE_SCHAR_ID: T = Context.SignedCharTy; break;
5930f4a2713aSLionel Sambuc case PREDEF_TYPE_WCHAR_ID: T = Context.WCharTy; break;
5931f4a2713aSLionel Sambuc case PREDEF_TYPE_SHORT_ID: T = Context.ShortTy; break;
5932f4a2713aSLionel Sambuc case PREDEF_TYPE_INT_ID: T = Context.IntTy; break;
5933f4a2713aSLionel Sambuc case PREDEF_TYPE_LONG_ID: T = Context.LongTy; break;
5934f4a2713aSLionel Sambuc case PREDEF_TYPE_LONGLONG_ID: T = Context.LongLongTy; break;
5935f4a2713aSLionel Sambuc case PREDEF_TYPE_INT128_ID: T = Context.Int128Ty; break;
5936f4a2713aSLionel Sambuc case PREDEF_TYPE_HALF_ID: T = Context.HalfTy; break;
5937f4a2713aSLionel Sambuc case PREDEF_TYPE_FLOAT_ID: T = Context.FloatTy; break;
5938f4a2713aSLionel Sambuc case PREDEF_TYPE_DOUBLE_ID: T = Context.DoubleTy; break;
5939f4a2713aSLionel Sambuc case PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy; break;
5940f4a2713aSLionel Sambuc case PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break;
5941f4a2713aSLionel Sambuc case PREDEF_TYPE_BOUND_MEMBER: T = Context.BoundMemberTy; break;
5942f4a2713aSLionel Sambuc case PREDEF_TYPE_PSEUDO_OBJECT: T = Context.PseudoObjectTy; break;
5943f4a2713aSLionel Sambuc case PREDEF_TYPE_DEPENDENT_ID: T = Context.DependentTy; break;
5944f4a2713aSLionel Sambuc case PREDEF_TYPE_UNKNOWN_ANY: T = Context.UnknownAnyTy; break;
5945f4a2713aSLionel Sambuc case PREDEF_TYPE_NULLPTR_ID: T = Context.NullPtrTy; break;
5946f4a2713aSLionel Sambuc case PREDEF_TYPE_CHAR16_ID: T = Context.Char16Ty; break;
5947f4a2713aSLionel Sambuc case PREDEF_TYPE_CHAR32_ID: T = Context.Char32Ty; break;
5948f4a2713aSLionel Sambuc case PREDEF_TYPE_OBJC_ID: T = Context.ObjCBuiltinIdTy; break;
5949f4a2713aSLionel Sambuc case PREDEF_TYPE_OBJC_CLASS: T = Context.ObjCBuiltinClassTy; break;
5950f4a2713aSLionel Sambuc case PREDEF_TYPE_OBJC_SEL: T = Context.ObjCBuiltinSelTy; break;
5951f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE1D_ID: T = Context.OCLImage1dTy; break;
5952f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE1D_ARR_ID: T = Context.OCLImage1dArrayTy; break;
5953f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE1D_BUFF_ID: T = Context.OCLImage1dBufferTy; break;
5954f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE2D_ID: T = Context.OCLImage2dTy; break;
5955f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE2D_ARR_ID: T = Context.OCLImage2dArrayTy; break;
5956f4a2713aSLionel Sambuc case PREDEF_TYPE_IMAGE3D_ID: T = Context.OCLImage3dTy; break;
5957f4a2713aSLionel Sambuc case PREDEF_TYPE_SAMPLER_ID: T = Context.OCLSamplerTy; break;
5958f4a2713aSLionel Sambuc case PREDEF_TYPE_EVENT_ID: T = Context.OCLEventTy; break;
5959f4a2713aSLionel Sambuc case PREDEF_TYPE_AUTO_DEDUCT: T = Context.getAutoDeductType(); break;
5960f4a2713aSLionel Sambuc
5961f4a2713aSLionel Sambuc case PREDEF_TYPE_AUTO_RREF_DEDUCT:
5962f4a2713aSLionel Sambuc T = Context.getAutoRRefDeductType();
5963f4a2713aSLionel Sambuc break;
5964f4a2713aSLionel Sambuc
5965f4a2713aSLionel Sambuc case PREDEF_TYPE_ARC_UNBRIDGED_CAST:
5966f4a2713aSLionel Sambuc T = Context.ARCUnbridgedCastTy;
5967f4a2713aSLionel Sambuc break;
5968f4a2713aSLionel Sambuc
5969f4a2713aSLionel Sambuc case PREDEF_TYPE_VA_LIST_TAG:
5970f4a2713aSLionel Sambuc T = Context.getVaListTagType();
5971f4a2713aSLionel Sambuc break;
5972f4a2713aSLionel Sambuc
5973f4a2713aSLionel Sambuc case PREDEF_TYPE_BUILTIN_FN:
5974f4a2713aSLionel Sambuc T = Context.BuiltinFnTy;
5975f4a2713aSLionel Sambuc break;
5976f4a2713aSLionel Sambuc }
5977f4a2713aSLionel Sambuc
5978f4a2713aSLionel Sambuc assert(!T.isNull() && "Unknown predefined type");
5979f4a2713aSLionel Sambuc return T.withFastQualifiers(FastQuals);
5980f4a2713aSLionel Sambuc }
5981f4a2713aSLionel Sambuc
5982f4a2713aSLionel Sambuc Index -= NUM_PREDEF_TYPE_IDS;
5983f4a2713aSLionel Sambuc assert(Index < TypesLoaded.size() && "Type index out-of-range");
5984f4a2713aSLionel Sambuc if (TypesLoaded[Index].isNull()) {
5985f4a2713aSLionel Sambuc TypesLoaded[Index] = readTypeRecord(Index);
5986f4a2713aSLionel Sambuc if (TypesLoaded[Index].isNull())
5987f4a2713aSLionel Sambuc return QualType();
5988f4a2713aSLionel Sambuc
5989f4a2713aSLionel Sambuc TypesLoaded[Index]->setFromAST();
5990f4a2713aSLionel Sambuc if (DeserializationListener)
5991f4a2713aSLionel Sambuc DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
5992f4a2713aSLionel Sambuc TypesLoaded[Index]);
5993f4a2713aSLionel Sambuc }
5994f4a2713aSLionel Sambuc
5995f4a2713aSLionel Sambuc return TypesLoaded[Index].withFastQualifiers(FastQuals);
5996f4a2713aSLionel Sambuc }
5997f4a2713aSLionel Sambuc
getLocalType(ModuleFile & F,unsigned LocalID)5998f4a2713aSLionel Sambuc QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) {
5999f4a2713aSLionel Sambuc return GetType(getGlobalTypeID(F, LocalID));
6000f4a2713aSLionel Sambuc }
6001f4a2713aSLionel Sambuc
6002f4a2713aSLionel Sambuc serialization::TypeID
getGlobalTypeID(ModuleFile & F,unsigned LocalID) const6003f4a2713aSLionel Sambuc ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {
6004f4a2713aSLionel Sambuc unsigned FastQuals = LocalID & Qualifiers::FastMask;
6005f4a2713aSLionel Sambuc unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
6006f4a2713aSLionel Sambuc
6007f4a2713aSLionel Sambuc if (LocalIndex < NUM_PREDEF_TYPE_IDS)
6008f4a2713aSLionel Sambuc return LocalID;
6009f4a2713aSLionel Sambuc
6010f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
6011f4a2713aSLionel Sambuc = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
6012f4a2713aSLionel Sambuc assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
6013f4a2713aSLionel Sambuc
6014f4a2713aSLionel Sambuc unsigned GlobalIndex = LocalIndex + I->second;
6015f4a2713aSLionel Sambuc return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
6016f4a2713aSLionel Sambuc }
6017f4a2713aSLionel Sambuc
6018f4a2713aSLionel Sambuc TemplateArgumentLocInfo
GetTemplateArgumentLocInfo(ModuleFile & F,TemplateArgument::ArgKind Kind,const RecordData & Record,unsigned & Index)6019f4a2713aSLionel Sambuc ASTReader::GetTemplateArgumentLocInfo(ModuleFile &F,
6020f4a2713aSLionel Sambuc TemplateArgument::ArgKind Kind,
6021f4a2713aSLionel Sambuc const RecordData &Record,
6022f4a2713aSLionel Sambuc unsigned &Index) {
6023f4a2713aSLionel Sambuc switch (Kind) {
6024f4a2713aSLionel Sambuc case TemplateArgument::Expression:
6025f4a2713aSLionel Sambuc return ReadExpr(F);
6026f4a2713aSLionel Sambuc case TemplateArgument::Type:
6027f4a2713aSLionel Sambuc return GetTypeSourceInfo(F, Record, Index);
6028f4a2713aSLionel Sambuc case TemplateArgument::Template: {
6029f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
6030f4a2713aSLionel Sambuc Index);
6031f4a2713aSLionel Sambuc SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
6032f4a2713aSLionel Sambuc return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
6033f4a2713aSLionel Sambuc SourceLocation());
6034f4a2713aSLionel Sambuc }
6035f4a2713aSLionel Sambuc case TemplateArgument::TemplateExpansion: {
6036f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
6037f4a2713aSLionel Sambuc Index);
6038f4a2713aSLionel Sambuc SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
6039f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
6040f4a2713aSLionel Sambuc return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
6041f4a2713aSLionel Sambuc EllipsisLoc);
6042f4a2713aSLionel Sambuc }
6043f4a2713aSLionel Sambuc case TemplateArgument::Null:
6044f4a2713aSLionel Sambuc case TemplateArgument::Integral:
6045f4a2713aSLionel Sambuc case TemplateArgument::Declaration:
6046f4a2713aSLionel Sambuc case TemplateArgument::NullPtr:
6047f4a2713aSLionel Sambuc case TemplateArgument::Pack:
6048f4a2713aSLionel Sambuc // FIXME: Is this right?
6049f4a2713aSLionel Sambuc return TemplateArgumentLocInfo();
6050f4a2713aSLionel Sambuc }
6051f4a2713aSLionel Sambuc llvm_unreachable("unexpected template argument loc");
6052f4a2713aSLionel Sambuc }
6053f4a2713aSLionel Sambuc
6054f4a2713aSLionel Sambuc TemplateArgumentLoc
ReadTemplateArgumentLoc(ModuleFile & F,const RecordData & Record,unsigned & Index)6055f4a2713aSLionel Sambuc ASTReader::ReadTemplateArgumentLoc(ModuleFile &F,
6056f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Index) {
6057f4a2713aSLionel Sambuc TemplateArgument Arg = ReadTemplateArgument(F, Record, Index);
6058f4a2713aSLionel Sambuc
6059f4a2713aSLionel Sambuc if (Arg.getKind() == TemplateArgument::Expression) {
6060f4a2713aSLionel Sambuc if (Record[Index++]) // bool InfoHasSameExpr.
6061f4a2713aSLionel Sambuc return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
6062f4a2713aSLionel Sambuc }
6063f4a2713aSLionel Sambuc return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(F, Arg.getKind(),
6064f4a2713aSLionel Sambuc Record, Index));
6065f4a2713aSLionel Sambuc }
6066f4a2713aSLionel Sambuc
6067f4a2713aSLionel Sambuc const ASTTemplateArgumentListInfo*
ReadASTTemplateArgumentListInfo(ModuleFile & F,const RecordData & Record,unsigned & Index)6068f4a2713aSLionel Sambuc ASTReader::ReadASTTemplateArgumentListInfo(ModuleFile &F,
6069f4a2713aSLionel Sambuc const RecordData &Record,
6070f4a2713aSLionel Sambuc unsigned &Index) {
6071f4a2713aSLionel Sambuc SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Index);
6072f4a2713aSLionel Sambuc SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Index);
6073f4a2713aSLionel Sambuc unsigned NumArgsAsWritten = Record[Index++];
6074f4a2713aSLionel Sambuc TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
6075f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumArgsAsWritten; ++i)
6076f4a2713aSLionel Sambuc TemplArgsInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Index));
6077f4a2713aSLionel Sambuc return ASTTemplateArgumentListInfo::Create(getContext(), TemplArgsInfo);
6078f4a2713aSLionel Sambuc }
6079f4a2713aSLionel Sambuc
GetExternalDecl(uint32_t ID)6080f4a2713aSLionel Sambuc Decl *ASTReader::GetExternalDecl(uint32_t ID) {
6081f4a2713aSLionel Sambuc return GetDecl(ID);
6082f4a2713aSLionel Sambuc }
6083f4a2713aSLionel Sambuc
CompleteRedeclChain(const Decl * D)6084*0a6a1f1dSLionel Sambuc void ASTReader::CompleteRedeclChain(const Decl *D) {
6085*0a6a1f1dSLionel Sambuc if (NumCurrentElementsDeserializing) {
6086*0a6a1f1dSLionel Sambuc // We arrange to not care about the complete redeclaration chain while we're
6087*0a6a1f1dSLionel Sambuc // deserializing. Just remember that the AST has marked this one as complete
6088*0a6a1f1dSLionel Sambuc // but that it's not actually complete yet, so we know we still need to
6089*0a6a1f1dSLionel Sambuc // complete it later.
6090*0a6a1f1dSLionel Sambuc PendingIncompleteDeclChains.push_back(const_cast<Decl*>(D));
6091*0a6a1f1dSLionel Sambuc return;
6092*0a6a1f1dSLionel Sambuc }
6093*0a6a1f1dSLionel Sambuc
6094*0a6a1f1dSLionel Sambuc const DeclContext *DC = D->getDeclContext()->getRedeclContext();
6095*0a6a1f1dSLionel Sambuc
6096*0a6a1f1dSLionel Sambuc // If this is a named declaration, complete it by looking it up
6097*0a6a1f1dSLionel Sambuc // within its context.
6098*0a6a1f1dSLionel Sambuc //
6099*0a6a1f1dSLionel Sambuc // FIXME: Merging a function definition should merge
6100*0a6a1f1dSLionel Sambuc // all mergeable entities within it.
6101*0a6a1f1dSLionel Sambuc if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
6102*0a6a1f1dSLionel Sambuc isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
6103*0a6a1f1dSLionel Sambuc if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
6104*0a6a1f1dSLionel Sambuc auto *II = Name.getAsIdentifierInfo();
6105*0a6a1f1dSLionel Sambuc if (isa<TranslationUnitDecl>(DC) && II) {
6106*0a6a1f1dSLionel Sambuc // Outside of C++, we don't have a lookup table for the TU, so update
6107*0a6a1f1dSLionel Sambuc // the identifier instead. In C++, either way should work fine.
6108*0a6a1f1dSLionel Sambuc if (II->isOutOfDate())
6109*0a6a1f1dSLionel Sambuc updateOutOfDateIdentifier(*II);
6110*0a6a1f1dSLionel Sambuc } else
6111*0a6a1f1dSLionel Sambuc DC->lookup(Name);
6112*0a6a1f1dSLionel Sambuc } else if (needsAnonymousDeclarationNumber(cast<NamedDecl>(D))) {
6113*0a6a1f1dSLionel Sambuc // FIXME: It'd be nice to do something a bit more targeted here.
6114*0a6a1f1dSLionel Sambuc D->getDeclContext()->decls_begin();
6115*0a6a1f1dSLionel Sambuc }
6116*0a6a1f1dSLionel Sambuc }
6117*0a6a1f1dSLionel Sambuc }
6118*0a6a1f1dSLionel Sambuc
readCXXBaseSpecifiers(ModuleFile & M,const RecordData & Record,unsigned & Idx)6119*0a6a1f1dSLionel Sambuc uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M,
6120*0a6a1f1dSLionel Sambuc const RecordData &Record,
6121f4a2713aSLionel Sambuc unsigned &Idx) {
6122*0a6a1f1dSLionel Sambuc if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXBaseSpecifiers) {
6123*0a6a1f1dSLionel Sambuc Error("malformed AST file: missing C++ base specifier");
6124f4a2713aSLionel Sambuc return 0;
6125*0a6a1f1dSLionel Sambuc }
6126f4a2713aSLionel Sambuc
6127f4a2713aSLionel Sambuc unsigned LocalID = Record[Idx++];
6128f4a2713aSLionel Sambuc return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
6129f4a2713aSLionel Sambuc }
6130f4a2713aSLionel Sambuc
GetExternalCXXBaseSpecifiers(uint64_t Offset)6131f4a2713aSLionel Sambuc CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
6132f4a2713aSLionel Sambuc RecordLocation Loc = getLocalBitOffset(Offset);
6133f4a2713aSLionel Sambuc BitstreamCursor &Cursor = Loc.F->DeclsCursor;
6134f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
6135f4a2713aSLionel Sambuc Cursor.JumpToBit(Loc.Offset);
6136f4a2713aSLionel Sambuc ReadingKindTracker ReadingKind(Read_Decl, *this);
6137f4a2713aSLionel Sambuc RecordData Record;
6138f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
6139f4a2713aSLionel Sambuc unsigned RecCode = Cursor.readRecord(Code, Record);
6140f4a2713aSLionel Sambuc if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
6141*0a6a1f1dSLionel Sambuc Error("malformed AST file: missing C++ base specifiers");
6142*0a6a1f1dSLionel Sambuc return nullptr;
6143f4a2713aSLionel Sambuc }
6144f4a2713aSLionel Sambuc
6145f4a2713aSLionel Sambuc unsigned Idx = 0;
6146f4a2713aSLionel Sambuc unsigned NumBases = Record[Idx++];
6147f4a2713aSLionel Sambuc void *Mem = Context.Allocate(sizeof(CXXBaseSpecifier) * NumBases);
6148f4a2713aSLionel Sambuc CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases];
6149f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumBases; ++I)
6150f4a2713aSLionel Sambuc Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx);
6151f4a2713aSLionel Sambuc return Bases;
6152f4a2713aSLionel Sambuc }
6153f4a2713aSLionel Sambuc
6154f4a2713aSLionel Sambuc serialization::DeclID
getGlobalDeclID(ModuleFile & F,LocalDeclID LocalID) const6155f4a2713aSLionel Sambuc ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
6156f4a2713aSLionel Sambuc if (LocalID < NUM_PREDEF_DECL_IDS)
6157f4a2713aSLionel Sambuc return LocalID;
6158f4a2713aSLionel Sambuc
6159f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
6160f4a2713aSLionel Sambuc = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
6161f4a2713aSLionel Sambuc assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
6162f4a2713aSLionel Sambuc
6163f4a2713aSLionel Sambuc return LocalID + I->second;
6164f4a2713aSLionel Sambuc }
6165f4a2713aSLionel Sambuc
isDeclIDFromModule(serialization::GlobalDeclID ID,ModuleFile & M) const6166f4a2713aSLionel Sambuc bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
6167f4a2713aSLionel Sambuc ModuleFile &M) const {
6168f4a2713aSLionel Sambuc GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);
6169f4a2713aSLionel Sambuc assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
6170f4a2713aSLionel Sambuc return &M == I->second;
6171f4a2713aSLionel Sambuc }
6172f4a2713aSLionel Sambuc
getOwningModuleFile(const Decl * D)6173f4a2713aSLionel Sambuc ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
6174f4a2713aSLionel Sambuc if (!D->isFromASTFile())
6175*0a6a1f1dSLionel Sambuc return nullptr;
6176f4a2713aSLionel Sambuc GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
6177f4a2713aSLionel Sambuc assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
6178f4a2713aSLionel Sambuc return I->second;
6179f4a2713aSLionel Sambuc }
6180f4a2713aSLionel Sambuc
getSourceLocationForDeclID(GlobalDeclID ID)6181f4a2713aSLionel Sambuc SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
6182f4a2713aSLionel Sambuc if (ID < NUM_PREDEF_DECL_IDS)
6183f4a2713aSLionel Sambuc return SourceLocation();
6184f4a2713aSLionel Sambuc
6185f4a2713aSLionel Sambuc unsigned Index = ID - NUM_PREDEF_DECL_IDS;
6186f4a2713aSLionel Sambuc
6187f4a2713aSLionel Sambuc if (Index > DeclsLoaded.size()) {
6188f4a2713aSLionel Sambuc Error("declaration ID out-of-range for AST file");
6189f4a2713aSLionel Sambuc return SourceLocation();
6190f4a2713aSLionel Sambuc }
6191f4a2713aSLionel Sambuc
6192f4a2713aSLionel Sambuc if (Decl *D = DeclsLoaded[Index])
6193f4a2713aSLionel Sambuc return D->getLocation();
6194f4a2713aSLionel Sambuc
6195f4a2713aSLionel Sambuc unsigned RawLocation = 0;
6196f4a2713aSLionel Sambuc RecordLocation Rec = DeclCursorForID(ID, RawLocation);
6197f4a2713aSLionel Sambuc return ReadSourceLocation(*Rec.F, RawLocation);
6198f4a2713aSLionel Sambuc }
6199f4a2713aSLionel Sambuc
GetExistingDecl(DeclID ID)6200*0a6a1f1dSLionel Sambuc Decl *ASTReader::GetExistingDecl(DeclID ID) {
6201f4a2713aSLionel Sambuc if (ID < NUM_PREDEF_DECL_IDS) {
6202f4a2713aSLionel Sambuc switch ((PredefinedDeclIDs)ID) {
6203f4a2713aSLionel Sambuc case PREDEF_DECL_NULL_ID:
6204*0a6a1f1dSLionel Sambuc return nullptr;
6205f4a2713aSLionel Sambuc
6206f4a2713aSLionel Sambuc case PREDEF_DECL_TRANSLATION_UNIT_ID:
6207f4a2713aSLionel Sambuc return Context.getTranslationUnitDecl();
6208f4a2713aSLionel Sambuc
6209f4a2713aSLionel Sambuc case PREDEF_DECL_OBJC_ID_ID:
6210f4a2713aSLionel Sambuc return Context.getObjCIdDecl();
6211f4a2713aSLionel Sambuc
6212f4a2713aSLionel Sambuc case PREDEF_DECL_OBJC_SEL_ID:
6213f4a2713aSLionel Sambuc return Context.getObjCSelDecl();
6214f4a2713aSLionel Sambuc
6215f4a2713aSLionel Sambuc case PREDEF_DECL_OBJC_CLASS_ID:
6216f4a2713aSLionel Sambuc return Context.getObjCClassDecl();
6217f4a2713aSLionel Sambuc
6218f4a2713aSLionel Sambuc case PREDEF_DECL_OBJC_PROTOCOL_ID:
6219f4a2713aSLionel Sambuc return Context.getObjCProtocolDecl();
6220f4a2713aSLionel Sambuc
6221f4a2713aSLionel Sambuc case PREDEF_DECL_INT_128_ID:
6222f4a2713aSLionel Sambuc return Context.getInt128Decl();
6223f4a2713aSLionel Sambuc
6224f4a2713aSLionel Sambuc case PREDEF_DECL_UNSIGNED_INT_128_ID:
6225f4a2713aSLionel Sambuc return Context.getUInt128Decl();
6226f4a2713aSLionel Sambuc
6227f4a2713aSLionel Sambuc case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
6228f4a2713aSLionel Sambuc return Context.getObjCInstanceTypeDecl();
6229f4a2713aSLionel Sambuc
6230f4a2713aSLionel Sambuc case PREDEF_DECL_BUILTIN_VA_LIST_ID:
6231f4a2713aSLionel Sambuc return Context.getBuiltinVaListDecl();
6232f4a2713aSLionel Sambuc }
6233f4a2713aSLionel Sambuc }
6234f4a2713aSLionel Sambuc
6235f4a2713aSLionel Sambuc unsigned Index = ID - NUM_PREDEF_DECL_IDS;
6236f4a2713aSLionel Sambuc
6237f4a2713aSLionel Sambuc if (Index >= DeclsLoaded.size()) {
6238f4a2713aSLionel Sambuc assert(0 && "declaration ID out-of-range for AST file");
6239f4a2713aSLionel Sambuc Error("declaration ID out-of-range for AST file");
6240*0a6a1f1dSLionel Sambuc return nullptr;
6241*0a6a1f1dSLionel Sambuc }
6242*0a6a1f1dSLionel Sambuc
6243*0a6a1f1dSLionel Sambuc return DeclsLoaded[Index];
6244*0a6a1f1dSLionel Sambuc }
6245*0a6a1f1dSLionel Sambuc
GetDecl(DeclID ID)6246*0a6a1f1dSLionel Sambuc Decl *ASTReader::GetDecl(DeclID ID) {
6247*0a6a1f1dSLionel Sambuc if (ID < NUM_PREDEF_DECL_IDS)
6248*0a6a1f1dSLionel Sambuc return GetExistingDecl(ID);
6249*0a6a1f1dSLionel Sambuc
6250*0a6a1f1dSLionel Sambuc unsigned Index = ID - NUM_PREDEF_DECL_IDS;
6251*0a6a1f1dSLionel Sambuc
6252*0a6a1f1dSLionel Sambuc if (Index >= DeclsLoaded.size()) {
6253*0a6a1f1dSLionel Sambuc assert(0 && "declaration ID out-of-range for AST file");
6254*0a6a1f1dSLionel Sambuc Error("declaration ID out-of-range for AST file");
6255*0a6a1f1dSLionel Sambuc return nullptr;
6256f4a2713aSLionel Sambuc }
6257f4a2713aSLionel Sambuc
6258f4a2713aSLionel Sambuc if (!DeclsLoaded[Index]) {
6259f4a2713aSLionel Sambuc ReadDeclRecord(ID);
6260f4a2713aSLionel Sambuc if (DeserializationListener)
6261f4a2713aSLionel Sambuc DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
6262f4a2713aSLionel Sambuc }
6263f4a2713aSLionel Sambuc
6264f4a2713aSLionel Sambuc return DeclsLoaded[Index];
6265f4a2713aSLionel Sambuc }
6266f4a2713aSLionel Sambuc
mapGlobalIDToModuleFileGlobalID(ModuleFile & M,DeclID GlobalID)6267f4a2713aSLionel Sambuc DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
6268f4a2713aSLionel Sambuc DeclID GlobalID) {
6269f4a2713aSLionel Sambuc if (GlobalID < NUM_PREDEF_DECL_IDS)
6270f4a2713aSLionel Sambuc return GlobalID;
6271f4a2713aSLionel Sambuc
6272f4a2713aSLionel Sambuc GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);
6273f4a2713aSLionel Sambuc assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
6274f4a2713aSLionel Sambuc ModuleFile *Owner = I->second;
6275f4a2713aSLionel Sambuc
6276f4a2713aSLionel Sambuc llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos
6277f4a2713aSLionel Sambuc = M.GlobalToLocalDeclIDs.find(Owner);
6278f4a2713aSLionel Sambuc if (Pos == M.GlobalToLocalDeclIDs.end())
6279f4a2713aSLionel Sambuc return 0;
6280f4a2713aSLionel Sambuc
6281f4a2713aSLionel Sambuc return GlobalID - Owner->BaseDeclID + Pos->second;
6282f4a2713aSLionel Sambuc }
6283f4a2713aSLionel Sambuc
ReadDeclID(ModuleFile & F,const RecordData & Record,unsigned & Idx)6284f4a2713aSLionel Sambuc serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F,
6285f4a2713aSLionel Sambuc const RecordData &Record,
6286f4a2713aSLionel Sambuc unsigned &Idx) {
6287f4a2713aSLionel Sambuc if (Idx >= Record.size()) {
6288f4a2713aSLionel Sambuc Error("Corrupted AST file");
6289f4a2713aSLionel Sambuc return 0;
6290f4a2713aSLionel Sambuc }
6291f4a2713aSLionel Sambuc
6292f4a2713aSLionel Sambuc return getGlobalDeclID(F, Record[Idx++]);
6293f4a2713aSLionel Sambuc }
6294f4a2713aSLionel Sambuc
6295f4a2713aSLionel Sambuc /// \brief Resolve the offset of a statement into a statement.
6296f4a2713aSLionel Sambuc ///
6297f4a2713aSLionel Sambuc /// This operation will read a new statement from the external
6298f4a2713aSLionel Sambuc /// source each time it is called, and is meant to be used via a
6299f4a2713aSLionel Sambuc /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
GetExternalDeclStmt(uint64_t Offset)6300f4a2713aSLionel Sambuc Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
6301f4a2713aSLionel Sambuc // Switch case IDs are per Decl.
6302f4a2713aSLionel Sambuc ClearSwitchCaseIDs();
6303f4a2713aSLionel Sambuc
6304f4a2713aSLionel Sambuc // Offset here is a global offset across the entire chain.
6305f4a2713aSLionel Sambuc RecordLocation Loc = getLocalBitOffset(Offset);
6306f4a2713aSLionel Sambuc Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
6307f4a2713aSLionel Sambuc return ReadStmtFromStream(*Loc.F);
6308f4a2713aSLionel Sambuc }
6309f4a2713aSLionel Sambuc
6310f4a2713aSLionel Sambuc namespace {
6311f4a2713aSLionel Sambuc class FindExternalLexicalDeclsVisitor {
6312f4a2713aSLionel Sambuc ASTReader &Reader;
6313f4a2713aSLionel Sambuc const DeclContext *DC;
6314f4a2713aSLionel Sambuc bool (*isKindWeWant)(Decl::Kind);
6315f4a2713aSLionel Sambuc
6316f4a2713aSLionel Sambuc SmallVectorImpl<Decl*> &Decls;
6317f4a2713aSLionel Sambuc bool PredefsVisited[NUM_PREDEF_DECL_IDS];
6318f4a2713aSLionel Sambuc
6319f4a2713aSLionel Sambuc public:
FindExternalLexicalDeclsVisitor(ASTReader & Reader,const DeclContext * DC,bool (* isKindWeWant)(Decl::Kind),SmallVectorImpl<Decl * > & Decls)6320f4a2713aSLionel Sambuc FindExternalLexicalDeclsVisitor(ASTReader &Reader, const DeclContext *DC,
6321f4a2713aSLionel Sambuc bool (*isKindWeWant)(Decl::Kind),
6322f4a2713aSLionel Sambuc SmallVectorImpl<Decl*> &Decls)
6323f4a2713aSLionel Sambuc : Reader(Reader), DC(DC), isKindWeWant(isKindWeWant), Decls(Decls)
6324f4a2713aSLionel Sambuc {
6325f4a2713aSLionel Sambuc for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)
6326f4a2713aSLionel Sambuc PredefsVisited[I] = false;
6327f4a2713aSLionel Sambuc }
6328f4a2713aSLionel Sambuc
visit(ModuleFile & M,bool Preorder,void * UserData)6329f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, bool Preorder, void *UserData) {
6330f4a2713aSLionel Sambuc if (Preorder)
6331f4a2713aSLionel Sambuc return false;
6332f4a2713aSLionel Sambuc
6333f4a2713aSLionel Sambuc FindExternalLexicalDeclsVisitor *This
6334f4a2713aSLionel Sambuc = static_cast<FindExternalLexicalDeclsVisitor *>(UserData);
6335f4a2713aSLionel Sambuc
6336f4a2713aSLionel Sambuc ModuleFile::DeclContextInfosMap::iterator Info
6337f4a2713aSLionel Sambuc = M.DeclContextInfos.find(This->DC);
6338f4a2713aSLionel Sambuc if (Info == M.DeclContextInfos.end() || !Info->second.LexicalDecls)
6339f4a2713aSLionel Sambuc return false;
6340f4a2713aSLionel Sambuc
6341f4a2713aSLionel Sambuc // Load all of the declaration IDs
6342f4a2713aSLionel Sambuc for (const KindDeclIDPair *ID = Info->second.LexicalDecls,
6343f4a2713aSLionel Sambuc *IDE = ID + Info->second.NumLexicalDecls;
6344f4a2713aSLionel Sambuc ID != IDE; ++ID) {
6345f4a2713aSLionel Sambuc if (This->isKindWeWant && !This->isKindWeWant((Decl::Kind)ID->first))
6346f4a2713aSLionel Sambuc continue;
6347f4a2713aSLionel Sambuc
6348f4a2713aSLionel Sambuc // Don't add predefined declarations to the lexical context more
6349f4a2713aSLionel Sambuc // than once.
6350f4a2713aSLionel Sambuc if (ID->second < NUM_PREDEF_DECL_IDS) {
6351f4a2713aSLionel Sambuc if (This->PredefsVisited[ID->second])
6352f4a2713aSLionel Sambuc continue;
6353f4a2713aSLionel Sambuc
6354f4a2713aSLionel Sambuc This->PredefsVisited[ID->second] = true;
6355f4a2713aSLionel Sambuc }
6356f4a2713aSLionel Sambuc
6357f4a2713aSLionel Sambuc if (Decl *D = This->Reader.GetLocalDecl(M, ID->second)) {
6358f4a2713aSLionel Sambuc if (!This->DC->isDeclInLexicalTraversal(D))
6359f4a2713aSLionel Sambuc This->Decls.push_back(D);
6360f4a2713aSLionel Sambuc }
6361f4a2713aSLionel Sambuc }
6362f4a2713aSLionel Sambuc
6363f4a2713aSLionel Sambuc return false;
6364f4a2713aSLionel Sambuc }
6365f4a2713aSLionel Sambuc };
6366f4a2713aSLionel Sambuc }
6367f4a2713aSLionel Sambuc
FindExternalLexicalDecls(const DeclContext * DC,bool (* isKindWeWant)(Decl::Kind),SmallVectorImpl<Decl * > & Decls)6368f4a2713aSLionel Sambuc ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
6369f4a2713aSLionel Sambuc bool (*isKindWeWant)(Decl::Kind),
6370f4a2713aSLionel Sambuc SmallVectorImpl<Decl*> &Decls) {
6371f4a2713aSLionel Sambuc // There might be lexical decls in multiple modules, for the TU at
6372f4a2713aSLionel Sambuc // least. Walk all of the modules in the order they were loaded.
6373f4a2713aSLionel Sambuc FindExternalLexicalDeclsVisitor Visitor(*this, DC, isKindWeWant, Decls);
6374f4a2713aSLionel Sambuc ModuleMgr.visitDepthFirst(&FindExternalLexicalDeclsVisitor::visit, &Visitor);
6375f4a2713aSLionel Sambuc ++NumLexicalDeclContextsRead;
6376f4a2713aSLionel Sambuc return ELR_Success;
6377f4a2713aSLionel Sambuc }
6378f4a2713aSLionel Sambuc
6379f4a2713aSLionel Sambuc namespace {
6380f4a2713aSLionel Sambuc
6381f4a2713aSLionel Sambuc class DeclIDComp {
6382f4a2713aSLionel Sambuc ASTReader &Reader;
6383f4a2713aSLionel Sambuc ModuleFile &Mod;
6384f4a2713aSLionel Sambuc
6385f4a2713aSLionel Sambuc public:
DeclIDComp(ASTReader & Reader,ModuleFile & M)6386f4a2713aSLionel Sambuc DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {}
6387f4a2713aSLionel Sambuc
operator ()(LocalDeclID L,LocalDeclID R) const6388f4a2713aSLionel Sambuc bool operator()(LocalDeclID L, LocalDeclID R) const {
6389f4a2713aSLionel Sambuc SourceLocation LHS = getLocation(L);
6390f4a2713aSLionel Sambuc SourceLocation RHS = getLocation(R);
6391f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
6392f4a2713aSLionel Sambuc }
6393f4a2713aSLionel Sambuc
operator ()(SourceLocation LHS,LocalDeclID R) const6394f4a2713aSLionel Sambuc bool operator()(SourceLocation LHS, LocalDeclID R) const {
6395f4a2713aSLionel Sambuc SourceLocation RHS = getLocation(R);
6396f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
6397f4a2713aSLionel Sambuc }
6398f4a2713aSLionel Sambuc
operator ()(LocalDeclID L,SourceLocation RHS) const6399f4a2713aSLionel Sambuc bool operator()(LocalDeclID L, SourceLocation RHS) const {
6400f4a2713aSLionel Sambuc SourceLocation LHS = getLocation(L);
6401f4a2713aSLionel Sambuc return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
6402f4a2713aSLionel Sambuc }
6403f4a2713aSLionel Sambuc
getLocation(LocalDeclID ID) const6404f4a2713aSLionel Sambuc SourceLocation getLocation(LocalDeclID ID) const {
6405f4a2713aSLionel Sambuc return Reader.getSourceManager().getFileLoc(
6406f4a2713aSLionel Sambuc Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));
6407f4a2713aSLionel Sambuc }
6408f4a2713aSLionel Sambuc };
6409f4a2713aSLionel Sambuc
6410f4a2713aSLionel Sambuc }
6411f4a2713aSLionel Sambuc
FindFileRegionDecls(FileID File,unsigned Offset,unsigned Length,SmallVectorImpl<Decl * > & Decls)6412f4a2713aSLionel Sambuc void ASTReader::FindFileRegionDecls(FileID File,
6413f4a2713aSLionel Sambuc unsigned Offset, unsigned Length,
6414f4a2713aSLionel Sambuc SmallVectorImpl<Decl *> &Decls) {
6415f4a2713aSLionel Sambuc SourceManager &SM = getSourceManager();
6416f4a2713aSLionel Sambuc
6417f4a2713aSLionel Sambuc llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File);
6418f4a2713aSLionel Sambuc if (I == FileDeclIDs.end())
6419f4a2713aSLionel Sambuc return;
6420f4a2713aSLionel Sambuc
6421f4a2713aSLionel Sambuc FileDeclsInfo &DInfo = I->second;
6422f4a2713aSLionel Sambuc if (DInfo.Decls.empty())
6423f4a2713aSLionel Sambuc return;
6424f4a2713aSLionel Sambuc
6425f4a2713aSLionel Sambuc SourceLocation
6426f4a2713aSLionel Sambuc BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);
6427f4a2713aSLionel Sambuc SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);
6428f4a2713aSLionel Sambuc
6429f4a2713aSLionel Sambuc DeclIDComp DIDComp(*this, *DInfo.Mod);
6430f4a2713aSLionel Sambuc ArrayRef<serialization::LocalDeclID>::iterator
6431f4a2713aSLionel Sambuc BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
6432f4a2713aSLionel Sambuc BeginLoc, DIDComp);
6433f4a2713aSLionel Sambuc if (BeginIt != DInfo.Decls.begin())
6434f4a2713aSLionel Sambuc --BeginIt;
6435f4a2713aSLionel Sambuc
6436f4a2713aSLionel Sambuc // If we are pointing at a top-level decl inside an objc container, we need
6437f4a2713aSLionel Sambuc // to backtrack until we find it otherwise we will fail to report that the
6438f4a2713aSLionel Sambuc // region overlaps with an objc container.
6439f4a2713aSLionel Sambuc while (BeginIt != DInfo.Decls.begin() &&
6440f4a2713aSLionel Sambuc GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt))
6441f4a2713aSLionel Sambuc ->isTopLevelDeclInObjCContainer())
6442f4a2713aSLionel Sambuc --BeginIt;
6443f4a2713aSLionel Sambuc
6444f4a2713aSLionel Sambuc ArrayRef<serialization::LocalDeclID>::iterator
6445f4a2713aSLionel Sambuc EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
6446f4a2713aSLionel Sambuc EndLoc, DIDComp);
6447f4a2713aSLionel Sambuc if (EndIt != DInfo.Decls.end())
6448f4a2713aSLionel Sambuc ++EndIt;
6449f4a2713aSLionel Sambuc
6450f4a2713aSLionel Sambuc for (ArrayRef<serialization::LocalDeclID>::iterator
6451f4a2713aSLionel Sambuc DIt = BeginIt; DIt != EndIt; ++DIt)
6452f4a2713aSLionel Sambuc Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
6453f4a2713aSLionel Sambuc }
6454f4a2713aSLionel Sambuc
6455f4a2713aSLionel Sambuc namespace {
6456f4a2713aSLionel Sambuc /// \brief ModuleFile visitor used to perform name lookup into a
6457f4a2713aSLionel Sambuc /// declaration context.
6458f4a2713aSLionel Sambuc class DeclContextNameLookupVisitor {
6459f4a2713aSLionel Sambuc ASTReader &Reader;
6460*0a6a1f1dSLionel Sambuc ArrayRef<const DeclContext *> Contexts;
6461f4a2713aSLionel Sambuc DeclarationName Name;
6462f4a2713aSLionel Sambuc SmallVectorImpl<NamedDecl *> &Decls;
6463f4a2713aSLionel Sambuc
6464f4a2713aSLionel Sambuc public:
DeclContextNameLookupVisitor(ASTReader & Reader,ArrayRef<const DeclContext * > Contexts,DeclarationName Name,SmallVectorImpl<NamedDecl * > & Decls)6465f4a2713aSLionel Sambuc DeclContextNameLookupVisitor(ASTReader &Reader,
6466*0a6a1f1dSLionel Sambuc ArrayRef<const DeclContext *> Contexts,
6467f4a2713aSLionel Sambuc DeclarationName Name,
6468f4a2713aSLionel Sambuc SmallVectorImpl<NamedDecl *> &Decls)
6469f4a2713aSLionel Sambuc : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { }
6470f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)6471f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
6472f4a2713aSLionel Sambuc DeclContextNameLookupVisitor *This
6473f4a2713aSLionel Sambuc = static_cast<DeclContextNameLookupVisitor *>(UserData);
6474f4a2713aSLionel Sambuc
6475f4a2713aSLionel Sambuc // Check whether we have any visible declaration information for
6476f4a2713aSLionel Sambuc // this context in this module.
6477f4a2713aSLionel Sambuc ModuleFile::DeclContextInfosMap::iterator Info;
6478f4a2713aSLionel Sambuc bool FoundInfo = false;
6479*0a6a1f1dSLionel Sambuc for (auto *DC : This->Contexts) {
6480*0a6a1f1dSLionel Sambuc Info = M.DeclContextInfos.find(DC);
6481f4a2713aSLionel Sambuc if (Info != M.DeclContextInfos.end() &&
6482f4a2713aSLionel Sambuc Info->second.NameLookupTableData) {
6483f4a2713aSLionel Sambuc FoundInfo = true;
6484f4a2713aSLionel Sambuc break;
6485f4a2713aSLionel Sambuc }
6486f4a2713aSLionel Sambuc }
6487f4a2713aSLionel Sambuc
6488f4a2713aSLionel Sambuc if (!FoundInfo)
6489f4a2713aSLionel Sambuc return false;
6490f4a2713aSLionel Sambuc
6491f4a2713aSLionel Sambuc // Look for this name within this module.
6492f4a2713aSLionel Sambuc ASTDeclContextNameLookupTable *LookupTable =
6493f4a2713aSLionel Sambuc Info->second.NameLookupTableData;
6494f4a2713aSLionel Sambuc ASTDeclContextNameLookupTable::iterator Pos
6495f4a2713aSLionel Sambuc = LookupTable->find(This->Name);
6496f4a2713aSLionel Sambuc if (Pos == LookupTable->end())
6497f4a2713aSLionel Sambuc return false;
6498f4a2713aSLionel Sambuc
6499f4a2713aSLionel Sambuc bool FoundAnything = false;
6500f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::data_type Data = *Pos;
6501f4a2713aSLionel Sambuc for (; Data.first != Data.second; ++Data.first) {
6502f4a2713aSLionel Sambuc NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
6503f4a2713aSLionel Sambuc if (!ND)
6504f4a2713aSLionel Sambuc continue;
6505f4a2713aSLionel Sambuc
6506f4a2713aSLionel Sambuc if (ND->getDeclName() != This->Name) {
6507f4a2713aSLionel Sambuc // A name might be null because the decl's redeclarable part is
6508f4a2713aSLionel Sambuc // currently read before reading its name. The lookup is triggered by
6509f4a2713aSLionel Sambuc // building that decl (likely indirectly), and so it is later in the
6510f4a2713aSLionel Sambuc // sense of "already existing" and can be ignored here.
6511*0a6a1f1dSLionel Sambuc // FIXME: This should not happen; deserializing declarations should
6512*0a6a1f1dSLionel Sambuc // not perform lookups since that can lead to deserialization cycles.
6513f4a2713aSLionel Sambuc continue;
6514f4a2713aSLionel Sambuc }
6515f4a2713aSLionel Sambuc
6516f4a2713aSLionel Sambuc // Record this declaration.
6517f4a2713aSLionel Sambuc FoundAnything = true;
6518f4a2713aSLionel Sambuc This->Decls.push_back(ND);
6519f4a2713aSLionel Sambuc }
6520f4a2713aSLionel Sambuc
6521f4a2713aSLionel Sambuc return FoundAnything;
6522f4a2713aSLionel Sambuc }
6523f4a2713aSLionel Sambuc };
6524f4a2713aSLionel Sambuc }
6525f4a2713aSLionel Sambuc
6526f4a2713aSLionel Sambuc /// \brief Retrieve the "definitive" module file for the definition of the
6527f4a2713aSLionel Sambuc /// given declaration context, if there is one.
6528f4a2713aSLionel Sambuc ///
6529f4a2713aSLionel Sambuc /// The "definitive" module file is the only place where we need to look to
6530f4a2713aSLionel Sambuc /// find information about the declarations within the given declaration
6531f4a2713aSLionel Sambuc /// context. For example, C++ and Objective-C classes, C structs/unions, and
6532f4a2713aSLionel Sambuc /// Objective-C protocols, categories, and extensions are all defined in a
6533f4a2713aSLionel Sambuc /// single place in the source code, so they have definitive module files
6534f4a2713aSLionel Sambuc /// associated with them. C++ namespaces, on the other hand, can have
6535f4a2713aSLionel Sambuc /// definitions in multiple different module files.
6536f4a2713aSLionel Sambuc ///
6537f4a2713aSLionel Sambuc /// Note: this needs to be kept in sync with ASTWriter::AddedVisibleDecl's
6538f4a2713aSLionel Sambuc /// NDEBUG checking.
getDefinitiveModuleFileFor(const DeclContext * DC,ASTReader & Reader)6539f4a2713aSLionel Sambuc static ModuleFile *getDefinitiveModuleFileFor(const DeclContext *DC,
6540f4a2713aSLionel Sambuc ASTReader &Reader) {
6541f4a2713aSLionel Sambuc if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
6542f4a2713aSLionel Sambuc return Reader.getOwningModuleFile(cast<Decl>(DefDC));
6543f4a2713aSLionel Sambuc
6544*0a6a1f1dSLionel Sambuc return nullptr;
6545f4a2713aSLionel Sambuc }
6546f4a2713aSLionel Sambuc
6547f4a2713aSLionel Sambuc bool
FindExternalVisibleDeclsByName(const DeclContext * DC,DeclarationName Name)6548f4a2713aSLionel Sambuc ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
6549f4a2713aSLionel Sambuc DeclarationName Name) {
6550f4a2713aSLionel Sambuc assert(DC->hasExternalVisibleStorage() &&
6551f4a2713aSLionel Sambuc "DeclContext has no visible decls in storage");
6552f4a2713aSLionel Sambuc if (!Name)
6553f4a2713aSLionel Sambuc return false;
6554f4a2713aSLionel Sambuc
6555*0a6a1f1dSLionel Sambuc Deserializing LookupResults(this);
6556*0a6a1f1dSLionel Sambuc
6557f4a2713aSLionel Sambuc SmallVector<NamedDecl *, 64> Decls;
6558f4a2713aSLionel Sambuc
6559f4a2713aSLionel Sambuc // Compute the declaration contexts we need to look into. Multiple such
6560f4a2713aSLionel Sambuc // declaration contexts occur when two declaration contexts from disjoint
6561f4a2713aSLionel Sambuc // modules get merged, e.g., when two namespaces with the same name are
6562f4a2713aSLionel Sambuc // independently defined in separate modules.
6563f4a2713aSLionel Sambuc SmallVector<const DeclContext *, 2> Contexts;
6564f4a2713aSLionel Sambuc Contexts.push_back(DC);
6565f4a2713aSLionel Sambuc
6566f4a2713aSLionel Sambuc if (DC->isNamespace()) {
6567*0a6a1f1dSLionel Sambuc auto Merged = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
6568f4a2713aSLionel Sambuc if (Merged != MergedDecls.end()) {
6569f4a2713aSLionel Sambuc for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
6570f4a2713aSLionel Sambuc Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
6571f4a2713aSLionel Sambuc }
6572f4a2713aSLionel Sambuc }
6573f4a2713aSLionel Sambuc
6574*0a6a1f1dSLionel Sambuc auto LookUpInContexts = [&](ArrayRef<const DeclContext*> Contexts) {
6575f4a2713aSLionel Sambuc DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);
6576f4a2713aSLionel Sambuc
6577f4a2713aSLionel Sambuc // If we can definitively determine which module file to look into,
6578f4a2713aSLionel Sambuc // only look there. Otherwise, look in all module files.
6579f4a2713aSLionel Sambuc ModuleFile *Definitive;
6580f4a2713aSLionel Sambuc if (Contexts.size() == 1 &&
6581*0a6a1f1dSLionel Sambuc (Definitive = getDefinitiveModuleFileFor(Contexts[0], *this))) {
6582f4a2713aSLionel Sambuc DeclContextNameLookupVisitor::visit(*Definitive, &Visitor);
6583f4a2713aSLionel Sambuc } else {
6584f4a2713aSLionel Sambuc ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
6585f4a2713aSLionel Sambuc }
6586*0a6a1f1dSLionel Sambuc };
6587*0a6a1f1dSLionel Sambuc
6588*0a6a1f1dSLionel Sambuc LookUpInContexts(Contexts);
6589*0a6a1f1dSLionel Sambuc
6590*0a6a1f1dSLionel Sambuc // If this might be an implicit special member function, then also search
6591*0a6a1f1dSLionel Sambuc // all merged definitions of the surrounding class. We need to search them
6592*0a6a1f1dSLionel Sambuc // individually, because finding an entity in one of them doesn't imply that
6593*0a6a1f1dSLionel Sambuc // we can't find a different entity in another one.
6594*0a6a1f1dSLionel Sambuc if (isa<CXXRecordDecl>(DC)) {
6595*0a6a1f1dSLionel Sambuc auto Kind = Name.getNameKind();
6596*0a6a1f1dSLionel Sambuc if (Kind == DeclarationName::CXXConstructorName ||
6597*0a6a1f1dSLionel Sambuc Kind == DeclarationName::CXXDestructorName ||
6598*0a6a1f1dSLionel Sambuc (Kind == DeclarationName::CXXOperatorName &&
6599*0a6a1f1dSLionel Sambuc Name.getCXXOverloadedOperator() == OO_Equal)) {
6600*0a6a1f1dSLionel Sambuc auto Merged = MergedLookups.find(DC);
6601*0a6a1f1dSLionel Sambuc if (Merged != MergedLookups.end()) {
6602*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I != Merged->second.size(); ++I) {
6603*0a6a1f1dSLionel Sambuc LookUpInContexts(Merged->second[I]);
6604*0a6a1f1dSLionel Sambuc // We might have just added some more merged lookups. If so, our
6605*0a6a1f1dSLionel Sambuc // iterator is now invalid, so grab a fresh one before continuing.
6606*0a6a1f1dSLionel Sambuc Merged = MergedLookups.find(DC);
6607*0a6a1f1dSLionel Sambuc }
6608*0a6a1f1dSLionel Sambuc }
6609*0a6a1f1dSLionel Sambuc }
6610*0a6a1f1dSLionel Sambuc }
6611*0a6a1f1dSLionel Sambuc
6612f4a2713aSLionel Sambuc ++NumVisibleDeclContextsRead;
6613f4a2713aSLionel Sambuc SetExternalVisibleDeclsForName(DC, Name, Decls);
6614f4a2713aSLionel Sambuc return !Decls.empty();
6615f4a2713aSLionel Sambuc }
6616f4a2713aSLionel Sambuc
6617f4a2713aSLionel Sambuc namespace {
6618f4a2713aSLionel Sambuc /// \brief ModuleFile visitor used to retrieve all visible names in a
6619f4a2713aSLionel Sambuc /// declaration context.
6620f4a2713aSLionel Sambuc class DeclContextAllNamesVisitor {
6621f4a2713aSLionel Sambuc ASTReader &Reader;
6622f4a2713aSLionel Sambuc SmallVectorImpl<const DeclContext *> &Contexts;
6623f4a2713aSLionel Sambuc DeclsMap &Decls;
6624f4a2713aSLionel Sambuc bool VisitAll;
6625f4a2713aSLionel Sambuc
6626f4a2713aSLionel Sambuc public:
DeclContextAllNamesVisitor(ASTReader & Reader,SmallVectorImpl<const DeclContext * > & Contexts,DeclsMap & Decls,bool VisitAll)6627f4a2713aSLionel Sambuc DeclContextAllNamesVisitor(ASTReader &Reader,
6628f4a2713aSLionel Sambuc SmallVectorImpl<const DeclContext *> &Contexts,
6629f4a2713aSLionel Sambuc DeclsMap &Decls, bool VisitAll)
6630f4a2713aSLionel Sambuc : Reader(Reader), Contexts(Contexts), Decls(Decls), VisitAll(VisitAll) { }
6631f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)6632f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
6633f4a2713aSLionel Sambuc DeclContextAllNamesVisitor *This
6634f4a2713aSLionel Sambuc = static_cast<DeclContextAllNamesVisitor *>(UserData);
6635f4a2713aSLionel Sambuc
6636f4a2713aSLionel Sambuc // Check whether we have any visible declaration information for
6637f4a2713aSLionel Sambuc // this context in this module.
6638f4a2713aSLionel Sambuc ModuleFile::DeclContextInfosMap::iterator Info;
6639f4a2713aSLionel Sambuc bool FoundInfo = false;
6640f4a2713aSLionel Sambuc for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {
6641f4a2713aSLionel Sambuc Info = M.DeclContextInfos.find(This->Contexts[I]);
6642f4a2713aSLionel Sambuc if (Info != M.DeclContextInfos.end() &&
6643f4a2713aSLionel Sambuc Info->second.NameLookupTableData) {
6644f4a2713aSLionel Sambuc FoundInfo = true;
6645f4a2713aSLionel Sambuc break;
6646f4a2713aSLionel Sambuc }
6647f4a2713aSLionel Sambuc }
6648f4a2713aSLionel Sambuc
6649f4a2713aSLionel Sambuc if (!FoundInfo)
6650f4a2713aSLionel Sambuc return false;
6651f4a2713aSLionel Sambuc
6652f4a2713aSLionel Sambuc ASTDeclContextNameLookupTable *LookupTable =
6653f4a2713aSLionel Sambuc Info->second.NameLookupTableData;
6654f4a2713aSLionel Sambuc bool FoundAnything = false;
6655f4a2713aSLionel Sambuc for (ASTDeclContextNameLookupTable::data_iterator
6656f4a2713aSLionel Sambuc I = LookupTable->data_begin(), E = LookupTable->data_end();
6657f4a2713aSLionel Sambuc I != E;
6658f4a2713aSLionel Sambuc ++I) {
6659f4a2713aSLionel Sambuc ASTDeclContextNameLookupTrait::data_type Data = *I;
6660f4a2713aSLionel Sambuc for (; Data.first != Data.second; ++Data.first) {
6661f4a2713aSLionel Sambuc NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M,
6662f4a2713aSLionel Sambuc *Data.first);
6663f4a2713aSLionel Sambuc if (!ND)
6664f4a2713aSLionel Sambuc continue;
6665f4a2713aSLionel Sambuc
6666f4a2713aSLionel Sambuc // Record this declaration.
6667f4a2713aSLionel Sambuc FoundAnything = true;
6668f4a2713aSLionel Sambuc This->Decls[ND->getDeclName()].push_back(ND);
6669f4a2713aSLionel Sambuc }
6670f4a2713aSLionel Sambuc }
6671f4a2713aSLionel Sambuc
6672f4a2713aSLionel Sambuc return FoundAnything && !This->VisitAll;
6673f4a2713aSLionel Sambuc }
6674f4a2713aSLionel Sambuc };
6675f4a2713aSLionel Sambuc }
6676f4a2713aSLionel Sambuc
completeVisibleDeclsMap(const DeclContext * DC)6677f4a2713aSLionel Sambuc void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
6678f4a2713aSLionel Sambuc if (!DC->hasExternalVisibleStorage())
6679f4a2713aSLionel Sambuc return;
6680f4a2713aSLionel Sambuc DeclsMap Decls;
6681f4a2713aSLionel Sambuc
6682f4a2713aSLionel Sambuc // Compute the declaration contexts we need to look into. Multiple such
6683f4a2713aSLionel Sambuc // declaration contexts occur when two declaration contexts from disjoint
6684f4a2713aSLionel Sambuc // modules get merged, e.g., when two namespaces with the same name are
6685f4a2713aSLionel Sambuc // independently defined in separate modules.
6686f4a2713aSLionel Sambuc SmallVector<const DeclContext *, 2> Contexts;
6687f4a2713aSLionel Sambuc Contexts.push_back(DC);
6688f4a2713aSLionel Sambuc
6689f4a2713aSLionel Sambuc if (DC->isNamespace()) {
6690f4a2713aSLionel Sambuc MergedDeclsMap::iterator Merged
6691f4a2713aSLionel Sambuc = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
6692f4a2713aSLionel Sambuc if (Merged != MergedDecls.end()) {
6693f4a2713aSLionel Sambuc for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
6694f4a2713aSLionel Sambuc Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
6695f4a2713aSLionel Sambuc }
6696f4a2713aSLionel Sambuc }
6697f4a2713aSLionel Sambuc
6698f4a2713aSLionel Sambuc DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls,
6699f4a2713aSLionel Sambuc /*VisitAll=*/DC->isFileContext());
6700f4a2713aSLionel Sambuc ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor);
6701f4a2713aSLionel Sambuc ++NumVisibleDeclContextsRead;
6702f4a2713aSLionel Sambuc
6703f4a2713aSLionel Sambuc for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
6704f4a2713aSLionel Sambuc SetExternalVisibleDeclsForName(DC, I->first, I->second);
6705f4a2713aSLionel Sambuc }
6706f4a2713aSLionel Sambuc const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);
6707f4a2713aSLionel Sambuc }
6708f4a2713aSLionel Sambuc
6709f4a2713aSLionel Sambuc /// \brief Under non-PCH compilation the consumer receives the objc methods
6710f4a2713aSLionel Sambuc /// before receiving the implementation, and codegen depends on this.
6711f4a2713aSLionel Sambuc /// We simulate this by deserializing and passing to consumer the methods of the
6712f4a2713aSLionel Sambuc /// implementation before passing the deserialized implementation decl.
PassObjCImplDeclToConsumer(ObjCImplDecl * ImplD,ASTConsumer * Consumer)6713f4a2713aSLionel Sambuc static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
6714f4a2713aSLionel Sambuc ASTConsumer *Consumer) {
6715f4a2713aSLionel Sambuc assert(ImplD && Consumer);
6716f4a2713aSLionel Sambuc
6717*0a6a1f1dSLionel Sambuc for (auto *I : ImplD->methods())
6718*0a6a1f1dSLionel Sambuc Consumer->HandleInterestingDecl(DeclGroupRef(I));
6719f4a2713aSLionel Sambuc
6720f4a2713aSLionel Sambuc Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
6721f4a2713aSLionel Sambuc }
6722f4a2713aSLionel Sambuc
PassInterestingDeclsToConsumer()6723f4a2713aSLionel Sambuc void ASTReader::PassInterestingDeclsToConsumer() {
6724f4a2713aSLionel Sambuc assert(Consumer);
6725*0a6a1f1dSLionel Sambuc
6726*0a6a1f1dSLionel Sambuc if (PassingDeclsToConsumer)
6727*0a6a1f1dSLionel Sambuc return;
6728*0a6a1f1dSLionel Sambuc
6729*0a6a1f1dSLionel Sambuc // Guard variable to avoid recursively redoing the process of passing
6730*0a6a1f1dSLionel Sambuc // decls to consumer.
6731*0a6a1f1dSLionel Sambuc SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
6732*0a6a1f1dSLionel Sambuc true);
6733*0a6a1f1dSLionel Sambuc
6734f4a2713aSLionel Sambuc while (!InterestingDecls.empty()) {
6735f4a2713aSLionel Sambuc Decl *D = InterestingDecls.front();
6736f4a2713aSLionel Sambuc InterestingDecls.pop_front();
6737f4a2713aSLionel Sambuc
6738f4a2713aSLionel Sambuc PassInterestingDeclToConsumer(D);
6739f4a2713aSLionel Sambuc }
6740f4a2713aSLionel Sambuc }
6741f4a2713aSLionel Sambuc
PassInterestingDeclToConsumer(Decl * D)6742f4a2713aSLionel Sambuc void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
6743f4a2713aSLionel Sambuc if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6744f4a2713aSLionel Sambuc PassObjCImplDeclToConsumer(ImplD, Consumer);
6745f4a2713aSLionel Sambuc else
6746f4a2713aSLionel Sambuc Consumer->HandleInterestingDecl(DeclGroupRef(D));
6747f4a2713aSLionel Sambuc }
6748f4a2713aSLionel Sambuc
StartTranslationUnit(ASTConsumer * Consumer)6749f4a2713aSLionel Sambuc void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
6750f4a2713aSLionel Sambuc this->Consumer = Consumer;
6751f4a2713aSLionel Sambuc
6752f4a2713aSLionel Sambuc if (!Consumer)
6753f4a2713aSLionel Sambuc return;
6754f4a2713aSLionel Sambuc
6755*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = EagerlyDeserializedDecls.size(); I != N; ++I) {
6756f4a2713aSLionel Sambuc // Force deserialization of this decl, which will cause it to be queued for
6757f4a2713aSLionel Sambuc // passing to the consumer.
6758*0a6a1f1dSLionel Sambuc GetDecl(EagerlyDeserializedDecls[I]);
6759f4a2713aSLionel Sambuc }
6760*0a6a1f1dSLionel Sambuc EagerlyDeserializedDecls.clear();
6761f4a2713aSLionel Sambuc
6762f4a2713aSLionel Sambuc PassInterestingDeclsToConsumer();
6763f4a2713aSLionel Sambuc }
6764f4a2713aSLionel Sambuc
PrintStats()6765f4a2713aSLionel Sambuc void ASTReader::PrintStats() {
6766f4a2713aSLionel Sambuc std::fprintf(stderr, "*** AST File Statistics:\n");
6767f4a2713aSLionel Sambuc
6768f4a2713aSLionel Sambuc unsigned NumTypesLoaded
6769f4a2713aSLionel Sambuc = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
6770f4a2713aSLionel Sambuc QualType());
6771f4a2713aSLionel Sambuc unsigned NumDeclsLoaded
6772f4a2713aSLionel Sambuc = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
6773*0a6a1f1dSLionel Sambuc (Decl *)nullptr);
6774f4a2713aSLionel Sambuc unsigned NumIdentifiersLoaded
6775f4a2713aSLionel Sambuc = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
6776f4a2713aSLionel Sambuc IdentifiersLoaded.end(),
6777*0a6a1f1dSLionel Sambuc (IdentifierInfo *)nullptr);
6778f4a2713aSLionel Sambuc unsigned NumMacrosLoaded
6779f4a2713aSLionel Sambuc = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
6780f4a2713aSLionel Sambuc MacrosLoaded.end(),
6781*0a6a1f1dSLionel Sambuc (MacroInfo *)nullptr);
6782f4a2713aSLionel Sambuc unsigned NumSelectorsLoaded
6783f4a2713aSLionel Sambuc = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
6784f4a2713aSLionel Sambuc SelectorsLoaded.end(),
6785f4a2713aSLionel Sambuc Selector());
6786f4a2713aSLionel Sambuc
6787f4a2713aSLionel Sambuc if (unsigned TotalNumSLocEntries = getTotalNumSLocs())
6788f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
6789f4a2713aSLionel Sambuc NumSLocEntriesRead, TotalNumSLocEntries,
6790f4a2713aSLionel Sambuc ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
6791f4a2713aSLionel Sambuc if (!TypesLoaded.empty())
6792f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u types read (%f%%)\n",
6793f4a2713aSLionel Sambuc NumTypesLoaded, (unsigned)TypesLoaded.size(),
6794f4a2713aSLionel Sambuc ((float)NumTypesLoaded/TypesLoaded.size() * 100));
6795f4a2713aSLionel Sambuc if (!DeclsLoaded.empty())
6796f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
6797f4a2713aSLionel Sambuc NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
6798f4a2713aSLionel Sambuc ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
6799f4a2713aSLionel Sambuc if (!IdentifiersLoaded.empty())
6800f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
6801f4a2713aSLionel Sambuc NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
6802f4a2713aSLionel Sambuc ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
6803f4a2713aSLionel Sambuc if (!MacrosLoaded.empty())
6804f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
6805f4a2713aSLionel Sambuc NumMacrosLoaded, (unsigned)MacrosLoaded.size(),
6806f4a2713aSLionel Sambuc ((float)NumMacrosLoaded/MacrosLoaded.size() * 100));
6807f4a2713aSLionel Sambuc if (!SelectorsLoaded.empty())
6808f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
6809f4a2713aSLionel Sambuc NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
6810f4a2713aSLionel Sambuc ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
6811f4a2713aSLionel Sambuc if (TotalNumStatements)
6812f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
6813f4a2713aSLionel Sambuc NumStatementsRead, TotalNumStatements,
6814f4a2713aSLionel Sambuc ((float)NumStatementsRead/TotalNumStatements * 100));
6815f4a2713aSLionel Sambuc if (TotalNumMacros)
6816f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
6817f4a2713aSLionel Sambuc NumMacrosRead, TotalNumMacros,
6818f4a2713aSLionel Sambuc ((float)NumMacrosRead/TotalNumMacros * 100));
6819f4a2713aSLionel Sambuc if (TotalLexicalDeclContexts)
6820f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
6821f4a2713aSLionel Sambuc NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
6822f4a2713aSLionel Sambuc ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
6823f4a2713aSLionel Sambuc * 100));
6824f4a2713aSLionel Sambuc if (TotalVisibleDeclContexts)
6825f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
6826f4a2713aSLionel Sambuc NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
6827f4a2713aSLionel Sambuc ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
6828f4a2713aSLionel Sambuc * 100));
6829f4a2713aSLionel Sambuc if (TotalNumMethodPoolEntries) {
6830f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
6831f4a2713aSLionel Sambuc NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
6832f4a2713aSLionel Sambuc ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
6833f4a2713aSLionel Sambuc * 100));
6834f4a2713aSLionel Sambuc }
6835f4a2713aSLionel Sambuc if (NumMethodPoolLookups) {
6836f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u method pool lookups succeeded (%f%%)\n",
6837f4a2713aSLionel Sambuc NumMethodPoolHits, NumMethodPoolLookups,
6838f4a2713aSLionel Sambuc ((float)NumMethodPoolHits/NumMethodPoolLookups * 100.0));
6839f4a2713aSLionel Sambuc }
6840f4a2713aSLionel Sambuc if (NumMethodPoolTableLookups) {
6841f4a2713aSLionel Sambuc std::fprintf(stderr, " %u/%u method pool table lookups succeeded (%f%%)\n",
6842f4a2713aSLionel Sambuc NumMethodPoolTableHits, NumMethodPoolTableLookups,
6843f4a2713aSLionel Sambuc ((float)NumMethodPoolTableHits/NumMethodPoolTableLookups
6844f4a2713aSLionel Sambuc * 100.0));
6845f4a2713aSLionel Sambuc }
6846f4a2713aSLionel Sambuc
6847f4a2713aSLionel Sambuc if (NumIdentifierLookupHits) {
6848f4a2713aSLionel Sambuc std::fprintf(stderr,
6849f4a2713aSLionel Sambuc " %u / %u identifier table lookups succeeded (%f%%)\n",
6850f4a2713aSLionel Sambuc NumIdentifierLookupHits, NumIdentifierLookups,
6851f4a2713aSLionel Sambuc (double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
6852f4a2713aSLionel Sambuc }
6853f4a2713aSLionel Sambuc
6854f4a2713aSLionel Sambuc if (GlobalIndex) {
6855f4a2713aSLionel Sambuc std::fprintf(stderr, "\n");
6856f4a2713aSLionel Sambuc GlobalIndex->printStats();
6857f4a2713aSLionel Sambuc }
6858f4a2713aSLionel Sambuc
6859f4a2713aSLionel Sambuc std::fprintf(stderr, "\n");
6860f4a2713aSLionel Sambuc dump();
6861f4a2713aSLionel Sambuc std::fprintf(stderr, "\n");
6862f4a2713aSLionel Sambuc }
6863f4a2713aSLionel Sambuc
6864f4a2713aSLionel Sambuc template<typename Key, typename ModuleFile, unsigned InitialCapacity>
6865f4a2713aSLionel Sambuc static void
dumpModuleIDMap(StringRef Name,const ContinuousRangeMap<Key,ModuleFile *,InitialCapacity> & Map)6866f4a2713aSLionel Sambuc dumpModuleIDMap(StringRef Name,
6867f4a2713aSLionel Sambuc const ContinuousRangeMap<Key, ModuleFile *,
6868f4a2713aSLionel Sambuc InitialCapacity> &Map) {
6869f4a2713aSLionel Sambuc if (Map.begin() == Map.end())
6870f4a2713aSLionel Sambuc return;
6871f4a2713aSLionel Sambuc
6872f4a2713aSLionel Sambuc typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType;
6873f4a2713aSLionel Sambuc llvm::errs() << Name << ":\n";
6874f4a2713aSLionel Sambuc for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
6875f4a2713aSLionel Sambuc I != IEnd; ++I) {
6876f4a2713aSLionel Sambuc llvm::errs() << " " << I->first << " -> " << I->second->FileName
6877f4a2713aSLionel Sambuc << "\n";
6878f4a2713aSLionel Sambuc }
6879f4a2713aSLionel Sambuc }
6880f4a2713aSLionel Sambuc
dump()6881f4a2713aSLionel Sambuc void ASTReader::dump() {
6882f4a2713aSLionel Sambuc llvm::errs() << "*** PCH/ModuleFile Remappings:\n";
6883f4a2713aSLionel Sambuc dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
6884f4a2713aSLionel Sambuc dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
6885f4a2713aSLionel Sambuc dumpModuleIDMap("Global type map", GlobalTypeMap);
6886f4a2713aSLionel Sambuc dumpModuleIDMap("Global declaration map", GlobalDeclMap);
6887f4a2713aSLionel Sambuc dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
6888f4a2713aSLionel Sambuc dumpModuleIDMap("Global macro map", GlobalMacroMap);
6889f4a2713aSLionel Sambuc dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
6890f4a2713aSLionel Sambuc dumpModuleIDMap("Global selector map", GlobalSelectorMap);
6891f4a2713aSLionel Sambuc dumpModuleIDMap("Global preprocessed entity map",
6892f4a2713aSLionel Sambuc GlobalPreprocessedEntityMap);
6893f4a2713aSLionel Sambuc
6894f4a2713aSLionel Sambuc llvm::errs() << "\n*** PCH/Modules Loaded:";
6895f4a2713aSLionel Sambuc for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(),
6896f4a2713aSLionel Sambuc MEnd = ModuleMgr.end();
6897f4a2713aSLionel Sambuc M != MEnd; ++M)
6898f4a2713aSLionel Sambuc (*M)->dump();
6899f4a2713aSLionel Sambuc }
6900f4a2713aSLionel Sambuc
6901f4a2713aSLionel Sambuc /// Return the amount of memory used by memory buffers, breaking down
6902f4a2713aSLionel Sambuc /// by heap-backed versus mmap'ed memory.
getMemoryBufferSizes(MemoryBufferSizes & sizes) const6903f4a2713aSLionel Sambuc void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
6904f4a2713aSLionel Sambuc for (ModuleConstIterator I = ModuleMgr.begin(),
6905f4a2713aSLionel Sambuc E = ModuleMgr.end(); I != E; ++I) {
6906f4a2713aSLionel Sambuc if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
6907f4a2713aSLionel Sambuc size_t bytes = buf->getBufferSize();
6908f4a2713aSLionel Sambuc switch (buf->getBufferKind()) {
6909f4a2713aSLionel Sambuc case llvm::MemoryBuffer::MemoryBuffer_Malloc:
6910f4a2713aSLionel Sambuc sizes.malloc_bytes += bytes;
6911f4a2713aSLionel Sambuc break;
6912f4a2713aSLionel Sambuc case llvm::MemoryBuffer::MemoryBuffer_MMap:
6913f4a2713aSLionel Sambuc sizes.mmap_bytes += bytes;
6914f4a2713aSLionel Sambuc break;
6915f4a2713aSLionel Sambuc }
6916f4a2713aSLionel Sambuc }
6917f4a2713aSLionel Sambuc }
6918f4a2713aSLionel Sambuc }
6919f4a2713aSLionel Sambuc
InitializeSema(Sema & S)6920f4a2713aSLionel Sambuc void ASTReader::InitializeSema(Sema &S) {
6921f4a2713aSLionel Sambuc SemaObj = &S;
6922f4a2713aSLionel Sambuc S.addExternalSource(this);
6923f4a2713aSLionel Sambuc
6924f4a2713aSLionel Sambuc // Makes sure any declarations that were deserialized "too early"
6925f4a2713aSLionel Sambuc // still get added to the identifier's declaration chains.
6926*0a6a1f1dSLionel Sambuc for (uint64_t ID : PreloadedDeclIDs) {
6927*0a6a1f1dSLionel Sambuc NamedDecl *D = cast<NamedDecl>(GetDecl(ID));
6928*0a6a1f1dSLionel Sambuc pushExternalDeclIntoScope(D, D->getDeclName());
6929f4a2713aSLionel Sambuc }
6930*0a6a1f1dSLionel Sambuc PreloadedDeclIDs.clear();
6931f4a2713aSLionel Sambuc
6932f4a2713aSLionel Sambuc // FIXME: What happens if these are changed by a module import?
6933f4a2713aSLionel Sambuc if (!FPPragmaOptions.empty()) {
6934f4a2713aSLionel Sambuc assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
6935f4a2713aSLionel Sambuc SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
6936f4a2713aSLionel Sambuc }
6937f4a2713aSLionel Sambuc
6938f4a2713aSLionel Sambuc // FIXME: What happens if these are changed by a module import?
6939f4a2713aSLionel Sambuc if (!OpenCLExtensions.empty()) {
6940f4a2713aSLionel Sambuc unsigned I = 0;
6941f4a2713aSLionel Sambuc #define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++];
6942f4a2713aSLionel Sambuc #include "clang/Basic/OpenCLExtensions.def"
6943f4a2713aSLionel Sambuc
6944f4a2713aSLionel Sambuc assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS");
6945f4a2713aSLionel Sambuc }
6946f4a2713aSLionel Sambuc
6947f4a2713aSLionel Sambuc UpdateSema();
6948f4a2713aSLionel Sambuc }
6949f4a2713aSLionel Sambuc
UpdateSema()6950f4a2713aSLionel Sambuc void ASTReader::UpdateSema() {
6951f4a2713aSLionel Sambuc assert(SemaObj && "no Sema to update");
6952f4a2713aSLionel Sambuc
6953f4a2713aSLionel Sambuc // Load the offsets of the declarations that Sema references.
6954f4a2713aSLionel Sambuc // They will be lazily deserialized when needed.
6955f4a2713aSLionel Sambuc if (!SemaDeclRefs.empty()) {
6956f4a2713aSLionel Sambuc assert(SemaDeclRefs.size() % 2 == 0);
6957f4a2713aSLionel Sambuc for (unsigned I = 0; I != SemaDeclRefs.size(); I += 2) {
6958f4a2713aSLionel Sambuc if (!SemaObj->StdNamespace)
6959f4a2713aSLionel Sambuc SemaObj->StdNamespace = SemaDeclRefs[I];
6960f4a2713aSLionel Sambuc if (!SemaObj->StdBadAlloc)
6961f4a2713aSLionel Sambuc SemaObj->StdBadAlloc = SemaDeclRefs[I+1];
6962f4a2713aSLionel Sambuc }
6963f4a2713aSLionel Sambuc SemaDeclRefs.clear();
6964f4a2713aSLionel Sambuc }
6965*0a6a1f1dSLionel Sambuc
6966*0a6a1f1dSLionel Sambuc // Update the state of 'pragma clang optimize'. Use the same API as if we had
6967*0a6a1f1dSLionel Sambuc // encountered the pragma in the source.
6968*0a6a1f1dSLionel Sambuc if(OptimizeOffPragmaLocation.isValid())
6969*0a6a1f1dSLionel Sambuc SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
6970f4a2713aSLionel Sambuc }
6971f4a2713aSLionel Sambuc
get(const char * NameStart,const char * NameEnd)6972f4a2713aSLionel Sambuc IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
6973f4a2713aSLionel Sambuc // Note that we are loading an identifier.
6974f4a2713aSLionel Sambuc Deserializing AnIdentifier(this);
6975f4a2713aSLionel Sambuc StringRef Name(NameStart, NameEnd - NameStart);
6976f4a2713aSLionel Sambuc
6977f4a2713aSLionel Sambuc // If there is a global index, look there first to determine which modules
6978f4a2713aSLionel Sambuc // provably do not have any results for this identifier.
6979f4a2713aSLionel Sambuc GlobalModuleIndex::HitSet Hits;
6980*0a6a1f1dSLionel Sambuc GlobalModuleIndex::HitSet *HitsPtr = nullptr;
6981f4a2713aSLionel Sambuc if (!loadGlobalIndex()) {
6982f4a2713aSLionel Sambuc if (GlobalIndex->lookupIdentifier(Name, Hits)) {
6983f4a2713aSLionel Sambuc HitsPtr = &Hits;
6984f4a2713aSLionel Sambuc }
6985f4a2713aSLionel Sambuc }
6986f4a2713aSLionel Sambuc IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0,
6987f4a2713aSLionel Sambuc NumIdentifierLookups,
6988f4a2713aSLionel Sambuc NumIdentifierLookupHits);
6989f4a2713aSLionel Sambuc ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);
6990f4a2713aSLionel Sambuc IdentifierInfo *II = Visitor.getIdentifierInfo();
6991f4a2713aSLionel Sambuc markIdentifierUpToDate(II);
6992f4a2713aSLionel Sambuc return II;
6993f4a2713aSLionel Sambuc }
6994f4a2713aSLionel Sambuc
6995f4a2713aSLionel Sambuc namespace clang {
6996f4a2713aSLionel Sambuc /// \brief An identifier-lookup iterator that enumerates all of the
6997f4a2713aSLionel Sambuc /// identifiers stored within a set of AST files.
6998f4a2713aSLionel Sambuc class ASTIdentifierIterator : public IdentifierIterator {
6999f4a2713aSLionel Sambuc /// \brief The AST reader whose identifiers are being enumerated.
7000f4a2713aSLionel Sambuc const ASTReader &Reader;
7001f4a2713aSLionel Sambuc
7002f4a2713aSLionel Sambuc /// \brief The current index into the chain of AST files stored in
7003f4a2713aSLionel Sambuc /// the AST reader.
7004f4a2713aSLionel Sambuc unsigned Index;
7005f4a2713aSLionel Sambuc
7006f4a2713aSLionel Sambuc /// \brief The current position within the identifier lookup table
7007f4a2713aSLionel Sambuc /// of the current AST file.
7008f4a2713aSLionel Sambuc ASTIdentifierLookupTable::key_iterator Current;
7009f4a2713aSLionel Sambuc
7010f4a2713aSLionel Sambuc /// \brief The end position within the identifier lookup table of
7011f4a2713aSLionel Sambuc /// the current AST file.
7012f4a2713aSLionel Sambuc ASTIdentifierLookupTable::key_iterator End;
7013f4a2713aSLionel Sambuc
7014f4a2713aSLionel Sambuc public:
7015f4a2713aSLionel Sambuc explicit ASTIdentifierIterator(const ASTReader &Reader);
7016f4a2713aSLionel Sambuc
7017*0a6a1f1dSLionel Sambuc StringRef Next() override;
7018f4a2713aSLionel Sambuc };
7019f4a2713aSLionel Sambuc }
7020f4a2713aSLionel Sambuc
ASTIdentifierIterator(const ASTReader & Reader)7021f4a2713aSLionel Sambuc ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader)
7022f4a2713aSLionel Sambuc : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) {
7023f4a2713aSLionel Sambuc ASTIdentifierLookupTable *IdTable
7024f4a2713aSLionel Sambuc = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable;
7025f4a2713aSLionel Sambuc Current = IdTable->key_begin();
7026f4a2713aSLionel Sambuc End = IdTable->key_end();
7027f4a2713aSLionel Sambuc }
7028f4a2713aSLionel Sambuc
Next()7029f4a2713aSLionel Sambuc StringRef ASTIdentifierIterator::Next() {
7030f4a2713aSLionel Sambuc while (Current == End) {
7031f4a2713aSLionel Sambuc // If we have exhausted all of our AST files, we're done.
7032f4a2713aSLionel Sambuc if (Index == 0)
7033f4a2713aSLionel Sambuc return StringRef();
7034f4a2713aSLionel Sambuc
7035f4a2713aSLionel Sambuc --Index;
7036f4a2713aSLionel Sambuc ASTIdentifierLookupTable *IdTable
7037f4a2713aSLionel Sambuc = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].
7038f4a2713aSLionel Sambuc IdentifierLookupTable;
7039f4a2713aSLionel Sambuc Current = IdTable->key_begin();
7040f4a2713aSLionel Sambuc End = IdTable->key_end();
7041f4a2713aSLionel Sambuc }
7042f4a2713aSLionel Sambuc
7043f4a2713aSLionel Sambuc // We have any identifiers remaining in the current AST file; return
7044f4a2713aSLionel Sambuc // the next one.
7045f4a2713aSLionel Sambuc StringRef Result = *Current;
7046f4a2713aSLionel Sambuc ++Current;
7047f4a2713aSLionel Sambuc return Result;
7048f4a2713aSLionel Sambuc }
7049f4a2713aSLionel Sambuc
getIdentifiers()7050f4a2713aSLionel Sambuc IdentifierIterator *ASTReader::getIdentifiers() {
7051f4a2713aSLionel Sambuc if (!loadGlobalIndex())
7052f4a2713aSLionel Sambuc return GlobalIndex->createIdentifierIterator();
7053f4a2713aSLionel Sambuc
7054f4a2713aSLionel Sambuc return new ASTIdentifierIterator(*this);
7055f4a2713aSLionel Sambuc }
7056f4a2713aSLionel Sambuc
7057f4a2713aSLionel Sambuc namespace clang { namespace serialization {
7058f4a2713aSLionel Sambuc class ReadMethodPoolVisitor {
7059f4a2713aSLionel Sambuc ASTReader &Reader;
7060f4a2713aSLionel Sambuc Selector Sel;
7061f4a2713aSLionel Sambuc unsigned PriorGeneration;
7062f4a2713aSLionel Sambuc unsigned InstanceBits;
7063f4a2713aSLionel Sambuc unsigned FactoryBits;
7064*0a6a1f1dSLionel Sambuc bool InstanceHasMoreThanOneDecl;
7065*0a6a1f1dSLionel Sambuc bool FactoryHasMoreThanOneDecl;
7066f4a2713aSLionel Sambuc SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
7067f4a2713aSLionel Sambuc SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
7068f4a2713aSLionel Sambuc
7069f4a2713aSLionel Sambuc public:
ReadMethodPoolVisitor(ASTReader & Reader,Selector Sel,unsigned PriorGeneration)7070f4a2713aSLionel Sambuc ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,
7071f4a2713aSLionel Sambuc unsigned PriorGeneration)
7072f4a2713aSLionel Sambuc : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration),
7073*0a6a1f1dSLionel Sambuc InstanceBits(0), FactoryBits(0), InstanceHasMoreThanOneDecl(false),
7074*0a6a1f1dSLionel Sambuc FactoryHasMoreThanOneDecl(false) {}
7075f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)7076f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
7077f4a2713aSLionel Sambuc ReadMethodPoolVisitor *This
7078f4a2713aSLionel Sambuc = static_cast<ReadMethodPoolVisitor *>(UserData);
7079f4a2713aSLionel Sambuc
7080f4a2713aSLionel Sambuc if (!M.SelectorLookupTable)
7081f4a2713aSLionel Sambuc return false;
7082f4a2713aSLionel Sambuc
7083f4a2713aSLionel Sambuc // If we've already searched this module file, skip it now.
7084f4a2713aSLionel Sambuc if (M.Generation <= This->PriorGeneration)
7085f4a2713aSLionel Sambuc return true;
7086f4a2713aSLionel Sambuc
7087f4a2713aSLionel Sambuc ++This->Reader.NumMethodPoolTableLookups;
7088f4a2713aSLionel Sambuc ASTSelectorLookupTable *PoolTable
7089f4a2713aSLionel Sambuc = (ASTSelectorLookupTable*)M.SelectorLookupTable;
7090f4a2713aSLionel Sambuc ASTSelectorLookupTable::iterator Pos = PoolTable->find(This->Sel);
7091f4a2713aSLionel Sambuc if (Pos == PoolTable->end())
7092f4a2713aSLionel Sambuc return false;
7093f4a2713aSLionel Sambuc
7094f4a2713aSLionel Sambuc ++This->Reader.NumMethodPoolTableHits;
7095f4a2713aSLionel Sambuc ++This->Reader.NumSelectorsRead;
7096f4a2713aSLionel Sambuc // FIXME: Not quite happy with the statistics here. We probably should
7097f4a2713aSLionel Sambuc // disable this tracking when called via LoadSelector.
7098f4a2713aSLionel Sambuc // Also, should entries without methods count as misses?
7099f4a2713aSLionel Sambuc ++This->Reader.NumMethodPoolEntriesRead;
7100f4a2713aSLionel Sambuc ASTSelectorLookupTrait::data_type Data = *Pos;
7101f4a2713aSLionel Sambuc if (This->Reader.DeserializationListener)
7102f4a2713aSLionel Sambuc This->Reader.DeserializationListener->SelectorRead(Data.ID,
7103f4a2713aSLionel Sambuc This->Sel);
7104f4a2713aSLionel Sambuc
7105f4a2713aSLionel Sambuc This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
7106f4a2713aSLionel Sambuc This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
7107f4a2713aSLionel Sambuc This->InstanceBits = Data.InstanceBits;
7108f4a2713aSLionel Sambuc This->FactoryBits = Data.FactoryBits;
7109*0a6a1f1dSLionel Sambuc This->InstanceHasMoreThanOneDecl = Data.InstanceHasMoreThanOneDecl;
7110*0a6a1f1dSLionel Sambuc This->FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;
7111f4a2713aSLionel Sambuc return true;
7112f4a2713aSLionel Sambuc }
7113f4a2713aSLionel Sambuc
7114f4a2713aSLionel Sambuc /// \brief Retrieve the instance methods found by this visitor.
getInstanceMethods() const7115f4a2713aSLionel Sambuc ArrayRef<ObjCMethodDecl *> getInstanceMethods() const {
7116f4a2713aSLionel Sambuc return InstanceMethods;
7117f4a2713aSLionel Sambuc }
7118f4a2713aSLionel Sambuc
7119f4a2713aSLionel Sambuc /// \brief Retrieve the instance methods found by this visitor.
getFactoryMethods() const7120f4a2713aSLionel Sambuc ArrayRef<ObjCMethodDecl *> getFactoryMethods() const {
7121f4a2713aSLionel Sambuc return FactoryMethods;
7122f4a2713aSLionel Sambuc }
7123f4a2713aSLionel Sambuc
getInstanceBits() const7124f4a2713aSLionel Sambuc unsigned getInstanceBits() const { return InstanceBits; }
getFactoryBits() const7125f4a2713aSLionel Sambuc unsigned getFactoryBits() const { return FactoryBits; }
instanceHasMoreThanOneDecl() const7126*0a6a1f1dSLionel Sambuc bool instanceHasMoreThanOneDecl() const {
7127*0a6a1f1dSLionel Sambuc return InstanceHasMoreThanOneDecl;
7128*0a6a1f1dSLionel Sambuc }
factoryHasMoreThanOneDecl() const7129*0a6a1f1dSLionel Sambuc bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; }
7130f4a2713aSLionel Sambuc };
7131f4a2713aSLionel Sambuc } } // end namespace clang::serialization
7132f4a2713aSLionel Sambuc
7133f4a2713aSLionel Sambuc /// \brief Add the given set of methods to the method list.
addMethodsToPool(Sema & S,ArrayRef<ObjCMethodDecl * > Methods,ObjCMethodList & List)7134f4a2713aSLionel Sambuc static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
7135f4a2713aSLionel Sambuc ObjCMethodList &List) {
7136f4a2713aSLionel Sambuc for (unsigned I = 0, N = Methods.size(); I != N; ++I) {
7137f4a2713aSLionel Sambuc S.addMethodToGlobalList(&List, Methods[I]);
7138f4a2713aSLionel Sambuc }
7139f4a2713aSLionel Sambuc }
7140f4a2713aSLionel Sambuc
ReadMethodPool(Selector Sel)7141f4a2713aSLionel Sambuc void ASTReader::ReadMethodPool(Selector Sel) {
7142f4a2713aSLionel Sambuc // Get the selector generation and update it to the current generation.
7143f4a2713aSLionel Sambuc unsigned &Generation = SelectorGeneration[Sel];
7144f4a2713aSLionel Sambuc unsigned PriorGeneration = Generation;
7145*0a6a1f1dSLionel Sambuc Generation = getGeneration();
7146f4a2713aSLionel Sambuc
7147f4a2713aSLionel Sambuc // Search for methods defined with this selector.
7148f4a2713aSLionel Sambuc ++NumMethodPoolLookups;
7149f4a2713aSLionel Sambuc ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration);
7150f4a2713aSLionel Sambuc ModuleMgr.visit(&ReadMethodPoolVisitor::visit, &Visitor);
7151f4a2713aSLionel Sambuc
7152f4a2713aSLionel Sambuc if (Visitor.getInstanceMethods().empty() &&
7153f4a2713aSLionel Sambuc Visitor.getFactoryMethods().empty())
7154f4a2713aSLionel Sambuc return;
7155f4a2713aSLionel Sambuc
7156f4a2713aSLionel Sambuc ++NumMethodPoolHits;
7157f4a2713aSLionel Sambuc
7158f4a2713aSLionel Sambuc if (!getSema())
7159f4a2713aSLionel Sambuc return;
7160f4a2713aSLionel Sambuc
7161f4a2713aSLionel Sambuc Sema &S = *getSema();
7162f4a2713aSLionel Sambuc Sema::GlobalMethodPool::iterator Pos
7163f4a2713aSLionel Sambuc = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first;
7164f4a2713aSLionel Sambuc
7165*0a6a1f1dSLionel Sambuc Pos->second.first.setBits(Visitor.getInstanceBits());
7166*0a6a1f1dSLionel Sambuc Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl());
7167*0a6a1f1dSLionel Sambuc Pos->second.second.setBits(Visitor.getFactoryBits());
7168*0a6a1f1dSLionel Sambuc Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl());
7169*0a6a1f1dSLionel Sambuc
7170*0a6a1f1dSLionel Sambuc // Add methods to the global pool *after* setting hasMoreThanOneDecl, since
7171*0a6a1f1dSLionel Sambuc // when building a module we keep every method individually and may need to
7172*0a6a1f1dSLionel Sambuc // update hasMoreThanOneDecl as we add the methods.
7173f4a2713aSLionel Sambuc addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);
7174f4a2713aSLionel Sambuc addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
7175f4a2713aSLionel Sambuc }
7176f4a2713aSLionel Sambuc
ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl * > & Namespaces)7177f4a2713aSLionel Sambuc void ASTReader::ReadKnownNamespaces(
7178f4a2713aSLionel Sambuc SmallVectorImpl<NamespaceDecl *> &Namespaces) {
7179f4a2713aSLionel Sambuc Namespaces.clear();
7180f4a2713aSLionel Sambuc
7181f4a2713aSLionel Sambuc for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
7182f4a2713aSLionel Sambuc if (NamespaceDecl *Namespace
7183f4a2713aSLionel Sambuc = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I])))
7184f4a2713aSLionel Sambuc Namespaces.push_back(Namespace);
7185f4a2713aSLionel Sambuc }
7186f4a2713aSLionel Sambuc }
7187f4a2713aSLionel Sambuc
ReadUndefinedButUsed(llvm::DenseMap<NamedDecl *,SourceLocation> & Undefined)7188f4a2713aSLionel Sambuc void ASTReader::ReadUndefinedButUsed(
7189f4a2713aSLionel Sambuc llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) {
7190f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) {
7191f4a2713aSLionel Sambuc NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedButUsed[Idx++]));
7192f4a2713aSLionel Sambuc SourceLocation Loc =
7193f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(UndefinedButUsed[Idx++]);
7194f4a2713aSLionel Sambuc Undefined.insert(std::make_pair(D, Loc));
7195f4a2713aSLionel Sambuc }
7196f4a2713aSLionel Sambuc }
7197f4a2713aSLionel Sambuc
ReadTentativeDefinitions(SmallVectorImpl<VarDecl * > & TentativeDefs)7198f4a2713aSLionel Sambuc void ASTReader::ReadTentativeDefinitions(
7199f4a2713aSLionel Sambuc SmallVectorImpl<VarDecl *> &TentativeDefs) {
7200f4a2713aSLionel Sambuc for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
7201f4a2713aSLionel Sambuc VarDecl *Var = dyn_cast_or_null<VarDecl>(GetDecl(TentativeDefinitions[I]));
7202f4a2713aSLionel Sambuc if (Var)
7203f4a2713aSLionel Sambuc TentativeDefs.push_back(Var);
7204f4a2713aSLionel Sambuc }
7205f4a2713aSLionel Sambuc TentativeDefinitions.clear();
7206f4a2713aSLionel Sambuc }
7207f4a2713aSLionel Sambuc
ReadUnusedFileScopedDecls(SmallVectorImpl<const DeclaratorDecl * > & Decls)7208f4a2713aSLionel Sambuc void ASTReader::ReadUnusedFileScopedDecls(
7209f4a2713aSLionel Sambuc SmallVectorImpl<const DeclaratorDecl *> &Decls) {
7210f4a2713aSLionel Sambuc for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
7211f4a2713aSLionel Sambuc DeclaratorDecl *D
7212f4a2713aSLionel Sambuc = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
7213f4a2713aSLionel Sambuc if (D)
7214f4a2713aSLionel Sambuc Decls.push_back(D);
7215f4a2713aSLionel Sambuc }
7216f4a2713aSLionel Sambuc UnusedFileScopedDecls.clear();
7217f4a2713aSLionel Sambuc }
7218f4a2713aSLionel Sambuc
ReadDelegatingConstructors(SmallVectorImpl<CXXConstructorDecl * > & Decls)7219f4a2713aSLionel Sambuc void ASTReader::ReadDelegatingConstructors(
7220f4a2713aSLionel Sambuc SmallVectorImpl<CXXConstructorDecl *> &Decls) {
7221f4a2713aSLionel Sambuc for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {
7222f4a2713aSLionel Sambuc CXXConstructorDecl *D
7223f4a2713aSLionel Sambuc = dyn_cast_or_null<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));
7224f4a2713aSLionel Sambuc if (D)
7225f4a2713aSLionel Sambuc Decls.push_back(D);
7226f4a2713aSLionel Sambuc }
7227f4a2713aSLionel Sambuc DelegatingCtorDecls.clear();
7228f4a2713aSLionel Sambuc }
7229f4a2713aSLionel Sambuc
ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl * > & Decls)7230f4a2713aSLionel Sambuc void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {
7231f4a2713aSLionel Sambuc for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I) {
7232f4a2713aSLionel Sambuc TypedefNameDecl *D
7233f4a2713aSLionel Sambuc = dyn_cast_or_null<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]));
7234f4a2713aSLionel Sambuc if (D)
7235f4a2713aSLionel Sambuc Decls.push_back(D);
7236f4a2713aSLionel Sambuc }
7237f4a2713aSLionel Sambuc ExtVectorDecls.clear();
7238f4a2713aSLionel Sambuc }
7239f4a2713aSLionel Sambuc
ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl * > & Decls)7240f4a2713aSLionel Sambuc void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {
7241f4a2713aSLionel Sambuc for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
7242f4a2713aSLionel Sambuc CXXRecordDecl *D
7243f4a2713aSLionel Sambuc = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));
7244f4a2713aSLionel Sambuc if (D)
7245f4a2713aSLionel Sambuc Decls.push_back(D);
7246f4a2713aSLionel Sambuc }
7247f4a2713aSLionel Sambuc DynamicClasses.clear();
7248f4a2713aSLionel Sambuc }
7249f4a2713aSLionel Sambuc
ReadUnusedLocalTypedefNameCandidates(llvm::SmallSetVector<const TypedefNameDecl *,4> & Decls)7250*0a6a1f1dSLionel Sambuc void ASTReader::ReadUnusedLocalTypedefNameCandidates(
7251*0a6a1f1dSLionel Sambuc llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
7252*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N;
7253*0a6a1f1dSLionel Sambuc ++I) {
7254*0a6a1f1dSLionel Sambuc TypedefNameDecl *D = dyn_cast_or_null<TypedefNameDecl>(
7255*0a6a1f1dSLionel Sambuc GetDecl(UnusedLocalTypedefNameCandidates[I]));
7256*0a6a1f1dSLionel Sambuc if (D)
7257*0a6a1f1dSLionel Sambuc Decls.insert(D);
7258*0a6a1f1dSLionel Sambuc }
7259*0a6a1f1dSLionel Sambuc UnusedLocalTypedefNameCandidates.clear();
7260*0a6a1f1dSLionel Sambuc }
7261*0a6a1f1dSLionel Sambuc
7262f4a2713aSLionel Sambuc void
ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl * > & Decls)7263f4a2713aSLionel Sambuc ASTReader::ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl *> &Decls) {
7264f4a2713aSLionel Sambuc for (unsigned I = 0, N = LocallyScopedExternCDecls.size(); I != N; ++I) {
7265f4a2713aSLionel Sambuc NamedDecl *D
7266f4a2713aSLionel Sambuc = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternCDecls[I]));
7267f4a2713aSLionel Sambuc if (D)
7268f4a2713aSLionel Sambuc Decls.push_back(D);
7269f4a2713aSLionel Sambuc }
7270f4a2713aSLionel Sambuc LocallyScopedExternCDecls.clear();
7271f4a2713aSLionel Sambuc }
7272f4a2713aSLionel Sambuc
ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,SourceLocation>> & Sels)7273f4a2713aSLionel Sambuc void ASTReader::ReadReferencedSelectors(
7274f4a2713aSLionel Sambuc SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
7275f4a2713aSLionel Sambuc if (ReferencedSelectorsData.empty())
7276f4a2713aSLionel Sambuc return;
7277f4a2713aSLionel Sambuc
7278f4a2713aSLionel Sambuc // If there are @selector references added them to its pool. This is for
7279f4a2713aSLionel Sambuc // implementation of -Wselector.
7280f4a2713aSLionel Sambuc unsigned int DataSize = ReferencedSelectorsData.size()-1;
7281f4a2713aSLionel Sambuc unsigned I = 0;
7282f4a2713aSLionel Sambuc while (I < DataSize) {
7283f4a2713aSLionel Sambuc Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
7284f4a2713aSLionel Sambuc SourceLocation SelLoc
7285f4a2713aSLionel Sambuc = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
7286f4a2713aSLionel Sambuc Sels.push_back(std::make_pair(Sel, SelLoc));
7287f4a2713aSLionel Sambuc }
7288f4a2713aSLionel Sambuc ReferencedSelectorsData.clear();
7289f4a2713aSLionel Sambuc }
7290f4a2713aSLionel Sambuc
ReadWeakUndeclaredIdentifiers(SmallVectorImpl<std::pair<IdentifierInfo *,WeakInfo>> & WeakIDs)7291f4a2713aSLionel Sambuc void ASTReader::ReadWeakUndeclaredIdentifiers(
7292f4a2713aSLionel Sambuc SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) {
7293f4a2713aSLionel Sambuc if (WeakUndeclaredIdentifiers.empty())
7294f4a2713aSLionel Sambuc return;
7295f4a2713aSLionel Sambuc
7296f4a2713aSLionel Sambuc for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {
7297f4a2713aSLionel Sambuc IdentifierInfo *WeakId
7298f4a2713aSLionel Sambuc = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
7299f4a2713aSLionel Sambuc IdentifierInfo *AliasId
7300f4a2713aSLionel Sambuc = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
7301f4a2713aSLionel Sambuc SourceLocation Loc
7302f4a2713aSLionel Sambuc = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);
7303f4a2713aSLionel Sambuc bool Used = WeakUndeclaredIdentifiers[I++];
7304f4a2713aSLionel Sambuc WeakInfo WI(AliasId, Loc);
7305f4a2713aSLionel Sambuc WI.setUsed(Used);
7306f4a2713aSLionel Sambuc WeakIDs.push_back(std::make_pair(WeakId, WI));
7307f4a2713aSLionel Sambuc }
7308f4a2713aSLionel Sambuc WeakUndeclaredIdentifiers.clear();
7309f4a2713aSLionel Sambuc }
7310f4a2713aSLionel Sambuc
ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> & VTables)7311f4a2713aSLionel Sambuc void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
7312f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {
7313f4a2713aSLionel Sambuc ExternalVTableUse VT;
7314f4a2713aSLionel Sambuc VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
7315f4a2713aSLionel Sambuc VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);
7316f4a2713aSLionel Sambuc VT.DefinitionRequired = VTableUses[Idx++];
7317f4a2713aSLionel Sambuc VTables.push_back(VT);
7318f4a2713aSLionel Sambuc }
7319f4a2713aSLionel Sambuc
7320f4a2713aSLionel Sambuc VTableUses.clear();
7321f4a2713aSLionel Sambuc }
7322f4a2713aSLionel Sambuc
ReadPendingInstantiations(SmallVectorImpl<std::pair<ValueDecl *,SourceLocation>> & Pending)7323f4a2713aSLionel Sambuc void ASTReader::ReadPendingInstantiations(
7324f4a2713aSLionel Sambuc SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {
7325f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
7326f4a2713aSLionel Sambuc ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
7327f4a2713aSLionel Sambuc SourceLocation Loc
7328f4a2713aSLionel Sambuc = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
7329f4a2713aSLionel Sambuc
7330f4a2713aSLionel Sambuc Pending.push_back(std::make_pair(D, Loc));
7331f4a2713aSLionel Sambuc }
7332f4a2713aSLionel Sambuc PendingInstantiations.clear();
7333f4a2713aSLionel Sambuc }
7334f4a2713aSLionel Sambuc
ReadLateParsedTemplates(llvm::DenseMap<const FunctionDecl *,LateParsedTemplate * > & LPTMap)7335f4a2713aSLionel Sambuc void ASTReader::ReadLateParsedTemplates(
7336f4a2713aSLionel Sambuc llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
7337f4a2713aSLionel Sambuc for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N;
7338f4a2713aSLionel Sambuc /* In loop */) {
7339f4a2713aSLionel Sambuc FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++]));
7340f4a2713aSLionel Sambuc
7341f4a2713aSLionel Sambuc LateParsedTemplate *LT = new LateParsedTemplate;
7342f4a2713aSLionel Sambuc LT->D = GetDecl(LateParsedTemplates[Idx++]);
7343f4a2713aSLionel Sambuc
7344f4a2713aSLionel Sambuc ModuleFile *F = getOwningModuleFile(LT->D);
7345f4a2713aSLionel Sambuc assert(F && "No module");
7346f4a2713aSLionel Sambuc
7347f4a2713aSLionel Sambuc unsigned TokN = LateParsedTemplates[Idx++];
7348f4a2713aSLionel Sambuc LT->Toks.reserve(TokN);
7349f4a2713aSLionel Sambuc for (unsigned T = 0; T < TokN; ++T)
7350f4a2713aSLionel Sambuc LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx));
7351f4a2713aSLionel Sambuc
7352f4a2713aSLionel Sambuc LPTMap[FD] = LT;
7353f4a2713aSLionel Sambuc }
7354f4a2713aSLionel Sambuc
7355f4a2713aSLionel Sambuc LateParsedTemplates.clear();
7356f4a2713aSLionel Sambuc }
7357f4a2713aSLionel Sambuc
LoadSelector(Selector Sel)7358f4a2713aSLionel Sambuc void ASTReader::LoadSelector(Selector Sel) {
7359f4a2713aSLionel Sambuc // It would be complicated to avoid reading the methods anyway. So don't.
7360f4a2713aSLionel Sambuc ReadMethodPool(Sel);
7361f4a2713aSLionel Sambuc }
7362f4a2713aSLionel Sambuc
SetIdentifierInfo(IdentifierID ID,IdentifierInfo * II)7363f4a2713aSLionel Sambuc void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
7364f4a2713aSLionel Sambuc assert(ID && "Non-zero identifier ID required");
7365f4a2713aSLionel Sambuc assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
7366f4a2713aSLionel Sambuc IdentifiersLoaded[ID - 1] = II;
7367f4a2713aSLionel Sambuc if (DeserializationListener)
7368f4a2713aSLionel Sambuc DeserializationListener->IdentifierRead(ID, II);
7369f4a2713aSLionel Sambuc }
7370f4a2713aSLionel Sambuc
7371f4a2713aSLionel Sambuc /// \brief Set the globally-visible declarations associated with the given
7372f4a2713aSLionel Sambuc /// identifier.
7373f4a2713aSLionel Sambuc ///
7374f4a2713aSLionel Sambuc /// If the AST reader is currently in a state where the given declaration IDs
7375f4a2713aSLionel Sambuc /// cannot safely be resolved, they are queued until it is safe to resolve
7376f4a2713aSLionel Sambuc /// them.
7377f4a2713aSLionel Sambuc ///
7378f4a2713aSLionel Sambuc /// \param II an IdentifierInfo that refers to one or more globally-visible
7379f4a2713aSLionel Sambuc /// declarations.
7380f4a2713aSLionel Sambuc ///
7381f4a2713aSLionel Sambuc /// \param DeclIDs the set of declaration IDs with the name @p II that are
7382f4a2713aSLionel Sambuc /// visible at global scope.
7383f4a2713aSLionel Sambuc ///
7384f4a2713aSLionel Sambuc /// \param Decls if non-null, this vector will be populated with the set of
7385f4a2713aSLionel Sambuc /// deserialized declarations. These declarations will not be pushed into
7386f4a2713aSLionel Sambuc /// scope.
7387f4a2713aSLionel Sambuc void
SetGloballyVisibleDecls(IdentifierInfo * II,const SmallVectorImpl<uint32_t> & DeclIDs,SmallVectorImpl<Decl * > * Decls)7388f4a2713aSLionel Sambuc ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
7389f4a2713aSLionel Sambuc const SmallVectorImpl<uint32_t> &DeclIDs,
7390f4a2713aSLionel Sambuc SmallVectorImpl<Decl *> *Decls) {
7391f4a2713aSLionel Sambuc if (NumCurrentElementsDeserializing && !Decls) {
7392f4a2713aSLionel Sambuc PendingIdentifierInfos[II].append(DeclIDs.begin(), DeclIDs.end());
7393f4a2713aSLionel Sambuc return;
7394f4a2713aSLionel Sambuc }
7395f4a2713aSLionel Sambuc
7396f4a2713aSLionel Sambuc for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
7397*0a6a1f1dSLionel Sambuc if (!SemaObj) {
7398*0a6a1f1dSLionel Sambuc // Queue this declaration so that it will be added to the
7399*0a6a1f1dSLionel Sambuc // translation unit scope and identifier's declaration chain
7400*0a6a1f1dSLionel Sambuc // once a Sema object is known.
7401*0a6a1f1dSLionel Sambuc PreloadedDeclIDs.push_back(DeclIDs[I]);
7402*0a6a1f1dSLionel Sambuc continue;
7403*0a6a1f1dSLionel Sambuc }
7404*0a6a1f1dSLionel Sambuc
7405f4a2713aSLionel Sambuc NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
7406*0a6a1f1dSLionel Sambuc
7407f4a2713aSLionel Sambuc // If we're simply supposed to record the declarations, do so now.
7408f4a2713aSLionel Sambuc if (Decls) {
7409f4a2713aSLionel Sambuc Decls->push_back(D);
7410f4a2713aSLionel Sambuc continue;
7411f4a2713aSLionel Sambuc }
7412f4a2713aSLionel Sambuc
7413f4a2713aSLionel Sambuc // Introduce this declaration into the translation-unit scope
7414f4a2713aSLionel Sambuc // and add it to the declaration chain for this identifier, so
7415f4a2713aSLionel Sambuc // that (unqualified) name lookup will find it.
7416f4a2713aSLionel Sambuc pushExternalDeclIntoScope(D, II);
7417f4a2713aSLionel Sambuc }
7418f4a2713aSLionel Sambuc }
7419f4a2713aSLionel Sambuc
DecodeIdentifierInfo(IdentifierID ID)7420f4a2713aSLionel Sambuc IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
7421f4a2713aSLionel Sambuc if (ID == 0)
7422*0a6a1f1dSLionel Sambuc return nullptr;
7423f4a2713aSLionel Sambuc
7424f4a2713aSLionel Sambuc if (IdentifiersLoaded.empty()) {
7425f4a2713aSLionel Sambuc Error("no identifier table in AST file");
7426*0a6a1f1dSLionel Sambuc return nullptr;
7427f4a2713aSLionel Sambuc }
7428f4a2713aSLionel Sambuc
7429f4a2713aSLionel Sambuc ID -= 1;
7430f4a2713aSLionel Sambuc if (!IdentifiersLoaded[ID]) {
7431f4a2713aSLionel Sambuc GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);
7432f4a2713aSLionel Sambuc assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");
7433f4a2713aSLionel Sambuc ModuleFile *M = I->second;
7434f4a2713aSLionel Sambuc unsigned Index = ID - M->BaseIdentifierID;
7435f4a2713aSLionel Sambuc const char *Str = M->IdentifierTableData + M->IdentifierOffsets[Index];
7436f4a2713aSLionel Sambuc
7437f4a2713aSLionel Sambuc // All of the strings in the AST file are preceded by a 16-bit length.
7438f4a2713aSLionel Sambuc // Extract that 16-bit length to avoid having to execute strlen().
7439f4a2713aSLionel Sambuc // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
7440f4a2713aSLionel Sambuc // unsigned integers. This is important to avoid integer overflow when
7441f4a2713aSLionel Sambuc // we cast them to 'unsigned'.
7442f4a2713aSLionel Sambuc const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
7443f4a2713aSLionel Sambuc unsigned StrLen = (((unsigned) StrLenPtr[0])
7444f4a2713aSLionel Sambuc | (((unsigned) StrLenPtr[1]) << 8)) - 1;
7445f4a2713aSLionel Sambuc IdentifiersLoaded[ID]
7446f4a2713aSLionel Sambuc = &PP.getIdentifierTable().get(StringRef(Str, StrLen));
7447f4a2713aSLionel Sambuc if (DeserializationListener)
7448f4a2713aSLionel Sambuc DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
7449f4a2713aSLionel Sambuc }
7450f4a2713aSLionel Sambuc
7451f4a2713aSLionel Sambuc return IdentifiersLoaded[ID];
7452f4a2713aSLionel Sambuc }
7453f4a2713aSLionel Sambuc
getLocalIdentifier(ModuleFile & M,unsigned LocalID)7454f4a2713aSLionel Sambuc IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) {
7455f4a2713aSLionel Sambuc return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));
7456f4a2713aSLionel Sambuc }
7457f4a2713aSLionel Sambuc
getGlobalIdentifierID(ModuleFile & M,unsigned LocalID)7458f4a2713aSLionel Sambuc IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
7459f4a2713aSLionel Sambuc if (LocalID < NUM_PREDEF_IDENT_IDS)
7460f4a2713aSLionel Sambuc return LocalID;
7461f4a2713aSLionel Sambuc
7462f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
7463f4a2713aSLionel Sambuc = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
7464f4a2713aSLionel Sambuc assert(I != M.IdentifierRemap.end()
7465f4a2713aSLionel Sambuc && "Invalid index into identifier index remap");
7466f4a2713aSLionel Sambuc
7467f4a2713aSLionel Sambuc return LocalID + I->second;
7468f4a2713aSLionel Sambuc }
7469f4a2713aSLionel Sambuc
getMacro(MacroID ID)7470f4a2713aSLionel Sambuc MacroInfo *ASTReader::getMacro(MacroID ID) {
7471f4a2713aSLionel Sambuc if (ID == 0)
7472*0a6a1f1dSLionel Sambuc return nullptr;
7473f4a2713aSLionel Sambuc
7474f4a2713aSLionel Sambuc if (MacrosLoaded.empty()) {
7475f4a2713aSLionel Sambuc Error("no macro table in AST file");
7476*0a6a1f1dSLionel Sambuc return nullptr;
7477f4a2713aSLionel Sambuc }
7478f4a2713aSLionel Sambuc
7479f4a2713aSLionel Sambuc ID -= NUM_PREDEF_MACRO_IDS;
7480f4a2713aSLionel Sambuc if (!MacrosLoaded[ID]) {
7481f4a2713aSLionel Sambuc GlobalMacroMapType::iterator I
7482f4a2713aSLionel Sambuc = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS);
7483f4a2713aSLionel Sambuc assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
7484f4a2713aSLionel Sambuc ModuleFile *M = I->second;
7485f4a2713aSLionel Sambuc unsigned Index = ID - M->BaseMacroID;
7486f4a2713aSLionel Sambuc MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]);
7487f4a2713aSLionel Sambuc
7488f4a2713aSLionel Sambuc if (DeserializationListener)
7489f4a2713aSLionel Sambuc DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS,
7490f4a2713aSLionel Sambuc MacrosLoaded[ID]);
7491f4a2713aSLionel Sambuc }
7492f4a2713aSLionel Sambuc
7493f4a2713aSLionel Sambuc return MacrosLoaded[ID];
7494f4a2713aSLionel Sambuc }
7495f4a2713aSLionel Sambuc
getGlobalMacroID(ModuleFile & M,unsigned LocalID)7496f4a2713aSLionel Sambuc MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
7497f4a2713aSLionel Sambuc if (LocalID < NUM_PREDEF_MACRO_IDS)
7498f4a2713aSLionel Sambuc return LocalID;
7499f4a2713aSLionel Sambuc
7500f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
7501f4a2713aSLionel Sambuc = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);
7502f4a2713aSLionel Sambuc assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");
7503f4a2713aSLionel Sambuc
7504f4a2713aSLionel Sambuc return LocalID + I->second;
7505f4a2713aSLionel Sambuc }
7506f4a2713aSLionel Sambuc
7507f4a2713aSLionel Sambuc serialization::SubmoduleID
getGlobalSubmoduleID(ModuleFile & M,unsigned LocalID)7508f4a2713aSLionel Sambuc ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
7509f4a2713aSLionel Sambuc if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
7510f4a2713aSLionel Sambuc return LocalID;
7511f4a2713aSLionel Sambuc
7512f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
7513f4a2713aSLionel Sambuc = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
7514f4a2713aSLionel Sambuc assert(I != M.SubmoduleRemap.end()
7515f4a2713aSLionel Sambuc && "Invalid index into submodule index remap");
7516f4a2713aSLionel Sambuc
7517f4a2713aSLionel Sambuc return LocalID + I->second;
7518f4a2713aSLionel Sambuc }
7519f4a2713aSLionel Sambuc
getSubmodule(SubmoduleID GlobalID)7520f4a2713aSLionel Sambuc Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
7521f4a2713aSLionel Sambuc if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
7522f4a2713aSLionel Sambuc assert(GlobalID == 0 && "Unhandled global submodule ID");
7523*0a6a1f1dSLionel Sambuc return nullptr;
7524f4a2713aSLionel Sambuc }
7525f4a2713aSLionel Sambuc
7526f4a2713aSLionel Sambuc if (GlobalID > SubmodulesLoaded.size()) {
7527f4a2713aSLionel Sambuc Error("submodule ID out of range in AST file");
7528*0a6a1f1dSLionel Sambuc return nullptr;
7529f4a2713aSLionel Sambuc }
7530f4a2713aSLionel Sambuc
7531f4a2713aSLionel Sambuc return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
7532f4a2713aSLionel Sambuc }
7533f4a2713aSLionel Sambuc
getModule(unsigned ID)7534f4a2713aSLionel Sambuc Module *ASTReader::getModule(unsigned ID) {
7535f4a2713aSLionel Sambuc return getSubmodule(ID);
7536f4a2713aSLionel Sambuc }
7537f4a2713aSLionel Sambuc
getLocalSelector(ModuleFile & M,unsigned LocalID)7538f4a2713aSLionel Sambuc Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
7539f4a2713aSLionel Sambuc return DecodeSelector(getGlobalSelectorID(M, LocalID));
7540f4a2713aSLionel Sambuc }
7541f4a2713aSLionel Sambuc
DecodeSelector(serialization::SelectorID ID)7542f4a2713aSLionel Sambuc Selector ASTReader::DecodeSelector(serialization::SelectorID ID) {
7543f4a2713aSLionel Sambuc if (ID == 0)
7544f4a2713aSLionel Sambuc return Selector();
7545f4a2713aSLionel Sambuc
7546f4a2713aSLionel Sambuc if (ID > SelectorsLoaded.size()) {
7547f4a2713aSLionel Sambuc Error("selector ID out of range in AST file");
7548f4a2713aSLionel Sambuc return Selector();
7549f4a2713aSLionel Sambuc }
7550f4a2713aSLionel Sambuc
7551*0a6a1f1dSLionel Sambuc if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == nullptr) {
7552f4a2713aSLionel Sambuc // Load this selector from the selector table.
7553f4a2713aSLionel Sambuc GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
7554f4a2713aSLionel Sambuc assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
7555f4a2713aSLionel Sambuc ModuleFile &M = *I->second;
7556f4a2713aSLionel Sambuc ASTSelectorLookupTrait Trait(*this, M);
7557f4a2713aSLionel Sambuc unsigned Idx = ID - M.BaseSelectorID - NUM_PREDEF_SELECTOR_IDS;
7558f4a2713aSLionel Sambuc SelectorsLoaded[ID - 1] =
7559f4a2713aSLionel Sambuc Trait.ReadKey(M.SelectorLookupTableData + M.SelectorOffsets[Idx], 0);
7560f4a2713aSLionel Sambuc if (DeserializationListener)
7561f4a2713aSLionel Sambuc DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
7562f4a2713aSLionel Sambuc }
7563f4a2713aSLionel Sambuc
7564f4a2713aSLionel Sambuc return SelectorsLoaded[ID - 1];
7565f4a2713aSLionel Sambuc }
7566f4a2713aSLionel Sambuc
GetExternalSelector(serialization::SelectorID ID)7567f4a2713aSLionel Sambuc Selector ASTReader::GetExternalSelector(serialization::SelectorID ID) {
7568f4a2713aSLionel Sambuc return DecodeSelector(ID);
7569f4a2713aSLionel Sambuc }
7570f4a2713aSLionel Sambuc
GetNumExternalSelectors()7571f4a2713aSLionel Sambuc uint32_t ASTReader::GetNumExternalSelectors() {
7572f4a2713aSLionel Sambuc // ID 0 (the null selector) is considered an external selector.
7573f4a2713aSLionel Sambuc return getTotalNumSelectors() + 1;
7574f4a2713aSLionel Sambuc }
7575f4a2713aSLionel Sambuc
7576f4a2713aSLionel Sambuc serialization::SelectorID
getGlobalSelectorID(ModuleFile & M,unsigned LocalID) const7577f4a2713aSLionel Sambuc ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {
7578f4a2713aSLionel Sambuc if (LocalID < NUM_PREDEF_SELECTOR_IDS)
7579f4a2713aSLionel Sambuc return LocalID;
7580f4a2713aSLionel Sambuc
7581f4a2713aSLionel Sambuc ContinuousRangeMap<uint32_t, int, 2>::iterator I
7582f4a2713aSLionel Sambuc = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
7583f4a2713aSLionel Sambuc assert(I != M.SelectorRemap.end()
7584f4a2713aSLionel Sambuc && "Invalid index into selector index remap");
7585f4a2713aSLionel Sambuc
7586f4a2713aSLionel Sambuc return LocalID + I->second;
7587f4a2713aSLionel Sambuc }
7588f4a2713aSLionel Sambuc
7589f4a2713aSLionel Sambuc DeclarationName
ReadDeclarationName(ModuleFile & F,const RecordData & Record,unsigned & Idx)7590f4a2713aSLionel Sambuc ASTReader::ReadDeclarationName(ModuleFile &F,
7591f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7592f4a2713aSLionel Sambuc DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
7593f4a2713aSLionel Sambuc switch (Kind) {
7594f4a2713aSLionel Sambuc case DeclarationName::Identifier:
7595f4a2713aSLionel Sambuc return DeclarationName(GetIdentifierInfo(F, Record, Idx));
7596f4a2713aSLionel Sambuc
7597f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
7598f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
7599f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
7600f4a2713aSLionel Sambuc return DeclarationName(ReadSelector(F, Record, Idx));
7601f4a2713aSLionel Sambuc
7602f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
7603f4a2713aSLionel Sambuc return Context.DeclarationNames.getCXXConstructorName(
7604f4a2713aSLionel Sambuc Context.getCanonicalType(readType(F, Record, Idx)));
7605f4a2713aSLionel Sambuc
7606f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
7607f4a2713aSLionel Sambuc return Context.DeclarationNames.getCXXDestructorName(
7608f4a2713aSLionel Sambuc Context.getCanonicalType(readType(F, Record, Idx)));
7609f4a2713aSLionel Sambuc
7610f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
7611f4a2713aSLionel Sambuc return Context.DeclarationNames.getCXXConversionFunctionName(
7612f4a2713aSLionel Sambuc Context.getCanonicalType(readType(F, Record, Idx)));
7613f4a2713aSLionel Sambuc
7614f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
7615f4a2713aSLionel Sambuc return Context.DeclarationNames.getCXXOperatorName(
7616f4a2713aSLionel Sambuc (OverloadedOperatorKind)Record[Idx++]);
7617f4a2713aSLionel Sambuc
7618f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
7619f4a2713aSLionel Sambuc return Context.DeclarationNames.getCXXLiteralOperatorName(
7620f4a2713aSLionel Sambuc GetIdentifierInfo(F, Record, Idx));
7621f4a2713aSLionel Sambuc
7622f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
7623f4a2713aSLionel Sambuc return DeclarationName::getUsingDirectiveName();
7624f4a2713aSLionel Sambuc }
7625f4a2713aSLionel Sambuc
7626f4a2713aSLionel Sambuc llvm_unreachable("Invalid NameKind!");
7627f4a2713aSLionel Sambuc }
7628f4a2713aSLionel Sambuc
ReadDeclarationNameLoc(ModuleFile & F,DeclarationNameLoc & DNLoc,DeclarationName Name,const RecordData & Record,unsigned & Idx)7629f4a2713aSLionel Sambuc void ASTReader::ReadDeclarationNameLoc(ModuleFile &F,
7630f4a2713aSLionel Sambuc DeclarationNameLoc &DNLoc,
7631f4a2713aSLionel Sambuc DeclarationName Name,
7632f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7633f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
7634f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
7635f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
7636f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
7637f4a2713aSLionel Sambuc DNLoc.NamedType.TInfo = GetTypeSourceInfo(F, Record, Idx);
7638f4a2713aSLionel Sambuc break;
7639f4a2713aSLionel Sambuc
7640f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
7641f4a2713aSLionel Sambuc DNLoc.CXXOperatorName.BeginOpNameLoc
7642f4a2713aSLionel Sambuc = ReadSourceLocation(F, Record, Idx).getRawEncoding();
7643f4a2713aSLionel Sambuc DNLoc.CXXOperatorName.EndOpNameLoc
7644f4a2713aSLionel Sambuc = ReadSourceLocation(F, Record, Idx).getRawEncoding();
7645f4a2713aSLionel Sambuc break;
7646f4a2713aSLionel Sambuc
7647f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
7648f4a2713aSLionel Sambuc DNLoc.CXXLiteralOperatorName.OpNameLoc
7649f4a2713aSLionel Sambuc = ReadSourceLocation(F, Record, Idx).getRawEncoding();
7650f4a2713aSLionel Sambuc break;
7651f4a2713aSLionel Sambuc
7652f4a2713aSLionel Sambuc case DeclarationName::Identifier:
7653f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
7654f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
7655f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
7656f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
7657f4a2713aSLionel Sambuc break;
7658f4a2713aSLionel Sambuc }
7659f4a2713aSLionel Sambuc }
7660f4a2713aSLionel Sambuc
ReadDeclarationNameInfo(ModuleFile & F,DeclarationNameInfo & NameInfo,const RecordData & Record,unsigned & Idx)7661f4a2713aSLionel Sambuc void ASTReader::ReadDeclarationNameInfo(ModuleFile &F,
7662f4a2713aSLionel Sambuc DeclarationNameInfo &NameInfo,
7663f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7664f4a2713aSLionel Sambuc NameInfo.setName(ReadDeclarationName(F, Record, Idx));
7665f4a2713aSLionel Sambuc NameInfo.setLoc(ReadSourceLocation(F, Record, Idx));
7666f4a2713aSLionel Sambuc DeclarationNameLoc DNLoc;
7667f4a2713aSLionel Sambuc ReadDeclarationNameLoc(F, DNLoc, NameInfo.getName(), Record, Idx);
7668f4a2713aSLionel Sambuc NameInfo.setInfo(DNLoc);
7669f4a2713aSLionel Sambuc }
7670f4a2713aSLionel Sambuc
ReadQualifierInfo(ModuleFile & F,QualifierInfo & Info,const RecordData & Record,unsigned & Idx)7671f4a2713aSLionel Sambuc void ASTReader::ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,
7672f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7673f4a2713aSLionel Sambuc Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
7674f4a2713aSLionel Sambuc unsigned NumTPLists = Record[Idx++];
7675f4a2713aSLionel Sambuc Info.NumTemplParamLists = NumTPLists;
7676f4a2713aSLionel Sambuc if (NumTPLists) {
7677f4a2713aSLionel Sambuc Info.TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
7678f4a2713aSLionel Sambuc for (unsigned i=0; i != NumTPLists; ++i)
7679f4a2713aSLionel Sambuc Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx);
7680f4a2713aSLionel Sambuc }
7681f4a2713aSLionel Sambuc }
7682f4a2713aSLionel Sambuc
7683f4a2713aSLionel Sambuc TemplateName
ReadTemplateName(ModuleFile & F,const RecordData & Record,unsigned & Idx)7684f4a2713aSLionel Sambuc ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record,
7685f4a2713aSLionel Sambuc unsigned &Idx) {
7686f4a2713aSLionel Sambuc TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
7687f4a2713aSLionel Sambuc switch (Kind) {
7688f4a2713aSLionel Sambuc case TemplateName::Template:
7689f4a2713aSLionel Sambuc return TemplateName(ReadDeclAs<TemplateDecl>(F, Record, Idx));
7690f4a2713aSLionel Sambuc
7691f4a2713aSLionel Sambuc case TemplateName::OverloadedTemplate: {
7692f4a2713aSLionel Sambuc unsigned size = Record[Idx++];
7693f4a2713aSLionel Sambuc UnresolvedSet<8> Decls;
7694f4a2713aSLionel Sambuc while (size--)
7695f4a2713aSLionel Sambuc Decls.addDecl(ReadDeclAs<NamedDecl>(F, Record, Idx));
7696f4a2713aSLionel Sambuc
7697f4a2713aSLionel Sambuc return Context.getOverloadedTemplateName(Decls.begin(), Decls.end());
7698f4a2713aSLionel Sambuc }
7699f4a2713aSLionel Sambuc
7700f4a2713aSLionel Sambuc case TemplateName::QualifiedTemplate: {
7701f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
7702f4a2713aSLionel Sambuc bool hasTemplKeyword = Record[Idx++];
7703f4a2713aSLionel Sambuc TemplateDecl *Template = ReadDeclAs<TemplateDecl>(F, Record, Idx);
7704f4a2713aSLionel Sambuc return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
7705f4a2713aSLionel Sambuc }
7706f4a2713aSLionel Sambuc
7707f4a2713aSLionel Sambuc case TemplateName::DependentTemplate: {
7708f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
7709f4a2713aSLionel Sambuc if (Record[Idx++]) // isIdentifier
7710f4a2713aSLionel Sambuc return Context.getDependentTemplateName(NNS,
7711f4a2713aSLionel Sambuc GetIdentifierInfo(F, Record,
7712f4a2713aSLionel Sambuc Idx));
7713f4a2713aSLionel Sambuc return Context.getDependentTemplateName(NNS,
7714f4a2713aSLionel Sambuc (OverloadedOperatorKind)Record[Idx++]);
7715f4a2713aSLionel Sambuc }
7716f4a2713aSLionel Sambuc
7717f4a2713aSLionel Sambuc case TemplateName::SubstTemplateTemplateParm: {
7718f4a2713aSLionel Sambuc TemplateTemplateParmDecl *param
7719f4a2713aSLionel Sambuc = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
7720f4a2713aSLionel Sambuc if (!param) return TemplateName();
7721f4a2713aSLionel Sambuc TemplateName replacement = ReadTemplateName(F, Record, Idx);
7722f4a2713aSLionel Sambuc return Context.getSubstTemplateTemplateParm(param, replacement);
7723f4a2713aSLionel Sambuc }
7724f4a2713aSLionel Sambuc
7725f4a2713aSLionel Sambuc case TemplateName::SubstTemplateTemplateParmPack: {
7726f4a2713aSLionel Sambuc TemplateTemplateParmDecl *Param
7727f4a2713aSLionel Sambuc = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
7728f4a2713aSLionel Sambuc if (!Param)
7729f4a2713aSLionel Sambuc return TemplateName();
7730f4a2713aSLionel Sambuc
7731f4a2713aSLionel Sambuc TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx);
7732f4a2713aSLionel Sambuc if (ArgPack.getKind() != TemplateArgument::Pack)
7733f4a2713aSLionel Sambuc return TemplateName();
7734f4a2713aSLionel Sambuc
7735f4a2713aSLionel Sambuc return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
7736f4a2713aSLionel Sambuc }
7737f4a2713aSLionel Sambuc }
7738f4a2713aSLionel Sambuc
7739f4a2713aSLionel Sambuc llvm_unreachable("Unhandled template name kind!");
7740f4a2713aSLionel Sambuc }
7741f4a2713aSLionel Sambuc
7742f4a2713aSLionel Sambuc TemplateArgument
ReadTemplateArgument(ModuleFile & F,const RecordData & Record,unsigned & Idx)7743f4a2713aSLionel Sambuc ASTReader::ReadTemplateArgument(ModuleFile &F,
7744f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7745f4a2713aSLionel Sambuc TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];
7746f4a2713aSLionel Sambuc switch (Kind) {
7747f4a2713aSLionel Sambuc case TemplateArgument::Null:
7748f4a2713aSLionel Sambuc return TemplateArgument();
7749f4a2713aSLionel Sambuc case TemplateArgument::Type:
7750f4a2713aSLionel Sambuc return TemplateArgument(readType(F, Record, Idx));
7751f4a2713aSLionel Sambuc case TemplateArgument::Declaration: {
7752f4a2713aSLionel Sambuc ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);
7753*0a6a1f1dSLionel Sambuc return TemplateArgument(D, readType(F, Record, Idx));
7754f4a2713aSLionel Sambuc }
7755f4a2713aSLionel Sambuc case TemplateArgument::NullPtr:
7756f4a2713aSLionel Sambuc return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);
7757f4a2713aSLionel Sambuc case TemplateArgument::Integral: {
7758f4a2713aSLionel Sambuc llvm::APSInt Value = ReadAPSInt(Record, Idx);
7759f4a2713aSLionel Sambuc QualType T = readType(F, Record, Idx);
7760f4a2713aSLionel Sambuc return TemplateArgument(Context, Value, T);
7761f4a2713aSLionel Sambuc }
7762f4a2713aSLionel Sambuc case TemplateArgument::Template:
7763f4a2713aSLionel Sambuc return TemplateArgument(ReadTemplateName(F, Record, Idx));
7764f4a2713aSLionel Sambuc case TemplateArgument::TemplateExpansion: {
7765f4a2713aSLionel Sambuc TemplateName Name = ReadTemplateName(F, Record, Idx);
7766f4a2713aSLionel Sambuc Optional<unsigned> NumTemplateExpansions;
7767f4a2713aSLionel Sambuc if (unsigned NumExpansions = Record[Idx++])
7768f4a2713aSLionel Sambuc NumTemplateExpansions = NumExpansions - 1;
7769f4a2713aSLionel Sambuc return TemplateArgument(Name, NumTemplateExpansions);
7770f4a2713aSLionel Sambuc }
7771f4a2713aSLionel Sambuc case TemplateArgument::Expression:
7772f4a2713aSLionel Sambuc return TemplateArgument(ReadExpr(F));
7773f4a2713aSLionel Sambuc case TemplateArgument::Pack: {
7774f4a2713aSLionel Sambuc unsigned NumArgs = Record[Idx++];
7775f4a2713aSLionel Sambuc TemplateArgument *Args = new (Context) TemplateArgument[NumArgs];
7776f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumArgs; ++I)
7777f4a2713aSLionel Sambuc Args[I] = ReadTemplateArgument(F, Record, Idx);
7778f4a2713aSLionel Sambuc return TemplateArgument(Args, NumArgs);
7779f4a2713aSLionel Sambuc }
7780f4a2713aSLionel Sambuc }
7781f4a2713aSLionel Sambuc
7782f4a2713aSLionel Sambuc llvm_unreachable("Unhandled template argument kind!");
7783f4a2713aSLionel Sambuc }
7784f4a2713aSLionel Sambuc
7785f4a2713aSLionel Sambuc TemplateParameterList *
ReadTemplateParameterList(ModuleFile & F,const RecordData & Record,unsigned & Idx)7786f4a2713aSLionel Sambuc ASTReader::ReadTemplateParameterList(ModuleFile &F,
7787f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7788f4a2713aSLionel Sambuc SourceLocation TemplateLoc = ReadSourceLocation(F, Record, Idx);
7789f4a2713aSLionel Sambuc SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Idx);
7790f4a2713aSLionel Sambuc SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx);
7791f4a2713aSLionel Sambuc
7792f4a2713aSLionel Sambuc unsigned NumParams = Record[Idx++];
7793f4a2713aSLionel Sambuc SmallVector<NamedDecl *, 16> Params;
7794f4a2713aSLionel Sambuc Params.reserve(NumParams);
7795f4a2713aSLionel Sambuc while (NumParams--)
7796f4a2713aSLionel Sambuc Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
7797f4a2713aSLionel Sambuc
7798f4a2713aSLionel Sambuc TemplateParameterList* TemplateParams =
7799f4a2713aSLionel Sambuc TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
7800f4a2713aSLionel Sambuc Params.data(), Params.size(), RAngleLoc);
7801f4a2713aSLionel Sambuc return TemplateParams;
7802f4a2713aSLionel Sambuc }
7803f4a2713aSLionel Sambuc
7804f4a2713aSLionel Sambuc void
7805f4a2713aSLionel Sambuc ASTReader::
ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> & TemplArgs,ModuleFile & F,const RecordData & Record,unsigned & Idx)7806f4a2713aSLionel Sambuc ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
7807f4a2713aSLionel Sambuc ModuleFile &F, const RecordData &Record,
7808f4a2713aSLionel Sambuc unsigned &Idx) {
7809f4a2713aSLionel Sambuc unsigned NumTemplateArgs = Record[Idx++];
7810f4a2713aSLionel Sambuc TemplArgs.reserve(NumTemplateArgs);
7811f4a2713aSLionel Sambuc while (NumTemplateArgs--)
7812f4a2713aSLionel Sambuc TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx));
7813f4a2713aSLionel Sambuc }
7814f4a2713aSLionel Sambuc
7815f4a2713aSLionel Sambuc /// \brief Read a UnresolvedSet structure.
ReadUnresolvedSet(ModuleFile & F,LazyASTUnresolvedSet & Set,const RecordData & Record,unsigned & Idx)7816f4a2713aSLionel Sambuc void ASTReader::ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
7817f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7818f4a2713aSLionel Sambuc unsigned NumDecls = Record[Idx++];
7819f4a2713aSLionel Sambuc Set.reserve(Context, NumDecls);
7820f4a2713aSLionel Sambuc while (NumDecls--) {
7821f4a2713aSLionel Sambuc DeclID ID = ReadDeclID(F, Record, Idx);
7822f4a2713aSLionel Sambuc AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
7823f4a2713aSLionel Sambuc Set.addLazyDecl(Context, ID, AS);
7824f4a2713aSLionel Sambuc }
7825f4a2713aSLionel Sambuc }
7826f4a2713aSLionel Sambuc
7827f4a2713aSLionel Sambuc CXXBaseSpecifier
ReadCXXBaseSpecifier(ModuleFile & F,const RecordData & Record,unsigned & Idx)7828f4a2713aSLionel Sambuc ASTReader::ReadCXXBaseSpecifier(ModuleFile &F,
7829f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7830f4a2713aSLionel Sambuc bool isVirtual = static_cast<bool>(Record[Idx++]);
7831f4a2713aSLionel Sambuc bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
7832f4a2713aSLionel Sambuc AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
7833f4a2713aSLionel Sambuc bool inheritConstructors = static_cast<bool>(Record[Idx++]);
7834f4a2713aSLionel Sambuc TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx);
7835f4a2713aSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
7836f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx);
7837f4a2713aSLionel Sambuc CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo,
7838f4a2713aSLionel Sambuc EllipsisLoc);
7839f4a2713aSLionel Sambuc Result.setInheritConstructors(inheritConstructors);
7840f4a2713aSLionel Sambuc return Result;
7841f4a2713aSLionel Sambuc }
7842f4a2713aSLionel Sambuc
7843f4a2713aSLionel Sambuc std::pair<CXXCtorInitializer **, unsigned>
ReadCXXCtorInitializers(ModuleFile & F,const RecordData & Record,unsigned & Idx)7844f4a2713aSLionel Sambuc ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
7845f4a2713aSLionel Sambuc unsigned &Idx) {
7846*0a6a1f1dSLionel Sambuc CXXCtorInitializer **CtorInitializers = nullptr;
7847f4a2713aSLionel Sambuc unsigned NumInitializers = Record[Idx++];
7848f4a2713aSLionel Sambuc if (NumInitializers) {
7849f4a2713aSLionel Sambuc CtorInitializers
7850f4a2713aSLionel Sambuc = new (Context) CXXCtorInitializer*[NumInitializers];
7851f4a2713aSLionel Sambuc for (unsigned i=0; i != NumInitializers; ++i) {
7852*0a6a1f1dSLionel Sambuc TypeSourceInfo *TInfo = nullptr;
7853f4a2713aSLionel Sambuc bool IsBaseVirtual = false;
7854*0a6a1f1dSLionel Sambuc FieldDecl *Member = nullptr;
7855*0a6a1f1dSLionel Sambuc IndirectFieldDecl *IndirectMember = nullptr;
7856f4a2713aSLionel Sambuc
7857f4a2713aSLionel Sambuc CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
7858f4a2713aSLionel Sambuc switch (Type) {
7859f4a2713aSLionel Sambuc case CTOR_INITIALIZER_BASE:
7860f4a2713aSLionel Sambuc TInfo = GetTypeSourceInfo(F, Record, Idx);
7861f4a2713aSLionel Sambuc IsBaseVirtual = Record[Idx++];
7862f4a2713aSLionel Sambuc break;
7863f4a2713aSLionel Sambuc
7864f4a2713aSLionel Sambuc case CTOR_INITIALIZER_DELEGATING:
7865f4a2713aSLionel Sambuc TInfo = GetTypeSourceInfo(F, Record, Idx);
7866f4a2713aSLionel Sambuc break;
7867f4a2713aSLionel Sambuc
7868f4a2713aSLionel Sambuc case CTOR_INITIALIZER_MEMBER:
7869f4a2713aSLionel Sambuc Member = ReadDeclAs<FieldDecl>(F, Record, Idx);
7870f4a2713aSLionel Sambuc break;
7871f4a2713aSLionel Sambuc
7872f4a2713aSLionel Sambuc case CTOR_INITIALIZER_INDIRECT_MEMBER:
7873f4a2713aSLionel Sambuc IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx);
7874f4a2713aSLionel Sambuc break;
7875f4a2713aSLionel Sambuc }
7876f4a2713aSLionel Sambuc
7877f4a2713aSLionel Sambuc SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx);
7878f4a2713aSLionel Sambuc Expr *Init = ReadExpr(F);
7879f4a2713aSLionel Sambuc SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
7880f4a2713aSLionel Sambuc SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
7881f4a2713aSLionel Sambuc bool IsWritten = Record[Idx++];
7882f4a2713aSLionel Sambuc unsigned SourceOrderOrNumArrayIndices;
7883f4a2713aSLionel Sambuc SmallVector<VarDecl *, 8> Indices;
7884f4a2713aSLionel Sambuc if (IsWritten) {
7885f4a2713aSLionel Sambuc SourceOrderOrNumArrayIndices = Record[Idx++];
7886f4a2713aSLionel Sambuc } else {
7887f4a2713aSLionel Sambuc SourceOrderOrNumArrayIndices = Record[Idx++];
7888f4a2713aSLionel Sambuc Indices.reserve(SourceOrderOrNumArrayIndices);
7889f4a2713aSLionel Sambuc for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
7890f4a2713aSLionel Sambuc Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx));
7891f4a2713aSLionel Sambuc }
7892f4a2713aSLionel Sambuc
7893f4a2713aSLionel Sambuc CXXCtorInitializer *BOMInit;
7894f4a2713aSLionel Sambuc if (Type == CTOR_INITIALIZER_BASE) {
7895f4a2713aSLionel Sambuc BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual,
7896f4a2713aSLionel Sambuc LParenLoc, Init, RParenLoc,
7897f4a2713aSLionel Sambuc MemberOrEllipsisLoc);
7898f4a2713aSLionel Sambuc } else if (Type == CTOR_INITIALIZER_DELEGATING) {
7899f4a2713aSLionel Sambuc BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc,
7900f4a2713aSLionel Sambuc Init, RParenLoc);
7901f4a2713aSLionel Sambuc } else if (IsWritten) {
7902f4a2713aSLionel Sambuc if (Member)
7903f4a2713aSLionel Sambuc BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc,
7904f4a2713aSLionel Sambuc LParenLoc, Init, RParenLoc);
7905f4a2713aSLionel Sambuc else
7906f4a2713aSLionel Sambuc BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember,
7907f4a2713aSLionel Sambuc MemberOrEllipsisLoc, LParenLoc,
7908f4a2713aSLionel Sambuc Init, RParenLoc);
7909f4a2713aSLionel Sambuc } else {
7910f4a2713aSLionel Sambuc if (IndirectMember) {
7911f4a2713aSLionel Sambuc assert(Indices.empty() && "Indirect field improperly initialized");
7912f4a2713aSLionel Sambuc BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember,
7913f4a2713aSLionel Sambuc MemberOrEllipsisLoc, LParenLoc,
7914f4a2713aSLionel Sambuc Init, RParenLoc);
7915f4a2713aSLionel Sambuc } else {
7916f4a2713aSLionel Sambuc BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,
7917f4a2713aSLionel Sambuc LParenLoc, Init, RParenLoc,
7918f4a2713aSLionel Sambuc Indices.data(), Indices.size());
7919f4a2713aSLionel Sambuc }
7920f4a2713aSLionel Sambuc }
7921f4a2713aSLionel Sambuc
7922f4a2713aSLionel Sambuc if (IsWritten)
7923f4a2713aSLionel Sambuc BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);
7924f4a2713aSLionel Sambuc CtorInitializers[i] = BOMInit;
7925f4a2713aSLionel Sambuc }
7926f4a2713aSLionel Sambuc }
7927f4a2713aSLionel Sambuc
7928f4a2713aSLionel Sambuc return std::make_pair(CtorInitializers, NumInitializers);
7929f4a2713aSLionel Sambuc }
7930f4a2713aSLionel Sambuc
7931f4a2713aSLionel Sambuc NestedNameSpecifier *
ReadNestedNameSpecifier(ModuleFile & F,const RecordData & Record,unsigned & Idx)7932f4a2713aSLionel Sambuc ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
7933f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
7934f4a2713aSLionel Sambuc unsigned N = Record[Idx++];
7935*0a6a1f1dSLionel Sambuc NestedNameSpecifier *NNS = nullptr, *Prev = nullptr;
7936f4a2713aSLionel Sambuc for (unsigned I = 0; I != N; ++I) {
7937f4a2713aSLionel Sambuc NestedNameSpecifier::SpecifierKind Kind
7938f4a2713aSLionel Sambuc = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
7939f4a2713aSLionel Sambuc switch (Kind) {
7940f4a2713aSLionel Sambuc case NestedNameSpecifier::Identifier: {
7941f4a2713aSLionel Sambuc IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
7942f4a2713aSLionel Sambuc NNS = NestedNameSpecifier::Create(Context, Prev, II);
7943f4a2713aSLionel Sambuc break;
7944f4a2713aSLionel Sambuc }
7945f4a2713aSLionel Sambuc
7946f4a2713aSLionel Sambuc case NestedNameSpecifier::Namespace: {
7947f4a2713aSLionel Sambuc NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
7948f4a2713aSLionel Sambuc NNS = NestedNameSpecifier::Create(Context, Prev, NS);
7949f4a2713aSLionel Sambuc break;
7950f4a2713aSLionel Sambuc }
7951f4a2713aSLionel Sambuc
7952f4a2713aSLionel Sambuc case NestedNameSpecifier::NamespaceAlias: {
7953f4a2713aSLionel Sambuc NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
7954f4a2713aSLionel Sambuc NNS = NestedNameSpecifier::Create(Context, Prev, Alias);
7955f4a2713aSLionel Sambuc break;
7956f4a2713aSLionel Sambuc }
7957f4a2713aSLionel Sambuc
7958f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpec:
7959f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpecWithTemplate: {
7960f4a2713aSLionel Sambuc const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
7961f4a2713aSLionel Sambuc if (!T)
7962*0a6a1f1dSLionel Sambuc return nullptr;
7963f4a2713aSLionel Sambuc
7964f4a2713aSLionel Sambuc bool Template = Record[Idx++];
7965f4a2713aSLionel Sambuc NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
7966f4a2713aSLionel Sambuc break;
7967f4a2713aSLionel Sambuc }
7968f4a2713aSLionel Sambuc
7969f4a2713aSLionel Sambuc case NestedNameSpecifier::Global: {
7970f4a2713aSLionel Sambuc NNS = NestedNameSpecifier::GlobalSpecifier(Context);
7971f4a2713aSLionel Sambuc // No associated value, and there can't be a prefix.
7972f4a2713aSLionel Sambuc break;
7973f4a2713aSLionel Sambuc }
7974*0a6a1f1dSLionel Sambuc
7975*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Super: {
7976*0a6a1f1dSLionel Sambuc CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx);
7977*0a6a1f1dSLionel Sambuc NNS = NestedNameSpecifier::SuperSpecifier(Context, RD);
7978*0a6a1f1dSLionel Sambuc break;
7979*0a6a1f1dSLionel Sambuc }
7980f4a2713aSLionel Sambuc }
7981f4a2713aSLionel Sambuc Prev = NNS;
7982f4a2713aSLionel Sambuc }
7983f4a2713aSLionel Sambuc return NNS;
7984f4a2713aSLionel Sambuc }
7985f4a2713aSLionel Sambuc
7986f4a2713aSLionel Sambuc NestedNameSpecifierLoc
ReadNestedNameSpecifierLoc(ModuleFile & F,const RecordData & Record,unsigned & Idx)7987f4a2713aSLionel Sambuc ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record,
7988f4a2713aSLionel Sambuc unsigned &Idx) {
7989f4a2713aSLionel Sambuc unsigned N = Record[Idx++];
7990f4a2713aSLionel Sambuc NestedNameSpecifierLocBuilder Builder;
7991f4a2713aSLionel Sambuc for (unsigned I = 0; I != N; ++I) {
7992f4a2713aSLionel Sambuc NestedNameSpecifier::SpecifierKind Kind
7993f4a2713aSLionel Sambuc = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
7994f4a2713aSLionel Sambuc switch (Kind) {
7995f4a2713aSLionel Sambuc case NestedNameSpecifier::Identifier: {
7996f4a2713aSLionel Sambuc IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
7997f4a2713aSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
7998f4a2713aSLionel Sambuc Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
7999f4a2713aSLionel Sambuc break;
8000f4a2713aSLionel Sambuc }
8001f4a2713aSLionel Sambuc
8002f4a2713aSLionel Sambuc case NestedNameSpecifier::Namespace: {
8003f4a2713aSLionel Sambuc NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
8004f4a2713aSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
8005f4a2713aSLionel Sambuc Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
8006f4a2713aSLionel Sambuc break;
8007f4a2713aSLionel Sambuc }
8008f4a2713aSLionel Sambuc
8009f4a2713aSLionel Sambuc case NestedNameSpecifier::NamespaceAlias: {
8010f4a2713aSLionel Sambuc NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
8011f4a2713aSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
8012f4a2713aSLionel Sambuc Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
8013f4a2713aSLionel Sambuc break;
8014f4a2713aSLionel Sambuc }
8015f4a2713aSLionel Sambuc
8016f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpec:
8017f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpecWithTemplate: {
8018f4a2713aSLionel Sambuc bool Template = Record[Idx++];
8019f4a2713aSLionel Sambuc TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
8020f4a2713aSLionel Sambuc if (!T)
8021f4a2713aSLionel Sambuc return NestedNameSpecifierLoc();
8022f4a2713aSLionel Sambuc SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
8023f4a2713aSLionel Sambuc
8024f4a2713aSLionel Sambuc // FIXME: 'template' keyword location not saved anywhere, so we fake it.
8025f4a2713aSLionel Sambuc Builder.Extend(Context,
8026f4a2713aSLionel Sambuc Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
8027f4a2713aSLionel Sambuc T->getTypeLoc(), ColonColonLoc);
8028f4a2713aSLionel Sambuc break;
8029f4a2713aSLionel Sambuc }
8030f4a2713aSLionel Sambuc
8031f4a2713aSLionel Sambuc case NestedNameSpecifier::Global: {
8032f4a2713aSLionel Sambuc SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
8033f4a2713aSLionel Sambuc Builder.MakeGlobal(Context, ColonColonLoc);
8034f4a2713aSLionel Sambuc break;
8035f4a2713aSLionel Sambuc }
8036*0a6a1f1dSLionel Sambuc
8037*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Super: {
8038*0a6a1f1dSLionel Sambuc CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx);
8039*0a6a1f1dSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
8040*0a6a1f1dSLionel Sambuc Builder.MakeSuper(Context, RD, Range.getBegin(), Range.getEnd());
8041*0a6a1f1dSLionel Sambuc break;
8042*0a6a1f1dSLionel Sambuc }
8043f4a2713aSLionel Sambuc }
8044f4a2713aSLionel Sambuc }
8045f4a2713aSLionel Sambuc
8046f4a2713aSLionel Sambuc return Builder.getWithLocInContext(Context);
8047f4a2713aSLionel Sambuc }
8048f4a2713aSLionel Sambuc
8049f4a2713aSLionel Sambuc SourceRange
ReadSourceRange(ModuleFile & F,const RecordData & Record,unsigned & Idx)8050f4a2713aSLionel Sambuc ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record,
8051f4a2713aSLionel Sambuc unsigned &Idx) {
8052f4a2713aSLionel Sambuc SourceLocation beg = ReadSourceLocation(F, Record, Idx);
8053f4a2713aSLionel Sambuc SourceLocation end = ReadSourceLocation(F, Record, Idx);
8054f4a2713aSLionel Sambuc return SourceRange(beg, end);
8055f4a2713aSLionel Sambuc }
8056f4a2713aSLionel Sambuc
8057f4a2713aSLionel Sambuc /// \brief Read an integral value
ReadAPInt(const RecordData & Record,unsigned & Idx)8058f4a2713aSLionel Sambuc llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
8059f4a2713aSLionel Sambuc unsigned BitWidth = Record[Idx++];
8060f4a2713aSLionel Sambuc unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
8061f4a2713aSLionel Sambuc llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
8062f4a2713aSLionel Sambuc Idx += NumWords;
8063f4a2713aSLionel Sambuc return Result;
8064f4a2713aSLionel Sambuc }
8065f4a2713aSLionel Sambuc
8066f4a2713aSLionel Sambuc /// \brief Read a signed integral value
ReadAPSInt(const RecordData & Record,unsigned & Idx)8067f4a2713aSLionel Sambuc llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
8068f4a2713aSLionel Sambuc bool isUnsigned = Record[Idx++];
8069f4a2713aSLionel Sambuc return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
8070f4a2713aSLionel Sambuc }
8071f4a2713aSLionel Sambuc
8072f4a2713aSLionel Sambuc /// \brief Read a floating-point value
ReadAPFloat(const RecordData & Record,const llvm::fltSemantics & Sem,unsigned & Idx)8073f4a2713aSLionel Sambuc llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record,
8074f4a2713aSLionel Sambuc const llvm::fltSemantics &Sem,
8075f4a2713aSLionel Sambuc unsigned &Idx) {
8076f4a2713aSLionel Sambuc return llvm::APFloat(Sem, ReadAPInt(Record, Idx));
8077f4a2713aSLionel Sambuc }
8078f4a2713aSLionel Sambuc
8079f4a2713aSLionel Sambuc // \brief Read a string
ReadString(const RecordData & Record,unsigned & Idx)8080f4a2713aSLionel Sambuc std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
8081f4a2713aSLionel Sambuc unsigned Len = Record[Idx++];
8082f4a2713aSLionel Sambuc std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
8083f4a2713aSLionel Sambuc Idx += Len;
8084f4a2713aSLionel Sambuc return Result;
8085f4a2713aSLionel Sambuc }
8086f4a2713aSLionel Sambuc
ReadPath(ModuleFile & F,const RecordData & Record,unsigned & Idx)8087*0a6a1f1dSLionel Sambuc std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record,
8088*0a6a1f1dSLionel Sambuc unsigned &Idx) {
8089*0a6a1f1dSLionel Sambuc std::string Filename = ReadString(Record, Idx);
8090*0a6a1f1dSLionel Sambuc ResolveImportedPath(F, Filename);
8091*0a6a1f1dSLionel Sambuc return Filename;
8092*0a6a1f1dSLionel Sambuc }
8093*0a6a1f1dSLionel Sambuc
ReadVersionTuple(const RecordData & Record,unsigned & Idx)8094f4a2713aSLionel Sambuc VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
8095f4a2713aSLionel Sambuc unsigned &Idx) {
8096f4a2713aSLionel Sambuc unsigned Major = Record[Idx++];
8097f4a2713aSLionel Sambuc unsigned Minor = Record[Idx++];
8098f4a2713aSLionel Sambuc unsigned Subminor = Record[Idx++];
8099f4a2713aSLionel Sambuc if (Minor == 0)
8100f4a2713aSLionel Sambuc return VersionTuple(Major);
8101f4a2713aSLionel Sambuc if (Subminor == 0)
8102f4a2713aSLionel Sambuc return VersionTuple(Major, Minor - 1);
8103f4a2713aSLionel Sambuc return VersionTuple(Major, Minor - 1, Subminor - 1);
8104f4a2713aSLionel Sambuc }
8105f4a2713aSLionel Sambuc
ReadCXXTemporary(ModuleFile & F,const RecordData & Record,unsigned & Idx)8106f4a2713aSLionel Sambuc CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F,
8107f4a2713aSLionel Sambuc const RecordData &Record,
8108f4a2713aSLionel Sambuc unsigned &Idx) {
8109f4a2713aSLionel Sambuc CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);
8110f4a2713aSLionel Sambuc return CXXTemporary::Create(Context, Decl);
8111f4a2713aSLionel Sambuc }
8112f4a2713aSLionel Sambuc
Diag(unsigned DiagID)8113f4a2713aSLionel Sambuc DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
8114f4a2713aSLionel Sambuc return Diag(CurrentImportLoc, DiagID);
8115f4a2713aSLionel Sambuc }
8116f4a2713aSLionel Sambuc
Diag(SourceLocation Loc,unsigned DiagID)8117f4a2713aSLionel Sambuc DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
8118f4a2713aSLionel Sambuc return Diags.Report(Loc, DiagID);
8119f4a2713aSLionel Sambuc }
8120f4a2713aSLionel Sambuc
8121f4a2713aSLionel Sambuc /// \brief Retrieve the identifier table associated with the
8122f4a2713aSLionel Sambuc /// preprocessor.
getIdentifierTable()8123f4a2713aSLionel Sambuc IdentifierTable &ASTReader::getIdentifierTable() {
8124f4a2713aSLionel Sambuc return PP.getIdentifierTable();
8125f4a2713aSLionel Sambuc }
8126f4a2713aSLionel Sambuc
8127f4a2713aSLionel Sambuc /// \brief Record that the given ID maps to the given switch-case
8128f4a2713aSLionel Sambuc /// statement.
RecordSwitchCaseID(SwitchCase * SC,unsigned ID)8129f4a2713aSLionel Sambuc void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
8130*0a6a1f1dSLionel Sambuc assert((*CurrSwitchCaseStmts)[ID] == nullptr &&
8131f4a2713aSLionel Sambuc "Already have a SwitchCase with this ID");
8132f4a2713aSLionel Sambuc (*CurrSwitchCaseStmts)[ID] = SC;
8133f4a2713aSLionel Sambuc }
8134f4a2713aSLionel Sambuc
8135f4a2713aSLionel Sambuc /// \brief Retrieve the switch-case statement with the given ID.
getSwitchCaseWithID(unsigned ID)8136f4a2713aSLionel Sambuc SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
8137*0a6a1f1dSLionel Sambuc assert((*CurrSwitchCaseStmts)[ID] != nullptr && "No SwitchCase with this ID");
8138f4a2713aSLionel Sambuc return (*CurrSwitchCaseStmts)[ID];
8139f4a2713aSLionel Sambuc }
8140f4a2713aSLionel Sambuc
ClearSwitchCaseIDs()8141f4a2713aSLionel Sambuc void ASTReader::ClearSwitchCaseIDs() {
8142f4a2713aSLionel Sambuc CurrSwitchCaseStmts->clear();
8143f4a2713aSLionel Sambuc }
8144f4a2713aSLionel Sambuc
ReadComments()8145f4a2713aSLionel Sambuc void ASTReader::ReadComments() {
8146f4a2713aSLionel Sambuc std::vector<RawComment *> Comments;
8147f4a2713aSLionel Sambuc for (SmallVectorImpl<std::pair<BitstreamCursor,
8148f4a2713aSLionel Sambuc serialization::ModuleFile *> >::iterator
8149f4a2713aSLionel Sambuc I = CommentsCursors.begin(),
8150f4a2713aSLionel Sambuc E = CommentsCursors.end();
8151f4a2713aSLionel Sambuc I != E; ++I) {
8152*0a6a1f1dSLionel Sambuc Comments.clear();
8153f4a2713aSLionel Sambuc BitstreamCursor &Cursor = I->first;
8154f4a2713aSLionel Sambuc serialization::ModuleFile &F = *I->second;
8155f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
8156f4a2713aSLionel Sambuc
8157f4a2713aSLionel Sambuc RecordData Record;
8158f4a2713aSLionel Sambuc while (true) {
8159f4a2713aSLionel Sambuc llvm::BitstreamEntry Entry =
8160f4a2713aSLionel Sambuc Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd);
8161f4a2713aSLionel Sambuc
8162f4a2713aSLionel Sambuc switch (Entry.Kind) {
8163f4a2713aSLionel Sambuc case llvm::BitstreamEntry::SubBlock: // Handled for us already.
8164f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Error:
8165f4a2713aSLionel Sambuc Error("malformed block record in AST file");
8166f4a2713aSLionel Sambuc return;
8167f4a2713aSLionel Sambuc case llvm::BitstreamEntry::EndBlock:
8168f4a2713aSLionel Sambuc goto NextCursor;
8169f4a2713aSLionel Sambuc case llvm::BitstreamEntry::Record:
8170f4a2713aSLionel Sambuc // The interesting case.
8171f4a2713aSLionel Sambuc break;
8172f4a2713aSLionel Sambuc }
8173f4a2713aSLionel Sambuc
8174f4a2713aSLionel Sambuc // Read a record.
8175f4a2713aSLionel Sambuc Record.clear();
8176f4a2713aSLionel Sambuc switch ((CommentRecordTypes)Cursor.readRecord(Entry.ID, Record)) {
8177f4a2713aSLionel Sambuc case COMMENTS_RAW_COMMENT: {
8178f4a2713aSLionel Sambuc unsigned Idx = 0;
8179f4a2713aSLionel Sambuc SourceRange SR = ReadSourceRange(F, Record, Idx);
8180f4a2713aSLionel Sambuc RawComment::CommentKind Kind =
8181f4a2713aSLionel Sambuc (RawComment::CommentKind) Record[Idx++];
8182f4a2713aSLionel Sambuc bool IsTrailingComment = Record[Idx++];
8183f4a2713aSLionel Sambuc bool IsAlmostTrailingComment = Record[Idx++];
8184f4a2713aSLionel Sambuc Comments.push_back(new (Context) RawComment(
8185f4a2713aSLionel Sambuc SR, Kind, IsTrailingComment, IsAlmostTrailingComment,
8186f4a2713aSLionel Sambuc Context.getLangOpts().CommentOpts.ParseAllComments));
8187f4a2713aSLionel Sambuc break;
8188f4a2713aSLionel Sambuc }
8189f4a2713aSLionel Sambuc }
8190f4a2713aSLionel Sambuc }
8191*0a6a1f1dSLionel Sambuc NextCursor:
8192*0a6a1f1dSLionel Sambuc Context.Comments.addDeserializedComments(Comments);
8193f4a2713aSLionel Sambuc }
8194*0a6a1f1dSLionel Sambuc }
8195*0a6a1f1dSLionel Sambuc
getInputFiles(ModuleFile & F,SmallVectorImpl<serialization::InputFile> & Files)8196*0a6a1f1dSLionel Sambuc void ASTReader::getInputFiles(ModuleFile &F,
8197*0a6a1f1dSLionel Sambuc SmallVectorImpl<serialization::InputFile> &Files) {
8198*0a6a1f1dSLionel Sambuc for (unsigned I = 0, E = F.InputFilesLoaded.size(); I != E; ++I) {
8199*0a6a1f1dSLionel Sambuc unsigned ID = I+1;
8200*0a6a1f1dSLionel Sambuc Files.push_back(getInputFile(F, ID));
8201*0a6a1f1dSLionel Sambuc }
8202*0a6a1f1dSLionel Sambuc }
8203*0a6a1f1dSLionel Sambuc
getOwningModuleNameForDiagnostic(const Decl * D)8204*0a6a1f1dSLionel Sambuc std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
8205*0a6a1f1dSLionel Sambuc // If we know the owning module, use it.
8206*0a6a1f1dSLionel Sambuc if (Module *M = D->getOwningModule())
8207*0a6a1f1dSLionel Sambuc return M->getFullModuleName();
8208*0a6a1f1dSLionel Sambuc
8209*0a6a1f1dSLionel Sambuc // Otherwise, use the name of the top-level module the decl is within.
8210*0a6a1f1dSLionel Sambuc if (ModuleFile *M = getOwningModuleFile(D))
8211*0a6a1f1dSLionel Sambuc return M->ModuleName;
8212*0a6a1f1dSLionel Sambuc
8213*0a6a1f1dSLionel Sambuc // Not from a module.
8214*0a6a1f1dSLionel Sambuc return "";
8215f4a2713aSLionel Sambuc }
8216f4a2713aSLionel Sambuc
finishPendingActions()8217f4a2713aSLionel Sambuc void ASTReader::finishPendingActions() {
8218*0a6a1f1dSLionel Sambuc while (!PendingIdentifierInfos.empty() ||
8219*0a6a1f1dSLionel Sambuc !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
8220f4a2713aSLionel Sambuc !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
8221*0a6a1f1dSLionel Sambuc !PendingUpdateRecords.empty()) {
8222f4a2713aSLionel Sambuc // If any identifiers with corresponding top-level declarations have
8223f4a2713aSLionel Sambuc // been loaded, load those declarations now.
8224f4a2713aSLionel Sambuc typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >
8225f4a2713aSLionel Sambuc TopLevelDeclsMap;
8226f4a2713aSLionel Sambuc TopLevelDeclsMap TopLevelDecls;
8227f4a2713aSLionel Sambuc
8228f4a2713aSLionel Sambuc while (!PendingIdentifierInfos.empty()) {
8229f4a2713aSLionel Sambuc IdentifierInfo *II = PendingIdentifierInfos.back().first;
8230*0a6a1f1dSLionel Sambuc SmallVector<uint32_t, 4> DeclIDs =
8231*0a6a1f1dSLionel Sambuc std::move(PendingIdentifierInfos.back().second);
8232f4a2713aSLionel Sambuc PendingIdentifierInfos.pop_back();
8233f4a2713aSLionel Sambuc
8234f4a2713aSLionel Sambuc SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]);
8235f4a2713aSLionel Sambuc }
8236f4a2713aSLionel Sambuc
8237*0a6a1f1dSLionel Sambuc // For each decl chain that we wanted to complete while deserializing, mark
8238*0a6a1f1dSLionel Sambuc // it as "still needs to be completed".
8239*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
8240*0a6a1f1dSLionel Sambuc markIncompleteDeclChain(PendingIncompleteDeclChains[I]);
8241*0a6a1f1dSLionel Sambuc }
8242*0a6a1f1dSLionel Sambuc PendingIncompleteDeclChains.clear();
8243*0a6a1f1dSLionel Sambuc
8244f4a2713aSLionel Sambuc // Load pending declaration chains.
8245f4a2713aSLionel Sambuc for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
8246f4a2713aSLionel Sambuc loadPendingDeclChain(PendingDeclChains[I]);
8247f4a2713aSLionel Sambuc PendingDeclChainsKnown.erase(PendingDeclChains[I]);
8248f4a2713aSLionel Sambuc }
8249f4a2713aSLionel Sambuc PendingDeclChains.clear();
8250f4a2713aSLionel Sambuc
8251f4a2713aSLionel Sambuc // Make the most recent of the top-level declarations visible.
8252f4a2713aSLionel Sambuc for (TopLevelDeclsMap::iterator TLD = TopLevelDecls.begin(),
8253f4a2713aSLionel Sambuc TLDEnd = TopLevelDecls.end(); TLD != TLDEnd; ++TLD) {
8254f4a2713aSLionel Sambuc IdentifierInfo *II = TLD->first;
8255f4a2713aSLionel Sambuc for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) {
8256f4a2713aSLionel Sambuc pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II);
8257f4a2713aSLionel Sambuc }
8258f4a2713aSLionel Sambuc }
8259f4a2713aSLionel Sambuc
8260f4a2713aSLionel Sambuc // Load any pending macro definitions.
8261f4a2713aSLionel Sambuc for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {
8262f4a2713aSLionel Sambuc IdentifierInfo *II = PendingMacroIDs.begin()[I].first;
8263f4a2713aSLionel Sambuc SmallVector<PendingMacroInfo, 2> GlobalIDs;
8264f4a2713aSLionel Sambuc GlobalIDs.swap(PendingMacroIDs.begin()[I].second);
8265f4a2713aSLionel Sambuc // Initialize the macro history from chained-PCHs ahead of module imports.
8266f4a2713aSLionel Sambuc for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
8267f4a2713aSLionel Sambuc ++IDIdx) {
8268f4a2713aSLionel Sambuc const PendingMacroInfo &Info = GlobalIDs[IDIdx];
8269*0a6a1f1dSLionel Sambuc if (Info.M->Kind != MK_ImplicitModule &&
8270*0a6a1f1dSLionel Sambuc Info.M->Kind != MK_ExplicitModule)
8271f4a2713aSLionel Sambuc resolvePendingMacro(II, Info);
8272f4a2713aSLionel Sambuc }
8273f4a2713aSLionel Sambuc // Handle module imports.
8274f4a2713aSLionel Sambuc for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
8275f4a2713aSLionel Sambuc ++IDIdx) {
8276f4a2713aSLionel Sambuc const PendingMacroInfo &Info = GlobalIDs[IDIdx];
8277*0a6a1f1dSLionel Sambuc if (Info.M->Kind == MK_ImplicitModule ||
8278*0a6a1f1dSLionel Sambuc Info.M->Kind == MK_ExplicitModule)
8279f4a2713aSLionel Sambuc resolvePendingMacro(II, Info);
8280f4a2713aSLionel Sambuc }
8281f4a2713aSLionel Sambuc }
8282f4a2713aSLionel Sambuc PendingMacroIDs.clear();
8283f4a2713aSLionel Sambuc
8284f4a2713aSLionel Sambuc // Wire up the DeclContexts for Decls that we delayed setting until
8285f4a2713aSLionel Sambuc // recursive loading is completed.
8286f4a2713aSLionel Sambuc while (!PendingDeclContextInfos.empty()) {
8287f4a2713aSLionel Sambuc PendingDeclContextInfo Info = PendingDeclContextInfos.front();
8288f4a2713aSLionel Sambuc PendingDeclContextInfos.pop_front();
8289f4a2713aSLionel Sambuc DeclContext *SemaDC = cast<DeclContext>(GetDecl(Info.SemaDC));
8290f4a2713aSLionel Sambuc DeclContext *LexicalDC = cast<DeclContext>(GetDecl(Info.LexicalDC));
8291f4a2713aSLionel Sambuc Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext());
8292f4a2713aSLionel Sambuc }
8293f4a2713aSLionel Sambuc
8294*0a6a1f1dSLionel Sambuc // Perform any pending declaration updates.
8295*0a6a1f1dSLionel Sambuc while (!PendingUpdateRecords.empty()) {
8296*0a6a1f1dSLionel Sambuc auto Update = PendingUpdateRecords.pop_back_val();
8297*0a6a1f1dSLionel Sambuc ReadingKindTracker ReadingKind(Read_Decl, *this);
8298*0a6a1f1dSLionel Sambuc loadDeclUpdateRecords(Update.first, Update.second);
8299f4a2713aSLionel Sambuc }
8300f4a2713aSLionel Sambuc }
8301f4a2713aSLionel Sambuc
8302f4a2713aSLionel Sambuc // If we deserialized any C++ or Objective-C class definitions, any
8303f4a2713aSLionel Sambuc // Objective-C protocol definitions, or any redeclarable templates, make sure
8304f4a2713aSLionel Sambuc // that all redeclarations point to the definitions. Note that this can only
8305f4a2713aSLionel Sambuc // happen now, after the redeclaration chains have been fully wired.
8306*0a6a1f1dSLionel Sambuc for (Decl *D : PendingDefinitions) {
8307*0a6a1f1dSLionel Sambuc if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
8308*0a6a1f1dSLionel Sambuc if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {
8309f4a2713aSLionel Sambuc // Make sure that the TagType points at the definition.
8310f4a2713aSLionel Sambuc const_cast<TagType*>(TagT)->decl = TD;
8311f4a2713aSLionel Sambuc }
8312f4a2713aSLionel Sambuc
8313*0a6a1f1dSLionel Sambuc if (auto RD = dyn_cast<CXXRecordDecl>(D)) {
8314*0a6a1f1dSLionel Sambuc for (auto R : RD->redecls()) {
8315*0a6a1f1dSLionel Sambuc assert((R == D) == R->isThisDeclarationADefinition() &&
8316*0a6a1f1dSLionel Sambuc "declaration thinks it's the definition but it isn't");
8317*0a6a1f1dSLionel Sambuc cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
8318*0a6a1f1dSLionel Sambuc }
8319f4a2713aSLionel Sambuc }
8320f4a2713aSLionel Sambuc
8321f4a2713aSLionel Sambuc continue;
8322f4a2713aSLionel Sambuc }
8323f4a2713aSLionel Sambuc
8324*0a6a1f1dSLionel Sambuc if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) {
8325f4a2713aSLionel Sambuc // Make sure that the ObjCInterfaceType points at the definition.
8326f4a2713aSLionel Sambuc const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
8327f4a2713aSLionel Sambuc ->Decl = ID;
8328f4a2713aSLionel Sambuc
8329*0a6a1f1dSLionel Sambuc for (auto R : ID->redecls())
8330f4a2713aSLionel Sambuc R->Data = ID->Data;
8331f4a2713aSLionel Sambuc
8332f4a2713aSLionel Sambuc continue;
8333f4a2713aSLionel Sambuc }
8334f4a2713aSLionel Sambuc
8335*0a6a1f1dSLionel Sambuc if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) {
8336*0a6a1f1dSLionel Sambuc for (auto R : PD->redecls())
8337f4a2713aSLionel Sambuc R->Data = PD->Data;
8338f4a2713aSLionel Sambuc
8339f4a2713aSLionel Sambuc continue;
8340f4a2713aSLionel Sambuc }
8341f4a2713aSLionel Sambuc
8342*0a6a1f1dSLionel Sambuc auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl();
8343*0a6a1f1dSLionel Sambuc for (auto R : RTD->redecls())
8344f4a2713aSLionel Sambuc R->Common = RTD->Common;
8345f4a2713aSLionel Sambuc }
8346f4a2713aSLionel Sambuc PendingDefinitions.clear();
8347f4a2713aSLionel Sambuc
8348f4a2713aSLionel Sambuc // Load the bodies of any functions or methods we've encountered. We do
8349f4a2713aSLionel Sambuc // this now (delayed) so that we can be sure that the declaration chains
8350f4a2713aSLionel Sambuc // have been fully wired up.
8351f4a2713aSLionel Sambuc for (PendingBodiesMap::iterator PB = PendingBodies.begin(),
8352f4a2713aSLionel Sambuc PBEnd = PendingBodies.end();
8353f4a2713aSLionel Sambuc PB != PBEnd; ++PB) {
8354f4a2713aSLionel Sambuc if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
8355f4a2713aSLionel Sambuc // FIXME: Check for =delete/=default?
8356f4a2713aSLionel Sambuc // FIXME: Complain about ODR violations here?
8357f4a2713aSLionel Sambuc if (!getContext().getLangOpts().Modules || !FD->hasBody())
8358f4a2713aSLionel Sambuc FD->setLazyBody(PB->second);
8359f4a2713aSLionel Sambuc continue;
8360f4a2713aSLionel Sambuc }
8361f4a2713aSLionel Sambuc
8362f4a2713aSLionel Sambuc ObjCMethodDecl *MD = cast<ObjCMethodDecl>(PB->first);
8363f4a2713aSLionel Sambuc if (!getContext().getLangOpts().Modules || !MD->hasBody())
8364f4a2713aSLionel Sambuc MD->setLazyBody(PB->second);
8365f4a2713aSLionel Sambuc }
8366f4a2713aSLionel Sambuc PendingBodies.clear();
8367f4a2713aSLionel Sambuc }
8368f4a2713aSLionel Sambuc
diagnoseOdrViolations()8369*0a6a1f1dSLionel Sambuc void ASTReader::diagnoseOdrViolations() {
8370*0a6a1f1dSLionel Sambuc if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty())
8371*0a6a1f1dSLionel Sambuc return;
8372*0a6a1f1dSLionel Sambuc
8373*0a6a1f1dSLionel Sambuc // Trigger the import of the full definition of each class that had any
8374*0a6a1f1dSLionel Sambuc // odr-merging problems, so we can produce better diagnostics for them.
8375*0a6a1f1dSLionel Sambuc // These updates may in turn find and diagnose some ODR failures, so take
8376*0a6a1f1dSLionel Sambuc // ownership of the set first.
8377*0a6a1f1dSLionel Sambuc auto OdrMergeFailures = std::move(PendingOdrMergeFailures);
8378*0a6a1f1dSLionel Sambuc PendingOdrMergeFailures.clear();
8379*0a6a1f1dSLionel Sambuc for (auto &Merge : OdrMergeFailures) {
8380*0a6a1f1dSLionel Sambuc Merge.first->buildLookup();
8381*0a6a1f1dSLionel Sambuc Merge.first->decls_begin();
8382*0a6a1f1dSLionel Sambuc Merge.first->bases_begin();
8383*0a6a1f1dSLionel Sambuc Merge.first->vbases_begin();
8384*0a6a1f1dSLionel Sambuc for (auto *RD : Merge.second) {
8385*0a6a1f1dSLionel Sambuc RD->decls_begin();
8386*0a6a1f1dSLionel Sambuc RD->bases_begin();
8387*0a6a1f1dSLionel Sambuc RD->vbases_begin();
8388*0a6a1f1dSLionel Sambuc }
8389*0a6a1f1dSLionel Sambuc }
8390*0a6a1f1dSLionel Sambuc
8391*0a6a1f1dSLionel Sambuc // For each declaration from a merged context, check that the canonical
8392*0a6a1f1dSLionel Sambuc // definition of that context also contains a declaration of the same
8393*0a6a1f1dSLionel Sambuc // entity.
8394*0a6a1f1dSLionel Sambuc //
8395*0a6a1f1dSLionel Sambuc // Caution: this loop does things that might invalidate iterators into
8396*0a6a1f1dSLionel Sambuc // PendingOdrMergeChecks. Don't turn this into a range-based for loop!
8397*0a6a1f1dSLionel Sambuc while (!PendingOdrMergeChecks.empty()) {
8398*0a6a1f1dSLionel Sambuc NamedDecl *D = PendingOdrMergeChecks.pop_back_val();
8399*0a6a1f1dSLionel Sambuc
8400*0a6a1f1dSLionel Sambuc // FIXME: Skip over implicit declarations for now. This matters for things
8401*0a6a1f1dSLionel Sambuc // like implicitly-declared special member functions. This isn't entirely
8402*0a6a1f1dSLionel Sambuc // correct; we can end up with multiple unmerged declarations of the same
8403*0a6a1f1dSLionel Sambuc // implicit entity.
8404*0a6a1f1dSLionel Sambuc if (D->isImplicit())
8405*0a6a1f1dSLionel Sambuc continue;
8406*0a6a1f1dSLionel Sambuc
8407*0a6a1f1dSLionel Sambuc DeclContext *CanonDef = D->getDeclContext();
8408*0a6a1f1dSLionel Sambuc
8409*0a6a1f1dSLionel Sambuc bool Found = false;
8410*0a6a1f1dSLionel Sambuc const Decl *DCanon = D->getCanonicalDecl();
8411*0a6a1f1dSLionel Sambuc
8412*0a6a1f1dSLionel Sambuc for (auto RI : D->redecls()) {
8413*0a6a1f1dSLionel Sambuc if (RI->getLexicalDeclContext() == CanonDef) {
8414*0a6a1f1dSLionel Sambuc Found = true;
8415*0a6a1f1dSLionel Sambuc break;
8416*0a6a1f1dSLionel Sambuc }
8417*0a6a1f1dSLionel Sambuc }
8418*0a6a1f1dSLionel Sambuc if (Found)
8419*0a6a1f1dSLionel Sambuc continue;
8420*0a6a1f1dSLionel Sambuc
8421*0a6a1f1dSLionel Sambuc llvm::SmallVector<const NamedDecl*, 4> Candidates;
8422*0a6a1f1dSLionel Sambuc DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName());
8423*0a6a1f1dSLionel Sambuc for (DeclContext::lookup_iterator I = R.begin(), E = R.end();
8424*0a6a1f1dSLionel Sambuc !Found && I != E; ++I) {
8425*0a6a1f1dSLionel Sambuc for (auto RI : (*I)->redecls()) {
8426*0a6a1f1dSLionel Sambuc if (RI->getLexicalDeclContext() == CanonDef) {
8427*0a6a1f1dSLionel Sambuc // This declaration is present in the canonical definition. If it's
8428*0a6a1f1dSLionel Sambuc // in the same redecl chain, it's the one we're looking for.
8429*0a6a1f1dSLionel Sambuc if (RI->getCanonicalDecl() == DCanon)
8430*0a6a1f1dSLionel Sambuc Found = true;
8431*0a6a1f1dSLionel Sambuc else
8432*0a6a1f1dSLionel Sambuc Candidates.push_back(cast<NamedDecl>(RI));
8433*0a6a1f1dSLionel Sambuc break;
8434*0a6a1f1dSLionel Sambuc }
8435*0a6a1f1dSLionel Sambuc }
8436*0a6a1f1dSLionel Sambuc }
8437*0a6a1f1dSLionel Sambuc
8438*0a6a1f1dSLionel Sambuc if (!Found) {
8439*0a6a1f1dSLionel Sambuc // The AST doesn't like TagDecls becoming invalid after they've been
8440*0a6a1f1dSLionel Sambuc // completed. We only really need to mark FieldDecls as invalid here.
8441*0a6a1f1dSLionel Sambuc if (!isa<TagDecl>(D))
8442*0a6a1f1dSLionel Sambuc D->setInvalidDecl();
8443*0a6a1f1dSLionel Sambuc
8444*0a6a1f1dSLionel Sambuc std::string CanonDefModule =
8445*0a6a1f1dSLionel Sambuc getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef));
8446*0a6a1f1dSLionel Sambuc Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl)
8447*0a6a1f1dSLionel Sambuc << D << getOwningModuleNameForDiagnostic(D)
8448*0a6a1f1dSLionel Sambuc << CanonDef << CanonDefModule.empty() << CanonDefModule;
8449*0a6a1f1dSLionel Sambuc
8450*0a6a1f1dSLionel Sambuc if (Candidates.empty())
8451*0a6a1f1dSLionel Sambuc Diag(cast<Decl>(CanonDef)->getLocation(),
8452*0a6a1f1dSLionel Sambuc diag::note_module_odr_violation_no_possible_decls) << D;
8453*0a6a1f1dSLionel Sambuc else {
8454*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Candidates.size(); I != N; ++I)
8455*0a6a1f1dSLionel Sambuc Diag(Candidates[I]->getLocation(),
8456*0a6a1f1dSLionel Sambuc diag::note_module_odr_violation_possible_decl)
8457*0a6a1f1dSLionel Sambuc << Candidates[I];
8458*0a6a1f1dSLionel Sambuc }
8459*0a6a1f1dSLionel Sambuc
8460*0a6a1f1dSLionel Sambuc DiagnosedOdrMergeFailures.insert(CanonDef);
8461*0a6a1f1dSLionel Sambuc }
8462*0a6a1f1dSLionel Sambuc }
8463*0a6a1f1dSLionel Sambuc
8464*0a6a1f1dSLionel Sambuc // Issue any pending ODR-failure diagnostics.
8465*0a6a1f1dSLionel Sambuc for (auto &Merge : OdrMergeFailures) {
8466*0a6a1f1dSLionel Sambuc // If we've already pointed out a specific problem with this class, don't
8467*0a6a1f1dSLionel Sambuc // bother issuing a general "something's different" diagnostic.
8468*0a6a1f1dSLionel Sambuc if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
8469*0a6a1f1dSLionel Sambuc continue;
8470*0a6a1f1dSLionel Sambuc
8471*0a6a1f1dSLionel Sambuc bool Diagnosed = false;
8472*0a6a1f1dSLionel Sambuc for (auto *RD : Merge.second) {
8473*0a6a1f1dSLionel Sambuc // Multiple different declarations got merged together; tell the user
8474*0a6a1f1dSLionel Sambuc // where they came from.
8475*0a6a1f1dSLionel Sambuc if (Merge.first != RD) {
8476*0a6a1f1dSLionel Sambuc // FIXME: Walk the definition, figure out what's different,
8477*0a6a1f1dSLionel Sambuc // and diagnose that.
8478*0a6a1f1dSLionel Sambuc if (!Diagnosed) {
8479*0a6a1f1dSLionel Sambuc std::string Module = getOwningModuleNameForDiagnostic(Merge.first);
8480*0a6a1f1dSLionel Sambuc Diag(Merge.first->getLocation(),
8481*0a6a1f1dSLionel Sambuc diag::err_module_odr_violation_different_definitions)
8482*0a6a1f1dSLionel Sambuc << Merge.first << Module.empty() << Module;
8483*0a6a1f1dSLionel Sambuc Diagnosed = true;
8484*0a6a1f1dSLionel Sambuc }
8485*0a6a1f1dSLionel Sambuc
8486*0a6a1f1dSLionel Sambuc Diag(RD->getLocation(),
8487*0a6a1f1dSLionel Sambuc diag::note_module_odr_violation_different_definitions)
8488*0a6a1f1dSLionel Sambuc << getOwningModuleNameForDiagnostic(RD);
8489*0a6a1f1dSLionel Sambuc }
8490*0a6a1f1dSLionel Sambuc }
8491*0a6a1f1dSLionel Sambuc
8492*0a6a1f1dSLionel Sambuc if (!Diagnosed) {
8493*0a6a1f1dSLionel Sambuc // All definitions are updates to the same declaration. This happens if a
8494*0a6a1f1dSLionel Sambuc // module instantiates the declaration of a class template specialization
8495*0a6a1f1dSLionel Sambuc // and two or more other modules instantiate its definition.
8496*0a6a1f1dSLionel Sambuc //
8497*0a6a1f1dSLionel Sambuc // FIXME: Indicate which modules had instantiations of this definition.
8498*0a6a1f1dSLionel Sambuc // FIXME: How can this even happen?
8499*0a6a1f1dSLionel Sambuc Diag(Merge.first->getLocation(),
8500*0a6a1f1dSLionel Sambuc diag::err_module_odr_violation_different_instantiations)
8501*0a6a1f1dSLionel Sambuc << Merge.first;
8502*0a6a1f1dSLionel Sambuc }
8503*0a6a1f1dSLionel Sambuc }
8504*0a6a1f1dSLionel Sambuc }
8505*0a6a1f1dSLionel Sambuc
FinishedDeserializing()8506f4a2713aSLionel Sambuc void ASTReader::FinishedDeserializing() {
8507f4a2713aSLionel Sambuc assert(NumCurrentElementsDeserializing &&
8508f4a2713aSLionel Sambuc "FinishedDeserializing not paired with StartedDeserializing");
8509f4a2713aSLionel Sambuc if (NumCurrentElementsDeserializing == 1) {
8510f4a2713aSLionel Sambuc // We decrease NumCurrentElementsDeserializing only after pending actions
8511f4a2713aSLionel Sambuc // are finished, to avoid recursively re-calling finishPendingActions().
8512f4a2713aSLionel Sambuc finishPendingActions();
8513f4a2713aSLionel Sambuc }
8514f4a2713aSLionel Sambuc --NumCurrentElementsDeserializing;
8515f4a2713aSLionel Sambuc
8516*0a6a1f1dSLionel Sambuc if (NumCurrentElementsDeserializing == 0) {
8517*0a6a1f1dSLionel Sambuc diagnoseOdrViolations();
8518f4a2713aSLionel Sambuc
8519f4a2713aSLionel Sambuc // We are not in recursive loading, so it's safe to pass the "interesting"
8520f4a2713aSLionel Sambuc // decls to the consumer.
8521*0a6a1f1dSLionel Sambuc if (Consumer)
8522*0a6a1f1dSLionel Sambuc PassInterestingDeclsToConsumer();
8523f4a2713aSLionel Sambuc }
8524f4a2713aSLionel Sambuc }
8525f4a2713aSLionel Sambuc
pushExternalDeclIntoScope(NamedDecl * D,DeclarationName Name)8526f4a2713aSLionel Sambuc void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
8527f4a2713aSLionel Sambuc D = D->getMostRecentDecl();
8528f4a2713aSLionel Sambuc
8529f4a2713aSLionel Sambuc if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) {
8530f4a2713aSLionel Sambuc SemaObj->TUScope->AddDecl(D);
8531f4a2713aSLionel Sambuc } else if (SemaObj->TUScope) {
8532f4a2713aSLionel Sambuc // Adding the decl to IdResolver may have failed because it was already in
8533f4a2713aSLionel Sambuc // (even though it was not added in scope). If it is already in, make sure
8534f4a2713aSLionel Sambuc // it gets in the scope as well.
8535f4a2713aSLionel Sambuc if (std::find(SemaObj->IdResolver.begin(Name),
8536f4a2713aSLionel Sambuc SemaObj->IdResolver.end(), D) != SemaObj->IdResolver.end())
8537f4a2713aSLionel Sambuc SemaObj->TUScope->AddDecl(D);
8538f4a2713aSLionel Sambuc }
8539f4a2713aSLionel Sambuc }
8540f4a2713aSLionel Sambuc
ASTReader(Preprocessor & PP,ASTContext & Context,StringRef isysroot,bool DisableValidation,bool AllowASTWithCompilerErrors,bool AllowConfigurationMismatch,bool ValidateSystemInputs,bool UseGlobalIndex)8541*0a6a1f1dSLionel Sambuc ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot,
8542*0a6a1f1dSLionel Sambuc bool DisableValidation, bool AllowASTWithCompilerErrors,
8543*0a6a1f1dSLionel Sambuc bool AllowConfigurationMismatch, bool ValidateSystemInputs,
8544*0a6a1f1dSLionel Sambuc bool UseGlobalIndex)
8545*0a6a1f1dSLionel Sambuc : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
8546*0a6a1f1dSLionel Sambuc OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
8547*0a6a1f1dSLionel Sambuc FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
8548*0a6a1f1dSLionel Sambuc SemaObj(nullptr), PP(PP), Context(Context), Consumer(nullptr),
8549*0a6a1f1dSLionel Sambuc ModuleMgr(PP.getFileManager()), isysroot(isysroot),
8550*0a6a1f1dSLionel Sambuc DisableValidation(DisableValidation),
8551f4a2713aSLionel Sambuc AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
8552*0a6a1f1dSLionel Sambuc AllowConfigurationMismatch(AllowConfigurationMismatch),
8553*0a6a1f1dSLionel Sambuc ValidateSystemInputs(ValidateSystemInputs),
8554f4a2713aSLionel Sambuc UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
8555*0a6a1f1dSLionel Sambuc CurrSwitchCaseStmts(&SwitchCaseStmts),
8556*0a6a1f1dSLionel Sambuc NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0),
8557*0a6a1f1dSLionel Sambuc TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0),
8558*0a6a1f1dSLionel Sambuc NumIdentifierLookups(0), NumIdentifierLookupHits(0), NumSelectorsRead(0),
8559*0a6a1f1dSLionel Sambuc NumMethodPoolEntriesRead(0), NumMethodPoolLookups(0),
8560*0a6a1f1dSLionel Sambuc NumMethodPoolHits(0), NumMethodPoolTableLookups(0),
8561*0a6a1f1dSLionel Sambuc NumMethodPoolTableHits(0), TotalNumMethodPoolEntries(0),
8562f4a2713aSLionel Sambuc NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
8563f4a2713aSLionel Sambuc NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
8564f4a2713aSLionel Sambuc TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
8565*0a6a1f1dSLionel Sambuc PassingDeclsToConsumer(false), NumCXXBaseSpecifiersLoaded(0),
8566*0a6a1f1dSLionel Sambuc ReadingKind(Read_None) {
8567f4a2713aSLionel Sambuc SourceMgr.setExternalSLocEntrySource(this);
8568f4a2713aSLionel Sambuc }
8569f4a2713aSLionel Sambuc
~ASTReader()8570f4a2713aSLionel Sambuc ASTReader::~ASTReader() {
8571*0a6a1f1dSLionel Sambuc if (OwnsDeserializationListener)
8572*0a6a1f1dSLionel Sambuc delete DeserializationListener;
8573*0a6a1f1dSLionel Sambuc
8574f4a2713aSLionel Sambuc for (DeclContextVisibleUpdatesPending::iterator
8575f4a2713aSLionel Sambuc I = PendingVisibleUpdates.begin(),
8576f4a2713aSLionel Sambuc E = PendingVisibleUpdates.end();
8577f4a2713aSLionel Sambuc I != E; ++I) {
8578f4a2713aSLionel Sambuc for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
8579f4a2713aSLionel Sambuc F = I->second.end();
8580f4a2713aSLionel Sambuc J != F; ++J)
8581f4a2713aSLionel Sambuc delete J->first;
8582f4a2713aSLionel Sambuc }
8583f4a2713aSLionel Sambuc }
8584