//===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines types useful for describing an Objective-C runtime.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H
#define LLVM_CLANG_BASIC_OBJCRUNTIME_H

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
#include <string>

namespace clang {

/// The basic abstraction for the target Objective-C runtime.
class ObjCRuntime {
public:
  /// The basic Objective-C runtimes that we know about.
  enum Kind {
    /// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
    /// X platforms that use the non-fragile ABI; the version is a
    /// release of that OS.
    MacOSX,

    /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on
    /// Mac OS X platforms that use the fragile ABI; the version is a
    /// release of that OS.
    FragileMacOSX,

    /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS
    /// simulator;  it is always non-fragile.  The version is a release
    /// version of iOS.
    iOS,

    /// 'watchos' is a variant of iOS for Apple's watchOS. The version
    /// is a release version of watchOS.
    WatchOS,

    /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
    /// fragile Objective-C ABI
    GCC,

    /// 'gnustep' is the modern non-fragile GNUstep runtime.
    GNUstep,

    /// 'objfw' is the Objective-C runtime included in ObjFW
    ObjFW
  };

private:
  Kind TheKind = MacOSX;
  VersionTuple Version;

public:
  /// A bogus initialization of the runtime.
  ObjCRuntime() = default;
  ObjCRuntime(Kind kind, const VersionTuple &version)
      : TheKind(kind), Version(version) {}

  void set(Kind kind, VersionTuple version) {
    TheKind = kind;
    Version = version;
  }

  Kind getKind() const { return TheKind; }
  const VersionTuple &getVersion() const { return Version; }

  /// Does this runtime follow the set of implied behaviors for a
  /// "non-fragile" ABI?
  bool isNonFragile() const {
    switch (getKind()) {
    case FragileMacOSX: return false;
    case GCC: return false;
    case MacOSX: return true;
    case GNUstep: return true;
    case ObjFW: return true;
    case iOS: return true;
    case WatchOS: return true;
    }
    llvm_unreachable("bad kind");
  }

  /// The inverse of isNonFragile():  does this runtime follow the set of
  /// implied behaviors for a "fragile" ABI?
  bool isFragile() const { return !isNonFragile(); }

  /// The default dispatch mechanism to use for the specified architecture
  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
    // The GNUstep runtime uses a newer dispatch method by default from
    // version 1.6 onwards
    if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
      if (Arch == llvm::Triple::arm ||
          Arch == llvm::Triple::x86 ||
          Arch == llvm::Triple::x86_64)
        return false;
    }
    else if ((getKind() ==  MacOSX) && isNonFragile() &&
             (getVersion() >= VersionTuple(10, 0)) &&
             (getVersion() < VersionTuple(10, 6)))
        return Arch != llvm::Triple::x86_64;
    // Except for deployment target of 10.5 or less,
    // Mac runtimes use legacy dispatch everywhere now.
    return true;
  }

  /// Is this runtime basically of the GNU family of runtimes?
  bool isGNUFamily() const {
    switch (getKind()) {
    case FragileMacOSX:
    case MacOSX:
    case iOS:
    case WatchOS:
      return false;
    case GCC:
    case GNUstep:
    case ObjFW:
      return true;
    }
    llvm_unreachable("bad kind");
  }

  /// Is this runtime basically of the NeXT family of runtimes?
  bool isNeXTFamily() const {
    // For now, this is just the inverse of isGNUFamily(), but that's
    // not inherently true.
    return !isGNUFamily();
  }

  /// Does this runtime allow ARC at all?
  bool allowsARC() const {
    switch (getKind()) {
    case FragileMacOSX:
      // No stub library for the fragile runtime.
      return getVersion() >= VersionTuple(10, 7);
    case MacOSX: return true;
    case iOS: return true;
    case WatchOS: return true;
    case GCC: return false;
    case GNUstep: return true;
    case ObjFW: return true;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime natively provide the ARC entrypoints?
  ///
  /// ARC cannot be directly supported on a platform that does not provide
  /// these entrypoints, although it may be supportable via a stub
  /// library.
  bool hasNativeARC() const {
    switch (getKind()) {
    case FragileMacOSX: return getVersion() >= VersionTuple(10, 7);
    case MacOSX: return getVersion() >= VersionTuple(10, 7);
    case iOS: return getVersion() >= VersionTuple(5);
    case WatchOS: return true;

    case GCC: return false;
    case GNUstep: return getVersion() >= VersionTuple(1, 6);
    case ObjFW: return true;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime provide ARC entrypoints that are likely to be faster
  /// than an ordinary message send of the appropriate selector?
  ///
  /// The ARC entrypoints are guaranteed to be equivalent to just sending the
  /// corresponding message.  If the entrypoint is implemented naively as just a
  /// message send, using it is a trade-off: it sacrifices a few cycles of
  /// overhead to save a small amount of code.  However, it's possible for
  /// runtimes to detect and special-case classes that use "standard"
  /// retain/release behavior; if that's dynamically a large proportion of all
  /// retained objects, using the entrypoint will also be faster than using a
  /// message send.
  ///
  /// When this method returns true, Clang will turn non-super message sends of
  /// certain selectors into calls to the correspond entrypoint:
  ///   retain => objc_retain
  ///   release => objc_release
  ///   autorelease => objc_autorelease
  bool shouldUseARCFunctionsForRetainRelease() const {
    switch (getKind()) {
    case FragileMacOSX:
      return false;
    case MacOSX:
      return getVersion() >= VersionTuple(10, 10);
    case iOS:
      return getVersion() >= VersionTuple(8);
    case WatchOS:
      return true;
    case GCC:
      return false;
    case GNUstep:
      return false;
    case ObjFW:
      return false;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime provide entrypoints that are likely to be faster
  /// than an ordinary message send of the "alloc" selector?
  ///
  /// The "alloc" entrypoint is guaranteed to be equivalent to just sending the
  /// corresponding message.  If the entrypoint is implemented naively as just a
  /// message send, using it is a trade-off: it sacrifices a few cycles of
  /// overhead to save a small amount of code.  However, it's possible for
  /// runtimes to detect and special-case classes that use "standard"
  /// alloc behavior; if that's dynamically a large proportion of all
  /// objects, using the entrypoint will also be faster than using a message
  /// send.
  ///
  /// When this method returns true, Clang will turn non-super message sends of
  /// certain selectors into calls to the corresponding entrypoint:
  ///   alloc => objc_alloc
  ///   allocWithZone:nil => objc_allocWithZone
  bool shouldUseRuntimeFunctionsForAlloc() const {
    switch (getKind()) {
    case FragileMacOSX:
      return false;
    case MacOSX:
      return getVersion() >= VersionTuple(10, 10);
    case iOS:
      return getVersion() >= VersionTuple(8);
    case WatchOS:
      return true;

    case GCC:
      return false;
    case GNUstep:
      return false;
    case ObjFW:
      return false;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime supports optimized setter entrypoints?
  bool hasOptimizedSetter() const {
    switch (getKind()) {
      case MacOSX:
        return getVersion() >= VersionTuple(10, 8);
      case iOS:
        return (getVersion() >= VersionTuple(6));
      case WatchOS:
        return true;
      case GNUstep:
        return getVersion() >= VersionTuple(1, 7);
      default:
        return false;
    }
  }

  /// Does this runtime allow the use of __weak?
  bool allowsWeak() const {
    return hasNativeWeak();
  }

  /// Does this runtime natively provide ARC-compliant 'weak'
  /// entrypoints?
  bool hasNativeWeak() const {
    // Right now, this is always equivalent to whether the runtime
    // natively supports ARC decision.
    return hasNativeARC();
  }

  /// Does this runtime directly support the subscripting methods?
  ///
  /// This is really a property of the library, not the runtime.
  bool hasSubscripting() const {
    switch (getKind()) {
    case FragileMacOSX: return false;
    case MacOSX: return getVersion() >= VersionTuple(10, 11);
    case iOS: return getVersion() >= VersionTuple(9);
    case WatchOS: return true;

    // This is really a lie, because some implementations and versions
    // of the runtime do not support ARC.  Probably -fgnu-runtime
    // should imply a "maximal" runtime or something?
    case GCC: return true;
    case GNUstep: return true;
    case ObjFW: return true;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime allow sizeof or alignof on object types?
  bool allowsSizeofAlignof() const {
    return isFragile();
  }

  /// Does this runtime allow pointer arithmetic on objects?
  ///
  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
  /// yields true) [].
  bool allowsPointerArithmetic() const {
    switch (getKind()) {
    case FragileMacOSX:
    case GCC:
      return true;
    case MacOSX:
    case iOS:
    case WatchOS:
    case GNUstep:
    case ObjFW:
      return false;
    }
    llvm_unreachable("bad kind");
  }

  /// Is subscripting pointer arithmetic?
  bool isSubscriptPointerArithmetic() const {
    return allowsPointerArithmetic();
  }

  /// Does this runtime provide an objc_terminate function?
  ///
  /// This is used in handlers for exceptions during the unwind process;
  /// without it, abort() must be used in pure ObjC files.
  bool hasTerminate() const {
    switch (getKind()) {
    case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
    case MacOSX: return getVersion() >= VersionTuple(10, 8);
    case iOS: return getVersion() >= VersionTuple(5);
    case WatchOS: return true;
    case GCC: return false;
    case GNUstep: return false;
    case ObjFW: return false;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime support weakly importing classes?
  bool hasWeakClassImport() const {
    switch (getKind()) {
    case MacOSX: return true;
    case iOS: return true;
    case WatchOS: return true;
    case FragileMacOSX: return false;
    case GCC: return true;
    case GNUstep: return true;
    case ObjFW: return true;
    }
    llvm_unreachable("bad kind");
  }

  /// Does this runtime use zero-cost exceptions?
  bool hasUnwindExceptions() const {
    switch (getKind()) {
    case MacOSX: return true;
    case iOS: return true;
    case WatchOS: return true;
    case FragileMacOSX: return false;
    case GCC: return true;
    case GNUstep: return true;
    case ObjFW: return true;
    }
    llvm_unreachable("bad kind");
  }

  bool hasAtomicCopyHelper() const {
    switch (getKind()) {
    case FragileMacOSX:
    case MacOSX:
    case iOS:
    case WatchOS:
      return true;
    case GNUstep:
      return getVersion() >= VersionTuple(1, 7);
    default: return false;
    }
  }

  /// Is objc_unsafeClaimAutoreleasedReturnValue available?
  bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
    switch (getKind()) {
    case MacOSX:
    case FragileMacOSX:
      return getVersion() >= VersionTuple(10, 11);
    case iOS:
      return getVersion() >= VersionTuple(9);
    case WatchOS:
      return getVersion() >= VersionTuple(2);
    case GNUstep:
      return false;
    default:
      return false;
    }
  }

  /// Are the empty collection symbols available?
  bool hasEmptyCollections() const {
    switch (getKind()) {
    default:
      return false;
    case MacOSX:
      return getVersion() >= VersionTuple(10, 11);
    case iOS:
      return getVersion() >= VersionTuple(9);
    case WatchOS:
      return getVersion() >= VersionTuple(2);
    }
  }

  /// Try to parse an Objective-C runtime specification from the given
  /// string.
  ///
  /// \return true on error.
  bool tryParse(StringRef input);

  std::string getAsString() const;

  friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
    return left.getKind() == right.getKind() &&
           left.getVersion() == right.getVersion();
  }

  friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
    return !(left == right);
  }
};

raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);

} // namespace clang

#endif // LLVM_CLANG_BASIC_OBJCRUNTIME_H
