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().DisablePCHValidation =
true;
133 CInvok->getPreprocessorOpts().Includes.clear();
134 CInvok->getPreprocessorOpts().MacroIncludes.clear();
135 CInvok->getPreprocessorOpts().Macros.clear();
137 CInvok->getFrontendOpts().Inputs.clear();
139 CInvok->getFrontendOpts().Inputs.push_back(InputFile);
147 std::unique_ptr<CompilerInstance> Clang(
149 Clang->setInvocation(std::move(CInvok));
150 Clang->setDiagnostics(Diags.get());
152 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
153 Clang->createFileManager();
154 Clang->createSourceManager(Clang->getFileManager());
156 Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
157 &Clang->getPreprocessor());
158 Clang->createASTContext();
160 auto Buffer = std::make_shared<PCHBuffer>();
162 auto consumer = llvm::make_unique<PCHGenerator>(
163 Clang->getPreprocessor(),
"-",
"", Buffer,
165 Clang->getASTContext().setASTMutationListener(
166 consumer->GetASTMutationListener());
167 Clang->setASTConsumer(std::move(consumer));
175 assert(!SerialBufs.empty());
179 for (
auto &SB : SerialBufs)
180 Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
181 std::string pchName = includes[i-1];
182 llvm::raw_string_ostream os(pchName);
184 serialBufNames.push_back(os.str());
188 *Clang, pchName, Bufs, serialBufNames,
189 Clang->getASTConsumer().GetASTDeserializationListener());
192 Clang->setModuleManager(Reader);
193 Clang->getASTContext().setExternalSource(Reader);
196 if (!Clang->InitializeSourceManager(InputFile))
200 Clang->getDiagnosticClient().EndSourceFile();
201 assert(Buffer->IsComplete &&
"serialization did not complete");
202 auto &serialAST = Buffer->Data;
203 SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
204 StringRef(serialAST.data(), serialAST.size())));
206 CIs.push_back(std::move(Clang));
209 assert(!SerialBufs.empty());
210 std::string pchName = includes.back() +
".pch-final";
211 serialBufNames.push_back(pchName);
217 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.