//===-- LayoutConstraint.h - Layout constraints types and APIs --*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines types and APIs for layout constraints.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LAYOUT_CONSTRAINT_H
#define SWIFT_LAYOUT_CONSTRAINT_H

#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringRef.h"
#include "swift/AST/PrintOptions.h"

namespace swift {

enum class AllocationArena;
class ASTContext;
class ASTPrinter;

/// Describes a layout constraint information.
enum class LayoutConstraintKind : unsigned char {
  // It is not a known layout constraint.
  UnknownLayout,
  // It is a layout constraint representing a trivial type of an unknown size.
  TrivialOfExactSize,
  // It is a layout constraint representing a trivial type of an unknown size.
  TrivialOfAtMostSize,
  // It is a layout constraint representing a trivial type of an unknown size.
  Trivial,
  // It is a layout constraint representing a reference counted class instance.
  Class,
  // It is a layout constraint representing a reference counted native class
  // instance.
  NativeClass,
  // It is a layout constraint representing a reference counted object.
  RefCountedObject,
  // It is a layout constraint representing a native reference counted object.
  NativeRefCountedObject,
  LastLayout = NativeRefCountedObject,
};

/// This is a class representing the layout constraint.
class LayoutConstraintInfo : public llvm::FoldingSetNode {
  friend class LayoutConstraint;
  // Alignment of the layout in bytes.
  const unsigned Alignment : 16;
  // Size of the layout in bits.
  const unsigned SizeInBits : 24;
  // Kind of the layout.
  const LayoutConstraintKind Kind;

  LayoutConstraintInfo()
      : Alignment(0), SizeInBits(0), Kind(LayoutConstraintKind::UnknownLayout) {
  }

  LayoutConstraintInfo(const LayoutConstraintInfo &Layout)
      : Alignment(Layout.Alignment), SizeInBits(Layout.SizeInBits),
        Kind(Layout.Kind) {
  }

  LayoutConstraintInfo(LayoutConstraintKind Kind)
      : Alignment(0), SizeInBits(0), Kind(Kind) {
    assert(!isKnownSizeTrivial() && "Size in bits should be specified");
  }

  LayoutConstraintInfo(LayoutConstraintKind Kind, unsigned SizeInBits,
                       unsigned Alignment)
      : Alignment(Alignment), SizeInBits(SizeInBits), Kind(Kind) {
    assert(
        isTrivial() &&
        "Size in bits should be specified only for trivial layout constraints");
  }
  public:
  LayoutConstraintKind getKind() const { return Kind; }

  bool isKnownLayout() const {
    return isKnownLayout(Kind);
  }

  bool isFixedSizeTrivial() const {
    return isFixedSizeTrivial(Kind);
  }

  bool isKnownSizeTrivial() const {
    return isKnownSizeTrivial(Kind);
  }

  bool isAddressOnlyTrivial() const {
    return isAddressOnlyTrivial(Kind);
  }

  bool isTrivial() const {
    return isTrivial(Kind);
  }

  bool isRefCountedObject() const {
    return isRefCountedObject(Kind);
  }

  bool isNativeRefCountedObject() const {
    return isNativeRefCountedObject(Kind);
  }

  bool isClass() const {
    return isClass(Kind);
  }

  bool isNativeClass() const {
    return isNativeClass(Kind);
  }

  bool isRefCounted() const {
    return isRefCounted(Kind);
  }

  bool isNativeRefCounted() const {
    return isNativeRefCounted(Kind);
  }

  unsigned getTrivialSizeInBytes() const {
    assert(isKnownSizeTrivial());
    return (SizeInBits + 7) / 8;
  }

  unsigned getMaxTrivialSizeInBytes() const {
    assert(isKnownSizeTrivial());
    return (SizeInBits + 7) / 8;
  }

  unsigned getTrivialSizeInBits() const {
    assert(isKnownSizeTrivial());
    return SizeInBits;
  }

  unsigned getMaxTrivialSizeInBits() const {
    assert(isKnownSizeTrivial());
    return SizeInBits;
  }

  unsigned getAlignmentInBits() const {
    return Alignment;
  }

  unsigned getAlignmentInBytes() const {
    assert(isKnownSizeTrivial());
    if (Alignment)
      return Alignment;

    // There is no explicitly defined alignment. Try to come up with a
    // reasonable one.

    // If the size is a power of 2, use it also for the default alignment.
    auto SizeInBytes = getTrivialSizeInBytes();
    if (llvm::isPowerOf2_32(SizeInBytes))
      return SizeInBytes * 8;

    // Otherwise assume the alignment of 8 bytes.
    return 8*8;
  }

  operator bool() const {
    return isKnownLayout();
  }

  bool operator==(const LayoutConstraintInfo &rhs) const {
    return getKind() == rhs.getKind() && SizeInBits == rhs.SizeInBits &&
           Alignment == rhs.Alignment;
  }

  bool operator!=(LayoutConstraintInfo rhs) const { return !(*this == rhs); }

  void print(raw_ostream &OS, const PrintOptions &PO = PrintOptions()) const;
  void print(ASTPrinter &Printer, const PrintOptions &PO) const;

  /// Return the layout constraint as a string, for use in diagnostics only.
  std::string getString(const PrintOptions &PO = PrintOptions()) const;

  /// Return the name of this layout constraint.
  StringRef getName() const;

  /// Return the name of a layout constraint with a given kind.
  static StringRef getName(LayoutConstraintKind Kind);

  static bool isKnownLayout(LayoutConstraintKind Kind);

  static bool isFixedSizeTrivial(LayoutConstraintKind Kind);

  static bool isKnownSizeTrivial(LayoutConstraintKind Kind);

  static bool isAddressOnlyTrivial(LayoutConstraintKind Kind);

  static bool isTrivial(LayoutConstraintKind Kind);

  static bool isRefCountedObject(LayoutConstraintKind Kind);

  static bool isNativeRefCountedObject(LayoutConstraintKind Kind);

  static bool isAnyRefCountedObject(LayoutConstraintKind Kind);

  static bool isClass(LayoutConstraintKind Kind);

  static bool isNativeClass(LayoutConstraintKind Kind);

  static bool isRefCounted(LayoutConstraintKind Kind);

  static bool isNativeRefCounted(LayoutConstraintKind Kind);

  /// Uniquing for the LayoutConstraintInfo.
  void Profile(llvm::FoldingSetNodeID &ID) {
    Profile(ID, Kind, SizeInBits, Alignment);
  }

  static void Profile(llvm::FoldingSetNodeID &ID,
                      LayoutConstraintKind Kind,
                      unsigned SizeInBits,
                      unsigned Alignment);
  private:
  // Make vanilla new/delete illegal for LayoutConstraintInfo.
  void *operator new(size_t Bytes) throw() = delete;
  void operator delete(void *Data) throw() = delete;
  public:
  // Only allow allocation of LayoutConstraintInfo using the allocator in
  // ASTContext or by doing a placement new.
  void *operator new(size_t bytes, const ASTContext &ctx,
                     AllocationArena arena, unsigned alignment = 8);
  void *operator new(size_t Bytes, void *Mem) throw() { return Mem; }

  // Representation of the non-parameterized layouts.
  static LayoutConstraintInfo UnknownLayoutConstraintInfo;
  static LayoutConstraintInfo RefCountedObjectConstraintInfo;
  static LayoutConstraintInfo NativeRefCountedObjectConstraintInfo;
  static LayoutConstraintInfo ClassConstraintInfo;
  static LayoutConstraintInfo NativeClassConstraintInfo;
  static LayoutConstraintInfo TrivialConstraintInfo;
};

/// A wrapper class containing a reference to the actual LayoutConstraintInfo
/// object.
class LayoutConstraint {
  LayoutConstraintInfo *Ptr;
  public:
  /*implicit*/ LayoutConstraint(LayoutConstraintInfo *P = 0) : Ptr(P) {}

  static LayoutConstraint getLayoutConstraint(const LayoutConstraint &Layout,
                                              ASTContext &C);

  static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind,
                                              ASTContext &C);

  static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind);

  static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind,
                                              unsigned SizeInBits,
                                              unsigned Alignment,
                                              ASTContext &C);

  static LayoutConstraint getUnknownLayout();

  LayoutConstraintInfo *getPointer() const { return Ptr; }

  bool isNull() const { return Ptr == 0; }

  LayoutConstraintInfo *operator->() const { return Ptr; }

  /// Merge these two constraints and return a more specific one
  /// or fail if they're incompatible and return an unknown constraint.
  LayoutConstraint merge(LayoutConstraint Other);

  explicit operator bool() const { return Ptr != 0; }

  void dump() const;
  void dump(raw_ostream &os, unsigned indent = 0) const;

  void print(raw_ostream &OS, const PrintOptions &PO = PrintOptions()) const;
  void print(ASTPrinter &Printer, const PrintOptions &PO) const;

  /// Return the layout constraint as a string, for use in diagnostics only.
  std::string getString(const PrintOptions &PO = PrintOptions()) const;

  bool operator==(LayoutConstraint rhs) const {
    if (isNull() && rhs.isNull())
      return true;
    return *getPointer() == *rhs.getPointer();
  }

  bool operator!=(LayoutConstraint rhs) const {
    return !(*this == rhs);
  }
};

// Permit direct uses of isa/cast/dyn_cast on LayoutConstraint.
template <class X> inline bool isa(LayoutConstraint LC) {
  return isa<X>(LC.getPointer());
}
template <class X> inline X cast_or_null(LayoutConstraint LC) {
  return cast_or_null<X>(LC.getPointer());
}
template <class X> inline X dyn_cast(LayoutConstraint LC) {
  return dyn_cast<X>(LC.getPointer());
}
template <class X> inline X dyn_cast_or_null(LayoutConstraint LC) {
  return dyn_cast_or_null<X>(LC.getPointer());
}

/// LayoutConstraintLoc - Provides source location information for a
/// parsed layout constraint.
struct LayoutConstraintLoc {
private:
  LayoutConstraint Layout;
  SourceLoc Loc;

public:
  LayoutConstraintLoc(LayoutConstraint Layout, SourceLoc Loc)
      : Layout(Layout), Loc(Loc) {}

  bool isError() const;

  // FIXME: We generally shouldn't need to build LayoutConstraintLoc without
  // a location.
  static LayoutConstraintLoc withoutLoc(LayoutConstraint Layout) {
    return LayoutConstraintLoc(Layout, SourceLoc());
  }

  /// Get the representative location of this type, for diagnostic
  /// purposes.
  SourceLoc getLoc() const { return Loc; }

  SourceRange getSourceRange() const;

  bool hasLocation() const { return Loc.isValid(); }
  LayoutConstraint getLayoutConstraint() const { return Layout; }

  bool isNull() const { return Layout.isNull(); }

  LayoutConstraintLoc clone(ASTContext &ctx) const { return *this; }
};

/// Checks if ID is a name of a layout constraint and returns this
/// constraint. If ID does not match any known layout constraint names,
/// returns UnknownLayout.
LayoutConstraint getLayoutConstraint(Identifier ID, ASTContext &Ctx);

} // end namespace swift

LLVM_DECLARE_TYPE_ALIGNMENT(swift::LayoutConstraintInfo, swift::TypeAlignInBits)

namespace llvm {
static inline raw_ostream &
operator<<(raw_ostream &OS, swift::LayoutConstraint LC) {
  LC->print(OS);
  return OS;
}

// A LayoutConstraint casts like a LayoutConstraintInfo*.
template <> struct simplify_type<const ::swift::LayoutConstraint> {
  typedef ::swift::LayoutConstraintInfo *SimpleType;
  static SimpleType getSimplifiedValue(const ::swift::LayoutConstraint &Val) {
    return Val.getPointer();
  }
};

template <>
struct simplify_type<::swift::LayoutConstraint>
    : public simplify_type<const ::swift::LayoutConstraint> {};

// LayoutConstraint hashes just like pointers.
template <> struct DenseMapInfo<swift::LayoutConstraint> {
  static swift::LayoutConstraint getEmptyKey() {
    return llvm::DenseMapInfo<swift::LayoutConstraintInfo *>::getEmptyKey();
  }
  static swift::LayoutConstraint getTombstoneKey() {
    return llvm::DenseMapInfo<swift::LayoutConstraintInfo *>::getTombstoneKey();
  }
  static unsigned getHashValue(swift::LayoutConstraint Val) {
    return DenseMapInfo<swift::LayoutConstraintInfo *>::getHashValue(
        Val.getPointer());
  }
  static bool isEqual(swift::LayoutConstraint LHS,
                      swift::LayoutConstraint RHS) {
    return LHS.getPointer() == RHS.getPointer();
  }
};

// A LayoutConstraint is "pointer like".
template <> class PointerLikeTypeTraits<swift::LayoutConstraint> {
public:
  static inline void *getAsVoidPointer(swift::LayoutConstraint I) {
    return (void *)I.getPointer();
  }
  static inline swift::LayoutConstraint getFromVoidPointer(void *P) {
    return (swift::LayoutConstraintInfo *)P;
  }
  enum { NumLowBitsAvailable = swift::TypeAlignInBits };
};
} // end namespace llvm

#endif
