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, CharUnits vbptroffset,
47                                 CharUnits datasize,
48                                 const uint64_t *fieldoffsets,
49                                 unsigned fieldcount,
50                                 CharUnits nonvirtualsize,
51                                 CharUnits nonvirtualalign,
52                                 CharUnits SizeOfLargestEmptySubobject,
53                                 const CXXRecordDecl *PrimaryBase,
54                                 bool IsPrimaryBaseVirtual,
55                                 const BaseOffsetsMapTy& BaseOffsets,
56                                 const VBaseOffsetsMapTy& VBaseOffsets)
57  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
58    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
59{
60  if (FieldCount > 0)  {
61    FieldOffsets = new (Ctx) uint64_t[FieldCount];
62    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
63  }
64
65  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
66  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
67  CXXInfo->NonVirtualSize = nonvirtualsize;
68  CXXInfo->NonVirtualAlign = nonvirtualalign;
69  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
70  CXXInfo->BaseOffsets = BaseOffsets;
71  CXXInfo->VBaseOffsets = VBaseOffsets;
72  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
73  CXXInfo->VBPtrOffset = vbptroffset;
74
75#ifndef NDEBUG
76    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
77      if (isPrimaryBaseVirtual()) {
78        // Microsoft ABI doesn't have primary virtual base
79        if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
80        assert(getVBaseClassOffset(PrimaryBase).isZero() &&
81               "Primary virtual base must be at offset 0!");
82        }
83      } else {
84        assert(getBaseClassOffset(PrimaryBase).isZero() &&
85               "Primary base must be at offset 0!");
86      }
87    }
88#endif
89}
90