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"
16226633Sdim#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)
35239462Sdim  : 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,
46263508Sdim                                 bool hasOwnVFPtr, bool hasExtendableVFPtr,
47263508Sdim                                 CharUnits vbptroffset,
48234353Sdim                                 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,
56263508Sdim                                 const CXXRecordDecl *BaseSharingVBPtr,
57263508Sdim                                 bool AlignAfterVBases,
58205219Srdivacky                                 const BaseOffsetsMapTy& BaseOffsets,
59239462Sdim                                 const VBaseOffsetsMapTy& VBaseOffsets)
60239462Sdim  : 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;
75239462Sdim  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
76226633Sdim  CXXInfo->VBPtrOffset = vbptroffset;
77263508Sdim  CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
78263508Sdim  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
79263508Sdim  CXXInfo->AlignAfterVBases = AlignAfterVBases;
80205219Srdivacky
81263508Sdim
82205219Srdivacky#ifndef NDEBUG
83205219Srdivacky    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
84226633Sdim      if (isPrimaryBaseVirtual()) {
85249423Sdim        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
86249423Sdim          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
87249423Sdim                 "Primary virtual base must be at offset 0!");
88226633Sdim        }
89226633Sdim      } else {
90239462Sdim        assert(getBaseClassOffset(PrimaryBase).isZero() &&
91205219Srdivacky               "Primary base must be at offset 0!");
92226633Sdim      }
93205219Srdivacky    }
94205219Srdivacky#endif
95204962Srdivacky}
96