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