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
18using namespace clang;
19
20void 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
31ASTRecordLayout::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.
47ASTRecordLayout::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