1 //===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the RecordLayout interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/RecordLayout.h"
16 #include "clang/Basic/TargetInfo.h"
17
18 using namespace clang;
19
Destroy(ASTContext & Ctx)20 void ASTRecordLayout::Destroy(ASTContext &Ctx) {
21 if (FieldOffsets)
22 Ctx.Deallocate(FieldOffsets);
23 if (CXXInfo) {
24 CXXInfo->~CXXRecordLayoutInfo();
25 Ctx.Deallocate(CXXInfo);
26 }
27 this->~ASTRecordLayout();
28 Ctx.Deallocate(this);
29 }
30
ASTRecordLayout(const ASTContext & Ctx,CharUnits size,CharUnits alignment,CharUnits requiredAlignment,CharUnits datasize,const uint64_t * fieldoffsets,unsigned fieldcount)31 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
32 CharUnits alignment,
33 CharUnits requiredAlignment,
34 CharUnits datasize,
35 const uint64_t *fieldoffsets,
36 unsigned fieldcount)
37 : Size(size), DataSize(datasize), Alignment(alignment),
38 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
39 FieldCount(fieldcount), CXXInfo(nullptr) {
40 if (FieldCount > 0) {
41 FieldOffsets = new (Ctx) uint64_t[FieldCount];
42 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
43 }
44 }
45
46 // Constructor for C++ records.
ASTRecordLayout(const ASTContext & Ctx,CharUnits size,CharUnits alignment,CharUnits requiredAlignment,bool hasOwnVFPtr,bool hasExtendableVFPtr,CharUnits vbptroffset,CharUnits datasize,const uint64_t * fieldoffsets,unsigned fieldcount,CharUnits nonvirtualsize,CharUnits nonvirtualalignment,CharUnits SizeOfLargestEmptySubobject,const CXXRecordDecl * PrimaryBase,bool IsPrimaryBaseVirtual,const CXXRecordDecl * BaseSharingVBPtr,bool HasZeroSizedSubObject,bool LeadsWithZeroSizedBase,const BaseOffsetsMapTy & BaseOffsets,const VBaseOffsetsMapTy & VBaseOffsets)47 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
48 CharUnits size, CharUnits alignment,
49 CharUnits requiredAlignment,
50 bool hasOwnVFPtr, bool hasExtendableVFPtr,
51 CharUnits vbptroffset,
52 CharUnits datasize,
53 const uint64_t *fieldoffsets,
54 unsigned fieldcount,
55 CharUnits nonvirtualsize,
56 CharUnits nonvirtualalignment,
57 CharUnits SizeOfLargestEmptySubobject,
58 const CXXRecordDecl *PrimaryBase,
59 bool IsPrimaryBaseVirtual,
60 const CXXRecordDecl *BaseSharingVBPtr,
61 bool HasZeroSizedSubObject,
62 bool LeadsWithZeroSizedBase,
63 const BaseOffsetsMapTy& BaseOffsets,
64 const VBaseOffsetsMapTy& VBaseOffsets)
65 : Size(size), DataSize(datasize), Alignment(alignment),
66 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
67 FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
68 {
69 if (FieldCount > 0) {
70 FieldOffsets = new (Ctx) uint64_t[FieldCount];
71 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
72 }
73
74 CXXInfo->PrimaryBase.setPointer(PrimaryBase);
75 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
76 CXXInfo->NonVirtualSize = nonvirtualsize;
77 CXXInfo->NonVirtualAlignment = nonvirtualalignment;
78 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
79 CXXInfo->BaseOffsets = BaseOffsets;
80 CXXInfo->VBaseOffsets = VBaseOffsets;
81 CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
82 CXXInfo->VBPtrOffset = vbptroffset;
83 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
84 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
85 CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
86 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
87
88
89 #ifndef NDEBUG
90 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
91 if (isPrimaryBaseVirtual()) {
92 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
93 assert(getVBaseClassOffset(PrimaryBase).isZero() &&
94 "Primary virtual base must be at offset 0!");
95 }
96 } else {
97 assert(getBaseClassOffset(PrimaryBase).isZero() &&
98 "Primary base must be at offset 0!");
99 }
100 }
101 #endif
102 }
103