clang API Documentation
00001 //===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the RecordLayout interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_LAYOUTINFO_H 00015 #define LLVM_CLANG_AST_LAYOUTINFO_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "clang/AST/CharUnits.h" 00020 #include "clang/AST/DeclCXX.h" 00021 00022 namespace clang { 00023 class ASTContext; 00024 class FieldDecl; 00025 class RecordDecl; 00026 class CXXRecordDecl; 00027 00028 /// ASTRecordLayout - 00029 /// This class contains layout information for one RecordDecl, 00030 /// which is a struct/union/class. The decl represented must be a definition, 00031 /// not a forward declaration. 00032 /// This class is also used to contain layout information for one 00033 /// ObjCInterfaceDecl. FIXME - Find appropriate name. 00034 /// These objects are managed by ASTContext. 00035 class ASTRecordLayout { 00036 public: 00037 struct VBaseInfo { 00038 /// The offset to this virtual base in the complete-object layout 00039 /// of this class. 00040 CharUnits VBaseOffset; 00041 00042 private: 00043 /// Whether this virtual base requires a vtordisp field in the 00044 /// Microsoft ABI. These fields are required for certain operations 00045 /// in constructors and destructors. 00046 bool HasVtorDisp; 00047 00048 public: 00049 bool hasVtorDisp() const { return HasVtorDisp; } 00050 00051 VBaseInfo() : HasVtorDisp(false) {} 00052 00053 VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) : 00054 VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {} 00055 }; 00056 00057 typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo> 00058 VBaseOffsetsMapTy; 00059 00060 private: 00061 /// Size - Size of record in characters. 00062 CharUnits Size; 00063 00064 /// DataSize - Size of record in characters without tail padding. 00065 CharUnits DataSize; 00066 00067 // Alignment - Alignment of record in characters. 00068 CharUnits Alignment; 00069 00070 /// FieldOffsets - Array of field offsets in bits. 00071 uint64_t *FieldOffsets; 00072 00073 // FieldCount - Number of fields. 00074 unsigned FieldCount; 00075 00076 /// CXXRecordLayoutInfo - Contains C++ specific layout information. 00077 struct CXXRecordLayoutInfo { 00078 /// NonVirtualSize - The non-virtual size (in chars) of an object, which is 00079 /// the size of the object without virtual bases. 00080 CharUnits NonVirtualSize; 00081 00082 /// NonVirtualAlign - The non-virtual alignment (in chars) of an object, 00083 /// which is the alignment of the object without virtual bases. 00084 CharUnits NonVirtualAlign; 00085 00086 /// SizeOfLargestEmptySubobject - The size of the largest empty subobject 00087 /// (either a base or a member). Will be zero if the class doesn't contain 00088 /// any empty subobjects. 00089 CharUnits SizeOfLargestEmptySubobject; 00090 00091 /// VBPtrOffset - Virtual base table offset (Microsoft-only). 00092 CharUnits VBPtrOffset; 00093 00094 /// HasOwnVFPtr - Does this class provide a virtual function table 00095 /// (vtable in Itanium, vftbl in Microsoft) that is independent from 00096 /// its base classes? 00097 bool HasOwnVFPtr; // TODO: stash this somewhere more efficient 00098 00099 /// PrimaryBase - The primary base info for this record. 00100 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; 00101 00102 /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) 00103 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 00104 00105 /// BaseOffsets - Contains a map from base classes to their offset. 00106 BaseOffsetsMapTy BaseOffsets; 00107 00108 /// VBaseOffsets - Contains a map from vbase classes to their offset. 00109 VBaseOffsetsMapTy VBaseOffsets; 00110 }; 00111 00112 /// CXXInfo - If the record layout is for a C++ record, this will have 00113 /// C++ specific information about the record. 00114 CXXRecordLayoutInfo *CXXInfo; 00115 00116 friend class ASTContext; 00117 00118 ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, 00119 CharUnits datasize, const uint64_t *fieldoffsets, 00120 unsigned fieldcount); 00121 00122 // Constructor for C++ records. 00123 typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; 00124 ASTRecordLayout(const ASTContext &Ctx, 00125 CharUnits size, CharUnits alignment, 00126 bool hasOwnVFPtr, CharUnits vbptroffset, 00127 CharUnits datasize, 00128 const uint64_t *fieldoffsets, unsigned fieldcount, 00129 CharUnits nonvirtualsize, CharUnits nonvirtualalign, 00130 CharUnits SizeOfLargestEmptySubobject, 00131 const CXXRecordDecl *PrimaryBase, 00132 bool IsPrimaryBaseVirtual, 00133 const BaseOffsetsMapTy& BaseOffsets, 00134 const VBaseOffsetsMapTy& VBaseOffsets); 00135 00136 ~ASTRecordLayout() {} 00137 00138 void Destroy(ASTContext &Ctx); 00139 00140 ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT 00141 void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT 00142 public: 00143 00144 /// getAlignment - Get the record alignment in characters. 00145 CharUnits getAlignment() const { return Alignment; } 00146 00147 /// getSize - Get the record size in characters. 00148 CharUnits getSize() const { return Size; } 00149 00150 /// getFieldCount - Get the number of fields in the layout. 00151 unsigned getFieldCount() const { return FieldCount; } 00152 00153 /// getFieldOffset - Get the offset of the given field index, in 00154 /// bits. 00155 uint64_t getFieldOffset(unsigned FieldNo) const { 00156 assert (FieldNo < FieldCount && "Invalid Field No"); 00157 return FieldOffsets[FieldNo]; 00158 } 00159 00160 /// getDataSize() - Get the record data size, which is the record size 00161 /// without tail padding, in characters. 00162 CharUnits getDataSize() const { 00163 return DataSize; 00164 } 00165 00166 /// getNonVirtualSize - Get the non-virtual size (in chars) of an object, 00167 /// which is the size of the object without virtual bases. 00168 CharUnits getNonVirtualSize() const { 00169 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00170 00171 return CXXInfo->NonVirtualSize; 00172 } 00173 00174 /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, 00175 /// which is the alignment of the object without virtual bases. 00176 CharUnits getNonVirtualAlign() const { 00177 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00178 00179 return CXXInfo->NonVirtualAlign; 00180 } 00181 00182 /// getPrimaryBase - Get the primary base for this record. 00183 const CXXRecordDecl *getPrimaryBase() const { 00184 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00185 00186 return CXXInfo->PrimaryBase.getPointer(); 00187 } 00188 00189 /// isPrimaryBaseVirtual - Get whether the primary base for this record 00190 /// is virtual or not. 00191 bool isPrimaryBaseVirtual() const { 00192 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00193 00194 return CXXInfo->PrimaryBase.getInt(); 00195 } 00196 00197 /// getBaseClassOffset - Get the offset, in chars, for the given base class. 00198 CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const { 00199 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00200 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 00201 00202 return CXXInfo->BaseOffsets[Base]; 00203 } 00204 00205 /// getVBaseClassOffset - Get the offset, in chars, for the given base class. 00206 CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const { 00207 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00208 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 00209 00210 return CXXInfo->VBaseOffsets[VBase].VBaseOffset; 00211 } 00212 00213 /// getBaseClassOffsetInBits - Get the offset, in bits, for the given 00214 /// base class. 00215 uint64_t getBaseClassOffsetInBits(const CXXRecordDecl *Base) const { 00216 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00217 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); 00218 00219 return getBaseClassOffset(Base).getQuantity() * 00220 Base->getASTContext().getCharWidth(); 00221 } 00222 00223 /// getVBaseClassOffsetInBits - Get the offset, in bits, for the given 00224 /// base class. 00225 uint64_t getVBaseClassOffsetInBits(const CXXRecordDecl *VBase) const { 00226 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00227 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); 00228 00229 return getVBaseClassOffset(VBase).getQuantity() * 00230 VBase->getASTContext().getCharWidth(); 00231 } 00232 00233 CharUnits getSizeOfLargestEmptySubobject() const { 00234 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00235 return CXXInfo->SizeOfLargestEmptySubobject; 00236 } 00237 00238 /// hasOwnVFPtr - Does this class provide its own virtual-function 00239 /// table pointer, rather than inheriting one from a primary base 00240 /// class? If so, it is at offset zero. 00241 /// 00242 /// This implies that the ABI has no primary base class, meaning 00243 /// that it has no base classes that are suitable under the conditions 00244 /// of the ABI. 00245 bool hasOwnVFPtr() const { 00246 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00247 return CXXInfo->HasOwnVFPtr; 00248 } 00249 00250 /// getVBPtrOffset - Get the offset for virtual base table pointer. 00251 /// This is only meaningful with the Microsoft ABI. 00252 CharUnits getVBPtrOffset() const { 00253 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00254 return CXXInfo->VBPtrOffset; 00255 } 00256 00257 const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { 00258 assert(CXXInfo && "Record layout does not have C++ specific info!"); 00259 return CXXInfo->VBaseOffsets; 00260 } 00261 }; 00262 00263 } // end namespace clang 00264 00265 #endif