1260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- C++ -*-===//
2260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
3260611a32535c851237926bfcf78869b13c07d5bJohn McCall//                     The LLVM Compiler Infrastructure
4260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
5260611a32535c851237926bfcf78869b13c07d5bJohn McCall// This file is distributed under the University of Illinois Open Source
6260611a32535c851237926bfcf78869b13c07d5bJohn McCall// License. See LICENSE.TXT for details.
7260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
8260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===----------------------------------------------------------------------===//
92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file
112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines types useful for describing an Objective-C runtime.
122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
13260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===----------------------------------------------------------------------===//
14260611a32535c851237926bfcf78869b13c07d5bJohn McCall
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_BASIC_OBJCRUNTIME_H
17260611a32535c851237926bfcf78869b13c07d5bJohn McCall
18260611a32535c851237926bfcf78869b13c07d5bJohn McCall#include "clang/Basic/VersionTuple.h"
192c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall#include "llvm/ADT/Triple.h"
20260611a32535c851237926bfcf78869b13c07d5bJohn McCall#include "llvm/Support/ErrorHandling.h"
21260611a32535c851237926bfcf78869b13c07d5bJohn McCall
22260611a32535c851237926bfcf78869b13c07d5bJohn McCallnamespace clang {
23260611a32535c851237926bfcf78869b13c07d5bJohn McCall
24af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief The basic abstraction for the target Objective-C runtime.
25260611a32535c851237926bfcf78869b13c07d5bJohn McCallclass ObjCRuntime {
26260611a32535c851237926bfcf78869b13c07d5bJohn McCallpublic:
27af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief The basic Objective-C runtimes that we know about.
28260611a32535c851237926bfcf78869b13c07d5bJohn McCall  enum Kind {
29260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
30260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// X platforms that use the non-fragile ABI; the version is a
31260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// release of that OS.
32260611a32535c851237926bfcf78869b13c07d5bJohn McCall    MacOSX,
33260611a32535c851237926bfcf78869b13c07d5bJohn McCall
34260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on
35260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// Mac OS X platforms that use the fragile ABI; the version is a
36260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// release of that OS.
37260611a32535c851237926bfcf78869b13c07d5bJohn McCall    FragileMacOSX,
38260611a32535c851237926bfcf78869b13c07d5bJohn McCall
39260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS
40260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// simulator;  it is always non-fragile.  The version is a release
41260611a32535c851237926bfcf78869b13c07d5bJohn McCall    /// version of iOS.
42260611a32535c851237926bfcf78869b13c07d5bJohn McCall    iOS,
43260611a32535c851237926bfcf78869b13c07d5bJohn McCall
4487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// 'watchos' is a variant of iOS for Apple's watchOS. The version
4587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// is a release version of watchOS.
4687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    WatchOS,
4787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
4811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
4911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// fragile Objective-C ABI
5011d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    GCC,
51260611a32535c851237926bfcf78869b13c07d5bJohn McCall
5211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// 'gnustep' is the modern non-fragile GNUstep runtime.
53f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    GNUstep,
54f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall
55f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    /// 'objfw' is the Objective-C runtime included in ObjFW
56f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    ObjFW
57260611a32535c851237926bfcf78869b13c07d5bJohn McCall  };
58260611a32535c851237926bfcf78869b13c07d5bJohn McCall
59260611a32535c851237926bfcf78869b13c07d5bJohn McCallprivate:
60260611a32535c851237926bfcf78869b13c07d5bJohn McCall  Kind TheKind;
61260611a32535c851237926bfcf78869b13c07d5bJohn McCall  VersionTuple Version;
62260611a32535c851237926bfcf78869b13c07d5bJohn McCall
63260611a32535c851237926bfcf78869b13c07d5bJohn McCallpublic:
64260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// A bogus initialization of the runtime.
65260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ObjCRuntime() : TheKind(MacOSX) {}
66260611a32535c851237926bfcf78869b13c07d5bJohn McCall
67260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ObjCRuntime(Kind kind, const VersionTuple &version)
68260611a32535c851237926bfcf78869b13c07d5bJohn McCall    : TheKind(kind), Version(version) {}
69260611a32535c851237926bfcf78869b13c07d5bJohn McCall
70260611a32535c851237926bfcf78869b13c07d5bJohn McCall  void set(Kind kind, VersionTuple version) {
71260611a32535c851237926bfcf78869b13c07d5bJohn McCall    TheKind = kind;
72260611a32535c851237926bfcf78869b13c07d5bJohn McCall    Version = version;
73260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
74260611a32535c851237926bfcf78869b13c07d5bJohn McCall
75260611a32535c851237926bfcf78869b13c07d5bJohn McCall  Kind getKind() const { return TheKind; }
76260611a32535c851237926bfcf78869b13c07d5bJohn McCall  const VersionTuple &getVersion() const { return Version; }
77260611a32535c851237926bfcf78869b13c07d5bJohn McCall
78af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime follow the set of implied behaviors for a
79260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// "non-fragile" ABI?
80260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isNonFragile() const {
81260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
82260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return false;
8311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return false;
84260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return true;
8511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
869ee92a0d225be4b2170cde2b39ca88b11964b636Bill Wendling    case ObjFW: return true;
87260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return true;
8887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
89260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
90260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
91260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
92260611a32535c851237926bfcf78869b13c07d5bJohn McCall
93af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// The inverse of isNonFragile():  does this runtime follow the set of
94260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// implied behaviors for a "fragile" ABI?
95260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isFragile() const { return !isNonFragile(); }
96260611a32535c851237926bfcf78869b13c07d5bJohn McCall
972c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  /// The default dispatch mechanism to use for the specified architecture
982c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
992c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    // The GNUstep runtime uses a newer dispatch method by default from
1002c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    // version 1.6 onwards
1012c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
1022c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall      if (Arch == llvm::Triple::arm ||
1032c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall          Arch == llvm::Triple::x86 ||
1042c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall          Arch == llvm::Triple::x86_64)
1052c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall        return false;
106a6f5cc368bb6c996f771c37b0e95d81bf1ded76eFariborz Jahanian    }
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((getKind() ==  MacOSX) && isNonFragile() &&
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             (getVersion() >= VersionTuple(10, 0)) &&
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             (getVersion() < VersionTuple(10, 6)))
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return Arch != llvm::Triple::x86_64;
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Except for deployment target of 10.5 or less,
112a6f5cc368bb6c996f771c37b0e95d81bf1ded76eFariborz Jahanian    // Mac runtimes use legacy dispatch everywhere now.
1132c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    return true;
1142c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  }
1152c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall
116d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  /// \brief Is this runtime basically of the GNU family of runtimes?
117260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isGNUFamily() const {
118260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
119260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX:
120260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX:
121260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS:
12287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS:
123260611a32535c851237926bfcf78869b13c07d5bJohn McCall      return false;
12411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC:
12511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep:
126f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW:
127260611a32535c851237926bfcf78869b13c07d5bJohn McCall      return true;
128260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
129260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
130260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
131260611a32535c851237926bfcf78869b13c07d5bJohn McCall
132af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Is this runtime basically of the NeXT family of runtimes?
133260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isNeXTFamily() const {
134260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // For now, this is just the inverse of isGNUFamily(), but that's
135260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // not inherently true.
136260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return !isGNUFamily();
137260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
138260611a32535c851237926bfcf78869b13c07d5bJohn McCall
1390a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  /// \brief Does this runtime allow ARC at all?
1400a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool allowsARC() const {
1410a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    switch (getKind()) {
14287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case FragileMacOSX:
14387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // No stub library for the fragile runtime.
14487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      return getVersion() >= VersionTuple(10, 7);
1450a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case MacOSX: return true;
1460a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case iOS: return true;
14787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
1480a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case GCC: return false;
1490a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case GNUstep: return true;
1500a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case ObjFW: return true;
1510a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    }
1520a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    llvm_unreachable("bad kind");
1530a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  }
1540a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
155af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime natively provide the ARC entrypoints?
156af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
157af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// ARC cannot be directly supported on a platform that does not provide
158260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// these entrypoints, although it may be supportable via a stub
159260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// library.
1600a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool hasNativeARC() const {
161260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
16287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case FragileMacOSX: return getVersion() >= VersionTuple(10, 7);
163260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 7);
164260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return getVersion() >= VersionTuple(5);
16587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
166260611a32535c851237926bfcf78869b13c07d5bJohn McCall
167a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    case GCC: return false;
168a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    case GNUstep: return getVersion() >= VersionTuple(1, 6);
1690a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case ObjFW: return true;
170260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
171260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
172260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
173260611a32535c851237926bfcf78869b13c07d5bJohn McCall
1747a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  /// \brief Does this runtime supports optimized setter entrypoints?
1757a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  bool hasOptimizedSetter() const {
1767a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    switch (getKind()) {
1777a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      case MacOSX:
1787a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar        return getVersion() >= VersionTuple(10, 8);
1797a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      case iOS:
1807a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar        return (getVersion() >= VersionTuple(6));
18187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case WatchOS:
18287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        return true;
183d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      case GNUstep:
184d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall        return getVersion() >= VersionTuple(1, 7);
1857a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar
1867a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      default:
1877a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      return false;
1887a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    }
1897a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  }
1907a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar
1910a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  /// Does this runtime allow the use of __weak?
1920a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool allowsWeak() const {
1930a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    return hasNativeWeak();
1940a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  }
1950a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
196af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime natively provide ARC-compliant 'weak'
197260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// entrypoints?
1980a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool hasNativeWeak() const {
1990a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    // Right now, this is always equivalent to whether the runtime
2000a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    // natively supports ARC decision.
2010a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    return hasNativeARC();
202260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
203260611a32535c851237926bfcf78869b13c07d5bJohn McCall
204af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime directly support the subscripting methods?
205af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
206260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// This is really a property of the library, not the runtime.
207260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool hasSubscripting() const {
208260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
209260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return false;
210260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 8);
2117a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    case iOS: return getVersion() >= VersionTuple(6);
21287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
213260611a32535c851237926bfcf78869b13c07d5bJohn McCall
214260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // This is really a lie, because some implementations and versions
215260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // of the runtime do not support ARC.  Probably -fgnu-runtime
216260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // should imply a "maximal" runtime or something?
21711d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
21811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
219f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
220260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
221260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
222260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
223260611a32535c851237926bfcf78869b13c07d5bJohn McCall
2241503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Does this runtime allow sizeof or alignof on object types?
2251503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool allowsSizeofAlignof() const {
2261503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    return isFragile();
2271503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2281503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
2291503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Does this runtime allow pointer arithmetic on objects?
2301503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  ///
2311503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
2321503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// yields true) [].
2331503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool allowsPointerArithmetic() const {
2341503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    switch (getKind()) {
2351503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case FragileMacOSX:
2361503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case GCC:
2371503f0ddab0057e33efa21393fc0577580d6287aJohn McCall      return true;
2381503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case MacOSX:
2391503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case iOS:
24087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS:
2411503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case GNUstep:
2421503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case ObjFW:
2431503f0ddab0057e33efa21393fc0577580d6287aJohn McCall      return false;
2441503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    }
2451503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    llvm_unreachable("bad kind");
2461503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2471503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
2481503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Is subscripting pointer arithmetic?
2491503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool isSubscriptPointerArithmetic() const {
2501503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    return allowsPointerArithmetic();
2511503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2521503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
253af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime provide an objc_terminate function?
254af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
255af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// This is used in handlers for exceptions during the unwind process;
256260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// without it, abort() must be used in pure ObjC files.
257260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool hasTerminate() const {
258260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
259260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
260260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 8);
261260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return getVersion() >= VersionTuple(5);
26287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
26311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return false;
26411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return false;
265f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return false;
266260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
267260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
268260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
269260611a32535c851237926bfcf78869b13c07d5bJohn McCall
270af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime support weakly importing classes?
2710b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  bool hasWeakClassImport() const {
2720b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    switch (getKind()) {
2730b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case MacOSX: return true;
2740b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case iOS: return true;
27587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
2760b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case FragileMacOSX: return false;
27711d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
27811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
279f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
28011d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    }
28111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    llvm_unreachable("bad kind");
28211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  }
2830a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
28411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  /// \brief Does this runtime use zero-cost exceptions?
28511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  bool hasUnwindExceptions() const {
28611d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    switch (getKind()) {
28711d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case MacOSX: return true;
28811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case iOS: return true;
28987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS: return true;
29011d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case FragileMacOSX: return false;
29111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
29211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
293f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
2940b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    }
2950b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    llvm_unreachable("bad kind");
2960b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  }
2970b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall
298d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  bool hasAtomicCopyHelper() const {
299d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    switch (getKind()) {
300d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case FragileMacOSX:
301d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case MacOSX:
302d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case iOS:
30387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case WatchOS:
304d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      return true;
305d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case GNUstep:
306d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      return getVersion() >= VersionTuple(1, 7);
307d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    default: return false;
308d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    }
309d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  }
310d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall
3114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Is objc_unsafeClaimAutoreleasedReturnValue available?
3124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
3134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    switch (getKind()) {
3144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case MacOSX:
3154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return getVersion() >= VersionTuple(10, 11);
3164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case iOS:
3174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return getVersion() >= VersionTuple(9);
3184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case WatchOS:
3194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return getVersion() >= VersionTuple(2);
3204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case GNUstep:
3214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return false;
3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    default:
3244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return false;
3254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
3264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
328af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Try to parse an Objective-C runtime specification from the given
329af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// string.
330260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ///
331af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \return true on error.
332260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool tryParse(StringRef input);
333260611a32535c851237926bfcf78869b13c07d5bJohn McCall
334260611a32535c851237926bfcf78869b13c07d5bJohn McCall  std::string getAsString() const;
335260611a32535c851237926bfcf78869b13c07d5bJohn McCall
336260611a32535c851237926bfcf78869b13c07d5bJohn McCall  friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
337260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return left.getKind() == right.getKind() &&
338260611a32535c851237926bfcf78869b13c07d5bJohn McCall           left.getVersion() == right.getVersion();
339260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
340260611a32535c851237926bfcf78869b13c07d5bJohn McCall
341260611a32535c851237926bfcf78869b13c07d5bJohn McCall  friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
342260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return !(left == right);
343260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
344260611a32535c851237926bfcf78869b13c07d5bJohn McCall};
345260611a32535c851237926bfcf78869b13c07d5bJohn McCall
346260611a32535c851237926bfcf78869b13c07d5bJohn McCallraw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
347260611a32535c851237926bfcf78869b13c07d5bJohn McCall
348260611a32535c851237926bfcf78869b13c07d5bJohn McCall}  // end namespace clang
349260611a32535c851237926bfcf78869b13c07d5bJohn McCall
350260611a32535c851237926bfcf78869b13c07d5bJohn McCall#endif
351