| //===- ToolChain.h - Collections of tools for one platform ------*- 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_DRIVER_TOOLCHAIN_H |
| #define LLVM_CLANG_DRIVER_TOOLCHAIN_H |
| |
| #include "clang/Basic/LLVM.h" |
| #include "clang/Basic/Sanitizers.h" |
| #include "clang/Driver/Action.h" |
| #include "clang/Driver/Multilib.h" |
| #include "clang/Driver/Types.h" |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/ADT/Triple.h" |
| #include "llvm/MC/MCTargetOptions.h" |
| #include "llvm/Option/Option.h" |
| #include "llvm/Support/VersionTuple.h" |
| #include "llvm/Target/TargetOptions.h" |
| #include <cassert> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| namespace llvm { |
| namespace opt { |
| |
| class Arg; |
| class ArgList; |
| class DerivedArgList; |
| |
| } // namespace opt |
| } // namespace llvm |
| |
| namespace clang { |
| |
| class ObjCRuntime; |
| |
| namespace vfs { |
| |
| class FileSystem; |
| |
| } // namespace vfs |
| |
| namespace driver { |
| |
| class Driver; |
| class InputInfo; |
| class SanitizerArgs; |
| class Tool; |
| class XRayArgs; |
| |
| /// Helper structure used to pass information extracted from clang executable |
| /// name such as `i686-linux-android-g++`. |
| struct ParsedClangName { |
| /// Target part of the executable name, as `i686-linux-android`. |
| std::string TargetPrefix; |
| |
| /// Driver mode part of the executable name, as `g++`. |
| std::string ModeSuffix; |
| |
| /// Corresponding driver mode argument, as '--driver-mode=g++' |
| const char *DriverMode = nullptr; |
| |
| /// True if TargetPrefix is recognized as a registered target name. |
| bool TargetIsValid = false; |
| |
| ParsedClangName() = default; |
| ParsedClangName(std::string Suffix, const char *Mode) |
| : ModeSuffix(Suffix), DriverMode(Mode) {} |
| ParsedClangName(std::string Target, std::string Suffix, const char *Mode, |
| bool IsRegistered) |
| : TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode), |
| TargetIsValid(IsRegistered) {} |
| |
| bool isEmpty() const { |
| return TargetPrefix.empty() && ModeSuffix.empty() && DriverMode == nullptr; |
| } |
| }; |
| |
| /// ToolChain - Access to tools for a single platform. |
| class ToolChain { |
| public: |
| using path_list = SmallVector<std::string, 16>; |
| |
| enum CXXStdlibType { |
| CST_Libcxx, |
| CST_Libstdcxx |
| }; |
| |
| enum RuntimeLibType { |
| RLT_CompilerRT, |
| RLT_Libgcc |
| }; |
| |
| enum RTTIMode { |
| RM_Enabled, |
| RM_Disabled, |
| }; |
| |
| private: |
| friend class RegisterEffectiveTriple; |
| |
| const Driver &D; |
| llvm::Triple Triple; |
| const llvm::opt::ArgList &Args; |
| |
| // We need to initialize CachedRTTIArg before CachedRTTIMode |
| const llvm::opt::Arg *const CachedRTTIArg; |
| |
| const RTTIMode CachedRTTIMode; |
| |
| /// The list of toolchain specific path prefixes to search for files. |
| path_list FilePaths; |
| |
| /// The list of toolchain specific path prefixes to search for programs. |
| path_list ProgramPaths; |
| |
| mutable std::unique_ptr<Tool> Clang; |
| mutable std::unique_ptr<Tool> Assemble; |
| mutable std::unique_ptr<Tool> Link; |
| mutable std::unique_ptr<Tool> OffloadBundler; |
| |
| Tool *getClang() const; |
| Tool *getAssemble() const; |
| Tool *getLink() const; |
| Tool *getClangAs() const; |
| Tool *getOffloadBundler() const; |
| |
| mutable std::unique_ptr<SanitizerArgs> SanitizerArguments; |
| mutable std::unique_ptr<XRayArgs> XRayArguments; |
| |
| /// The effective clang triple for the current Job. |
| mutable llvm::Triple EffectiveTriple; |
| |
| /// Set the toolchain's effective clang triple. |
| void setEffectiveTriple(llvm::Triple ET) const { |
| EffectiveTriple = std::move(ET); |
| } |
| |
| protected: |
| MultilibSet Multilibs; |
| |
| ToolChain(const Driver &D, const llvm::Triple &T, |
| const llvm::opt::ArgList &Args); |
| |
| void setTripleEnvironment(llvm::Triple::EnvironmentType Env); |
| |
| virtual Tool *buildAssembler() const; |
| virtual Tool *buildLinker() const; |
| virtual Tool *getTool(Action::ActionClass AC) const; |
| |
| /// \name Utilities for implementing subclasses. |
| ///@{ |
| static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args, |
| const Twine &Path); |
| static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args, |
| const Twine &Path); |
| static void |
| addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args, |
| const Twine &Path); |
| static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args, |
| ArrayRef<StringRef> Paths); |
| ///@} |
| |
| public: |
| virtual ~ToolChain(); |
| |
| // Accessors |
| |
| const Driver &getDriver() const { return D; } |
| vfs::FileSystem &getVFS() const; |
| const llvm::Triple &getTriple() const { return Triple; } |
| |
| /// Get the toolchain's aux triple, if it has one. |
| /// |
| /// Exactly what the aux triple represents depends on the toolchain, but for |
| /// example when compiling CUDA code for the GPU, the triple might be NVPTX, |
| /// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu. |
| virtual const llvm::Triple *getAuxTriple() const { return nullptr; } |
| |
| /// Some toolchains need to modify the file name, for example to replace the |
| /// extension for object files with .cubin for OpenMP offloading to Nvidia |
| /// GPUs. |
| virtual std::string getInputFilename(const InputInfo &Input) const; |
| |
| llvm::Triple::ArchType getArch() const { return Triple.getArch(); } |
| StringRef getArchName() const { return Triple.getArchName(); } |
| StringRef getPlatform() const { return Triple.getVendorName(); } |
| StringRef getOS() const { return Triple.getOSName(); } |
| |
| /// Provide the default architecture name (as expected by -arch) for |
| /// this toolchain. |
| StringRef getDefaultUniversalArchName() const; |
| |
| std::string getTripleString() const { |
| return Triple.getTriple(); |
| } |
| |
| /// Get the toolchain's effective clang triple. |
| const llvm::Triple &getEffectiveTriple() const { |
| assert(!EffectiveTriple.getTriple().empty() && "No effective triple"); |
| return EffectiveTriple; |
| } |
| |
| path_list &getFilePaths() { return FilePaths; } |
| const path_list &getFilePaths() const { return FilePaths; } |
| |
| path_list &getProgramPaths() { return ProgramPaths; } |
| const path_list &getProgramPaths() const { return ProgramPaths; } |
| |
| const MultilibSet &getMultilibs() const { return Multilibs; } |
| |
| const SanitizerArgs& getSanitizerArgs() const; |
| |
| const XRayArgs& getXRayArgs() const; |
| |
| // Returns the Arg * that explicitly turned on/off rtti, or nullptr. |
| const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; } |
| |
| // Returns the RTTIMode for the toolchain with the current arguments. |
| RTTIMode getRTTIMode() const { return CachedRTTIMode; } |
| |
| /// Return any implicit target and/or mode flag for an invocation of |
| /// the compiler driver as `ProgName`. |
| /// |
| /// For example, when called with i686-linux-android-g++, the first element |
| /// of the return value will be set to `"i686-linux-android"` and the second |
| /// will be set to "--driver-mode=g++"`. |
| /// It is OK if the target name is not registered. In this case the return |
| /// value contains false in the field TargetIsValid. |
| /// |
| /// \pre `llvm::InitializeAllTargets()` has been called. |
| /// \param ProgName The name the Clang driver was invoked with (from, |
| /// e.g., argv[0]). |
| /// \return A structure of type ParsedClangName that contains the executable |
| /// name parts. |
| static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName); |
| |
| // Tool access. |
| |
| /// TranslateArgs - Create a new derived argument list for any argument |
| /// translations this ToolChain may wish to perform, or 0 if no tool chain |
| /// specific translations are needed. If \p DeviceOffloadKind is specified |
| /// the translation specific for that offload kind is performed. |
| /// |
| /// \param BoundArch - The bound architecture name, or 0. |
| /// \param DeviceOffloadKind - The device offload kind used for the |
| /// translation. |
| virtual llvm::opt::DerivedArgList * |
| TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, |
| Action::OffloadKind DeviceOffloadKind) const { |
| return nullptr; |
| } |
| |
| /// TranslateOpenMPTargetArgs - Create a new derived argument list for |
| /// that contains the OpenMP target specific flags passed via |
| /// -Xopenmp-target -opt=val OR -Xopenmp-target=<triple> -opt=val |
| virtual llvm::opt::DerivedArgList *TranslateOpenMPTargetArgs( |
| const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, |
| SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const; |
| |
| /// Choose a tool to use to handle the action \p JA. |
| /// |
| /// This can be overridden when a particular ToolChain needs to use |
| /// a compiler other than Clang. |
| virtual Tool *SelectTool(const JobAction &JA) const; |
| |
| // Helper methods |
| |
| std::string GetFilePath(const char *Name) const; |
| std::string GetProgramPath(const char *Name) const; |
| |
| /// Returns the linker path, respecting the -fuse-ld= argument to determine |
| /// the linker suffix or name. |
| std::string GetLinkerPath() const; |
| |
| /// Dispatch to the specific toolchain for verbose printing. |
| /// |
| /// This is used when handling the verbose option to print detailed, |
| /// toolchain-specific information useful for understanding the behavior of |
| /// the driver on a specific platform. |
| virtual void printVerboseInfo(raw_ostream &OS) const {} |
| |
| // Platform defaults information |
| |
| /// Returns true if the toolchain is targeting a non-native |
| /// architecture. |
| virtual bool isCrossCompiling() const; |
| |
| /// HasNativeLTOLinker - Check whether the linker and related tools have |
| /// native LLVM support. |
| virtual bool HasNativeLLVMSupport() const; |
| |
| /// LookupTypeForExtension - Return the default language type to use for the |
| /// given extension. |
| virtual types::ID LookupTypeForExtension(StringRef Ext) const; |
| |
| /// IsBlocksDefault - Does this tool chain enable -fblocks by default. |
| virtual bool IsBlocksDefault() const { return false; } |
| |
| /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as |
| /// by default. |
| virtual bool IsIntegratedAssemblerDefault() const { return false; } |
| |
| /// Check if the toolchain should use the integrated assembler. |
| virtual bool useIntegratedAs() const; |
| |
| /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default. |
| virtual bool IsMathErrnoDefault() const { return true; } |
| |
| /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable |
| /// -fencode-extended-block-signature by default. |
| virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; } |
| |
| /// IsObjCNonFragileABIDefault - Does this tool chain set |
| /// -fobjc-nonfragile-abi by default. |
| virtual bool IsObjCNonFragileABIDefault() const { return false; } |
| |
| /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the |
| /// mixed dispatch method be used? |
| virtual bool UseObjCMixedDispatch() const { return false; } |
| |
| /// Check whether to enable x86 relax relocations by default. |
| virtual bool useRelaxRelocations() const; |
| |
| /// GetDefaultStackProtectorLevel - Get the default stack protector level for |
| /// this tool chain (0=off, 1=on, 2=strong, 3=all). |
| virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { |
| return 0; |
| } |
| |
| /// GetDefaultLinker - Get the default linker to use. |
| virtual const char *getDefaultLinker() const { return "ld"; } |
| |
| /// GetDefaultRuntimeLibType - Get the default runtime library variant to use. |
| virtual RuntimeLibType GetDefaultRuntimeLibType() const { |
| return ToolChain::RLT_Libgcc; |
| } |
| |
| virtual CXXStdlibType GetDefaultCXXStdlibType() const { |
| return ToolChain::CST_Libstdcxx; |
| } |
| |
| virtual std::string getCompilerRTPath() const; |
| |
| virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, |
| StringRef Component, |
| bool Shared = false) const; |
| |
| const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, |
| StringRef Component, |
| bool Shared = false) const; |
| |
| // Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such |
| // as OpenMP) to find arch-specific libraries. |
| std::string getArchSpecificLibPath() const; |
| |
| // Returns <OSname> part of above. |
| StringRef getOSLibName() const; |
| |
| /// needsProfileRT - returns true if instrumentation profile is on. |
| static bool needsProfileRT(const llvm::opt::ArgList &Args); |
| |
| /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables |
| /// by default. |
| virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const; |
| |
| /// Test whether this toolchain defaults to PIC. |
| virtual bool isPICDefault() const = 0; |
| |
| /// Test whether this toolchain defaults to PIE. |
| virtual bool isPIEDefault() const = 0; |
| |
| /// Tests whether this toolchain forces its default for PIC, PIE or |
| /// non-PIC. If this returns true, any PIC related flags should be ignored |
| /// and instead the results of \c isPICDefault() and \c isPIEDefault() are |
| /// used exclusively. |
| virtual bool isPICDefaultForced() const = 0; |
| |
| /// SupportsProfiling - Does this tool chain support -pg. |
| virtual bool SupportsProfiling() const { return true; } |
| |
| /// Complain if this tool chain doesn't support Objective-C ARC. |
| virtual void CheckObjCARC() const {} |
| |
| /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf |
| /// compile unit information. |
| virtual bool UseDwarfDebugFlags() const { return false; } |
| |
| // Return the DWARF version to emit, in the absence of arguments |
| // to the contrary. |
| virtual unsigned GetDefaultDwarfVersion() const { return 4; } |
| |
| // True if the driver should assume "-fstandalone-debug" |
| // in the absence of an option specifying otherwise, |
| // provided that debugging was requested in the first place. |
| // i.e. a value of 'true' does not imply that debugging is wanted. |
| virtual bool GetDefaultStandaloneDebug() const { return false; } |
| |
| // Return the default debugger "tuning." |
| virtual llvm::DebuggerKind getDefaultDebuggerTuning() const { |
| return llvm::DebuggerKind::GDB; |
| } |
| |
| /// Does this toolchain supports given debug info option or not. |
| virtual bool supportsDebugInfoOption(const llvm::opt::Arg *) const { |
| return true; |
| } |
| |
| /// GetExceptionModel - Return the tool chain exception model. |
| virtual llvm::ExceptionHandling |
| GetExceptionModel(const llvm::opt::ArgList &Args) const; |
| |
| /// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode. |
| virtual bool SupportsEmbeddedBitcode() const { return false; } |
| |
| /// getThreadModel() - Which thread model does this target use? |
| virtual std::string getThreadModel() const { return "posix"; } |
| |
| /// isThreadModelSupported() - Does this target support a thread model? |
| virtual bool isThreadModelSupported(const StringRef Model) const; |
| |
| /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking |
| /// command line arguments into account. |
| virtual std::string |
| ComputeLLVMTriple(const llvm::opt::ArgList &Args, |
| types::ID InputType = types::TY_INVALID) const; |
| |
| /// ComputeEffectiveClangTriple - Return the Clang triple to use for this |
| /// target, which may take into account the command line arguments. For |
| /// example, on Darwin the -mmacosx-version-min= command line argument (which |
| /// sets the deployment target) determines the version in the triple passed to |
| /// Clang. |
| virtual std::string ComputeEffectiveClangTriple( |
| const llvm::opt::ArgList &Args, |
| types::ID InputType = types::TY_INVALID) const; |
| |
| /// getDefaultObjCRuntime - Return the default Objective-C runtime |
| /// for this platform. |
| /// |
| /// FIXME: this really belongs on some sort of DeploymentTarget abstraction |
| virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const; |
| |
| /// hasBlocksRuntime - Given that the user is compiling with |
| /// -fblocks, does this tool chain guarantee the existence of a |
| /// blocks runtime? |
| /// |
| /// FIXME: this really belongs on some sort of DeploymentTarget abstraction |
| virtual bool hasBlocksRuntime() const { return true; } |
| |
| /// Add the clang cc1 arguments for system include paths. |
| /// |
| /// This routine is responsible for adding the necessary cc1 arguments to |
| /// include headers from standard system header directories. |
| virtual void |
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args) const; |
| |
| /// Add options that need to be passed to cc1 for this target. |
| virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args, |
| Action::OffloadKind DeviceOffloadKind) const; |
| |
| /// Add warning options that need to be passed to cc1 for this target. |
| virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const; |
| |
| // GetRuntimeLibType - Determine the runtime library type to use with the |
| // given compilation arguments. |
| virtual RuntimeLibType |
| GetRuntimeLibType(const llvm::opt::ArgList &Args) const; |
| |
| // GetCXXStdlibType - Determine the C++ standard library type to use with the |
| // given compilation arguments. |
| virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const; |
| |
| /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set |
| /// the include paths to use for the given C++ standard library type. |
| virtual void |
| AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args) const; |
| |
| /// Returns if the C++ standard library should be linked in. |
| /// Note that e.g. -lm should still be linked even if this returns false. |
| bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const; |
| |
| /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use |
| /// for the given C++ standard library type. |
| virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, |
| llvm::opt::ArgStringList &CmdArgs) const; |
| |
| /// AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option. |
| void AddFilePathLibArgs(const llvm::opt::ArgList &Args, |
| llvm::opt::ArgStringList &CmdArgs) const; |
| |
| /// AddCCKextLibArgs - Add the system specific linker arguments to use |
| /// for kernel extensions (Darwin-specific). |
| virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, |
| llvm::opt::ArgStringList &CmdArgs) const; |
| |
| /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets |
| /// global flags for unsafe floating point math, add it and return true. |
| /// |
| /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. |
| virtual bool AddFastMathRuntimeIfAvailable( |
| const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; |
| |
| /// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass |
| /// a suitable profile runtime library to the linker. |
| virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, |
| llvm::opt::ArgStringList &CmdArgs) const; |
| |
| /// Add arguments to use system-specific CUDA includes. |
| virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args) const; |
| |
| /// Add arguments to use MCU GCC toolchain includes. |
| virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
| llvm::opt::ArgStringList &CC1Args) const; |
| |
| /// On Windows, returns the MSVC compatibility version. |
| virtual VersionTuple computeMSVCVersion(const Driver *D, |
| const llvm::opt::ArgList &Args) const; |
| |
| /// Return sanitizers which are available in this toolchain. |
| virtual SanitizerMask getSupportedSanitizers() const; |
| |
| /// Return sanitizers which are enabled by default. |
| virtual SanitizerMask getDefaultSanitizers() const { return 0; } |
| }; |
| |
| /// Set a ToolChain's effective triple. Reset it when the registration object |
| /// is destroyed. |
| class RegisterEffectiveTriple { |
| const ToolChain &TC; |
| |
| public: |
| RegisterEffectiveTriple(const ToolChain &TC, llvm::Triple T) : TC(TC) { |
| TC.setEffectiveTriple(std::move(T)); |
| } |
| |
| ~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); } |
| }; |
| |
| } // namespace driver |
| |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_DRIVER_TOOLCHAIN_H |