23 #include "llvm/Support/MemoryBuffer.h"
25 using namespace clang;
30 ~ChainedIncludesSource()
override;
34 std::vector<CompilerInstance *> CIs;
42 Decl *GetExternalDecl(uint32_t
ID)
override;
43 Selector GetExternalSelector(uint32_t
ID)
override;
44 uint32_t GetNumExternalSelectors()
override;
45 Stmt *GetExternalDeclStmt(uint64_t
Offset)
override;
48 bool FindExternalVisibleDeclsByName(
const DeclContext *DC,
52 llvm::function_ref<
bool(
Decl::Kind)> IsKindWeWant,
54 void CompleteType(
TagDecl *Tag)
override;
56 void StartedDeserializing()
override;
57 void FinishedDeserializing()
override;
58 void StartTranslationUnit(
ASTConsumer *Consumer)
override;
59 void PrintStats()
override;
63 void getMemoryBufferSizes(MemoryBufferSizes &sizes)
const override;
69 void InitializeSema(
Sema &
S)
override;
70 void ForgetSema()
override;
71 void ReadMethodPool(
Selector Sel)
override;
82 std::unique_ptr<ASTReader> Reader;
87 for (
unsigned ti = 0; ti < bufNames.size(); ++ti) {
88 StringRef sr(bufNames[ti]);
89 Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
91 Reader->setDeserializationListener(deserialListener);
97 return Reader.release();
110 ChainedIncludesSource::~ChainedIncludesSource() {
111 for (
unsigned i = 0, e = CIs.size(); i != e; ++i)
119 assert(!includes.empty() &&
"No '-chain-include' in options!");
127 for (
unsigned i = 0, e = includes.size(); i != e; ++i) {
128 bool firstInclude = (i == 0);
129 std::unique_ptr<CompilerInvocation> CInvok;
132 CInvok->getPreprocessorOpts().ChainedIncludes.clear();
133 CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
134 CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
135 CInvok->getPreprocessorOpts().DisablePCHValidation =
true;
136 CInvok->getPreprocessorOpts().Includes.clear();
137 CInvok->getPreprocessorOpts().MacroIncludes.clear();
138 CInvok->getPreprocessorOpts().Macros.clear();
140 CInvok->getFrontendOpts().Inputs.clear();
142 CInvok->getFrontendOpts().Inputs.push_back(InputFile);
150 std::unique_ptr<CompilerInstance> Clang(
152 Clang->setInvocation(CInvok.release());
153 Clang->setDiagnostics(Diags.get());
155 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
156 Clang->createFileManager();
157 Clang->createSourceManager(Clang->getFileManager());
159 Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
160 &Clang->getPreprocessor());
161 Clang->createASTContext();
163 auto Buffer = std::make_shared<PCHBuffer>();
165 auto consumer = llvm::make_unique<PCHGenerator>(
166 Clang->getPreprocessor(),
"-",
nullptr,
"",
Buffer,
168 Clang->getASTContext().setASTMutationListener(
169 consumer->GetASTMutationListener());
170 Clang->setASTConsumer(std::move(consumer));
178 assert(!SerialBufs.empty());
182 for (
auto &SB : SerialBufs)
183 Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
184 std::string pchName = includes[i-1];
185 llvm::raw_string_ostream os(pchName);
187 serialBufNames.push_back(os.str());
191 *Clang, pchName, Bufs, serialBufNames,
192 Clang->getASTConsumer().GetASTDeserializationListener());
195 Clang->setModuleManager(Reader);
196 Clang->getASTContext().setExternalSource(Reader);
199 if (!Clang->InitializeSourceManager(InputFile))
203 Clang->getDiagnosticClient().EndSourceFile();
204 assert(
Buffer->IsComplete &&
"serialization did not complete");
205 auto &serialAST =
Buffer->Data;
206 SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
207 StringRef(serialAST.data(), serialAST.size())));
209 source->CIs.push_back(Clang.release());
212 assert(!SerialBufs.empty());
213 std::string pchName = includes.back() +
".pch-final";
214 serialBufNames.push_back(pchName);
219 source->FinalReader = Reader;
227 Decl *ChainedIncludesSource::GetExternalDecl(uint32_t
ID) {
228 return getFinalReader().GetExternalDecl(ID);
230 Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) {
231 return getFinalReader().GetExternalSelector(ID);
233 uint32_t ChainedIncludesSource::GetNumExternalSelectors() {
234 return getFinalReader().GetNumExternalSelectors();
236 Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t
Offset) {
237 return getFinalReader().GetExternalDeclStmt(Offset);
240 ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
241 return getFinalReader().GetExternalCXXBaseSpecifiers(Offset);
244 ChainedIncludesSource::GetExternalCXXCtorInitializers(uint64_t Offset) {
245 return getFinalReader().GetExternalCXXCtorInitializers(Offset);
248 ChainedIncludesSource::FindExternalVisibleDeclsByName(
const DeclContext *DC,
250 return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
252 void ChainedIncludesSource::FindExternalLexicalDecls(
255 return getFinalReader().FindExternalLexicalDecls(DC, IsKindWeWant, Result);
257 void ChainedIncludesSource::CompleteType(
TagDecl *Tag) {
258 return getFinalReader().CompleteType(Tag);
261 return getFinalReader().CompleteType(Class);
263 void ChainedIncludesSource::StartedDeserializing() {
264 return getFinalReader().StartedDeserializing();
266 void ChainedIncludesSource::FinishedDeserializing() {
267 return getFinalReader().FinishedDeserializing();
269 void ChainedIncludesSource::StartTranslationUnit(
ASTConsumer *Consumer) {
270 return getFinalReader().StartTranslationUnit(Consumer);
272 void ChainedIncludesSource::PrintStats() {
273 return getFinalReader().PrintStats();
275 void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)
const{
276 for (
unsigned i = 0, e = CIs.size(); i != e; ++i) {
278 CIs[i]->getASTContext().getExternalSource()) {
279 eSrc->getMemoryBufferSizes(sizes);
283 getFinalReader().getMemoryBufferSizes(sizes);
286 void ChainedIncludesSource::InitializeSema(
Sema &
S) {
287 return getFinalReader().InitializeSema(S);
289 void ChainedIncludesSource::ForgetSema() {
290 return getFinalReader().ForgetSema();
292 void ChainedIncludesSource::ReadMethodPool(
Selector Sel) {
293 getFinalReader().ReadMethodPool(Sel);
296 return getFinalReader().LookupUnqualified(R, S);
ASTContext & getASTContext() const
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
Smart pointer class that efficiently represents Objective-C method names.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing...
Decl - This represents one declaration (or definition), e.g.
DiagnosticOptions & getDiagnosticOpts()
The translation unit is a prefix to a translation unit, and is not complete.
std::unique_ptr< llvm::MemoryBuffer > Buffer
static ASTReader * createASTReader(CompilerInstance &CI, StringRef pchFile, SmallVectorImpl< std::unique_ptr< llvm::MemoryBuffer >> &MemBufs, SmallVectorImpl< std::string > &bufNames, ASTDeserializationListener *deserialListener=nullptr)
Builtin::Context & getBuiltinInfo()
void setPredefines(const char *P)
Set the predefines for this Preprocessor.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
const LangOptions & getLangOpts() const
Represents the results of name lookup.
FrontendOptions & getFrontendOpts()
Concrete class used by the front-end to report problems and issues.
Scope - A scope is a transient data structure that is used while parsing the program.
Represents an ObjC class declaration.
The AST file itself appears corrupted.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
Sema - This implements semantic analysis and AST building for C.
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
ID
Defines the set of possible language-specific address spaces.
Defines the clang::Preprocessor interface.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
The result type of a method or function.
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.
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
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.
TagDecl - Represents the declaration of a struct/union/class/enum.
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...
std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const
The AST file was writtten with a different language/target configuration.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Reads an AST files chain containing the contents of a translation unit.
DeclarationName - The name of a declaration.
Used for handling and querying diagnostic IDs.
Helper class for holding the data necessary to invoke the compiler.
Represents a C++ base or member initializer.
Represents a base class of a C++ class.
Defines the clang::TargetInfo interface.
The AST file is out-of-date relative to its input files, and needs to be regenerated.
Kind
Lists the kind of concrete classes of Decl.
The AST file was written by a different version of Clang.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.