Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:53

0001 //===- ToolChain.h - Collections of tools for one platform ------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
0010 #define LLVM_CLANG_DRIVER_TOOLCHAIN_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Basic/LangOptions.h"
0014 #include "clang/Basic/Sanitizers.h"
0015 #include "clang/Driver/Action.h"
0016 #include "clang/Driver/Multilib.h"
0017 #include "clang/Driver/Types.h"
0018 #include "llvm/ADT/APFloat.h"
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/FloatingPointMode.h"
0021 #include "llvm/ADT/SmallVector.h"
0022 #include "llvm/ADT/StringRef.h"
0023 #include "llvm/Frontend/Debug/Options.h"
0024 #include "llvm/MC/MCTargetOptions.h"
0025 #include "llvm/Option/Option.h"
0026 #include "llvm/Support/VersionTuple.h"
0027 #include "llvm/Target/TargetOptions.h"
0028 #include "llvm/TargetParser/Triple.h"
0029 #include <cassert>
0030 #include <climits>
0031 #include <memory>
0032 #include <optional>
0033 #include <string>
0034 #include <utility>
0035 
0036 namespace llvm {
0037 namespace opt {
0038 
0039 class Arg;
0040 class ArgList;
0041 class DerivedArgList;
0042 
0043 } // namespace opt
0044 namespace vfs {
0045 
0046 class FileSystem;
0047 
0048 } // namespace vfs
0049 } // namespace llvm
0050 
0051 namespace clang {
0052 
0053 class ObjCRuntime;
0054 
0055 namespace driver {
0056 
0057 class Driver;
0058 class InputInfo;
0059 class SanitizerArgs;
0060 class Tool;
0061 class XRayArgs;
0062 
0063 /// Helper structure used to pass information extracted from clang executable
0064 /// name such as `i686-linux-android-g++`.
0065 struct ParsedClangName {
0066   /// Target part of the executable name, as `i686-linux-android`.
0067   std::string TargetPrefix;
0068 
0069   /// Driver mode part of the executable name, as `g++`.
0070   std::string ModeSuffix;
0071 
0072   /// Corresponding driver mode argument, as '--driver-mode=g++'
0073   const char *DriverMode = nullptr;
0074 
0075   /// True if TargetPrefix is recognized as a registered target name.
0076   bool TargetIsValid = false;
0077 
0078   ParsedClangName() = default;
0079   ParsedClangName(std::string Suffix, const char *Mode)
0080       : ModeSuffix(Suffix), DriverMode(Mode) {}
0081   ParsedClangName(std::string Target, std::string Suffix, const char *Mode,
0082                   bool IsRegistered)
0083       : TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode),
0084         TargetIsValid(IsRegistered) {}
0085 
0086   bool isEmpty() const {
0087     return TargetPrefix.empty() && ModeSuffix.empty() && DriverMode == nullptr;
0088   }
0089 };
0090 
0091 /// ToolChain - Access to tools for a single platform.
0092 class ToolChain {
0093 public:
0094   using path_list = SmallVector<std::string, 16>;
0095 
0096   enum CXXStdlibType {
0097     CST_Libcxx,
0098     CST_Libstdcxx
0099   };
0100 
0101   enum RuntimeLibType {
0102     RLT_CompilerRT,
0103     RLT_Libgcc
0104   };
0105 
0106   enum UnwindLibType {
0107     UNW_None,
0108     UNW_CompilerRT,
0109     UNW_Libgcc
0110   };
0111 
0112   enum class UnwindTableLevel {
0113     None,
0114     Synchronous,
0115     Asynchronous,
0116   };
0117 
0118   enum RTTIMode {
0119     RM_Enabled,
0120     RM_Disabled,
0121   };
0122 
0123   enum ExceptionsMode {
0124     EM_Enabled,
0125     EM_Disabled,
0126   };
0127 
0128   struct BitCodeLibraryInfo {
0129     std::string Path;
0130     bool ShouldInternalize;
0131     BitCodeLibraryInfo(StringRef Path, bool ShouldInternalize = true)
0132         : Path(Path), ShouldInternalize(ShouldInternalize) {}
0133   };
0134 
0135   enum FileType { FT_Object, FT_Static, FT_Shared };
0136 
0137 private:
0138   friend class RegisterEffectiveTriple;
0139 
0140   const Driver &D;
0141   llvm::Triple Triple;
0142   const llvm::opt::ArgList &Args;
0143 
0144   // We need to initialize CachedRTTIArg before CachedRTTIMode
0145   const llvm::opt::Arg *const CachedRTTIArg;
0146 
0147   const RTTIMode CachedRTTIMode;
0148 
0149   const ExceptionsMode CachedExceptionsMode;
0150 
0151   /// The list of toolchain specific path prefixes to search for libraries.
0152   path_list LibraryPaths;
0153 
0154   /// The list of toolchain specific path prefixes to search for files.
0155   path_list FilePaths;
0156 
0157   /// The list of toolchain specific path prefixes to search for programs.
0158   path_list ProgramPaths;
0159 
0160   mutable std::unique_ptr<Tool> Clang;
0161   mutable std::unique_ptr<Tool> Flang;
0162   mutable std::unique_ptr<Tool> Assemble;
0163   mutable std::unique_ptr<Tool> Link;
0164   mutable std::unique_ptr<Tool> StaticLibTool;
0165   mutable std::unique_ptr<Tool> IfsMerge;
0166   mutable std::unique_ptr<Tool> OffloadBundler;
0167   mutable std::unique_ptr<Tool> OffloadPackager;
0168   mutable std::unique_ptr<Tool> LinkerWrapper;
0169 
0170   Tool *getClang() const;
0171   Tool *getFlang() const;
0172   Tool *getAssemble() const;
0173   Tool *getLink() const;
0174   Tool *getStaticLibTool() const;
0175   Tool *getIfsMerge() const;
0176   Tool *getClangAs() const;
0177   Tool *getOffloadBundler() const;
0178   Tool *getOffloadPackager() const;
0179   Tool *getLinkerWrapper() const;
0180 
0181   mutable bool SanitizerArgsChecked = false;
0182   mutable std::unique_ptr<XRayArgs> XRayArguments;
0183 
0184   /// The effective clang triple for the current Job.
0185   mutable llvm::Triple EffectiveTriple;
0186 
0187   /// Set the toolchain's effective clang triple.
0188   void setEffectiveTriple(llvm::Triple ET) const {
0189     EffectiveTriple = std::move(ET);
0190   }
0191 
0192   std::optional<std::string>
0193   getFallbackAndroidTargetPath(StringRef BaseDir) const;
0194 
0195   mutable std::optional<CXXStdlibType> cxxStdlibType;
0196   mutable std::optional<RuntimeLibType> runtimeLibType;
0197   mutable std::optional<UnwindLibType> unwindLibType;
0198 
0199 protected:
0200   MultilibSet Multilibs;
0201   llvm::SmallVector<Multilib> SelectedMultilibs;
0202 
0203   ToolChain(const Driver &D, const llvm::Triple &T,
0204             const llvm::opt::ArgList &Args);
0205 
0206   /// Executes the given \p Executable and returns the stdout.
0207   llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
0208   executeToolChainProgram(StringRef Executable) const;
0209 
0210   void setTripleEnvironment(llvm::Triple::EnvironmentType Env);
0211 
0212   virtual Tool *buildAssembler() const;
0213   virtual Tool *buildLinker() const;
0214   virtual Tool *buildStaticLibTool() const;
0215   virtual Tool *getTool(Action::ActionClass AC) const;
0216 
0217   virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args,
0218                                               StringRef Component,
0219                                               FileType Type,
0220                                               bool AddArch) const;
0221 
0222   /// Find the target-specific subdirectory for the current target triple under
0223   /// \p BaseDir, doing fallback triple searches as necessary.
0224   /// \return The subdirectory path if it exists.
0225   std::optional<std::string> getTargetSubDirPath(StringRef BaseDir) const;
0226 
0227   /// \name Utilities for implementing subclasses.
0228   ///@{
0229   static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
0230                                llvm::opt::ArgStringList &CC1Args,
0231                                const Twine &Path);
0232   static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs,
0233                                       llvm::opt::ArgStringList &CC1Args,
0234                                       const Twine &Path);
0235   static void
0236       addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs,
0237                                       llvm::opt::ArgStringList &CC1Args,
0238                                       const Twine &Path);
0239   static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
0240                                 llvm::opt::ArgStringList &CC1Args,
0241                                 ArrayRef<StringRef> Paths);
0242 
0243   static std::string concat(StringRef Path, const Twine &A, const Twine &B = "",
0244                             const Twine &C = "", const Twine &D = "");
0245   ///@}
0246 
0247 public:
0248   virtual ~ToolChain();
0249 
0250   // Accessors
0251 
0252   const Driver &getDriver() const { return D; }
0253   llvm::vfs::FileSystem &getVFS() const;
0254   const llvm::Triple &getTriple() const { return Triple; }
0255 
0256   /// Get the toolchain's aux triple, if it has one.
0257   ///
0258   /// Exactly what the aux triple represents depends on the toolchain, but for
0259   /// example when compiling CUDA code for the GPU, the triple might be NVPTX,
0260   /// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu.
0261   virtual const llvm::Triple *getAuxTriple() const { return nullptr; }
0262 
0263   /// Some toolchains need to modify the file name, for example to replace the
0264   /// extension for object files with .cubin for OpenMP offloading to Nvidia
0265   /// GPUs.
0266   virtual std::string getInputFilename(const InputInfo &Input) const;
0267 
0268   llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
0269   StringRef getArchName() const { return Triple.getArchName(); }
0270   StringRef getPlatform() const { return Triple.getVendorName(); }
0271   StringRef getOS() const { return Triple.getOSName(); }
0272 
0273   /// Provide the default architecture name (as expected by -arch) for
0274   /// this toolchain.
0275   StringRef getDefaultUniversalArchName() const;
0276 
0277   std::string getTripleString() const {
0278     return Triple.getTriple();
0279   }
0280 
0281   /// Get the toolchain's effective clang triple.
0282   const llvm::Triple &getEffectiveTriple() const {
0283     assert(!EffectiveTriple.getTriple().empty() && "No effective triple");
0284     return EffectiveTriple;
0285   }
0286 
0287   bool hasEffectiveTriple() const {
0288     return !EffectiveTriple.getTriple().empty();
0289   }
0290 
0291   path_list &getLibraryPaths() { return LibraryPaths; }
0292   const path_list &getLibraryPaths() const { return LibraryPaths; }
0293 
0294   path_list &getFilePaths() { return FilePaths; }
0295   const path_list &getFilePaths() const { return FilePaths; }
0296 
0297   path_list &getProgramPaths() { return ProgramPaths; }
0298   const path_list &getProgramPaths() const { return ProgramPaths; }
0299 
0300   const MultilibSet &getMultilibs() const { return Multilibs; }
0301 
0302   const llvm::SmallVector<Multilib> &getSelectedMultilibs() const {
0303     return SelectedMultilibs;
0304   }
0305 
0306   /// Get flags suitable for multilib selection, based on the provided clang
0307   /// command line arguments. The command line arguments aren't suitable to be
0308   /// used directly for multilib selection because they are not normalized and
0309   /// normalization is a complex process. The result of this function is similar
0310   /// to clang command line arguments except that the list of arguments is
0311   /// incomplete. Only certain command line arguments are processed. If more
0312   /// command line arguments are needed for multilib selection then this
0313   /// function should be extended.
0314   /// To allow users to find out what flags are returned, clang accepts a
0315   /// -print-multi-flags-experimental argument.
0316   Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const;
0317 
0318   SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const;
0319 
0320   const XRayArgs& getXRayArgs() const;
0321 
0322   // Returns the Arg * that explicitly turned on/off rtti, or nullptr.
0323   const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
0324 
0325   // Returns the RTTIMode for the toolchain with the current arguments.
0326   RTTIMode getRTTIMode() const { return CachedRTTIMode; }
0327 
0328   // Returns the ExceptionsMode for the toolchain with the current arguments.
0329   ExceptionsMode getExceptionsMode() const { return CachedExceptionsMode; }
0330 
0331   /// Return any implicit target and/or mode flag for an invocation of
0332   /// the compiler driver as `ProgName`.
0333   ///
0334   /// For example, when called with i686-linux-android-g++, the first element
0335   /// of the return value will be set to `"i686-linux-android"` and the second
0336   /// will be set to "--driver-mode=g++"`.
0337   /// It is OK if the target name is not registered. In this case the return
0338   /// value contains false in the field TargetIsValid.
0339   ///
0340   /// \pre `llvm::InitializeAllTargets()` has been called.
0341   /// \param ProgName The name the Clang driver was invoked with (from,
0342   /// e.g., argv[0]).
0343   /// \return A structure of type ParsedClangName that contains the executable
0344   /// name parts.
0345   static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName);
0346 
0347   // Tool access.
0348 
0349   /// TranslateArgs - Create a new derived argument list for any argument
0350   /// translations this ToolChain may wish to perform, or 0 if no tool chain
0351   /// specific translations are needed. If \p DeviceOffloadKind is specified
0352   /// the translation specific for that offload kind is performed.
0353   ///
0354   /// \param BoundArch - The bound architecture name, or 0.
0355   /// \param DeviceOffloadKind - The device offload kind used for the
0356   /// translation.
0357   virtual llvm::opt::DerivedArgList *
0358   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
0359                 Action::OffloadKind DeviceOffloadKind) const {
0360     return nullptr;
0361   }
0362 
0363   /// TranslateOpenMPTargetArgs - Create a new derived argument list for
0364   /// that contains the OpenMP target specific flags passed via
0365   /// -Xopenmp-target -opt=val OR -Xopenmp-target=<triple> -opt=val
0366   virtual llvm::opt::DerivedArgList *TranslateOpenMPTargetArgs(
0367       const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
0368       SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const;
0369 
0370   /// Append the argument following \p A to \p DAL assuming \p A is an Xarch
0371   /// argument. If \p AllocatedArgs is null pointer, synthesized arguments are
0372   /// added to \p DAL, otherwise they are appended to \p AllocatedArgs.
0373   virtual void TranslateXarchArgs(
0374       const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
0375       llvm::opt::DerivedArgList *DAL,
0376       SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs = nullptr) const;
0377 
0378   /// Translate -Xarch_ arguments. If there are no such arguments, return
0379   /// a null pointer, otherwise return a DerivedArgList containing the
0380   /// translated arguments.
0381   virtual llvm::opt::DerivedArgList *
0382   TranslateXarchArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
0383                      Action::OffloadKind DeviceOffloadKind,
0384                      SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const;
0385 
0386   /// Choose a tool to use to handle the action \p JA.
0387   ///
0388   /// This can be overridden when a particular ToolChain needs to use
0389   /// a compiler other than Clang.
0390   virtual Tool *SelectTool(const JobAction &JA) const;
0391 
0392   // Helper methods
0393 
0394   std::string GetFilePath(const char *Name) const;
0395   std::string GetProgramPath(const char *Name) const;
0396 
0397   /// Returns the linker path, respecting the -fuse-ld= argument to determine
0398   /// the linker suffix or name.
0399   /// If LinkerIsLLD is non-nullptr, it is set to true if the returned linker
0400   /// is LLD. If it's set, it can be assumed that the linker is LLD built
0401   /// at the same revision as clang, and clang can make assumptions about
0402   /// LLD's supported flags, error output, etc.
0403   std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
0404 
0405   /// Returns the linker path for emitting a static library.
0406   std::string GetStaticLibToolPath() const;
0407 
0408   /// Dispatch to the specific toolchain for verbose printing.
0409   ///
0410   /// This is used when handling the verbose option to print detailed,
0411   /// toolchain-specific information useful for understanding the behavior of
0412   /// the driver on a specific platform.
0413   virtual void printVerboseInfo(raw_ostream &OS) const {}
0414 
0415   // Platform defaults information
0416 
0417   /// Returns true if the toolchain is targeting a non-native
0418   /// architecture.
0419   virtual bool isCrossCompiling() const;
0420 
0421   /// HasNativeLTOLinker - Check whether the linker and related tools have
0422   /// native LLVM support.
0423   virtual bool HasNativeLLVMSupport() const;
0424 
0425   /// LookupTypeForExtension - Return the default language type to use for the
0426   /// given extension.
0427   virtual types::ID LookupTypeForExtension(StringRef Ext) const;
0428 
0429   /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
0430   virtual bool IsBlocksDefault() const { return false; }
0431 
0432   /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
0433   /// by default.
0434   virtual bool IsIntegratedAssemblerDefault() const { return true; }
0435 
0436   /// IsIntegratedBackendDefault - Does this tool chain enable
0437   /// -fintegrated-objemitter by default.
0438   virtual bool IsIntegratedBackendDefault() const { return true; }
0439 
0440   /// IsIntegratedBackendSupported - Does this tool chain support
0441   /// -fintegrated-objemitter.
0442   virtual bool IsIntegratedBackendSupported() const { return true; }
0443 
0444   /// IsNonIntegratedBackendSupported - Does this tool chain support
0445   /// -fno-integrated-objemitter.
0446   virtual bool IsNonIntegratedBackendSupported() const { return false; }
0447 
0448   /// Check if the toolchain should use the integrated assembler.
0449   virtual bool useIntegratedAs() const;
0450 
0451   /// Check if the toolchain should use the integrated backend.
0452   virtual bool useIntegratedBackend() const;
0453 
0454   /// Check if the toolchain should use AsmParser to parse inlineAsm when
0455   /// integrated assembler is not default.
0456   virtual bool parseInlineAsmUsingAsmParser() const { return false; }
0457 
0458   /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default.
0459   virtual bool IsMathErrnoDefault() const { return true; }
0460 
0461   /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable
0462   /// -fencode-extended-block-signature by default.
0463   virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; }
0464 
0465   /// IsObjCNonFragileABIDefault - Does this tool chain set
0466   /// -fobjc-nonfragile-abi by default.
0467   virtual bool IsObjCNonFragileABIDefault() const { return false; }
0468 
0469   /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
0470   /// mixed dispatch method be used?
0471   virtual bool UseObjCMixedDispatch() const { return false; }
0472 
0473   /// Check whether to enable x86 relax relocations by default.
0474   virtual bool useRelaxRelocations() const;
0475 
0476   /// Check whether use IEEE binary128 as long double format by default.
0477   bool defaultToIEEELongDouble() const;
0478 
0479   /// GetDefaultStackProtectorLevel - Get the default stack protector level for
0480   /// this tool chain.
0481   virtual LangOptions::StackProtectorMode
0482   GetDefaultStackProtectorLevel(bool KernelOrKext) const {
0483     return LangOptions::SSPOff;
0484   }
0485 
0486   /// Get the default trivial automatic variable initialization.
0487   virtual LangOptions::TrivialAutoVarInitKind
0488   GetDefaultTrivialAutoVarInit() const {
0489     return LangOptions::TrivialAutoVarInitKind::Uninitialized;
0490   }
0491 
0492   /// GetDefaultLinker - Get the default linker to use.
0493   virtual const char *getDefaultLinker() const { return "ld"; }
0494 
0495   /// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
0496   virtual RuntimeLibType GetDefaultRuntimeLibType() const {
0497     return ToolChain::RLT_Libgcc;
0498   }
0499 
0500   virtual CXXStdlibType GetDefaultCXXStdlibType() const {
0501     return ToolChain::CST_Libstdcxx;
0502   }
0503 
0504   virtual UnwindLibType GetDefaultUnwindLibType() const {
0505     return ToolChain::UNW_None;
0506   }
0507 
0508   virtual std::string getCompilerRTPath() const;
0509 
0510   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
0511                                     StringRef Component,
0512                                     FileType Type = ToolChain::FT_Static) const;
0513 
0514   const char *
0515   getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component,
0516                          FileType Type = ToolChain::FT_Static) const;
0517 
0518   std::string getCompilerRTBasename(const llvm::opt::ArgList &Args,
0519                                     StringRef Component,
0520                                     FileType Type = ToolChain::FT_Static) const;
0521 
0522   // Returns the target specific runtime path if it exists.
0523   std::optional<std::string> getRuntimePath() const;
0524 
0525   // Returns target specific standard library path if it exists.
0526   std::optional<std::string> getStdlibPath() const;
0527 
0528   // Returns target specific standard library include path if it exists.
0529   std::optional<std::string> getStdlibIncludePath() const;
0530 
0531   // Returns <ResourceDir>/lib/<OSName>/<arch> or <ResourceDir>/lib/<triple>.
0532   // This is used by runtimes (such as OpenMP) to find arch-specific libraries.
0533   virtual path_list getArchSpecificLibPaths() const;
0534 
0535   // Returns <OSname> part of above.
0536   virtual StringRef getOSLibName() const;
0537 
0538   /// needsProfileRT - returns true if instrumentation profile is on.
0539   static bool needsProfileRT(const llvm::opt::ArgList &Args);
0540 
0541   /// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on.
0542   static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args);
0543 
0544   /// How detailed should the unwind tables be by default.
0545   virtual UnwindTableLevel
0546   getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const;
0547 
0548   /// Test whether this toolchain supports outline atomics by default.
0549   virtual bool
0550   IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const {
0551     return false;
0552   }
0553 
0554   /// Test whether this toolchain defaults to PIC.
0555   virtual bool isPICDefault() const = 0;
0556 
0557   /// Test whether this toolchain defaults to PIE.
0558   virtual bool isPIEDefault(const llvm::opt::ArgList &Args) const = 0;
0559 
0560   /// Tests whether this toolchain forces its default for PIC, PIE or
0561   /// non-PIC.  If this returns true, any PIC related flags should be ignored
0562   /// and instead the results of \c isPICDefault() and \c isPIEDefault(const
0563   /// llvm::opt::ArgList &Args) are used exclusively.
0564   virtual bool isPICDefaultForced() const = 0;
0565 
0566   /// SupportsProfiling - Does this tool chain support -pg.
0567   virtual bool SupportsProfiling() const { return true; }
0568 
0569   /// Complain if this tool chain doesn't support Objective-C ARC.
0570   virtual void CheckObjCARC() const {}
0571 
0572   /// Get the default debug info format. Typically, this is DWARF.
0573   virtual llvm::codegenoptions::DebugInfoFormat getDefaultDebugFormat() const {
0574     return llvm::codegenoptions::DIF_DWARF;
0575   }
0576 
0577   /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
0578   /// compile unit information.
0579   virtual bool UseDwarfDebugFlags() const { return false; }
0580 
0581   /// Add an additional -fdebug-prefix-map entry.
0582   virtual std::string GetGlobalDebugPathRemapping() const { return {}; }
0583 
0584   // Return the DWARF version to emit, in the absence of arguments
0585   // to the contrary.
0586   virtual unsigned GetDefaultDwarfVersion() const { return 5; }
0587 
0588   // Some toolchains may have different restrictions on the DWARF version and
0589   // may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host
0590   // compilation uses DWARF5.
0591   virtual unsigned getMaxDwarfVersion() const { return UINT_MAX; }
0592 
0593   // True if the driver should assume "-fstandalone-debug"
0594   // in the absence of an option specifying otherwise,
0595   // provided that debugging was requested in the first place.
0596   // i.e. a value of 'true' does not imply that debugging is wanted.
0597   virtual bool GetDefaultStandaloneDebug() const { return false; }
0598 
0599   // Return the default debugger "tuning."
0600   virtual llvm::DebuggerKind getDefaultDebuggerTuning() const {
0601     return llvm::DebuggerKind::GDB;
0602   }
0603 
0604   /// Does this toolchain supports given debug info option or not.
0605   virtual bool supportsDebugInfoOption(const llvm::opt::Arg *) const {
0606     return true;
0607   }
0608 
0609   /// Adjust debug information kind considering all passed options.
0610   virtual void
0611   adjustDebugInfoKind(llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
0612                       const llvm::opt::ArgList &Args) const {}
0613 
0614   /// GetExceptionModel - Return the tool chain exception model.
0615   virtual llvm::ExceptionHandling
0616   GetExceptionModel(const llvm::opt::ArgList &Args) const;
0617 
0618   /// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
0619   virtual bool SupportsEmbeddedBitcode() const { return false; }
0620 
0621   /// getThreadModel() - Which thread model does this target use?
0622   virtual std::string getThreadModel() const { return "posix"; }
0623 
0624   /// isThreadModelSupported() - Does this target support a thread model?
0625   virtual bool isThreadModelSupported(const StringRef Model) const;
0626 
0627   /// isBareMetal - Is this a bare metal target.
0628   virtual bool isBareMetal() const { return false; }
0629 
0630   virtual std::string getMultiarchTriple(const Driver &D,
0631                                          const llvm::Triple &TargetTriple,
0632                                          StringRef SysRoot) const {
0633     return TargetTriple.str();
0634   }
0635 
0636   /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
0637   /// command line arguments into account.
0638   virtual std::string
0639   ComputeLLVMTriple(const llvm::opt::ArgList &Args,
0640                     types::ID InputType = types::TY_INVALID) const;
0641 
0642   /// ComputeEffectiveClangTriple - Return the Clang triple to use for this
0643   /// target, which may take into account the command line arguments. For
0644   /// example, on Darwin the -mmacos-version-min= command line argument (which
0645   /// sets the deployment target) determines the version in the triple passed to
0646   /// Clang.
0647   virtual std::string ComputeEffectiveClangTriple(
0648       const llvm::opt::ArgList &Args,
0649       types::ID InputType = types::TY_INVALID) const;
0650 
0651   /// getDefaultObjCRuntime - Return the default Objective-C runtime
0652   /// for this platform.
0653   ///
0654   /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
0655   virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
0656 
0657   /// hasBlocksRuntime - Given that the user is compiling with
0658   /// -fblocks, does this tool chain guarantee the existence of a
0659   /// blocks runtime?
0660   ///
0661   /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
0662   virtual bool hasBlocksRuntime() const { return true; }
0663 
0664   /// Return the sysroot, possibly searching for a default sysroot using
0665   /// target-specific logic.
0666   virtual std::string computeSysRoot() const;
0667 
0668   /// Add the clang cc1 arguments for system include paths.
0669   ///
0670   /// This routine is responsible for adding the necessary cc1 arguments to
0671   /// include headers from standard system header directories.
0672   virtual void
0673   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0674                             llvm::opt::ArgStringList &CC1Args) const;
0675 
0676   /// Add options that need to be passed to cc1 for this target.
0677   virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
0678                                      llvm::opt::ArgStringList &CC1Args,
0679                                      Action::OffloadKind DeviceOffloadKind) const;
0680 
0681   /// Add options that need to be passed to cc1as for this target.
0682   virtual void
0683   addClangCC1ASTargetOptions(const llvm::opt::ArgList &Args,
0684                              llvm::opt::ArgStringList &CC1ASArgs) const;
0685 
0686   /// Add warning options that need to be passed to cc1 for this target.
0687   virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
0688 
0689   // Get the list of extra macro defines requested by the multilib
0690   // configuration.
0691   virtual SmallVector<std::string>
0692   getMultilibMacroDefinesStr(llvm::opt::ArgList &Args) const {
0693     return {};
0694   };
0695 
0696   // GetRuntimeLibType - Determine the runtime library type to use with the
0697   // given compilation arguments.
0698   virtual RuntimeLibType
0699   GetRuntimeLibType(const llvm::opt::ArgList &Args) const;
0700 
0701   // GetCXXStdlibType - Determine the C++ standard library type to use with the
0702   // given compilation arguments.
0703   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
0704 
0705   // GetUnwindLibType - Determine the unwind library type to use with the
0706   // given compilation arguments.
0707   virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
0708 
0709   // Detect the highest available version of libc++ in include path.
0710   virtual std::string detectLibcxxVersion(StringRef IncludePath) const;
0711 
0712   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
0713   /// the include paths to use for the given C++ standard library type.
0714   virtual void
0715   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0716                                llvm::opt::ArgStringList &CC1Args) const;
0717 
0718   /// AddClangCXXStdlibIsystemArgs - Add the clang -cc1 level arguments to set
0719   /// the specified include paths for the C++ standard library.
0720   void AddClangCXXStdlibIsystemArgs(const llvm::opt::ArgList &DriverArgs,
0721                                     llvm::opt::ArgStringList &CC1Args) const;
0722 
0723   /// Returns if the C++ standard library should be linked in.
0724   /// Note that e.g. -lm should still be linked even if this returns false.
0725   bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
0726 
0727   /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
0728   /// for the given C++ standard library type.
0729   virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
0730                                    llvm::opt::ArgStringList &CmdArgs) const;
0731 
0732   /// AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
0733   void AddFilePathLibArgs(const llvm::opt::ArgList &Args,
0734                           llvm::opt::ArgStringList &CmdArgs) const;
0735 
0736   /// AddCCKextLibArgs - Add the system specific linker arguments to use
0737   /// for kernel extensions (Darwin-specific).
0738   virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
0739                                 llvm::opt::ArgStringList &CmdArgs) const;
0740 
0741   /// If a runtime library exists that sets global flags for unsafe floating
0742   /// point math, return true.
0743   ///
0744   /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
0745   virtual bool isFastMathRuntimeAvailable(
0746     const llvm::opt::ArgList &Args, std::string &Path) const;
0747 
0748   /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
0749   /// global flags for unsafe floating point math, add it and return true.
0750   ///
0751   /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
0752   bool addFastMathRuntimeIfAvailable(
0753     const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
0754 
0755   /// getSystemGPUArchs - Use a tool to detect the user's availible GPUs.
0756   virtual Expected<SmallVector<std::string>>
0757   getSystemGPUArchs(const llvm::opt::ArgList &Args) const;
0758 
0759   /// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass
0760   /// a suitable profile runtime library to the linker.
0761   virtual void addProfileRTLibs(const llvm::opt::ArgList &Args,
0762                                 llvm::opt::ArgStringList &CmdArgs) const;
0763 
0764   /// Add arguments to use system-specific CUDA includes.
0765   virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0766                                   llvm::opt::ArgStringList &CC1Args) const;
0767 
0768   /// Add arguments to use system-specific HIP includes.
0769   virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0770                                  llvm::opt::ArgStringList &CC1Args) const;
0771 
0772   /// Add arguments to use system-specific SYCL includes.
0773   virtual void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0774                                   llvm::opt::ArgStringList &CC1Args) const;
0775 
0776   /// Add arguments to use MCU GCC toolchain includes.
0777   virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
0778                                    llvm::opt::ArgStringList &CC1Args) const;
0779 
0780   /// On Windows, returns the MSVC compatibility version.
0781   virtual VersionTuple computeMSVCVersion(const Driver *D,
0782                                           const llvm::opt::ArgList &Args) const;
0783 
0784   /// Get paths for device libraries.
0785   virtual llvm::SmallVector<BitCodeLibraryInfo, 12>
0786   getDeviceLibs(const llvm::opt::ArgList &Args) const;
0787 
0788   /// Add the system specific linker arguments to use
0789   /// for the given HIP runtime library type.
0790   virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
0791                                     llvm::opt::ArgStringList &CmdArgs) const {}
0792 
0793   /// Return sanitizers which are available in this toolchain.
0794   virtual SanitizerMask getSupportedSanitizers() const;
0795 
0796   /// Return sanitizers which are enabled by default.
0797   virtual SanitizerMask getDefaultSanitizers() const {
0798     return SanitizerMask();
0799   }
0800 
0801   /// Returns true when it's possible to split LTO unit to use whole
0802   /// program devirtualization and CFI santiizers.
0803   virtual bool canSplitThinLTOUnit() const { return true; }
0804 
0805   /// Returns the output denormal handling type in the default floating point
0806   /// environment for the given \p FPType if given. Otherwise, the default
0807   /// assumed mode for any floating point type.
0808   virtual llvm::DenormalMode getDefaultDenormalModeForType(
0809       const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
0810       const llvm::fltSemantics *FPType = nullptr) const {
0811     return llvm::DenormalMode::getIEEE();
0812   }
0813 
0814   // We want to expand the shortened versions of the triples passed in to
0815   // the values used for the bitcode libraries.
0816   static llvm::Triple getOpenMPTriple(StringRef TripleStr) {
0817     llvm::Triple TT(TripleStr);
0818     if (TT.getVendor() == llvm::Triple::UnknownVendor ||
0819         TT.getOS() == llvm::Triple::UnknownOS) {
0820       if (TT.getArch() == llvm::Triple::nvptx)
0821         return llvm::Triple("nvptx-nvidia-cuda");
0822       if (TT.getArch() == llvm::Triple::nvptx64)
0823         return llvm::Triple("nvptx64-nvidia-cuda");
0824       if (TT.getArch() == llvm::Triple::amdgcn)
0825         return llvm::Triple("amdgcn-amd-amdhsa");
0826     }
0827     return TT;
0828   }
0829 };
0830 
0831 /// Set a ToolChain's effective triple. Reset it when the registration object
0832 /// is destroyed.
0833 class RegisterEffectiveTriple {
0834   const ToolChain &TC;
0835 
0836 public:
0837   RegisterEffectiveTriple(const ToolChain &TC, llvm::Triple T) : TC(TC) {
0838     TC.setEffectiveTriple(std::move(T));
0839   }
0840 
0841   ~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); }
0842 };
0843 
0844 } // namespace driver
0845 
0846 } // namespace clang
0847 
0848 #endif // LLVM_CLANG_DRIVER_TOOLCHAIN_H