xref: /freebsd/contrib/llvm-project/clang/lib/AST/RecordLayout.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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  
Destroy(ASTContext & Ctx)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  
ASTRecordLayout(const ASTContext & Ctx,CharUnits size,CharUnits alignment,CharUnits preferredAlignment,CharUnits unadjustedAlignment,CharUnits requiredAlignment,CharUnits datasize,ArrayRef<uint64_t> fieldoffsets)30  ASTRecordLayout::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.
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  ASTRecordLayout::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