1 //===-- RecordLayout.cpp - 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 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/RecordLayout.h" 16 17 using namespace clang; 18 19 void ASTRecordLayout::Destroy(ASTContext &Ctx) { 20 if (FieldOffsets) 21 Ctx.Deallocate(FieldOffsets); 22 if (CXXInfo) { 23 Ctx.Deallocate(CXXInfo); 24 CXXInfo->~CXXRecordLayoutInfo(); 25 } 26 this->~ASTRecordLayout(); 27 Ctx.Deallocate(this); 28 } 29 30 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 31 CharUnits alignment, CharUnits datasize, 32 const uint64_t *fieldoffsets, 33 unsigned fieldcount) 34 : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), 35 FieldCount(fieldcount), CXXInfo(0) { 36 if (FieldCount > 0) { 37 FieldOffsets = new (Ctx) uint64_t[FieldCount]; 38 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 39 } 40 } 41 42 // Constructor for C++ records. 43 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 44 CharUnits size, CharUnits alignment, 45 CharUnits datasize, 46 const uint64_t *fieldoffsets, 47 unsigned fieldcount, 48 CharUnits nonvirtualsize, 49 CharUnits nonvirtualalign, 50 CharUnits SizeOfLargestEmptySubobject, 51 const CXXRecordDecl *PrimaryBase, 52 bool IsPrimaryBaseVirtual, 53 const BaseOffsetsMapTy& BaseOffsets, 54 const BaseOffsetsMapTy& VBaseOffsets) 55 : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), 56 FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 57 { 58 if (FieldCount > 0) { 59 FieldOffsets = new (Ctx) uint64_t[FieldCount]; 60 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 61 } 62 63 CXXInfo->PrimaryBase.setPointer(PrimaryBase); 64 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 65 CXXInfo->NonVirtualSize = nonvirtualsize; 66 CXXInfo->NonVirtualAlign = nonvirtualalign; 67 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 68 CXXInfo->BaseOffsets = BaseOffsets; 69 CXXInfo->VBaseOffsets = VBaseOffsets; 70 71 #ifndef NDEBUG 72 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 73 if (isPrimaryBaseVirtual()) 74 assert(getVBaseClassOffset(PrimaryBase).isZero() && 75 "Primary virtual base must be at offset 0!"); 76 else 77 assert(getBaseClassOffsetInBits(PrimaryBase) == 0 && 78 "Primary base must be at offset 0!"); 79 } 80 #endif 81 } 82