92 lines · cpp
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-exception6//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 NDEBUG79 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#endif91}92