25 #include "llvm/Support/MemoryBuffer.h"
27 using namespace clang;
32 ChainedIncludesSourceImpl(std::vector<std::unique_ptr<CompilerInstance>> CIs)
33 : CIs(
std::move(CIs)) {}
42 void getMemoryBufferSizes(MemoryBufferSizes &sizes)
const override {
43 for (
unsigned i = 0, e = CIs.size(); i != e; ++i) {
45 CIs[i]->getASTContext().getExternalSource()) {
46 eSrc->getMemoryBufferSizes(sizes);
52 std::vector<std::unique_ptr<CompilerInstance>> CIs;
57 struct ChainedIncludesSourceMembers {
58 ChainedIncludesSourceMembers(
59 std::vector<std::unique_ptr<CompilerInstance>> CIs,
60 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
61 : Impl(
std::move(CIs)), FinalReader(
std::move(FinalReader)) {}
62 ChainedIncludesSourceImpl Impl;
63 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
68 class ChainedIncludesSource
69 :
private ChainedIncludesSourceMembers,
72 ChainedIncludesSource(std::vector<std::unique_ptr<CompilerInstance>> CIs,
73 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
74 : ChainedIncludesSourceMembers(
std::move(CIs),
std::move(FinalReader)),
85 std::unique_ptr<ASTReader> Reader;
90 for (
unsigned ti = 0; ti < bufNames.size(); ++ti) {
91 StringRef sr(bufNames[ti]);
92 Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
94 Reader->setDeserializationListener(deserialListener);
100 return Reader.release();
117 assert(!includes.empty() &&
"No '-chain-include' in options!");
119 std::vector<std::unique_ptr<CompilerInstance>> CIs;
125 for (
unsigned i = 0, e = includes.size(); i != e; ++i) {
126 bool firstInclude = (i == 0);
127 std::unique_ptr<CompilerInvocation> CInvok;
130 CInvok->getPreprocessorOpts().ChainedIncludes.clear();
131 CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
132 CInvok->getPreprocessorOpts().DisablePCHOrModuleValidation =
134 CInvok->getPreprocessorOpts().Includes.clear();
135 CInvok->getPreprocessorOpts().MacroIncludes.clear();
136 CInvok->getPreprocessorOpts().Macros.clear();
138 CInvok->getFrontendOpts().Inputs.clear();
140 CInvok->getFrontendOpts().Inputs.push_back(InputFile);
148 std::unique_ptr<CompilerInstance> Clang(
150 Clang->setInvocation(std::move(CInvok));
151 Clang->setDiagnostics(Diags.get());
153 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
154 Clang->createFileManager();
155 Clang->createSourceManager(Clang->getFileManager());
157 Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
158 &Clang->getPreprocessor());
159 Clang->createASTContext();
161 auto Buffer = std::make_shared<PCHBuffer>();
163 auto consumer = std::make_unique<PCHGenerator>(
164 Clang->getPreprocessor(), Clang->getModuleCache(),
"-",
"",
165 Buffer, Extensions,
true);
166 Clang->getASTContext().setASTMutationListener(
167 consumer->GetASTMutationListener());
168 Clang->setASTConsumer(std::move(consumer));
176 assert(!SerialBufs.empty());
180 for (
auto &SB : SerialBufs)
181 Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
183 llvm::raw_string_ostream os(pchName);
185 serialBufNames.push_back(os.str());
189 *Clang, pchName, Bufs, serialBufNames,
190 Clang->getASTConsumer().GetASTDeserializationListener());
193 Clang->setASTReader(Reader);
194 Clang->getASTContext().setExternalSource(Reader);
197 if (!Clang->InitializeSourceManager(InputFile))
201 Clang->getDiagnosticClient().EndSourceFile();
202 assert(Buffer->IsComplete &&
"serialization did not complete");
203 auto &serialAST = Buffer->Data;
204 SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
205 StringRef(serialAST.data(), serialAST.size())));
207 CIs.push_back(std::move(Clang));
210 assert(!SerialBufs.empty());
211 std::string pchName = includes.back() +
".pch-final";
212 serialBufNames.push_back(pchName);
218 new ChainedIncludesSource(std::move(CIs), Reader));