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