//===--- MetadataLayout.h - Type metadata layout ----------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Information recording the layout of type metadata objects.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_METADATALAYOUT_H
#define SWIFT_IRGEN_METADATALAYOUT_H

#include "IRGen.h"
#include "swift/SIL/SILDeclRef.h"

namespace swift {
class ClassDecl;
class EnumDecl;
class StructDecl;
class VarDecl;

namespace irgen {
class Address;
class IRGenFunction;
class IRGenModule;

/// The total size and address point of a metadata object.
struct MetadataSize {
  Size FullSize;
  Size AddressPoint;

  /// Return the offset from the address point to the end of the
  /// metadata object.
  Size getOffsetToEnd() const {
    return FullSize - AddressPoint;
  }
};

/// A base class for various kinds of metadata layout.
class MetadataLayout {
public:
  enum class Kind {
    Class,
    Struct,
    Enum,
    ForeignClass,
  };

  class StoredOffset {
  public:
    enum Kind {
      /// The high bits are an integer displacement.
      Static = 0,

      /// The high bits are an integer displacement relative to a offset stored
      /// in a class metadata base offset global variable. This is used to
      /// access members of class metadata where the superclass is resilient to
      /// us, and therefore has an unknown size.
      Dynamic,
    };

  private:
    enum : uint64_t {
      KindBits = 1,
      KindMask = (1 << KindBits) - 1,
      PayloadMask = ~uint64_t(KindMask)
    };

    mutable uintptr_t Data;
  public:
    StoredOffset() : Data(0) {}
    explicit StoredOffset(Size offset, Kind kind)
      : Data((static_cast<uint64_t>(offset.getValue()) << KindBits) | kind) {
      assert(kind == Kind::Dynamic || !offset.isZero() &&
             "cannot store a zero static offset");
      if (kind == Kind::Static)
        assert(getStaticOffset() == offset && "overflow");
      if (kind == Kind::Dynamic)
        assert(getRelativeOffset() == offset && "overflow");
    }

    bool isValid() const { return Data != 0; }
    bool isStatic() const { return isValid() && (Data & KindMask) == Static; }
    bool isDynamic() const { return (Data & KindMask) == Dynamic; }

    /// If this is a metadata offset into a resilient class, returns the offset
    /// relative to the size of the superclass metadata.
    Size getRelativeOffset() const {
      assert(isDynamic());
      return Size(static_cast<int64_t>(Data) >> KindBits);
    }

    /// Returns the offset relative to start of metadata. Only used for
    /// metadata fields whose offset is completely known at compile time.
    Size getStaticOffset() const {
      assert(isStatic());
      return Size(static_cast<int64_t>(Data) >> KindBits);
    }
  };

private:
  Kind TheKind;

protected:
  MetadataSize TheSize;

  MetadataLayout(Kind theKind) : TheKind(theKind) {}

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

public:
  /// Destruct and deallocate this layout object.
  void destroy() const;

  Kind getKind() const { return TheKind; }

  MetadataSize getSize() const { return TheSize; }
};

/// Base class for nominal type metadata layouts.
class NominalMetadataLayout : public MetadataLayout {
protected:
  NominalTypeDecl *Nominal;
  StoredOffset GenericRequirements;

  NominalMetadataLayout(Kind kind, NominalTypeDecl *nominal)
      : MetadataLayout(kind), Nominal(nominal) {}

  Offset emitOffset(IRGenFunction &IGF, StoredOffset offset) const;

public:
  NominalTypeDecl *getDecl() const {
    return Nominal;
  }

  bool hasGenericRequirements() const {
    return GenericRequirements.isValid();
  }

  /// Should only be used when emitting the nominal type descriptor.
  Size getStaticGenericRequirementsOffset() const;

  Offset getGenericRequirementsOffset(IRGenFunction &IGF) const;

  static bool classof(const MetadataLayout *layout) {
    switch (layout->getKind()) {
    case MetadataLayout::Kind::Class:
    case MetadataLayout::Kind::Enum:
    case MetadataLayout::Kind::Struct:
      return true;

    case MetadataLayout::Kind::ForeignClass:
      return false;
    }
    llvm_unreachable("unhandled kind");
  }
};

/// Layout for class type metadata.
class ClassMetadataLayout : public NominalMetadataLayout {
public:
  class MethodInfo {
    Offset TheOffset;
  public:
    MethodInfo(Offset offset)
      : TheOffset(offset) {}
    Offset getOffset() const { return TheOffset; }
  };

private:
  bool HasResilientSuperclass = false;

  StoredOffset StartOfImmediateMembers;

  StoredOffset MetadataSize;
  StoredOffset MetadataAddressPoint;

  StoredOffset InstanceSize;
  StoredOffset InstanceAlignMask;

  struct StoredMethodInfo {
    StoredOffset TheOffset;
    StoredMethodInfo(StoredOffset offset) : TheOffset(offset) {}
  };
  llvm::DenseMap<SILDeclRef, StoredMethodInfo> MethodInfos;

  /// Field offsets for various fields.
  llvm::DenseMap<VarDecl*, StoredOffset> FieldOffsets;

  /// The start of the vtable.
  StoredOffset VTableOffset;

  /// The start of the field-offset vector.
  StoredOffset FieldOffsetVector;

  /// The number of members to add after superclass metadata.
  unsigned NumImmediateMembers;

  const StoredMethodInfo &getStoredMethodInfo(SILDeclRef method) const {
    auto it = MethodInfos.find(method);
    assert(it != MethodInfos.end());
    return it->second;
  }

  const StoredOffset &getStoredFieldOffset(VarDecl *field) const {
    auto it = FieldOffsets.find(field);
    assert(it != FieldOffsets.end());
    return it->second;
  }

  friend class IRGenModule;
  ClassMetadataLayout(IRGenModule &IGM, ClassDecl *theClass);

public:
  ClassDecl *getDecl() const {
    return cast<ClassDecl>(Nominal);
  }

  bool hasResilientSuperclass() const {
    return HasResilientSuperclass;
  }

  constexpr static bool areImmediateMembersNegative() {
    return false;
  }

  Size getMetadataSizeOffset() const;

  Size getMetadataAddressPointOffset() const;

  Size getInstanceSizeOffset() const;

  Size getInstanceAlignMaskOffset() const;

  MethodInfo getMethodInfo(IRGenFunction &IGF, SILDeclRef method) const;

  Offset getFieldOffset(IRGenFunction &IGF, VarDecl *field) const;

  /// Assuming that the given field offset is at a static offset in
  /// the metadata, return that static offset.
  ///
  /// DEPRECATED: callers should be updated to handle this in a
  /// more arbitrary fashion.
  Size getStaticFieldOffset(VarDecl *field) const;

  /// Should only be used when emitting the nominal type descriptor.
  Size getRelativeGenericRequirementsOffset() const;

  Size getStaticFieldOffsetVectorOffset() const;
  Size getRelativeFieldOffsetVectorOffset() const;

  Size getStaticVTableOffset() const;
  Size getRelativeVTableOffset() const;

  Offset getFieldOffsetVectorOffset(IRGenFunction &IGF) const;

  /// If the start of the immediate members is statically known, this
  /// method will return it. Otherwise, it will assert.
  Size getStartOfImmediateMembers() const {
    return StartOfImmediateMembers.getStaticOffset();
  }

  /// The number of members to add after superclass metadata. The size of
  /// this metadata is the superclass size plus the number of immediate
  /// members in the class itself.
  unsigned getNumImmediateMembers() const {
    return NumImmediateMembers;
  }

  static bool classof(const MetadataLayout *layout) {
    return layout->getKind() == Kind::Class;
  }
};

/// Layout for enum type metadata.
class EnumMetadataLayout : public NominalMetadataLayout {
  /// The offset of the payload size field, if there is one.
  StoredOffset PayloadSizeOffset;

  // TODO: presumably it would be useful to store *something* here
  // for resilience.

  friend class IRGenModule;
  EnumMetadataLayout(IRGenModule &IGM, EnumDecl *theEnum);

public:
  EnumDecl *getDecl() const {
    return cast<EnumDecl>(Nominal);
  }

  bool hasPayloadSizeOffset() const {
    return PayloadSizeOffset.isValid();
  }

  Offset getPayloadSizeOffset() const;

  static bool classof(const MetadataLayout *layout) {
    return layout->getKind() == Kind::Enum;
  }
};

/// Layout for struct type metadata.
class StructMetadataLayout : public NominalMetadataLayout {
  llvm::DenseMap<VarDecl*, StoredOffset> FieldOffsets;

  /// The start of the field-offset vector.
  StoredOffset FieldOffsetVector;

  const StoredOffset &getStoredFieldOffset(VarDecl *field) const {
    auto it = FieldOffsets.find(field);
    assert(it != FieldOffsets.end());
    return it->second;
  }

  friend class IRGenModule;
  StructMetadataLayout(IRGenModule &IGM, StructDecl *theStruct);

public:
  StructDecl *getDecl() const {
    return cast<StructDecl>(Nominal);
  }

  Offset getFieldOffset(IRGenFunction &IGF, VarDecl *field) const;

  /// Assuming that the given field offset is at a static offset in
  /// the metadata, return that static offset.
  ///
  /// DEPRECATED: callers should be updated to handle this in a
  /// more arbitrary fashion.
  Size getStaticFieldOffset(VarDecl *field) const;

  Offset getFieldOffsetVectorOffset() const;

  static bool classof(const MetadataLayout *layout) {
    return layout->getKind() == Kind::Struct;
  }
};

/// Layout for foreign class type metadata.
class ForeignClassMetadataLayout : public MetadataLayout {
  ClassDecl *Class;
  StoredOffset SuperClassOffset;

  friend class IRGenModule;
  ForeignClassMetadataLayout(IRGenModule &IGM, ClassDecl *theClass);

public:
  StoredOffset getSuperClassOffset() const { return SuperClassOffset; }

  static bool classof(const MetadataLayout *layout) {
    return layout->getKind() == Kind::ForeignClass;
  }
};

/// Emit the address of the field-offset slot in the given class metadata.
Address emitAddressOfClassFieldOffset(IRGenFunction &IGF,
                                      llvm::Value *metadata,
                                      ClassDecl *theClass,
                                      VarDecl *field);

/// Get the offset to a field offset in the class type metadata.
///
/// DEPRECATED: callers should be updated to handle this in a more
/// arbitrary fashion.
Size getClassFieldOffsetOffset(IRGenModule &IGM,
                               ClassDecl *theClass,
                               VarDecl *field);

/// Emit the address of the field-offset vector in the given class or struct
/// metadata.
Address emitAddressOfFieldOffsetVector(IRGenFunction &IGF,
                                       llvm::Value *metadata,
                                       NominalTypeDecl *theDecl);

/// Given a reference to class type metadata of the given type,
/// decide the offset to the given field.  This assumes that the
/// offset is stored in the metadata, i.e. its offset is potentially
/// dependent on generic arguments.  The result is a ptrdiff_t.
llvm::Value *emitClassFieldOffset(IRGenFunction &IGF,
                                  ClassDecl *theClass,
                                  VarDecl *field,
                                  llvm::Value *metadata);

/// Given a class metadata pointer, emit the address of its superclass field.  
Address emitAddressOfSuperclassRefInClassMetadata(IRGenFunction &IGF,
                                                  llvm::Value *metadata);

} // end namespace irgen
} // end namespace swift

#endif
