1f4a2713aSLionel Sambuc //===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- C++ -*-===//
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 ChainedIncludesSource class, which converts headers
11f4a2713aSLionel Sambuc //  to chained PCHs in memory, mainly used for testing.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
16f4a2713aSLionel Sambuc #include "clang/Frontend/ASTUnit.h"
17f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
18f4a2713aSLionel Sambuc #include "clang/Frontend/TextDiagnosticPrinter.h"
19f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
20f4a2713aSLionel Sambuc #include "clang/Parse/ParseAST.h"
21f4a2713aSLionel Sambuc #include "clang/Serialization/ASTReader.h"
22f4a2713aSLionel Sambuc #include "clang/Serialization/ASTWriter.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc using namespace clang;
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc namespace {
28*0a6a1f1dSLionel Sambuc class ChainedIncludesSource : public ExternalSemaSource {
29*0a6a1f1dSLionel Sambuc public:
30*0a6a1f1dSLionel Sambuc   virtual ~ChainedIncludesSource();
31*0a6a1f1dSLionel Sambuc 
getFinalReader() const32*0a6a1f1dSLionel Sambuc   ExternalSemaSource &getFinalReader() const { return *FinalReader; }
33*0a6a1f1dSLionel Sambuc 
34*0a6a1f1dSLionel Sambuc   std::vector<CompilerInstance *> CIs;
35*0a6a1f1dSLionel Sambuc   IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
36*0a6a1f1dSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc protected:
38*0a6a1f1dSLionel Sambuc   //===----------------------------------------------------------------------===//
39*0a6a1f1dSLionel Sambuc   // ExternalASTSource interface.
40*0a6a1f1dSLionel Sambuc   //===----------------------------------------------------------------------===//
41*0a6a1f1dSLionel Sambuc 
42*0a6a1f1dSLionel Sambuc   Decl *GetExternalDecl(uint32_t ID) override;
43*0a6a1f1dSLionel Sambuc   Selector GetExternalSelector(uint32_t ID) override;
44*0a6a1f1dSLionel Sambuc   uint32_t GetNumExternalSelectors() override;
45*0a6a1f1dSLionel Sambuc   Stmt *GetExternalDeclStmt(uint64_t Offset) override;
46*0a6a1f1dSLionel Sambuc   CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
47*0a6a1f1dSLionel Sambuc   bool FindExternalVisibleDeclsByName(const DeclContext *DC,
48*0a6a1f1dSLionel Sambuc                                       DeclarationName Name) override;
49*0a6a1f1dSLionel Sambuc   ExternalLoadResult
50*0a6a1f1dSLionel Sambuc   FindExternalLexicalDecls(const DeclContext *DC,
51*0a6a1f1dSLionel Sambuc                            bool (*isKindWeWant)(Decl::Kind),
52*0a6a1f1dSLionel Sambuc                            SmallVectorImpl<Decl *> &Result) override;
53*0a6a1f1dSLionel Sambuc   void CompleteType(TagDecl *Tag) override;
54*0a6a1f1dSLionel Sambuc   void CompleteType(ObjCInterfaceDecl *Class) override;
55*0a6a1f1dSLionel Sambuc   void StartedDeserializing() override;
56*0a6a1f1dSLionel Sambuc   void FinishedDeserializing() override;
57*0a6a1f1dSLionel Sambuc   void StartTranslationUnit(ASTConsumer *Consumer) override;
58*0a6a1f1dSLionel Sambuc   void PrintStats() override;
59*0a6a1f1dSLionel Sambuc 
60*0a6a1f1dSLionel Sambuc   /// Return the amount of memory used by memory buffers, breaking down
61*0a6a1f1dSLionel Sambuc   /// by heap-backed versus mmap'ed memory.
62*0a6a1f1dSLionel Sambuc   void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
63*0a6a1f1dSLionel Sambuc 
64*0a6a1f1dSLionel Sambuc   //===----------------------------------------------------------------------===//
65*0a6a1f1dSLionel Sambuc   // ExternalSemaSource interface.
66*0a6a1f1dSLionel Sambuc   //===----------------------------------------------------------------------===//
67*0a6a1f1dSLionel Sambuc 
68*0a6a1f1dSLionel Sambuc   void InitializeSema(Sema &S) override;
69*0a6a1f1dSLionel Sambuc   void ForgetSema() override;
70*0a6a1f1dSLionel Sambuc   void ReadMethodPool(Selector Sel) override;
71*0a6a1f1dSLionel Sambuc   bool LookupUnqualified(LookupResult &R, Scope *S) override;
72*0a6a1f1dSLionel Sambuc };
73*0a6a1f1dSLionel Sambuc }
74*0a6a1f1dSLionel Sambuc 
75*0a6a1f1dSLionel Sambuc static ASTReader *
createASTReader(CompilerInstance & CI,StringRef pchFile,SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> & MemBufs,SmallVectorImpl<std::string> & bufNames,ASTDeserializationListener * deserialListener=nullptr)76*0a6a1f1dSLionel Sambuc createASTReader(CompilerInstance &CI, StringRef pchFile,
77*0a6a1f1dSLionel Sambuc                 SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &MemBufs,
78f4a2713aSLionel Sambuc                 SmallVectorImpl<std::string> &bufNames,
79*0a6a1f1dSLionel Sambuc                 ASTDeserializationListener *deserialListener = nullptr) {
80f4a2713aSLionel Sambuc   Preprocessor &PP = CI.getPreprocessor();
81*0a6a1f1dSLionel Sambuc   std::unique_ptr<ASTReader> Reader;
82f4a2713aSLionel Sambuc   Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
83f4a2713aSLionel Sambuc                              /*DisableValidation=*/true));
84f4a2713aSLionel Sambuc   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
85f4a2713aSLionel Sambuc     StringRef sr(bufNames[ti]);
86*0a6a1f1dSLionel Sambuc     Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
87f4a2713aSLionel Sambuc   }
88f4a2713aSLionel Sambuc   Reader->setDeserializationListener(deserialListener);
89f4a2713aSLionel Sambuc   switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(),
90f4a2713aSLionel Sambuc                           ASTReader::ARR_None)) {
91f4a2713aSLionel Sambuc   case ASTReader::Success:
92f4a2713aSLionel Sambuc     // Set the predefines buffer as suggested by the PCH reader.
93f4a2713aSLionel Sambuc     PP.setPredefines(Reader->getSuggestedPredefines());
94*0a6a1f1dSLionel Sambuc     return Reader.release();
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc   case ASTReader::Failure:
97f4a2713aSLionel Sambuc   case ASTReader::Missing:
98f4a2713aSLionel Sambuc   case ASTReader::OutOfDate:
99f4a2713aSLionel Sambuc   case ASTReader::VersionMismatch:
100f4a2713aSLionel Sambuc   case ASTReader::ConfigurationMismatch:
101f4a2713aSLionel Sambuc   case ASTReader::HadErrors:
102f4a2713aSLionel Sambuc     break;
103f4a2713aSLionel Sambuc   }
104*0a6a1f1dSLionel Sambuc   return nullptr;
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc 
~ChainedIncludesSource()107f4a2713aSLionel Sambuc ChainedIncludesSource::~ChainedIncludesSource() {
108f4a2713aSLionel Sambuc   for (unsigned i = 0, e = CIs.size(); i != e; ++i)
109f4a2713aSLionel Sambuc     delete CIs[i];
110f4a2713aSLionel Sambuc }
111f4a2713aSLionel Sambuc 
createChainedIncludesSource(CompilerInstance & CI,IntrusiveRefCntPtr<ExternalSemaSource> & Reader)112*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
113*0a6a1f1dSLionel Sambuc     CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) {
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc   std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
116f4a2713aSLionel Sambuc   assert(!includes.empty() && "No '-chain-include' in options!");
117f4a2713aSLionel Sambuc 
118*0a6a1f1dSLionel Sambuc   IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
119f4a2713aSLionel Sambuc   InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();
120f4a2713aSLionel Sambuc 
121*0a6a1f1dSLionel Sambuc   SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs;
122f4a2713aSLionel Sambuc   SmallVector<std::string, 4> serialBufNames;
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   for (unsigned i = 0, e = includes.size(); i != e; ++i) {
125f4a2713aSLionel Sambuc     bool firstInclude = (i == 0);
126*0a6a1f1dSLionel Sambuc     std::unique_ptr<CompilerInvocation> CInvok;
127f4a2713aSLionel Sambuc     CInvok.reset(new CompilerInvocation(CI.getInvocation()));
128f4a2713aSLionel Sambuc 
129f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().ChainedIncludes.clear();
130f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
131f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
132f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().DisablePCHValidation = true;
133f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().Includes.clear();
134f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().MacroIncludes.clear();
135f4a2713aSLionel Sambuc     CInvok->getPreprocessorOpts().Macros.clear();
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc     CInvok->getFrontendOpts().Inputs.clear();
138f4a2713aSLionel Sambuc     FrontendInputFile InputFile(includes[i], IK);
139f4a2713aSLionel Sambuc     CInvok->getFrontendOpts().Inputs.push_back(InputFile);
140f4a2713aSLionel Sambuc 
141f4a2713aSLionel Sambuc     TextDiagnosticPrinter *DiagClient =
142f4a2713aSLionel Sambuc       new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
143f4a2713aSLionel Sambuc     IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
144f4a2713aSLionel Sambuc     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
145f4a2713aSLionel Sambuc         new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));
146f4a2713aSLionel Sambuc 
147*0a6a1f1dSLionel Sambuc     std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
148*0a6a1f1dSLionel Sambuc     Clang->setInvocation(CInvok.release());
149*0a6a1f1dSLionel Sambuc     Clang->setDiagnostics(Diags.get());
150*0a6a1f1dSLionel Sambuc     Clang->setTarget(TargetInfo::CreateTargetInfo(
151*0a6a1f1dSLionel Sambuc         Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
152f4a2713aSLionel Sambuc     Clang->createFileManager();
153f4a2713aSLionel Sambuc     Clang->createSourceManager(Clang->getFileManager());
154*0a6a1f1dSLionel Sambuc     Clang->createPreprocessor(TU_Prefix);
155f4a2713aSLionel Sambuc     Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
156f4a2713aSLionel Sambuc                                                  &Clang->getPreprocessor());
157f4a2713aSLionel Sambuc     Clang->createASTContext();
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc     SmallVector<char, 256> serialAST;
160f4a2713aSLionel Sambuc     llvm::raw_svector_ostream OS(serialAST);
161*0a6a1f1dSLionel Sambuc     auto consumer =
162*0a6a1f1dSLionel Sambuc         llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr,
163*0a6a1f1dSLionel Sambuc                                         /*isysroot=*/"", &OS);
164f4a2713aSLionel Sambuc     Clang->getASTContext().setASTMutationListener(
165f4a2713aSLionel Sambuc                                             consumer->GetASTMutationListener());
166*0a6a1f1dSLionel Sambuc     Clang->setASTConsumer(std::move(consumer));
167*0a6a1f1dSLionel Sambuc     Clang->createSema(TU_Prefix, nullptr);
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc     if (firstInclude) {
170f4a2713aSLionel Sambuc       Preprocessor &PP = Clang->getPreprocessor();
171f4a2713aSLionel Sambuc       PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
172f4a2713aSLionel Sambuc                                              PP.getLangOpts());
173f4a2713aSLionel Sambuc     } else {
174*0a6a1f1dSLionel Sambuc       assert(!SerialBufs.empty());
175*0a6a1f1dSLionel Sambuc       SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> Bufs;
176*0a6a1f1dSLionel Sambuc       // TODO: Pass through the existing MemoryBuffer instances instead of
177*0a6a1f1dSLionel Sambuc       // allocating new ones.
178*0a6a1f1dSLionel Sambuc       for (auto &SB : SerialBufs)
179*0a6a1f1dSLionel Sambuc         Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
180f4a2713aSLionel Sambuc       std::string pchName = includes[i-1];
181f4a2713aSLionel Sambuc       llvm::raw_string_ostream os(pchName);
182f4a2713aSLionel Sambuc       os << ".pch" << i-1;
183*0a6a1f1dSLionel Sambuc       serialBufNames.push_back(os.str());
184f4a2713aSLionel Sambuc 
185*0a6a1f1dSLionel Sambuc       IntrusiveRefCntPtr<ASTReader> Reader;
186*0a6a1f1dSLionel Sambuc       Reader = createASTReader(
187*0a6a1f1dSLionel Sambuc           *Clang, pchName, Bufs, serialBufNames,
188*0a6a1f1dSLionel Sambuc           Clang->getASTConsumer().GetASTDeserializationListener());
189f4a2713aSLionel Sambuc       if (!Reader)
190*0a6a1f1dSLionel Sambuc         return nullptr;
191*0a6a1f1dSLionel Sambuc       Clang->setModuleManager(Reader);
192f4a2713aSLionel Sambuc       Clang->getASTContext().setExternalSource(Reader);
193f4a2713aSLionel Sambuc     }
194f4a2713aSLionel Sambuc 
195f4a2713aSLionel Sambuc     if (!Clang->InitializeSourceManager(InputFile))
196*0a6a1f1dSLionel Sambuc       return nullptr;
197f4a2713aSLionel Sambuc 
198f4a2713aSLionel Sambuc     ParseAST(Clang->getSema());
199f4a2713aSLionel Sambuc     Clang->getDiagnosticClient().EndSourceFile();
200*0a6a1f1dSLionel Sambuc     SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
201*0a6a1f1dSLionel Sambuc     source->CIs.push_back(Clang.release());
202f4a2713aSLionel Sambuc   }
203f4a2713aSLionel Sambuc 
204*0a6a1f1dSLionel Sambuc   assert(!SerialBufs.empty());
205f4a2713aSLionel Sambuc   std::string pchName = includes.back() + ".pch-final";
206f4a2713aSLionel Sambuc   serialBufNames.push_back(pchName);
207*0a6a1f1dSLionel Sambuc   Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames);
208f4a2713aSLionel Sambuc   if (!Reader)
209*0a6a1f1dSLionel Sambuc     return nullptr;
210f4a2713aSLionel Sambuc 
211*0a6a1f1dSLionel Sambuc   source->FinalReader = Reader;
212*0a6a1f1dSLionel Sambuc   return source;
213f4a2713aSLionel Sambuc }
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
216f4a2713aSLionel Sambuc // ExternalASTSource interface.
217f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
218f4a2713aSLionel Sambuc 
GetExternalDecl(uint32_t ID)219f4a2713aSLionel Sambuc Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) {
220f4a2713aSLionel Sambuc   return getFinalReader().GetExternalDecl(ID);
221f4a2713aSLionel Sambuc }
GetExternalSelector(uint32_t ID)222f4a2713aSLionel Sambuc Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) {
223f4a2713aSLionel Sambuc   return getFinalReader().GetExternalSelector(ID);
224f4a2713aSLionel Sambuc }
GetNumExternalSelectors()225f4a2713aSLionel Sambuc uint32_t ChainedIncludesSource::GetNumExternalSelectors() {
226f4a2713aSLionel Sambuc   return getFinalReader().GetNumExternalSelectors();
227f4a2713aSLionel Sambuc }
GetExternalDeclStmt(uint64_t Offset)228f4a2713aSLionel Sambuc Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) {
229f4a2713aSLionel Sambuc   return getFinalReader().GetExternalDeclStmt(Offset);
230f4a2713aSLionel Sambuc }
231f4a2713aSLionel Sambuc CXXBaseSpecifier *
GetExternalCXXBaseSpecifiers(uint64_t Offset)232f4a2713aSLionel Sambuc ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
233f4a2713aSLionel Sambuc   return getFinalReader().GetExternalCXXBaseSpecifiers(Offset);
234f4a2713aSLionel Sambuc }
235f4a2713aSLionel Sambuc bool
FindExternalVisibleDeclsByName(const DeclContext * DC,DeclarationName Name)236f4a2713aSLionel Sambuc ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
237f4a2713aSLionel Sambuc                                                       DeclarationName Name) {
238f4a2713aSLionel Sambuc   return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
239f4a2713aSLionel Sambuc }
240f4a2713aSLionel Sambuc ExternalLoadResult
FindExternalLexicalDecls(const DeclContext * DC,bool (* isKindWeWant)(Decl::Kind),SmallVectorImpl<Decl * > & Result)241f4a2713aSLionel Sambuc ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
242f4a2713aSLionel Sambuc                                       bool (*isKindWeWant)(Decl::Kind),
243f4a2713aSLionel Sambuc                                       SmallVectorImpl<Decl*> &Result) {
244f4a2713aSLionel Sambuc   return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
245f4a2713aSLionel Sambuc }
CompleteType(TagDecl * Tag)246f4a2713aSLionel Sambuc void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
247f4a2713aSLionel Sambuc   return getFinalReader().CompleteType(Tag);
248f4a2713aSLionel Sambuc }
CompleteType(ObjCInterfaceDecl * Class)249f4a2713aSLionel Sambuc void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) {
250f4a2713aSLionel Sambuc   return getFinalReader().CompleteType(Class);
251f4a2713aSLionel Sambuc }
StartedDeserializing()252f4a2713aSLionel Sambuc void ChainedIncludesSource::StartedDeserializing() {
253f4a2713aSLionel Sambuc   return getFinalReader().StartedDeserializing();
254f4a2713aSLionel Sambuc }
FinishedDeserializing()255f4a2713aSLionel Sambuc void ChainedIncludesSource::FinishedDeserializing() {
256f4a2713aSLionel Sambuc   return getFinalReader().FinishedDeserializing();
257f4a2713aSLionel Sambuc }
StartTranslationUnit(ASTConsumer * Consumer)258f4a2713aSLionel Sambuc void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) {
259f4a2713aSLionel Sambuc   return getFinalReader().StartTranslationUnit(Consumer);
260f4a2713aSLionel Sambuc }
PrintStats()261f4a2713aSLionel Sambuc void ChainedIncludesSource::PrintStats() {
262f4a2713aSLionel Sambuc   return getFinalReader().PrintStats();
263f4a2713aSLionel Sambuc }
getMemoryBufferSizes(MemoryBufferSizes & sizes) const264f4a2713aSLionel Sambuc void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{
265f4a2713aSLionel Sambuc   for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
266f4a2713aSLionel Sambuc     if (const ExternalASTSource *eSrc =
267f4a2713aSLionel Sambuc         CIs[i]->getASTContext().getExternalSource()) {
268f4a2713aSLionel Sambuc       eSrc->getMemoryBufferSizes(sizes);
269f4a2713aSLionel Sambuc     }
270f4a2713aSLionel Sambuc   }
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc   getFinalReader().getMemoryBufferSizes(sizes);
273f4a2713aSLionel Sambuc }
274f4a2713aSLionel Sambuc 
InitializeSema(Sema & S)275f4a2713aSLionel Sambuc void ChainedIncludesSource::InitializeSema(Sema &S) {
276f4a2713aSLionel Sambuc   return getFinalReader().InitializeSema(S);
277f4a2713aSLionel Sambuc }
ForgetSema()278f4a2713aSLionel Sambuc void ChainedIncludesSource::ForgetSema() {
279f4a2713aSLionel Sambuc   return getFinalReader().ForgetSema();
280f4a2713aSLionel Sambuc }
ReadMethodPool(Selector Sel)281f4a2713aSLionel Sambuc void ChainedIncludesSource::ReadMethodPool(Selector Sel) {
282f4a2713aSLionel Sambuc   getFinalReader().ReadMethodPool(Sel);
283f4a2713aSLionel Sambuc }
LookupUnqualified(LookupResult & R,Scope * S)284f4a2713aSLionel Sambuc bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) {
285f4a2713aSLionel Sambuc   return getFinalReader().LookupUnqualified(R, S);
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc 
288