1206084Srdivacky//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===// 2206084Srdivacky// 3206084Srdivacky// The LLVM Compiler Infrastructure 4206084Srdivacky// 5206084Srdivacky// This file is distributed under the University of Illinois Open Source 6206084Srdivacky// License. See LICENSE.TXT for details. 7206084Srdivacky// 8206084Srdivacky//===----------------------------------------------------------------------===// 9206084Srdivacky 10206084Srdivacky#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H 11206084Srdivacky#define CLANG_CODEGEN_CGRECORDLAYOUT_H 12206084Srdivacky 13226633Sdim#include "clang/AST/CharUnits.h" 14226633Sdim#include "clang/AST/Decl.h" 15226633Sdim#include "clang/Basic/LLVM.h" 16206084Srdivacky#include "llvm/ADT/DenseMap.h" 17249423Sdim#include "llvm/IR/DerivedTypes.h" 18226633Sdim 19206084Srdivackynamespace llvm { 20218893Sdim class StructType; 21206084Srdivacky} 22206084Srdivacky 23206084Srdivackynamespace clang { 24206084Srdivackynamespace CodeGen { 25206084Srdivacky 26249423Sdim/// \brief Structure with information about how a bitfield should be accessed. 27207619Srdivacky/// 28249423Sdim/// Often we layout a sequence of bitfields as a contiguous sequence of bits. 29249423Sdim/// When the AST record layout does this, we represent it in the LLVM IR's type 30249423Sdim/// as either a sequence of i8 members or a byte array to reserve the number of 31249423Sdim/// bytes touched without forcing any particular alignment beyond the basic 32249423Sdim/// character alignment. 33249423Sdim/// 34249423Sdim/// Then accessing a particular bitfield involves converting this byte array 35249423Sdim/// into a single integer of that size (i24 or i40 -- may not be power-of-two 36249423Sdim/// size), loading it, and shifting and masking to extract the particular 37249423Sdim/// subsequence of bits which make up that particular bitfield. This structure 38249423Sdim/// encodes the information used to construct the extraction code sequences. 39249423Sdim/// The CGRecordLayout also has a field index which encodes which byte-sequence 40249423Sdim/// this bitfield falls within. Let's assume the following C struct: 41249423Sdim/// 42249423Sdim/// struct S { 43249423Sdim/// char a, b, c; 44249423Sdim/// unsigned bits : 3; 45249423Sdim/// unsigned more_bits : 4; 46249423Sdim/// unsigned still_more_bits : 7; 47249423Sdim/// }; 48249423Sdim/// 49249423Sdim/// This will end up as the following LLVM type. The first array is the 50249423Sdim/// bitfield, and the second is the padding out to a 4-byte alignmnet. 51249423Sdim/// 52249423Sdim/// %t = type { i8, i8, i8, i8, i8, [3 x i8] } 53249423Sdim/// 54249423Sdim/// When generating code to access more_bits, we'll generate something 55249423Sdim/// essentially like this: 56249423Sdim/// 57249423Sdim/// define i32 @foo(%t* %base) { 58249423Sdim/// %0 = gep %t* %base, i32 0, i32 3 59249423Sdim/// %2 = load i8* %1 60249423Sdim/// %3 = lshr i8 %2, 3 61249423Sdim/// %4 = and i8 %3, 15 62249423Sdim/// %5 = zext i8 %4 to i32 63249423Sdim/// ret i32 %i 64249423Sdim/// } 65249423Sdim/// 66249423Sdimstruct CGBitFieldInfo { 67249423Sdim /// The offset within a contiguous run of bitfields that are represented as 68249423Sdim /// a single "field" within the LLVM struct type. This offset is in bits. 69249423Sdim unsigned Offset : 16; 70206275Srdivacky 71207619Srdivacky /// The total size of the bit-field, in bits. 72249423Sdim unsigned Size : 15; 73207619Srdivacky 74207619Srdivacky /// Whether the bit-field is signed. 75249423Sdim unsigned IsSigned : 1; 76207619Srdivacky 77249423Sdim /// The storage size in bits which should be used when accessing this 78249423Sdim /// bitfield. 79249423Sdim unsigned StorageSize; 80207619Srdivacky 81249423Sdim /// The alignment which should be used when accessing the bitfield. 82249423Sdim unsigned StorageAlignment; 83207619Srdivacky 84249423Sdim CGBitFieldInfo() 85249423Sdim : Offset(), Size(), IsSigned(), StorageSize(), StorageAlignment() {} 86207619Srdivacky 87249423Sdim CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned, 88249423Sdim unsigned StorageSize, unsigned StorageAlignment) 89249423Sdim : Offset(Offset), Size(Size), IsSigned(IsSigned), 90249423Sdim StorageSize(StorageSize), StorageAlignment(StorageAlignment) {} 91207619Srdivacky 92226633Sdim void print(raw_ostream &OS) const; 93207619Srdivacky void dump() const; 94212904Sdim 95212904Sdim /// \brief Given a bit-field decl, build an appropriate helper object for 96212904Sdim /// accessing that field (which is expected to have the given offset and 97212904Sdim /// size). 98249423Sdim static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, 99249423Sdim const FieldDecl *FD, 100249423Sdim uint64_t Offset, uint64_t Size, 101249423Sdim uint64_t StorageSize, 102249423Sdim uint64_t StorageAlignment); 103206275Srdivacky}; 104206275Srdivacky 105206084Srdivacky/// CGRecordLayout - This class handles struct and union layout info while 106206084Srdivacky/// lowering AST types to LLVM types. 107206084Srdivacky/// 108206084Srdivacky/// These layout objects are only created on demand as IR generation requires. 109206084Srdivackyclass CGRecordLayout { 110206084Srdivacky friend class CodeGenTypes; 111206084Srdivacky 112243830Sdim CGRecordLayout(const CGRecordLayout &) LLVM_DELETED_FUNCTION; 113243830Sdim void operator=(const CGRecordLayout &) LLVM_DELETED_FUNCTION; 114206084Srdivacky 115206084Srdivackyprivate: 116218893Sdim /// The LLVM type corresponding to this record layout; used when 117218893Sdim /// laying it out as a complete object. 118224145Sdim llvm::StructType *CompleteObjectType; 119206084Srdivacky 120218893Sdim /// The LLVM type for the non-virtual part of this record layout; 121218893Sdim /// used when laying it out as a base subobject. 122224145Sdim llvm::StructType *BaseSubobjectType; 123218893Sdim 124206084Srdivacky /// Map from (non-bit-field) struct field to the corresponding llvm struct 125206084Srdivacky /// type field no. This info is populated by record builder. 126206084Srdivacky llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo; 127206084Srdivacky 128206084Srdivacky /// Map from (bit-field) struct field to the corresponding llvm struct type 129206084Srdivacky /// field no. This info is populated by record builder. 130206275Srdivacky llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields; 131206084Srdivacky 132208600Srdivacky // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single 133208600Srdivacky // map for both virtual and non virtual bases. 134218893Sdim llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases; 135208600Srdivacky 136218893Sdim /// Map from virtual bases to their field index in the complete object. 137218893Sdim llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases; 138218893Sdim 139218893Sdim /// False if any direct or indirect subobject of this class, when 140218893Sdim /// considered as a complete object, requires a non-zero bitpattern 141218893Sdim /// when zero-initialized. 142212904Sdim bool IsZeroInitializable : 1; 143206084Srdivacky 144218893Sdim /// False if any direct or indirect subobject of this class, when 145218893Sdim /// considered as a base subobject, requires a non-zero bitpattern 146218893Sdim /// when zero-initialized. 147218893Sdim bool IsZeroInitializableAsBase : 1; 148218893Sdim 149206084Srdivackypublic: 150224145Sdim CGRecordLayout(llvm::StructType *CompleteObjectType, 151224145Sdim llvm::StructType *BaseSubobjectType, 152218893Sdim bool IsZeroInitializable, 153218893Sdim bool IsZeroInitializableAsBase) 154218893Sdim : CompleteObjectType(CompleteObjectType), 155218893Sdim BaseSubobjectType(BaseSubobjectType), 156218893Sdim IsZeroInitializable(IsZeroInitializable), 157218893Sdim IsZeroInitializableAsBase(IsZeroInitializableAsBase) {} 158206084Srdivacky 159218893Sdim /// \brief Return the "complete object" LLVM type associated with 160218893Sdim /// this record. 161224145Sdim llvm::StructType *getLLVMType() const { 162224145Sdim return CompleteObjectType; 163206084Srdivacky } 164206084Srdivacky 165218893Sdim /// \brief Return the "base subobject" LLVM type associated with 166218893Sdim /// this record. 167224145Sdim llvm::StructType *getBaseSubobjectLLVMType() const { 168224145Sdim return BaseSubobjectType; 169218893Sdim } 170218893Sdim 171212904Sdim /// \brief Check whether this struct can be C++ zero-initialized 172212904Sdim /// with a zeroinitializer. 173212904Sdim bool isZeroInitializable() const { 174212904Sdim return IsZeroInitializable; 175206084Srdivacky } 176206084Srdivacky 177218893Sdim /// \brief Check whether this struct can be C++ zero-initialized 178218893Sdim /// with a zeroinitializer when considered as a base subobject. 179218893Sdim bool isZeroInitializableAsBase() const { 180218893Sdim return IsZeroInitializableAsBase; 181218893Sdim } 182218893Sdim 183207619Srdivacky /// \brief Return llvm::StructType element number that corresponds to the 184207619Srdivacky /// field FD. 185206084Srdivacky unsigned getLLVMFieldNo(const FieldDecl *FD) const { 186206084Srdivacky assert(FieldInfo.count(FD) && "Invalid field for record!"); 187206084Srdivacky return FieldInfo.lookup(FD); 188206084Srdivacky } 189206084Srdivacky 190208600Srdivacky unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const { 191218893Sdim assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!"); 192218893Sdim return NonVirtualBases.lookup(RD); 193208600Srdivacky } 194208600Srdivacky 195218893Sdim /// \brief Return the LLVM field index corresponding to the given 196218893Sdim /// virtual base. Only valid when operating on the complete object. 197218893Sdim unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const { 198218893Sdim assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!"); 199218893Sdim return CompleteObjectVirtualBases.lookup(base); 200218893Sdim } 201218893Sdim 202207619Srdivacky /// \brief Return the BitFieldInfo that corresponds to the field FD. 203206275Srdivacky const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const { 204206084Srdivacky assert(FD->isBitField() && "Invalid call for non bit-field decl!"); 205206275Srdivacky llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator 206206084Srdivacky it = BitFields.find(FD); 207218893Sdim assert(it != BitFields.end() && "Unable to find bitfield info"); 208206084Srdivacky return it->second; 209206084Srdivacky } 210207619Srdivacky 211226633Sdim void print(raw_ostream &OS) const; 212207619Srdivacky void dump() const; 213206084Srdivacky}; 214206084Srdivacky 215206084Srdivacky} // end namespace CodeGen 216206084Srdivacky} // end namespace clang 217206084Srdivacky 218206084Srdivacky#endif 219