1 //===- ToolChain.h - Collections of tools for one platform ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
10 #define LLVM_CLANG_DRIVER_TOOLCHAIN_H
11 
12 #include "clang/Basic/DebugInfoOptions.h"
13 #include "clang/Basic/LLVM.h"
14 #include "clang/Basic/LangOptions.h"
15 #include "clang/Basic/Sanitizers.h"
16 #include "clang/Driver/Action.h"
17 #include "clang/Driver/Multilib.h"
18 #include "clang/Driver/Types.h"
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/FloatingPointMode.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/Triple.h"
25 #include "llvm/MC/MCTargetOptions.h"
26 #include "llvm/Option/Option.h"
27 #include "llvm/Support/VersionTuple.h"
28 #include "llvm/Target/TargetOptions.h"
29 #include <cassert>
30 #include <climits>
31 #include <memory>
32 #include <string>
33 #include <utility>
34 
35 namespace llvm {
36 namespace opt {
37 
38 class Arg;
39 class ArgList;
40 class DerivedArgList;
41 
42 } // namespace opt
43 namespace vfs {
44 
45 class FileSystem;
46 
47 } // namespace vfs
48 } // namespace llvm
49 
50 namespace clang {
51 
52 class ObjCRuntime;
53 
54 namespace driver {
55 
56 class Driver;
57 class InputInfo;
58 class SanitizerArgs;
59 class Tool;
60 class XRayArgs;
61 
62 /// Helper structure used to pass information extracted from clang executable
63 /// name such as `i686-linux-android-g++`.
64 struct ParsedClangName {
65   /// Target part of the executable name, as `i686-linux-android`.
66   std::string TargetPrefix;
67 
68   /// Driver mode part of the executable name, as `g++`.
69   std::string ModeSuffix;
70 
71   /// Corresponding driver mode argument, as '--driver-mode=g++'
72   const char *DriverMode = nullptr;
73 
74   /// True if TargetPrefix is recognized as a registered target name.
75   bool TargetIsValid = false;
76 
77   ParsedClangName() = default;
78   ParsedClangName(std::string Suffix, const char *Mode)
79       : ModeSuffix(Suffix), DriverMode(Mode) {}
80   ParsedClangName(std::string Target, std::string Suffix, const char *Mode,
81                   bool IsRegistered)
82       : TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode),
83         TargetIsValid(IsRegistered) {}
84 
85   bool isEmpty() const {
86     return TargetPrefix.empty() && ModeSuffix.empty() && DriverMode == nullptr;
87   }
88 };
89 
90 /// ToolChain - Access to tools for a single platform.
91 class ToolChain {
92 public:
93   using path_list = SmallVector<std::string, 16>;
94 
95   enum CXXStdlibType {
96     CST_Libcxx,
97     CST_Libstdcxx
98   };
99 
100   enum RuntimeLibType {
101     RLT_CompilerRT,
102     RLT_Libgcc
103   };
104 
105   enum UnwindLibType {
106     UNW_None,
107     UNW_CompilerRT,
108     UNW_Libgcc
109   };
110 
111   enum RTTIMode {
112     RM_Enabled,
113     RM_Disabled,
114   };
115 
116   struct BitCodeLibraryInfo {
117     std::string Path;
118     bool ShouldInternalize;
119     BitCodeLibraryInfo(StringRef Path, bool ShouldInternalize = true)
120         : Path(Path), ShouldInternalize(ShouldInternalize) {}
121   };
122 
123   enum FileType { FT_Object, FT_Static, FT_Shared };
124 
125 private:
126   friend class RegisterEffectiveTriple;
127 
128   const Driver &D;
129   llvm::Triple Triple;
130   const llvm::opt::ArgList &Args;
131 
132   // We need to initialize CachedRTTIArg before CachedRTTIMode
133   const llvm::opt::Arg *const CachedRTTIArg;
134 
135   const RTTIMode CachedRTTIMode;
136 
137   /// The list of toolchain specific path prefixes to search for libraries.
138   path_list LibraryPaths;
139 
140   /// The list of toolchain specific path prefixes to search for files.
141   path_list FilePaths;
142 
143   /// The list of toolchain specific path prefixes to search for programs.
144   path_list ProgramPaths;
145 
146   mutable std::unique_ptr<Tool> Clang;
147   mutable std::unique_ptr<Tool> Flang;
148   mutable std::unique_ptr<Tool> Assemble;
149   mutable std::unique_ptr<Tool> Link;
150   mutable std::unique_ptr<Tool> StaticLibTool;
151   mutable std::unique_ptr<Tool> IfsMerge;
152   mutable std::unique_ptr<Tool> OffloadBundler;
153   mutable std::unique_ptr<Tool> OffloadWrapper;
154   mutable std::unique_ptr<Tool> OffloadPackager;
155   mutable std::unique_ptr<Tool> LinkerWrapper;
156 
157   Tool *getClang() const;
158   Tool *getFlang() const;
159   Tool *getAssemble() const;
160   Tool *getLink() const;
161   Tool *getStaticLibTool() const;
162   Tool *getIfsMerge() const;
163   Tool *getClangAs() const;
164   Tool *getOffloadBundler() const;
165   Tool *getOffloadWrapper() const;
166   Tool *getOffloadPackager() const;
167   Tool *getLinkerWrapper() const;
168 
169   mutable bool SanitizerArgsChecked = false;
170   mutable std::unique_ptr<XRayArgs> XRayArguments;
171 
172   /// The effective clang triple for the current Job.
173   mutable llvm::Triple EffectiveTriple;
174 
175   /// Set the toolchain's effective clang triple.
176   void setEffectiveTriple(llvm::Triple ET) const {
177     EffectiveTriple = std::move(ET);
178   }
179 
180   mutable llvm::Optional<CXXStdlibType> cxxStdlibType;
181   mutable llvm::Optional<RuntimeLibType> runtimeLibType;
182   mutable llvm::Optional<UnwindLibType> unwindLibType;
183 
184 protected:
185   MultilibSet Multilibs;
186   Multilib SelectedMultilib;
187 
188   ToolChain(const Driver &D, const llvm::Triple &T,
189             const llvm::opt::ArgList &Args);
190 
191   void setTripleEnvironment(llvm::Triple::EnvironmentType Env);
192 
193   virtual Tool *buildAssembler() const;
194   virtual Tool *buildLinker() const;
195   virtual Tool *buildStaticLibTool() const;
196   virtual Tool *getTool(Action::ActionClass AC) const;
197 
198   virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args,
199                                               StringRef Component,
200                                               FileType Type,
201                                               bool AddArch) const;
202 
203   /// \name Utilities for implementing subclasses.
204   ///@{
205   static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
206                                llvm::opt::ArgStringList &CC1Args,
207                                const Twine &Path);
208   static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs,
209                                       llvm::opt::ArgStringList &CC1Args,
210                                       const Twine &Path);
211   static void
212       addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs,
213                                       llvm::opt::ArgStringList &CC1Args,
214                                       const Twine &Path);
215   static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
216                                 llvm::opt::ArgStringList &CC1Args,
217                                 ArrayRef<StringRef> Paths);
218 
219   static std::string concat(StringRef Path, const Twine &A, const Twine &B = "",
220                             const Twine &C = "", const Twine &D = "");
221   ///@}
222 
223 public:
224   virtual ~ToolChain();
225 
226   // Accessors
227 
228   const Driver &getDriver() const { return D; }
229   llvm::vfs::FileSystem &getVFS() const;
230   const llvm::Triple &getTriple() const { return Triple; }
231 
232   /// Get the toolchain's aux triple, if it has one.
233   ///
234   /// Exactly what the aux triple represents depends on the toolchain, but for
235   /// example when compiling CUDA code for the GPU, the triple might be NVPTX,
236   /// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu.
237   virtual const llvm::Triple *getAuxTriple() const { return nullptr; }
238 
239   /// Some toolchains need to modify the file name, for example to replace the
240   /// extension for object files with .cubin for OpenMP offloading to Nvidia
241   /// GPUs.
242   virtual std::string getInputFilename(const InputInfo &Input) const;
243 
244   llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
245   StringRef getArchName() const { return Triple.getArchName(); }
246   StringRef getPlatform() const { return Triple.getVendorName(); }
247   StringRef getOS() const { return Triple.getOSName(); }
248 
249   /// Provide the default architecture name (as expected by -arch) for
250   /// this toolchain.
251   StringRef getDefaultUniversalArchName() const;
252 
253   std::string getTripleString() const {
254     return Triple.getTriple();
255   }
256 
257   /// Get the toolchain's effective clang triple.
258   const llvm::Triple &getEffectiveTriple() const {
259     assert(!EffectiveTriple.getTriple().empty() && "No effective triple");
260     return EffectiveTriple;
261   }
262 
263   path_list &getLibraryPaths() { return LibraryPaths; }
264   const path_list &getLibraryPaths() const { return LibraryPaths; }
265 
266   path_list &getFilePaths() { return FilePaths; }
267   const path_list &getFilePaths() const { return FilePaths; }
268 
269   path_list &getProgramPaths() { return ProgramPaths; }
270   const path_list &getProgramPaths() const { return ProgramPaths; }
271 
272   const MultilibSet &getMultilibs() const { return Multilibs; }
273 
274   const Multilib &getMultilib() const { return SelectedMultilib; }
275 
276   SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const;
277 
278   const XRayArgs& getXRayArgs() const;
279 
280   // Returns the Arg * that explicitly turned on/off rtti, or nullptr.
281   const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
282 
283   // Returns the RTTIMode for the toolchain with the current arguments.
284   RTTIMode getRTTIMode() const { return CachedRTTIMode; }
285 
286   /// Return any implicit target and/or mode flag for an invocation of
287   /// the compiler driver as `ProgName`.
288   ///
289   /// For example, when called with i686-linux-android-g++, the first element
290   /// of the return value will be set to `"i686-linux-android"` and the second
291   /// will be set to "--driver-mode=g++"`.
292   /// It is OK if the target name is not registered. In this case the return
293   /// value contains false in the field TargetIsValid.
294   ///
295   /// \pre `llvm::InitializeAllTargets()` has been called.
296   /// \param ProgName The name the Clang driver was invoked with (from,
297   /// e.g., argv[0]).
298   /// \return A structure of type ParsedClangName that contains the executable
299   /// name parts.
300   static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName);
301 
302   // Tool access.
303 
304   /// TranslateArgs - Create a new derived argument list for any argument
305   /// translations this ToolChain may wish to perform, or 0 if no tool chain
306   /// specific translations are needed. If \p DeviceOffloadKind is specified
307   /// the translation specific for that offload kind is performed.
308   ///
309   /// \param BoundArch - The bound architecture name, or 0.
310   /// \param DeviceOffloadKind - The device offload kind used for the
311   /// translation.
312   virtual llvm::opt::DerivedArgList *
313   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
314                 Action::OffloadKind DeviceOffloadKind) const {
315     return nullptr;
316   }
317 
318   /// TranslateOpenMPTargetArgs - Create a new derived argument list for
319   /// that contains the OpenMP target specific flags passed via
320   /// -Xopenmp-target -opt=val OR -Xopenmp-target=<triple> -opt=val
321   virtual llvm::opt::DerivedArgList *TranslateOpenMPTargetArgs(
322       const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
323       SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const;
324 
325   /// Append the argument following \p A to \p DAL assuming \p A is an Xarch
326   /// argument. If \p AllocatedArgs is null pointer, synthesized arguments are
327   /// added to \p DAL, otherwise they are appended to \p AllocatedArgs.
328   virtual void TranslateXarchArgs(
329       const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
330       llvm::opt::DerivedArgList *DAL,
331       SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs = nullptr) const;
332 
333   /// Translate -Xarch_ arguments. If there are no such arguments, return
334   /// a null pointer, otherwise return a DerivedArgList containing the
335   /// translated arguments.
336   virtual llvm::opt::DerivedArgList *
337   TranslateXarchArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
338                      Action::OffloadKind DeviceOffloadKind,
339                      SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const;
340 
341   /// Choose a tool to use to handle the action \p JA.
342   ///
343   /// This can be overridden when a particular ToolChain needs to use
344   /// a compiler other than Clang.
345   virtual Tool *SelectTool(const JobAction &JA) const;
346 
347   // Helper methods
348 
349   std::string GetFilePath(const char *Name) const;
350   std::string GetProgramPath(const char *Name) const;
351 
352   /// Returns the linker path, respecting the -fuse-ld= argument to determine
353   /// the linker suffix or name.
354   /// If LinkerIsLLD is non-nullptr, it is set to true if the returned linker
355   /// is LLD. If it's set, it can be assumed that the linker is LLD built
356   /// at the same revision as clang, and clang can make assumptions about
357   /// LLD's supported flags, error output, etc.
358   std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
359 
360   /// Returns the linker path for emitting a static library.
361   std::string GetStaticLibToolPath() const;
362 
363   /// Dispatch to the specific toolchain for verbose printing.
364   ///
365   /// This is used when handling the verbose option to print detailed,
366   /// toolchain-specific information useful for understanding the behavior of
367   /// the driver on a specific platform.
368   virtual void printVerboseInfo(raw_ostream &OS) const {}
369 
370   // Platform defaults information
371 
372   /// Returns true if the toolchain is targeting a non-native
373   /// architecture.
374   virtual bool isCrossCompiling() const;
375 
376   /// HasNativeLTOLinker - Check whether the linker and related tools have
377   /// native LLVM support.
378   virtual bool HasNativeLLVMSupport() const;
379 
380   /// LookupTypeForExtension - Return the default language type to use for the
381   /// given extension.
382   virtual types::ID LookupTypeForExtension(StringRef Ext) const;
383 
384   /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
385   virtual bool IsBlocksDefault() const { return false; }
386 
387   /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
388   /// by default.
389   virtual bool IsIntegratedAssemblerDefault() const { return false; }
390 
391   /// IsIntegratedBackendDefault - Does this tool chain enable
392   /// -fintegrated-objemitter by default.
393   virtual bool IsIntegratedBackendDefault() const { return true; }
394 
395   /// IsIntegratedBackendSupported - Does this tool chain support
396   /// -fintegrated-objemitter.
397   virtual bool IsIntegratedBackendSupported() const { return true; }
398 
399   /// IsNonIntegratedBackendSupported - Does this tool chain support
400   /// -fno-integrated-objemitter.
401   virtual bool IsNonIntegratedBackendSupported() const { return false; }
402 
403   /// Check if the toolchain should use the integrated assembler.
404   virtual bool useIntegratedAs() const;
405 
406   /// Check if the toolchain should use the integrated backend.
407   virtual bool useIntegratedBackend() const;
408 
409   /// Check if the toolchain should use AsmParser to parse inlineAsm when
410   /// integrated assembler is not default.
411   virtual bool parseInlineAsmUsingAsmParser() const { return false; }
412 
413   /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default.
414   virtual bool IsMathErrnoDefault() const { return true; }
415 
416   /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable
417   /// -fencode-extended-block-signature by default.
418   virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; }
419 
420   /// IsObjCNonFragileABIDefault - Does this tool chain set
421   /// -fobjc-nonfragile-abi by default.
422   virtual bool IsObjCNonFragileABIDefault() const { return false; }
423 
424   /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
425   /// mixed dispatch method be used?
426   virtual bool UseObjCMixedDispatch() const { return false; }
427 
428   /// Check whether to enable x86 relax relocations by default.
429   virtual bool useRelaxRelocations() const;
430 
431   /// Check whether use IEEE binary128 as long double format by default.
432   bool defaultToIEEELongDouble() const;
433 
434   /// GetDefaultStackProtectorLevel - Get the default stack protector level for
435   /// this tool chain.
436   virtual LangOptions::StackProtectorMode
437   GetDefaultStackProtectorLevel(bool KernelOrKext) const {
438     return LangOptions::SSPOff;
439   }
440 
441   /// Get the default trivial automatic variable initialization.
442   virtual LangOptions::TrivialAutoVarInitKind
443   GetDefaultTrivialAutoVarInit() const {
444     return LangOptions::TrivialAutoVarInitKind::Uninitialized;
445   }
446 
447   /// GetDefaultLinker - Get the default linker to use.
448   virtual const char *getDefaultLinker() const { return "ld"; }
449 
450   /// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
451   virtual RuntimeLibType GetDefaultRuntimeLibType() const {
452     return ToolChain::RLT_Libgcc;
453   }
454 
455   virtual CXXStdlibType GetDefaultCXXStdlibType() const {
456     return ToolChain::CST_Libstdcxx;
457   }
458 
459   virtual UnwindLibType GetDefaultUnwindLibType() const {
460     return ToolChain::UNW_None;
461   }
462 
463   virtual std::string getCompilerRTPath() const;
464 
465   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
466                                     StringRef Component,
467                                     FileType Type = ToolChain::FT_Static) const;
468 
469   const char *
470   getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component,
471                          FileType Type = ToolChain::FT_Static) const;
472 
473   std::string getCompilerRTBasename(const llvm::opt::ArgList &Args,
474                                     StringRef Component,
475                                     FileType Type = ToolChain::FT_Static) const;
476 
477   // Returns target specific runtime paths.
478   path_list getRuntimePaths() const;
479 
480   // Returns target specific standard library paths.
481   path_list getStdlibPaths() const;
482 
483   // Returns <ResourceDir>/lib/<OSName>/<arch>.  This is used by runtimes (such
484   // as OpenMP) to find arch-specific libraries.
485   std::string getArchSpecificLibPath() const;
486 
487   // Returns <OSname> part of above.
488   virtual StringRef getOSLibName() const;
489 
490   /// needsProfileRT - returns true if instrumentation profile is on.
491   static bool needsProfileRT(const llvm::opt::ArgList &Args);
492 
493   /// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on.
494   static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args);
495 
496   /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
497   /// by default.
498   virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const;
499 
500   /// Test whether this toolchain supports outline atomics by default.
501   virtual bool
502   IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const {
503     return false;
504   }
505 
506   /// Test whether this toolchain defaults to PIC.
507   virtual bool isPICDefault() const = 0;
508 
509   /// Test whether this toolchain defaults to PIE.
510   virtual bool isPIEDefault(const llvm::opt::ArgList &Args) const = 0;
511 
512   /// Tests whether this toolchain forces its default for PIC, PIE or
513   /// non-PIC.  If this returns true, any PIC related flags should be ignored
514   /// and instead the results of \c isPICDefault() and \c isPIEDefault(const
515   /// llvm::opt::ArgList &Args) are used exclusively.
516   virtual bool isPICDefaultForced() const = 0;
517 
518   /// SupportsProfiling - Does this tool chain support -pg.
519   virtual bool SupportsProfiling() const { return true; }
520 
521   /// Complain if this tool chain doesn't support Objective-C ARC.
522   virtual void CheckObjCARC() const {}
523 
524   /// Get the default debug info format. Typically, this is DWARF.
525   virtual codegenoptions::DebugInfoFormat getDefaultDebugFormat() const {
526     return codegenoptions::DIF_DWARF;
527   }
528 
529   /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
530   /// compile unit information.
531   virtual bool UseDwarfDebugFlags() const { return false; }
532 
533   /// Add an additional -fdebug-prefix-map entry.
534   virtual std::string GetGlobalDebugPathRemapping() const { return {}; }
535 
536   // Return the DWARF version to emit, in the absence of arguments
537   // to the contrary.
538   virtual unsigned GetDefaultDwarfVersion() const { return 5; }
539 
540   // Some toolchains may have different restrictions on the DWARF version and
541   // may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host
542   // compilation uses DWARF5.
543   virtual unsigned getMaxDwarfVersion() const { return UINT_MAX; }
544 
545   // True if the driver should assume "-fstandalone-debug"
546   // in the absence of an option specifying otherwise,
547   // provided that debugging was requested in the first place.
548   // i.e. a value of 'true' does not imply that debugging is wanted.
549   virtual bool GetDefaultStandaloneDebug() const { return false; }
550 
551   // Return the default debugger "tuning."
552   virtual llvm::DebuggerKind getDefaultDebuggerTuning() const {
553     return llvm::DebuggerKind::GDB;
554   }
555 
556   /// Does this toolchain supports given debug info option or not.
557   virtual bool supportsDebugInfoOption(const llvm::opt::Arg *) const {
558     return true;
559   }
560 
561   /// Adjust debug information kind considering all passed options.
562   virtual void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind,
563                                    const llvm::opt::ArgList &Args) const {}
564 
565   /// GetExceptionModel - Return the tool chain exception model.
566   virtual llvm::ExceptionHandling
567   GetExceptionModel(const llvm::opt::ArgList &Args) const;
568 
569   /// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
570   virtual bool SupportsEmbeddedBitcode() const { return false; }
571 
572   /// getThreadModel() - Which thread model does this target use?
573   virtual std::string getThreadModel() const { return "posix"; }
574 
575   /// isThreadModelSupported() - Does this target support a thread model?
576   virtual bool isThreadModelSupported(const StringRef Model) const;
577 
578   virtual std::string getMultiarchTriple(const Driver &D,
579                                          const llvm::Triple &TargetTriple,
580                                          StringRef SysRoot) const {
581     return TargetTriple.str();
582   }
583 
584   /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
585   /// command line arguments into account.
586   virtual std::string
587   ComputeLLVMTriple(const llvm::opt::ArgList &Args,
588                     types::ID InputType = types::TY_INVALID) const;
589 
590   /// ComputeEffectiveClangTriple - Return the Clang triple to use for this
591   /// target, which may take into account the command line arguments. For
592   /// example, on Darwin the -mmacosx-version-min= command line argument (which
593   /// sets the deployment target) determines the version in the triple passed to
594   /// Clang.
595   virtual std::string ComputeEffectiveClangTriple(
596       const llvm::opt::ArgList &Args,
597       types::ID InputType = types::TY_INVALID) const;
598 
599   /// getDefaultObjCRuntime - Return the default Objective-C runtime
600   /// for this platform.
601   ///
602   /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
603   virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
604 
605   /// hasBlocksRuntime - Given that the user is compiling with
606   /// -fblocks, does this tool chain guarantee the existence of a
607   /// blocks runtime?
608   ///
609   /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
610   virtual bool hasBlocksRuntime() const { return true; }
611 
612   /// Return the sysroot, possibly searching for a default sysroot using
613   /// target-specific logic.
614   virtual std::string computeSysRoot() const;
615 
616   /// Add the clang cc1 arguments for system include paths.
617   ///
618   /// This routine is responsible for adding the necessary cc1 arguments to
619   /// include headers from standard system header directories.
620   virtual void
621   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
622                             llvm::opt::ArgStringList &CC1Args) const;
623 
624   /// Add options that need to be passed to cc1 for this target.
625   virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
626                                      llvm::opt::ArgStringList &CC1Args,
627                                      Action::OffloadKind DeviceOffloadKind) const;
628 
629   /// Add warning options that need to be passed to cc1 for this target.
630   virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
631 
632   // GetRuntimeLibType - Determine the runtime library type to use with the
633   // given compilation arguments.
634   virtual RuntimeLibType
635   GetRuntimeLibType(const llvm::opt::ArgList &Args) const;
636 
637   // GetCXXStdlibType - Determine the C++ standard library type to use with the
638   // given compilation arguments.
639   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
640 
641   // GetUnwindLibType - Determine the unwind library type to use with the
642   // given compilation arguments.
643   virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
644 
645   // Detect the highest available version of libc++ in include path.
646   virtual std::string detectLibcxxVersion(StringRef IncludePath) const;
647 
648   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
649   /// the include paths to use for the given C++ standard library type.
650   virtual void
651   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
652                                llvm::opt::ArgStringList &CC1Args) const;
653 
654   /// AddClangCXXStdlibIsystemArgs - Add the clang -cc1 level arguments to set
655   /// the specified include paths for the C++ standard library.
656   void AddClangCXXStdlibIsystemArgs(const llvm::opt::ArgList &DriverArgs,
657                                     llvm::opt::ArgStringList &CC1Args) const;
658 
659   /// Returns if the C++ standard library should be linked in.
660   /// Note that e.g. -lm should still be linked even if this returns false.
661   bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
662 
663   /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
664   /// for the given C++ standard library type.
665   virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
666                                    llvm::opt::ArgStringList &CmdArgs) const;
667 
668   /// AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
669   void AddFilePathLibArgs(const llvm::opt::ArgList &Args,
670                           llvm::opt::ArgStringList &CmdArgs) const;
671 
672   /// AddCCKextLibArgs - Add the system specific linker arguments to use
673   /// for kernel extensions (Darwin-specific).
674   virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
675                                 llvm::opt::ArgStringList &CmdArgs) const;
676 
677   /// If a runtime library exists that sets global flags for unsafe floating
678   /// point math, return true.
679   ///
680   /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
681   virtual bool isFastMathRuntimeAvailable(
682     const llvm::opt::ArgList &Args, std::string &Path) const;
683 
684   /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
685   /// global flags for unsafe floating point math, add it and return true.
686   ///
687   /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
688   bool addFastMathRuntimeIfAvailable(
689     const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
690 
691   /// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass
692   /// a suitable profile runtime library to the linker.
693   virtual void addProfileRTLibs(const llvm::opt::ArgList &Args,
694                                 llvm::opt::ArgStringList &CmdArgs) const;
695 
696   /// Add arguments to use system-specific CUDA includes.
697   virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
698                                   llvm::opt::ArgStringList &CC1Args) const;
699 
700   /// Add arguments to use system-specific HIP includes.
701   virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
702                                  llvm::opt::ArgStringList &CC1Args) const;
703 
704   /// Add arguments to use MCU GCC toolchain includes.
705   virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
706                                    llvm::opt::ArgStringList &CC1Args) const;
707 
708   /// On Windows, returns the MSVC compatibility version.
709   virtual VersionTuple computeMSVCVersion(const Driver *D,
710                                           const llvm::opt::ArgList &Args) const;
711 
712   /// Get paths of HIP device libraries.
713   virtual llvm::SmallVector<BitCodeLibraryInfo, 12>
714   getHIPDeviceLibs(const llvm::opt::ArgList &Args) const;
715 
716   /// Add the system specific linker arguments to use
717   /// for the given HIP runtime library type.
718   virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
719                                     llvm::opt::ArgStringList &CmdArgs) const {}
720 
721   /// Return sanitizers which are available in this toolchain.
722   virtual SanitizerMask getSupportedSanitizers() const;
723 
724   /// Return sanitizers which are enabled by default.
725   virtual SanitizerMask getDefaultSanitizers() const {
726     return SanitizerMask();
727   }
728 
729   /// Returns true when it's possible to split LTO unit to use whole
730   /// program devirtualization and CFI santiizers.
731   virtual bool canSplitThinLTOUnit() const { return true; }
732 
733   /// Returns the output denormal handling type in the default floating point
734   /// environment for the given \p FPType if given. Otherwise, the default
735   /// assumed mode for any floating point type.
736   virtual llvm::DenormalMode getDefaultDenormalModeForType(
737       const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
738       const llvm::fltSemantics *FPType = nullptr) const {
739     return llvm::DenormalMode::getIEEE();
740   }
741 
742   virtual Optional<llvm::Triple> getTargetVariantTriple() const {
743     return llvm::None;
744   }
745 
746   // We want to expand the shortened versions of the triples passed in to
747   // the values used for the bitcode libraries.
748   static llvm::Triple getOpenMPTriple(StringRef TripleStr) {
749     llvm::Triple TT(TripleStr);
750     if (TT.getVendor() == llvm::Triple::UnknownVendor ||
751         TT.getOS() == llvm::Triple::UnknownOS) {
752       if (TT.getArch() == llvm::Triple::nvptx)
753         return llvm::Triple("nvptx-nvidia-cuda");
754       if (TT.getArch() == llvm::Triple::nvptx64)
755         return llvm::Triple("nvptx64-nvidia-cuda");
756       if (TT.getArch() == llvm::Triple::amdgcn)
757         return llvm::Triple("amdgcn-amd-amdhsa");
758     }
759     return TT;
760   }
761 };
762 
763 /// Set a ToolChain's effective triple. Reset it when the registration object
764 /// is destroyed.
765 class RegisterEffectiveTriple {
766   const ToolChain &TC;
767 
768 public:
769   RegisterEffectiveTriple(const ToolChain &TC, llvm::Triple T) : TC(TC) {
770     TC.setEffectiveTriple(std::move(T));
771   }
772 
773   ~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); }
774 };
775 
776 } // namespace driver
777 
778 } // namespace clang
779 
780 #endif // LLVM_CLANG_DRIVER_TOOLCHAIN_H
781