blob: 38e28d44d0ff06545b24e216d1e9244666838466 [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,
Warren Hunt7b252d22013-12-06 00:01:17 +000032 CharUnits alignment,
33 CharUnits requiredAlignment,
34 CharUnits datasize,
Jay Foad39c79802011-01-12 09:06:06 +000035 const uint64_t *fieldoffsets,
36 unsigned fieldcount)
Warren Hunt7b252d22013-12-06 00:01:17 +000037 : Size(size), DataSize(datasize), Alignment(alignment),
Craig Topper36250ad2014-05-12 05:36:57 +000038 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
39 FieldCount(fieldcount), CXXInfo(nullptr) {
Ted Kremenekc3015a92010-03-08 20:56:29 +000040 if (FieldCount > 0) {
41 FieldOffsets = new (Ctx) uint64_t[FieldCount];
Benjamin Kramerbbf5c262010-03-09 12:53:38 +000042 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenekc3015a92010-03-08 20:56:29 +000043 }
44}
45
46// Constructor for C++ records.
Jay Foad39c79802011-01-12 09:06:06 +000047ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
Ken Dyck7ad11e72011-02-15 02:32:40 +000048 CharUnits size, CharUnits alignment,
Warren Hunt7b252d22013-12-06 00:01:17 +000049 CharUnits requiredAlignment,
Warren Hunt486e7142013-11-13 22:16:13 +000050 bool hasOwnVFPtr, bool hasExtendableVFPtr,
Warren Hunt8f8bad72013-10-11 20:19:00 +000051 CharUnits vbptroffset,
Eli Friedman43114f92011-10-21 22:49:56 +000052 CharUnits datasize,
Anders Carlsson6a848892010-03-11 04:10:39 +000053 const uint64_t *fieldoffsets,
54 unsigned fieldcount,
Ken Dyck316d6f62011-02-01 01:52:10 +000055 CharUnits nonvirtualsize,
Warren Huntd640d7d2014-01-09 00:30:56 +000056 CharUnits nonvirtualalignment,
Anders Carlsson28466ab2010-10-31 22:13:23 +000057 CharUnits SizeOfLargestEmptySubobject,
Anders Carlssond20e7cd2010-05-26 05:20:58 +000058 const CXXRecordDecl *PrimaryBase,
Anders Carlsson19bda8a2010-11-24 23:20:19 +000059 bool IsPrimaryBaseVirtual,
Timur Iskhodzhanov2c9341f2013-11-08 11:45:35 +000060 const CXXRecordDecl *BaseSharingVBPtr,
Warren Hunt049f6732013-12-06 19:54:25 +000061 bool HasZeroSizedSubObject,
62 bool LeadsWithZeroSizedBase,
Anders Carlsson6a848892010-03-11 04:10:39 +000063 const BaseOffsetsMapTy& BaseOffsets,
John McCalle42a3362012-05-01 08:55:32 +000064 const VBaseOffsetsMapTy& VBaseOffsets)
Warren Hunt7b252d22013-12-06 00:01:17 +000065 : Size(size), DataSize(datasize), Alignment(alignment),
Craig Topper36250ad2014-05-12 05:36:57 +000066 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
Ted Kremenekc3015a92010-03-08 20:56:29 +000067 FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
68{
69 if (FieldCount > 0) {
70 FieldOffsets = new (Ctx) uint64_t[FieldCount];
Benjamin Kramerbbf5c262010-03-09 12:53:38 +000071 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
Ted Kremenekc3015a92010-03-08 20:56:29 +000072 }
73
Anders Carlsson19bda8a2010-11-24 23:20:19 +000074 CXXInfo->PrimaryBase.setPointer(PrimaryBase);
75 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
Ted Kremenekc3015a92010-03-08 20:56:29 +000076 CXXInfo->NonVirtualSize = nonvirtualsize;
Warren Huntd640d7d2014-01-09 00:30:56 +000077 CXXInfo->NonVirtualAlignment = nonvirtualalignment;
Anders Carlsson2357bfd2010-05-08 22:35:05 +000078 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
Anders Carlsson6a848892010-03-11 04:10:39 +000079 CXXInfo->BaseOffsets = BaseOffsets;
80 CXXInfo->VBaseOffsets = VBaseOffsets;
John McCalle42a3362012-05-01 08:55:32 +000081 CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
Eli Friedman84d2d3a2011-09-27 19:12:27 +000082 CXXInfo->VBPtrOffset = vbptroffset;
Warren Hunt486e7142013-11-13 22:16:13 +000083 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
Timur Iskhodzhanov2c9341f2013-11-08 11:45:35 +000084 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
Warren Hunt049f6732013-12-06 19:54:25 +000085 CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
86 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
Warren Hunt8f8bad72013-10-11 20:19:00 +000087
Anders Carlsson09db5372010-03-11 01:49:18 +000088
89#ifndef NDEBUG
90 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
Eli Friedman84d2d3a2011-09-27 19:12:27 +000091 if (isPrimaryBaseVirtual()) {
John McCall359b8852013-01-25 22:30:49 +000092 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
93 assert(getVBaseClassOffset(PrimaryBase).isZero() &&
94 "Primary virtual base must be at offset 0!");
Eli Friedman84d2d3a2011-09-27 19:12:27 +000095 }
96 } else {
Benjamin Kramer2ef30312012-07-04 18:45:14 +000097 assert(getBaseClassOffset(PrimaryBase).isZero() &&
Anders Carlsson09db5372010-03-11 01:49:18 +000098 "Primary base must be at offset 0!");
Eli Friedman84d2d3a2011-09-27 19:12:27 +000099 }
Anders Carlsson09db5372010-03-11 01:49:18 +0000100 }
101#endif
Ted Kremenekc3015a92010-03-08 20:56:29 +0000102}