1//===- RecordLayout.cpp - Layout information for a struct/union -----------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file defines the RecordLayout interface. 10// 11//===----------------------------------------------------------------------===// 12 13#include "clang/AST/RecordLayout.h" 14#include "clang/AST/ASTContext.h" 15#include "clang/Basic/TargetCXXABI.h" 16#include "clang/Basic/TargetInfo.h" 17#include <cassert> 18 19using namespace clang; 20 21void ASTRecordLayout::Destroy(ASTContext &Ctx) { 22 if (CXXInfo) { 23 CXXInfo->~CXXRecordLayoutInfo(); 24 Ctx.Deallocate(CXXInfo); 25 } 26 this->~ASTRecordLayout(); 27 Ctx.Deallocate(this); 28} 29 30ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 31 CharUnits alignment, 32 CharUnits preferredAlignment, 33 CharUnits unadjustedAlignment, 34 CharUnits requiredAlignment, 35 CharUnits datasize, 36 ArrayRef<uint64_t> fieldoffsets) 37 : Size(size), DataSize(datasize), Alignment(alignment), 38 PreferredAlignment(preferredAlignment), 39 UnadjustedAlignment(unadjustedAlignment), 40 RequiredAlignment(requiredAlignment) { 41 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 42} 43 44// Constructor for C++ records. 45ASTRecordLayout::ASTRecordLayout( 46 const ASTContext &Ctx, CharUnits size, CharUnits alignment, 47 CharUnits preferredAlignment, CharUnits unadjustedAlignment, 48 CharUnits requiredAlignment, bool hasOwnVFPtr, bool hasExtendableVFPtr, 49 CharUnits vbptroffset, CharUnits datasize, ArrayRef<uint64_t> fieldoffsets, 50 CharUnits nonvirtualsize, CharUnits nonvirtualalignment, 51 CharUnits preferrednvalignment, CharUnits SizeOfLargestEmptySubobject, 52 const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, 53 const CXXRecordDecl *BaseSharingVBPtr, bool EndsWithZeroSizedObject, 54 bool LeadsWithZeroSizedBase, const BaseOffsetsMapTy &BaseOffsets, 55 const VBaseOffsetsMapTy &VBaseOffsets) 56 : Size(size), DataSize(datasize), Alignment(alignment), 57 PreferredAlignment(preferredAlignment), 58 UnadjustedAlignment(unadjustedAlignment), 59 RequiredAlignment(requiredAlignment), 60 CXXInfo(new (Ctx) CXXRecordLayoutInfo) { 61 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 62 63 CXXInfo->PrimaryBase.setPointer(PrimaryBase); 64 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 65 CXXInfo->NonVirtualSize = nonvirtualsize; 66 CXXInfo->NonVirtualAlignment = nonvirtualalignment; 67 CXXInfo->PreferredNVAlignment = preferrednvalignment; 68 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 69 CXXInfo->BaseOffsets = BaseOffsets; 70 CXXInfo->VBaseOffsets = VBaseOffsets; 71 CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 72 CXXInfo->VBPtrOffset = vbptroffset; 73 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 74 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 75 CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject; 76 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; 77 78#ifndef NDEBUG 79 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 80 if (isPrimaryBaseVirtual()) { 81 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 82 assert(getVBaseClassOffset(PrimaryBase).isZero() && 83 "Primary virtual base must be at offset 0!"); 84 } 85 } else { 86 assert(getBaseClassOffset(PrimaryBase).isZero() && 87 "Primary base must be at offset 0!"); 88 } 89 } 90#endif 91} 92