1327952Sdim//===- RecordLayout.cpp - Layout information for a struct/union -----------===//
2204962Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6204962Srdivacky//
7204962Srdivacky//===----------------------------------------------------------------------===//
8204962Srdivacky//
9204962Srdivacky//  This file defines the RecordLayout interface.
10204962Srdivacky//
11204962Srdivacky//===----------------------------------------------------------------------===//
12204962Srdivacky
13327952Sdim#include "clang/AST/RecordLayout.h"
14204962Srdivacky#include "clang/AST/ASTContext.h"
15327952Sdim#include "clang/Basic/TargetCXXABI.h"
16226633Sdim#include "clang/Basic/TargetInfo.h"
17327952Sdim#include <cassert>
18204962Srdivacky
19204962Srdivackyusing namespace clang;
20204962Srdivacky
21204962Srdivackyvoid ASTRecordLayout::Destroy(ASTContext &Ctx) {
22212904Sdim  if (CXXInfo) {
23276479Sdim    CXXInfo->~CXXRecordLayoutInfo();
24204962Srdivacky    Ctx.Deallocate(CXXInfo);
25212904Sdim  }
26204962Srdivacky  this->~ASTRecordLayout();
27204962Srdivacky  Ctx.Deallocate(this);
28204962Srdivacky}
29204962Srdivacky
30218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
31309124Sdim                                 CharUnits alignment,
32341825Sdim                                 CharUnits unadjustedAlignment,
33276479Sdim                                 CharUnits requiredAlignment,
34276479Sdim                                 CharUnits datasize,
35309124Sdim                                 ArrayRef<uint64_t> fieldoffsets)
36309124Sdim    : Size(size), DataSize(datasize), Alignment(alignment),
37341825Sdim      UnadjustedAlignment(unadjustedAlignment),
38327952Sdim      RequiredAlignment(requiredAlignment) {
39309124Sdim  FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
40204962Srdivacky}
41204962Srdivacky
42204962Srdivacky// Constructor for C++ records.
43218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
44218893Sdim                                 CharUnits size, CharUnits alignment,
45341825Sdim                                 CharUnits unadjustedAlignment,
46276479Sdim                                 CharUnits requiredAlignment,
47261991Sdim                                 bool hasOwnVFPtr, bool hasExtendableVFPtr,
48261991Sdim                                 CharUnits vbptroffset,
49234353Sdim                                 CharUnits datasize,
50309124Sdim                                 ArrayRef<uint64_t> fieldoffsets,
51218893Sdim                                 CharUnits nonvirtualsize,
52276479Sdim                                 CharUnits nonvirtualalignment,
53218893Sdim                                 CharUnits SizeOfLargestEmptySubobject,
54208600Srdivacky                                 const CXXRecordDecl *PrimaryBase,
55218893Sdim                                 bool IsPrimaryBaseVirtual,
56261991Sdim                                 const CXXRecordDecl *BaseSharingVBPtr,
57309124Sdim                                 bool EndsWithZeroSizedObject,
58276479Sdim                                 bool LeadsWithZeroSizedBase,
59205219Srdivacky                                 const BaseOffsetsMapTy& BaseOffsets,
60239462Sdim                                 const VBaseOffsetsMapTy& VBaseOffsets)
61276479Sdim  : Size(size), DataSize(datasize), Alignment(alignment),
62341825Sdim    UnadjustedAlignment(unadjustedAlignment),
63309124Sdim    RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
64204962Srdivacky{
65309124Sdim  FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
66204962Srdivacky
67218893Sdim  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
68218893Sdim  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
69204962Srdivacky  CXXInfo->NonVirtualSize = nonvirtualsize;
70276479Sdim  CXXInfo->NonVirtualAlignment = nonvirtualalignment;
71208600Srdivacky  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
72205219Srdivacky  CXXInfo->BaseOffsets = BaseOffsets;
73205219Srdivacky  CXXInfo->VBaseOffsets = VBaseOffsets;
74239462Sdim  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
75226633Sdim  CXXInfo->VBPtrOffset = vbptroffset;
76261991Sdim  CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
77261991Sdim  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
78309124Sdim  CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
79276479Sdim  CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
80205219Srdivacky
81205219Srdivacky#ifndef NDEBUG
82205219Srdivacky    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
83226633Sdim      if (isPrimaryBaseVirtual()) {
84249423Sdim        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
85249423Sdim          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
86249423Sdim                 "Primary virtual base must be at offset 0!");
87226633Sdim        }
88226633Sdim      } else {
89239462Sdim        assert(getBaseClassOffset(PrimaryBase).isZero() &&
90205219Srdivacky               "Primary base must be at offset 0!");
91226633Sdim      }
92205219Srdivacky    }
93341825Sdim#endif
94204962Srdivacky}
95