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