//===--- SwiftObject.mm - Native Swift Object root class ------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This implements the Objective-C root class that provides basic `id`-
// compatibility and `NSObject` protocol conformance for pure Swift classes.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Config.h"

#if SWIFT_OBJC_INTEROP
#include <objc/NSObject.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <objc/objc.h>
#endif
#include "llvm/ADT/StringRef.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Lazy.h"
#include "swift/Runtime/Casting.h"
#include "swift/Runtime/Heap.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/ObjCBridge.h"
#include "swift/Strings.h"
#include "../SwiftShims/RuntimeShims.h"
#include "../SwiftShims/AssertionReporting.h"
#include "CompatibilityOverride.h"
#include "Private.h"
#include "SwiftObject.h"
#include "WeakReference.h"
#include "swift/Runtime/Debug.h"
#if SWIFT_OBJC_INTEROP
#include <dlfcn.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unordered_map>
#if SWIFT_OBJC_INTEROP
# import <CoreFoundation/CFBase.h> // for CFTypeID
# import <Foundation/Foundation.h>
# include <malloc/malloc.h>
# include <dispatch/dispatch.h>
#endif

using namespace swift;

#if SWIFT_HAS_ISA_MASKING
OBJC_EXPORT __attribute__((__weak_import__))
const uintptr_t objc_debug_isa_class_mask;

static uintptr_t computeISAMask() {
  // The versions of the Objective-C runtime which use non-pointer
  // ISAs also export this symbol.
  if (auto runtimeSymbol = &objc_debug_isa_class_mask)
    return *runtimeSymbol;
  return ~uintptr_t(0);
}

SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
uintptr_t swift::swift_isaMask = computeISAMask();
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
#endif

const ClassMetadata *swift::_swift_getClass(const void *object) {
#if SWIFT_OBJC_INTEROP
  if (!isObjCTaggedPointer(object))
    return _swift_getClassOfAllocated(object);
  return reinterpret_cast<const ClassMetadata*>(
    object_getClass(id_const_cast(object)));
#else
  return _swift_getClassOfAllocated(object);
#endif
}

bool isObjCPinned(HeapObject *obj) {
  #if SWIFT_OBJC_INTEROP
    /* future: implement checking the relevant objc runtime bits */
    return true;
  #else
    return false;
  #endif
}

// returns non-null if realloc was successful
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
HeapObject *swift::_swift_reallocObject(HeapObject *obj, size_t size) {
 if (isObjCPinned(obj) || obj->refCounts.hasSideTable()) {
   return nullptr;
 }
 return (HeapObject *)realloc(obj, size);
}

#if SWIFT_OBJC_INTEROP

/// Replacement for ObjC object_isClass(), which is unavailable on
/// deployment targets macOS 10.9 and iOS 7.
static bool objcObjectIsClass(id object) {
  // same as object_isClass(object)
  return class_isMetaClass(object_getClass(object));
}

/// Same as _swift_getClassOfAllocated() but returns type Class.
static Class _swift_getObjCClassOfAllocated(const void *object) {
  return class_const_cast(_swift_getClassOfAllocated(object));
}

/// Fetch the ObjC class object associated with the formal dynamic
/// type of the given (possibly Objective-C) object.  The formal
/// dynamic type ignores dynamic subclasses such as those introduced
/// by KVO.
///
/// The object pointer may be a tagged pointer, but cannot be null.
const ClassMetadata *swift::swift_getObjCClassFromObject(HeapObject *object) {
  auto classAsMetadata = _swift_getClass(object);

  // Walk up the superclass chain skipping over artifical Swift classes.
  // If we find a non-Swift class use the result of [object class] instead.

  while (classAsMetadata && classAsMetadata->isTypeMetadata()) {
    if (!classAsMetadata->isArtificialSubclass())
      return classAsMetadata;
    classAsMetadata = classAsMetadata->Superclass;
  }

  id objcObject = reinterpret_cast<id>(object);
  Class objcClass = [objcObject class];
  if (objcObjectIsClass(objcObject)) {
    // Original object is a class. We want a
    // metaclass but +class doesn't give that to us.
    objcClass = object_getClass(objcClass);
  }
  classAsMetadata = reinterpret_cast<const ClassMetadata *>(objcClass);
  return classAsMetadata;
}
#endif

/// Fetch the type metadata associated with the formal dynamic
/// type of the given (possibly Objective-C) object.  The formal
/// dynamic type ignores dynamic subclasses such as those introduced
/// by KVO.
///
/// The object pointer may be a tagged pointer, but cannot be null.
const Metadata *swift::swift_getObjectType(HeapObject *object) {
  auto classAsMetadata = _swift_getClass(object);

#if SWIFT_OBJC_INTEROP
  // Walk up the superclass chain skipping over artifical Swift classes.
  // If we find a non-Swift class use the result of [object class] instead.

  while (classAsMetadata && classAsMetadata->isTypeMetadata()) {
    if (!classAsMetadata->isArtificialSubclass())
      return classAsMetadata;
    classAsMetadata = classAsMetadata->Superclass;
  }

  id objcObject = reinterpret_cast<id>(object);
  Class objcClass = [objcObject class];
  if (objcObjectIsClass(objcObject)) {
    // Original object is a class. We want a
    // metaclass but +class doesn't give that to us.
    objcClass = object_getClass(objcClass);
  }
  classAsMetadata = reinterpret_cast<const ClassMetadata *>(objcClass);
  return swift_getObjCClassMetadata(classAsMetadata);
#else
  assert(classAsMetadata &&
         classAsMetadata->isTypeMetadata() &&
         !classAsMetadata->isArtificialSubclass());
  return classAsMetadata;
#endif
}

#if SWIFT_OBJC_INTEROP
static SwiftObject *_allocHelper(Class cls) {
  // XXX FIXME
  // When we have layout information, do precise alignment rounding
  // For now, assume someone is using hardware vector types
#if defined(__x86_64__) || defined(__i386__)
  const size_t mask = 32 - 1;
#else
  const size_t mask = 16 - 1;
#endif
  return reinterpret_cast<SwiftObject *>(swift::swift_allocObject(
    reinterpret_cast<HeapMetadata const *>(cls),
    class_getInstanceSize(cls), mask));
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
NSString *swift_stdlib_getDescription(OpaqueValue *value,
                                      const Metadata *type);

NSString *swift::getDescription(OpaqueValue *value, const Metadata *type) {
  auto result = swift_stdlib_getDescription(value, type);
  type->vw_destroy(value);
  return [result autorelease];
}

static NSString *_getObjectDescription(SwiftObject *obj) {
  swift_retain((HeapObject*)obj);
  return getDescription((OpaqueValue*)&obj,
                        _swift_getClassOfAllocated(obj));
}

static NSString *_getClassDescription(Class cls) {
  return NSStringFromClass(cls);
}


@implementation SwiftObject
+ (void)initialize {}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
  assert(zone == nullptr);
  return _allocHelper(self);
}

+ (instancetype)alloc {
  // we do not support "placement new" or zones,
  // so there is no need to call allocWithZone
  return _allocHelper(self);
}

+ (Class)class {
  return self;
}
- (Class)class {
  return _swift_getObjCClassOfAllocated(self);
}
+ (Class)superclass {
  return (Class)((const ClassMetadata*) self)->Superclass;
}
- (Class)superclass {
  return (Class)_swift_getClassOfAllocated(self)->Superclass;
}

+ (BOOL)isMemberOfClass:(Class)cls {
  return cls == _swift_getObjCClassOfAllocated(self);
}

- (BOOL)isMemberOfClass:(Class)cls {
  return cls == _swift_getObjCClassOfAllocated(self);
}

- (instancetype)self {
  return self;
}
- (BOOL)isProxy {
  return NO;
}

- (struct _NSZone *)zone {
  auto zone = malloc_zone_from_ptr(self);
  return (struct _NSZone *)(zone ? zone : malloc_default_zone());
}

- (void)doesNotRecognizeSelector: (SEL) sel {
  Class cls = _swift_getObjCClassOfAllocated(self);
  fatalError(/* flags = */ 0,
             "Unrecognized selector %c[%s %s]\n",
             class_isMetaClass(cls) ? '+' : '-',
             class_getName(cls), sel_getName(sel));
}

- (id)retain {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_retain(SELF);
  return self;
}
- (void)release {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_release(SELF);
}
- (id)autorelease {
  return _objc_rootAutorelease(self);
}
- (NSUInteger)retainCount {
  return swift::swift_retainCount(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)_isDeallocating {
  return swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)_tryRetain {
  return swift_tryRetain(reinterpret_cast<HeapObject*>(self)) != nullptr;
}
- (BOOL)allowsWeakReference {
  return !swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)retainWeakReference {
  return swift_tryRetain(reinterpret_cast<HeapObject*>(self)) != nullptr;
}

// Retaining the class object itself is a no-op.
+ (id)retain {
  return self;
}
+ (void)release {
  /* empty */
}
+ (id)autorelease {
  return self;
}
+ (NSUInteger)retainCount {
  return ULONG_MAX;
}
+ (BOOL)_isDeallocating {
  return NO;
}
+ (BOOL)_tryRetain {
  return YES;
}
+ (BOOL)allowsWeakReference {
  return YES;
}
+ (BOOL)retainWeakReference {
  return YES;
}

- (void)dealloc {
  swift_rootObjCDealloc(reinterpret_cast<HeapObject *>(self));
}

- (BOOL)isKindOfClass:(Class)someClass {
  for (auto cls = _swift_getClassOfAllocated(self); cls != nullptr;
       cls = cls->Superclass)
    if (cls == (const ClassMetadata*) someClass)
      return YES;

  return NO;
}

+ (BOOL)isSubclassOfClass:(Class)someClass {
  for (auto cls = (const ClassMetadata*) self; cls != nullptr;
       cls = cls->Superclass)
    if (cls == (const ClassMetadata*) someClass)
      return YES;

  return NO;
}

+ (BOOL)respondsToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(_swift_getObjCClassOfAllocated(self), sel);
}

- (BOOL)respondsToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(_swift_getObjCClassOfAllocated(self), sel);
}

+ (BOOL)instancesRespondToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(self, sel);
}


+ (IMP)methodForSelector:(SEL)sel {
  return class_getMethodImplementation(object_getClass((id)self), sel);
}

- (IMP)methodForSelector:(SEL)sel {
  return class_getMethodImplementation(object_getClass(self), sel);
}

+ (IMP)instanceMethodForSelector:(SEL)sel {
  return class_getMethodImplementation(self, sel);
}


- (BOOL)conformsToProtocol:(Protocol*)proto {
  if (!proto) return NO;
  auto selfClass = _swift_getObjCClassOfAllocated(self);

  // Walk the superclass chain.
  while (selfClass) {
    if (class_conformsToProtocol(selfClass, proto))
      return YES;
    selfClass = class_getSuperclass(selfClass);
  }

  return NO;
}

+ (BOOL)conformsToProtocol:(Protocol*)proto {
  if (!proto) return NO;

  // Walk the superclass chain.
  Class selfClass = self;
  while (selfClass) {
    if (class_conformsToProtocol(selfClass, proto))
      return YES;
    selfClass = class_getSuperclass(selfClass);
  }

  return NO;
}

- (NSUInteger)hash {
  return (NSUInteger)self;
}

- (BOOL)isEqual:(id)object {
  return self == object;
}

- (id)performSelector:(SEL)aSelector {
  return ((id(*)(id, SEL))objc_msgSend)(self, aSelector);
}

- (id)performSelector:(SEL)aSelector withObject:(id)object {
  return ((id(*)(id, SEL, id))objc_msgSend)(self, aSelector, object);
}

- (id)performSelector:(SEL)aSelector withObject:(id)object1
                                     withObject:(id)object2 {
  return ((id(*)(id, SEL, id, id))objc_msgSend)(self, aSelector, object1,
                                                                 object2);
}

- (NSString *)description {
  return _getObjectDescription(self);
}
- (NSString *)debugDescription {
  return _getObjectDescription(self);
}

+ (NSString *)description {
  return _getClassDescription(self);
}
+ (NSString *)debugDescription {
  return _getClassDescription(self);
}

- (NSString *)_copyDescription {
  // The NSObject version of this pushes an autoreleasepool in case -description
  // autoreleases, but we're OK with leaking things if we're at the top level
  // of the main thread with no autorelease pool.
  return [[self description] retain];
}

- (CFTypeID)_cfTypeID {
  // Adopt the same CFTypeID as NSObject.
  static CFTypeID result;
  static dispatch_once_t predicate;
  dispatch_once_f(&predicate, &result, [](void *resultAddr) {
    id obj = [[NSObject alloc] init];
    *(CFTypeID*)resultAddr = [obj _cfTypeID];
    [obj release];
  });
  return result;
}

// Foundation collections expect these to be implemented.
- (BOOL)isNSArray__      { return NO; }
- (BOOL)isNSCFConstantString__  { return NO; }
- (BOOL)isNSData__       { return NO; }
- (BOOL)isNSDate__       { return NO; }
- (BOOL)isNSDictionary__ { return NO; }
- (BOOL)isNSObject__     { return NO; }
- (BOOL)isNSOrderedSet__ { return NO; }
- (BOOL)isNSNumber__     { return NO; }
- (BOOL)isNSSet__        { return NO; }
- (BOOL)isNSString__     { return NO; }
- (BOOL)isNSTimeZone__   { return NO; }
- (BOOL)isNSValue__      { return NO; }

@end

#endif

/// Decide dynamically whether the given class uses native Swift
/// reference-counting.
bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
#if SWIFT_OBJC_INTEROP
  if (!theClass->isTypeMetadata()) return false;
  return (theClass->getFlags() & ClassFlags::UsesSwiftRefcounting);
#else
  return true;
#endif
}

/// Decide dynamically whether the given type metadata uses native Swift
/// reference-counting.  The metadata is known to correspond to a class
/// type, but note that does not imply being known to be a ClassMetadata
/// due to the existence of ObjCClassWrapper.
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
bool
_swift_objcClassUsesNativeSwiftReferenceCounting(const Metadata *theClass) {
#if SWIFT_OBJC_INTEROP
  // If this is ObjC wrapper metadata, the class is definitely not using
  // Swift ref-counting.
  if (isa<ObjCClassWrapperMetadata>(theClass)) return false;

  // Otherwise, it's class metadata.
  return usesNativeSwiftReferenceCounting(cast<ClassMetadata>(theClass));
#else
  return true;
#endif
}

// The non-pointer bits, excluding the tag bits.
static auto const unTaggedNonNativeBridgeObjectBits
  = heap_object_abi::SwiftSpareBitsMask
  & ~heap_object_abi::ObjCReservedBitsMask
  & ~heap_object_abi::BridgeObjectTagBitsMask;

#if SWIFT_OBJC_INTEROP

#if defined(__x86_64__)
static uintptr_t const objectPointerIsObjCBit = 0x4000000000000000ULL;
#elif defined(__arm64__) || defined(__arch64__) || defined(_M_ARM64)
static uintptr_t const objectPointerIsObjCBit = 0x4000000000000000ULL;
#else
static uintptr_t const objectPointerIsObjCBit = 0x00000002U;
#endif

void *swift::swift_unknownObjectRetain_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_retain_n(static_cast<HeapObject *>(object), n);
  }
  for (int i = 0; i < n; ++i)
    objc_retain(static_cast<id>(object));

  return object;
}

void swift::swift_unknownObjectRelease_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release_n(static_cast<HeapObject *>(object), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(object));
}

void *swift::swift_unknownObjectRetain(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_retain(static_cast<HeapObject *>(object));
  }
  return objc_retain(static_cast<id>(object));
}

void swift::swift_unknownObjectRelease(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release(static_cast<HeapObject *>(object));
  return objc_release(static_cast<id>(object));
}

void *swift::swift_nonatomic_unknownObjectRetain_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_nonatomic_retain_n(static_cast<HeapObject *>(object), n);
  }
  for (int i = 0; i < n; ++i)
    objc_retain(static_cast<id>(object));
  return object;
}

void swift::swift_nonatomic_unknownObjectRelease_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_nonatomic_release_n(static_cast<HeapObject *>(object), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(object));
}

void *swift::swift_nonatomic_unknownObjectRetain(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_nonatomic_retain(static_cast<HeapObject *>(object));
  }
  return objc_retain(static_cast<id>(object));
}

void swift::swift_nonatomic_unknownObjectRelease(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release(static_cast<HeapObject *>(object));
  return objc_release(static_cast<id>(object));
}

/// Return true iff the given BridgeObject is not known to use native
/// reference-counting.
///
/// Precondition: object does not encode a tagged pointer
static bool isNonNative_unTagged_bridgeObject(void *object) {
  static_assert((heap_object_abi::SwiftSpareBitsMask & objectPointerIsObjCBit) ==
                objectPointerIsObjCBit,
                "isObjC bit not within spare bits");
  return (uintptr_t(object) & objectPointerIsObjCBit) != 0
      && (uintptr_t(object) & heap_object_abi::BridgeObjectTagBitsMask) == 0;
}

/// Return true iff the given BridgeObject is a tagged value.
static bool isBridgeObjectTaggedPointer(void *object) {
  return (uintptr_t(object) & heap_object_abi::BridgeObjectTagBitsMask) != 0;
}

#endif

// Mask out the spare bits in a bridgeObject, returning the object it
// encodes.
///
/// Precondition: object does not encode a tagged pointer
static void* toPlainObject_unTagged_bridgeObject(void *object) {
  return (void*)(uintptr_t(object) & ~unTaggedNonNativeBridgeObjectBits);
}

void *swift::swift_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_retain(static_cast<HeapObject *>(objectRef));
    return object;
  }
  objc_retain(static_cast<id>(objectRef));
  return object;
#else
  swift_retain(static_cast<HeapObject *>(objectRef));
  return object;
#endif
}

SWIFT_RUNTIME_EXPORT
void *swift::swift_nonatomic_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_nonatomic_retain(static_cast<HeapObject *>(objectRef));
    return object;
  }
  objc_retain(static_cast<id>(objectRef));
  return object;
#else
  swift_nonatomic_retain(static_cast<HeapObject *>(objectRef));
  return object;
#endif
}

SWIFT_RUNTIME_EXPORT
void swift::swift_bridgeObjectRelease(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_release(static_cast<HeapObject *>(objectRef));
  return objc_release(static_cast<id>(objectRef));
#else
  swift_release(static_cast<HeapObject *>(objectRef));
#endif
}

void swift::swift_nonatomic_bridgeObjectRelease(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_nonatomic_release(static_cast<HeapObject *>(objectRef));
  return objc_release(static_cast<id>(objectRef));
#else
  swift_nonatomic_release(static_cast<HeapObject *>(objectRef));
#endif
}

void *swift::swift_bridgeObjectRetain_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  void *objc_ret = nullptr;
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_retain_n(static_cast<HeapObject *>(objectRef), n);
    return object;
  }
  for (int i = 0;i < n; ++i)
    objc_ret = objc_retain(static_cast<id>(objectRef));
  return object;
#else
  swift_retain_n(static_cast<HeapObject *>(objectRef), n);
  return object;
#endif
}

void swift::swift_bridgeObjectRelease_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_release_n(static_cast<HeapObject *>(objectRef), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(objectRef));
#else
  swift_release_n(static_cast<HeapObject *>(objectRef), n);
#endif
}

void *swift::swift_nonatomic_bridgeObjectRetain_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  void *objc_ret = nullptr;
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_nonatomic_retain_n(static_cast<HeapObject *>(objectRef), n);
    return object;
  }
  for (int i = 0;i < n; ++i)
    objc_ret = objc_retain(static_cast<id>(objectRef));
  return object;
#else
  swift_nonatomic_retain_n(static_cast<HeapObject *>(objectRef), n);
  return object;
#endif
}

void swift::swift_nonatomic_bridgeObjectRelease_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_nonatomic_release_n(static_cast<HeapObject *>(objectRef), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(objectRef));
#else
  swift_nonatomic_release_n(static_cast<HeapObject *>(objectRef), n);
#endif
}


#if SWIFT_OBJC_INTEROP

/*****************************************************************************/
/************************ UNKNOWN UNOWNED REFERENCES *************************/
/*****************************************************************************/

// Swift's native unowned references are implemented purely with
// reference-counting: as long as an unowned reference is held to an object,
// it can be destroyed but never deallocated, being that it remains fully safe
// to pass around a pointer and perform further reference-counting operations.
//
// For imported class types (meaning ObjC, for now, but in principle any
// type which supports ObjC-style weak references but not directly Swift-style
// unowned references), we have to implement this on top of the weak-reference
// support, at least for now.  But we'd like to be able to statically take
// advantage of Swift's representational advantages when we know that all the
// objects involved are Swift-native.  That means that whatever scheme we use
// for unowned references needs to interoperate with code just doing naive
// loads and stores, at least when the ObjC case isn't triggered.
//
// We have to be sensitive about making unreasonable assumptions about the
// implementation of ObjC weak references, and we definitely cannot modify
// memory owned by the ObjC runtime.  In the long run, direct support from
// the ObjC runtime can allow an efficient implementation that doesn't violate
// those requirements, both by allowing us to directly check whether a weak
// reference was cleared by deallocation vs. just initialized to nil and by
// guaranteeing a bit pattern that distinguishes Swift references.  In the
// meantime, out-of-band allocation is inefficient but not ridiculously so.
//
// Note that unowned references need not provide guaranteed behavior in
// the presence of read/write or write/write races on the reference itself.
// Furthermore, and unlike weak references, they also do not need to be
// safe against races with the deallocation of the object.  It is the user's
// responsibility to ensure that the reference remains valid at the time
// that the unowned reference is read.

namespace {
  /// An Objective-C unowned reference.  Given an unknown unowned reference
  /// in memory, it is an ObjC unowned reference if the IsObjCFlag bit
  /// is set; if so, the pointer stored in the reference actually points
  /// to out-of-line storage containing an ObjC weak reference.
  ///
  /// It is an invariant that this out-of-line storage is only ever
  /// allocated and constructed for non-null object references, so if the
  /// weak load yields null, it can only be because the object was deallocated.
  struct ObjCUnownedReference : UnownedReference {
    // Pretending that there's a subclass relationship here means that
    // accesses to objects formally constructed as UnownedReferences will
    // technically be aliasing violations.  However, the language runtime
    // will generally not see any such objects.

    enum : uintptr_t { IsObjCMask = 0x1, IsObjCFlag = 0x1 };

    /// The out-of-line storage of an ObjC unowned reference.
    struct Storage {
      /// A weak reference registered with the ObjC runtime.
      mutable id WeakRef;

      Storage(id ref) {
        assert(ref && "creating storage for null reference?");
        objc_initWeak(&WeakRef, ref);
      }

      Storage(const Storage &other) {
        objc_copyWeak(&WeakRef, &other.WeakRef);
      }

      Storage &operator=(const Storage &other) = delete;

      Storage &operator=(id ref) {
        objc_storeWeak(&WeakRef, ref);
        return *this;
      }

      ~Storage() {
        objc_destroyWeak(&WeakRef);
      }

      // Don't use the C++ allocator.
      void *operator new(size_t size) { return malloc(size); }
      void operator delete(void *ptr) { free(ptr); }
    };

    Storage *storage() {
      assert(isa<ObjCUnownedReference>(this));
      return reinterpret_cast<Storage*>(
               reinterpret_cast<uintptr_t>(Value) & ~IsObjCMask);
    }

    static void initialize(UnownedReference *dest, id value) {
      initializeWithStorage(dest, new Storage(value));
    }

    static void initializeWithCopy(UnownedReference *dest, Storage *src) {
      initializeWithStorage(dest, new Storage(*src));
    }

    static void initializeWithStorage(UnownedReference *dest,
                                      Storage *storage) {
      dest->Value = (HeapObject*) (uintptr_t(storage) | IsObjCFlag);
    }

    static bool classof(const UnownedReference *ref) {
      return (uintptr_t(ref->Value) & IsObjCMask) == IsObjCFlag;
    }
  };
}

static bool isObjCForUnownedReference(void *value) {
  return (isObjCTaggedPointer(value) ||
          !objectUsesNativeSwiftReferenceCounting(value));
}

UnownedReference *swift::swift_unknownObjectUnownedInit(UnownedReference *dest,
                                                        void *value) {
  // Note that LLDB also needs to know about the memory layout of unowned
  // references. The implementation here needs to be kept in sync with
  // lldb_private::SwiftLanguagueRuntime.
  if (!value) {
    dest->Value = nullptr;
  } else if (isObjCForUnownedReference(value)) {
    ObjCUnownedReference::initialize(dest, (id) value);
  } else {
    swift_unownedInit(dest, (HeapObject*) value);
  }
  return dest;
}

UnownedReference *
swift::swift_unknownObjectUnownedAssign(UnownedReference *dest, void *value) {
  if (!value) {
    swift_unknownObjectUnownedDestroy(dest);
    dest->Value = nullptr;
  } else if (isObjCForUnownedReference(value)) {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      objc_storeWeak(&objcDest->storage()->WeakRef, (id) value);
    } else {
      swift_unownedDestroy(dest);
      ObjCUnownedReference::initialize(dest, (id) value);
    }
  } else {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      delete objcDest->storage();
      swift_unownedInit(dest, (HeapObject*) value);
    } else {
      swift_unownedAssign(dest, (HeapObject*) value);
    }
  }
  return dest;
}

void *swift::swift_unknownObjectUnownedLoadStrong(UnownedReference *ref) {
  if (!ref->Value) {
    return nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    if (result == nullptr) {
      swift::swift_abortRetainUnowned(nullptr);
    }
    return result;
  } else {
    return swift_unownedLoadStrong(ref);
  }
}

void *swift::swift_unknownObjectUnownedTakeStrong(UnownedReference *ref) {
  if (!ref->Value) {
    return nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    auto storage = objcRef->storage();
    auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    if (result == nullptr) {
      swift::swift_abortRetainUnowned(nullptr);
    }
    delete storage;
    return result;
  } else {
    return swift_unownedTakeStrong(ref);
  }
}

void swift::swift_unknownObjectUnownedDestroy(UnownedReference *ref) {
  if (!ref->Value) {
    // Nothing to do.
    return;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    delete objcRef->storage();
  } else {
    swift_unownedDestroy(ref);
  }
}

UnownedReference *
swift::swift_unknownObjectUnownedCopyInit(UnownedReference *dest,
                                          UnownedReference *src) {
  assert(dest != src);
  if (!src->Value) {
    dest->Value = nullptr;
  } else if (auto objcSrc = dyn_cast<ObjCUnownedReference>(src)) {
    ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage());
  } else {
    swift_unownedCopyInit(dest, src);
  }
  return dest;
}

UnownedReference *
swift::swift_unknownObjectUnownedTakeInit(UnownedReference *dest,
                                          UnownedReference *src) {
  assert(dest != src);
  dest->Value = src->Value;
  return dest;
}

UnownedReference *
swift::swift_unknownObjectUnownedCopyAssign(UnownedReference *dest,
                                            UnownedReference *src) {
  if (dest == src) return dest;

  if (auto objcSrc = dyn_cast<ObjCUnownedReference>(src)) {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      // ObjC unfortunately doesn't expose a copy-assign operation.
      objc_destroyWeak(&objcDest->storage()->WeakRef);
      objc_copyWeak(&objcDest->storage()->WeakRef,
                    &objcSrc->storage()->WeakRef);
      return dest;
    }

    swift_unownedDestroy(dest);
    ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage());
  } else {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      delete objcDest->storage();
      swift_unownedCopyInit(dest, src);
    } else {
      swift_unownedCopyAssign(dest, src);
    }
  }
  return dest;
}

UnownedReference *
swift::swift_unknownObjectUnownedTakeAssign(UnownedReference *dest,
                                            UnownedReference *src) {
  assert(dest != src);

  // There's not really anything more efficient to do here than this.
  swift_unknownObjectUnownedDestroy(dest);
  dest->Value = src->Value;
  return dest;
}

bool swift::swift_unknownObjectUnownedIsEqual(UnownedReference *ref,
                                              void *value) {
  if (!ref->Value) {
    return value == nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    id refValue = objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    bool isEqual = (void*)refValue == value;
    // This ObjC case has no deliberate unowned check here,
    // unlike the Swift case.
    [refValue release];
    return isEqual;
  } else {
    return swift_unownedIsEqual(ref, (HeapObject *)value);
  }
}

/*****************************************************************************/
/************************** UNKNOWN WEAK REFERENCES **************************/
/*****************************************************************************/

WeakReference *swift::swift_unknownObjectWeakInit(WeakReference *ref,
                                                  void *value) {
  ref->unknownInit(value);
  return ref;
}

WeakReference *swift::swift_unknownObjectWeakAssign(WeakReference *ref,
                                                    void *value) {
  ref->unknownAssign(value);
  return ref;
}

void *swift::swift_unknownObjectWeakLoadStrong(WeakReference *ref) {
  return ref->unknownLoadStrong();
}

void *swift::swift_unknownObjectWeakTakeStrong(WeakReference *ref) {
  return ref->unknownTakeStrong();
}

void swift::swift_unknownObjectWeakDestroy(WeakReference *ref) {
  ref->unknownDestroy();
}

WeakReference *swift::swift_unknownObjectWeakCopyInit(WeakReference *dest,
                                                      WeakReference *src) {
  dest->unknownCopyInit(src);
  return dest;
}
WeakReference *swift::swift_unknownObjectWeakTakeInit(WeakReference *dest,
                                                      WeakReference *src) {
  dest->unknownTakeInit(src);
  return dest;
}
WeakReference *swift::swift_unknownObjectWeakCopyAssign(WeakReference *dest,
                                                        WeakReference *src) {
  dest->unknownCopyAssign(src);
  return dest;
}
WeakReference *swift::swift_unknownObjectWeakTakeAssign(WeakReference *dest,
                                                        WeakReference *src) {
  dest->unknownTakeAssign(src);
  return dest;
}

// SWIFT_OBJC_INTEROP
#endif

/*****************************************************************************/
/******************************* DYNAMIC CASTS *******************************/
/*****************************************************************************/

#if SWIFT_OBJC_INTEROP
static const void *
swift_dynamicCastObjCClassImpl(const void *object,
                               const ClassMetadata *targetType) {
  // FIXME: We need to decide if this is really how we want to treat 'nil'.
  if (object == nullptr)
    return nullptr;

  if ([id_const_cast(object) isKindOfClass:class_const_cast(targetType)]) {
    return object;
  }

  return nullptr;
}

static const void *
swift_dynamicCastObjCClassUnconditionalImpl(const void *object,
                                            const ClassMetadata *targetType,
                                            const char *filename,
                                            unsigned line, unsigned column) {
  // FIXME: We need to decide if this is really how we want to treat 'nil'.
  if (object == nullptr)
    return nullptr;

  if ([id_const_cast(object) isKindOfClass:class_const_cast(targetType)]) {
    return object;
  }

  Class sourceType = object_getClass(id_const_cast(object));
  swift_dynamicCastFailure(reinterpret_cast<const Metadata *>(sourceType),
                           targetType);
}

static const void *
swift_dynamicCastForeignClassImpl(const void *object,
                                  const ForeignClassMetadata *targetType) {
  // FIXME: Actually compare CFTypeIDs, once they are available in the metadata.
  return object;
}

static const void *
swift_dynamicCastForeignClassUnconditionalImpl(
         const void *object,
         const ForeignClassMetadata *targetType,
         const char *filename,
         unsigned line, unsigned column) {
  // FIXME: Actual compare CFTypeIDs, once they are available in the metadata.
  return object;
}

bool swift::objectConformsToObjCProtocol(const void *theObject,
                                         ProtocolDescriptorRef protocol) {
  return [id_const_cast(theObject)
          conformsToProtocol: protocol.getObjCProtocol()];
}


bool swift::classConformsToObjCProtocol(const void *theClass,
                                        ProtocolDescriptorRef protocol) {
  return [class_const_cast(theClass)
          conformsToProtocol: protocol.getObjCProtocol()];
}

SWIFT_RUNTIME_EXPORT
const Metadata *swift_dynamicCastTypeToObjCProtocolUnconditional(
                                               const Metadata *type,
                                               size_t numProtocols,
                                               Protocol * const *protocols,
                                               const char *filename,
                                               unsigned line, unsigned column) {
  Class classObject;

  switch (type->getKind()) {
  case MetadataKind::Class:
  case MetadataKind::ObjCClassWrapper:
    // Native class metadata is also the class object.
    // ObjC class wrappers get unwrapped.
    classObject = type->getObjCClassObject();
    break;

  // Other kinds of type can never conform to ObjC protocols.
  default:
    swift_dynamicCastFailure(type, nameForMetadata(type).c_str(),
                             protocols[0], protocol_getName(protocols[0]));

  case MetadataKind::HeapLocalVariable:
  case MetadataKind::HeapGenericLocalVariable:
  case MetadataKind::ErrorObject:
    assert(false && "not type metadata");
    break;
  }

  for (size_t i = 0; i < numProtocols; ++i) {
    if (![classObject conformsToProtocol:protocols[i]]) {
      swift_dynamicCastFailure(type, nameForMetadata(type).c_str(),
                               protocols[i], protocol_getName(protocols[i]));
    }
  }

  return type;
}

SWIFT_RUNTIME_EXPORT
const Metadata *swift_dynamicCastTypeToObjCProtocolConditional(
                                                const Metadata *type,
                                                size_t numProtocols,
                                                Protocol * const *protocols) {
  Class classObject;

  switch (type->getKind()) {
  case MetadataKind::Class:
  case MetadataKind::ObjCClassWrapper:
    // Native class metadata is also the class object.
    // ObjC class wrappers get unwrapped.
    classObject = type->getObjCClassObject();
    break;

  // Other kinds of type can never conform to ObjC protocols.
  default:
    return nullptr;

  case MetadataKind::HeapLocalVariable:
  case MetadataKind::HeapGenericLocalVariable:
  case MetadataKind::ErrorObject:
    assert(false && "not type metadata");
    break;
  }

  for (size_t i = 0; i < numProtocols; ++i) {
    if (![classObject conformsToProtocol:protocols[i]]) {
      return nullptr;
    }
  }

  return type;
}

SWIFT_RUNTIME_EXPORT
id swift_dynamicCastObjCProtocolUnconditional(id object,
                                              size_t numProtocols,
                                              Protocol * const *protocols,
                                              const char *filename,
                                              unsigned line, unsigned column) {
  for (size_t i = 0; i < numProtocols; ++i) {
    if (![object conformsToProtocol:protocols[i]]) {
      Class sourceType = object_getClass(object);
      swift_dynamicCastFailure(sourceType, class_getName(sourceType),
                               protocols[i], protocol_getName(protocols[i]));
    }
  }

  return object;
}

SWIFT_RUNTIME_EXPORT
id swift_dynamicCastObjCProtocolConditional(id object,
                                            size_t numProtocols,
                                            Protocol * const *protocols) {
  for (size_t i = 0; i < numProtocols; ++i) {
    if (![object conformsToProtocol:protocols[i]]) {
      return nil;
    }
  }

  return object;
}

void swift::swift_instantiateObjCClass(const ClassMetadata *_c) {
  static const objc_image_info ImageInfo = {0, 0};

  // Ensure the superclass is realized.
  Class c = class_const_cast(_c);
  [class_getSuperclass(c) class];

  // Register the class.
  Class registered = objc_readClassPair(c, &ImageInfo);
  assert(registered == c
         && "objc_readClassPair failed to instantiate the class in-place");
  (void)registered;
}

Class swift::swift_getInitializedObjCClass(Class c) {
  // Used when we have class metadata and we want to ensure a class has been
  // initialized by the Objective-C runtime. We need to do this because the
  // class "c" might be valid metadata, but it hasn't been initialized yet.
  return [c class];
}

static const ClassMetadata *
swift_dynamicCastObjCClassMetatypeImpl(const ClassMetadata *source,
                                       const ClassMetadata *dest) {
  if ([class_const_cast(source) isSubclassOfClass:class_const_cast(dest)])
    return source;
  return nil;
}

static const ClassMetadata *
swift_dynamicCastObjCClassMetatypeUnconditionalImpl(const ClassMetadata *source,
                                                    const ClassMetadata *dest,
                                                    const char *filename,
                                                    unsigned line, unsigned column) {
  if ([class_const_cast(source) isSubclassOfClass:class_const_cast(dest)])
    return source;

  swift_dynamicCastFailure(source, dest);
}

#endif

static const ClassMetadata *
swift_dynamicCastForeignClassMetatypeImpl(const ClassMetadata *sourceType,
                                          const ClassMetadata *targetType) {
  // FIXME: Actually compare CFTypeIDs, once they are available in
  // the metadata.
  return sourceType;
}

static const ClassMetadata *
swift_dynamicCastForeignClassMetatypeUnconditionalImpl(
  const ClassMetadata *sourceType,
  const ClassMetadata *targetType,
  const char *filename,
  unsigned line, unsigned column)
{
  // FIXME: Actually compare CFTypeIDs, once they arae available in
  // the metadata.
  return sourceType;
}

#if SWIFT_OBJC_INTEROP
// Given a non-nil object reference, return true iff the object uses
// native swift reference counting.
static bool usesNativeSwiftReferenceCounting_nonNull(
  const void* object
) {
  assert(object != nullptr);
  return !isObjCTaggedPointer(object) &&
    objectUsesNativeSwiftReferenceCounting(object);
}
#endif

bool swift::swift_isUniquelyReferenced_nonNull_native(const HeapObject *object){
  assert(object != nullptr);
  assert(!object->refCounts.isDeiniting());
  return object->refCounts.isUniquelyReferenced();
}

bool swift::swift_isUniquelyReferenced_native(const HeapObject* object) {
  return object != nullptr
    && swift::swift_isUniquelyReferenced_nonNull_native(object);
}

bool swift::swift_isUniquelyReferencedNonObjC_nonNull(const void* object) {
  assert(object != nullptr);
  return
#if SWIFT_OBJC_INTEROP
    usesNativeSwiftReferenceCounting_nonNull(object) &&
#endif
    swift_isUniquelyReferenced_nonNull_native((const HeapObject*)object);
}

// Given an object reference, return true iff it is non-nil and refers
// to a native swift object with strong reference count of 1.
bool swift::swift_isUniquelyReferencedNonObjC(
  const void* object
) {
  return object != nullptr
    && swift_isUniquelyReferencedNonObjC_nonNull(object);
}

/// Return true if the given bits of a Builtin.BridgeObject refer to a
/// native swift object whose strong reference count is 1.
bool swift::swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject(
  uintptr_t bits
) {
  auto bridgeObject = (void*)bits;

  if (isObjCTaggedPointer(bridgeObject))
    return false;

  const auto object = toPlainObject_unTagged_bridgeObject(bridgeObject);

  // Note: we could just return false if all spare bits are set,
  // but in that case the cost of a deeper check for a unique native
  // object is going to be a negligible cost for a possible big win.
#if SWIFT_OBJC_INTEROP
  return !isNonNative_unTagged_bridgeObject(bridgeObject)
             ? swift_isUniquelyReferenced_nonNull_native(
                   (const HeapObject *)object)
             : swift_isUniquelyReferencedNonObjC_nonNull(object);
#else
  return swift_isUniquelyReferenced_nonNull_native((const HeapObject *)object);
#endif
}

// Given a non-@objc object reference, return true iff the
// object is non-nil and has a strong reference count greather than 1
bool swift::swift_isEscapingClosureAtFileLocation(const HeapObject *object,
                                                  const unsigned char *filename,
                                                  int32_t filenameLength,
                                                  int32_t line, int32_t column,
                                                  unsigned verifcationType) {
  assert((verifcationType == 0 || verifcationType == 1) &&
         "Unknown verifcation type");

  bool isEscaping =
      object != nullptr && !object->refCounts.isUniquelyReferenced();

  // Print a message if the closure escaped.
  if (isEscaping) {
    auto *message = (verifcationType == 0)
                        ? "closure argument was escaped in "
                          "withoutActuallyEscaping block"
                        : "closure argument passed as @noescape "
                          "to Objective-C has escaped";
    auto messageLength = strlen(message);

    char *log;
    swift_asprintf(
        &log, "%.*s: file %.*s, line %" PRIu32 ", column %" PRIu32 " \n",
        messageLength, message, filenameLength, filename, line, column);

    printCurrentBacktrace(2/*framesToSkip*/);

    if (_swift_shouldReportFatalErrorsToDebugger()) {
      RuntimeErrorDetails details = {
          .version = RuntimeErrorDetails::currentVersion,
          .errorType = "escaping-closure-violation",
          .currentStackDescription = "Closure has escaped",
          .framesToSkip = 1,
      };
      _swift_reportToDebugger(RuntimeErrorFlagFatal, log, &details);
    }

    swift_reportError(RuntimeErrorFlagFatal, log);
    free(log);
  }
  return isEscaping;
}

struct ClassExtents {
  size_t negative;
  size_t positive; 
};

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
ClassExtents
_swift_getSwiftClassInstanceExtents(const Metadata *c) {
  assert(c && c->isClassObject());
  auto metaData = c->getClassObject();
  return ClassExtents{
    metaData->getInstanceAddressPoint(),
    metaData->getInstanceSize() - metaData->getInstanceAddressPoint()
  };
}

#if SWIFT_OBJC_INTEROP

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
ClassExtents
_swift_getObjCClassInstanceExtents(const ClassMetadata* c) {
  // Pure ObjC classes never have negative extents.
  if (c->isPureObjC())
    return ClassExtents{0, class_getInstanceSize(class_const_cast(c))};

  return _swift_getSwiftClassInstanceExtents(c);
}

SWIFT_CC(swift)
SWIFT_RUNTIME_EXPORT
void swift_objc_swift3ImplicitObjCEntrypoint(id self, SEL selector,
                                             const char *filename,
                                             size_t filenameLength,
                                             size_t line, size_t column,
                                             std::atomic<bool> *didLog) {
  // Only log once. We should have been given a unique zero-initialized
  // atomic flag for each entry point.
  if (didLog->exchange(true))
    return;
  
  // Figure out how much reporting we want by querying the environment
  // variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT. We have four meaningful
  // levels:
  //
  //   0: Don't report anything
  //   1: Complain about uses of implicit @objc entrypoints.
  //   2: Complain about uses of implicit @objc entrypoints, with backtraces
  //      if possible.
  //   3: Complain about uses of implicit @objc entrypoints, then abort().
  //
  // The actual reportLevel is stored as the above values +1, so that
  // 0 indicates we have not yet checked. It's fine to race through here.
  //
  // The default, if SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT is not set, is 2.
  static int storedReportLevel = 0;
  if (storedReportLevel == 0) {
    auto reportLevelStr = getenv("SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT");
    if (reportLevelStr &&
        reportLevelStr[0] >= '0' && reportLevelStr[0] <= '3' &&
        reportLevelStr[1] == 0)
      storedReportLevel = (reportLevelStr[0] - '0') + 1;
    else
      storedReportLevel = 3;
  }

  int reportLevel = storedReportLevel - 1;
  if (reportLevel < 1) return;

  // Report the error.
  uint32_t flags = 0;
  if (reportLevel >= 2)
    flags |= 1 << 0; // Backtrace
  bool isInstanceMethod = !class_isMetaClass(object_getClass(self));
  void (*reporter)(uint32_t, const char *, ...) =
    reportLevel > 2 ? swift::fatalError : swift::warning;
  
  if (filenameLength > INT_MAX)
    filenameLength = INT_MAX;

  char *message, *nullTerminatedFilename;
  asprintf(&message,
           "implicit Objective-C entrypoint %c[%s %s] is deprecated and will "
           "be removed in Swift 4",
           isInstanceMethod ? '-' : '+',
           class_getName([self class]),
           sel_getName(selector));
  asprintf(&nullTerminatedFilename, "%*s", (int)filenameLength, filename);

  RuntimeErrorDetails::FixIt fixit = {
    .filename = nullTerminatedFilename,
    .startLine = line,
    .endLine = line,
    .startColumn = column,
    .endColumn = column,
    .replacementText = "@objc "
  };
  RuntimeErrorDetails::Note note = {
    .description = "add '@objc' to expose this Swift declaration to Objective-C",
    .numFixIts = 1,
    .fixIts = &fixit
  };
  RuntimeErrorDetails details = {
    .version = RuntimeErrorDetails::currentVersion,
    .errorType = "implicit-objc-entrypoint",
    .framesToSkip = 1,
    .numNotes = 1,
    .notes = &note
  };
  uintptr_t runtime_error_flags = RuntimeErrorFlagNone;
  if (reporter == swift::fatalError)
    runtime_error_flags = RuntimeErrorFlagFatal;
  _swift_reportToDebugger(runtime_error_flags, message, &details);

  reporter(flags,
           "*** %s:%zu:%zu: %s; add explicit '@objc' to the declaration to "
           "emit the Objective-C entrypoint in Swift 4 and suppress this "
           "message\n",
           nullTerminatedFilename, line, column, message);
  free(message);
  free(nullTerminatedFilename);
}

#endif

const ClassMetadata *swift::getRootSuperclass() {
#if SWIFT_OBJC_INTEROP
  static Lazy<const ClassMetadata *> SwiftObjectClass;

  return SwiftObjectClass.get([](void *ptr) {
    *((const ClassMetadata **) ptr) =
        (const ClassMetadata *)[SwiftObject class];
  });
#else
  return nullptr;
#endif
}

#define OVERRIDE_OBJC COMPATIBILITY_OVERRIDE
#include "CompatibilityOverride.def"

#define OVERRIDE_FOREIGN COMPATIBILITY_OVERRIDE
#include "CompatibilityOverride.def"
