24 #include "llvm/Support/MemoryBuffer.h" 26 using namespace clang;
31 ChainedIncludesSourceImpl(std::vector<std::unique_ptr<CompilerInstance>> CIs)
32 : CIs(
std::move(CIs)) {}
41 void getMemoryBufferSizes(MemoryBufferSizes &sizes)
const override {
42 for (
unsigned i = 0, e = CIs.size(); i != e; ++i) {
44 CIs[i]->getASTContext().getExternalSource()) {
45 eSrc->getMemoryBufferSizes(sizes);
51 std::vector<std::unique_ptr<CompilerInstance>> CIs;
56 struct ChainedIncludesSourceMembers {
57 ChainedIncludesSourceMembers(
58 std::vector<std::unique_ptr<CompilerInstance>> CIs,
59 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
60 : Impl(
std::move(CIs)), FinalReader(
std::move(FinalReader)) {}
61 ChainedIncludesSourceImpl Impl;
62 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
67 class ChainedIncludesSource
68 :
private ChainedIncludesSourceMembers,
71 ChainedIncludesSource(std::vector<std::unique_ptr<CompilerInstance>> CIs,
72 IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
73 : ChainedIncludesSourceMembers(
std::move(CIs),
std::move(FinalReader)),
84 std::unique_ptr<ASTReader> Reader;
89 for (
unsigned ti = 0; ti < bufNames.size(); ++ti) {
90 StringRef sr(bufNames[ti]);
91 Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
93 Reader->setDeserializationListener(deserialListener);
99 return Reader.release();
116 assert(!includes.empty() &&
"No '-chain-include' in options!");
118 std::vector<std::unique_ptr<CompilerInstance>> CIs;
124 for (
unsigned i = 0, e = includes.size(); i != e; ++i) {
125 bool firstInclude = (i == 0);
126 std::unique_ptr<CompilerInvocation> CInvok;
129 CInvok->getPreprocessorOpts().ChainedIncludes.clear();
130 CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
131 CInvok->getPreprocessorOpts().DisablePCHValidation =
true;
132 CInvok->getPreprocessorOpts().Includes.clear();
133 CInvok->getPreprocessorOpts().MacroIncludes.clear();
134 CInvok->getPreprocessorOpts().Macros.clear();
136 CInvok->getFrontendOpts().Inputs.clear();
138 CInvok->getFrontendOpts().Inputs.push_back(InputFile);
146 std::unique_ptr<CompilerInstance> Clang(
148 Clang->setInvocation(std::move(CInvok));
149 Clang->setDiagnostics(Diags.get());
151 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
152 Clang->createFileManager();
153 Clang->createSourceManager(Clang->getFileManager());
155 Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
156 &Clang->getPreprocessor());
157 Clang->createASTContext();
159 auto Buffer = std::make_shared<PCHBuffer>();
161 auto consumer = std::make_unique<PCHGenerator>(
162 Clang->getPreprocessor(), Clang->getModuleCache(),
"-",
"",
163 Buffer, Extensions,
true);
164 Clang->getASTContext().setASTMutationListener(
165 consumer->GetASTMutationListener());
166 Clang->setASTConsumer(std::move(consumer));
174 assert(!SerialBufs.empty());
178 for (
auto &SB : SerialBufs)
179 Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
180 std::string pchName = includes[i-1];
181 llvm::raw_string_ostream os(pchName);
183 serialBufNames.push_back(os.str());
187 *Clang, pchName, Bufs, serialBufNames,
188 Clang->getASTConsumer().GetASTDeserializationListener());
191 Clang->setModuleManager(Reader);
192 Clang->getASTContext().setExternalSource(Reader);
195 if (!Clang->InitializeSourceManager(InputFile))
199 Clang->getDiagnosticClient().EndSourceFile();
200 assert(Buffer->IsComplete &&
"serialization did not complete");
201 auto &serialAST = Buffer->Data;
202 SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
203 StringRef(serialAST.data(), serialAST.size())));
205 CIs.push_back(std::move(Clang));
208 assert(!SerialBufs.empty());
209 std::string pchName = includes.back() +
".pch-final";
210 serialBufNames.push_back(pchName);
216 new ChainedIncludesSource(std::move(CIs), Reader));
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing...
std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const
DiagnosticOptions & getDiagnosticOpts()
The translation unit is a prefix to a translation unit, and is not complete.
static ASTReader * createASTReader(CompilerInstance &CI, StringRef pchFile, SmallVectorImpl< std::unique_ptr< llvm::MemoryBuffer >> &MemBufs, SmallVectorImpl< std::string > &bufNames, ASTDeserializationListener *deserialListener=nullptr)
InMemoryModuleCache & getModuleCache() const
ASTContext & getASTContext() const
Builtin::Context & getBuiltinInfo()
void setPredefines(const char *P)
Set the predefines for this Preprocessor.
const LangOptions & getLangOpts() const
FrontendOptions & getFrontendOpts()
Concrete class used by the front-end to report problems and issues.
The AST file itself appears corrupted.
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
An abstract interface that should be implemented by external AST sources that also provide informatio...
Defines the clang::Preprocessor interface.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
The client can't handle any AST loading failures.
The AST file was missing.
An abstract interface that should be implemented by external AST sources that also provide informatio...
Abstract interface for external sources of AST nodes.
The control block was read successfully.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Encodes a location in the source.
File is a PCH file treated as such.
Options for controlling the compiler diagnostics engine.
std::vector< FrontendInputFile > Inputs
The input files and their types.
IdentifierTable & getIdentifierTable()
void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats=false, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr, bool SkipFunctionBodies=false)
Parse the entire file specified, notifying the ASTConsumer as the file is parsed. ...
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
The AST file was writtten with a different language/target configuration.
Dataflow Directional Tag Classes.
Reads an AST files chain containing the contents of a translation unit.
Used for handling and querying diagnostic IDs.
Helper class for holding the data necessary to invoke the compiler.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
Defines the clang::TargetInfo interface.
The AST file is out-of-date relative to its input files, and needs to be regenerated.
The AST file was written by a different version of Clang.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.