//===--- MetadataLayout.cpp - Metadata construct layout -------------------===//
//
// 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 file includes code for laying out type metadata.
// 
//  It also implements certain low-level access routines for type metadata.
//  These routines are generally declared in one of two different places:
//
//    - Mid-level routines to extract data from metadata are declared in
//      GenMeta.h.  This file is a sort of sub-module of GenMeta.cpp.
//
//    - Low-level routines to project the addresses of fields in metadata
//      are declared in MetadataLayout.h.
//
//===----------------------------------------------------------------------===//

#include "MetadataLayout.h"
#include "GenMeta.h"

#include "ClassMetadataVisitor.h"
#include "EnumMetadataVisitor.h"
#include "IRGenFunction.h"
#include "StructMetadataVisitor.h"
#include "ForeignClassMetadataVisitor.h"

#include "swift/Basic/LLVM.h"
#include "llvm/ADT/Optional.h"

using namespace swift;
using namespace irgen;

namespace {

template <class Impl, template <class> class Base>
class LayoutScanner : public Base<Impl> {
  Optional<Size> AddressPoint;

protected:
  Optional<Size> DynamicOffsetBase;

  template <class... As>
  LayoutScanner(As &&... args) : Base<Impl>(std::forward<As>(args)...) {}

public:
  using StoredOffset = MetadataLayout::StoredOffset;

  void noteAddressPoint() { AddressPoint = this->NextOffset; }
  StoredOffset getNextOffset() const {
    if (DynamicOffsetBase) {
      return StoredOffset(this->NextOffset - *DynamicOffsetBase,
                          StoredOffset::Dynamic);
    }

    return StoredOffset(this->NextOffset - *AddressPoint,
                        StoredOffset::Static);
  }

  Size getAddressPoint() const {
    return *AddressPoint;
  }

  MetadataSize getMetadataSize() const {
    assert(AddressPoint.hasValue() && !AddressPoint->isInvalid()
           && "did not find address point?!");
    assert(*AddressPoint < this->NextOffset
           && "address point is after end?!");
    return {this->NextOffset, *AddressPoint};
  }
};

}

ClassMetadataLayout &IRGenModule::getClassMetadataLayout(ClassDecl *decl) {
  assert(!decl->isForeign() && "Use getForeignMetadataLayout()");
  return cast<ClassMetadataLayout>(
                        getMetadataLayout(static_cast<NominalTypeDecl*>(decl)));
}

ForeignClassMetadataLayout &IRGenModule::getForeignMetadataLayout(
                                                          ClassDecl *decl) {
  assert(decl->isForeign() && "Use getMetadataLayout()");
  return cast<ForeignClassMetadataLayout>(
           getMetadataLayout(static_cast<NominalTypeDecl*>(decl)));
}

EnumMetadataLayout &IRGenModule::getMetadataLayout(EnumDecl *decl) {
  return cast<EnumMetadataLayout>(
                        getMetadataLayout(static_cast<NominalTypeDecl*>(decl)));
}

StructMetadataLayout &IRGenModule::getMetadataLayout(StructDecl *decl) {
  return cast<StructMetadataLayout>(
                        getMetadataLayout(static_cast<NominalTypeDecl*>(decl)));
}

NominalMetadataLayout &IRGenModule::getNominalMetadataLayout(
                                                    NominalTypeDecl *decl) {
  return cast<NominalMetadataLayout>(getMetadataLayout(decl));
}

MetadataLayout &IRGenModule::getMetadataLayout(NominalTypeDecl *decl) {
  auto &entry = MetadataLayouts[decl];
  if (!entry) {
    if (auto theClass = dyn_cast<ClassDecl>(decl)) {
      if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType)
        entry = new ForeignClassMetadataLayout(*this, theClass);
      else
        entry = new ClassMetadataLayout(*this, theClass);
    } else if (auto theEnum = dyn_cast<EnumDecl>(decl)) {
      entry = new EnumMetadataLayout(*this, theEnum);
    } else if (auto theStruct = dyn_cast<StructDecl>(decl)) {
      entry = new StructMetadataLayout(*this, theStruct);
    } else {
      llvm_unreachable("bad nominal type!");
    }
  }
  return *cast<MetadataLayout>(entry);
}

void IRGenModule::destroyMetadataLayoutMap() {
  for (auto &entry : MetadataLayouts) {
    entry.second->destroy();
  }
}

void MetadataLayout::destroy() const {
  switch (getKind()) {
  case Kind::Class:
    delete cast<ClassMetadataLayout>(this);
    return;

  case Kind::Struct:
    delete cast<StructMetadataLayout>(this);
    return;

  case Kind::Enum:
    delete cast<EnumMetadataLayout>(this);
    return;

  case Kind::ForeignClass:
    delete cast<ForeignClassMetadataLayout>(this);
    return;
  }
  llvm_unreachable("bad kind");
}

/******************************* NOMINAL TYPES ********************************/

Offset NominalMetadataLayout::emitOffset(IRGenFunction &IGF,
                                         StoredOffset offset) const {
  assert(offset.isValid());

  if (offset.isStatic())
    return Offset(offset.getStaticOffset());

  Address layoutAddr(
    IGF.IGM.getAddrOfClassMetadataBounds(cast<ClassDecl>(getDecl()),
                                         NotForDefinition),
    IGF.IGM.getPointerAlignment());

  auto offsetBaseAddr = IGF.Builder.CreateStructGEP(layoutAddr, 0, Size(0));

  // FIXME: Should this be an invariant load?
  llvm::Value *offsetVal = IGF.Builder.CreateLoad(offsetBaseAddr, "base");

  auto relativeOffset = offset.getRelativeOffset().getValue();
  if (relativeOffset != 0) {
    offsetVal = IGF.Builder.CreateAdd(offsetVal,
                                      llvm::ConstantInt::get(IGF.IGM.SizeTy,
                                                             relativeOffset));
  }

  return Offset(offsetVal);
}

Size
NominalMetadataLayout::getStaticGenericRequirementsOffset() const {
  return GenericRequirements.getStaticOffset();
}

Offset
NominalMetadataLayout::getGenericRequirementsOffset(IRGenFunction &IGF) const {
  return emitOffset(IGF, GenericRequirements);
}

static llvm::Value *emitLoadOfGenericRequirement(IRGenFunction &IGF,
                                                 llvm::Value *metadata,
                                                 NominalTypeDecl *decl,
                                                 unsigned reqtIndex,
                                                 llvm::Type *reqtTy) {
  auto offset =
    IGF.IGM.getNominalMetadataLayout(decl).getGenericRequirementsOffset(IGF);
  offset = offset.offsetBy(IGF, Size(reqtIndex * IGF.IGM.getPointerSize()));

  auto slot = IGF.emitAddressAtOffset(metadata, offset, reqtTy,
                                      IGF.IGM.getPointerAlignment());
  auto witness = IGF.emitInvariantLoad(slot);
  return witness;
}

/// Given a reference to nominal type metadata of the given type,
/// derive a reference to the nth argument metadata.  The type must
/// have generic arguments.
llvm::Value *irgen::emitArgumentMetadataRef(IRGenFunction &IGF,
                                            NominalTypeDecl *decl,
                                      const GenericTypeRequirements &reqts,
                                            unsigned reqtIndex,
                                            llvm::Value *metadata) {
  assert(reqts.getRequirements()[reqtIndex].Protocol == nullptr);
  return emitLoadOfGenericRequirement(IGF, metadata, decl, reqtIndex,
                                      IGF.IGM.TypeMetadataPtrTy);
}

/// Given a reference to nominal type metadata of the given type,
/// derive a reference to a protocol witness table for the nth
/// argument metadata.  The type must have generic arguments.
llvm::Value *irgen::emitArgumentWitnessTableRef(IRGenFunction &IGF,
                                                NominalTypeDecl *decl,
                                          const GenericTypeRequirements &reqts,
                                                unsigned reqtIndex,
                                                llvm::Value *metadata) {
  assert(reqts.getRequirements()[reqtIndex].Protocol != nullptr);
  return emitLoadOfGenericRequirement(IGF, metadata, decl, reqtIndex,
                                      IGF.IGM.WitnessTablePtrTy);
}

Address irgen::emitAddressOfFieldOffsetVector(IRGenFunction &IGF,
                                              llvm::Value *metadata,
                                              NominalTypeDecl *decl) {
  auto &layout = IGF.IGM.getMetadataLayout(decl);
  auto offset = [&]() {
    if (isa<ClassDecl>(decl)) {
      return cast<ClassMetadataLayout>(layout)
        .getFieldOffsetVectorOffset(IGF);
    } else {
      assert(isa<StructDecl>(decl));
      return cast<StructMetadataLayout>(layout)
        .getFieldOffsetVectorOffset();
    }
  }();

  auto *elementSize = IGF.IGM.SizeTy;
  if (isa<StructDecl>(decl))
    elementSize = IGF.IGM.Int32Ty;

  return IGF.emitAddressAtOffset(metadata, offset, elementSize,
                                 IGF.IGM.getPointerAlignment());
}

/********************************** CLASSES ***********************************/

ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
    : NominalMetadataLayout(Kind::Class, decl), NumImmediateMembers(0) {

  struct Scanner : LayoutScanner<Scanner, ClassMetadataScanner> {
    using super = LayoutScanner;

    ClassMetadataLayout &Layout;

    Scanner(IRGenModule &IGM, ClassDecl *decl, ClassMetadataLayout &layout)
      : super(IGM, decl), Layout(layout) {}

    void noteResilientSuperclass() {
      Layout.HasResilientSuperclass = true;
    }

    void noteStartOfImmediateMembers(ClassDecl *forClass) {
      // If our superclass is resilient to us, or the class itself is resilient
      // to us, we will access metadata members relative to a base offset.
      if (forClass == Target) {
        Layout.StartOfImmediateMembers = getNextOffset();

        if (Layout.HasResilientSuperclass ||
            IGM.hasResilientMetadata(forClass, ResilienceExpansion::Maximal)) {
          assert(!DynamicOffsetBase);
          DynamicOffsetBase = NextOffset;
        }
      }
    }

    void addClassSize() {
      Layout.MetadataSize = getNextOffset();
      super::addClassSize();
    }

    void addClassAddressPoint() {
      Layout.MetadataAddressPoint = getNextOffset();
      super::addClassAddressPoint();
    }

    void addInstanceSize() {
      Layout.InstanceSize = getNextOffset();
      super::addInstanceSize();
    }

    void addInstanceAlignMask() {
      Layout.InstanceAlignMask = getNextOffset();
      super::addInstanceAlignMask();
    }

    void noteStartOfGenericRequirements(ClassDecl *forClass) {
      if (forClass == Target)
        Layout.GenericRequirements = getNextOffset();
      super::noteStartOfGenericRequirements(forClass);
    }

    void addGenericWitnessTable(ClassDecl *forClass) {
      if (forClass == Target) {
        Layout.NumImmediateMembers++;
      }
      super::addGenericWitnessTable(forClass);
    }

    void addGenericArgument(ClassDecl *forClass) {
      if (forClass == Target) {
        Layout.NumImmediateMembers++;
      }
      super::addGenericArgument(forClass);
    }

    void addMethod(SILDeclRef fn) {
      if (fn.getDecl()->getDeclContext() == Target) {
        Layout.NumImmediateMembers++;
        Layout.MethodInfos.try_emplace(fn, getNextOffset());
      }
      super::addMethod(fn);
    }

    void noteStartOfFieldOffsets(ClassDecl *forClass) {
      if (forClass == Target)
        Layout.FieldOffsetVector = getNextOffset();
      super::noteStartOfFieldOffsets(forClass);
    }

    void addFieldOffset(VarDecl *field) {
      if (field->getDeclContext() == Target) {
        Layout.NumImmediateMembers++;
        Layout.FieldOffsets.try_emplace(field, getNextOffset());
      }
      super::addFieldOffset(field);
    }

    void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
      if (placeholder->getDeclContext() == Target) {
        Layout.NumImmediateMembers +=
          placeholder->getNumberOfFieldOffsetVectorEntries();
      }
      super::addFieldOffsetPlaceholders(placeholder);
    }

    void addVTableEntries(ClassDecl *forClass) {
      if (forClass == Target)
        Layout.VTableOffset = getNextOffset();
      super::addVTableEntries(forClass);
    }

    void layout() {
      super::layout();
      Layout.TheSize = getMetadataSize();
    }
  };

  Scanner(IGM, decl, *this).layout();
}

Size ClassMetadataLayout::getMetadataSizeOffset() const {
  assert(MetadataSize.isStatic());
  return MetadataSize.getStaticOffset();
}

Size ClassMetadataLayout::getMetadataAddressPointOffset() const {
  assert(MetadataAddressPoint.isStatic());
  return MetadataAddressPoint.getStaticOffset();
}

Size ClassMetadataLayout::getInstanceSizeOffset() const {
  assert(InstanceSize.isStatic());
  return InstanceSize.getStaticOffset();
}

Size ClassMetadataLayout::getInstanceAlignMaskOffset() const {
  assert(InstanceAlignMask.isStatic());
  return InstanceAlignMask.getStaticOffset();
}

ClassMetadataLayout::MethodInfo
ClassMetadataLayout::getMethodInfo(IRGenFunction &IGF, SILDeclRef method) const{
  auto &stored = getStoredMethodInfo(method);
  auto offset = emitOffset(IGF, stored.TheOffset);
  return MethodInfo(offset);
}

Offset ClassMetadataLayout::getFieldOffset(IRGenFunction &IGF,
                                           VarDecl *field) const {
  return emitOffset(IGF, getStoredFieldOffset(field));
}

Size ClassMetadataLayout::getStaticFieldOffset(VarDecl *field) const {
  auto &stored = getStoredFieldOffset(field);
  assert(stored.isStatic() && "resilient class metadata layout unsupported!");
  return stored.getStaticOffset();
}

Size
ClassMetadataLayout::getRelativeGenericRequirementsOffset() const {
  return GenericRequirements.getRelativeOffset();
}

Size
ClassMetadataLayout::getStaticFieldOffsetVectorOffset() const {
  return FieldOffsetVector.getStaticOffset();
}

Size
ClassMetadataLayout::getRelativeFieldOffsetVectorOffset() const {
  return FieldOffsetVector.getRelativeOffset();
}

Size
ClassMetadataLayout::getStaticVTableOffset() const {
  return VTableOffset.getStaticOffset();
}

Size
ClassMetadataLayout::getRelativeVTableOffset() const {
  return VTableOffset.getRelativeOffset();
}

Offset
ClassMetadataLayout::getFieldOffsetVectorOffset(IRGenFunction &IGF) const {
  return emitOffset(IGF, FieldOffsetVector);
}

Size irgen::getClassFieldOffsetOffset(IRGenModule &IGM, ClassDecl *theClass,
                                      VarDecl *field) {
  if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType)
    return Size();

  return IGM.getClassMetadataLayout(theClass).getStaticFieldOffset(field);
}

/// Given a reference to class metadata of the given type,
/// compute the field offset for a stored property.
/// The type must have dependent generic layout.
llvm::Value *irgen::emitClassFieldOffset(IRGenFunction &IGF,
                                         ClassDecl *theClass,
                                         VarDecl *field,
                                         llvm::Value *metadata) {
  auto slot = emitAddressOfClassFieldOffset(IGF, metadata, theClass, field);
  return IGF.emitInvariantLoad(slot);
}

Address irgen::emitAddressOfClassFieldOffset(IRGenFunction &IGF,
                                             llvm::Value *metadata,
                                             ClassDecl *theClass,
                                             VarDecl *field) {
  auto offset =
    IGF.IGM.getClassMetadataLayout(theClass).getFieldOffset(IGF, field);
  auto slot = IGF.emitAddressAtOffset(metadata, offset, IGF.IGM.SizeTy,
                                      IGF.IGM.getPointerAlignment());
  return slot;
}

Address irgen::emitAddressOfSuperclassRefInClassMetadata(IRGenFunction &IGF,
                                                         llvm::Value *metadata) {
  // The superclass field in a class type is the first field past the isa.
  unsigned index = 1;

  Address addr(metadata, IGF.IGM.getPointerAlignment());
  addr = IGF.Builder.CreateElementBitCast(addr, IGF.IGM.TypeMetadataPtrTy);
  return IGF.Builder.CreateConstArrayGEP(addr, index, IGF.IGM.getPointerSize());
}

/*********************************** ENUMS ************************************/

EnumMetadataLayout::EnumMetadataLayout(IRGenModule &IGM, EnumDecl *decl)
    : NominalMetadataLayout(Kind::Enum, decl) {

  struct Scanner : LayoutScanner<Scanner, EnumMetadataScanner> {
    using super = LayoutScanner;

    EnumMetadataLayout &Layout;
    Scanner(IRGenModule &IGM, EnumDecl *decl, EnumMetadataLayout &layout)
      : super(IGM, decl), Layout(layout) {}

    void noteStartOfTypeSpecificMembers() {
      assert(getNextOffset().getStaticOffset() ==
               IGM.getOffsetOfEnumTypeSpecificMetadataMembers());
    }

    void addPayloadSize() {
      Layout.PayloadSizeOffset = getNextOffset();
      super::addPayloadSize();
    }

    void noteStartOfGenericRequirements() {
      Layout.GenericRequirements = getNextOffset();
      super::noteStartOfGenericRequirements();
    }

    void layout() {
      super::layout();
      Layout.TheSize = getMetadataSize();
    }
  };

  Scanner(IGM, decl, *this).layout();
}

Offset
EnumMetadataLayout::getPayloadSizeOffset() const {
  assert(PayloadSizeOffset.isStatic());
  return Offset(PayloadSizeOffset.getStaticOffset());
}

/********************************** STRUCTS ***********************************/

StructMetadataLayout::StructMetadataLayout(IRGenModule &IGM, StructDecl *decl)
    : NominalMetadataLayout(Kind::Struct, decl) {

  struct Scanner : LayoutScanner<Scanner, StructMetadataScanner> {
    using super = LayoutScanner;

    StructMetadataLayout &Layout;
    Scanner(IRGenModule &IGM, StructDecl *decl, StructMetadataLayout &layout)
      : super(IGM, decl), Layout(layout) {}

    void noteStartOfTypeSpecificMembers() {
      assert(getNextOffset().getStaticOffset() ==
               IGM.getOffsetOfStructTypeSpecificMetadataMembers());
    }

    void noteStartOfGenericRequirements() {
      Layout.GenericRequirements = getNextOffset();
      super::noteStartOfGenericRequirements();
    }

    void noteStartOfFieldOffsets() {
      Layout.FieldOffsetVector = getNextOffset();
      super::noteStartOfFieldOffsets();
    }

    void addFieldOffset(VarDecl *field) {
      Layout.FieldOffsets.try_emplace(field, getNextOffset());
      super::addFieldOffset(field);
    }

    void noteEndOfFieldOffsets() {
      super::noteEndOfFieldOffsets();
    }

    void layout() {
      super::layout();
      Layout.TheSize = getMetadataSize();
    }
  };

  Scanner(IGM, decl, *this).layout();
}

Offset StructMetadataLayout::getFieldOffset(IRGenFunction &IGF,
                                            VarDecl *field) const {
  // TODO: implement resilient metadata layout
  return Offset(getStaticFieldOffset(field));
}
Size StructMetadataLayout::getStaticFieldOffset(VarDecl *field) const {
  auto &stored = getStoredFieldOffset(field);
  assert(stored.isStatic() && "resilient struct metadata layout unsupported!");
  return stored.getStaticOffset();
}

Offset
StructMetadataLayout::getFieldOffsetVectorOffset() const {
  assert(FieldOffsetVector.isStatic());
  return Offset(FieldOffsetVector.getStaticOffset());
}

/****************************** FOREIGN CLASSES *******************************/
ForeignClassMetadataLayout::ForeignClassMetadataLayout(IRGenModule &IGM,
                                                       ClassDecl *theClass)
    : MetadataLayout(Kind::ForeignClass), Class(theClass) {
  assert(theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
         "Not a foreign class");

  struct Scanner : LayoutScanner<Scanner, ForeignClassMetadataScanner> {
    using super = LayoutScanner;

    ForeignClassMetadataLayout &Layout;
    Scanner(IRGenModule &IGM, ClassDecl *decl,
            ForeignClassMetadataLayout &layout)
      : super(IGM, decl), Layout(layout) {}

    void addSuperclass() {
      Layout.SuperClassOffset = getNextOffset();
      super::addSuperclass();
    }

    void layout() {
      super::layout();
      Layout.TheSize = getMetadataSize();
    }
  };

  Scanner(IGM, theClass, *this).layout();

}
