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#include "clang/Basic/TargetInfo.h" 17 18using namespace clang; 19 20void ASTRecordLayout::Destroy(ASTContext &Ctx) { 21 if (CXXInfo) { 22 CXXInfo->~CXXRecordLayoutInfo(); 23 Ctx.Deallocate(CXXInfo); 24 } 25 this->~ASTRecordLayout(); 26 Ctx.Deallocate(this); 27} 28 29ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 30 CharUnits alignment, 31 CharUnits requiredAlignment, 32 CharUnits datasize, 33 ArrayRef<uint64_t> fieldoffsets) 34 : Size(size), DataSize(datasize), Alignment(alignment), 35 RequiredAlignment(requiredAlignment), CXXInfo(nullptr) { 36 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 37} 38 39// Constructor for C++ records. 40ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 41 CharUnits size, CharUnits alignment, 42 CharUnits requiredAlignment, 43 bool hasOwnVFPtr, bool hasExtendableVFPtr, 44 CharUnits vbptroffset, 45 CharUnits datasize, 46 ArrayRef<uint64_t> fieldoffsets, 47 CharUnits nonvirtualsize, 48 CharUnits nonvirtualalignment, 49 CharUnits SizeOfLargestEmptySubobject, 50 const CXXRecordDecl *PrimaryBase, 51 bool IsPrimaryBaseVirtual, 52 const CXXRecordDecl *BaseSharingVBPtr, 53 bool EndsWithZeroSizedObject, 54 bool LeadsWithZeroSizedBase, 55 const BaseOffsetsMapTy& BaseOffsets, 56 const VBaseOffsetsMapTy& VBaseOffsets) 57 : Size(size), DataSize(datasize), Alignment(alignment), 58 RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 59{ 60 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 61 62 CXXInfo->PrimaryBase.setPointer(PrimaryBase); 63 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 64 CXXInfo->NonVirtualSize = nonvirtualsize; 65 CXXInfo->NonVirtualAlignment = nonvirtualalignment; 66 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 67 CXXInfo->BaseOffsets = BaseOffsets; 68 CXXInfo->VBaseOffsets = VBaseOffsets; 69 CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 70 CXXInfo->VBPtrOffset = vbptroffset; 71 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 72 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 73 CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject; 74 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; 75 76 77#ifndef NDEBUG 78 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 79 if (isPrimaryBaseVirtual()) { 80 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 81 assert(getVBaseClassOffset(PrimaryBase).isZero() && 82 "Primary virtual base must be at offset 0!"); 83 } 84 } else { 85 assert(getBaseClassOffset(PrimaryBase).isZero() && 86 "Primary base must be at offset 0!"); 87 } 88 } 89#endif 90} 91