10b57cec5SDimitry Andric //===- RecordLayout.cpp - Layout information for a struct/union -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the RecordLayout interface.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/Basic/TargetCXXABI.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
170b57cec5SDimitry Andric #include <cassert>
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric using namespace clang;
200b57cec5SDimitry Andric
Destroy(ASTContext & Ctx)210b57cec5SDimitry Andric void ASTRecordLayout::Destroy(ASTContext &Ctx) {
220b57cec5SDimitry Andric if (CXXInfo) {
230b57cec5SDimitry Andric CXXInfo->~CXXRecordLayoutInfo();
240b57cec5SDimitry Andric Ctx.Deallocate(CXXInfo);
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric this->~ASTRecordLayout();
270b57cec5SDimitry Andric Ctx.Deallocate(this);
280b57cec5SDimitry Andric }
290b57cec5SDimitry Andric
ASTRecordLayout(const ASTContext & Ctx,CharUnits size,CharUnits alignment,CharUnits preferredAlignment,CharUnits unadjustedAlignment,CharUnits requiredAlignment,CharUnits datasize,ArrayRef<uint64_t> fieldoffsets)300b57cec5SDimitry Andric ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
310b57cec5SDimitry Andric CharUnits alignment,
32*e8d8bef9SDimitry Andric CharUnits preferredAlignment,
330b57cec5SDimitry Andric CharUnits unadjustedAlignment,
340b57cec5SDimitry Andric CharUnits requiredAlignment,
350b57cec5SDimitry Andric CharUnits datasize,
360b57cec5SDimitry Andric ArrayRef<uint64_t> fieldoffsets)
370b57cec5SDimitry Andric : Size(size), DataSize(datasize), Alignment(alignment),
38*e8d8bef9SDimitry Andric PreferredAlignment(preferredAlignment),
390b57cec5SDimitry Andric UnadjustedAlignment(unadjustedAlignment),
400b57cec5SDimitry Andric RequiredAlignment(requiredAlignment) {
410b57cec5SDimitry Andric FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric // Constructor for C++ records.
ASTRecordLayout(const ASTContext & Ctx,CharUnits size,CharUnits alignment,CharUnits preferredAlignment,CharUnits unadjustedAlignment,CharUnits requiredAlignment,bool hasOwnVFPtr,bool hasExtendableVFPtr,CharUnits vbptroffset,CharUnits datasize,ArrayRef<uint64_t> fieldoffsets,CharUnits nonvirtualsize,CharUnits nonvirtualalignment,CharUnits preferrednvalignment,CharUnits SizeOfLargestEmptySubobject,const CXXRecordDecl * PrimaryBase,bool IsPrimaryBaseVirtual,const CXXRecordDecl * BaseSharingVBPtr,bool EndsWithZeroSizedObject,bool LeadsWithZeroSizedBase,const BaseOffsetsMapTy & BaseOffsets,const VBaseOffsetsMapTy & VBaseOffsets)45*e8d8bef9SDimitry Andric ASTRecordLayout::ASTRecordLayout(
46*e8d8bef9SDimitry Andric const ASTContext &Ctx, CharUnits size, CharUnits alignment,
47*e8d8bef9SDimitry Andric CharUnits preferredAlignment, CharUnits unadjustedAlignment,
48*e8d8bef9SDimitry Andric CharUnits requiredAlignment, bool hasOwnVFPtr, bool hasExtendableVFPtr,
49*e8d8bef9SDimitry Andric CharUnits vbptroffset, CharUnits datasize, ArrayRef<uint64_t> fieldoffsets,
50*e8d8bef9SDimitry Andric CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
51*e8d8bef9SDimitry Andric CharUnits preferrednvalignment, CharUnits SizeOfLargestEmptySubobject,
52*e8d8bef9SDimitry Andric const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual,
53*e8d8bef9SDimitry Andric const CXXRecordDecl *BaseSharingVBPtr, bool EndsWithZeroSizedObject,
54*e8d8bef9SDimitry Andric bool LeadsWithZeroSizedBase, const BaseOffsetsMapTy &BaseOffsets,
550b57cec5SDimitry Andric const VBaseOffsetsMapTy &VBaseOffsets)
560b57cec5SDimitry Andric : Size(size), DataSize(datasize), Alignment(alignment),
57*e8d8bef9SDimitry Andric PreferredAlignment(preferredAlignment),
580b57cec5SDimitry Andric UnadjustedAlignment(unadjustedAlignment),
59*e8d8bef9SDimitry Andric RequiredAlignment(requiredAlignment),
60*e8d8bef9SDimitry Andric CXXInfo(new (Ctx) CXXRecordLayoutInfo) {
610b57cec5SDimitry Andric FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric CXXInfo->PrimaryBase.setPointer(PrimaryBase);
640b57cec5SDimitry Andric CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
650b57cec5SDimitry Andric CXXInfo->NonVirtualSize = nonvirtualsize;
660b57cec5SDimitry Andric CXXInfo->NonVirtualAlignment = nonvirtualalignment;
67*e8d8bef9SDimitry Andric CXXInfo->PreferredNVAlignment = preferrednvalignment;
680b57cec5SDimitry Andric CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
690b57cec5SDimitry Andric CXXInfo->BaseOffsets = BaseOffsets;
700b57cec5SDimitry Andric CXXInfo->VBaseOffsets = VBaseOffsets;
710b57cec5SDimitry Andric CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
720b57cec5SDimitry Andric CXXInfo->VBPtrOffset = vbptroffset;
730b57cec5SDimitry Andric CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
740b57cec5SDimitry Andric CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
750b57cec5SDimitry Andric CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
760b57cec5SDimitry Andric CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric #ifndef NDEBUG
790b57cec5SDimitry Andric if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
800b57cec5SDimitry Andric if (isPrimaryBaseVirtual()) {
810b57cec5SDimitry Andric if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
820b57cec5SDimitry Andric assert(getVBaseClassOffset(PrimaryBase).isZero() &&
830b57cec5SDimitry Andric "Primary virtual base must be at offset 0!");
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric } else {
860b57cec5SDimitry Andric assert(getBaseClassOffset(PrimaryBase).isZero() &&
870b57cec5SDimitry Andric "Primary base must be at offset 0!");
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric #endif
910b57cec5SDimitry Andric }
92