Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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 "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
13.0k
  const toolchains::MachO &getMachOToolChain() const {
39
13.0k
    return reinterpret_cast<const toolchains::MachO &>(getToolChain());
40
13.0k
  }
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
3.54k
             ResponseFlag) {}
50
};
51
52
class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
53
public:
54
  Assembler(const ToolChain &TC)
55
16
      : MachOTool("darwin::Assembler", "assembler", TC) {}
56
57
16
  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
2.63k
                  llvm::sys::WEM_UTF8, "-filelist") {}
75
76
2.62k
  bool hasIntegratedCPP() const override { return false; }
77
0
  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
858
  Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
88
89
856
  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
35
      : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
101
102
35
  bool hasIntegratedCPP() const override { return false; }
103
0
  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
2
      : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
115
116
2
  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
0
                              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
13
                                      llvm::opt::ArgStringList &CmdArgs) const {
165
13
  }
166
167
  virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
168
13
                                 llvm::opt::ArgStringList &CmdArgs) const {}
169
170
  /// On some iOS platforms, kernel and kernel modules were built statically. Is
171
  /// this such a target?
172
0
  virtual bool isKernelStatic() const { return false; }
173
174
  /// Is the target either iOS or an iOS simulator?
175
2.63k
  bool isTargetIOSBased() const { return false; }
176
177
  /// Options to control how a runtime library is linked.
178
  enum RuntimeLinkOptions : unsigned {
179
    /// Link the library in even if it can't be found in the VFS.
180
    RLO_AlwaysLink = 1 << 0,
181
182
    /// Use the embedded runtime from the macho_embedded directory.
183
    RLO_IsEmbedded = 1 << 1,
184
185
    /// Emit rpaths for @executable_path as well as the resource directory.
186
    RLO_AddRPath = 1 << 2,
187
188
    /// Link the library in before any others.
189
    RLO_FirstLink = 1 << 3,
190
  };
191
192
  /// Add a runtime library to the list of items to link.
193
  void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
194
                         llvm::opt::ArgStringList &CmdArgs, StringRef Component,
195
                         RuntimeLinkOptions Opts = RuntimeLinkOptions(),
196
                         bool IsShared = false) const;
197
198
  /// Add any profiling runtime libraries that are needed. This is essentially a
199
  /// MachO specific version of addProfileRT in Tools.cpp.
200
  void addProfileRTLibs(const llvm::opt::ArgList &Args,
201
13
                        llvm::opt::ArgStringList &CmdArgs) const override {
202
13
    // There aren't any profiling libs for embedded targets currently.
203
13
  }
204
205
  /// }
206
  /// @name ToolChain Implementation
207
  /// {
208
209
  types::ID LookupTypeForExtension(StringRef Ext) const override;
210
211
  bool HasNativeLLVMSupport() const override;
212
213
  llvm::opt::DerivedArgList *
214
  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
215
                Action::OffloadKind DeviceOffloadKind) const override;
216
217
20.8k
  bool IsBlocksDefault() const override {
218
20.8k
    // Always allow blocks on Apple; users interested in versioning are
219
20.8k
    // expected to use /usr/include/Block.h.
220
20.8k
    return true;
221
20.8k
  }
222
105k
  bool IsIntegratedAssemblerDefault() const override {
223
105k
    // Default integrated assembler to on for Apple's MachO targets.
224
105k
    return true;
225
105k
  }
226
227
20.8k
  bool IsMathErrnoDefault() const override { return false; }
228
229
20.8k
  bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
230
231
20.8k
  bool IsObjCNonFragileABIDefault() const override {
232
20.8k
    // Non-fragile ABI is default for everything but i386.
233
20.8k
    return getTriple().getArch() != llvm::Triple::x86;
234
20.8k
  }
235
236
0
  bool UseObjCMixedDispatch() const override { return true; }
237
238
  bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
239
240
0
  RuntimeLibType GetDefaultRuntimeLibType() const override {
241
0
    return ToolChain::RLT_CompilerRT;
242
0
  }
243
244
  bool isPICDefault() const override;
245
  bool isPIEDefault() const override;
246
  bool isPICDefaultForced() const override;
247
248
  bool SupportsProfiling() const override;
249
250
  bool UseDwarfDebugFlags() const override;
251
252
  llvm::ExceptionHandling
253
1.61k
  GetExceptionModel(const llvm::opt::ArgList &Args) const override {
254
1.61k
    return llvm::ExceptionHandling::None;
255
1.61k
  }
256
257
13
  virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
258
13
    return "";
259
13
  }
260
261
  /// }
262
};
263
264
/// Darwin - The base Darwin tool chain.
265
class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
266
public:
267
  /// Whether the information on the target has been initialized.
268
  //
269
  // FIXME: This should be eliminated. What we want to do is make this part of
270
  // the "default target for arguments" selection process, once we get out of
271
  // the argument translation business.
272
  mutable bool TargetInitialized;
273
274
  enum DarwinPlatformKind {
275
    MacOS,
276
    IPhoneOS,
277
    TvOS,
278
    WatchOS,
279
    LastDarwinPlatform = WatchOS
280
  };
281
  enum DarwinEnvironmentKind {
282
    NativeEnvironment,
283
    Simulator,
284
  };
285
286
  mutable DarwinPlatformKind TargetPlatform;
287
  mutable DarwinEnvironmentKind TargetEnvironment;
288
289
  /// The OS version we are targeting.
290
  mutable VersionTuple TargetVersion;
291
292
  /// The information about the darwin SDK that was used.
293
  mutable Optional<DarwinSDKInfo> SDKInfo;
294
295
  CudaInstallationDetector CudaInstallation;
296
297
private:
298
  void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
299
300
public:
301
  Darwin(const Driver &D, const llvm::Triple &Triple,
302
         const llvm::opt::ArgList &Args);
303
  ~Darwin() override;
304
305
  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
306
                                          types::ID InputType) const override;
307
308
  /// @name Apple Specific Toolchain Implementation
309
  /// {
310
311
  void addMinVersionArgs(const llvm::opt::ArgList &Args,
312
                         llvm::opt::ArgStringList &CmdArgs) const override;
313
314
  void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
315
                              llvm::opt::ArgStringList &CmdArgs) const override;
316
317
1
  bool isKernelStatic() const override {
318
1
    return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
319
1
            
!isTargetWatchOS()0
);
320
1
  }
321
322
  void addProfileRTLibs(const llvm::opt::ArgList &Args,
323
                        llvm::opt::ArgStringList &CmdArgs) const override;
324
325
protected:
326
  /// }
327
  /// @name Darwin specific Toolchain functions
328
  /// {
329
330
  // FIXME: Eliminate these ...Target functions and derive separate tool chains
331
  // for these targets and put version in constructor.
332
  void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
333
22.0k
                 unsigned Major, unsigned Minor, unsigned Micro) const {
334
22.0k
    // FIXME: For now, allow reinitialization as long as values don't
335
22.0k
    // change. This will go away when we move away from argument translation.
336
22.0k
    if (TargetInitialized && 
TargetPlatform == Platform511
&&
337
22.0k
        
TargetEnvironment == Environment511
&&
338
22.0k
        
TargetVersion == VersionTuple(Major, Minor, Micro)511
)
339
511
      return;
340
21.5k
341
21.5k
    assert(!TargetInitialized && "Target already initialized!");
342
21.5k
    TargetInitialized = true;
343
21.5k
    TargetPlatform = Platform;
344
21.5k
    TargetEnvironment = Environment;
345
21.5k
    TargetVersion = VersionTuple(Major, Minor, Micro);
346
21.5k
    if (Environment == Simulator)
347
933
      const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
348
21.5k
  }
349
350
172k
  bool isTargetIPhoneOS() const {
351
172k
    assert(TargetInitialized && "Target not initialized!");
352
172k
    return (TargetPlatform == IPhoneOS || 
TargetPlatform == TvOS74.8k
) &&
353
172k
           
TargetEnvironment == NativeEnvironment98.2k
;
354
172k
  }
355
356
87.5k
  bool isTargetIOSSimulator() const {
357
87.5k
    assert(TargetInitialized && "Target not initialized!");
358
87.5k
    return (TargetPlatform == IPhoneOS || 
TargetPlatform == TvOS65.4k
) &&
359
87.5k
           
TargetEnvironment == Simulator22.2k
;
360
87.5k
  }
361
362
146k
  bool isTargetIOSBased() const {
363
146k
    assert(TargetInitialized && "Target not initialized!");
364
146k
    return isTargetIPhoneOS() || 
isTargetIOSSimulator()70.8k
;
365
146k
  }
366
367
2.60k
  bool isTargetTvOS() const {
368
2.60k
    assert(TargetInitialized && "Target not initialized!");
369
2.60k
    return TargetPlatform == TvOS && 
TargetEnvironment == NativeEnvironment15
;
370
2.60k
  }
371
372
13.1k
  bool isTargetTvOSSimulator() const {
373
13.1k
    assert(TargetInitialized && "Target not initialized!");
374
13.1k
    return TargetPlatform == TvOS && 
TargetEnvironment == Simulator27
;
375
13.1k
  }
376
377
24.1k
  bool isTargetTvOSBased() const {
378
24.1k
    assert(TargetInitialized && "Target not initialized!");
379
24.1k
    return TargetPlatform == TvOS;
380
24.1k
  }
381
382
2.62k
  bool isTargetWatchOS() const {
383
2.62k
    assert(TargetInitialized && "Target not initialized!");
384
2.62k
    return TargetPlatform == WatchOS && 
TargetEnvironment == NativeEnvironment16
;
385
2.62k
  }
386
387
2.60k
  bool isTargetWatchOSSimulator() const {
388
2.60k
    assert(TargetInitialized && "Target not initialized!");
389
2.60k
    return TargetPlatform == WatchOS && 
TargetEnvironment == Simulator3
;
390
2.60k
  }
391
392
124k
  bool isTargetWatchOSBased() const {
393
124k
    assert(TargetInitialized && "Target not initialized!");
394
124k
    return TargetPlatform == WatchOS;
395
124k
  }
396
397
97.0k
  bool isTargetMacOS() const {
398
97.0k
    assert(TargetInitialized && "Target not initialized!");
399
97.0k
    return TargetPlatform == MacOS;
400
97.0k
  }
401
402
24.2k
  bool isTargetInitialized() const { return TargetInitialized; }
403
404
26.8k
  VersionTuple getTargetVersion() const {
405
26.8k
    assert(TargetInitialized && "Target not initialized!");
406
26.8k
    return TargetVersion;
407
26.8k
  }
408
409
  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
410
58.6k
                           unsigned V2 = 0) const {
411
58.6k
    assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
412
58.6k
    return TargetVersion < VersionTuple(V0, V1, V2);
413
58.6k
  }
414
415
44.5k
  bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
416
44.5k
    assert(isTargetMacOS() && "Unexpected call for non OS X target!");
417
44.5k
    return TargetVersion < VersionTuple(V0, V1, V2);
418
44.5k
  }
419
420
  /// Return true if c++17 aligned allocation/deallocation functions are not
421
  /// implemented in the c++ standard library of the deployment target we are
422
  /// targeting.
423
  bool isAlignedAllocationUnavailable() const;
424
425
  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
426
                             llvm::opt::ArgStringList &CC1Args,
427
                             Action::OffloadKind DeviceOffloadKind) const override;
428
429
  StringRef getPlatformFamily() const;
430
  StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
431
432
public:
433
  static StringRef getSDKName(StringRef isysroot);
434
435
  /// }
436
  /// @name ToolChain Implementation
437
  /// {
438
439
  // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
440
  // most development is done against SDKs, so compiling for a different
441
  // architecture should not get any special treatment.
442
2.61k
  bool isCrossCompiling() const override { return false; }
443
444
  llvm::opt::DerivedArgList *
445
  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
446
                Action::OffloadKind DeviceOffloadKind) const override;
447
448
  CXXStdlibType GetDefaultCXXStdlibType() const override;
449
  ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
450
  bool hasBlocksRuntime() const override;
451
452
  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
453
                          llvm::opt::ArgStringList &CC1Args) const override;
454
455
660
  bool UseObjCMixedDispatch() const override {
456
660
    // This is only used with the non-fragile ABI and non-legacy dispatch.
457
660
458
660
    // Mixed dispatch is used everywhere except OS X before 10.6.
459
660
    return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
460
660
  }
461
462
20.0k
  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
463
20.0k
    // Stack protectors default to on for user code on 10.5,
464
20.0k
    // and for everything in 10.6 and beyond
465
20.0k
    if (isTargetIOSBased() || 
isTargetWatchOSBased()10.1k
)
466
9.93k
      return 1;
467
10.1k
    else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
468
9.42k
      return 1;
469
694
    else if (isTargetMacOS() && 
!isMacosxVersionLT(10, 5)693
&&
!KernelOrKext679
)
470
352
      return 1;
471
342
472
342
    return 0;
473
342
  }
474
475
  void CheckObjCARC() const override;
476
477
  llvm::ExceptionHandling GetExceptionModel(
478
      const llvm::opt::ArgList &Args) const override;
479
480
  bool SupportsEmbeddedBitcode() const override;
481
482
  SanitizerMask getSupportedSanitizers() const override;
483
484
  void printVerboseInfo(raw_ostream &OS) const override;
485
};
486
487
/// DarwinClang - The Darwin toolchain used by Clang.
488
class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
489
public:
490
  DarwinClang(const Driver &D, const llvm::Triple &Triple,
491
              const llvm::opt::ArgList &Args);
492
493
  /// @name Apple ToolChain Implementation
494
  /// {
495
496
  RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
497
498
  void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
499
                             llvm::opt::ArgStringList &CmdArgs,
500
                             bool ForceLinkBuiltinRT = false) const override;
501
502
  void AddClangCXXStdlibIncludeArgs(
503
      const llvm::opt::ArgList &DriverArgs,
504
      llvm::opt::ArgStringList &CC1Args) const override;
505
506
  void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
507
                                 llvm::opt::ArgStringList &CC1Args) const override;
508
509
  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
510
                           llvm::opt::ArgStringList &CmdArgs) const override;
511
512
  void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
513
                        llvm::opt::ArgStringList &CmdArgs) const override;
514
515
  void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
516
517
  void AddLinkARCArgs(const llvm::opt::ArgList &Args,
518
                      llvm::opt::ArgStringList &CmdArgs) const override;
519
520
  unsigned GetDefaultDwarfVersion() const override;
521
  // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
522
  // Darwin defaults to standalone/full debug info.
523
18
  bool GetDefaultStandaloneDebug() const override { return true; }
524
20.0k
  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
525
20.0k
    return llvm::DebuggerKind::LLDB;
526
20.0k
  }
527
528
  /// }
529
530
private:
531
  void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
532
                               llvm::opt::ArgStringList &CmdArgs,
533
                               StringRef Sanitizer,
534
                               bool shared = true) const;
535
536
  bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
537
                                   llvm::opt::ArgStringList &CC1Args,
538
                                   llvm::SmallString<128> Base,
539
                                   llvm::StringRef Version,
540
                                   llvm::StringRef ArchDir,
541
                                   llvm::StringRef BitDir) const;
542
543
  llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const;
544
};
545
546
} // end namespace toolchains
547
} // end namespace driver
548
} // end namespace clang
549
550
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H