//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Reflection.h"
#include "swift/Runtime/Config.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/Enum.h"
#include "swift/Runtime/Unreachable.h"
#include "swift/Basic/Demangle.h"
#include "swift/Runtime/Debug.h"
#include "swift/Runtime/Portability.h"
#include "Private.h"
#include "WeakReference.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstdio>
#include <cstring>
#include <new>
#include <string>
#include <tuple>

#if SWIFT_OBJC_INTEROP
#include "swift/Runtime/ObjCBridge.h"
#include <Foundation/Foundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#endif

using namespace swift;

#if SWIFT_OBJC_INTEROP
// Declare the debugQuickLookObject selector.
@interface DeclareSelectors

- (id)debugQuickLookObject;
@end

@class SwiftObject;
#endif

namespace {

/// The layout of Any.
using Any = OpaqueExistentialContainer;

// Swift assumes Any is returned in memory.
// Use AnyReturn to guarantee that even on architectures
// where Any would be returned in registers.
struct AnyReturn {
  Any any;
  AnyReturn(Any a) : any(a) { }
  operator Any() { return any; }
  ~AnyReturn() { }
};

struct MagicMirrorData;

struct String;

SWIFT_CC(swift)
extern "C" void swift_stringFromUTF8InRawMemory(String *out,
                                                const char *start,
                                                intptr_t len);

struct String {
  // Keep the details of String's implementation opaque to the runtime.
  const void *x, *y, *z;

  /// Keep String trivial on the C++ side so we can control its instantiation.
  String() = default;

  /// Wrap a string literal in a swift String.
  template<size_t N>
  explicit String(const char (&s)[N]) {
    swift_stringFromUTF8InRawMemory(this, s, N-1);
  }

  /// Copy an ASCII string into a swift String on the heap.
  explicit String(const char *ptr, size_t size) {
    swift_stringFromUTF8InRawMemory(this, ptr, size);
  }

  explicit String(const char *ptr)
    : String(ptr, strlen(ptr))
  {}

#if SWIFT_OBJC_INTEROP
  explicit String(NSString *s)
    // FIXME: Use the usual NSString bridging entry point.
    : String([s UTF8String])
  {}
#endif
};

/// A Mirror witness table for use by MagicMirror.
struct MirrorWitnessTable;

// This structure needs to mirror _MagicMirrorData in the stdlib.
struct MagicMirrorData {
  /// The owner pointer for the buffer the value lives in. For class values
  /// this is the class instance itself. The mirror owns a strong reference to
  /// this object.
  HeapObject *Owner;
  /// The pointer to the value. The mirror does not own the referenced value.
  const OpaqueValue *Value;
  /// The type metadata for the referenced value. For an ObjC witness, this is
  /// the ObjC class.
  const Metadata *Type;
};
static_assert(sizeof(MagicMirrorData) == sizeof(ValueBuffer),
              "MagicMirrorData doesn't exactly fill a ValueBuffer");

/// A magic implementation of Mirror that can use runtime metadata to walk an
/// arbitrary object.
///
/// This type is layout-compatible with a Swift existential container for the
/// _Mirror protocol.
class MagicMirror {
public:
  // The data for the mirror.
  MagicMirrorData Data;

  // The existential header.
  const Metadata *Self;
  const MirrorWitnessTable *MirrorWitness;

  MagicMirror() = default;

  /// Build a new MagicMirror for type T by taking ownership of the referenced
  /// value.
  MagicMirror(OpaqueValue *value, const Metadata *T, bool take);

  /// Build a new MagicMirror for type T, sharing ownership with an existing
  /// heap object, which is retained.
  MagicMirror(HeapObject *owner, const OpaqueValue *value, const Metadata *T);
};

static_assert(alignof(MagicMirror) == alignof(Mirror),
              "MagicMirror layout does not match existential container");
static_assert(sizeof(MagicMirror) == sizeof(Mirror),
              "MagicMirror layout does not match existential container");
static_assert(offsetof(MagicMirror, Data) == offsetof(OpaqueExistentialContainer, Buffer),
              "MagicMirror layout does not match existential container");
static_assert(offsetof(MagicMirror, Self) == offsetof(OpaqueExistentialContainer, Type),
              "MagicMirror layout does not match existential container");
static_assert(offsetof(MagicMirror, MirrorWitness) ==
              offsetof(Mirror, MirrorWitness),
              "MagicMirror layout does not match existential container");

// -- Build an Any from an arbitrary value unowned-referenced by a mirror.

// We intentionally use a non-POD return type with these entry points to give
// them an indirect return ABI for compatibility with Swift.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"


SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
AnyReturn swift_MagicMirrorData_value(HeapObject *owner,
                                      const OpaqueValue *value,
                                      const Metadata *type) {
  Any result;

  result.Type = type;
  type->vw_initializeBufferWithCopy(&result.Buffer,
                                    const_cast<OpaqueValue*>(value));

  return AnyReturn(result);
}
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
const Metadata *swift_MagicMirrorData_valueType(HeapObject *owner,
                                                const OpaqueValue *value,
                                                const Metadata *type) {
  return swift_getDynamicType(const_cast<OpaqueValue*>(value), type,
                              /*existential metatype*/ true);
}

#if SWIFT_OBJC_INTEROP
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
AnyReturn swift_MagicMirrorData_objcValue(HeapObject *owner,
                                          const OpaqueValue *value,
                                          const Metadata *type) {
  Any result;

  void *object = *reinterpret_cast<void * const *>(value);
  auto isa = _swift_getClass(object);
  result.Type = swift_getObjCClassMetadata(isa);
  swift_unknownRetain(object);
  *reinterpret_cast<void **>(&result.Buffer) = object;
  return AnyReturn(result);
}
#endif

#pragma clang diagnostic pop

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
const char *swift_OpaqueSummary(const Metadata *T) {
  switch (T->getKind()) {
    case MetadataKind::Class:
    case MetadataKind::Struct:
    case MetadataKind::Enum:
    case MetadataKind::Optional:
    case MetadataKind::Metatype:
      return nullptr;
    case MetadataKind::Opaque:
      return "(Opaque Value)";
    case MetadataKind::Tuple:
      return "(Tuple)";
    case MetadataKind::Function:
      return "(Function)";
    case MetadataKind::Existential:
      return "(Existential)";
    case MetadataKind::ObjCClassWrapper:
      return "(Objective-C Class Wrapper)";
    case MetadataKind::ExistentialMetatype:
      return "(Existential Metatype)";
    case MetadataKind::ForeignClass:
      return "(Foreign Class)";
    case MetadataKind::HeapLocalVariable:
      return "(Heap Local Variable)";
    case MetadataKind::HeapGenericLocalVariable:
      return "(Heap Generic Local Variable)";
    case MetadataKind::ErrorObject:
      return "(ErrorType Object)";
  }
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_MagicMirrorData_summary(const Metadata *T, String *result) {
  switch (T->getKind()) {
    case MetadataKind::Class:
      new (result) String("(Class)");
      break;
    case MetadataKind::Struct:
      new (result) String("(Struct)");
      break;
    case MetadataKind::Enum:
    case MetadataKind::Optional:
      new (result) String("(Enum Value)");
      break;
    case MetadataKind::Opaque:
      new (result) String("(Opaque Value)");
      break;
    case MetadataKind::Tuple:
      new (result) String("(Tuple)");
      break;
    case MetadataKind::Function:
      new (result) String("(Function)");
      break;
    case MetadataKind::Existential:
      new (result) String("(Existential)");
      break;
    case MetadataKind::Metatype:
      new (result) String("(Metatype)");
      break;
    case MetadataKind::ObjCClassWrapper:
      new (result) String("(Objective-C Class Wrapper)");
      break;
    case MetadataKind::ExistentialMetatype:
      new (result) String("(ExistentialMetatype)");
      break;
    case MetadataKind::ForeignClass:
      new (result) String("(Foreign Class)");
      break;
    case MetadataKind::HeapLocalVariable:
      new (result) String("(Heap Local Variable)");
      break;
    case MetadataKind::HeapGenericLocalVariable:
      new (result) String("(Heap Generic Local Variable)");
      break;
    case MetadataKind::ErrorObject:
      new (result) String("(Error Object)");
      break;
  }
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
const Metadata *swift_MagicMirrorData_objcValueType(HeapObject *owner,
                                                    const OpaqueValue *value,
                                                    const Metadata *type) {
  void *object = *reinterpret_cast<void * const *>(value);
  auto isa = _swift_getClass(object);
  return swift_getObjCClassMetadata(isa);
}

static std::tuple<const Metadata *, const OpaqueValue *>
unwrapExistential(const Metadata *T, const OpaqueValue *Value) {
  // If the value is an existential container, look through it to reflect the
  // contained value.
  // TODO: Should look through existential metatypes too, but it doesn't
  // really matter yet since we don't have any special mirror behavior for
  // concrete metatypes yet.
  while (T->getKind() == MetadataKind::Existential) {
    auto existential
      = static_cast<const ExistentialTypeMetadata *>(T);

    // Unwrap the existential container.
    T = existential->getDynamicType(Value);
    Value = existential->projectValue(Value);

    // Existential containers can end up nested in some cases due to generic
    // abstraction barriers.  Repeat in case we have a nested existential.
  }
  return std::make_tuple(T, Value);
}

/// Produce a mirror for any value, like swift_reflectAny, but do not consume
/// the value, so we can produce a mirror for a subobject of a value already
/// owned by a mirror.
///
/// \param owner passed at +1, consumed.
/// \param value passed unowned.
static Mirror reflect(HeapObject *owner,
                      const OpaqueValue *value,
                      const Metadata *T) {
  const Metadata *mirrorType;
  const OpaqueValue *mirrorValue;
  std::tie(mirrorType, mirrorValue) = unwrapExistential(T, value);

  // Use MagicMirror.
  // Consumes 'owner'.
  Mirror result;
  ::new (&result) MagicMirror(owner, mirrorValue, mirrorType);
  return result;
}

// -- Tuple destructuring.

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
intptr_t swift_TupleMirror_count(HeapObject *owner,
                                 const OpaqueValue *value,
                                 const Metadata *type) {
  auto Tuple = static_cast<const TupleTypeMetadata *>(type);
  swift_release(owner);
  return Tuple->NumElements;
}

/// \param owner passed at +1, consumed.
/// \param value passed unowned.
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_TupleMirror_subscript(String *outString,
                                 Mirror *outMirror,
                                 intptr_t i,
                                 HeapObject *owner,
                                 const OpaqueValue *value,
                                 const Metadata *type) {
  auto Tuple = static_cast<const TupleTypeMetadata *>(type);

  if (i < 0 || (size_t)i > Tuple->NumElements)
    swift::crash("Swift mirror subscript bounds check failure");

  // Determine whether there is a label.
  bool hasLabel = false;
  if (const char *labels = Tuple->Labels) {
    const char *space = strchr(labels, ' ');
    for (intptr_t j = 0; j != i && space; ++j) {
      labels = space + 1;
      space = strchr(labels, ' ');
    }

    // If we have a label, create it.
    if (labels && space && labels != space) {
      new (outString) String(labels, space - labels);
      hasLabel = true;
    }
  }

  if (!hasLabel) {
    // The name is the stringized element number '.0'.
    char buf[32];
    snprintf(buf, sizeof(buf), ".%zd", i);
    new (outString) String(buf, strlen(buf));
  }

  // Get a Mirror for the nth element.
  auto &elt = Tuple->getElement(i);
  auto bytes = reinterpret_cast<const char*>(value);
  auto eltData = reinterpret_cast<const OpaqueValue *>(bytes + elt.Offset);

  // 'owner' is consumed by this call.
  new (outMirror) Mirror(reflect(owner, eltData, elt.Type));
}

// Get a field name from a doubly-null-terminated list.
static const char *getFieldName(const char *fieldNames, size_t i) {
  const char *fieldName = fieldNames;
  for (size_t j = 0; j < i; ++j) {
    size_t len = strlen(fieldName);
    assert(len != 0);
    fieldName += len + 1;
  }

  return fieldName;
}


static bool loadSpecialReferenceStorage(HeapObject *owner,
                                        OpaqueValue *fieldData,
                                        const FieldType fieldType,
                                        Mirror *outMirror) {
  // isWeak() implies a reference type via Sema.
  if (!fieldType.isWeak())
    return false;

  auto type = fieldType.getType();
  assert(type->getKind() == MetadataKind::Optional);

  auto weakField = reinterpret_cast<WeakReference *>(fieldData);
  auto strongValue = swift_unknownWeakLoadStrong(weakField);

  // Now that we have a strong reference, we need to create a temporary buffer
  // from which to copy the whole value, which might be a native class-bound
  // existential, which means we also need to copy n witness tables, for
  // however many protocols are in the protocol composition. For example, if we
  // are copying a:
  // weak var myWeakProperty : (Protocol1 & Protocol2)?
  // then we need to copy three values:
  // - the instance
  // - the witness table for Protocol1
  // - the witness table for Protocol2

  auto weakContainer =
    reinterpret_cast<WeakClassExistentialContainer *>(fieldData);

  // Create a temporary existential where we can put the strong reference.
  // The allocateBuffer value witness requires a ValueBuffer to own the
  // allocated storage.
  ValueBuffer temporaryBuffer;

  auto temporaryValue =
    reinterpret_cast<ClassExistentialContainer *>(
      type->vw_allocateBuffer(&temporaryBuffer));

  // Now copy the entire value out of the parent, which will include the
  // witness tables.
  temporaryValue->Value = strongValue;
  auto valueWitnessesSize = type->getValueWitnesses()->getSize() -
                            sizeof(WeakClassExistentialContainer);
  memcpy(temporaryValue->getWitnessTables(), weakContainer->getWitnessTables(),
         valueWitnessesSize);

  // This MagicMirror constructor creates a box to hold the loaded reference
  // value, which becomes the new owner for the value.
  new (outMirror) MagicMirror(reinterpret_cast<OpaqueValue *>(temporaryValue),
                              type, /*take*/ true);

  type->vw_deallocateBuffer(&temporaryBuffer);

  // swift_StructMirror_subscript and swift_ClassMirror_subscript
  // requires that the owner be consumed. Since we have the new heap box as the
  // owner now, we need to release the old owner to maintain the contract.
  if (owner->metadata->isAnyClass())
    swift_unknownRelease(owner);
  else
    swift_release(owner);

  return true;
}

// -- Struct destructuring.

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
intptr_t swift_StructMirror_count(HeapObject *owner,
                                  const OpaqueValue *value,
                                  const Metadata *type) {
  auto Struct = static_cast<const StructMetadata *>(type);
  swift_release(owner);
  return Struct->Description->Struct.NumFields;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_StructMirror_subscript(String *outString,
                                  Mirror *outMirror,
                                  intptr_t i,
                                  HeapObject *owner,
                                  OpaqueValue *value,
                                  const Metadata *type) {
  auto Struct = static_cast<const StructMetadata *>(type);

  if (i < 0 || (size_t)i > Struct->Description->Struct.NumFields)
    swift::crash("Swift mirror subscript bounds check failure");

  // Load the type and offset from their respective vectors.
  auto fieldType = Struct->getFieldTypes()[i];
  auto fieldOffset = Struct->getFieldOffsets()[i];

  auto bytes = reinterpret_cast<char*>(value);
  auto fieldData = reinterpret_cast<OpaqueValue *>(bytes + fieldOffset);

  new (outString) String(getFieldName(Struct->Description->Struct.FieldNames, i));

  // 'owner' is consumed by this call.
  assert(!fieldType.isIndirect() && "indirect struct fields not implemented");

  if (loadSpecialReferenceStorage(owner, fieldData, fieldType, outMirror))
    return;

  new (outMirror) Mirror(reflect(owner, fieldData, fieldType.getType()));
}

// -- Enum destructuring.

static bool isEnumReflectable(const Metadata *type) {
  const auto Enum = static_cast<const EnumMetadata *>(type);
  const auto &Description = Enum->Description->Enum;

  // No metadata for C and @objc enums yet
  if (Description.CaseNames == nullptr)
    return false;

  return true;
}

static void getEnumMirrorInfo(const OpaqueValue *value,
                              const Metadata *type,
                              unsigned *tagPtr,
                              const Metadata **payloadTypePtr,
                              bool *indirectPtr) {
  const auto Enum = static_cast<const EnumMetadata *>(type);
  const auto &Description = Enum->Description->Enum;

  unsigned payloadCases = Description.getNumPayloadCases();

  // 'tag' is in the range [-ElementsWithPayload..ElementsWithNoPayload-1].
  int tag = type->vw_getEnumTag(value);

  // Convert resilient tag index to fragile tag index.
  tag += payloadCases;

  const Metadata *payloadType = nullptr;
  bool indirect = false;

  if (static_cast<unsigned>(tag) < payloadCases) {
    auto payload = Description.GetCaseTypes(type)[tag];
    payloadType = payload.getType();
    indirect = payload.isIndirect();
  }

  if (tagPtr)
    *tagPtr = tag;
  if (payloadTypePtr)
    *payloadTypePtr = payloadType;
  if (indirectPtr)
    *indirectPtr = indirect;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
const char *swift_EnumMirror_caseName(HeapObject *owner,
                                      const OpaqueValue *value,
                                      const Metadata *type) {
  if (!isEnumReflectable(type)) {
    swift_release(owner);
    return nullptr;
  }

  const auto Enum = static_cast<const EnumMetadata *>(type);
  const auto &Description = Enum->Description->Enum;

  unsigned tag;
  getEnumMirrorInfo(value, type, &tag, nullptr, nullptr);

  swift_release(owner);

  return getFieldName(Description.CaseNames, tag);
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
const char *swift_EnumCaseName(OpaqueValue *value, const Metadata *type) {
  // Build a magic mirror. Unconditionally destroy the value at the end.
  const Metadata *mirrorType;
  const OpaqueValue *cMirrorValue;
  std::tie(mirrorType, cMirrorValue) = unwrapExistential(type, value);

  OpaqueValue *mirrorValue = const_cast<OpaqueValue*>(cMirrorValue);
  Mirror mirror;

  bool take = mirrorValue == value;
  ::new (&mirror) MagicMirror(mirrorValue, mirrorType, take);

  MagicMirror *theMirror = reinterpret_cast<MagicMirror *>(&mirror);
  MagicMirrorData data = theMirror->Data;
  const char *result = swift_EnumMirror_caseName(data.Owner, data.Value, data.Type);
  return result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
intptr_t swift_EnumMirror_count(HeapObject *owner,
                                const OpaqueValue *value,
                                const Metadata *type) {
  if (!isEnumReflectable(type)) {
    swift_release(owner);
    return 0;
  }

  const Metadata *payloadType;
  getEnumMirrorInfo(value, type, nullptr, &payloadType, nullptr);
  swift_release(owner);
  return (payloadType != nullptr) ? 1 : 0;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_EnumMirror_subscript(String *outString,
                                Mirror *outMirror,
                                intptr_t i,
                                HeapObject *owner,
                                const OpaqueValue *value,
                                const Metadata *type) {
  const auto Enum = static_cast<const EnumMetadata *>(type);
  const auto &Description = Enum->Description->Enum;

  unsigned tag;
  const Metadata *payloadType;
  bool indirect;

  getEnumMirrorInfo(value, type, &tag, &payloadType, &indirect);

  // Copy the enum payload into a box
  const Metadata *boxType = (indirect ? &METADATA_SYM(Bo).base : payloadType);
  BoxPair pair = swift_allocBox(boxType);

  type->vw_destructiveProjectEnumData(const_cast<OpaqueValue *>(value));
  boxType->vw_initializeWithCopy(pair.second, const_cast<OpaqueValue *>(value));
  type->vw_destructiveInjectEnumTag(const_cast<OpaqueValue *>(value),
                                    (int) (tag - Description.getNumPayloadCases()));

  swift_release(owner);

  owner = pair.first;
  value = pair.second;

  // If the payload is indirect, we need to jump through the box to get it.
  if (indirect) {
    owner = *reinterpret_cast<HeapObject * const *>(value);
    value = swift_projectBox(const_cast<HeapObject *>(owner));
    swift_retain(owner);
    swift_release(pair.first);
  }

  new (outString) String(getFieldName(Description.CaseNames, tag));
  new (outMirror) Mirror(reflect(owner, value, payloadType));
}

// -- Class destructuring.
static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
                                     HeapObject *owner,
                                     const OpaqueValue *value,
                                     const Metadata *type);

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
intptr_t swift_ClassMirror_count(HeapObject *owner,
                                 const OpaqueValue *value,
                                 const Metadata *type) {
  auto Clas = static_cast<const ClassMetadata*>(type);
  swift_release(owner);
  auto count = Clas->getDescription()->Class.NumFields;

  // If the class has a superclass, the superclass instance is treated as the
  // first child.
  if (classHasSuperclass(Clas))
    count += 1;

  return count;
}

/// \param owner passed at +1, consumed.
/// \param value passed unowned.
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_ClassMirror_subscript(String *outString,
                                 Mirror *outMirror,
                                 intptr_t i,
                                 HeapObject *owner,
                                 OpaqueValue *value,
                                 const Metadata *type) {
  auto Clas = static_cast<const ClassMetadata*>(type);

  if (classHasSuperclass(Clas)) {
    // If the class has a superclass, the superclass instance is treated as the
    // first child.
    if (i == 0) {
      // FIXME: Put superclass name here
      new (outString) String("super");
      new (outMirror) Mirror(
        getMirrorForSuperclass(Clas->SuperClass, owner, value, type));
      return;
    }
    --i;
  }

  if (i < 0 || (size_t)i > Clas->getDescription()->Class.NumFields)
    swift::crash("Swift mirror subscript bounds check failure");

  // Load the type and offset from their respective vectors.
  auto fieldType = Clas->getFieldTypes()[i];
  assert(!fieldType.isIndirect()
         && "class indirect properties not implemented");

  // FIXME: If the class has ObjC heritage, get the field offset using the ObjC
  // metadata, because we don't update the field offsets in the face of
  // resilient base classes.
  uintptr_t fieldOffset;
  if (usesNativeSwiftReferenceCounting(Clas)) {
    fieldOffset = Clas->getFieldOffsets()[i];
  } else {
#if SWIFT_OBJC_INTEROP
    Ivar *ivars = class_copyIvarList((Class)Clas, nullptr);
    fieldOffset = ivar_getOffset(ivars[i]);
    free(ivars);
#else
    swift::crash("Object appears to be Objective-C, but no runtime.");
#endif
  }

  auto bytes = *reinterpret_cast<char * const *>(value);
  auto fieldData = reinterpret_cast<OpaqueValue *>(bytes + fieldOffset);

  new (outString) String(getFieldName(Clas->getDescription()->Class.FieldNames,
                                      i));

 if (loadSpecialReferenceStorage(owner, fieldData, fieldType, outMirror))
   return;

  // 'owner' is consumed by this call.
  new (outMirror) Mirror(reflect(owner, fieldData, fieldType.getType()));
}

// -- Mirror witnesses for ObjC classes.

#if SWIFT_OBJC_INTEROP

extern "C" const Metadata METADATA_SYM(Sb); // Bool
extern "C" const Metadata METADATA_SYM(Si); // Int
extern "C" const Metadata METADATA_SYM(Su); // UInt
extern "C" const Metadata METADATA_SYM(Sf); // Float
extern "C" const Metadata METADATA_SYM(Sd); // Double
extern "C" const Metadata STRUCT_METADATA_SYM(s4Int8);
extern "C" const Metadata STRUCT_METADATA_SYM(s5Int16);
extern "C" const Metadata STRUCT_METADATA_SYM(s5Int32);
extern "C" const Metadata STRUCT_METADATA_SYM(s5Int64);
extern "C" const Metadata STRUCT_METADATA_SYM(s5UInt8);
extern "C" const Metadata STRUCT_METADATA_SYM(s6UInt16);
extern "C" const Metadata STRUCT_METADATA_SYM(s6UInt32);
extern "C" const Metadata STRUCT_METADATA_SYM(s6UInt64);

// Set to 1 to enable reflection of objc ivars.
#define REFLECT_OBJC_IVARS 0

/// Map an ObjC type encoding string to a Swift type metadata object.
///
#if REFLECT_OBJC_IVARS
static const Metadata *getMetadataForEncoding(const char *encoding) {
  switch (*encoding) {
  case 'c': // char
    return &STRUCT_METADATA_SYM(s4Int8);
  case 's': // short
    return &STRUCT_METADATA_SYM(s5Int16);
  case 'i': // int
    return &STRUCT_METADATA_SYM(s5Int32);
  case 'l': // long
    return &METADATA_SYM(Si);
  case 'q': // long long
    return &STRUCT_METADATA_SYM(s5Int64);

  case 'C': // unsigned char
    return &STRUCT_METADATA_SYM(s5UInt8);
  case 'S': // unsigned short
    return &STRUCT_METADATA_SYM(s6UInt16);
  case 'I': // unsigned int
    return &STRUCT_METADATA_SYM(s6UInt32);
  case 'L': // unsigned long
    return &METADATA_SYM(Su);
  case 'Q': // unsigned long long
    return &STRUCT_METADATA_SYM(s6UInt64);

  case 'B': // _Bool
    return &METADATA_SYM(Sb);

  case '@': { // Class
    // TODO: Better metadata?
    const OpaqueMetadata *M = &METADATA_SYM(BO);
    return &M->base;
  }

  default: // TODO
    // Return 'void' as the type of fields we don't understand.
    return &METADATA_SYM(EMPTY_TUPLE_MANGLING);
  }
}
#endif

/// \param owner passed at +1, consumed.
/// \param value passed unowned.
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
intptr_t swift_ObjCMirror_count(HeapObject *owner,
                                const OpaqueValue *value,
                                const Metadata *type) {
  auto isa = (Class)type;

  unsigned count = 0;
#if REFLECT_OBJC_IVARS
  // Don't reflect ivars of classes that lie about their layout.
  if (objcClassLiesAboutLayout(isa)) {
    count = 0;
  } else {
    // Copying the ivar list just to free it is lame, but we have
    // nowhere to save it.
    Ivar *ivars = class_copyIvarList(isa, &count);
    free(ivars);
  }
#else
  // ObjC makes no guarantees about the state of ivars, so we can't safely
  // introspect them in the general case.

  // The superobject counts as a child.
  if (_swift_getSuperclass((const ClassMetadata*) isa))
    count += 1;

  swift_release(owner);
  return count;
#endif
}

static Mirror ObjC_getMirrorForSuperclass(Class sup,
                                          HeapObject *owner,
                                          const OpaqueValue *value,
                                          const Metadata *type);

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_ObjCMirror_subscript(String *outString,
                                Mirror *outMirror,
                                intptr_t i,
                                HeapObject *owner,
                                const OpaqueValue *value,
                                const Metadata *type) {
#if REFLECT_OBJC_IVARS
  id object = *reinterpret_cast<const id *>(value);
#endif
  auto isa = (Class)type;

  // If there's a superclass, it becomes the first child.
  if (auto sup = (Class) _swift_getSuperclass((const ClassMetadata*) isa)) {
    if (i == 0) {
      const char *supName = class_getName(sup);
      new (outString) String(supName, strlen(supName));
      new (outMirror) Mirror(
                        ObjC_getMirrorForSuperclass(sup, owner, value, type));
      return;
    }
    --i;
  }

#if REFLECT_OBJC_IVARS
  // Copying the ivar list just to free it is lame, but we have
  // no room to save it.
  unsigned count;
  Ivar *ivars;
  // Don't reflect ivars of classes that lie about their layout.
  if (objcClassLiesAboutLayout(isa)) {
    count = 0;
    ivars = nullptr;
  } else {
    // Copying the ivar list just to free it is lame, but we have
    // nowhere to save it.
    ivars = class_copyIvarList(isa, &count);
  }

  if (i < 0 || (uintptr_t)i >= (uintptr_t)count)
    swift::crash("Swift mirror subscript bounds check failure");

  const char *name = ivar_getName(ivars[i]);
  ptrdiff_t offset = ivar_getOffset(ivars[i]);
  const char *typeEncoding = ivar_getTypeEncoding(ivars[i]);
  free(ivars);

  const OpaqueValue *ivar =
    reinterpret_cast<const OpaqueValue *>(
    reinterpret_cast<const char*>(object) + offset);

  const Metadata *ivarType = getMetadataForEncoding(typeEncoding);

  new (outString) String(name, strlen(name));
  // 'owner' is consumed by this call.
  new (outMirror) Mirror(reflect(owner, ivar, ivarType));
#else
  // ObjC makes no guarantees about the state of ivars, so we can't safely
  // introspect them in the general case.
  abort();
#endif
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
id
swift_ClassMirror_quickLookObject(HeapObject *owner, const OpaqueValue *value,
                                  const Metadata *type) {
  id object = [*reinterpret_cast<const id *>(value) retain];
  swift_release(owner);
  if ([object respondsToSelector:@selector(debugQuickLookObject)]) {
    id quickLookObject = [object debugQuickLookObject];
    [quickLookObject retain];
    [object release];
    return quickLookObject;
  }

  return object;
}

#endif

// -- MagicMirror implementation.

#define MIRROR_CONFORMANCE_SYM(Mirror, Subst) \
  SELECT_MANGLING(WPV##Mirror##s7_Mirrors , Mirror##Vs01_##Subst##0sWP)
#define OBJC_MIRROR_CONFORMANCE_SYM() \
  SELECT_MANGLING(WPVs11_ObjCMirrors7_Mirrors, s11_ObjCMirrorVs7_MirrorsWP)

// Addresses of the type metadata and Mirror witness tables for the primitive
// mirrors.
typedef const Metadata *(*MetadataFn)();

extern "C" Metadata *OpaqueMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s13_OpaqueMirror)));
extern "C" const MirrorWitnessTable OpaqueMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s13_OpaqueMirror, B)));
extern "C" Metadata *TupleMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s12_TupleMirror)));
extern "C" const MirrorWitnessTable TupleMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s12_TupleMirror, B)));

extern "C" Metadata *StructMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s13_StructMirror)));
extern "C" const MirrorWitnessTable StructMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s13_StructMirror, B)));

extern "C" Metadata *EnumMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s11_EnumMirror)));
extern "C" const MirrorWitnessTable EnumMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s11_EnumMirror, B)));

extern "C" Metadata *ClassMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s12_ClassMirror)));
extern "C" const MirrorWitnessTable ClassMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s12_ClassMirror, B)));

extern "C" Metadata *ClassSuperMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s17_ClassSuperMirror)));
extern "C" const MirrorWitnessTable ClassSuperMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s17_ClassSuperMirror, C)));

extern "C" Metadata *MetatypeMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s15_MetatypeMirror)));
extern "C" const MirrorWitnessTable MetatypeMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s15_MetatypeMirror, B)));

#if SWIFT_OBJC_INTEROP
extern "C" Metadata *ObjCMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s11_ObjCMirror)));
extern "C" const MirrorWitnessTable ObjCMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(OBJC_MIRROR_CONFORMANCE_SYM()));
extern "C" Metadata *ObjCSuperMirrorMetadata()
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(STRUCT_MD_ACCESSOR_SYM(s16_ObjCSuperMirror)));
extern "C" const MirrorWitnessTable ObjCSuperMirrorWitnessTable
  __asm__(SWIFT_QUOTED_SYMBOL_NAME(MIRROR_CONFORMANCE_SYM(s16_ObjCSuperMirror, C)));
#endif

/// \param owner passed at +1, consumed.
/// \param value passed unowned.
static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
                                     HeapObject *owner,
                                     const OpaqueValue *value,
                                     const Metadata *type) {
#if SWIFT_OBJC_INTEROP
  // If the superclass is natively ObjC, cut over to the ObjC mirror
  // implementation.
  if (!sup->isTypeMetadata())
    return ObjC_getMirrorForSuperclass((Class)sup, owner, value, type);
#endif

  Mirror resultBuf;
  MagicMirror *result = ::new (&resultBuf) MagicMirror;

  result->Self = ClassSuperMirrorMetadata();
  result->MirrorWitness = &ClassSuperMirrorWitnessTable;
  result->Data.Owner = owner;
  result->Data.Type = sup;
  result->Data.Value = value;

  return resultBuf;
}

#if SWIFT_OBJC_INTEROP
/// \param owner passed at +1, consumed.
/// \param value passed unowned.
static Mirror ObjC_getMirrorForSuperclass(Class sup,
                                          HeapObject *owner,
                                          const OpaqueValue *value,
                                          const Metadata *type) {
  Mirror resultBuf;
  MagicMirror *result = ::new (&resultBuf) MagicMirror;

  result->Self = ObjCSuperMirrorMetadata();
  result->MirrorWitness = &ObjCSuperMirrorWitnessTable;
  result->Data.Owner = owner;
  result->Data.Type = reinterpret_cast<ClassMetadata*>(sup);
  result->Data.Value = value;
  return resultBuf;
}
#endif

// (type being mirrored, mirror type, mirror witness)
using MirrorTriple
  = std::tuple<const Metadata *, const Metadata *, const MirrorWitnessTable *>;

static MirrorTriple
getImplementationForClass(const OpaqueValue *Value) {
  // Get the runtime type of the object.
  const void *obj = *reinterpret_cast<const void * const *>(Value);
  auto isa = _swift_getClass(obj);

  // Look through artificial subclasses.
  while (isa->isTypeMetadata() && isa->isArtificialSubclass()) {
    isa = isa->SuperClass;
  }

#if SWIFT_OBJC_INTEROP
  // If this is a pure ObjC class, reflect it using ObjC's runtime facilities.
  if (!isa->isTypeMetadata())
    return {isa, ObjCMirrorMetadata(), &ObjCMirrorWitnessTable};
#endif

  // Otherwise, use the native Swift facilities.
  return std::make_tuple(
      isa, ClassMirrorMetadata(), &ClassMirrorWitnessTable);
}

/// Get the magic mirror witnesses appropriate to a particular type.
static MirrorTriple
getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
  switch (T->getKind()) {
  case MetadataKind::Tuple:
    return std::make_tuple(
        T, TupleMirrorMetadata(), &TupleMirrorWitnessTable);

  case MetadataKind::Struct:
    return std::make_tuple(
        T, StructMirrorMetadata(), &StructMirrorWitnessTable);

  case MetadataKind::Enum:
  case MetadataKind::Optional:
    return std::make_tuple(
        T, EnumMirrorMetadata(), &EnumMirrorWitnessTable);

  case MetadataKind::ObjCClassWrapper:
  case MetadataKind::ForeignClass:
  case MetadataKind::Class: {
    return getImplementationForClass(Value);
  }

  case MetadataKind::Metatype:
  case MetadataKind::ExistentialMetatype: {
    return std::make_tuple(T, MetatypeMirrorMetadata(),
                           &MetatypeMirrorWitnessTable);
  }

  case MetadataKind::Opaque: {
#if SWIFT_OBJC_INTEROP
    // If this is the Builtin.UnknownObject type, use the dynamic type of the
    // object reference.
    if (T == &METADATA_SYM(BO).base) {
      return getImplementationForClass(Value);
    }
#endif
    // If this is the Builtin.NativeObject type, and the heap object is a
    // class instance, use the dynamic type of the object reference.
    if (T == &METADATA_SYM(Bo).base) {
      const HeapObject *obj
        = *reinterpret_cast<const HeapObject * const*>(Value);
      if (obj->metadata->getKind() == MetadataKind::Class)
        return getImplementationForClass(Value);
    }
    LLVM_FALLTHROUGH;
  }

  /// TODO: Implement specialized mirror witnesses for all kinds.
  case MetadataKind::Function:
  case MetadataKind::Existential:
    return std::make_tuple(
        T, OpaqueMirrorMetadata(), &OpaqueMirrorWitnessTable);

  // Types can't have these kinds.
  case MetadataKind::HeapLocalVariable:
  case MetadataKind::HeapGenericLocalVariable:
  case MetadataKind::ErrorObject:
    swift::crash("Swift mirror lookup failure");
  }

  swift_runtime_unreachable("Unhandled MetadataKind in switch.");
}

/// MagicMirror ownership-taking whole-value constructor.
///
/// \param owner passed at +1, consumed.
MagicMirror::MagicMirror(OpaqueValue *value, const Metadata *T,
                         bool take) {
  // Put value types into a box so we can take stable interior pointers.
  // TODO: Specialize behavior here. If the value is a swift-refcounted class
  // we don't need to put it in a box to point into it.
  BoxPair box = swift_allocBox(T);

  if (take)
    T->vw_initializeWithTake(box.second, value);
  else
    T->vw_initializeWithCopy(box.second, value);
  std::tie(T, Self, MirrorWitness) = getImplementationForType(T, box.second);

  Data = {box.first, box.second, T};
}

/// MagicMirror ownership-sharing subvalue constructor.
///
/// \param owner passed at +1, consumed.
MagicMirror::MagicMirror(HeapObject *owner,
                         const OpaqueValue *value, const Metadata *T) {
  std::tie(T, Self, MirrorWitness) = getImplementationForType(T, value);
  Data = {owner, value, T};
}

} // end anonymous namespace

/// func reflect<T>(x: T) -> Mirror
///
/// Produce a mirror for any value.  The runtime produces a mirror that
/// structurally reflects values of any type.
///
/// This function consumes 'value', following Swift's +1 convention for "in"
/// arguments.
SWIFT_CC(swift)
MirrorReturn swift::swift_reflectAny(OpaqueValue *value, const Metadata *T) {
  const Metadata *mirrorType;
  const OpaqueValue *cMirrorValue;
  std::tie(mirrorType, cMirrorValue) = unwrapExistential(T, value);

  OpaqueValue *mirrorValue = const_cast<OpaqueValue*>(cMirrorValue);

  // Use MagicMirror.
  Mirror result;
  // Take the value, unless we projected a subvalue from it. We don't want to
  // deal with partial value deinitialization.
  bool take = mirrorValue == value;
  ::new (&result) MagicMirror(mirrorValue, mirrorType, take);
  // Destroy the whole original value if we couldn't take it.
  if (!take)
    T->vw_destroy(value);
  return MirrorReturn(result);
}

// NB: This function is not used directly in the Swift codebase, but is
// exported for Xcode support and is used by the sanitizers. Please coordinate
// before changing.
//
/// Demangles a Swift symbol name.
///
/// \param mangledName is the symbol name that needs to be demangled.
/// \param mangledNameLength is the length of the string that should be
/// demangled.
/// \param outputBuffer is the user provided buffer where the demangled name
/// will be placed. If nullptr, a new buffer will be malloced. In that case,
/// the user of this API is responsible for freeing the returned buffer.
/// \param outputBufferSize is the size of the output buffer. If the demangled
/// name does not fit into the outputBuffer, the output will be truncated and
/// the size will be updated, indicating how large the buffer should be.
/// \param flags can be used to select the demangling style. TODO: We should
//// define what these will be.
/// \returns the demangled name. Returns nullptr if the input String is not a
/// Swift mangled name.
SWIFT_RUNTIME_EXPORT
char *swift_demangle(const char *mangledName,
                     size_t mangledNameLength,
                     char *outputBuffer,
                     size_t *outputBufferSize,
                     uint32_t flags) {
  if (flags != 0) {
    swift::fatalError(0, "Only 'flags' value of '0' is currently supported.");
  }
  if (outputBuffer != nullptr && outputBufferSize == nullptr) {
    swift::fatalError(0, "'outputBuffer' is passed but the size is 'nullptr'.");
  }

  // Check if we are dealing with Swift mangled name, otherwise, don't try
  // to demangle and send indication to the user.
  if (mangledName[0] != '_' || mangledName[1] != 'T') {
    return nullptr;
  }

  // Demangle the name.
  auto options = Demangle::DemangleOptions();
  options.DisplayDebuggerGeneratedModule = false;
  auto result =
      Demangle::demangleSymbolAsString(mangledName,
                                       mangledNameLength,
                                       options);

  // If the output buffer is not provided, malloc memory ourselves.
  if (outputBuffer == nullptr || *outputBufferSize == 0) {
    return strdup(result.c_str());
  }

  // Indicate a failure if the result does not fit and will be truncated
  // and set the required outputBufferSize.
  if (*outputBufferSize < result.length() + 1) {
    *outputBufferSize = result.length() + 1;
  }

  // Copy into the provided buffer.
  _swift_strlcpy(outputBuffer, result.c_str(), *outputBufferSize);
  return outputBuffer;
}
