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