blob: f90bf907e94b302fd91a631aef1089e73eca6d5a [file] [log] [blame]
Anders Carlsson79474332009-07-18 20:20:21 +00001//=== ASTRecordLayoutBuilder.cpp - Helper class for building record layouts ==//
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#include "RecordLayoutBuilder.h"
11
12#include "clang/AST/Attr.h"
13#include "clang/AST/Decl.h"
Anders Carlsson6d9f6f32009-07-19 00:18:47 +000014#include "clang/AST/DeclCXX.h"
Anders Carlsson4f516282009-07-18 20:50:59 +000015#include "clang/AST/DeclObjC.h"
Anders Carlsson79474332009-07-18 20:20:21 +000016#include "clang/AST/Expr.h"
Anders Carlsson79474332009-07-18 20:20:21 +000017#include "clang/Basic/TargetInfo.h"
Mike Stumpd8fe7b22009-08-05 22:37:18 +000018#include <llvm/ADT/SmallSet.h>
Anders Carlsson79474332009-07-18 20:20:21 +000019#include <llvm/Support/MathExtras.h>
20
21using namespace clang;
22
Mike Stump11289f42009-09-09 15:08:12 +000023ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
Anders Carlssonba958402009-11-22 19:13:51 +000024 : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
25 MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0),
Anders Carlsson03ff3792009-11-27 22:05:05 +000026 NonVirtualAlignment(8) { }
Anders Carlsson79474332009-07-18 20:20:21 +000027
Mike Stump25094802009-08-06 00:38:46 +000028/// LayoutVtable - Lay out the vtable and set PrimaryBase.
Anders Carlsson81430692009-09-22 03:02:06 +000029void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
Mike Stumpaa08da72009-08-12 22:06:55 +000030 if (!RD->isDynamicClass()) {
Mike Stump25094802009-08-06 00:38:46 +000031 // There is no primary base in this case.
Mike Stumpd8fe7b22009-08-05 22:37:18 +000032 return;
Mike Stump25094802009-08-06 00:38:46 +000033 }
Mike Stumpd8fe7b22009-08-05 22:37:18 +000034
Anders Carlsson81430692009-09-22 03:02:06 +000035 SelectPrimaryBase(RD);
Anders Carlssona30c0d32009-11-27 22:14:40 +000036 if (!PrimaryBase.getBase()) {
Mike Stumpd8fe7b22009-08-05 22:37:18 +000037 int AS = 0;
38 UpdateAlignment(Ctx.Target.getPointerAlign(AS));
39 Size += Ctx.Target.getPointerWidth(AS);
Anders Carlsson47680d82009-09-26 01:34:51 +000040 DataSize = Size;
Mike Stumpd8fe7b22009-08-05 22:37:18 +000041 }
Mike Stump3dc7eb92009-07-30 00:22:38 +000042}
43
Mike Stumpd8fe7b22009-08-05 22:37:18 +000044/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
45/// no other data.
Anders Carlsson81430692009-09-22 03:02:06 +000046bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
Mike Stumpd8fe7b22009-08-05 22:37:18 +000047 // FIXME: Audit the corners
48 if (!RD->isDynamicClass())
49 return false;
50 const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
51 if (BaseInfo.getNonVirtualSize() == Ctx.Target.getPointerWidth(0))
52 return true;
53 return false;
54}
55
Anders Carlsson81430692009-09-22 03:02:06 +000056void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
Anders Carlsson03ff3792009-11-27 22:05:05 +000057 const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
58 Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo();
Anders Carlsson81430692009-09-22 03:02:06 +000059
60 // If the record has a primary base class that is virtual, add it to the set
61 // of primary bases.
Anders Carlssona30c0d32009-11-27 22:14:40 +000062 if (BaseInfo.isVirtual())
63 IndirectPrimaryBases.insert(BaseInfo.getBase());
Anders Carlsson81430692009-09-22 03:02:06 +000064
65 // Now traverse all bases and find primary bases for them.
Mike Stumpd8fe7b22009-08-05 22:37:18 +000066 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
67 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +000068 assert(!i->getType()->isDependentType() &&
69 "Cannot layout class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +000070 const CXXRecordDecl *Base =
Mike Stump78696a72009-08-11 04:03:59 +000071 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlsson81430692009-09-22 03:02:06 +000072
Mike Stump78696a72009-08-11 04:03:59 +000073 // Only bases with virtual bases participate in computing the
74 // indirect primary virtual base classes.
Mike Stumpc2f591b2009-08-13 22:53:07 +000075 if (Base->getNumVBases())
Anders Carlsson81430692009-09-22 03:02:06 +000076 IdentifyPrimaryBases(Base);
Mike Stumpd8fe7b22009-08-05 22:37:18 +000077 }
78}
79
Anders Carlsson81430692009-09-22 03:02:06 +000080void
81ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
82 const CXXRecordDecl *&FirstPrimary) {
Mike Stump6f3793b2009-08-12 21:50:08 +000083 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
84 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +000085 assert(!i->getType()->isDependentType() &&
86 "Cannot layout class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +000087 const CXXRecordDecl *Base =
Mike Stump6f3793b2009-08-12 21:50:08 +000088 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
89 if (!i->isVirtual()) {
Anders Carlsson81430692009-09-22 03:02:06 +000090 SelectPrimaryVBase(Base, FirstPrimary);
Anders Carlssona30c0d32009-11-27 22:14:40 +000091 if (PrimaryBase.getBase())
Mike Stump6f3793b2009-08-12 21:50:08 +000092 return;
93 continue;
94 }
95 if (IsNearlyEmpty(Base)) {
96 if (FirstPrimary==0)
97 FirstPrimary = Base;
Anders Carlsson81430692009-09-22 03:02:06 +000098 if (!IndirectPrimaryBases.count(Base)) {
Anders Carlsson03ff3792009-11-27 22:05:05 +000099 setPrimaryBase(Base, /*IsVirtual=*/true);
Mike Stump6f3793b2009-08-12 21:50:08 +0000100 return;
101 }
102 }
Zhongxing Xuec345b72010-02-15 04:28:35 +0000103 assert(i->isVirtual());
104 SelectPrimaryVBase(Base, FirstPrimary);
105 if (PrimaryBase.getBase())
106 return;
Mike Stump6f3793b2009-08-12 21:50:08 +0000107 }
108}
109
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000110/// SelectPrimaryBase - Selects the primary base for the given class and
Mike Stump590a7c72009-08-13 23:26:06 +0000111/// record that with setPrimaryBase. We also calculate the IndirectPrimaries.
Anders Carlsson81430692009-09-22 03:02:06 +0000112void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
113 // Compute all the primary virtual bases for all of our direct and
Mike Stump590a7c72009-08-13 23:26:06 +0000114 // indirect bases, and record all their primary virtual base classes.
Mike Stump590a7c72009-08-13 23:26:06 +0000115 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
116 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000117 assert(!i->getType()->isDependentType() &&
118 "Cannot layout class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +0000119 const CXXRecordDecl *Base =
Mike Stump590a7c72009-08-13 23:26:06 +0000120 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlsson81430692009-09-22 03:02:06 +0000121 IdentifyPrimaryBases(Base);
Mike Stump590a7c72009-08-13 23:26:06 +0000122 }
123
Anders Carlsson81430692009-09-22 03:02:06 +0000124 // If the record has a dynamic base class, attempt to choose a primary base
125 // class. It is the first (in direct base class order) non-virtual dynamic
126 // base class, if one exists.
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000127 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
128 e = RD->bases_end(); i != e; ++i) {
Anders Carlsson03ff3792009-11-27 22:05:05 +0000129 // Ignore virtual bases.
130 if (i->isVirtual())
131 continue;
132
133 const CXXRecordDecl *Base =
134 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
135
136 if (Base->isDynamicClass()) {
137 // We found it.
138 PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
139 return;
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000140 }
141 }
142
143 // Otherwise, it is the first nearly empty virtual base that is not an
Mike Stump78696a72009-08-11 04:03:59 +0000144 // indirect primary virtual base class, if one exists.
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000145
146 // If we have no virtual bases at this point, bail out as the searching below
147 // is expensive.
Anders Carlsson96cff1f2009-09-22 18:21:58 +0000148 if (RD->getNumVBases() == 0)
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000149 return;
Anders Carlsson81430692009-09-22 03:02:06 +0000150
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000151 // Then we can search for the first nearly empty virtual base itself.
Anders Carlsson81430692009-09-22 03:02:06 +0000152 const CXXRecordDecl *FirstPrimary = 0;
153 SelectPrimaryVBase(RD, FirstPrimary);
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000154
Mike Stumpc266c6d2009-08-07 19:00:50 +0000155 // Otherwise if is the first nearly empty virtual base, if one exists,
156 // otherwise there is no primary base class.
Anders Carlssona30c0d32009-11-27 22:14:40 +0000157 if (!PrimaryBase.getBase())
Anders Carlsson03ff3792009-11-27 22:05:05 +0000158 setPrimaryBase(FirstPrimary, /*IsVirtual=*/true);
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000159}
160
Mike Stump2b84dd32009-11-05 04:02:15 +0000161uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) {
162 for (size_t i = 0; i < Bases.size(); ++i) {
163 if (Bases[i].first == Base)
164 return Bases[i].second;
165 }
166 for (size_t i = 0; i < VBases.size(); ++i) {
167 if (VBases[i].first == Base)
168 return VBases[i].second;
169 }
170 assert(0 && "missing base");
171 return 0;
172}
173
Anders Carlsson09ffa322010-03-10 22:21:28 +0000174void
175ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
176 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
177 e = RD->bases_end(); i != e; ++i) {
178 if (!i->isVirtual()) {
179 assert(!i->getType()->isDependentType() &&
180 "Cannot layout class with dependent bases.");
181 const CXXRecordDecl *Base =
182 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
183 // Skip the PrimaryBase here, as it is laid down first.
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000184 if (Base != PrimaryBase.getBase() || PrimaryBase.isVirtual()) {
185 // Lay out the base.
186 LayoutNonVirtualBase(Base);
187 }
Anders Carlsson09ffa322010-03-10 22:21:28 +0000188 }
189 }
190}
191
192void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000193 // Layout the base.
194 uint64_t Offset = LayoutBase(RD);
195
196 // Add its base class offset.
197 Bases.push_back(std::make_pair(RD, Offset));
Anders Carlsson09ffa322010-03-10 22:21:28 +0000198}
Mike Stump2b84dd32009-11-05 04:02:15 +0000199
200void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
201 const CXXRecordDecl *RD,
Mike Stump996576f32009-08-16 19:04:13 +0000202 const CXXRecordDecl *PB,
Mike Stump2b84dd32009-11-05 04:02:15 +0000203 uint64_t Offset,
Mike Stump22ea1f82009-08-16 01:46:26 +0000204 llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
Mike Stump13007542009-08-13 02:02:14 +0000205 llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
Mike Stumpc2f591b2009-08-13 22:53:07 +0000206 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
207 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000208 assert(!i->getType()->isDependentType() &&
209 "Cannot layout class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +0000210 const CXXRecordDecl *Base =
Mike Stump6b2556f2009-08-06 13:41:24 +0000211 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stump2b84dd32009-11-05 04:02:15 +0000212 uint64_t BaseOffset = Offset;
Mike Stump22ea1f82009-08-16 01:46:26 +0000213 if (i->isVirtual()) {
Mike Stump996576f32009-08-16 19:04:13 +0000214 if (Base == PB) {
215 // Only lay things out once.
216 if (mark.count(Base))
217 continue;
218 // Mark it so we don't lay it out twice.
219 mark.insert(Base);
220 assert (IndirectPrimary.count(Base) && "IndirectPrimary was wrong");
Anders Carlssond6020c32009-09-22 00:04:45 +0000221 VBases.push_back(std::make_pair(Base, Offset));
Mike Stump996576f32009-08-16 19:04:13 +0000222 } else if (IndirectPrimary.count(Base)) {
223 // Someone else will eventually lay this out.
224 ;
225 } else {
226 // Only lay things out once.
227 if (mark.count(Base))
228 continue;
229 // Mark it so we don't lay it out twice.
230 mark.insert(Base);
Mike Stump22ea1f82009-08-16 01:46:26 +0000231 LayoutVirtualBase(Base);
Anders Carlssond6020c32009-09-22 00:04:45 +0000232 BaseOffset = VBases.back().second;
Mike Stump996576f32009-08-16 19:04:13 +0000233 }
Mike Stump2b84dd32009-11-05 04:02:15 +0000234 } else {
235 if (RD == Class)
236 BaseOffset = getBaseOffset(Base);
237 else {
Mike Stump4e16d052009-11-11 02:49:00 +0000238 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
Mike Stump2b84dd32009-11-05 04:02:15 +0000239 BaseOffset = Offset + Layout.getBaseClassOffset(Base);
240 }
Mike Stumpc2f591b2009-08-13 22:53:07 +0000241 }
Mike Stump2b84dd32009-11-05 04:02:15 +0000242
Mike Stump996576f32009-08-16 19:04:13 +0000243 if (Base->getNumVBases()) {
Anders Carlsson03ff3792009-11-27 22:05:05 +0000244 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
Anders Carlssona30c0d32009-11-27 22:14:40 +0000245 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().getBase();
Anders Carlsson03ff3792009-11-27 22:05:05 +0000246 LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark,
247 IndirectPrimary);
Mike Stump996576f32009-08-16 19:04:13 +0000248 }
Mike Stump6b2556f2009-08-06 13:41:24 +0000249 }
250}
251
Anders Carlsson09ffa322010-03-10 22:21:28 +0000252void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000253 // Layout the base.
254 uint64_t Offset = LayoutBase(RD);
255
256 // Add its base class offset.
257 VBases.push_back(std::make_pair(RD, Offset));
Anders Carlsson09ffa322010-03-10 22:21:28 +0000258}
259
260uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
261 const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
262
263 // If we have an empty base class, try to place it at offset 0.
264 if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
265 // We were able to place the class at offset 0.
266 UpdateEmptyClassOffsets(RD, 0);
267
268 Size = std::max(Size, BaseInfo.getSize());
269
270 return 0;
271 }
272
273 unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
274
275 // Round up the current record size to the base's alignment boundary.
276 uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign);
277
278 // Try to place the base.
279 while (true) {
280 if (canPlaceRecordAtOffset(RD, Offset))
281 break;
282
283 Offset += BaseAlign;
284 }
285
286 if (!RD->isEmpty()) {
287 // Update the data size.
288 DataSize = Offset + BaseInfo.getNonVirtualSize();
289
290 Size = std::max(Size, DataSize);
291 } else
292 Size = std::max(Size, Offset + BaseInfo.getSize());
293
294 // Remember max struct/class alignment.
295 UpdateAlignment(BaseAlign);
296
297 UpdateEmptyClassOffsets(RD, Offset);
298 return Offset;
299}
300
Anders Carlsson6522b052009-09-24 03:13:30 +0000301bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
302 uint64_t Offset) const {
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000303 // Look for an empty class with the same type at the same offset.
304 for (EmptyClassOffsetsTy::const_iterator I =
305 EmptyClassOffsets.lower_bound(Offset),
306 E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
307
308 if (I->second == RD)
309 return false;
310 }
311
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000312 const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
313
314 // Check bases.
315 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
316 E = RD->bases_end(); I != E; ++I) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000317 assert(!I->getType()->isDependentType() &&
318 "Cannot layout class with dependent bases.");
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000319 if (I->isVirtual())
320 continue;
321
322 const CXXRecordDecl *Base =
323 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
324
325 uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
326
327 if (!canPlaceRecordAtOffset(Base, Offset + BaseClassOffset))
328 return false;
329 }
330
Anders Carlssond7d358a2009-09-25 15:39:00 +0000331 // Check fields.
332 unsigned FieldNo = 0;
333 for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
334 I != E; ++I, ++FieldNo) {
335 const FieldDecl *FD = *I;
336
337 uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
338
339 if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset))
340 return false;
341 }
342
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000343 // FIXME: virtual bases.
Anders Carlsson6522b052009-09-24 03:13:30 +0000344 return true;
345}
346
Anders Carlsson6f95c702009-09-25 00:02:51 +0000347bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
348 uint64_t Offset) const {
Anders Carlsson4bf82142009-09-25 01:23:32 +0000349 QualType T = FD->getType();
350 if (const RecordType *RT = T->getAs<RecordType>()) {
Anders Carlsson6f95c702009-09-25 00:02:51 +0000351 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
352 return canPlaceRecordAtOffset(RD, Offset);
353 }
354
Anders Carlsson4bf82142009-09-25 01:23:32 +0000355 if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
356 QualType ElemTy = Ctx.getBaseElementType(AT);
357 const RecordType *RT = ElemTy->getAs<RecordType>();
358 if (!RT)
359 return true;
360 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
361 if (!RD)
362 return true;
363
364 const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
365
366 uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
Mike Stump2b84dd32009-11-05 04:02:15 +0000367 uint64_t ElementOffset = Offset;
Anders Carlsson4bf82142009-09-25 01:23:32 +0000368 for (uint64_t I = 0; I != NumElements; ++I) {
369 if (!canPlaceRecordAtOffset(RD, ElementOffset))
370 return false;
371
372 ElementOffset += Info.getSize();
373 }
374 }
Anders Carlsson6f95c702009-09-25 00:02:51 +0000375
376 return true;
377}
378
Anders Carlsson6522b052009-09-24 03:13:30 +0000379void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
380 uint64_t Offset) {
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000381 if (RD->isEmpty())
382 EmptyClassOffsets.insert(std::make_pair(Offset, RD));
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000383
384 const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
385
386 // Update bases.
387 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
388 E = RD->bases_end(); I != E; ++I) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000389 assert(!I->getType()->isDependentType() &&
390 "Cannot layout class with dependent bases.");
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000391 if (I->isVirtual())
392 continue;
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000393
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000394 const CXXRecordDecl *Base =
395 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
396
397 uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
398 UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset);
399 }
400
Anders Carlssond7d358a2009-09-25 15:39:00 +0000401 // Update fields.
402 unsigned FieldNo = 0;
403 for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
404 I != E; ++I, ++FieldNo) {
405 const FieldDecl *FD = *I;
406
407 uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
408 UpdateEmptyClassOffsets(FD, Offset + FieldOffset);
409 }
410
411 // FIXME: Update virtual bases.
Anders Carlsson6522b052009-09-24 03:13:30 +0000412}
413
Anders Carlssone1883102009-09-25 01:54:38 +0000414void
415ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
416 uint64_t Offset) {
417 QualType T = FD->getType();
418
419 if (const RecordType *RT = T->getAs<RecordType>()) {
420 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
421 UpdateEmptyClassOffsets(RD, Offset);
422 return;
423 }
424 }
425
426 if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
427 QualType ElemTy = Ctx.getBaseElementType(AT);
428 const RecordType *RT = ElemTy->getAs<RecordType>();
429 if (!RT)
430 return;
431 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
432 if (!RD)
433 return;
434
435 const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
436
437 uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
Mike Stump2b84dd32009-11-05 04:02:15 +0000438 uint64_t ElementOffset = Offset;
Anders Carlssone1883102009-09-25 01:54:38 +0000439
440 for (uint64_t I = 0; I != NumElements; ++I) {
441 UpdateEmptyClassOffsets(RD, ElementOffset);
442 ElementOffset += Info.getSize();
443 }
444 }
445}
446
Anders Carlsson79474332009-07-18 20:20:21 +0000447void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
448 IsUnion = D->isUnion();
Anders Carlsson68e0b682009-08-08 18:23:56 +0000449
Anders Carlsson28a5fa22009-08-08 19:38:24 +0000450 Packed = D->hasAttr<PackedAttr>();
451
452 // The #pragma pack attribute specifies the maximum field alignment.
Anders Carlsson68e0b682009-08-08 18:23:56 +0000453 if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
Anders Carlsson28a5fa22009-08-08 19:38:24 +0000454 MaxFieldAlignment = PPA->getAlignment();
Mike Stump11289f42009-09-09 15:08:12 +0000455
Anders Carlsson79474332009-07-18 20:20:21 +0000456 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
Alexis Hunt96d5c762009-11-21 08:43:09 +0000457 UpdateAlignment(AA->getMaxAlignment());
Anders Carlsson6d9f6f32009-07-19 00:18:47 +0000458
Mike Stump22ea1f82009-08-16 01:46:26 +0000459 // If this is a C++ class, lay out the vtable and the non-virtual bases.
Mike Stump6b2556f2009-08-06 13:41:24 +0000460 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
461 if (RD) {
Anders Carlsson81430692009-09-22 03:02:06 +0000462 LayoutVtable(RD);
Mike Stump25094802009-08-06 00:38:46 +0000463 // PrimaryBase goes first.
Anders Carlssona30c0d32009-11-27 22:14:40 +0000464 if (PrimaryBase.getBase()) {
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000465 if (PrimaryBase.isVirtual()) {
Anders Carlssona30c0d32009-11-27 22:14:40 +0000466 IndirectPrimaryBases.insert(PrimaryBase.getBase());
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000467
468 LayoutVirtualBase(PrimaryBase.getBase());
469 } else {
470 LayoutNonVirtualBase(PrimaryBase.getBase());
471 }
Mike Stump13007542009-08-13 02:02:14 +0000472 }
Mike Stump3dc7eb92009-07-30 00:22:38 +0000473 LayoutNonVirtualBases(RD);
Mike Stump3dc7eb92009-07-30 00:22:38 +0000474 }
Anders Carlsson6d9f6f32009-07-19 00:18:47 +0000475
Anders Carlsson118ce162009-07-18 21:48:39 +0000476 LayoutFields(D);
Mike Stump11289f42009-09-09 15:08:12 +0000477
Anders Carlssonfc8cfa82009-07-28 19:24:15 +0000478 NonVirtualSize = Size;
479 NonVirtualAlignment = Alignment;
Mike Stump3dc7eb92009-07-30 00:22:38 +0000480
Mike Stump22ea1f82009-08-16 01:46:26 +0000481 if (RD) {
482 llvm::SmallSet<const CXXRecordDecl*, 32> mark;
Anders Carlssona30c0d32009-11-27 22:14:40 +0000483 LayoutVirtualBases(RD, RD, PrimaryBase.getBase(),
484 0, mark, IndirectPrimaryBases);
Mike Stump22ea1f82009-08-16 01:46:26 +0000485 }
Mike Stump6b2556f2009-08-06 13:41:24 +0000486
Anders Carlsson79474332009-07-18 20:20:21 +0000487 // Finally, round the size of the total struct up to the alignment of the
488 // struct itself.
489 FinishLayout();
490}
491
Fariborz Jahanianaef66222010-02-19 00:31:17 +0000492// FIXME. Impl is no longer needed.
Anders Carlsson4f516282009-07-18 20:50:59 +0000493void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
494 const ObjCImplementationDecl *Impl) {
495 if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
496 const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD);
497
498 UpdateAlignment(SL.getAlignment());
Mike Stump11289f42009-09-09 15:08:12 +0000499
Anders Carlsson4f516282009-07-18 20:50:59 +0000500 // We start laying out ivars not at the end of the superclass
501 // structure, but at the next byte following the last field.
Anders Carlsson27b50132009-07-18 21:26:44 +0000502 Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8);
Anders Carlsson47680d82009-09-26 01:34:51 +0000503 DataSize = Size;
Anders Carlsson4f516282009-07-18 20:50:59 +0000504 }
Mike Stump11289f42009-09-09 15:08:12 +0000505
Anders Carlsson28a5fa22009-08-08 19:38:24 +0000506 Packed = D->hasAttr<PackedAttr>();
Mike Stump11289f42009-09-09 15:08:12 +0000507
Anders Carlsson28a5fa22009-08-08 19:38:24 +0000508 // The #pragma pack attribute specifies the maximum field alignment.
509 if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
510 MaxFieldAlignment = PPA->getAlignment();
Mike Stump11289f42009-09-09 15:08:12 +0000511
Anders Carlsson4f516282009-07-18 20:50:59 +0000512 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
Alexis Hunt96d5c762009-11-21 08:43:09 +0000513 UpdateAlignment(AA->getMaxAlignment());
Anders Carlsson4f516282009-07-18 20:50:59 +0000514 // Layout each ivar sequentially.
515 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
Fariborz Jahanianaef66222010-02-19 00:31:17 +0000516 Ctx.ShallowCollectObjCIvars(D, Ivars);
Anders Carlsson4f516282009-07-18 20:50:59 +0000517 for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
518 LayoutField(Ivars[i]);
Mike Stump11289f42009-09-09 15:08:12 +0000519
Anders Carlsson4f516282009-07-18 20:50:59 +0000520 // Finally, round the size of the total struct up to the alignment of the
521 // struct itself.
522 FinishLayout();
523}
524
Anders Carlsson118ce162009-07-18 21:48:39 +0000525void ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
526 // Layout each field, for now, just sequentially, respecting alignment. In
527 // the future, this will need to be tweakable by targets.
Mike Stump11289f42009-09-09 15:08:12 +0000528 for (RecordDecl::field_iterator Field = D->field_begin(),
Anders Carlsson118ce162009-07-18 21:48:39 +0000529 FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
530 LayoutField(*Field);
531}
532
Anders Carlsson07209442009-11-22 17:37:31 +0000533void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
534 bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
Anders Carlssonba958402009-11-22 19:13:51 +0000535 uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
Anders Carlsson07209442009-11-22 17:37:31 +0000536 uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
537
538 std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
539 uint64_t TypeSize = FieldInfo.first;
540 unsigned FieldAlign = FieldInfo.second;
541
542 if (FieldPacked)
543 FieldAlign = 1;
544 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
545 FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
546
547 // The maximum field alignment overrides the aligned attribute.
548 if (MaxFieldAlignment)
549 FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
550
551 // Check if we need to add padding to give the field the correct
552 // alignment.
553 if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
554 FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
555
556 // Padding members don't affect overall alignment
557 if (!D->getIdentifier())
558 FieldAlign = 1;
559
560 // Place this field at the current location.
561 FieldOffsets.push_back(FieldOffset);
562
Anders Carlssonba958402009-11-22 19:13:51 +0000563 // Update DataSize to include the last byte containing (part of) the bitfield.
564 if (IsUnion) {
565 // FIXME: I think FieldSize should be TypeSize here.
566 DataSize = std::max(DataSize, FieldSize);
567 } else {
568 uint64_t NewSizeInBits = FieldOffset + FieldSize;
569
570 DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
571 UnfilledBitsInLastByte = DataSize - NewSizeInBits;
572 }
Anders Carlsson07209442009-11-22 17:37:31 +0000573
Anders Carlssonba958402009-11-22 19:13:51 +0000574 // Update the size.
575 Size = std::max(Size, DataSize);
Anders Carlsson07209442009-11-22 17:37:31 +0000576
577 // Remember max struct/class alignment.
578 UpdateAlignment(FieldAlign);
579}
580
Anders Carlsson79474332009-07-18 20:20:21 +0000581void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
Anders Carlsson07209442009-11-22 17:37:31 +0000582 if (D->isBitField()) {
583 LayoutBitField(D);
584 return;
585 }
586
Anders Carlssonba958402009-11-22 19:13:51 +0000587 // Reset the unfilled bits.
588 UnfilledBitsInLastByte = 0;
589
Anders Carlsson07209442009-11-22 17:37:31 +0000590 bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
Anders Carlsson47680d82009-09-26 01:34:51 +0000591 uint64_t FieldOffset = IsUnion ? 0 : DataSize;
Anders Carlsson79474332009-07-18 20:20:21 +0000592 uint64_t FieldSize;
593 unsigned FieldAlign;
Anders Carlsson07209442009-11-22 17:37:31 +0000594
595 if (D->getType()->isIncompleteArrayType()) {
596 // This is a flexible array member; we can't directly
597 // query getTypeInfo about these, so we figure it out here.
598 // Flexible array members don't have any size, but they
599 // have to be aligned appropriately for their element type.
600 FieldSize = 0;
601 const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
602 FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
603 } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
604 unsigned AS = RT->getPointeeType().getAddressSpace();
605 FieldSize = Ctx.Target.getPointerWidth(AS);
606 FieldAlign = Ctx.Target.getPointerAlign(AS);
Anders Carlsson79474332009-07-18 20:20:21 +0000607 } else {
Anders Carlsson07209442009-11-22 17:37:31 +0000608 std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
609 FieldSize = FieldInfo.first;
610 FieldAlign = FieldInfo.second;
Anders Carlsson79474332009-07-18 20:20:21 +0000611 }
Mike Stump11289f42009-09-09 15:08:12 +0000612
Anders Carlsson07209442009-11-22 17:37:31 +0000613 if (FieldPacked)
614 FieldAlign = 8;
615 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
616 FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
617
618 // The maximum field alignment overrides the aligned attribute.
619 if (MaxFieldAlignment)
620 FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
621
622 // Round up the current record size to the field's alignment boundary.
623 FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
624
625 if (!IsUnion) {
626 while (true) {
627 // Check if we can place the field at this offset.
628 if (canPlaceFieldAtOffset(D, FieldOffset))
629 break;
630
631 // We couldn't place the field at the offset. Try again at a new offset.
632 FieldOffset += FieldAlign;
633 }
634
635 UpdateEmptyClassOffsets(D, FieldOffset);
636 }
637
Anders Carlsson79474332009-07-18 20:20:21 +0000638 // Place this field at the current location.
639 FieldOffsets.push_back(FieldOffset);
Mike Stump11289f42009-09-09 15:08:12 +0000640
Anders Carlsson79474332009-07-18 20:20:21 +0000641 // Reserve space for this field.
642 if (IsUnion)
643 Size = std::max(Size, FieldSize);
644 else
645 Size = FieldOffset + FieldSize;
Mike Stump11289f42009-09-09 15:08:12 +0000646
Anders Carlsson47680d82009-09-26 01:34:51 +0000647 // Update the data size.
648 DataSize = Size;
Mike Stump11289f42009-09-09 15:08:12 +0000649
Anders Carlsson79474332009-07-18 20:20:21 +0000650 // Remember max struct/class alignment.
651 UpdateAlignment(FieldAlign);
652}
653
654void ASTRecordLayoutBuilder::FinishLayout() {
655 // In C++, records cannot be of size 0.
656 if (Ctx.getLangOptions().CPlusPlus && Size == 0)
657 Size = 8;
658 // Finally, round the size of the record up to the alignment of the
659 // record itself.
Anders Carlsson07209442009-11-22 17:37:31 +0000660 Size = llvm::RoundUpToAlignment(Size, Alignment);
Anders Carlsson79474332009-07-18 20:20:21 +0000661}
662
663void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
664 if (NewAlignment <= Alignment)
665 return;
Mike Stump11289f42009-09-09 15:08:12 +0000666
Anders Carlsson79474332009-07-18 20:20:21 +0000667 assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2"));
Mike Stump11289f42009-09-09 15:08:12 +0000668
Anders Carlsson79474332009-07-18 20:20:21 +0000669 Alignment = NewAlignment;
670}
Mike Stump11289f42009-09-09 15:08:12 +0000671
Anders Carlsson5ebf8b42009-12-07 04:35:11 +0000672const ASTRecordLayout *
673ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
674 const RecordDecl *D) {
675 ASTRecordLayoutBuilder Builder(Ctx);
676
677 Builder.Layout(D);
678
679 if (!isa<CXXRecordDecl>(D))
Ted Kremenekc3015a92010-03-08 20:56:29 +0000680 return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
681 Builder.Size,
682 Builder.FieldOffsets.data(),
683 Builder.FieldOffsets.size());
Anders Carlsson5ebf8b42009-12-07 04:35:11 +0000684
685 // FIXME: This is not always correct. See the part about bitfields at
686 // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
687 // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
688 bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
689
690 // FIXME: This should be done in FinalizeLayout.
691 uint64_t DataSize =
692 IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize;
693 uint64_t NonVirtualSize =
694 IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
695
Ted Kremenekc3015a92010-03-08 20:56:29 +0000696 return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
697 DataSize, Builder.FieldOffsets.data(),
698 Builder.FieldOffsets.size(),
699 NonVirtualSize,
700 Builder.NonVirtualAlignment,
701 Builder.PrimaryBase,
702 Builder.Bases.data(),
703 Builder.Bases.size(),
704 Builder.VBases.data(),
705 Builder.VBases.size());
Anders Carlsson5ebf8b42009-12-07 04:35:11 +0000706}
707
708const ASTRecordLayout *
709ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
710 const ObjCInterfaceDecl *D,
711 const ObjCImplementationDecl *Impl) {
712 ASTRecordLayoutBuilder Builder(Ctx);
713
714 Builder.Layout(D, Impl);
715
Ted Kremenekc3015a92010-03-08 20:56:29 +0000716 return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
717 Builder.DataSize,
718 Builder.FieldOffsets.data(),
719 Builder.FieldOffsets.size());
Anders Carlsson5ebf8b42009-12-07 04:35:11 +0000720}
721
722const CXXMethodDecl *
723ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
724 assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
725
726 // If a class isnt' polymorphic it doesn't have a key function.
727 if (!RD->isPolymorphic())
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +0000728 return 0;
Eli Friedmanf2c79b62009-12-08 03:56:49 +0000729
730 // A class inside an anonymous namespace doesn't have a key function. (Or
731 // at least, there's no point to assigning a key function to such a class;
732 // this doesn't affect the ABI.)
733 if (RD->isInAnonymousNamespace())
734 return 0;
735
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +0000736 for (CXXRecordDecl::method_iterator I = RD->method_begin(),
737 E = RD->method_end(); I != E; ++I) {
738 const CXXMethodDecl *MD = *I;
739
740 if (!MD->isVirtual())
741 continue;
742
743 if (MD->isPure())
744 continue;
Eli Friedmanf2c79b62009-12-08 03:56:49 +0000745
Anders Carlssonf98849e2009-12-02 17:15:43 +0000746 // Ignore implicit member functions, they are always marked as inline, but
747 // they don't have a body until they're defined.
748 if (MD->isImplicit())
749 continue;
Douglas Gregora318efd2010-01-05 19:06:31 +0000750
751 if (MD->isInlineSpecified())
752 continue;
Eli Friedman71a26d82009-12-06 20:50:05 +0000753
754 if (MD->hasInlineBody())
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +0000755 continue;
756
757 // We found it.
758 return MD;
759 }
760
761 return 0;
762}
763