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().ImplicitPTHInclude.clear();
133 CInvok->getPreprocessorOpts().DisablePCHValidation =
true;
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 = llvm::make_unique<PCHGenerator>(
164 Clang->getPreprocessor(),
"-",
"", Buffer,
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()));
182 std::string pchName = includes[i-1];
183 llvm::raw_string_ostream os(pchName);
185 serialBufNames.push_back(os.str());
189 *Clang, pchName, Bufs, serialBufNames,
190 Clang->getASTConsumer().GetASTDeserializationListener());
193 Clang->setModuleManager(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));
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)
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.