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