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