1327952Sdim//===- RecordLayout.cpp - Layout information for a struct/union -----------===// 2204962Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6204962Srdivacky// 7204962Srdivacky//===----------------------------------------------------------------------===// 8204962Srdivacky// 9204962Srdivacky// This file defines the RecordLayout interface. 10204962Srdivacky// 11204962Srdivacky//===----------------------------------------------------------------------===// 12204962Srdivacky 13327952Sdim#include "clang/AST/RecordLayout.h" 14204962Srdivacky#include "clang/AST/ASTContext.h" 15327952Sdim#include "clang/Basic/TargetCXXABI.h" 16226633Sdim#include "clang/Basic/TargetInfo.h" 17327952Sdim#include <cassert> 18204962Srdivacky 19204962Srdivackyusing namespace clang; 20204962Srdivacky 21204962Srdivackyvoid ASTRecordLayout::Destroy(ASTContext &Ctx) { 22212904Sdim if (CXXInfo) { 23276479Sdim CXXInfo->~CXXRecordLayoutInfo(); 24204962Srdivacky Ctx.Deallocate(CXXInfo); 25212904Sdim } 26204962Srdivacky this->~ASTRecordLayout(); 27204962Srdivacky Ctx.Deallocate(this); 28204962Srdivacky} 29204962Srdivacky 30218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 31309124Sdim CharUnits alignment, 32341825Sdim CharUnits unadjustedAlignment, 33276479Sdim CharUnits requiredAlignment, 34276479Sdim CharUnits datasize, 35309124Sdim ArrayRef<uint64_t> fieldoffsets) 36309124Sdim : Size(size), DataSize(datasize), Alignment(alignment), 37341825Sdim UnadjustedAlignment(unadjustedAlignment), 38327952Sdim RequiredAlignment(requiredAlignment) { 39309124Sdim FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 40204962Srdivacky} 41204962Srdivacky 42204962Srdivacky// Constructor for C++ records. 43218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 44218893Sdim CharUnits size, CharUnits alignment, 45341825Sdim CharUnits unadjustedAlignment, 46276479Sdim CharUnits requiredAlignment, 47261991Sdim bool hasOwnVFPtr, bool hasExtendableVFPtr, 48261991Sdim CharUnits vbptroffset, 49234353Sdim CharUnits datasize, 50309124Sdim ArrayRef<uint64_t> fieldoffsets, 51218893Sdim CharUnits nonvirtualsize, 52276479Sdim CharUnits nonvirtualalignment, 53218893Sdim CharUnits SizeOfLargestEmptySubobject, 54208600Srdivacky const CXXRecordDecl *PrimaryBase, 55218893Sdim bool IsPrimaryBaseVirtual, 56261991Sdim const CXXRecordDecl *BaseSharingVBPtr, 57309124Sdim bool EndsWithZeroSizedObject, 58276479Sdim bool LeadsWithZeroSizedBase, 59205219Srdivacky const BaseOffsetsMapTy& BaseOffsets, 60239462Sdim const VBaseOffsetsMapTy& VBaseOffsets) 61276479Sdim : Size(size), DataSize(datasize), Alignment(alignment), 62341825Sdim UnadjustedAlignment(unadjustedAlignment), 63309124Sdim RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 64204962Srdivacky{ 65309124Sdim FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 66204962Srdivacky 67218893Sdim CXXInfo->PrimaryBase.setPointer(PrimaryBase); 68218893Sdim CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 69204962Srdivacky CXXInfo->NonVirtualSize = nonvirtualsize; 70276479Sdim CXXInfo->NonVirtualAlignment = nonvirtualalignment; 71208600Srdivacky CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 72205219Srdivacky CXXInfo->BaseOffsets = BaseOffsets; 73205219Srdivacky CXXInfo->VBaseOffsets = VBaseOffsets; 74239462Sdim CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 75226633Sdim CXXInfo->VBPtrOffset = vbptroffset; 76261991Sdim CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 77261991Sdim CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 78309124Sdim CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject; 79276479Sdim CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; 80205219Srdivacky 81205219Srdivacky#ifndef NDEBUG 82205219Srdivacky if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 83226633Sdim if (isPrimaryBaseVirtual()) { 84249423Sdim if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 85249423Sdim assert(getVBaseClassOffset(PrimaryBase).isZero() && 86249423Sdim "Primary virtual base must be at offset 0!"); 87226633Sdim } 88226633Sdim } else { 89239462Sdim assert(getBaseClassOffset(PrimaryBase).isZero() && 90205219Srdivacky "Primary base must be at offset 0!"); 91226633Sdim } 92205219Srdivacky } 93341825Sdim#endif 94204962Srdivacky} 95