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
15260611a32535c851237926bfcf78869b13c07d5bJohn McCall#ifndef LLVM_CLANG_OBJCRUNTIME_H
16260611a32535c851237926bfcf78869b13c07d5bJohn McCall#define LLVM_CLANG_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
4411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
4511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// fragile Objective-C ABI
4611d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    GCC,
47260611a32535c851237926bfcf78869b13c07d5bJohn McCall
4811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    /// 'gnustep' is the modern non-fragile GNUstep runtime.
49f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    GNUstep,
50f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall
51f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    /// 'objfw' is the Objective-C runtime included in ObjFW
52f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    ObjFW
53260611a32535c851237926bfcf78869b13c07d5bJohn McCall  };
54260611a32535c851237926bfcf78869b13c07d5bJohn McCall
55260611a32535c851237926bfcf78869b13c07d5bJohn McCallprivate:
56260611a32535c851237926bfcf78869b13c07d5bJohn McCall  Kind TheKind;
57260611a32535c851237926bfcf78869b13c07d5bJohn McCall  VersionTuple Version;
58260611a32535c851237926bfcf78869b13c07d5bJohn McCall
59260611a32535c851237926bfcf78869b13c07d5bJohn McCallpublic:
60260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// A bogus initialization of the runtime.
61260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ObjCRuntime() : TheKind(MacOSX) {}
62260611a32535c851237926bfcf78869b13c07d5bJohn McCall
63260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ObjCRuntime(Kind kind, const VersionTuple &version)
64260611a32535c851237926bfcf78869b13c07d5bJohn McCall    : TheKind(kind), Version(version) {}
65260611a32535c851237926bfcf78869b13c07d5bJohn McCall
66260611a32535c851237926bfcf78869b13c07d5bJohn McCall  void set(Kind kind, VersionTuple version) {
67260611a32535c851237926bfcf78869b13c07d5bJohn McCall    TheKind = kind;
68260611a32535c851237926bfcf78869b13c07d5bJohn McCall    Version = version;
69260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
70260611a32535c851237926bfcf78869b13c07d5bJohn McCall
71260611a32535c851237926bfcf78869b13c07d5bJohn McCall  Kind getKind() const { return TheKind; }
72260611a32535c851237926bfcf78869b13c07d5bJohn McCall  const VersionTuple &getVersion() const { return Version; }
73260611a32535c851237926bfcf78869b13c07d5bJohn McCall
74af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime follow the set of implied behaviors for a
75260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// "non-fragile" ABI?
76260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isNonFragile() const {
77260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
78260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return false;
7911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return false;
80260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return true;
8111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
829ee92a0d225be4b2170cde2b39ca88b11964b636Bill Wendling    case ObjFW: return true;
83260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return true;
84260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
85260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
86260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
87260611a32535c851237926bfcf78869b13c07d5bJohn McCall
88af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// The inverse of isNonFragile():  does this runtime follow the set of
89260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// implied behaviors for a "fragile" ABI?
90260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isFragile() const { return !isNonFragile(); }
91260611a32535c851237926bfcf78869b13c07d5bJohn McCall
922c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  /// The default dispatch mechanism to use for the specified architecture
932c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
942c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    // The GNUstep runtime uses a newer dispatch method by default from
952c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    // version 1.6 onwards
962c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
972c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall      if (Arch == llvm::Triple::arm ||
982c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall          Arch == llvm::Triple::x86 ||
992c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall          Arch == llvm::Triple::x86_64)
1002c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall        return false;
101a6f5cc368bb6c996f771c37b0e95d81bf1ded76eFariborz Jahanian    }
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((getKind() ==  MacOSX) && isNonFragile() &&
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             (getVersion() >= VersionTuple(10, 0)) &&
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             (getVersion() < VersionTuple(10, 6)))
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return Arch != llvm::Triple::x86_64;
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Except for deployment target of 10.5 or less,
107a6f5cc368bb6c996f771c37b0e95d81bf1ded76eFariborz Jahanian    // Mac runtimes use legacy dispatch everywhere now.
1082c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall    return true;
1092c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall  }
1102c7886ddec1e2cee68daee9866637d2e02f434efDavid Chisnall
111d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  /// \brief Is this runtime basically of the GNU family of runtimes?
112260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isGNUFamily() const {
113260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
114260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX:
115260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX:
116260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS:
117260611a32535c851237926bfcf78869b13c07d5bJohn McCall      return false;
11811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC:
11911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep:
120f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW:
121260611a32535c851237926bfcf78869b13c07d5bJohn McCall      return true;
122260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
123260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
124260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
125260611a32535c851237926bfcf78869b13c07d5bJohn McCall
126af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Is this runtime basically of the NeXT family of runtimes?
127260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool isNeXTFamily() const {
128260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // For now, this is just the inverse of isGNUFamily(), but that's
129260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // not inherently true.
130260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return !isGNUFamily();
131260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
132260611a32535c851237926bfcf78869b13c07d5bJohn McCall
1330a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  /// \brief Does this runtime allow ARC at all?
1340a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool allowsARC() const {
1350a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    switch (getKind()) {
1360a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case FragileMacOSX: return false;
1370a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case MacOSX: return true;
1380a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case iOS: return true;
1390a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case GCC: return false;
1400a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case GNUstep: return true;
1410a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case ObjFW: return true;
1420a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    }
1430a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    llvm_unreachable("bad kind");
1440a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  }
1450a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
146af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime natively provide the ARC entrypoints?
147af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
148af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// ARC cannot be directly supported on a platform that does not provide
149260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// these entrypoints, although it may be supportable via a stub
150260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// library.
1510a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool hasNativeARC() const {
152260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
153260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return false;
154260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 7);
155260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return getVersion() >= VersionTuple(5);
156260611a32535c851237926bfcf78869b13c07d5bJohn McCall
157a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    case GCC: return false;
158a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    case GNUstep: return getVersion() >= VersionTuple(1, 6);
1590a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    case ObjFW: return true;
160260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
161260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
162260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
163260611a32535c851237926bfcf78869b13c07d5bJohn McCall
1647a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  /// \brief Does this runtime supports optimized setter entrypoints?
1657a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  bool hasOptimizedSetter() const {
1667a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    switch (getKind()) {
1677a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      case MacOSX:
1687a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar        return getVersion() >= VersionTuple(10, 8);
1697a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      case iOS:
1707a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar        return (getVersion() >= VersionTuple(6));
171d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      case GNUstep:
172d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall        return getVersion() >= VersionTuple(1, 7);
1737a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar
1747a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      default:
1757a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar      return false;
1767a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    }
1777a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar  }
1787a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar
1790a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  /// Does this runtime allow the use of __weak?
1800a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool allowsWeak() const {
1810a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    return hasNativeWeak();
1820a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  }
1830a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
184af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime natively provide ARC-compliant 'weak'
185260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// entrypoints?
1860a7dd788dbef975f35f273c7ab913f480f7edd60John McCall  bool hasNativeWeak() const {
1870a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    // Right now, this is always equivalent to whether the runtime
1880a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    // natively supports ARC decision.
1890a7dd788dbef975f35f273c7ab913f480f7edd60John McCall    return hasNativeARC();
190260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
191260611a32535c851237926bfcf78869b13c07d5bJohn McCall
192af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime directly support the subscripting methods?
193af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
194260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// This is really a property of the library, not the runtime.
195260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool hasSubscripting() const {
196260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
197260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return false;
198260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 8);
1997a0c064770355a4918df69f95de8dea6338a59a2Daniel Dunbar    case iOS: return getVersion() >= VersionTuple(6);
200260611a32535c851237926bfcf78869b13c07d5bJohn McCall
201260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // This is really a lie, because some implementations and versions
202260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // of the runtime do not support ARC.  Probably -fgnu-runtime
203260611a32535c851237926bfcf78869b13c07d5bJohn McCall    // should imply a "maximal" runtime or something?
20411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
20511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
206f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
207260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
208260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
209260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
210260611a32535c851237926bfcf78869b13c07d5bJohn McCall
2111503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Does this runtime allow sizeof or alignof on object types?
2121503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool allowsSizeofAlignof() const {
2131503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    return isFragile();
2141503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2151503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
2161503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Does this runtime allow pointer arithmetic on objects?
2171503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  ///
2181503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
2191503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// yields true) [].
2201503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool allowsPointerArithmetic() const {
2211503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    switch (getKind()) {
2221503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case FragileMacOSX:
2231503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case GCC:
2241503f0ddab0057e33efa21393fc0577580d6287aJohn McCall      return true;
2251503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case MacOSX:
2261503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case iOS:
2271503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case GNUstep:
2281503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    case ObjFW:
2291503f0ddab0057e33efa21393fc0577580d6287aJohn McCall      return false;
2301503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    }
2311503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    llvm_unreachable("bad kind");
2321503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2331503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
2341503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  /// \brief Is subscripting pointer arithmetic?
2351503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  bool isSubscriptPointerArithmetic() const {
2361503f0ddab0057e33efa21393fc0577580d6287aJohn McCall    return allowsPointerArithmetic();
2371503f0ddab0057e33efa21393fc0577580d6287aJohn McCall  }
2381503f0ddab0057e33efa21393fc0577580d6287aJohn McCall
239af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime provide an objc_terminate function?
240af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
241af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// This is used in handlers for exceptions during the unwind process;
242260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// without it, abort() must be used in pure ObjC files.
243260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool hasTerminate() const {
244260611a32535c851237926bfcf78869b13c07d5bJohn McCall    switch (getKind()) {
245260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
246260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case MacOSX: return getVersion() >= VersionTuple(10, 8);
247260611a32535c851237926bfcf78869b13c07d5bJohn McCall    case iOS: return getVersion() >= VersionTuple(5);
24811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return false;
24911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return false;
250f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return false;
251260611a32535c851237926bfcf78869b13c07d5bJohn McCall    }
252260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("bad kind");
253260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
254260611a32535c851237926bfcf78869b13c07d5bJohn McCall
255af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Does this runtime support weakly importing classes?
2560b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  bool hasWeakClassImport() const {
2570b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    switch (getKind()) {
2580b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case MacOSX: return true;
2590b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case iOS: return true;
2600b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    case FragileMacOSX: return false;
26111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
26211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
263f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
26411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    }
26511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    llvm_unreachable("bad kind");
26611d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  }
2670a7dd788dbef975f35f273c7ab913f480f7edd60John McCall
26811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  /// \brief Does this runtime use zero-cost exceptions?
26911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  bool hasUnwindExceptions() const {
27011d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    switch (getKind()) {
27111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case MacOSX: return true;
27211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case iOS: return true;
27311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case FragileMacOSX: return false;
27411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GCC: return true;
27511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    case GNUstep: return true;
276f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    case ObjFW: return true;
2770b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    }
2780b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall    llvm_unreachable("bad kind");
2790b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  }
2800b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall
281d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  bool hasAtomicCopyHelper() const {
282d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    switch (getKind()) {
283d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case FragileMacOSX:
284d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case MacOSX:
285d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case iOS:
286d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      return true;
287d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    case GNUstep:
288d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall      return getVersion() >= VersionTuple(1, 7);
289d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    default: return false;
290d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall    }
291d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall  }
292d397cfef01d49a41554309d67ea26340c39e1e94David Chisnall
293af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Try to parse an Objective-C runtime specification from the given
294af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// string.
295260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ///
296af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \return true on error.
297260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool tryParse(StringRef input);
298260611a32535c851237926bfcf78869b13c07d5bJohn McCall
299260611a32535c851237926bfcf78869b13c07d5bJohn McCall  std::string getAsString() const;
300260611a32535c851237926bfcf78869b13c07d5bJohn McCall
301260611a32535c851237926bfcf78869b13c07d5bJohn McCall  friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
302260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return left.getKind() == right.getKind() &&
303260611a32535c851237926bfcf78869b13c07d5bJohn McCall           left.getVersion() == right.getVersion();
304260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
305260611a32535c851237926bfcf78869b13c07d5bJohn McCall
306260611a32535c851237926bfcf78869b13c07d5bJohn McCall  friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
307260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return !(left == right);
308260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
309260611a32535c851237926bfcf78869b13c07d5bJohn McCall};
310260611a32535c851237926bfcf78869b13c07d5bJohn McCall
311260611a32535c851237926bfcf78869b13c07d5bJohn McCallraw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
312260611a32535c851237926bfcf78869b13c07d5bJohn McCall
313260611a32535c851237926bfcf78869b13c07d5bJohn McCall}  // end namespace clang
314260611a32535c851237926bfcf78869b13c07d5bJohn McCall
315260611a32535c851237926bfcf78869b13c07d5bJohn McCall#endif
316