Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h
Line
Count
Source (jump to first uncovered line)
1
//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- 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
/// \file
11
/// \brief Defines types useful for describing an Objective-C runtime.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H
16
#define LLVM_CLANG_BASIC_OBJCRUNTIME_H
17
18
#include "clang/Basic/VersionTuple.h"
19
#include "llvm/ADT/Triple.h"
20
#include "llvm/Support/ErrorHandling.h"
21
22
namespace clang {
23
24
/// \brief The basic abstraction for the target Objective-C runtime.
25
class ObjCRuntime {
26
public:
27
  /// \brief The basic Objective-C runtimes that we know about.
28
  enum Kind {
29
    /// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
30
    /// X platforms that use the non-fragile ABI; the version is a
31
    /// release of that OS.
32
    MacOSX,
33
34
    /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on
35
    /// Mac OS X platforms that use the fragile ABI; the version is a
36
    /// release of that OS.
37
    FragileMacOSX,
38
39
    /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS
40
    /// simulator;  it is always non-fragile.  The version is a release
41
    /// version of iOS.
42
    iOS,
43
44
    /// 'watchos' is a variant of iOS for Apple's watchOS. The version
45
    /// is a release version of watchOS.
46
    WatchOS,
47
48
    /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
49
    /// fragile Objective-C ABI
50
    GCC,
51
52
    /// 'gnustep' is the modern non-fragile GNUstep runtime.
53
    GNUstep,
54
55
    /// 'objfw' is the Objective-C runtime included in ObjFW
56
    ObjFW
57
  };
58
59
private:
60
  Kind TheKind;
61
  VersionTuple Version;
62
63
public:
64
  /// A bogus initialization of the runtime.
65
553k
  ObjCRuntime() : TheKind(MacOSX) {}
66
67
  ObjCRuntime(Kind kind, const VersionTuple &version)
68
30.6k
    : TheKind(kind), Version(version) {}
69
70
0
  void set(Kind kind, VersionTuple version) {
71
0
    TheKind = kind;
72
0
    Version = version;
73
0
  }
74
75
5.96M
  Kind getKind() const { return TheKind; }
76
69.5k
  const VersionTuple &getVersion() const { return Version; }
77
78
  /// \brief Does this runtime follow the set of implied behaviors for a
79
  /// "non-fragile" ABI?
80
3.96M
  bool isNonFragile() const {
81
3.96M
    switch (getKind()) {
82
2.23k
    case FragileMacOSX: return false;
83
5.92k
    case GCC: return false;
84
3.87M
    case MacOSX: return true;
85
1.49k
    case GNUstep: return true;
86
54
    case ObjFW: return true;
87
76.6k
    case iOS: return true;
88
39
    case WatchOS: return true;
89
3.96M
    }
90
0
    
llvm_unreachable0
("bad kind");
91
3.96M
  }
92
93
  /// The inverse of isNonFragile():  does this runtime follow the set of
94
  /// implied behaviors for a "fragile" ABI?
95
79.3k
  bool isFragile() const { return !isNonFragile(); }
96
97
  /// The default dispatch mechanism to use for the specified architecture
98
21.1k
  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
99
21.1k
    // The GNUstep runtime uses a newer dispatch method by default from
100
21.1k
    // version 1.6 onwards
101
21.1k
    if (
getKind() == GNUstep && 21.1k
getVersion() >= VersionTuple(1, 6)1.27k
) {
102
1
      if (Arch == llvm::Triple::arm ||
103
1
          Arch == llvm::Triple::x86 ||
104
1
          Arch == llvm::Triple::x86_64)
105
1
        return false;
106
1
    }
107
21.1k
    else 
if (21.1k
(getKind() == MacOSX) && 21.1k
isNonFragile()4.58k
&&
108
4.58k
             (getVersion() >= VersionTuple(10, 0)) &&
109
4.57k
             (getVersion() < VersionTuple(10, 6)))
110
697
        return Arch != llvm::Triple::x86_64;
111
21.1k
    // Except for deployment target of 10.5 or less,
112
21.1k
    // Mac runtimes use legacy dispatch everywhere now.
113
20.4k
    return true;
114
21.1k
  }
115
116
  /// \brief Is this runtime basically of the GNU family of runtimes?
117
6.14k
  bool isGNUFamily() const {
118
6.14k
    switch (getKind()) {
119
6.07k
    case FragileMacOSX:
120
6.07k
    case MacOSX:
121
6.07k
    case iOS:
122
6.07k
    case WatchOS:
123
6.07k
      return false;
124
63
    case GCC:
125
63
    case GNUstep:
126
63
    case ObjFW:
127
63
      return true;
128
6.14k
    }
129
0
    
llvm_unreachable0
("bad kind");
130
6.14k
  }
131
132
  /// \brief Is this runtime basically of the NeXT family of runtimes?
133
5.66k
  bool isNeXTFamily() const {
134
5.66k
    // For now, this is just the inverse of isGNUFamily(), but that's
135
5.66k
    // not inherently true.
136
5.66k
    return !isGNUFamily();
137
5.66k
  }
138
139
  /// \brief Does this runtime allow ARC at all?
140
324
  bool allowsARC() const {
141
324
    switch (getKind()) {
142
6
    case FragileMacOSX:
143
6
      // No stub library for the fragile runtime.
144
6
      return getVersion() >= VersionTuple(10, 7);
145
304
    case MacOSX: return true;
146
11
    case iOS: return true;
147
2
    case WatchOS: return true;
148
0
    case GCC: return false;
149
1
    case GNUstep: return true;
150
0
    case ObjFW: return true;
151
324
    }
152
0
    
llvm_unreachable0
("bad kind");
153
324
  }
154
155
  /// \brief Does this runtime natively provide the ARC entrypoints? 
156
  ///
157
  /// ARC cannot be directly supported on a platform that does not provide
158
  /// these entrypoints, although it may be supportable via a stub
159
  /// library.
160
3.50k
  bool hasNativeARC() const {
161
3.50k
    switch (getKind()) {
162
291
    case FragileMacOSX: return getVersion() >= VersionTuple(10, 7);
163
3.03k
    case MacOSX: return getVersion() >= VersionTuple(10, 7);
164
119
    case iOS: return getVersion() >= VersionTuple(5);
165
5
    case WatchOS: return true;
166
3.50k
167
15
    case GCC: return false;
168
28
    case GNUstep: return getVersion() >= VersionTuple(1, 6);
169
8
    case ObjFW: return true;
170
3.50k
    }
171
0
    
llvm_unreachable0
("bad kind");
172
3.50k
  }
173
174
  /// \brief Does this runtime supports optimized setter entrypoints?
175
86
  bool hasOptimizedSetter() const {
176
86
    switch (getKind()) {
177
66
      case MacOSX:
178
66
        return getVersion() >= VersionTuple(10, 8);
179
16
      case iOS:
180
16
        return (getVersion() >= VersionTuple(6));
181
0
      case WatchOS:
182
0
        return true;
183
4
      case GNUstep:
184
4
        return getVersion() >= VersionTuple(1, 7);
185
86
    
186
0
      default:
187
0
      return false;
188
86
    }
189
86
  }
190
191
  /// Does this runtime allow the use of __weak?
192
3.02k
  bool allowsWeak() const {
193
3.02k
    return hasNativeWeak();
194
3.02k
  }
195
196
  /// \brief Does this runtime natively provide ARC-compliant 'weak'
197
  /// entrypoints?
198
3.02k
  bool hasNativeWeak() const {
199
3.02k
    // Right now, this is always equivalent to whether the runtime
200
3.02k
    // natively supports ARC decision.
201
3.02k
    return hasNativeARC();
202
3.02k
  }
203
204
  /// \brief Does this runtime directly support the subscripting methods?
205
  ///
206
  /// This is really a property of the library, not the runtime.
207
3
  bool hasSubscripting() const {
208
3
    switch (getKind()) {
209
0
    case FragileMacOSX: return false;
210
3
    case MacOSX: return getVersion() >= VersionTuple(10, 8);
211
0
    case iOS: return getVersion() >= VersionTuple(6);
212
0
    case WatchOS: return true;
213
3
214
3
    // This is really a lie, because some implementations and versions
215
3
    // of the runtime do not support ARC.  Probably -fgnu-runtime
216
3
    // should imply a "maximal" runtime or something?
217
0
    case GCC: return true;
218
0
    case GNUstep: return true;
219
0
    case ObjFW: return true;
220
3
    }
221
0
    
llvm_unreachable0
("bad kind");
222
3
  }
223
224
  /// \brief Does this runtime allow sizeof or alignof on object types?
225
66.2k
  bool allowsSizeofAlignof() const {
226
66.2k
    return isFragile();
227
66.2k
  }
228
229
  /// \brief Does this runtime allow pointer arithmetic on objects?
230
  ///
231
  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
232
  /// yields true) [].
233
279
  bool allowsPointerArithmetic() const {
234
279
    switch (getKind()) {
235
22
    case FragileMacOSX:
236
22
    case GCC:
237
22
      return true;
238
257
    case MacOSX:
239
257
    case iOS:
240
257
    case WatchOS:
241
257
    case GNUstep:
242
257
    case ObjFW:
243
257
      return false;
244
279
    }
245
0
    
llvm_unreachable0
("bad kind");
246
279
  }
247
248
  /// \brief Is subscripting pointer arithmetic?
249
263
  bool isSubscriptPointerArithmetic() const {
250
263
    return allowsPointerArithmetic();
251
263
  }
252
253
  /// \brief Does this runtime provide an objc_terminate function?
254
  ///
255
  /// This is used in handlers for exceptions during the unwind process;
256
  /// without it, abort() must be used in pure ObjC files.
257
21
  bool hasTerminate() const {
258
21
    switch (getKind()) {
259
2
    case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
260
1
    case MacOSX: return getVersion() >= VersionTuple(10, 8);
261
18
    case iOS: return getVersion() >= VersionTuple(5);
262
0
    case WatchOS: return true;
263
0
    case GCC: return false;
264
0
    case GNUstep: return false;
265
0
    case ObjFW: return false;
266
21
    }
267
0
    
llvm_unreachable0
("bad kind");
268
21
  }
269
270
  /// \brief Does this runtime support weakly importing classes?
271
1.90M
  bool hasWeakClassImport() const {
272
1.90M
    switch (getKind()) {
273
1.88M
    case MacOSX: return true;
274
24.5k
    case iOS: return true;
275
6
    case WatchOS: return true;
276
135
    case FragileMacOSX: return false;
277
3
    case GCC: return true;
278
0
    case GNUstep: return true;
279
3
    case ObjFW: return true;
280
1.90M
    }
281
0
    
llvm_unreachable0
("bad kind");
282
1.90M
  }
283
284
  /// \brief Does this runtime use zero-cost exceptions?
285
475
  bool hasUnwindExceptions() const {
286
475
    switch (getKind()) {
287
83
    case MacOSX: return true;
288
380
    case iOS: return true;
289
0
    case WatchOS: return true;
290
4
    case FragileMacOSX: return false;
291
3
    case GCC: return true;
292
5
    case GNUstep: return true;
293
0
    case ObjFW: return true;
294
475
    }
295
0
    
llvm_unreachable0
("bad kind");
296
475
  }
297
298
61
  bool hasAtomicCopyHelper() const {
299
61
    switch (getKind()) {
300
57
    case FragileMacOSX:
301
57
    case MacOSX:
302
57
    case iOS:
303
57
    case WatchOS:
304
57
      return true;
305
4
    case GNUstep:
306
4
      return getVersion() >= VersionTuple(1, 7);
307
0
    default: return false;
308
61
    }
309
61
  }
310
311
  /// Is objc_unsafeClaimAutoreleasedReturnValue available?
312
53
  bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
313
53
    switch (getKind()) {
314
23
    case MacOSX:
315
23
    case FragileMacOSX:
316
23
      return getVersion() >= VersionTuple(10, 11);
317
30
    case iOS:
318
30
      return getVersion() >= VersionTuple(9);
319
0
    case WatchOS:
320
0
      return getVersion() >= VersionTuple(2);
321
0
    case GNUstep:
322
0
      return false;
323
23
324
0
    default:
325
0
      return false;
326
53
    }
327
53
  }
328
329
  /// Are the empty collection symbols available?
330
50
  bool hasEmptyCollections() const {
331
50
    switch (getKind()) {
332
0
    default:
333
0
      return false;
334
26
    case MacOSX:
335
26
      return getVersion() >= VersionTuple(10, 11);
336
16
    case iOS:
337
16
      return getVersion() >= VersionTuple(9);
338
8
    case WatchOS:
339
8
      return getVersion() >= VersionTuple(2);
340
50
    }
341
50
  }
342
343
  /// \brief Try to parse an Objective-C runtime specification from the given
344
  /// string.
345
  ///
346
  /// \return true on error.
347
  bool tryParse(StringRef input);
348
349
  std::string getAsString() const;
350
351
2.60k
  friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
352
2.60k
    return left.getKind() == right.getKind() &&
353
2.60k
           left.getVersion() == right.getVersion();
354
2.60k
  }
355
356
2.60k
  friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
357
2.60k
    return !(left == right);
358
2.60k
  }
359
};
360
361
raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
362
363
}  // end namespace clang
364
365
#endif