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