From 0a0354f39e284020cca2f754f932c2c864ec03a0 Mon Sep 17 00:00:00 2001 From: arphaman Date: Tue, 16 Jul 2013 15:50:01 +0100 Subject: moved compiler instance to flang --- include/clang/Frontend/CompilerInstance.h | 675 ---------------------------- include/clang/Frontend/CompilerInvocation.h | 209 --------- include/flang/Frontend/CompilerInstance.h | 675 ++++++++++++++++++++++++++++ include/flang/Frontend/CompilerInvocation.h | 209 +++++++++ 4 files changed, 884 insertions(+), 884 deletions(-) delete mode 100644 include/clang/Frontend/CompilerInstance.h delete mode 100644 include/clang/Frontend/CompilerInvocation.h create mode 100644 include/flang/Frontend/CompilerInstance.h create mode 100644 include/flang/Frontend/CompilerInvocation.h diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h deleted file mode 100644 index 5673c5908d..0000000000 --- a/include/clang/Frontend/CompilerInstance.h +++ /dev/null @@ -1,675 +0,0 @@ -//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ -#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ - -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Frontend/CompilerInvocation.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 -#include -#include -#include - -namespace llvm { -class raw_fd_ostream; -class Timer; -} - -namespace clang { -class ASTContext; -class ASTConsumer; -class ASTReader; -class CodeCompleteConsumer; -class DiagnosticsEngine; -class DiagnosticConsumer; -class ExternalASTSource; -class FileEntry; -class FileManager; -class FrontendAction; -class Module; -class Preprocessor; -class Sema; -class SourceManager; -class TargetInfo; - -/// CompilerInstance - Helper class for managing a single instance of the Clang -/// compiler. -/// -/// The CompilerInstance serves two purposes: -/// (1) It manages the various objects which are necessary to run the compiler, -/// for example the preprocessor, the target information, and the AST -/// context. -/// (2) It provides utility routines for constructing and manipulating the -/// common Clang objects. -/// -/// The compiler instance generally owns the instance of all the objects that it -/// manages. However, clients can still share objects by manually setting the -/// object and retaking ownership prior to destroying the CompilerInstance. -/// -/// The compiler instance is intended to simplify clients, but not to lock them -/// in to the compiler instance for everything. When possible, utility functions -/// come in two forms; a short form that reuses the CompilerInstance objects, -/// and a long form that takes explicit instances of any required objects. -class CompilerInstance : public ModuleLoader { - /// The options used in this compiler instance. - IntrusiveRefCntPtr Invocation; - - /// The diagnostics engine instance. - IntrusiveRefCntPtr Diagnostics; - - /// The target being compiled for. - IntrusiveRefCntPtr Target; - - /// The file manager. - IntrusiveRefCntPtr FileMgr; - - /// The source manager. - IntrusiveRefCntPtr SourceMgr; - - /// The preprocessor. - IntrusiveRefCntPtr PP; - - /// The AST context. - IntrusiveRefCntPtr Context; - - /// The AST consumer. - OwningPtr Consumer; - - /// The code completion consumer. - OwningPtr CompletionConsumer; - - /// \brief The semantic analysis object. - OwningPtr TheSema; - - /// \brief The frontend timer - OwningPtr FrontendTimer; - - /// \brief Non-owning reference to the ASTReader, if one exists. - ASTReader *ModuleManager; - - /// \brief The set of top-level modules that has already been loaded, - /// along with the module map - llvm::DenseMap KnownModules; - - /// \brief The location of the module-import keyword for the last module - /// import. - SourceLocation LastModuleImportLoc; - - /// \brief The result of the last module import. - /// - ModuleLoadResult LastModuleImportResult; - - /// \brief Whether we should (re)build the global module index once we - /// have finished with this translation unit. - bool BuildGlobalModuleIndex; - - /// \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 - /// failed. - struct OutputFile { - std::string Filename; - std::string TempFilename; - raw_ostream *OS; - - OutputFile(const std::string &filename, const std::string &tempFilename, - raw_ostream *os) - : Filename(filename), TempFilename(tempFilename), OS(os) { } - }; - - /// The list of active output files. - std::list OutputFiles; - - CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION; - void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION; -public: - CompilerInstance(); - ~CompilerInstance(); - - /// @name High-Level Operations - /// { - - /// ExecuteAction - Execute the provided action against the compiler's - /// CompilerInvocation object. - /// - /// This function makes the following assumptions: - /// - /// - The invocation options should be initialized. This function does not - /// handle the '-help' or '-version' options, clients should handle those - /// directly. - /// - /// - The diagnostics engine should have already been created by the client. - /// - /// - No other CompilerInstance state should have been initialized (this is - /// an unchecked error). - /// - /// - Clients should have initialized any LLVM target features that may be - /// required. - /// - /// - Clients should eventually call llvm_shutdown() upon the completion of - /// this routine to ensure that any managed objects are properly destroyed. - /// - /// Note that this routine may write output to 'stderr'. - /// - /// \param Act - The action to execute. - /// \return - True on success. - // - // FIXME: This function should take the stream to write any debugging / - // verbose output to as an argument. - // - // FIXME: Eliminate the llvm_shutdown requirement, that should either be part - // of the context or else not CompilerInstance specific. - bool ExecuteAction(FrontendAction &Act); - - /// } - /// @name Compiler Invocation and Options - /// { - - bool hasInvocation() const { return Invocation != 0; } - - CompilerInvocation &getInvocation() { - assert(Invocation && "Compiler instance has no invocation!"); - return *Invocation; - } - - /// setInvocation - Replace the current invocation. - void setInvocation(CompilerInvocation *Value); - - /// \brief Indicates whether we should (re)build the global module index. - bool shouldBuildGlobalModuleIndex() const; - - /// \brief Set the flag indicating whether we should (re)build the global - /// module index. - void setBuildGlobalModuleIndex(bool Build) { - BuildGlobalModuleIndex = Build; - } - - /// } - /// @name Forwarding Methods - /// { - - AnalyzerOptionsRef getAnalyzerOpts() { - return Invocation->getAnalyzerOpts(); - } - - CodeGenOptions &getCodeGenOpts() { - return Invocation->getCodeGenOpts(); - } - const CodeGenOptions &getCodeGenOpts() const { - return Invocation->getCodeGenOpts(); - } - - DependencyOutputOptions &getDependencyOutputOpts() { - return Invocation->getDependencyOutputOpts(); - } - const DependencyOutputOptions &getDependencyOutputOpts() const { - return Invocation->getDependencyOutputOpts(); - } - - DiagnosticOptions &getDiagnosticOpts() { - return Invocation->getDiagnosticOpts(); - } - const DiagnosticOptions &getDiagnosticOpts() const { - return Invocation->getDiagnosticOpts(); - } - - const FileSystemOptions &getFileSystemOpts() const { - return Invocation->getFileSystemOpts(); - } - - FrontendOptions &getFrontendOpts() { - return Invocation->getFrontendOpts(); - } - const FrontendOptions &getFrontendOpts() const { - return Invocation->getFrontendOpts(); - } - - HeaderSearchOptions &getHeaderSearchOpts() { - return Invocation->getHeaderSearchOpts(); - } - const HeaderSearchOptions &getHeaderSearchOpts() const { - return Invocation->getHeaderSearchOpts(); - } - - LangOptions &getLangOpts() { - return *Invocation->getLangOpts(); - } - const LangOptions &getLangOpts() const { - return *Invocation->getLangOpts(); - } - - PreprocessorOptions &getPreprocessorOpts() { - return Invocation->getPreprocessorOpts(); - } - const PreprocessorOptions &getPreprocessorOpts() const { - return Invocation->getPreprocessorOpts(); - } - - PreprocessorOutputOptions &getPreprocessorOutputOpts() { - return Invocation->getPreprocessorOutputOpts(); - } - const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { - return Invocation->getPreprocessorOutputOpts(); - } - - TargetOptions &getTargetOpts() { - return Invocation->getTargetOpts(); - } - const TargetOptions &getTargetOpts() const { - return Invocation->getTargetOpts(); - } - - /// } - /// @name Diagnostics Engine - /// { - - bool hasDiagnostics() const { return Diagnostics != 0; } - - /// Get the current diagnostics engine. - DiagnosticsEngine &getDiagnostics() const { - assert(Diagnostics && "Compiler instance has no diagnostics!"); - return *Diagnostics; - } - - /// setDiagnostics - Replace the current diagnostics engine. - void setDiagnostics(DiagnosticsEngine *Value); - - DiagnosticConsumer &getDiagnosticClient() const { - assert(Diagnostics && Diagnostics->getClient() && - "Compiler instance has no diagnostic client!"); - return *Diagnostics->getClient(); - } - - /// } - /// @name Target Info - /// { - - bool hasTarget() const { return Target != 0; } - - TargetInfo &getTarget() const { - assert(Target && "Compiler instance has no target!"); - return *Target; - } - - /// Replace the current diagnostics engine. - void setTarget(TargetInfo *Value); - - /// } - /// @name File Manager - /// { - - bool hasFileManager() const { return FileMgr != 0; } - - /// Return the current file manager to the caller. - FileManager &getFileManager() const { - assert(FileMgr && "Compiler instance has no file manager!"); - return *FileMgr; - } - - void resetAndLeakFileManager() { - FileMgr.resetWithoutRelease(); - } - - /// setFileManager - Replace the current file manager. - void setFileManager(FileManager *Value); - - /// } - /// @name Source Manager - /// { - - bool hasSourceManager() const { return SourceMgr != 0; } - - /// Return the current source manager. - SourceManager &getSourceManager() const { - assert(SourceMgr && "Compiler instance has no source manager!"); - return *SourceMgr; - } - - void resetAndLeakSourceManager() { - SourceMgr.resetWithoutRelease(); - } - - /// setSourceManager - Replace the current source manager. - void setSourceManager(SourceManager *Value); - - /// } - /// @name Preprocessor - /// { - - bool hasPreprocessor() const { return PP != 0; } - - /// Return the current preprocessor. - Preprocessor &getPreprocessor() const { - assert(PP && "Compiler instance has no preprocessor!"); - return *PP; - } - - void resetAndLeakPreprocessor() { - PP.resetWithoutRelease(); - } - - /// Replace the current preprocessor. - void setPreprocessor(Preprocessor *Value); - - /// } - /// @name ASTContext - /// { - - bool hasASTContext() const { return Context != 0; } - - ASTContext &getASTContext() const { - assert(Context && "Compiler instance has no AST context!"); - return *Context; - } - - void resetAndLeakASTContext() { - Context.resetWithoutRelease(); - } - - /// setASTContext - Replace the current AST context. - void setASTContext(ASTContext *Value); - - /// \brief Replace the current Sema; the compiler instance takes ownership - /// of S. - void setSema(Sema *S); - - /// } - /// @name ASTConsumer - /// { - - bool hasASTConsumer() const { return Consumer.isValid(); } - - ASTConsumer &getASTConsumer() const { - assert(Consumer && "Compiler instance has no AST consumer!"); - return *Consumer; - } - - /// takeASTConsumer - Remove the current AST consumer and give ownership to - /// the caller. - ASTConsumer *takeASTConsumer() { return Consumer.take(); } - - /// setASTConsumer - Replace the current AST consumer; the compiler instance - /// takes ownership of \p Value. - void setASTConsumer(ASTConsumer *Value); - - /// } - /// @name Semantic analysis - /// { - bool hasSema() const { return TheSema.isValid(); } - - Sema &getSema() const { - assert(TheSema && "Compiler instance has no Sema object!"); - return *TheSema; - } - - Sema *takeSema() { return TheSema.take(); } - - /// } - /// @name Module Management - /// { - - ASTReader *getModuleManager() const { return ModuleManager; } - void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; } - - /// } - /// @name Code Completion - /// { - - bool hasCodeCompletionConsumer() const { - return CompletionConsumer.isValid(); - } - - CodeCompleteConsumer &getCodeCompletionConsumer() const { - assert(CompletionConsumer && - "Compiler instance has no code completion consumer!"); - return *CompletionConsumer; - } - - /// takeCodeCompletionConsumer - Remove the current code completion consumer - /// and give ownership to the caller. - CodeCompleteConsumer *takeCodeCompletionConsumer() { - return CompletionConsumer.take(); - } - - /// setCodeCompletionConsumer - Replace the current code completion consumer; - /// the compiler instance takes ownership of \p Value. - void setCodeCompletionConsumer(CodeCompleteConsumer *Value); - - /// } - /// @name Frontend timer - /// { - - bool hasFrontendTimer() const { return FrontendTimer.isValid(); } - - llvm::Timer &getFrontendTimer() const { - assert(FrontendTimer && "Compiler instance has no frontend timer!"); - return *FrontendTimer; - } - - /// } - /// @name Output Files - /// { - - /// addOutputFile - Add an output file onto the list of tracked output files. - /// - /// \param OutFile - The output file info. - void addOutputFile(const OutputFile &OutFile); - - /// clearOutputFiles - Clear the output file list, destroying the contained - /// output streams. - /// - /// \param EraseFiles - If true, attempt to erase the files from disk. - void clearOutputFiles(bool EraseFiles); - - /// } - /// @name Construction Utility Methods - /// { - - /// Create the diagnostics engine using the invocation's diagnostic options - /// and replace any existing one with it. - /// - /// Note that this routine also replaces the diagnostic client, - /// allocating one if one is not provided. - /// - /// \param Client If non-NULL, a diagnostic client that will be - /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST - /// unit. - /// - /// \param ShouldOwnClient If Client is non-NULL, specifies whether - /// the diagnostic object should take ownership of the client. - void createDiagnostics(DiagnosticConsumer *Client = 0, - bool ShouldOwnClient = true); - - /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. - /// - /// If no diagnostic client is provided, this creates a - /// DiagnosticConsumer that is owned by the returned diagnostic - /// object, if using directly the caller is responsible for - /// releasing the returned DiagnosticsEngine's client eventually. - /// - /// \param Opts - The diagnostic options; note that the created text - /// diagnostic object contains a reference to these options. - /// - /// \param Client If non-NULL, a diagnostic client that will be - /// attached to (and, then, owned by) the returned DiagnosticsEngine - /// object. - /// - /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be - /// used by some diagnostics printers (for logging purposes only). - /// - /// \return The new object on success, or null on failure. - static IntrusiveRefCntPtr - createDiagnostics(DiagnosticOptions *Opts, - DiagnosticConsumer *Client = 0, - bool ShouldOwnClient = true, - const CodeGenOptions *CodeGenOpts = 0); - - /// Create the file manager and replace any existing one with it. - void createFileManager(); - - /// Create the source manager and replace any existing one with it. - void createSourceManager(FileManager &FileMgr); - - /// Create the preprocessor, using the invocation, file, and source managers, - /// and replace any existing one with it. - void createPreprocessor(); - - /// 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, - bool AllowPCHWithCompilerErrors, - void *DeserializationListener); - - /// 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); - - /// Create a code completion consumer using the invocation; note that this - /// will cause the source manager to truncate the input source file at the - /// completion point. - void createCodeCompletionConsumer(); - - /// Create a code completion consumer to print code completion results, at - /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. - static CodeCompleteConsumer * - createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, - unsigned Line, unsigned Column, - const CodeCompleteOptions &Opts, - raw_ostream &OS); - - /// \brief Create the Sema object to be used for parsing. - void createSema(TranslationUnitKind TUKind, - CodeCompleteConsumer *CompletionConsumer); - - /// Create the frontend timer and replace any existing one with it. - void createFrontendTimer(); - - /// Create the default output file (from the invocation's options) and add it - /// to the list of tracked output files. - /// - /// The files created by this function always use temporary files to write to - /// their result (that is, the data is written to a temporary file which will - /// atomically replace the target output on success). - /// - /// \return - Null on error. - llvm::raw_fd_ostream * - createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", - StringRef Extension = ""); - - /// Create a new output file and add it to the list of tracked output files, - /// optionally deriving the output path name. - /// - /// \return - Null on error. - llvm::raw_fd_ostream * - createOutputFile(StringRef OutputPath, - bool Binary, bool RemoveFileOnSignal, - StringRef BaseInput, - StringRef Extension, - bool UseTemporary, - bool CreateMissingDirectories = false); - - /// Create a new output file, optionally deriving the output path name. - /// - /// If \p OutputPath is empty, then createOutputFile will derive an output - /// path location as \p BaseInput, with any suffix removed, and \p Extension - /// appended. If \p OutputPath is not stdout and \p UseTemporary - /// is true, createOutputFile will create a new temporary file that must be - /// renamed to \p OutputPath in the end. - /// - /// \param OutputPath - If given, the path to the output file. - /// \param Error [out] - On failure, the error message. - /// \param BaseInput - If \p OutputPath is empty, the input path name to use - /// for deriving the output path. - /// \param Extension - The extension to use for derived output names. - /// \param Binary - The mode to open the file in. - /// \param RemoveFileOnSignal - Whether the file should be registered with - /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for - /// multithreaded use, as the underlying signal mechanism is not reentrant - /// \param UseTemporary - Create a new temporary file that must be renamed to - /// OutputPath in the end. - /// \param CreateMissingDirectories - When \p UseTemporary is true, create - /// missing directories in the output path. - /// \param ResultPathName [out] - If given, the result path name will be - /// stored here on success. - /// \param TempPathName [out] - If given, the temporary file path name - /// will be stored here on success. - static llvm::raw_fd_ostream * - createOutputFile(StringRef OutputPath, std::string &Error, - bool Binary, bool RemoveFileOnSignal, - StringRef BaseInput, - StringRef Extension, - bool UseTemporary, - bool CreateMissingDirectories, - std::string *ResultPathName, - std::string *TempPathName); - - /// } - /// @name Initialization Utility Methods - /// { - - /// InitializeSourceManager - Initialize the source manager to set InputFile - /// as the main file. - /// - /// \return True on success. - bool InitializeSourceManager(const FrontendInputFile &Input); - - /// InitializeSourceManager - Initialize the source manager to set InputFile - /// as the main file. - /// - /// \return True on success. - static bool InitializeSourceManager(const FrontendInputFile &Input, - DiagnosticsEngine &Diags, - FileManager &FileMgr, - SourceManager &SourceMgr, - 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); - - bool hadModuleLoaderFatalFailure() const { - return ModuleLoader::HadFatalFailure; - } - -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h deleted file mode 100644 index f64773c2c4..0000000000 --- a/include/clang/Frontend/CompilerInvocation.h +++ /dev/null @@ -1,209 +0,0 @@ -//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ -#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ - -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/FileSystemOptions.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/TargetOptions.h" -#include "clang/Frontend/CodeGenOptions.h" -#include "clang/Frontend/DependencyOutputOptions.h" -#include "clang/Frontend/FrontendOptions.h" -#include "clang/Frontend/LangStandard.h" -#include "clang/Frontend/MigratorOptions.h" -#include "clang/Frontend/PreprocessorOutputOptions.h" -#include "clang/Lex/HeaderSearchOptions.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include -#include - -namespace llvm { -namespace opt { -class ArgList; -} -} - -namespace clang { -class CompilerInvocation; -class DiagnosticsEngine; - -/// \brief Fill out Opts based on the options given in Args. -/// -/// Args must have been created from the OptTable returned by -/// createCC1OptTable(). -/// -/// When errors are encountered, return false and, if Diags is non-null, -/// report the error(s). -bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, - DiagnosticsEngine *Diags = 0); - -class CompilerInvocationBase : public RefCountedBase { -protected: - /// Options controlling the language variant. - IntrusiveRefCntPtr LangOpts; - - /// Options controlling the target. - IntrusiveRefCntPtr TargetOpts; - - /// Options controlling the diagnostic engine. - IntrusiveRefCntPtr DiagnosticOpts; - - /// Options controlling the \#include directive. - IntrusiveRefCntPtr HeaderSearchOpts; - - /// Options controlling the preprocessor (aside from \#include handling). - IntrusiveRefCntPtr PreprocessorOpts; - -public: - CompilerInvocationBase(); - - CompilerInvocationBase(const CompilerInvocationBase &X); - - LangOptions *getLangOpts() { return LangOpts.getPtr(); } - const LangOptions *getLangOpts() const { return LangOpts.getPtr(); } - - TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); } - const TargetOptions &getTargetOpts() const { - return *TargetOpts.getPtr(); - } - - DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; } - - HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; } - const HeaderSearchOptions &getHeaderSearchOpts() const { - return *HeaderSearchOpts; - } - - PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; } - const PreprocessorOptions &getPreprocessorOpts() const { - return *PreprocessorOpts; - } -}; - -/// \brief Helper class for holding the data necessary to invoke the compiler. -/// -/// This class is designed to represent an abstract "invocation" of the -/// compiler, including data such as the include paths, the code generation -/// options, the warning flags, and so on. -class CompilerInvocation : public CompilerInvocationBase { - /// Options controlling the static analyzer. - AnalyzerOptionsRef AnalyzerOpts; - - MigratorOptions MigratorOpts; - - /// Options controlling IRgen and the backend. - CodeGenOptions CodeGenOpts; - - /// Options controlling dependency output. - DependencyOutputOptions DependencyOutputOpts; - - /// Options controlling file system operations. - FileSystemOptions FileSystemOpts; - - /// Options controlling the frontend itself. - FrontendOptions FrontendOpts; - - /// Options controlling preprocessed output. - PreprocessorOutputOptions PreprocessorOutputOpts; - -public: - CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {} - - /// @name Utility Methods - /// @{ - - /// \brief Create a compiler invocation from a list of input options. - /// \returns true on success. - /// - /// \param [out] Res - The resulting invocation. - /// \param ArgBegin - The first element in the argument vector. - /// \param ArgEnd - The last element in the argument vector. - /// \param Diags - The diagnostic engine to use for errors. - static bool CreateFromArgs(CompilerInvocation &Res, - const char* const *ArgBegin, - const char* const *ArgEnd, - DiagnosticsEngine &Diags); - - /// \brief Get the directory where the compiler headers - /// reside, relative to the compiler binary (found by the passed in - /// arguments). - /// - /// \param Argv0 - The program path (from argv[0]), for finding the builtin - /// compiler path. - /// \param MainAddr - The address of main (or some other function in the main - /// executable), for finding the builtin compiler path. - static std::string GetResourcesPath(const char *Argv0, void *MainAddr); - - /// \brief Set language defaults for the given input language and - /// language standard in the given LangOptions object. - /// - /// \param Opts - The LangOptions object to set up. - /// \param IK - The input language. - /// \param LangStd - The input language standard. - static void setLangDefaults(LangOptions &Opts, InputKind IK, - LangStandard::Kind LangStd = LangStandard::lang_unspecified); - - /// \brief Retrieve a module hash string that is suitable for uniquely - /// identifying the conditions under which the module was built. - std::string getModuleHash() const; - - /// @} - /// @name Option Subgroups - /// @{ - - AnalyzerOptionsRef getAnalyzerOpts() const { - return AnalyzerOpts; - } - - MigratorOptions &getMigratorOpts() { return MigratorOpts; } - const MigratorOptions &getMigratorOpts() const { - return MigratorOpts; - } - - CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; } - const CodeGenOptions &getCodeGenOpts() const { - return CodeGenOpts; - } - - DependencyOutputOptions &getDependencyOutputOpts() { - return DependencyOutputOpts; - } - const DependencyOutputOptions &getDependencyOutputOpts() const { - return DependencyOutputOpts; - } - - FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } - const FileSystemOptions &getFileSystemOpts() const { - return FileSystemOpts; - } - - FrontendOptions &getFrontendOpts() { return FrontendOpts; } - const FrontendOptions &getFrontendOpts() const { - return FrontendOpts; - } - - PreprocessorOutputOptions &getPreprocessorOutputOpts() { - return PreprocessorOutputOpts; - } - const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { - return PreprocessorOutputOpts; - } - - /// @} -}; - -} // end namespace clang - -#endif diff --git a/include/flang/Frontend/CompilerInstance.h b/include/flang/Frontend/CompilerInstance.h new file mode 100644 index 0000000000..5673c5908d --- /dev/null +++ b/include/flang/Frontend/CompilerInstance.h @@ -0,0 +1,675 @@ +//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ +#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/CompilerInvocation.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 +#include +#include +#include + +namespace llvm { +class raw_fd_ostream; +class Timer; +} + +namespace clang { +class ASTContext; +class ASTConsumer; +class ASTReader; +class CodeCompleteConsumer; +class DiagnosticsEngine; +class DiagnosticConsumer; +class ExternalASTSource; +class FileEntry; +class FileManager; +class FrontendAction; +class Module; +class Preprocessor; +class Sema; +class SourceManager; +class TargetInfo; + +/// CompilerInstance - Helper class for managing a single instance of the Clang +/// compiler. +/// +/// The CompilerInstance serves two purposes: +/// (1) It manages the various objects which are necessary to run the compiler, +/// for example the preprocessor, the target information, and the AST +/// context. +/// (2) It provides utility routines for constructing and manipulating the +/// common Clang objects. +/// +/// The compiler instance generally owns the instance of all the objects that it +/// manages. However, clients can still share objects by manually setting the +/// object and retaking ownership prior to destroying the CompilerInstance. +/// +/// The compiler instance is intended to simplify clients, but not to lock them +/// in to the compiler instance for everything. When possible, utility functions +/// come in two forms; a short form that reuses the CompilerInstance objects, +/// and a long form that takes explicit instances of any required objects. +class CompilerInstance : public ModuleLoader { + /// The options used in this compiler instance. + IntrusiveRefCntPtr Invocation; + + /// The diagnostics engine instance. + IntrusiveRefCntPtr Diagnostics; + + /// The target being compiled for. + IntrusiveRefCntPtr Target; + + /// The file manager. + IntrusiveRefCntPtr FileMgr; + + /// The source manager. + IntrusiveRefCntPtr SourceMgr; + + /// The preprocessor. + IntrusiveRefCntPtr PP; + + /// The AST context. + IntrusiveRefCntPtr Context; + + /// The AST consumer. + OwningPtr Consumer; + + /// The code completion consumer. + OwningPtr CompletionConsumer; + + /// \brief The semantic analysis object. + OwningPtr TheSema; + + /// \brief The frontend timer + OwningPtr FrontendTimer; + + /// \brief Non-owning reference to the ASTReader, if one exists. + ASTReader *ModuleManager; + + /// \brief The set of top-level modules that has already been loaded, + /// along with the module map + llvm::DenseMap KnownModules; + + /// \brief The location of the module-import keyword for the last module + /// import. + SourceLocation LastModuleImportLoc; + + /// \brief The result of the last module import. + /// + ModuleLoadResult LastModuleImportResult; + + /// \brief Whether we should (re)build the global module index once we + /// have finished with this translation unit. + bool BuildGlobalModuleIndex; + + /// \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 + /// failed. + struct OutputFile { + std::string Filename; + std::string TempFilename; + raw_ostream *OS; + + OutputFile(const std::string &filename, const std::string &tempFilename, + raw_ostream *os) + : Filename(filename), TempFilename(tempFilename), OS(os) { } + }; + + /// The list of active output files. + std::list OutputFiles; + + CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION; + void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION; +public: + CompilerInstance(); + ~CompilerInstance(); + + /// @name High-Level Operations + /// { + + /// ExecuteAction - Execute the provided action against the compiler's + /// CompilerInvocation object. + /// + /// This function makes the following assumptions: + /// + /// - The invocation options should be initialized. This function does not + /// handle the '-help' or '-version' options, clients should handle those + /// directly. + /// + /// - The diagnostics engine should have already been created by the client. + /// + /// - No other CompilerInstance state should have been initialized (this is + /// an unchecked error). + /// + /// - Clients should have initialized any LLVM target features that may be + /// required. + /// + /// - Clients should eventually call llvm_shutdown() upon the completion of + /// this routine to ensure that any managed objects are properly destroyed. + /// + /// Note that this routine may write output to 'stderr'. + /// + /// \param Act - The action to execute. + /// \return - True on success. + // + // FIXME: This function should take the stream to write any debugging / + // verbose output to as an argument. + // + // FIXME: Eliminate the llvm_shutdown requirement, that should either be part + // of the context or else not CompilerInstance specific. + bool ExecuteAction(FrontendAction &Act); + + /// } + /// @name Compiler Invocation and Options + /// { + + bool hasInvocation() const { return Invocation != 0; } + + CompilerInvocation &getInvocation() { + assert(Invocation && "Compiler instance has no invocation!"); + return *Invocation; + } + + /// setInvocation - Replace the current invocation. + void setInvocation(CompilerInvocation *Value); + + /// \brief Indicates whether we should (re)build the global module index. + bool shouldBuildGlobalModuleIndex() const; + + /// \brief Set the flag indicating whether we should (re)build the global + /// module index. + void setBuildGlobalModuleIndex(bool Build) { + BuildGlobalModuleIndex = Build; + } + + /// } + /// @name Forwarding Methods + /// { + + AnalyzerOptionsRef getAnalyzerOpts() { + return Invocation->getAnalyzerOpts(); + } + + CodeGenOptions &getCodeGenOpts() { + return Invocation->getCodeGenOpts(); + } + const CodeGenOptions &getCodeGenOpts() const { + return Invocation->getCodeGenOpts(); + } + + DependencyOutputOptions &getDependencyOutputOpts() { + return Invocation->getDependencyOutputOpts(); + } + const DependencyOutputOptions &getDependencyOutputOpts() const { + return Invocation->getDependencyOutputOpts(); + } + + DiagnosticOptions &getDiagnosticOpts() { + return Invocation->getDiagnosticOpts(); + } + const DiagnosticOptions &getDiagnosticOpts() const { + return Invocation->getDiagnosticOpts(); + } + + const FileSystemOptions &getFileSystemOpts() const { + return Invocation->getFileSystemOpts(); + } + + FrontendOptions &getFrontendOpts() { + return Invocation->getFrontendOpts(); + } + const FrontendOptions &getFrontendOpts() const { + return Invocation->getFrontendOpts(); + } + + HeaderSearchOptions &getHeaderSearchOpts() { + return Invocation->getHeaderSearchOpts(); + } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return Invocation->getHeaderSearchOpts(); + } + + LangOptions &getLangOpts() { + return *Invocation->getLangOpts(); + } + const LangOptions &getLangOpts() const { + return *Invocation->getLangOpts(); + } + + PreprocessorOptions &getPreprocessorOpts() { + return Invocation->getPreprocessorOpts(); + } + const PreprocessorOptions &getPreprocessorOpts() const { + return Invocation->getPreprocessorOpts(); + } + + PreprocessorOutputOptions &getPreprocessorOutputOpts() { + return Invocation->getPreprocessorOutputOpts(); + } + const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { + return Invocation->getPreprocessorOutputOpts(); + } + + TargetOptions &getTargetOpts() { + return Invocation->getTargetOpts(); + } + const TargetOptions &getTargetOpts() const { + return Invocation->getTargetOpts(); + } + + /// } + /// @name Diagnostics Engine + /// { + + bool hasDiagnostics() const { return Diagnostics != 0; } + + /// Get the current diagnostics engine. + DiagnosticsEngine &getDiagnostics() const { + assert(Diagnostics && "Compiler instance has no diagnostics!"); + return *Diagnostics; + } + + /// setDiagnostics - Replace the current diagnostics engine. + void setDiagnostics(DiagnosticsEngine *Value); + + DiagnosticConsumer &getDiagnosticClient() const { + assert(Diagnostics && Diagnostics->getClient() && + "Compiler instance has no diagnostic client!"); + return *Diagnostics->getClient(); + } + + /// } + /// @name Target Info + /// { + + bool hasTarget() const { return Target != 0; } + + TargetInfo &getTarget() const { + assert(Target && "Compiler instance has no target!"); + return *Target; + } + + /// Replace the current diagnostics engine. + void setTarget(TargetInfo *Value); + + /// } + /// @name File Manager + /// { + + bool hasFileManager() const { return FileMgr != 0; } + + /// Return the current file manager to the caller. + FileManager &getFileManager() const { + assert(FileMgr && "Compiler instance has no file manager!"); + return *FileMgr; + } + + void resetAndLeakFileManager() { + FileMgr.resetWithoutRelease(); + } + + /// setFileManager - Replace the current file manager. + void setFileManager(FileManager *Value); + + /// } + /// @name Source Manager + /// { + + bool hasSourceManager() const { return SourceMgr != 0; } + + /// Return the current source manager. + SourceManager &getSourceManager() const { + assert(SourceMgr && "Compiler instance has no source manager!"); + return *SourceMgr; + } + + void resetAndLeakSourceManager() { + SourceMgr.resetWithoutRelease(); + } + + /// setSourceManager - Replace the current source manager. + void setSourceManager(SourceManager *Value); + + /// } + /// @name Preprocessor + /// { + + bool hasPreprocessor() const { return PP != 0; } + + /// Return the current preprocessor. + Preprocessor &getPreprocessor() const { + assert(PP && "Compiler instance has no preprocessor!"); + return *PP; + } + + void resetAndLeakPreprocessor() { + PP.resetWithoutRelease(); + } + + /// Replace the current preprocessor. + void setPreprocessor(Preprocessor *Value); + + /// } + /// @name ASTContext + /// { + + bool hasASTContext() const { return Context != 0; } + + ASTContext &getASTContext() const { + assert(Context && "Compiler instance has no AST context!"); + return *Context; + } + + void resetAndLeakASTContext() { + Context.resetWithoutRelease(); + } + + /// setASTContext - Replace the current AST context. + void setASTContext(ASTContext *Value); + + /// \brief Replace the current Sema; the compiler instance takes ownership + /// of S. + void setSema(Sema *S); + + /// } + /// @name ASTConsumer + /// { + + bool hasASTConsumer() const { return Consumer.isValid(); } + + ASTConsumer &getASTConsumer() const { + assert(Consumer && "Compiler instance has no AST consumer!"); + return *Consumer; + } + + /// takeASTConsumer - Remove the current AST consumer and give ownership to + /// the caller. + ASTConsumer *takeASTConsumer() { return Consumer.take(); } + + /// setASTConsumer - Replace the current AST consumer; the compiler instance + /// takes ownership of \p Value. + void setASTConsumer(ASTConsumer *Value); + + /// } + /// @name Semantic analysis + /// { + bool hasSema() const { return TheSema.isValid(); } + + Sema &getSema() const { + assert(TheSema && "Compiler instance has no Sema object!"); + return *TheSema; + } + + Sema *takeSema() { return TheSema.take(); } + + /// } + /// @name Module Management + /// { + + ASTReader *getModuleManager() const { return ModuleManager; } + void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; } + + /// } + /// @name Code Completion + /// { + + bool hasCodeCompletionConsumer() const { + return CompletionConsumer.isValid(); + } + + CodeCompleteConsumer &getCodeCompletionConsumer() const { + assert(CompletionConsumer && + "Compiler instance has no code completion consumer!"); + return *CompletionConsumer; + } + + /// takeCodeCompletionConsumer - Remove the current code completion consumer + /// and give ownership to the caller. + CodeCompleteConsumer *takeCodeCompletionConsumer() { + return CompletionConsumer.take(); + } + + /// setCodeCompletionConsumer - Replace the current code completion consumer; + /// the compiler instance takes ownership of \p Value. + void setCodeCompletionConsumer(CodeCompleteConsumer *Value); + + /// } + /// @name Frontend timer + /// { + + bool hasFrontendTimer() const { return FrontendTimer.isValid(); } + + llvm::Timer &getFrontendTimer() const { + assert(FrontendTimer && "Compiler instance has no frontend timer!"); + return *FrontendTimer; + } + + /// } + /// @name Output Files + /// { + + /// addOutputFile - Add an output file onto the list of tracked output files. + /// + /// \param OutFile - The output file info. + void addOutputFile(const OutputFile &OutFile); + + /// clearOutputFiles - Clear the output file list, destroying the contained + /// output streams. + /// + /// \param EraseFiles - If true, attempt to erase the files from disk. + void clearOutputFiles(bool EraseFiles); + + /// } + /// @name Construction Utility Methods + /// { + + /// Create the diagnostics engine using the invocation's diagnostic options + /// and replace any existing one with it. + /// + /// Note that this routine also replaces the diagnostic client, + /// allocating one if one is not provided. + /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST + /// unit. + /// + /// \param ShouldOwnClient If Client is non-NULL, specifies whether + /// the diagnostic object should take ownership of the client. + void createDiagnostics(DiagnosticConsumer *Client = 0, + bool ShouldOwnClient = true); + + /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. + /// + /// If no diagnostic client is provided, this creates a + /// DiagnosticConsumer that is owned by the returned diagnostic + /// object, if using directly the caller is responsible for + /// releasing the returned DiagnosticsEngine's client eventually. + /// + /// \param Opts - The diagnostic options; note that the created text + /// diagnostic object contains a reference to these options. + /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the returned DiagnosticsEngine + /// object. + /// + /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be + /// used by some diagnostics printers (for logging purposes only). + /// + /// \return The new object on success, or null on failure. + static IntrusiveRefCntPtr + createDiagnostics(DiagnosticOptions *Opts, + DiagnosticConsumer *Client = 0, + bool ShouldOwnClient = true, + const CodeGenOptions *CodeGenOpts = 0); + + /// Create the file manager and replace any existing one with it. + void createFileManager(); + + /// Create the source manager and replace any existing one with it. + void createSourceManager(FileManager &FileMgr); + + /// Create the preprocessor, using the invocation, file, and source managers, + /// and replace any existing one with it. + void createPreprocessor(); + + /// 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, + bool AllowPCHWithCompilerErrors, + void *DeserializationListener); + + /// 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); + + /// Create a code completion consumer using the invocation; note that this + /// will cause the source manager to truncate the input source file at the + /// completion point. + void createCodeCompletionConsumer(); + + /// Create a code completion consumer to print code completion results, at + /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. + static CodeCompleteConsumer * + createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, + unsigned Line, unsigned Column, + const CodeCompleteOptions &Opts, + raw_ostream &OS); + + /// \brief Create the Sema object to be used for parsing. + void createSema(TranslationUnitKind TUKind, + CodeCompleteConsumer *CompletionConsumer); + + /// Create the frontend timer and replace any existing one with it. + void createFrontendTimer(); + + /// Create the default output file (from the invocation's options) and add it + /// to the list of tracked output files. + /// + /// The files created by this function always use temporary files to write to + /// their result (that is, the data is written to a temporary file which will + /// atomically replace the target output on success). + /// + /// \return - Null on error. + llvm::raw_fd_ostream * + createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", + StringRef Extension = ""); + + /// Create a new output file and add it to the list of tracked output files, + /// optionally deriving the output path name. + /// + /// \return - Null on error. + llvm::raw_fd_ostream * + createOutputFile(StringRef OutputPath, + bool Binary, bool RemoveFileOnSignal, + StringRef BaseInput, + StringRef Extension, + bool UseTemporary, + bool CreateMissingDirectories = false); + + /// Create a new output file, optionally deriving the output path name. + /// + /// If \p OutputPath is empty, then createOutputFile will derive an output + /// path location as \p BaseInput, with any suffix removed, and \p Extension + /// appended. If \p OutputPath is not stdout and \p UseTemporary + /// is true, createOutputFile will create a new temporary file that must be + /// renamed to \p OutputPath in the end. + /// + /// \param OutputPath - If given, the path to the output file. + /// \param Error [out] - On failure, the error message. + /// \param BaseInput - If \p OutputPath is empty, the input path name to use + /// for deriving the output path. + /// \param Extension - The extension to use for derived output names. + /// \param Binary - The mode to open the file in. + /// \param RemoveFileOnSignal - Whether the file should be registered with + /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for + /// multithreaded use, as the underlying signal mechanism is not reentrant + /// \param UseTemporary - Create a new temporary file that must be renamed to + /// OutputPath in the end. + /// \param CreateMissingDirectories - When \p UseTemporary is true, create + /// missing directories in the output path. + /// \param ResultPathName [out] - If given, the result path name will be + /// stored here on success. + /// \param TempPathName [out] - If given, the temporary file path name + /// will be stored here on success. + static llvm::raw_fd_ostream * + createOutputFile(StringRef OutputPath, std::string &Error, + bool Binary, bool RemoveFileOnSignal, + StringRef BaseInput, + StringRef Extension, + bool UseTemporary, + bool CreateMissingDirectories, + std::string *ResultPathName, + std::string *TempPathName); + + /// } + /// @name Initialization Utility Methods + /// { + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + bool InitializeSourceManager(const FrontendInputFile &Input); + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + static bool InitializeSourceManager(const FrontendInputFile &Input, + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr, + 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); + + bool hadModuleLoaderFatalFailure() const { + return ModuleLoader::HadFatalFailure; + } + +}; + +} // end namespace clang + +#endif diff --git a/include/flang/Frontend/CompilerInvocation.h b/include/flang/Frontend/CompilerInvocation.h new file mode 100644 index 0000000000..f64773c2c4 --- /dev/null +++ b/include/flang/Frontend/CompilerInvocation.h @@ -0,0 +1,209 @@ +//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ +#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ + +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/CodeGenOptions.h" +#include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Frontend/FrontendOptions.h" +#include "clang/Frontend/LangStandard.h" +#include "clang/Frontend/MigratorOptions.h" +#include "clang/Frontend/PreprocessorOutputOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +namespace llvm { +namespace opt { +class ArgList; +} +} + +namespace clang { +class CompilerInvocation; +class DiagnosticsEngine; + +/// \brief Fill out Opts based on the options given in Args. +/// +/// Args must have been created from the OptTable returned by +/// createCC1OptTable(). +/// +/// When errors are encountered, return false and, if Diags is non-null, +/// report the error(s). +bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, + DiagnosticsEngine *Diags = 0); + +class CompilerInvocationBase : public RefCountedBase { +protected: + /// Options controlling the language variant. + IntrusiveRefCntPtr LangOpts; + + /// Options controlling the target. + IntrusiveRefCntPtr TargetOpts; + + /// Options controlling the diagnostic engine. + IntrusiveRefCntPtr DiagnosticOpts; + + /// Options controlling the \#include directive. + IntrusiveRefCntPtr HeaderSearchOpts; + + /// Options controlling the preprocessor (aside from \#include handling). + IntrusiveRefCntPtr PreprocessorOpts; + +public: + CompilerInvocationBase(); + + CompilerInvocationBase(const CompilerInvocationBase &X); + + LangOptions *getLangOpts() { return LangOpts.getPtr(); } + const LangOptions *getLangOpts() const { return LangOpts.getPtr(); } + + TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); } + const TargetOptions &getTargetOpts() const { + return *TargetOpts.getPtr(); + } + + DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; } + + HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return *HeaderSearchOpts; + } + + PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; } + const PreprocessorOptions &getPreprocessorOpts() const { + return *PreprocessorOpts; + } +}; + +/// \brief Helper class for holding the data necessary to invoke the compiler. +/// +/// This class is designed to represent an abstract "invocation" of the +/// compiler, including data such as the include paths, the code generation +/// options, the warning flags, and so on. +class CompilerInvocation : public CompilerInvocationBase { + /// Options controlling the static analyzer. + AnalyzerOptionsRef AnalyzerOpts; + + MigratorOptions MigratorOpts; + + /// Options controlling IRgen and the backend. + CodeGenOptions CodeGenOpts; + + /// Options controlling dependency output. + DependencyOutputOptions DependencyOutputOpts; + + /// Options controlling file system operations. + FileSystemOptions FileSystemOpts; + + /// Options controlling the frontend itself. + FrontendOptions FrontendOpts; + + /// Options controlling preprocessed output. + PreprocessorOutputOptions PreprocessorOutputOpts; + +public: + CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {} + + /// @name Utility Methods + /// @{ + + /// \brief Create a compiler invocation from a list of input options. + /// \returns true on success. + /// + /// \param [out] Res - The resulting invocation. + /// \param ArgBegin - The first element in the argument vector. + /// \param ArgEnd - The last element in the argument vector. + /// \param Diags - The diagnostic engine to use for errors. + static bool CreateFromArgs(CompilerInvocation &Res, + const char* const *ArgBegin, + const char* const *ArgEnd, + DiagnosticsEngine &Diags); + + /// \brief Get the directory where the compiler headers + /// reside, relative to the compiler binary (found by the passed in + /// arguments). + /// + /// \param Argv0 - The program path (from argv[0]), for finding the builtin + /// compiler path. + /// \param MainAddr - The address of main (or some other function in the main + /// executable), for finding the builtin compiler path. + static std::string GetResourcesPath(const char *Argv0, void *MainAddr); + + /// \brief Set language defaults for the given input language and + /// language standard in the given LangOptions object. + /// + /// \param Opts - The LangOptions object to set up. + /// \param IK - The input language. + /// \param LangStd - The input language standard. + static void setLangDefaults(LangOptions &Opts, InputKind IK, + LangStandard::Kind LangStd = LangStandard::lang_unspecified); + + /// \brief Retrieve a module hash string that is suitable for uniquely + /// identifying the conditions under which the module was built. + std::string getModuleHash() const; + + /// @} + /// @name Option Subgroups + /// @{ + + AnalyzerOptionsRef getAnalyzerOpts() const { + return AnalyzerOpts; + } + + MigratorOptions &getMigratorOpts() { return MigratorOpts; } + const MigratorOptions &getMigratorOpts() const { + return MigratorOpts; + } + + CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; } + const CodeGenOptions &getCodeGenOpts() const { + return CodeGenOpts; + } + + DependencyOutputOptions &getDependencyOutputOpts() { + return DependencyOutputOpts; + } + const DependencyOutputOptions &getDependencyOutputOpts() const { + return DependencyOutputOpts; + } + + FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } + const FileSystemOptions &getFileSystemOpts() const { + return FileSystemOpts; + } + + FrontendOptions &getFrontendOpts() { return FrontendOpts; } + const FrontendOptions &getFrontendOpts() const { + return FrontendOpts; + } + + PreprocessorOutputOptions &getPreprocessorOutputOpts() { + return PreprocessorOutputOpts; + } + const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { + return PreprocessorOutputOpts; + } + + /// @} +}; + +} // end namespace clang + +#endif -- cgit v1.2.1