RecordLayout.cpp revision 234353
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)
35204962Srdivacky  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
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,
46234353Sdim                                 CharUnits vfptroffset, CharUnits vbptroffset,
47234353Sdim                                 CharUnits datasize,
48205219Srdivacky                                 const uint64_t *fieldoffsets,
49205219Srdivacky                                 unsigned fieldcount,
50218893Sdim                                 CharUnits nonvirtualsize,
51218893Sdim                                 CharUnits nonvirtualalign,
52218893Sdim                                 CharUnits SizeOfLargestEmptySubobject,
53208600Srdivacky                                 const CXXRecordDecl *PrimaryBase,
54218893Sdim                                 bool IsPrimaryBaseVirtual,
55205219Srdivacky                                 const BaseOffsetsMapTy& BaseOffsets,
56205219Srdivacky                                 const BaseOffsetsMapTy& VBaseOffsets)
57204962Srdivacky  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
58204962Srdivacky    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
59204962Srdivacky{
60204962Srdivacky  if (FieldCount > 0)  {
61204962Srdivacky    FieldOffsets = new (Ctx) uint64_t[FieldCount];
62204962Srdivacky    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
63204962Srdivacky  }
64204962Srdivacky
65218893Sdim  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
66218893Sdim  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
67204962Srdivacky  CXXInfo->NonVirtualSize = nonvirtualsize;
68204962Srdivacky  CXXInfo->NonVirtualAlign = nonvirtualalign;
69208600Srdivacky  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
70205219Srdivacky  CXXInfo->BaseOffsets = BaseOffsets;
71205219Srdivacky  CXXInfo->VBaseOffsets = VBaseOffsets;
72234353Sdim  CXXInfo->VFPtrOffset = vfptroffset;
73226633Sdim  CXXInfo->VBPtrOffset = vbptroffset;
74205219Srdivacky
75205219Srdivacky#ifndef NDEBUG
76205219Srdivacky    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
77226633Sdim      if (isPrimaryBaseVirtual()) {
78226633Sdim        // Microsoft ABI doesn't have primary virtual base
79226633Sdim        if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
80218893Sdim        assert(getVBaseClassOffset(PrimaryBase).isZero() &&
81205219Srdivacky               "Primary virtual base must be at offset 0!");
82226633Sdim        }
83226633Sdim      } else {
84218893Sdim        assert(getBaseClassOffsetInBits(PrimaryBase) == 0 &&
85205219Srdivacky               "Primary base must be at offset 0!");
86226633Sdim      }
87205219Srdivacky    }
88205219Srdivacky#endif
89204962Srdivacky}
90