1 //===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the RecordLayout interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_LAYOUTINFO_H 15 #define LLVM_CLANG_AST_LAYOUTINFO_H 16 17 #include "llvm/Support/DataTypes.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "clang/AST/CharUnits.h" 20 #include "clang/AST/DeclCXX.h" 21 22 namespace clang { 23 class ASTContext; 24 class FieldDecl; 25 class RecordDecl; 26 class CXXRecordDecl; 27 28 /// ASTRecordLayout - 29 /// This class contains layout information for one RecordDecl, 30 /// which is a struct/union/class. The decl represented must be a definition, 31 /// not a forward declaration. 32 /// This class is also used to contain layout information for one 33 /// ObjCInterfaceDecl. FIXME - Find appropriate name. 34 /// These objects are managed by ASTContext. 35 class ASTRecordLayout { 36 /// Size - Size of record in characters. 37 CharUnits Size; 38 39 /// DataSize - Size of record in characters without tail padding. 40 CharUnits DataSize; 41 42 /// FieldOffsets - Array of field offsets in bits. 43 uint64_t *FieldOffsets; 44 45 // Alignment - Alignment of record in characters. 46 CharUnits Alignment; 47 48 // FieldCount - Number of fields. 49 unsigned FieldCount; 50 51 /// CXXRecordLayoutInfo - Contains C++ specific layout information. 52 struct CXXRecordLayoutInfo { 53 /// NonVirtualSize - The non-virtual size (in chars) of an object, which is 54 /// the size of the object without virtual bases. 55 CharUnits NonVirtualSize; 56 57 /// NonVirtualAlign - The non-virtual alignment (in chars) of an object, 58 /// which is the alignment of the object without virtual bases. 59 CharUnits NonVirtualAlign; 60 61 /// SizeOfLargestEmptySubobject - The size of the largest empty subobject 62 /// (either a base or a member). Will be zero if the class doesn't contain 63 /// any empty subobjects. 64 CharUnits SizeOfLargestEmptySubobject; 65 66 /// VFPtrOffset - Virtual function table offset (Microsoft-only). 67 CharUnits VFPtrOffset; 68 69 /// VBPtrOffset - Virtual base table offset (Microsoft-only). 70 CharUnits VBPtrOffset; 71 72 /// PrimaryBase - The primary base info for this record. 73 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; 74 75 /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) 76 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 77 78 /// BaseOffsets - Contains a map from base classes to their offset. 79 BaseOffsetsMapTy BaseOffsets; 80 81 /// VBaseOffsets - Contains a map from vbase classes to their offset. 82 BaseOffsetsMapTy VBaseOffsets; 83 }; 84 85 /// CXXInfo - If the record layout is for a C++ record, this will have 86 /// C++ specific information about the record. 87 CXXRecordLayoutInfo *CXXInfo; 88 89 friend class ASTContext; 90 91 ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, 92 CharUnits datasize, const uint64_t *fieldoffsets, 93 unsigned fieldcount); 94 95 // Constructor for C++ records. 96 typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; 97 ASTRecordLayout(const ASTContext &Ctx, 98 CharUnits size, CharUnits alignment, 99 CharUnits vfptroffset, CharUnits vbptroffset, 100 CharUnits datasize, 101 const uint64_t *fieldoffsets, unsigned fieldcount, 102 CharUnits nonvirtualsize, CharUnits nonvirtualalign, 103 CharUnits SizeOfLargestEmptySubobject, 104 const CXXRecordDecl *PrimaryBase, 105 bool IsPrimaryBaseVirtual, 106 const BaseOffsetsMapTy& BaseOffsets, 107 const BaseOffsetsMapTy& VBaseOffsets); 108 109 ~ASTRecordLayout() {} 110 111 void Destroy(ASTContext &Ctx); 112 113 ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT 114 void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT 115 public: 116 117 /// getAlignment - Get the record alignment in characters. 118 CharUnits getAlignment() const { return Alignment; } 119 120 /// getSize - Get the record size in characters. 121 CharUnits getSize() const { return Size; } 122 123 /// getFieldCount - Get the number of fields in the layout. 124 unsigned getFieldCount() const { return FieldCount; } 125 126 /// getFieldOffset - Get the offset of the given field index, in 127 /// bits. 128 uint64_t getFieldOffset(unsigned FieldNo) const { 129 assert (FieldNo < FieldCount && "Invalid Field No"); 130 return FieldOffsets[FieldNo]; 131 } 132 133 /// getDataSize() - Get the record data size, which is the record size 134 /// without tail padding, in characters. 135 CharUnits getDataSize() const { 136 return DataSize; 137 } 138 139 /// getNonVirtualSize - Get the non-virtual size (in chars) of an object, 140 /// which is the size of the object without virtual bases. 141 CharUnits getNonVirtualSize() const { 142 assert(CXXInfo && "Record layout does not have C++ specific info!"); 143 144 return CXXInfo->NonVirtualSize; 145 } 146 147 /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, 148 /// which is the alignment of the object without virtual bases. 149 CharUnits getNonVirtualAlign() const { 150 assert(CXXInfo && "Record layout does not have C++ specific info!"); 151 152 return CXXInfo->NonVirtualAlign; 153 } 154 155 /// getPrimaryBase - Get the primary base for this record. 156 const CXXRecordDecl *getPrimaryBase() const { 157 assert(CXXInfo && "Record layout does not have C++ specific info!"); 158 159 return CXXInfo->PrimaryBase.getPointer(); 160 } 161 162 /// isPrimaryBaseVirtual - Get whether the primary base for this record 163 /// is virtual or not. 164 bool isPrimaryBaseVirtual() const { 165 assert(CXXInfo && "Record layout does not have C++ specific info!"); 166 167 return CXXInfo->PrimaryBase.getInt(); 168 } 169 170 /// getBaseClassOffset - Get the offset, in chars, for the given base class. 171 CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const { 172 assert(CXXInfo && "Record layout does not have C++ specific info!"); 173 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 174 175 return CXXInfo->BaseOffsets[Base]; 176 } 177 178 /// getVBaseClassOffset - Get the offset, in chars, for the given base class. 179 CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const { 180 assert(CXXInfo && "Record layout does not have C++ specific info!"); 181 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 182 183 return CXXInfo->VBaseOffsets[VBase]; 184 } 185 186 /// getBaseClassOffsetInBits - Get the offset, in bits, for the given 187 /// base class. 188 uint64_t getBaseClassOffsetInBits(const CXXRecordDecl *Base) const { 189 assert(CXXInfo && "Record layout does not have C++ specific info!"); 190 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 191 192 return getBaseClassOffset(Base).getQuantity() * 193 Base->getASTContext().getCharWidth(); 194 } 195 196 /// getVBaseClassOffsetInBits - Get the offset, in bits, for the given 197 /// base class. 198 uint64_t getVBaseClassOffsetInBits(const CXXRecordDecl *VBase) const { 199 assert(CXXInfo && "Record layout does not have C++ specific info!"); 200 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 201 202 return getVBaseClassOffset(VBase).getQuantity() * 203 VBase->getASTContext().getCharWidth(); 204 } 205 206 CharUnits getSizeOfLargestEmptySubobject() const { 207 assert(CXXInfo && "Record layout does not have C++ specific info!"); 208 return CXXInfo->SizeOfLargestEmptySubobject; 209 } 210 211 /// getVFPtrOffset - Get the offset for virtual function table pointer. 212 /// This is only meaningful with the Microsoft ABI. 213 CharUnits getVFPtrOffset() const { 214 assert(CXXInfo && "Record layout does not have C++ specific info!"); 215 return CXXInfo->VFPtrOffset; 216 } 217 218 /// getVBPtrOffset - Get the offset for virtual base table pointer. 219 /// This is only meaningful with the Microsoft ABI. 220 CharUnits getVBPtrOffset() const { 221 assert(CXXInfo && "Record layout does not have C++ specific info!"); 222 return CXXInfo->VBPtrOffset; 223 } 224 }; 225 226 } // end namespace clang 227 228 #endif 229