]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h
MFV r359393: tcsh: import 6974bc35a5cd
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / Driver / ToolChains / Darwin.h
1 //===--- Darwin.h - Darwin ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_DARWIN_H
10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
11
12 #include "Cuda.h"
13 #include "clang/Driver/DarwinSDKInfo.h"
14 #include "clang/Driver/Tool.h"
15 #include "clang/Driver/ToolChain.h"
16 #include "clang/Driver/XRayArgs.h"
17
18 namespace clang {
19 namespace driver {
20
21 namespace toolchains {
22 class MachO;
23 } // end namespace toolchains
24
25 namespace tools {
26
27 namespace darwin {
28 llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
29 void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
30
31 class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
32   virtual void anchor();
33
34 protected:
35   void AddMachOArch(const llvm::opt::ArgList &Args,
36                     llvm::opt::ArgStringList &CmdArgs) const;
37
38   const toolchains::MachO &getMachOToolChain() const {
39     return reinterpret_cast<const toolchains::MachO &>(getToolChain());
40   }
41
42 public:
43   MachOTool(
44       const char *Name, const char *ShortName, const ToolChain &TC,
45       ResponseFileSupport ResponseSupport = RF_None,
46       llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
47       const char *ResponseFlag = "@")
48       : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
49              ResponseFlag) {}
50 };
51
52 class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
53 public:
54   Assembler(const ToolChain &TC)
55       : MachOTool("darwin::Assembler", "assembler", TC) {}
56
57   bool hasIntegratedCPP() const override { return false; }
58
59   void ConstructJob(Compilation &C, const JobAction &JA,
60                     const InputInfo &Output, const InputInfoList &Inputs,
61                     const llvm::opt::ArgList &TCArgs,
62                     const char *LinkingOutput) const override;
63 };
64
65 class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
66   bool NeedsTempPath(const InputInfoList &Inputs) const;
67   void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
68                    llvm::opt::ArgStringList &CmdArgs,
69                    const InputInfoList &Inputs) const;
70
71 public:
72   Linker(const ToolChain &TC)
73       : MachOTool("darwin::Linker", "linker", TC, RF_FileList,
74                   llvm::sys::WEM_UTF8, "-filelist") {}
75
76   bool hasIntegratedCPP() const override { return false; }
77   bool isLinkJob() const override { return true; }
78
79   void ConstructJob(Compilation &C, const JobAction &JA,
80                     const InputInfo &Output, const InputInfoList &Inputs,
81                     const llvm::opt::ArgList &TCArgs,
82                     const char *LinkingOutput) const override;
83 };
84
85 class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
86 public:
87   Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
88
89   bool hasIntegratedCPP() const override { return false; }
90
91   void ConstructJob(Compilation &C, const JobAction &JA,
92                     const InputInfo &Output, const InputInfoList &Inputs,
93                     const llvm::opt::ArgList &TCArgs,
94                     const char *LinkingOutput) const override;
95 };
96
97 class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
98 public:
99   Dsymutil(const ToolChain &TC)
100       : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
101
102   bool hasIntegratedCPP() const override { return false; }
103   bool isDsymutilJob() const override { return true; }
104
105   void ConstructJob(Compilation &C, const JobAction &JA,
106                     const InputInfo &Output, const InputInfoList &Inputs,
107                     const llvm::opt::ArgList &TCArgs,
108                     const char *LinkingOutput) const override;
109 };
110
111 class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
112 public:
113   VerifyDebug(const ToolChain &TC)
114       : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
115
116   bool hasIntegratedCPP() const override { return false; }
117
118   void ConstructJob(Compilation &C, const JobAction &JA,
119                     const InputInfo &Output, const InputInfoList &Inputs,
120                     const llvm::opt::ArgList &TCArgs,
121                     const char *LinkingOutput) const override;
122 };
123 } // end namespace darwin
124 } // end namespace tools
125
126 namespace toolchains {
127
128 class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
129 protected:
130   Tool *buildAssembler() const override;
131   Tool *buildLinker() const override;
132   Tool *getTool(Action::ActionClass AC) const override;
133
134 private:
135   mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
136   mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
137   mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
138
139 public:
140   MachO(const Driver &D, const llvm::Triple &Triple,
141         const llvm::opt::ArgList &Args);
142   ~MachO() override;
143
144   /// @name MachO specific toolchain API
145   /// {
146
147   /// Get the "MachO" arch name for a particular compiler invocation. For
148   /// example, Apple treats different ARM variations as distinct architectures.
149   StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
150
151   /// Add the linker arguments to link the ARC runtime library.
152   virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
153                               llvm::opt::ArgStringList &CmdArgs) const {}
154
155   /// Add the linker arguments to link the compiler runtime library.
156   ///
157   /// FIXME: This API is intended for use with embedded libraries only, and is
158   /// misleadingly named.
159   virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
160                                      llvm::opt::ArgStringList &CmdArgs,
161                                      bool ForceLinkBuiltinRT = false) const;
162
163   virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
164                                       llvm::opt::ArgStringList &CmdArgs) const {
165   }
166
167   virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
168                                  llvm::opt::ArgStringList &CmdArgs) const {}
169
170   virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args,
171                                       llvm::opt::ArgStringList &CmdArgs) const {
172   }
173
174   /// On some iOS platforms, kernel and kernel modules were built statically. Is
175   /// this such a target?
176   virtual bool isKernelStatic() const { return false; }
177
178   /// Is the target either iOS or an iOS simulator?
179   bool isTargetIOSBased() const { return false; }
180
181   /// Options to control how a runtime library is linked.
182   enum RuntimeLinkOptions : unsigned {
183     /// Link the library in even if it can't be found in the VFS.
184     RLO_AlwaysLink = 1 << 0,
185
186     /// Use the embedded runtime from the macho_embedded directory.
187     RLO_IsEmbedded = 1 << 1,
188
189     /// Emit rpaths for @executable_path as well as the resource directory.
190     RLO_AddRPath = 1 << 2,
191
192     /// Link the library in before any others.
193     RLO_FirstLink = 1 << 3,
194   };
195
196   /// Add a runtime library to the list of items to link.
197   void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
198                          llvm::opt::ArgStringList &CmdArgs, StringRef Component,
199                          RuntimeLinkOptions Opts = RuntimeLinkOptions(),
200                          bool IsShared = false) const;
201
202   /// Add any profiling runtime libraries that are needed. This is essentially a
203   /// MachO specific version of addProfileRT in Tools.cpp.
204   void addProfileRTLibs(const llvm::opt::ArgList &Args,
205                         llvm::opt::ArgStringList &CmdArgs) const override {
206     // There aren't any profiling libs for embedded targets currently.
207   }
208
209   /// }
210   /// @name ToolChain Implementation
211   /// {
212
213   types::ID LookupTypeForExtension(StringRef Ext) const override;
214
215   bool HasNativeLLVMSupport() const override;
216
217   llvm::opt::DerivedArgList *
218   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
219                 Action::OffloadKind DeviceOffloadKind) const override;
220
221   bool IsBlocksDefault() const override {
222     // Always allow blocks on Apple; users interested in versioning are
223     // expected to use /usr/include/Block.h.
224     return true;
225   }
226   bool IsIntegratedAssemblerDefault() const override {
227     // Default integrated assembler to on for Apple's MachO targets.
228     return true;
229   }
230
231   bool IsMathErrnoDefault() const override { return false; }
232
233   bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
234
235   bool IsObjCNonFragileABIDefault() const override {
236     // Non-fragile ABI is default for everything but i386.
237     return getTriple().getArch() != llvm::Triple::x86;
238   }
239
240   bool UseObjCMixedDispatch() const override { return true; }
241
242   bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
243
244   RuntimeLibType GetDefaultRuntimeLibType() const override {
245     return ToolChain::RLT_CompilerRT;
246   }
247
248   bool isPICDefault() const override;
249   bool isPIEDefault() const override;
250   bool isPICDefaultForced() const override;
251
252   bool SupportsProfiling() const override;
253
254   bool UseDwarfDebugFlags() const override;
255
256   llvm::ExceptionHandling
257   GetExceptionModel(const llvm::opt::ArgList &Args) const override {
258     return llvm::ExceptionHandling::None;
259   }
260
261   virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
262     return "";
263   }
264
265   // Darwin toolchain uses legacy thin LTO API, which is not
266   // capable of unit splitting.
267   bool canSplitThinLTOUnit() const override { return false; }
268   /// }
269 };
270
271 /// Darwin - The base Darwin tool chain.
272 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
273 public:
274   /// Whether the information on the target has been initialized.
275   //
276   // FIXME: This should be eliminated. What we want to do is make this part of
277   // the "default target for arguments" selection process, once we get out of
278   // the argument translation business.
279   mutable bool TargetInitialized;
280
281   enum DarwinPlatformKind {
282     MacOS,
283     IPhoneOS,
284     TvOS,
285     WatchOS,
286     LastDarwinPlatform = WatchOS
287   };
288   enum DarwinEnvironmentKind {
289     NativeEnvironment,
290     Simulator,
291   };
292
293   mutable DarwinPlatformKind TargetPlatform;
294   mutable DarwinEnvironmentKind TargetEnvironment;
295
296   /// The OS version we are targeting.
297   mutable VersionTuple TargetVersion;
298
299   /// The information about the darwin SDK that was used.
300   mutable Optional<DarwinSDKInfo> SDKInfo;
301
302   CudaInstallationDetector CudaInstallation;
303
304 private:
305   void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
306
307 public:
308   Darwin(const Driver &D, const llvm::Triple &Triple,
309          const llvm::opt::ArgList &Args);
310   ~Darwin() override;
311
312   std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
313                                           types::ID InputType) const override;
314
315   /// @name Apple Specific Toolchain Implementation
316   /// {
317
318   void addMinVersionArgs(const llvm::opt::ArgList &Args,
319                          llvm::opt::ArgStringList &CmdArgs) const override;
320
321   void addPlatformVersionArgs(const llvm::opt::ArgList &Args,
322                               llvm::opt::ArgStringList &CmdArgs) const override;
323
324   void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
325                               llvm::opt::ArgStringList &CmdArgs) const override;
326
327   bool isKernelStatic() const override {
328     return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
329             !isTargetWatchOS());
330   }
331
332   void addProfileRTLibs(const llvm::opt::ArgList &Args,
333                         llvm::opt::ArgStringList &CmdArgs) const override;
334
335 protected:
336   /// }
337   /// @name Darwin specific Toolchain functions
338   /// {
339
340   // FIXME: Eliminate these ...Target functions and derive separate tool chains
341   // for these targets and put version in constructor.
342   void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
343                  unsigned Major, unsigned Minor, unsigned Micro) const {
344     // FIXME: For now, allow reinitialization as long as values don't
345     // change. This will go away when we move away from argument translation.
346     if (TargetInitialized && TargetPlatform == Platform &&
347         TargetEnvironment == Environment &&
348         TargetVersion == VersionTuple(Major, Minor, Micro))
349       return;
350
351     assert(!TargetInitialized && "Target already initialized!");
352     TargetInitialized = true;
353     TargetPlatform = Platform;
354     TargetEnvironment = Environment;
355     TargetVersion = VersionTuple(Major, Minor, Micro);
356     if (Environment == Simulator)
357       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
358   }
359
360   bool isTargetIPhoneOS() const {
361     assert(TargetInitialized && "Target not initialized!");
362     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
363            TargetEnvironment == NativeEnvironment;
364   }
365
366   bool isTargetIOSSimulator() const {
367     assert(TargetInitialized && "Target not initialized!");
368     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
369            TargetEnvironment == Simulator;
370   }
371
372   bool isTargetIOSBased() const {
373     assert(TargetInitialized && "Target not initialized!");
374     return isTargetIPhoneOS() || isTargetIOSSimulator();
375   }
376
377   bool isTargetTvOS() const {
378     assert(TargetInitialized && "Target not initialized!");
379     return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
380   }
381
382   bool isTargetTvOSSimulator() const {
383     assert(TargetInitialized && "Target not initialized!");
384     return TargetPlatform == TvOS && TargetEnvironment == Simulator;
385   }
386
387   bool isTargetTvOSBased() const {
388     assert(TargetInitialized && "Target not initialized!");
389     return TargetPlatform == TvOS;
390   }
391
392   bool isTargetWatchOS() const {
393     assert(TargetInitialized && "Target not initialized!");
394     return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
395   }
396
397   bool isTargetWatchOSSimulator() const {
398     assert(TargetInitialized && "Target not initialized!");
399     return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
400   }
401
402   bool isTargetWatchOSBased() const {
403     assert(TargetInitialized && "Target not initialized!");
404     return TargetPlatform == WatchOS;
405   }
406
407   bool isTargetMacOS() const {
408     assert(TargetInitialized && "Target not initialized!");
409     return TargetPlatform == MacOS;
410   }
411
412   bool isTargetInitialized() const { return TargetInitialized; }
413
414   VersionTuple getTargetVersion() const {
415     assert(TargetInitialized && "Target not initialized!");
416     return TargetVersion;
417   }
418
419   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
420                            unsigned V2 = 0) const {
421     assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
422     return TargetVersion < VersionTuple(V0, V1, V2);
423   }
424
425   bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
426     assert(isTargetMacOS() && "Unexpected call for non OS X target!");
427     return TargetVersion < VersionTuple(V0, V1, V2);
428   }
429
430   /// Return true if c++17 aligned allocation/deallocation functions are not
431   /// implemented in the c++ standard library of the deployment target we are
432   /// targeting.
433   bool isAlignedAllocationUnavailable() const;
434
435   void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
436                              llvm::opt::ArgStringList &CC1Args,
437                              Action::OffloadKind DeviceOffloadKind) const override;
438
439   StringRef getPlatformFamily() const;
440   StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
441
442 public:
443   static StringRef getSDKName(StringRef isysroot);
444
445   /// }
446   /// @name ToolChain Implementation
447   /// {
448
449   // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
450   // most development is done against SDKs, so compiling for a different
451   // architecture should not get any special treatment.
452   bool isCrossCompiling() const override { return false; }
453
454   llvm::opt::DerivedArgList *
455   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
456                 Action::OffloadKind DeviceOffloadKind) const override;
457
458   CXXStdlibType GetDefaultCXXStdlibType() const override;
459   ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
460   bool hasBlocksRuntime() const override;
461
462   void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
463                           llvm::opt::ArgStringList &CC1Args) const override;
464
465   bool UseObjCMixedDispatch() const override {
466     // This is only used with the non-fragile ABI and non-legacy dispatch.
467
468     // Mixed dispatch is used everywhere except OS X before 10.6.
469     return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
470   }
471
472   unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
473     // Stack protectors default to on for user code on 10.5,
474     // and for everything in 10.6 and beyond
475     if (isTargetIOSBased() || isTargetWatchOSBased())
476       return 1;
477     else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
478       return 1;
479     else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
480       return 1;
481
482     return 0;
483   }
484
485   void CheckObjCARC() const override;
486
487   llvm::ExceptionHandling GetExceptionModel(
488       const llvm::opt::ArgList &Args) const override;
489
490   bool SupportsEmbeddedBitcode() const override;
491
492   SanitizerMask getSupportedSanitizers() const override;
493
494   void printVerboseInfo(raw_ostream &OS) const override;
495 };
496
497 /// DarwinClang - The Darwin toolchain used by Clang.
498 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
499 public:
500   DarwinClang(const Driver &D, const llvm::Triple &Triple,
501               const llvm::opt::ArgList &Args);
502
503   /// @name Apple ToolChain Implementation
504   /// {
505
506   RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
507
508   void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
509                              llvm::opt::ArgStringList &CmdArgs,
510                              bool ForceLinkBuiltinRT = false) const override;
511
512   void AddClangCXXStdlibIncludeArgs(
513       const llvm::opt::ArgList &DriverArgs,
514       llvm::opt::ArgStringList &CC1Args) const override;
515
516   void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
517                                  llvm::opt::ArgStringList &CC1Args) const override;
518
519   void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
520                            llvm::opt::ArgStringList &CmdArgs) const override;
521
522   void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
523                         llvm::opt::ArgStringList &CmdArgs) const override;
524
525   void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
526
527   void AddLinkARCArgs(const llvm::opt::ArgList &Args,
528                       llvm::opt::ArgStringList &CmdArgs) const override;
529
530   unsigned GetDefaultDwarfVersion() const override;
531   // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
532   // Darwin defaults to standalone/full debug info.
533   bool GetDefaultStandaloneDebug() const override { return true; }
534   llvm::DebuggerKind getDefaultDebuggerTuning() const override {
535     return llvm::DebuggerKind::LLDB;
536   }
537
538   /// }
539
540 private:
541   void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
542                                llvm::opt::ArgStringList &CmdArgs,
543                                StringRef Sanitizer,
544                                bool shared = true) const;
545
546   bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
547                                    llvm::opt::ArgStringList &CC1Args,
548                                    llvm::SmallString<128> Base,
549                                    llvm::StringRef Version,
550                                    llvm::StringRef ArchDir,
551                                    llvm::StringRef BitDir) const;
552
553   llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const;
554 };
555
556 } // end namespace toolchains
557 } // end namespace driver
558 } // end namespace clang
559
560 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H