RecordLayout.h revision 478851c3ed6bd784e7377dffd8e57b200c1b9ba9
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 "clang/AST/ASTContext.h" 18#include "clang/AST/CharUnits.h" 19#include "clang/AST/DeclCXX.h" 20#include "llvm/ADT/DenseMap.h" 21 22namespace 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. 35class ASTRecordLayout { 36public: 37 struct VBaseInfo { 38 /// The offset to this virtual base in the complete-object layout 39 /// of this class. 40 CharUnits VBaseOffset; 41 42 private: 43 /// Whether this virtual base requires a vtordisp field in the 44 /// Microsoft ABI. These fields are required for certain operations 45 /// in constructors and destructors. 46 bool HasVtorDisp; 47 48 public: 49 bool hasVtorDisp() const { return HasVtorDisp; } 50 51 VBaseInfo() : HasVtorDisp(false) {} 52 53 VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) : 54 VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {} 55 }; 56 57 typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo> 58 VBaseOffsetsMapTy; 59 60private: 61 /// Size - Size of record in characters. 62 CharUnits Size; 63 64 /// DataSize - Size of record in characters without tail padding. 65 CharUnits DataSize; 66 67 // Alignment - Alignment of record in characters. 68 CharUnits Alignment; 69 70 /// FieldOffsets - Array of field offsets in bits. 71 uint64_t *FieldOffsets; 72 73 // FieldCount - Number of fields. 74 unsigned FieldCount; 75 76 /// CXXRecordLayoutInfo - Contains C++ specific layout information. 77 struct CXXRecordLayoutInfo { 78 /// NonVirtualSize - The non-virtual size (in chars) of an object, which is 79 /// the size of the object without virtual bases. 80 CharUnits NonVirtualSize; 81 82 /// NonVirtualAlign - The non-virtual alignment (in chars) of an object, 83 /// which is the alignment of the object without virtual bases. 84 CharUnits NonVirtualAlign; 85 86 /// SizeOfLargestEmptySubobject - The size of the largest empty subobject 87 /// (either a base or a member). Will be zero if the class doesn't contain 88 /// any empty subobjects. 89 CharUnits SizeOfLargestEmptySubobject; 90 91 /// VBPtrOffset - Virtual base table offset (Microsoft-only). 92 CharUnits VBPtrOffset; 93 94 /// HasOwnVFPtr - Does this class provide a virtual function table 95 /// (vtable in Itanium, vftbl in Microsoft) that is independent from 96 /// its base classes? 97 bool HasOwnVFPtr; // TODO: stash this somewhere more efficient 98 99 /// PrimaryBase - The primary base info for this record. 100 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; 101 102 /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) 103 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 104 105 /// BaseOffsets - Contains a map from base classes to their offset. 106 BaseOffsetsMapTy BaseOffsets; 107 108 /// VBaseOffsets - Contains a map from vbase classes to their offset. 109 VBaseOffsetsMapTy VBaseOffsets; 110 }; 111 112 /// CXXInfo - If the record layout is for a C++ record, this will have 113 /// C++ specific information about the record. 114 CXXRecordLayoutInfo *CXXInfo; 115 116 friend class ASTContext; 117 118 ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, 119 CharUnits datasize, const uint64_t *fieldoffsets, 120 unsigned fieldcount); 121 122 // Constructor for C++ records. 123 typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; 124 ASTRecordLayout(const ASTContext &Ctx, 125 CharUnits size, CharUnits alignment, 126 bool hasOwnVFPtr, CharUnits vbptroffset, 127 CharUnits datasize, 128 const uint64_t *fieldoffsets, unsigned fieldcount, 129 CharUnits nonvirtualsize, CharUnits nonvirtualalign, 130 CharUnits SizeOfLargestEmptySubobject, 131 const CXXRecordDecl *PrimaryBase, 132 bool IsPrimaryBaseVirtual, 133 const BaseOffsetsMapTy& BaseOffsets, 134 const VBaseOffsetsMapTy& VBaseOffsets); 135 136 ~ASTRecordLayout() {} 137 138 void Destroy(ASTContext &Ctx); 139 140 ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT 141 void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT 142public: 143 144 /// getAlignment - Get the record alignment in characters. 145 CharUnits getAlignment() const { return Alignment; } 146 147 /// getSize - Get the record size in characters. 148 CharUnits getSize() const { return Size; } 149 150 /// getFieldCount - Get the number of fields in the layout. 151 unsigned getFieldCount() const { return FieldCount; } 152 153 /// getFieldOffset - Get the offset of the given field index, in 154 /// bits. 155 uint64_t getFieldOffset(unsigned FieldNo) const { 156 assert (FieldNo < FieldCount && "Invalid Field No"); 157 return FieldOffsets[FieldNo]; 158 } 159 160 /// getDataSize() - Get the record data size, which is the record size 161 /// without tail padding, in characters. 162 CharUnits getDataSize() const { 163 return DataSize; 164 } 165 166 /// getNonVirtualSize - Get the non-virtual size (in chars) of an object, 167 /// which is the size of the object without virtual bases. 168 CharUnits getNonVirtualSize() const { 169 assert(CXXInfo && "Record layout does not have C++ specific info!"); 170 171 return CXXInfo->NonVirtualSize; 172 } 173 174 /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, 175 /// which is the alignment of the object without virtual bases. 176 CharUnits getNonVirtualAlign() const { 177 assert(CXXInfo && "Record layout does not have C++ specific info!"); 178 179 return CXXInfo->NonVirtualAlign; 180 } 181 182 /// getPrimaryBase - Get the primary base for this record. 183 const CXXRecordDecl *getPrimaryBase() const { 184 assert(CXXInfo && "Record layout does not have C++ specific info!"); 185 186 return CXXInfo->PrimaryBase.getPointer(); 187 } 188 189 /// isPrimaryBaseVirtual - Get whether the primary base for this record 190 /// is virtual or not. 191 bool isPrimaryBaseVirtual() const { 192 assert(CXXInfo && "Record layout does not have C++ specific info!"); 193 194 return CXXInfo->PrimaryBase.getInt(); 195 } 196 197 /// getBaseClassOffset - Get the offset, in chars, for the given base class. 198 CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const { 199 assert(CXXInfo && "Record layout does not have C++ specific info!"); 200 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 201 202 return CXXInfo->BaseOffsets[Base]; 203 } 204 205 /// getVBaseClassOffset - Get the offset, in chars, for the given base class. 206 CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const { 207 assert(CXXInfo && "Record layout does not have C++ specific info!"); 208 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 209 210 return CXXInfo->VBaseOffsets[VBase].VBaseOffset; 211 } 212 213 /// getBaseClassOffsetInBits - Get the offset, in bits, for the given 214 /// base class. 215 uint64_t getBaseClassOffsetInBits(const CXXRecordDecl *Base) const { 216 assert(CXXInfo && "Record layout does not have C++ specific info!"); 217 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 218 219 return getBaseClassOffset(Base).getQuantity() * 220 Base->getASTContext().getCharWidth(); 221 } 222 223 /// getVBaseClassOffsetInBits - Get the offset, in bits, for the given 224 /// base class. 225 uint64_t getVBaseClassOffsetInBits(const CXXRecordDecl *VBase) const { 226 assert(CXXInfo && "Record layout does not have C++ specific info!"); 227 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 228 229 return getVBaseClassOffset(VBase).getQuantity() * 230 VBase->getASTContext().getCharWidth(); 231 } 232 233 CharUnits getSizeOfLargestEmptySubobject() const { 234 assert(CXXInfo && "Record layout does not have C++ specific info!"); 235 return CXXInfo->SizeOfLargestEmptySubobject; 236 } 237 238 /// hasOwnVFPtr - Does this class provide its own virtual-function 239 /// table pointer, rather than inheriting one from a primary base 240 /// class? If so, it is at offset zero. 241 /// 242 /// This implies that the ABI has no primary base class, meaning 243 /// that it has no base classes that are suitable under the conditions 244 /// of the ABI. 245 bool hasOwnVFPtr() const { 246 assert(CXXInfo && "Record layout does not have C++ specific info!"); 247 return CXXInfo->HasOwnVFPtr; 248 } 249 250 /// getVBPtrOffset - Get the offset for virtual base table pointer. 251 /// This is only meaningful with the Microsoft ABI. 252 CharUnits getVBPtrOffset() const { 253 assert(CXXInfo && "Record layout does not have C++ specific info!"); 254 return CXXInfo->VBPtrOffset; 255 } 256 257 const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { 258 assert(CXXInfo && "Record layout does not have C++ specific info!"); 259 return CXXInfo->VBaseOffsets; 260 } 261}; 262 263} // end namespace clang 264 265#endif 266