RecordLayout.cpp revision 263508
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    Ctx.Deallocate(CXXInfo);
25    CXXInfo->~CXXRecordLayoutInfo();
26  }
27  this->~ASTRecordLayout();
28  Ctx.Deallocate(this);
29}
30
31ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
32                                 CharUnits alignment, CharUnits datasize,
33                                 const uint64_t *fieldoffsets,
34                                 unsigned fieldcount)
35  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
36    FieldCount(fieldcount), CXXInfo(0) {
37  if (FieldCount > 0)  {
38    FieldOffsets = new (Ctx) uint64_t[FieldCount];
39    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
40  }
41}
42
43// Constructor for C++ records.
44ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
45                                 CharUnits size, CharUnits alignment,
46                                 bool hasOwnVFPtr, bool hasExtendableVFPtr,
47                                 CharUnits vbptroffset,
48                                 CharUnits datasize,
49                                 const uint64_t *fieldoffsets,
50                                 unsigned fieldcount,
51                                 CharUnits nonvirtualsize,
52                                 CharUnits nonvirtualalign,
53                                 CharUnits SizeOfLargestEmptySubobject,
54                                 const CXXRecordDecl *PrimaryBase,
55                                 bool IsPrimaryBaseVirtual,
56                                 const CXXRecordDecl *BaseSharingVBPtr,
57                                 bool AlignAfterVBases,
58                                 const BaseOffsetsMapTy& BaseOffsets,
59                                 const VBaseOffsetsMapTy& VBaseOffsets)
60  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
61    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
62{
63  if (FieldCount > 0)  {
64    FieldOffsets = new (Ctx) uint64_t[FieldCount];
65    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
66  }
67
68  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
69  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
70  CXXInfo->NonVirtualSize = nonvirtualsize;
71  CXXInfo->NonVirtualAlign = nonvirtualalign;
72  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
73  CXXInfo->BaseOffsets = BaseOffsets;
74  CXXInfo->VBaseOffsets = VBaseOffsets;
75  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
76  CXXInfo->VBPtrOffset = vbptroffset;
77  CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
78  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
79  CXXInfo->AlignAfterVBases = AlignAfterVBases;
80
81
82#ifndef NDEBUG
83    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
84      if (isPrimaryBaseVirtual()) {
85        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
86          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
87                 "Primary virtual base must be at offset 0!");
88        }
89      } else {
90        assert(getBaseClassOffset(PrimaryBase).isZero() &&
91               "Primary base must be at offset 0!");
92      }
93    }
94#endif
95}
96