1204962Srdivacky//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==// 2204962Srdivacky// 3204962Srdivacky// The LLVM Compiler Infrastructure 4204962Srdivacky// 5204962Srdivacky// This file is distributed under the University of Illinois Open Source 6204962Srdivacky// License. See LICENSE.TXT for details. 7204962Srdivacky// 8204962Srdivacky//===----------------------------------------------------------------------===// 9204962Srdivacky// 10204962Srdivacky// This file defines the RecordLayout interface. 11204962Srdivacky// 12204962Srdivacky//===----------------------------------------------------------------------===// 13204962Srdivacky 14204962Srdivacky#include "clang/AST/ASTContext.h" 15204962Srdivacky#include "clang/AST/RecordLayout.h" 16226890Sdim#include "clang/Basic/TargetInfo.h" 17204962Srdivacky 18204962Srdivackyusing namespace clang; 19204962Srdivacky 20204962Srdivackyvoid ASTRecordLayout::Destroy(ASTContext &Ctx) { 21204962Srdivacky if (FieldOffsets) 22204962Srdivacky Ctx.Deallocate(FieldOffsets); 23212904Sdim if (CXXInfo) { 24204962Srdivacky Ctx.Deallocate(CXXInfo); 25212904Sdim CXXInfo->~CXXRecordLayoutInfo(); 26212904Sdim } 27204962Srdivacky this->~ASTRecordLayout(); 28204962Srdivacky Ctx.Deallocate(this); 29204962Srdivacky} 30204962Srdivacky 31218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 32218893Sdim CharUnits alignment, CharUnits datasize, 33218893Sdim const uint64_t *fieldoffsets, 34218893Sdim unsigned fieldcount) 35245431Sdim : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0), 36204962Srdivacky FieldCount(fieldcount), CXXInfo(0) { 37204962Srdivacky if (FieldCount > 0) { 38204962Srdivacky FieldOffsets = new (Ctx) uint64_t[FieldCount]; 39204962Srdivacky memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 40204962Srdivacky } 41204962Srdivacky} 42204962Srdivacky 43204962Srdivacky// Constructor for C++ records. 44218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 45218893Sdim CharUnits size, CharUnits alignment, 46263509Sdim bool hasOwnVFPtr, bool hasExtendableVFPtr, 47263509Sdim CharUnits vbptroffset, 48235633Sdim CharUnits datasize, 49205219Srdivacky const uint64_t *fieldoffsets, 50205219Srdivacky unsigned fieldcount, 51218893Sdim CharUnits nonvirtualsize, 52218893Sdim CharUnits nonvirtualalign, 53218893Sdim CharUnits SizeOfLargestEmptySubobject, 54208600Srdivacky const CXXRecordDecl *PrimaryBase, 55218893Sdim bool IsPrimaryBaseVirtual, 56263509Sdim const CXXRecordDecl *BaseSharingVBPtr, 57263509Sdim bool AlignAfterVBases, 58205219Srdivacky const BaseOffsetsMapTy& BaseOffsets, 59245431Sdim const VBaseOffsetsMapTy& VBaseOffsets) 60245431Sdim : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0), 61204962Srdivacky FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 62204962Srdivacky{ 63204962Srdivacky if (FieldCount > 0) { 64204962Srdivacky FieldOffsets = new (Ctx) uint64_t[FieldCount]; 65204962Srdivacky memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 66204962Srdivacky } 67204962Srdivacky 68218893Sdim CXXInfo->PrimaryBase.setPointer(PrimaryBase); 69218893Sdim CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 70204962Srdivacky CXXInfo->NonVirtualSize = nonvirtualsize; 71204962Srdivacky CXXInfo->NonVirtualAlign = nonvirtualalign; 72208600Srdivacky CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 73205219Srdivacky CXXInfo->BaseOffsets = BaseOffsets; 74205219Srdivacky CXXInfo->VBaseOffsets = VBaseOffsets; 75245431Sdim CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 76226890Sdim CXXInfo->VBPtrOffset = vbptroffset; 77263509Sdim CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 78263509Sdim CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 79263509Sdim CXXInfo->AlignAfterVBases = AlignAfterVBases; 80205219Srdivacky 81263509Sdim 82205219Srdivacky#ifndef NDEBUG 83205219Srdivacky if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 84226890Sdim if (isPrimaryBaseVirtual()) { 85252723Sdim if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 86252723Sdim assert(getVBaseClassOffset(PrimaryBase).isZero() && 87252723Sdim "Primary virtual base must be at offset 0!"); 88226890Sdim } 89226890Sdim } else { 90245431Sdim assert(getBaseClassOffset(PrimaryBase).isZero() && 91205219Srdivacky "Primary base must be at offset 0!"); 92226890Sdim } 93205219Srdivacky } 94205219Srdivacky#endif 95204962Srdivacky} 96