xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/RecordLayout.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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