27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/Timer.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include <system_error>
33 using namespace clang;
35 template class llvm::Registry<clang::PluginASTAction>;
44 explicit DelegatingDeserializationListener(
46 : Previous(Previous), DeletePrevious(DeletePrevious) {}
47 ~DelegatingDeserializationListener()
override {
52 void ReaderInitialized(
ASTReader *Reader)
override {
81 class DeserializedDeclsDumper :
public DelegatingDeserializationListener {
85 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
89 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
90 llvm::outs() <<
" - " << *ND;
93 DelegatingDeserializationListener::DeclRead(ID, D);
99 class DeserializedDeclsChecker :
public DelegatingDeserializationListener {
101 std::set<std::string> NamesToCheck;
105 const std::set<std::string> &NamesToCheck,
108 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
109 NamesToCheck(NamesToCheck) {}
112 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
113 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
116 "%0 was deserialized");
118 << ND->getNameAsString();
121 DelegatingDeserializationListener::DeclRead(ID, D);
132 std::unique_ptr<ASTUnit> AST) {
133 this->CurrentInput = CurrentInput;
134 CurrentASTUnit = std::move(AST);
137 std::unique_ptr<ASTConsumer>
149 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
150 Consumers.push_back(std::move(Consumer));
156 for (FrontendPluginRegistry::iterator
157 it = FrontendPluginRegistry::begin(),
158 ie = FrontendPluginRegistry::end();
162 std::unique_ptr<PluginASTAction>
P = it->instantiate();
164 Consumers.push_back(P->CreateASTConsumer(CI, InFile));
168 return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
173 assert(!Instance &&
"Already processing a source file!");
174 assert(!Input.
isEmpty() &&
"Unexpected empty filename!");
178 StringRef InputFile = Input.
getFile();
179 bool HasBegunSourceFile =
false;
187 "Attempt to pass AST file to preprocessor only action!");
189 "This action does not have AST file support!");
193 std::unique_ptr<ASTUnit> AST =
202 HasBegunSourceFile =
true;
243 "This action does not have IR file support!");
247 HasBegunSourceFile =
true;
270 llvm::sys::path::native(PCHDir->getName(), DirNative);
272 for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
273 Dir != DirEnd && !EC; Dir.increment(EC)) {
278 SpecificModuleCachePath)) {
300 HasBegunSourceFile =
true;
318 std::unique_ptr<ASTConsumer> Consumer =
319 CreateWrappedASTConsumer(CI, InputFile);
337 assert(
hasPCHSupport() &&
"This action does not have PCH support!");
339 Consumer->GetASTDeserializationListener();
340 bool DeleteDeserialListener =
false;
342 DeserialListener =
new DeserializedDeclsDumper(DeserialListener,
343 DeleteDeserialListener);
344 DeleteDeserialListener =
true;
347 DeserialListener =
new DeserializedDeclsChecker(
350 DeserialListener, DeleteDeserialListener);
351 DeleteDeserialListener =
true;
357 DeleteDeserialListener);
384 "modules enabled but created an external source that "
385 "doesn't support modules");
424 if (HasBegunSourceFile)
481 llvm::errs() <<
"\nSTATISTICS FOR '" <<
getCurrentFile() <<
"':\n";
486 llvm::errs() <<
"\n";
540 void PluginASTAction::anchor() { }
542 std::unique_ptr<ASTConsumer>
545 llvm_unreachable(
"Invalid CreateASTConsumer on preprocessor action!");
548 std::unique_ptr<ASTConsumer>
551 return WrappedAction->CreateASTConsumer(CI, InFile);
554 return WrappedAction->BeginInvocation(CI);
557 StringRef Filename) {
559 WrappedAction->setCompilerInstance(&CI);
560 return WrappedAction->BeginSourceFileAction(CI, Filename);
563 WrappedAction->ExecuteAction();
566 WrappedAction->EndSourceFileAction();
570 return WrappedAction->usesPreprocessorOnly();
573 return WrappedAction->getTranslationUnitKind();
576 return WrappedAction->hasPCHSupport();
579 return WrappedAction->hasASTFileSupport();
582 return WrappedAction->hasIRSupport();
585 return WrappedAction->hasCodeCompletionSupport();
589 : WrappedAction(WrappedAction) {}
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
Defines the clang::ASTContext interface.
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
LangOptions & getLangOpts()
void resetAndLeakFileManager()
bool hasFileManager() const
ASTContext & getASTContext() const
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
void createCodeCompletionConsumer()
Smart pointer class that efficiently represents Objective-C method names.
std::vector< std::vector< std::string > > AddPluginArgs
Args to pass to the additional plugins.
bool hasASTConsumer() const
Implements support for file system lookup, file system caching, and directory search management...
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer...
uint32_t IdentID
An ID number that refers to an identifier in an AST file.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
virtual bool hasCodeCompletionSupport() const
Does this action support use with code completion?
Abstract base class for actions which can be performed by the frontend.
CompilerInstance & getCompilerInstance() const
void EndSourceFile()
Inform the preprocessor callbacks that processing is complete.
bool hasCodeCompletionConsumer() const
virtual bool usesPreprocessorOnly() const =0
Does this action only use the preprocessor?
bool hasErrorOccurred() const
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Provide a default implementation which returns aborts; this method should never be called by Frontend...
FullSourceLoc getFullLoc(SourceLocation Loc) const
uint32_t DeclID
An ID number that refers to a declaration in an AST file.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override
Callback at the start of processing a single input.
bool InitializeSourceManager(const FrontendInputFile &Input)
virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II)
An identifier was deserialized from the AST file.
void setModuleManager(IntrusiveRefCntPtr< ASTReader > Reader)
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
SourceManager & getSourceManager() const
Return the current source manager.
Builtin::Context & getBuiltinInfo()
WrapperFrontendAction(FrontendAction *WrappedAction)
const FrontendInputFile & getCurrentInput() const
virtual void ReaderInitialized(ASTReader *Reader)
The ASTReader was initialized.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Record the location of a macro definition.
bool usesPreprocessorOnly() const override
Does this action only use the preprocessor?
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
void createFileManager()
Create the file manager and replace any existing one with it.
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
virtual bool hasASTFileSupport() const
Does this action support use with AST files?
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
const LangOptions & getLangOpts() const
static std::unique_ptr< ASTUnit > LoadFromASTFile(const std::string &Filename, const PCHContainerReader &PCHContainerRdr, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls=false, ArrayRef< RemappedFile > RemappedFiles=None, bool CaptureDiagnostics=false, bool AllowPCHWithCompilerErrors=false, bool UserFilesAreVolatile=false)
Create a ASTUnit from an AST file.
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
bool hasPCHSupport() const override
Does this action support use with PCH?
FrontendOptions & getFrontendOpts()
DiagnosticConsumer & getDiagnosticClient() const
HeaderSearch & getHeaderSearchInfo() const
virtual ~FrontendAction()
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
unsigned SkipFunctionBodies
IntrusiveRefCntPtr< ASTReader > getModuleManager() const
virtual bool BeginInvocation(CompilerInstance &CI)
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
bool BeginInvocation(CompilerInstance &CI) override
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename)
Callback at the start of processing a single input.
bool DisablePCHValidation
When true, disables most of the normal validation performed on precompiled headers.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
DiagnosticsEngine & getDiagnostics() const
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel)
A selector was read from the AST file.
void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)
bool hasVirtualFileSystem() const
static ErrorCode writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, StringRef Path)
Write a global index into the given.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
virtual void DeclRead(serialization::DeclID ID, const Decl *D)
A decl was deserialized from the AST file.
void setPreprocessor(Preprocessor *Value)
Replace the current preprocessor.
bool hasCodeCompletionSupport() const override
Does this action support use with code completion?
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
void setVirtualFileSystem(IntrusiveRefCntPtr< vfs::FileSystem > FS)
Replace the current virtual file system.
virtual bool shouldEraseOutputFiles()
Callback at the end of processing a single input, to determine if the output files should be erased o...
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
void resetAndLeakPreprocessor()
void setCurrentInput(const FrontendInputFile &CurrentInput, std::unique_ptr< ASTUnit > AST=nullptr)
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, std::string ExistingModuleCachePath)
Determine whether the given AST file is acceptable to load into a translation unit with the given lan...
ID
Defines the set of possible language-specific address spaces.
bool hasIRSupport() const override
Does this action support use with IR files?
std::string getSpecificModuleCachePath()
std::set< std::string > DeserializedPCHDeclsToErrorOn
This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...
Defines the clang::Preprocessor interface.
IntrusiveRefCntPtr< vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
void createASTContext()
Create the AST context.
const char * getDeclKindName() const
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
virtual bool hasIRSupport() const
Does this action support use with IR files?
virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0
Create the AST consumer object for this action, if supported.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
virtual void ExecuteAction()=0
Callback to run the program action, using the initialized compiler instance.
void EndSourceFileAction() override
Callback at the end of processing a single input.
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
bool hasSourceManager() const
FileSystemOptions & getFileSystemOpts()
const PCHContainerReader & getPCHContainerReader() const
void resetAndLeakSourceManager()
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
bool Execute()
Set the source manager's main input file, and run the action.
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input. ...
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD)
A macro definition was read from the AST file.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
const StringRef getCurrentFile() const
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. ...
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
void createPreprocessor(TranslationUnitKind TUKind)
virtual void TypeRead(serialization::TypeIdx Idx, QualType T)
A type was deserialized from the AST file. The ID here has the qualifier bits already removed...
std::string OverrideRecordLayoutsFile
File name of the file that will provide record layouts (in the format produced by -fdump-record-layou...
Abstract interface for a consumer of code-completion information.
bool hasFrontendTimer() const
Reads an AST files chain containing the contents of a translation unit.
FileManager & getFileManager() const
Return the current file manager to the caller.
bool loadModuleFile(StringRef FileName)
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
bool isCurrentFileAST() const
virtual bool hasPCHSupport() const
Does this action support use with PCH?
void clearOutputFiles(bool EraseFiles)
void BuryPointer(const void *Ptr)
bool hasASTFileSupport() const override
Does this action support use with AST files?
void setCompilerInstance(CompilerInstance *Value)
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
CodeCompleteConsumer & getCodeCompletionConsumer() const
bool hasASTContext() const
std::vector< std::string > AddPluginActions
The list of plugin actions to run in addition to the normal action.
Cached information about one directory (either on disk or in the virtual file system).
unsigned DisableFree
Disable memory freeing on exit.
void InitializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
An external AST source that overrides the layout of a specified set of record types.
uint32_t PreprocessedEntityID
An ID number that refers to an entity in the detailed preprocessing record.
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
void resetAndLeakASTContext()
uint32_t SelectorID
An ID number that refers to an ObjC selector in an AST file.
llvm::Timer & getFrontendTimer() const
TranslationUnitKind
Describes the kind of translation unit being processed.
void PrintStats() const
Print statistics to stderr.
bool hasPreprocessor() const
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
std::unique_ptr< ASTConsumer > takeASTConsumer()
void createModuleManager()
}
SourceLocation getLocation() const
bool DumpDeserializedPCHDecls
Dump declarations that are deserialized from PCH, for testing.
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
TargetOptions & getTargetOpts()
A type index; the type ID with the qualifier bits removed.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
std::vector< std::string > ModuleMapFiles
The list of module map files to load before processing the input.