//===--- 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
    // Update NominalMetadataLayout::classof if you add a non-nominal layout.
  };

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

      /// The high bits are an llvm::Constant* for the displacement,
      /// which may be null if it hasn't been computed yet.
      Dynamic,
    };
    enum : uint64_t {
      KindBits = 1,
      KindMask = (1 << KindBits) - 1,
      PayloadMask = ~uint64_t(KindMask)
    };

    mutable uintptr_t Data;
  public:
    StoredOffset() : Data(0) {}
    explicit StoredOffset(llvm::Constant *offset)
      : Data(reinterpret_cast<uintptr_t>(offset) | Dynamic) {}
    explicit StoredOffset(Size offset)
      : Data((static_cast<uint64_t>(offset.getValue()) << KindBits) | Static) {
      assert(!offset.isZero() && "cannot store a zero offset");
      assert(getStaticOffset() == offset && "overflow");
    }

    bool isValid() const { return Data != 0; }
    bool isStatic() const { return isValid() && (Data & KindMask) == Static; }
    bool isDynamic() const { return (Data & KindMask) == Dynamic; }
    Size getStaticOffset() const {
      assert(isStatic());
      return Size(static_cast<int64_t>(Data) >> KindBits);
    }
    llvm::Constant *getDynamicOffsetVariable() const {
      assert(isDynamic());
      return reinterpret_cast<llvm::Constant*>(Data & PayloadMask);
    }
    void setDynamicOffsetVariable(llvm::Constant *pointer) const {
      assert(isDynamic());
      Data = reinterpret_cast<uintptr_t>(pointer) | Dynamic;
    }
  };

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:
  StoredOffset GenericRequirements;
  StoredOffset Parent;

  NominalMetadataLayout(Kind kind) : MetadataLayout(kind) {}

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

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

  Offset getGenericRequirementsOffset(IRGenFunction &IGF) const;

  Offset getParentOffset(IRGenFunction &IGF) const;

  static bool classof(const MetadataLayout *layout) {
    return true; // No non-nominal metadata for now.
  }
};

/// 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:
  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;

  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:
  Size getInstanceSizeOffset() const;

  Size getInstanceAlignMaskOffset() const;

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

  /// Returns the start of the vtable in the class metadata.
  Offset getVTableOffset(IRGenFunction &IGF) const;

  /// Returns the size of the vtable, in words.
  unsigned getVTableSize() const {
    return MethodInfos.size();
  }

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

  /// Assuming that the given method 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 getStaticMethodOffset(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 getStaticFieldOffsetVectorOffset() const;

  Offset getFieldOffsetVectorOffset(IRGenFunction &IGF) const;

  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:
  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:

  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;
  }
};

/// Emit the address of the 'parent' slot in the given nominal-type metadata.
Address emitAddressOfParentMetadataSlot(IRGenFunction &IGF,
                                        llvm::Value *metadata,
                                        NominalTypeDecl *decl);

/// 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);

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

#endif
