blob: 2ae0aab19f699129c87493bc0fa97361be2cea2f [file] [log] [blame]
Ted Kremenek503524a2010-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 Friedman2fe36362011-09-27 19:12:27 +000016#include "clang/Basic/TargetInfo.h"
Ted Kremenek503524a2010-03-08 20:56:29 +000017
18using namespace clang;
19
20void ASTRecordLayout::Destroy(ASTContext &Ctx) {
21 if (FieldOffsets)
22 Ctx.Deallocate(FieldOffsets);
Argyrios Kyrtzidis42f81e62010-08-25 00:32:19 +000023 if (CXXInfo) {
Ted Kremenek503524a2010-03-08 20:56:29 +000024 Ctx.Deallocate(CXXInfo);
Argyrios Kyrtzidis42f81e62010-08-25 00:32:19 +000025 CXXInfo->~CXXRecordLayoutInfo();
26 }
Ted Kremenek503524a2010-03-08 20:56:29 +000027 this->~ASTRecordLayout();
28 Ctx.Deallocate(this);
29}
30
Ken Dyck5f022d82011-02-09 01:59:34 +000031ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
Ken Dyckdac54c12011-02-15 02:32:40 +000032 CharUnits alignment, CharUnits datasize,
Jay Foad4ba2a172011-01-12 09:06:06 +000033 const uint64_t *fieldoffsets,
34 unsigned fieldcount)
John McCall441c6232012-05-01 08:55:32 +000035 : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
Ted Kremenek503524a2010-03-08 20:56:29 +000036 FieldCount(fieldcount), CXXInfo(0) {
37 if (FieldCount > 0) {
38 FieldOffsets = new (Ctx) uint64_t[FieldCount];
Benjamin Kramerbb9357c2010-03-09 12:53:38 +000039 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenek503524a2010-03-08 20:56:29 +000040 }
41}
42
43// Constructor for C++ records.
Jay Foad4ba2a172011-01-12 09:06:06 +000044ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
Ken Dyckdac54c12011-02-15 02:32:40 +000045 CharUnits size, CharUnits alignment,
John McCall441c6232012-05-01 08:55:32 +000046 bool hasOwnVFPtr, CharUnits vbptroffset,
Eli Friedman227e4832011-10-21 22:49:56 +000047 CharUnits datasize,
Anders Carlsson147b5dd2010-03-11 04:10:39 +000048 const uint64_t *fieldoffsets,
49 unsigned fieldcount,
Ken Dyck5c3633f2011-02-01 01:52:10 +000050 CharUnits nonvirtualsize,
Ken Dyck68cf1a52011-02-08 02:02:47 +000051 CharUnits nonvirtualalign,
Anders Carlssona3d43802010-10-31 22:13:23 +000052 CharUnits SizeOfLargestEmptySubobject,
Anders Carlsson28fdd0a2010-05-26 05:20:58 +000053 const CXXRecordDecl *PrimaryBase,
Anders Carlsson0b9fb2f2010-11-24 23:20:19 +000054 bool IsPrimaryBaseVirtual,
Anders Carlsson147b5dd2010-03-11 04:10:39 +000055 const BaseOffsetsMapTy& BaseOffsets,
John McCall441c6232012-05-01 08:55:32 +000056 const VBaseOffsetsMapTy& VBaseOffsets)
57 : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
Ted Kremenek503524a2010-03-08 20:56:29 +000058 FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
59{
60 if (FieldCount > 0) {
61 FieldOffsets = new (Ctx) uint64_t[FieldCount];
Benjamin Kramerbb9357c2010-03-09 12:53:38 +000062 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenek503524a2010-03-08 20:56:29 +000063 }
64
Anders Carlsson0b9fb2f2010-11-24 23:20:19 +000065 CXXInfo->PrimaryBase.setPointer(PrimaryBase);
66 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
Ted Kremenek503524a2010-03-08 20:56:29 +000067 CXXInfo->NonVirtualSize = nonvirtualsize;
68 CXXInfo->NonVirtualAlign = nonvirtualalign;
Anders Carlssonc3fddeb2010-05-08 22:35:05 +000069 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
Anders Carlsson147b5dd2010-03-11 04:10:39 +000070 CXXInfo->BaseOffsets = BaseOffsets;
71 CXXInfo->VBaseOffsets = VBaseOffsets;
John McCall441c6232012-05-01 08:55:32 +000072 CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
Eli Friedman2fe36362011-09-27 19:12:27 +000073 CXXInfo->VBPtrOffset = vbptroffset;
Anders Carlssonb6ee4b02010-03-11 01:49:18 +000074
75#ifndef NDEBUG
76 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
Eli Friedman2fe36362011-09-27 19:12:27 +000077 if (isPrimaryBaseVirtual()) {
78 // Microsoft ABI doesn't have primary virtual base
79 if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
Anders Carlsson3069a0d2010-10-31 23:45:59 +000080 assert(getVBaseClassOffset(PrimaryBase).isZero() &&
Anders Carlssonb6ee4b02010-03-11 01:49:18 +000081 "Primary virtual base must be at offset 0!");
Eli Friedman2fe36362011-09-27 19:12:27 +000082 }
83 } else {
Benjamin Kramerd4f51982012-07-04 18:45:14 +000084 assert(getBaseClassOffset(PrimaryBase).isZero() &&
Anders Carlssonb6ee4b02010-03-11 01:49:18 +000085 "Primary base must be at offset 0!");
Eli Friedman2fe36362011-09-27 19:12:27 +000086 }
Anders Carlssonb6ee4b02010-03-11 01:49:18 +000087 }
88#endif
Ted Kremenek503524a2010-03-08 20:56:29 +000089}