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