Coverage Report

Created: 2023-09-30 09:22

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