blob: ccc591a28f32997a9de2be0feb9fc292cac594f6 [file] [log] [blame]
Ted Kremenekc3015a92010-03-08 20:56:29 +00001//===-- 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"
Eli Friedman84d2d3a2011-09-27 19:12:27 +000016#include "clang/Basic/TargetInfo.h"
Ted Kremenekc3015a92010-03-08 20:56:29 +000017
18using namespace clang;
19
20void ASTRecordLayout::Destroy(ASTContext &Ctx) {
21 if (FieldOffsets)
22 Ctx.Deallocate(FieldOffsets);
Argyrios Kyrtzidis96dbfa22010-08-25 00:32:19 +000023 if (CXXInfo) {
Ted Kremenekc3015a92010-03-08 20:56:29 +000024 Ctx.Deallocate(CXXInfo);
Argyrios Kyrtzidis96dbfa22010-08-25 00:32:19 +000025 CXXInfo->~CXXRecordLayoutInfo();
26 }
Ted Kremenekc3015a92010-03-08 20:56:29 +000027 this->~ASTRecordLayout();
28 Ctx.Deallocate(this);
29}
30
Ken Dyckc8ae5502011-02-09 01:59:34 +000031ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
Ken Dyck7ad11e72011-02-15 02:32:40 +000032 CharUnits alignment, CharUnits datasize,
Jay Foad39c79802011-01-12 09:06:06 +000033 const uint64_t *fieldoffsets,
34 unsigned fieldcount)
Ted Kremenekc3015a92010-03-08 20:56:29 +000035 : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
36 FieldCount(fieldcount), CXXInfo(0) {
37 if (FieldCount > 0) {
38 FieldOffsets = new (Ctx) uint64_t[FieldCount];
Benjamin Kramerbbf5c262010-03-09 12:53:38 +000039 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenekc3015a92010-03-08 20:56:29 +000040 }
41}
42
43// Constructor for C++ records.
Jay Foad39c79802011-01-12 09:06:06 +000044ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
Ken Dyck7ad11e72011-02-15 02:32:40 +000045 CharUnits size, CharUnits alignment,
Eli Friedman84d2d3a2011-09-27 19:12:27 +000046 CharUnits vbptroffset, CharUnits datasize,
Anders Carlsson6a848892010-03-11 04:10:39 +000047 const uint64_t *fieldoffsets,
48 unsigned fieldcount,
Ken Dyck316d6f62011-02-01 01:52:10 +000049 CharUnits nonvirtualsize,
Ken Dyckbec02852011-02-08 02:02:47 +000050 CharUnits nonvirtualalign,
Anders Carlsson28466ab2010-10-31 22:13:23 +000051 CharUnits SizeOfLargestEmptySubobject,
Anders Carlssond20e7cd2010-05-26 05:20:58 +000052 const CXXRecordDecl *PrimaryBase,
Anders Carlsson19bda8a2010-11-24 23:20:19 +000053 bool IsPrimaryBaseVirtual,
Anders Carlsson6a848892010-03-11 04:10:39 +000054 const BaseOffsetsMapTy& BaseOffsets,
55 const BaseOffsetsMapTy& VBaseOffsets)
Ted Kremenekc3015a92010-03-08 20:56:29 +000056 : 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];
Benjamin Kramerbbf5c262010-03-09 12:53:38 +000061 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenekc3015a92010-03-08 20:56:29 +000062 }
63
Anders Carlsson19bda8a2010-11-24 23:20:19 +000064 CXXInfo->PrimaryBase.setPointer(PrimaryBase);
65 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
Ted Kremenekc3015a92010-03-08 20:56:29 +000066 CXXInfo->NonVirtualSize = nonvirtualsize;
67 CXXInfo->NonVirtualAlign = nonvirtualalign;
Anders Carlsson2357bfd2010-05-08 22:35:05 +000068 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
Anders Carlsson6a848892010-03-11 04:10:39 +000069 CXXInfo->BaseOffsets = BaseOffsets;
70 CXXInfo->VBaseOffsets = VBaseOffsets;
Eli Friedman84d2d3a2011-09-27 19:12:27 +000071 CXXInfo->VBPtrOffset = vbptroffset;
Anders Carlsson09db5372010-03-11 01:49:18 +000072
73#ifndef NDEBUG
74 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
Eli Friedman84d2d3a2011-09-27 19:12:27 +000075 if (isPrimaryBaseVirtual()) {
76 // Microsoft ABI doesn't have primary virtual base
77 if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
Anders Carlsson3f018712010-10-31 23:45:59 +000078 assert(getVBaseClassOffset(PrimaryBase).isZero() &&
Anders Carlsson09db5372010-03-11 01:49:18 +000079 "Primary virtual base must be at offset 0!");
Eli Friedman84d2d3a2011-09-27 19:12:27 +000080 }
81 } else {
Anders Carlssonfd88a612010-10-31 23:22:37 +000082 assert(getBaseClassOffsetInBits(PrimaryBase) == 0 &&
Anders Carlsson09db5372010-03-11 01:49:18 +000083 "Primary base must be at offset 0!");
Eli Friedman84d2d3a2011-09-27 19:12:27 +000084 }
Anders Carlsson09db5372010-03-11 01:49:18 +000085 }
86#endif
Ted Kremenekc3015a92010-03-08 20:56:29 +000087}