diff options
Diffstat (limited to 'include/clang/Frontend/CompilerInstance.h')
-rw-r--r-- | include/clang/Frontend/CompilerInstance.h | 157 |
1 files changed, 103 insertions, 54 deletions
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 5673c5908d780..44e91026acb53 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -13,14 +13,15 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/Utils.h" #include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include <cassert> #include <list> +#include <memory> #include <string> #include <utility> @@ -74,6 +75,9 @@ class CompilerInstance : public ModuleLoader { /// The target being compiled for. IntrusiveRefCntPtr<TargetInfo> Target; + /// The virtual file system. + IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem; + /// The file manager. IntrusiveRefCntPtr<FileManager> FileMgr; @@ -87,19 +91,27 @@ class CompilerInstance : public ModuleLoader { IntrusiveRefCntPtr<ASTContext> Context; /// The AST consumer. - OwningPtr<ASTConsumer> Consumer; + std::unique_ptr<ASTConsumer> Consumer; /// The code completion consumer. - OwningPtr<CodeCompleteConsumer> CompletionConsumer; + std::unique_ptr<CodeCompleteConsumer> CompletionConsumer; /// \brief The semantic analysis object. - OwningPtr<Sema> TheSema; + std::unique_ptr<Sema> TheSema; /// \brief The frontend timer - OwningPtr<llvm::Timer> FrontendTimer; + std::unique_ptr<llvm::Timer> FrontendTimer; + + /// \brief The ASTReader, if one exists. + IntrusiveRefCntPtr<ASTReader> ModuleManager; + + /// \brief The module dependency collector for crashdumps + std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector; + + /// \brief The dependency file generator. + std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator; - /// \brief Non-owning reference to the ASTReader, if one exists. - ASTReader *ModuleManager; + std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors; /// \brief The set of top-level modules that has already been loaded, /// along with the module map @@ -117,13 +129,16 @@ class CompilerInstance : public ModuleLoader { /// have finished with this translation unit. bool BuildGlobalModuleIndex; + /// \brief We have a full global module index, with all modules. + bool HaveFullGlobalModuleIndex; + /// \brief One or more modules failed to build. bool ModuleBuildFailed; /// \brief Holds information about the output file. /// /// If TempFilename is not empty we must rename it to Filename at the end. - /// TempFilename may be empty and Filename non empty if creating the temporary + /// TempFilename may be empty and Filename non-empty if creating the temporary /// failed. struct OutputFile { std::string Filename; @@ -141,7 +156,7 @@ class CompilerInstance : public ModuleLoader { CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION; void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION; public: - CompilerInstance(); + explicit CompilerInstance(bool BuildingModule = false); ~CompilerInstance(); /// @name High-Level Operations @@ -183,7 +198,7 @@ public: /// @name Compiler Invocation and Options /// { - bool hasInvocation() const { return Invocation != 0; } + bool hasInvocation() const { return Invocation != nullptr; } CompilerInvocation &getInvocation() { assert(Invocation && "Compiler instance has no invocation!"); @@ -281,7 +296,7 @@ public: /// @name Diagnostics Engine /// { - bool hasDiagnostics() const { return Diagnostics != 0; } + bool hasDiagnostics() const { return Diagnostics != nullptr; } /// Get the current diagnostics engine. DiagnosticsEngine &getDiagnostics() const { @@ -302,7 +317,7 @@ public: /// @name Target Info /// { - bool hasTarget() const { return Target != 0; } + bool hasTarget() const { return Target != nullptr; } TargetInfo &getTarget() const { assert(Target && "Compiler instance has no target!"); @@ -313,10 +328,30 @@ public: void setTarget(TargetInfo *Value); /// } + /// @name Virtual File System + /// { + + bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; } + + vfs::FileSystem &getVirtualFileSystem() const { + assert(hasVirtualFileSystem() && + "Compiler instance has no virtual file system"); + return *VirtualFileSystem; + } + + /// \brief Replace the current virtual file system. + /// + /// \note Most clients should use setFileManager, which will implicitly reset + /// the virtual file system to the one contained in the file manager. + void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) { + VirtualFileSystem = FS; + } + + /// } /// @name File Manager /// { - bool hasFileManager() const { return FileMgr != 0; } + bool hasFileManager() const { return FileMgr != nullptr; } /// Return the current file manager to the caller. FileManager &getFileManager() const { @@ -325,17 +360,18 @@ public: } void resetAndLeakFileManager() { + BuryPointer(FileMgr.get()); FileMgr.resetWithoutRelease(); } - /// setFileManager - Replace the current file manager. + /// \brief Replace the current file manager and virtual file system. void setFileManager(FileManager *Value); /// } /// @name Source Manager /// { - bool hasSourceManager() const { return SourceMgr != 0; } + bool hasSourceManager() const { return SourceMgr != nullptr; } /// Return the current source manager. SourceManager &getSourceManager() const { @@ -344,6 +380,7 @@ public: } void resetAndLeakSourceManager() { + BuryPointer(SourceMgr.get()); SourceMgr.resetWithoutRelease(); } @@ -354,7 +391,7 @@ public: /// @name Preprocessor /// { - bool hasPreprocessor() const { return PP != 0; } + bool hasPreprocessor() const { return PP != nullptr; } /// Return the current preprocessor. Preprocessor &getPreprocessor() const { @@ -363,6 +400,7 @@ public: } void resetAndLeakPreprocessor() { + BuryPointer(PP.get()); PP.resetWithoutRelease(); } @@ -373,7 +411,7 @@ public: /// @name ASTContext /// { - bool hasASTContext() const { return Context != 0; } + bool hasASTContext() const { return Context != nullptr; } ASTContext &getASTContext() const { assert(Context && "Compiler instance has no AST context!"); @@ -381,6 +419,7 @@ public: } void resetAndLeakASTContext() { + BuryPointer(Context.get()); Context.resetWithoutRelease(); } @@ -395,7 +434,7 @@ public: /// @name ASTConsumer /// { - bool hasASTConsumer() const { return Consumer.isValid(); } + bool hasASTConsumer() const { return (bool)Consumer; } ASTConsumer &getASTConsumer() const { assert(Consumer && "Compiler instance has no AST consumer!"); @@ -404,7 +443,7 @@ public: /// takeASTConsumer - Remove the current AST consumer and give ownership to /// the caller. - ASTConsumer *takeASTConsumer() { return Consumer.take(); } + ASTConsumer *takeASTConsumer() { return Consumer.release(); } /// setASTConsumer - Replace the current AST consumer; the compiler instance /// takes ownership of \p Value. @@ -413,29 +452,32 @@ public: /// } /// @name Semantic analysis /// { - bool hasSema() const { return TheSema.isValid(); } - + bool hasSema() const { return (bool)TheSema; } + Sema &getSema() const { assert(TheSema && "Compiler instance has no Sema object!"); return *TheSema; } - - Sema *takeSema() { return TheSema.take(); } - + + Sema *takeSema() { return TheSema.release(); } + void resetAndLeakSema() { BuryPointer(TheSema.release()); } + /// } /// @name Module Management /// { - ASTReader *getModuleManager() const { return ModuleManager; } - void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; } + IntrusiveRefCntPtr<ASTReader> getModuleManager() const; + void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader); + + std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const; + void setModuleDepCollector( + std::shared_ptr<ModuleDependencyCollector> Collector); /// } /// @name Code Completion /// { - bool hasCodeCompletionConsumer() const { - return CompletionConsumer.isValid(); - } + bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; } CodeCompleteConsumer &getCodeCompletionConsumer() const { assert(CompletionConsumer && @@ -446,7 +488,7 @@ public: /// takeCodeCompletionConsumer - Remove the current code completion consumer /// and give ownership to the caller. CodeCompleteConsumer *takeCodeCompletionConsumer() { - return CompletionConsumer.take(); + return CompletionConsumer.release(); } /// setCodeCompletionConsumer - Replace the current code completion consumer; @@ -457,7 +499,7 @@ public: /// @name Frontend timer /// { - bool hasFrontendTimer() const { return FrontendTimer.isValid(); } + bool hasFrontendTimer() const { return (bool)FrontendTimer; } llvm::Timer &getFrontendTimer() const { assert(FrontendTimer && "Compiler instance has no frontend timer!"); @@ -495,7 +537,7 @@ public: /// /// \param ShouldOwnClient If Client is non-NULL, specifies whether /// the diagnostic object should take ownership of the client. - void createDiagnostics(DiagnosticConsumer *Client = 0, + void createDiagnostics(DiagnosticConsumer *Client = nullptr, bool ShouldOwnClient = true); /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. @@ -518,9 +560,9 @@ public: /// \return The new object on success, or null on failure. static IntrusiveRefCntPtr<DiagnosticsEngine> createDiagnostics(DiagnosticOptions *Opts, - DiagnosticConsumer *Client = 0, + DiagnosticConsumer *Client = nullptr, bool ShouldOwnClient = true, - const CodeGenOptions *CodeGenOpts = 0); + const CodeGenOptions *CodeGenOpts = nullptr); /// Create the file manager and replace any existing one with it. void createFileManager(); @@ -530,28 +572,26 @@ public: /// Create the preprocessor, using the invocation, file, and source managers, /// and replace any existing one with it. - void createPreprocessor(); + void createPreprocessor(TranslationUnitKind TUKind); /// Create the AST context. void createASTContext(); /// Create an external AST source to read a PCH file and attach it to the AST /// context. - void createPCHExternalASTSource(StringRef Path, - bool DisablePCHValidation, + void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, - void *DeserializationListener); + void *DeserializationListener, + bool OwnDeserializationListener); /// Create an external AST source to read a PCH file. /// /// \return - The new object on success, or null on failure. - static ExternalASTSource * - createPCHExternalASTSource(StringRef Path, const std::string &Sysroot, - bool DisablePCHValidation, - bool AllowPCHWithCompilerErrors, - Preprocessor &PP, ASTContext &Context, - void *DeserializationListener, bool Preamble, - bool UseGlobalModuleIndex); + static ExternalASTSource *createPCHExternalASTSource( + StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, + bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + void *DeserializationListener, bool OwnDeserializationListener, + bool Preamble, bool UseGlobalModuleIndex); /// Create a code completion consumer using the invocation; note that this /// will cause the source manager to truncate the input source file at the @@ -632,6 +672,8 @@ public: std::string *ResultPathName, std::string *TempPathName); + llvm::raw_null_ostream *createNullOutputFile(); + /// } /// @name Initialization Utility Methods /// { @@ -653,21 +695,28 @@ public: const FrontendOptions &Opts); /// } - - virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, - ModuleIdPath Path, - Module::NameVisibilityKind Visibility, - bool IsInclusionDirective); - virtual void makeModuleVisible(Module *Mod, - Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain); + // Create module manager. + void createModuleManager(); + + ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, + Module::NameVisibilityKind Visibility, + bool IsInclusionDirective) override; + + void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, + SourceLocation ImportLoc, bool Complain) override; bool hadModuleLoaderFatalFailure() const { return ModuleLoader::HadFatalFailure; } + GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override; + + bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override; + + void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) { + DependencyCollectors.push_back(std::move(Listener)); + } }; } // end namespace clang |