//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
#define CLANG_CODEGEN_CGRECORDLAYOUT_H

#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/DerivedTypes.h"

namespace llvm {
  class StructType;
}

namespace clang {
namespace CodeGen {

/// \brief Helper object for describing how to generate the code for access to a
/// bit-field.
///
/// This structure is intended to describe the "policy" of how the bit-field
/// should be accessed, which may be target, language, or ABI dependent.
class CGBitFieldInfo {
public:
  /// Descriptor for a single component of a bit-field access. The entire
  /// bit-field is constituted of a bitwise OR of all of the individual
  /// components.
  ///
  /// Each component describes an accessed value, which is how the component
  /// should be transferred to/from memory, and a target placement, which is how
  /// that component fits into the constituted bit-field. The pseudo-IR for a
  /// load is:
  ///
  ///   %0 = gep %base, 0, FieldIndex
  ///   %1 = gep (i8*) %0, FieldByteOffset
  ///   %2 = (i(AccessWidth) *) %1
  ///   %3 = load %2, align AccessAlignment
  ///   %4 = shr %3, FieldBitStart
  ///
  /// and the composed bit-field is formed as the boolean OR of all accesses,
  /// masked to TargetBitWidth bits and shifted to TargetBitOffset.
  struct AccessInfo {
    /// Offset of the field to load in the LLVM structure, if any.
    unsigned FieldIndex;

    /// Byte offset from the field address, if any. This should generally be
    /// unused as the cleanest IR comes from having a well-constructed LLVM type
    /// with proper GEP instructions, but sometimes its use is required, for
    /// example if an access is intended to straddle an LLVM field boundary.
    CharUnits FieldByteOffset;

    /// Bit offset in the accessed value to use. The width is implied by \see
    /// TargetBitWidth.
    unsigned FieldBitStart;

    /// Bit width of the memory access to perform.
    unsigned AccessWidth;

    /// The alignment of the memory access, or 0 if the default alignment should
    /// be used.
    //
    // FIXME: Remove use of 0 to encode default, instead have IRgen do the right
    // thing when it generates the code, if avoiding align directives is
    // desired.
    CharUnits AccessAlignment;

    /// Offset for the target value.
    unsigned TargetBitOffset;

    /// Number of bits in the access that are destined for the bit-field.
    unsigned TargetBitWidth;
  };

private:
  /// The components to use to access the bit-field. We may need up to three
  /// separate components to support up to i64 bit-field access (4 + 2 + 1 byte
  /// accesses).
  //
  // FIXME: De-hardcode this, just allocate following the struct.
  AccessInfo Components[3];

  /// The total size of the bit-field, in bits.
  unsigned Size;

  /// The number of access components to use.
  unsigned NumComponents;

  /// Whether the bit-field is signed.
  bool IsSigned : 1;

public:
  CGBitFieldInfo(unsigned Size, unsigned NumComponents, AccessInfo *_Components,
                 bool IsSigned) : Size(Size), NumComponents(NumComponents),
                                  IsSigned(IsSigned) {
    assert(NumComponents <= 3 && "invalid number of components!");
    for (unsigned i = 0; i != NumComponents; ++i)
      Components[i] = _Components[i];

    // Check some invariants.
    unsigned AccessedSize = 0;
    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
      const AccessInfo &AI = getComponent(i);
      AccessedSize += AI.TargetBitWidth;

      // We shouldn't try to load 0 bits.
      assert(AI.TargetBitWidth > 0);

      // We can't load more bits than we accessed.
      assert(AI.FieldBitStart + AI.TargetBitWidth <= AI.AccessWidth);

      // We shouldn't put any bits outside the result size.
      assert(AI.TargetBitWidth + AI.TargetBitOffset <= Size);
    }

    // Check that the total number of target bits matches the total bit-field
    // size.
    assert(AccessedSize == Size && "Total size does not match accessed size!");
  }

public:
  /// \brief Check whether this bit-field access is (i.e., should be sign
  /// extended on loads).
  bool isSigned() const { return IsSigned; }

  /// \brief Get the size of the bit-field, in bits.
  unsigned getSize() const { return Size; }

  /// @name Component Access
  /// @{

  unsigned getNumComponents() const { return NumComponents; }

  const AccessInfo &getComponent(unsigned Index) const {
    assert(Index < getNumComponents() && "Invalid access!");
    return Components[Index];
  }

  /// @}

  void print(raw_ostream &OS) const;
  void dump() const;

  /// \brief Given a bit-field decl, build an appropriate helper object for
  /// accessing that field (which is expected to have the given offset and
  /// size).
  static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, const FieldDecl *FD,
                                 uint64_t FieldOffset, uint64_t FieldSize);

  /// \brief Given a bit-field decl, build an appropriate helper object for
  /// accessing that field (which is expected to have the given offset and
  /// size). The field decl should be known to be contained within a type of at
  /// least the given size and with the given alignment.
  static CGBitFieldInfo MakeInfo(CodeGenTypes &Types, const FieldDecl *FD,
                                 uint64_t FieldOffset, uint64_t FieldSize,
                                 uint64_t ContainingTypeSizeInBits,
                                 unsigned ContainingTypeAlign);
};

/// CGRecordLayout - This class handles struct and union layout info while
/// lowering AST types to LLVM types.
///
/// These layout objects are only created on demand as IR generation requires.
class CGRecordLayout {
  friend class CodeGenTypes;

  CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT
  void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT

private:
  /// The LLVM type corresponding to this record layout; used when
  /// laying it out as a complete object.
  llvm::StructType *CompleteObjectType;

  /// The LLVM type for the non-virtual part of this record layout;
  /// used when laying it out as a base subobject.
  llvm::StructType *BaseSubobjectType;

  /// Map from (non-bit-field) struct field to the corresponding llvm struct
  /// type field no. This info is populated by record builder.
  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;

  /// Map from (bit-field) struct field to the corresponding llvm struct type
  /// field no. This info is populated by record builder.
  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;

  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
  // map for both virtual and non virtual bases.
  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;

  /// Map from virtual bases to their field index in the complete object.
  llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;

  /// False if any direct or indirect subobject of this class, when
  /// considered as a complete object, requires a non-zero bitpattern
  /// when zero-initialized.
  bool IsZeroInitializable : 1;

  /// False if any direct or indirect subobject of this class, when
  /// considered as a base subobject, requires a non-zero bitpattern
  /// when zero-initialized.
  bool IsZeroInitializableAsBase : 1;

public:
  CGRecordLayout(llvm::StructType *CompleteObjectType,
                 llvm::StructType *BaseSubobjectType,
                 bool IsZeroInitializable,
                 bool IsZeroInitializableAsBase)
    : CompleteObjectType(CompleteObjectType),
      BaseSubobjectType(BaseSubobjectType),
      IsZeroInitializable(IsZeroInitializable),
      IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}

  /// \brief Return the "complete object" LLVM type associated with
  /// this record.
  llvm::StructType *getLLVMType() const {
    return CompleteObjectType;
  }

  /// \brief Return the "base subobject" LLVM type associated with
  /// this record.
  llvm::StructType *getBaseSubobjectLLVMType() const {
    return BaseSubobjectType;
  }

  /// \brief Check whether this struct can be C++ zero-initialized
  /// with a zeroinitializer.
  bool isZeroInitializable() const {
    return IsZeroInitializable;
  }

  /// \brief Check whether this struct can be C++ zero-initialized
  /// with a zeroinitializer when considered as a base subobject.
  bool isZeroInitializableAsBase() const {
    return IsZeroInitializableAsBase;
  }

  /// \brief Return llvm::StructType element number that corresponds to the
  /// field FD.
  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
    assert(!FD->isBitField() && "Invalid call for bit-field decl!");
    assert(FieldInfo.count(FD) && "Invalid field for record!");
    return FieldInfo.lookup(FD);
  }

  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
    assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");
    return NonVirtualBases.lookup(RD);
  }

  /// \brief Return the LLVM field index corresponding to the given
  /// virtual base.  Only valid when operating on the complete object.
  unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {
    assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");
    return CompleteObjectVirtualBases.lookup(base);
  }

  /// \brief Return the BitFieldInfo that corresponds to the field FD.
  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
      it = BitFields.find(FD);
    assert(it != BitFields.end() && "Unable to find bitfield info");
    return it->second;
  }

  void print(raw_ostream &OS) const;
  void dump() const;
};

}  // end namespace CodeGen
}  // end namespace clang

#endif
