150
|
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
|
|
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
|
|
30 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
|
|
31 CharUnits alignment,
|
|
32 CharUnits unadjustedAlignment,
|
|
33 CharUnits requiredAlignment,
|
|
34 CharUnits datasize,
|
|
35 ArrayRef<uint64_t> fieldoffsets)
|
|
36 : Size(size), DataSize(datasize), Alignment(alignment),
|
|
37 UnadjustedAlignment(unadjustedAlignment),
|
|
38 RequiredAlignment(requiredAlignment) {
|
|
39 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
|
|
40 }
|
|
41
|
|
42 // Constructor for C++ records.
|
|
43 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
|
|
44 CharUnits size, CharUnits alignment,
|
|
45 CharUnits unadjustedAlignment,
|
|
46 CharUnits requiredAlignment,
|
|
47 bool hasOwnVFPtr, bool hasExtendableVFPtr,
|
|
48 CharUnits vbptroffset,
|
|
49 CharUnits datasize,
|
|
50 ArrayRef<uint64_t> fieldoffsets,
|
|
51 CharUnits nonvirtualsize,
|
|
52 CharUnits nonvirtualalignment,
|
|
53 CharUnits SizeOfLargestEmptySubobject,
|
|
54 const CXXRecordDecl *PrimaryBase,
|
|
55 bool IsPrimaryBaseVirtual,
|
|
56 const CXXRecordDecl *BaseSharingVBPtr,
|
|
57 bool EndsWithZeroSizedObject,
|
|
58 bool LeadsWithZeroSizedBase,
|
|
59 const BaseOffsetsMapTy& BaseOffsets,
|
|
60 const VBaseOffsetsMapTy& VBaseOffsets)
|
|
61 : Size(size), DataSize(datasize), Alignment(alignment),
|
|
62 UnadjustedAlignment(unadjustedAlignment),
|
|
63 RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
|
|
64 {
|
|
65 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
|
|
66
|
|
67 CXXInfo->PrimaryBase.setPointer(PrimaryBase);
|
|
68 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
|
|
69 CXXInfo->NonVirtualSize = nonvirtualsize;
|
|
70 CXXInfo->NonVirtualAlignment = nonvirtualalignment;
|
|
71 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
|
|
72 CXXInfo->BaseOffsets = BaseOffsets;
|
|
73 CXXInfo->VBaseOffsets = VBaseOffsets;
|
|
74 CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
|
|
75 CXXInfo->VBPtrOffset = vbptroffset;
|
|
76 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
|
|
77 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
|
|
78 CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
|
|
79 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
|
|
80
|
|
81 #ifndef NDEBUG
|
|
82 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
|
|
83 if (isPrimaryBaseVirtual()) {
|
|
84 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
|
|
85 assert(getVBaseClassOffset(PrimaryBase).isZero() &&
|
|
86 "Primary virtual base must be at offset 0!");
|
|
87 }
|
|
88 } else {
|
|
89 assert(getBaseClassOffset(PrimaryBase).isZero() &&
|
|
90 "Primary base must be at offset 0!");
|
|
91 }
|
|
92 }
|
|
93 #endif
|
|
94 }
|