1204962Srdivacky//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
2204962Srdivacky//
3204962Srdivacky//                     The LLVM Compiler Infrastructure
4204962Srdivacky//
5204962Srdivacky// This file is distributed under the University of Illinois Open Source
6204962Srdivacky// License. See LICENSE.TXT for details.
7204962Srdivacky//
8204962Srdivacky//===----------------------------------------------------------------------===//
9204962Srdivacky//
10204962Srdivacky//  This file defines the RecordLayout interface.
11204962Srdivacky//
12204962Srdivacky//===----------------------------------------------------------------------===//
13204962Srdivacky
14204962Srdivacky#include "clang/AST/ASTContext.h"
15204962Srdivacky#include "clang/AST/RecordLayout.h"
16226890Sdim#include "clang/Basic/TargetInfo.h"
17204962Srdivacky
18204962Srdivackyusing namespace clang;
19204962Srdivacky
20204962Srdivackyvoid ASTRecordLayout::Destroy(ASTContext &Ctx) {
21204962Srdivacky  if (FieldOffsets)
22204962Srdivacky    Ctx.Deallocate(FieldOffsets);
23212904Sdim  if (CXXInfo) {
24204962Srdivacky    Ctx.Deallocate(CXXInfo);
25212904Sdim    CXXInfo->~CXXRecordLayoutInfo();
26212904Sdim  }
27204962Srdivacky  this->~ASTRecordLayout();
28204962Srdivacky  Ctx.Deallocate(this);
29204962Srdivacky}
30204962Srdivacky
31218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
32218893Sdim                                 CharUnits alignment, CharUnits datasize,
33218893Sdim                                 const uint64_t *fieldoffsets,
34218893Sdim                                 unsigned fieldcount)
35245431Sdim  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
36204962Srdivacky    FieldCount(fieldcount), CXXInfo(0) {
37204962Srdivacky  if (FieldCount > 0)  {
38204962Srdivacky    FieldOffsets = new (Ctx) uint64_t[FieldCount];
39204962Srdivacky    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
40204962Srdivacky  }
41204962Srdivacky}
42204962Srdivacky
43204962Srdivacky// Constructor for C++ records.
44218893SdimASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
45218893Sdim                                 CharUnits size, CharUnits alignment,
46263509Sdim                                 bool hasOwnVFPtr, bool hasExtendableVFPtr,
47263509Sdim                                 CharUnits vbptroffset,
48235633Sdim                                 CharUnits datasize,
49205219Srdivacky                                 const uint64_t *fieldoffsets,
50205219Srdivacky                                 unsigned fieldcount,
51218893Sdim                                 CharUnits nonvirtualsize,
52218893Sdim                                 CharUnits nonvirtualalign,
53218893Sdim                                 CharUnits SizeOfLargestEmptySubobject,
54208600Srdivacky                                 const CXXRecordDecl *PrimaryBase,
55218893Sdim                                 bool IsPrimaryBaseVirtual,
56263509Sdim                                 const CXXRecordDecl *BaseSharingVBPtr,
57263509Sdim                                 bool AlignAfterVBases,
58205219Srdivacky                                 const BaseOffsetsMapTy& BaseOffsets,
59245431Sdim                                 const VBaseOffsetsMapTy& VBaseOffsets)
60245431Sdim  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
61204962Srdivacky    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
62204962Srdivacky{
63204962Srdivacky  if (FieldCount > 0)  {
64204962Srdivacky    FieldOffsets = new (Ctx) uint64_t[FieldCount];
65204962Srdivacky    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
66204962Srdivacky  }
67204962Srdivacky
68218893Sdim  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
69218893Sdim  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
70204962Srdivacky  CXXInfo->NonVirtualSize = nonvirtualsize;
71204962Srdivacky  CXXInfo->NonVirtualAlign = nonvirtualalign;
72208600Srdivacky  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
73205219Srdivacky  CXXInfo->BaseOffsets = BaseOffsets;
74205219Srdivacky  CXXInfo->VBaseOffsets = VBaseOffsets;
75245431Sdim  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
76226890Sdim  CXXInfo->VBPtrOffset = vbptroffset;
77263509Sdim  CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
78263509Sdim  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
79263509Sdim  CXXInfo->AlignAfterVBases = AlignAfterVBases;
80205219Srdivacky
81263509Sdim
82205219Srdivacky#ifndef NDEBUG
83205219Srdivacky    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
84226890Sdim      if (isPrimaryBaseVirtual()) {
85252723Sdim        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
86252723Sdim          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
87252723Sdim                 "Primary virtual base must be at offset 0!");
88226890Sdim        }
89226890Sdim      } else {
90245431Sdim        assert(getBaseClassOffset(PrimaryBase).isZero() &&
91205219Srdivacky               "Primary base must be at offset 0!");
92226890Sdim      }
93205219Srdivacky    }
94205219Srdivacky#endif
95204962Srdivacky}
96