blob: df7ed57a580a5a72aca7872af6fcd4fc58abbf15 [file] [log] [blame]
Anders Carlsson35a36eb2010-05-26 05:41:04 +00001//=== RecordLayoutBuilder.cpp - Helper class for building record layouts ---==//
Anders Carlsson79474332009-07-18 20:20:21 +00002//
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
Anders Carlsson79474332009-07-18 20:20:21 +000010#include "clang/AST/Attr.h"
11#include "clang/AST/Decl.h"
Anders Carlsson6d9f6f32009-07-19 00:18:47 +000012#include "clang/AST/DeclCXX.h"
Anders Carlsson4f516282009-07-18 20:50:59 +000013#include "clang/AST/DeclObjC.h"
Anders Carlsson79474332009-07-18 20:20:21 +000014#include "clang/AST/Expr.h"
Anders Carlsson35a36eb2010-05-26 05:41:04 +000015#include "clang/AST/RecordLayout.h"
Anders Carlsson79474332009-07-18 20:20:21 +000016#include "clang/Basic/TargetInfo.h"
Daniel Dunbaraa423af2010-04-08 02:59:49 +000017#include "llvm/Support/Format.h"
18#include "llvm/ADT/SmallSet.h"
19#include "llvm/Support/MathExtras.h"
Anders Carlsson35a36eb2010-05-26 05:41:04 +000020#include <map>
Anders Carlsson79474332009-07-18 20:20:21 +000021
22using namespace clang;
23
Benjamin Kramerc7656cd2010-05-26 09:58:31 +000024namespace {
Anders Carlssonf58de112010-05-26 15:32:58 +000025
26/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different
27/// offsets while laying out a C++ class.
28class EmptySubobjectMap {
29 ASTContext &Context;
Daniel Dunbar592a85c2010-05-27 02:25:46 +000030
Anders Carlssonf58de112010-05-26 15:32:58 +000031 /// Class - The class whose empty entries we're keeping track of.
32 const CXXRecordDecl *Class;
Daniel Dunbar592a85c2010-05-27 02:25:46 +000033
Anders Carlsson439edd12010-05-27 05:41:06 +000034 /// EmptyClassOffsets - A map from offsets to empty record decls.
35 typedef llvm::SmallVector<const CXXRecordDecl *, 1> ClassVectorTy;
36 typedef llvm::DenseMap<uint64_t, ClassVectorTy> EmptyClassOffsetsMapTy;
37 EmptyClassOffsetsMapTy EmptyClassOffsets;
38
Daniel Dunbar592a85c2010-05-27 02:25:46 +000039 /// ComputeEmptySubobjectSizes - Compute the size of the largest base or
Anders Carlssonc5ca1f72010-05-26 15:54:25 +000040 /// member subobject that is empty.
41 void ComputeEmptySubobjectSizes();
Daniel Dunbar592a85c2010-05-27 02:25:46 +000042
Anders Carlsson439edd12010-05-27 05:41:06 +000043 struct BaseInfo {
44 const CXXRecordDecl *Class;
45 bool IsVirtual;
46
47 const CXXRecordDecl *PrimaryVirtualBase;
48
49 llvm::SmallVector<BaseInfo*, 4> Bases;
50 const BaseInfo *Derived;
51 };
52
53 llvm::DenseMap<const CXXRecordDecl *, BaseInfo *> VirtualBaseInfo;
54 llvm::DenseMap<const CXXRecordDecl *, BaseInfo *> NonVirtualBaseInfo;
55
56 BaseInfo *ComputeBaseInfo(const CXXRecordDecl *RD, bool IsVirtual,
57 const BaseInfo *Derived);
58 void ComputeBaseInfo();
59
60 bool CanPlaceBaseSubobjectAtOffset(const BaseInfo *Info, uint64_t Offset);
61 void UpdateEmptyBaseSubobjects(const BaseInfo *Info, uint64_t Offset);
62
Anders Carlssonf58de112010-05-26 15:32:58 +000063public:
Anders Carlssonc5ca1f72010-05-26 15:54:25 +000064 /// This holds the size of the largest empty subobject (either a base
Daniel Dunbar592a85c2010-05-27 02:25:46 +000065 /// or a member). Will be zero if the record being built doesn't contain
Anders Carlssonc5ca1f72010-05-26 15:54:25 +000066 /// any empty classes.
67 uint64_t SizeOfLargestEmptySubobject;
Daniel Dunbar592a85c2010-05-27 02:25:46 +000068
Anders Carlssonf58de112010-05-26 15:32:58 +000069 EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class)
Anders Carlssonc121b4e2010-05-27 00:07:01 +000070 : Context(Context), Class(Class), SizeOfLargestEmptySubobject(0) {
71 ComputeEmptySubobjectSizes();
Anders Carlsson439edd12010-05-27 05:41:06 +000072
73 ComputeBaseInfo();
Anders Carlssonc121b4e2010-05-27 00:07:01 +000074 }
75
76 /// CanPlaceBaseAtOffset - Return whether the given base class can be placed
77 /// at the given offset.
Daniel Dunbar592a85c2010-05-27 02:25:46 +000078 /// Returns false if placing the record will result in two components
Anders Carlssonc121b4e2010-05-27 00:07:01 +000079 /// (direct or indirect) of the same type having the same offset.
80 bool CanPlaceBaseAtOffset(const CXXRecordDecl *RD, bool BaseIsVirtual,
81 uint64_t Offset);
Anders Carlssonf58de112010-05-26 15:32:58 +000082};
Anders Carlssonc5ca1f72010-05-26 15:54:25 +000083
84void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
85 // Check the bases.
86 for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
87 E = Class->bases_end(); I != E; ++I) {
88 const CXXRecordDecl *BaseDecl =
89 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
90
91 uint64_t EmptySize = 0;
92 const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
93 if (BaseDecl->isEmpty()) {
94 // If the class decl is empty, get its size.
95 EmptySize = Layout.getSize();
96 } else {
97 // Otherwise, we get the largest empty subobject for the decl.
98 EmptySize = Layout.getSizeOfLargestEmptySubobject();
99 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000100
101 SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000102 EmptySize);
103 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000104
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000105 // Check the fields.
106 for (CXXRecordDecl::field_iterator I = Class->field_begin(),
107 E = Class->field_end(); I != E; ++I) {
108 const FieldDecl *FD = *I;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000109
110 const RecordType *RT =
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000111 Context.getBaseElementType(FD->getType())->getAs<RecordType>();
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000112
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000113 // We only care about record types.
114 if (!RT)
115 continue;
116
117 uint64_t EmptySize = 0;
118 const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
119 const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
120 if (MemberDecl->isEmpty()) {
121 // If the class decl is empty, get its size.
122 EmptySize = Layout.getSize();
123 } else {
124 // Otherwise, we get the largest empty subobject for the decl.
125 EmptySize = Layout.getSizeOfLargestEmptySubobject();
126 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000127
128 SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000129 EmptySize);
130 }
131}
132
Anders Carlsson439edd12010-05-27 05:41:06 +0000133EmptySubobjectMap::BaseInfo *
134EmptySubobjectMap::ComputeBaseInfo(const CXXRecordDecl *RD, bool IsVirtual,
135 const BaseInfo *Derived) {
136 BaseInfo *Info;
137
138 if (IsVirtual) {
139 BaseInfo *&InfoSlot = VirtualBaseInfo[RD];
140 if (InfoSlot) {
141 assert(InfoSlot->Class == RD && "Wrong class for virtual base info!");
142 return InfoSlot;
143 }
144
145 InfoSlot = new (Context) BaseInfo;
146 Info = InfoSlot;
147 } else {
148 Info = new (Context) BaseInfo;
149 }
150
151 Info->Class = RD;
152 Info->IsVirtual = IsVirtual;
153 Info->Derived = Derived;
154 Info->PrimaryVirtualBase = 0;
155
156 if (RD->getNumVBases()) {
157 // Check if this class has a primary virtual base.
158 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
159 if (Layout.getPrimaryBaseWasVirtual()) {
160 Info->PrimaryVirtualBase = Layout.getPrimaryBase();
161 assert(Info->PrimaryVirtualBase &&
162 "Didn't have a primary virtual base!");
163 }
164 }
165
166 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
167 E = RD->bases_end(); I != E; ++I) {
168 bool IsVirtual = I->isVirtual();
169
170 const CXXRecordDecl *BaseDecl =
171 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
172
173 Info->Bases.push_back(ComputeBaseInfo(BaseDecl, IsVirtual, Info));
174 }
175
176 return Info;
177}
178
179void EmptySubobjectMap::ComputeBaseInfo() {
180 for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
181 E = Class->bases_end(); I != E; ++I) {
182 bool IsVirtual = I->isVirtual();
183
184 const CXXRecordDecl *BaseDecl =
185 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
186
187 BaseInfo *Info = ComputeBaseInfo(BaseDecl, IsVirtual, /*Derived=*/0);
188 if (IsVirtual) {
189 // ComputeBaseInfo has already added this base for us.
190 continue;
191 }
192
193 // Add the base info to the map of non-virtual bases.
194 assert(!NonVirtualBaseInfo.count(BaseDecl) &&
195 "Non-virtual base already exists!");
196 NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info));
197 }
198}
199
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000200bool
Anders Carlsson439edd12010-05-27 05:41:06 +0000201EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseInfo *Info,
202 uint64_t Offset) {
203 // Traverse all non-virtual bases.
204 for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
205 BaseInfo* Base = Info->Bases[I];
206 if (Base->IsVirtual)
207 continue;
208
209 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
210 uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
211
212 if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset))
213 return false;
214 }
215
216 if (Info->PrimaryVirtualBase) {
217 BaseInfo *PrimaryVirtualBaseInfo =
218 VirtualBaseInfo.lookup(Info->PrimaryVirtualBase);
219 assert(PrimaryVirtualBaseInfo && "Didn't find base info!");
220
221 if (Info == PrimaryVirtualBaseInfo->Derived) {
222 if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset))
223 return false;
224 }
225 }
226
227 // FIXME: Member variables.
228 return true;
229}
230
231void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseInfo *Info,
232 uint64_t Offset) {
233 if (Info->Class->isEmpty()) {
234 // FIXME: Record that there is an empty class at this offset.
235 }
236
237 // Traverse all non-virtual bases.
238 for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
239 BaseInfo* Base = Info->Bases[I];
240 if (Base->IsVirtual)
241 continue;
242
243 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
244 uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
245
246 UpdateEmptyBaseSubobjects(Base, BaseOffset);
247 }
248
249 if (Info->PrimaryVirtualBase) {
250 BaseInfo *PrimaryVirtualBaseInfo =
251 VirtualBaseInfo.lookup(Info->PrimaryVirtualBase);
252 assert(PrimaryVirtualBaseInfo && "Didn't find base info!");
253
254 if (Info == PrimaryVirtualBaseInfo->Derived)
255 UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset);
256 }
257
258 // FIXME: Member variables.
259}
260
261bool EmptySubobjectMap::CanPlaceBaseAtOffset(const CXXRecordDecl *RD,
262 bool BaseIsVirtual,
263 uint64_t Offset) {
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000264 // If we know this class doesn't have any empty subobjects we don't need to
265 // bother checking.
266 if (!SizeOfLargestEmptySubobject)
267 return true;
268
Anders Carlsson439edd12010-05-27 05:41:06 +0000269 BaseInfo *Info;
270
271 if (BaseIsVirtual)
272 Info = VirtualBaseInfo.lookup(RD);
273 else
274 Info = NonVirtualBaseInfo.lookup(RD);
275
276 if (!CanPlaceBaseSubobjectAtOffset(Info, Offset))
277 return false;
278
279 UpdateEmptyBaseSubobjects(Info, Offset);
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000280 return true;
281}
282
Anders Carlssonc2226202010-05-26 05:58:59 +0000283class RecordLayoutBuilder {
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000284 // FIXME: Remove this and make the appropriate fields public.
285 friend class clang::ASTContext;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000286
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000287 ASTContext &Context;
288
Anders Carlssonf58de112010-05-26 15:32:58 +0000289 EmptySubobjectMap *EmptySubobjects;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000290
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000291 /// Size - The current size of the record layout.
292 uint64_t Size;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000293
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000294 /// Alignment - The current alignment of the record layout.
295 unsigned Alignment;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000296
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000297 llvm::SmallVector<uint64_t, 16> FieldOffsets;
298
299 /// Packed - Whether the record is packed or not.
300 bool Packed;
301
302 /// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
303 /// this contains the number of bits in the last byte that can be used for
304 /// an adjacent bitfield if necessary.
305 unsigned char UnfilledBitsInLastByte;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000306
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000307 /// MaxFieldAlignment - The maximum allowed field alignment. This is set by
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000308 /// #pragma pack.
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000309 unsigned MaxFieldAlignment;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000310
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000311 /// DataSize - The data size of the record being laid out.
312 uint64_t DataSize;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000313
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000314 bool IsUnion;
315
316 uint64_t NonVirtualSize;
317 unsigned NonVirtualAlignment;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000318
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000319 /// PrimaryBase - the primary base class (if one exists) of the class
320 /// we're laying out.
321 const CXXRecordDecl *PrimaryBase;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000322
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000323 /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying
324 /// out is virtual.
325 bool PrimaryBaseIsVirtual;
326
327 typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000328
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000329 /// Bases - base classes and their offsets in the record.
330 BaseOffsetsMapTy Bases;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000331
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000332 // VBases - virtual base classes and their offsets in the record.
333 BaseOffsetsMapTy VBases;
334
335 /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
336 /// primary base classes for some other direct or indirect base class.
337 llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000338
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000339 /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in
340 /// inheritance graph order. Used for determining the primary base class.
341 const CXXRecordDecl *FirstNearlyEmptyVBase;
342
343 /// VisitedVirtualBases - A set of all the visited virtual bases, used to
344 /// avoid visiting virtual bases more than once.
345 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000346
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000347 /// EmptyClassOffsets - A map from offsets to empty record decls.
348 typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
349 EmptyClassOffsetsTy EmptyClassOffsets;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000350
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000351 RecordLayoutBuilder(ASTContext &Context, EmptySubobjectMap *EmptySubobjects)
352 : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(8),
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000353 Packed(false), UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0),
354 IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0),
Anders Carlssonc5ca1f72010-05-26 15:54:25 +0000355 PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000356
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000357 void Layout(const RecordDecl *D);
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000358 void Layout(const CXXRecordDecl *D);
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000359 void Layout(const ObjCInterfaceDecl *D);
360
361 void LayoutFields(const RecordDecl *D);
362 void LayoutField(const FieldDecl *D);
363 void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
364 void LayoutBitField(const FieldDecl *D);
365
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000366 /// ComputeEmptySubobjectSizes - Compute the size of the largest base or
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000367 /// member subobject that is empty.
368 void ComputeEmptySubobjectSizes(const CXXRecordDecl *RD);
369
370 /// DeterminePrimaryBase - Determine the primary base of the given class.
371 void DeterminePrimaryBase(const CXXRecordDecl *RD);
372
373 void SelectPrimaryVBase(const CXXRecordDecl *RD);
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000374
375 /// IdentifyPrimaryBases - Identify all virtual base classes, direct or
376 /// indirect, that are primary base classes for some other direct or indirect
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000377 /// base class.
378 void IdentifyPrimaryBases(const CXXRecordDecl *RD);
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000379
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000380 bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000381
382 /// LayoutNonVirtualBases - Determines the primary base class (if any) and
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000383 /// lays it out. Will then proceed to lay out all non-virtual base clasess.
384 void LayoutNonVirtualBases(const CXXRecordDecl *RD);
385
386 /// LayoutNonVirtualBase - Lays out a single non-virtual base.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000387 void LayoutNonVirtualBase(const CXXRecordDecl *Base);
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000388
389 void AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
390 const CXXRecordDecl *MostDerivedClass);
391
392 /// LayoutVirtualBases - Lays out all the virtual bases.
393 void LayoutVirtualBases(const CXXRecordDecl *RD,
394 const CXXRecordDecl *MostDerivedClass);
395
396 /// LayoutVirtualBase - Lays out a single virtual base.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000397 void LayoutVirtualBase(const CXXRecordDecl *Base);
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000398
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000399 /// LayoutBase - Will lay out a base and return the offset where it was
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000400 /// placed, in bits.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000401 uint64_t LayoutBase(const CXXRecordDecl *Base, bool BaseIsVirtual);
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000402
403 /// canPlaceRecordAtOffset - Return whether a record (either a base class
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000404 /// or a field) can be placed at the given offset.
405 /// Returns false if placing the record will result in two components
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000406 /// (direct or indirect) of the same type having the same offset.
407 bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset,
408 bool CheckVBases) const;
409
410 /// canPlaceFieldAtOffset - Return whether a field can be placed at the given
411 /// offset.
412 bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
413
414 /// UpdateEmptyClassOffsets - Called after a record (either a base class
415 /// or a field) has been placed at the given offset. Will update the
416 /// EmptyClassOffsets map if the class is empty or has any empty bases or
417 /// fields.
418 void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset,
419 bool UpdateVBases);
420
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000421 /// UpdateEmptyClassOffsets - Called after a field has been placed at the
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000422 /// given offset.
423 void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000424
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000425 /// InitializeLayout - Initialize record layout for the given record decl.
426 void InitializeLayout(const RecordDecl *D);
427
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000428 /// FinishLayout - Finalize record layout. Adjust record size based on the
429 /// alignment.
430 void FinishLayout();
431
432 void UpdateAlignment(unsigned NewAlignment);
433
Anders Carlssonc2226202010-05-26 05:58:59 +0000434 RecordLayoutBuilder(const RecordLayoutBuilder&); // DO NOT IMPLEMENT
435 void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000436public:
437 static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
438};
Benjamin Kramerc7656cd2010-05-26 09:58:31 +0000439} // end anonymous namespace
Anders Carlsson35a36eb2010-05-26 05:41:04 +0000440
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000441/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
442/// no other data.
Anders Carlssonc2226202010-05-26 05:58:59 +0000443bool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000444 // FIXME: Audit the corners
445 if (!RD->isDynamicClass())
446 return false;
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000447 const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
448 if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0))
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000449 return true;
450 return false;
451}
452
Anders Carlssonc2226202010-05-26 05:58:59 +0000453void RecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000454 const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000455 Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000456
Anders Carlsson81430692009-09-22 03:02:06 +0000457 // If the record has a primary base class that is virtual, add it to the set
458 // of primary bases.
Anders Carlssona30c0d32009-11-27 22:14:40 +0000459 if (BaseInfo.isVirtual())
460 IndirectPrimaryBases.insert(BaseInfo.getBase());
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000461
Anders Carlsson81430692009-09-22 03:02:06 +0000462 // Now traverse all bases and find primary bases for them.
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000463 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000464 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000465 assert(!i->getType()->isDependentType() &&
466 "Cannot layout class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +0000467 const CXXRecordDecl *Base =
Mike Stump78696a72009-08-11 04:03:59 +0000468 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000469
Mike Stump78696a72009-08-11 04:03:59 +0000470 // Only bases with virtual bases participate in computing the
471 // indirect primary virtual base classes.
Mike Stumpc2f591b2009-08-13 22:53:07 +0000472 if (Base->getNumVBases())
Anders Carlsson81430692009-09-22 03:02:06 +0000473 IdentifyPrimaryBases(Base);
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000474 }
475}
476
Anders Carlsson81430692009-09-22 03:02:06 +0000477void
Anders Carlssonc2226202010-05-26 05:58:59 +0000478RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
Anders Carlssonf2fa75b2010-03-11 03:39:12 +0000479 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000480 E = RD->bases_end(); I != E; ++I) {
Anders Carlssonf2fa75b2010-03-11 03:39:12 +0000481 assert(!I->getType()->isDependentType() &&
Sebastian Redl1054fae2009-10-25 17:03:50 +0000482 "Cannot layout class with dependent bases.");
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000483
Mike Stump11289f42009-09-09 15:08:12 +0000484 const CXXRecordDecl *Base =
Anders Carlssonf2fa75b2010-03-11 03:39:12 +0000485 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000486
Anders Carlssonf2fa75b2010-03-11 03:39:12 +0000487 // Check if this is a nearly empty virtual base.
488 if (I->isVirtual() && IsNearlyEmpty(Base)) {
489 // If it's not an indirect primary base, then we've found our primary
490 // base.
Anders Carlsson81430692009-09-22 03:02:06 +0000491 if (!IndirectPrimaryBases.count(Base)) {
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000492 PrimaryBase = Base;
493 PrimaryBaseIsVirtual = true;
Mike Stump6f3793b2009-08-12 21:50:08 +0000494 return;
495 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000496
Anders Carlssonf2fa75b2010-03-11 03:39:12 +0000497 // Is this the first nearly empty virtual base?
498 if (!FirstNearlyEmptyVBase)
499 FirstNearlyEmptyVBase = Base;
Mike Stump6f3793b2009-08-12 21:50:08 +0000500 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000501
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000502 SelectPrimaryVBase(Base);
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000503 if (PrimaryBase)
Zhongxing Xuec345b72010-02-15 04:28:35 +0000504 return;
Mike Stump6f3793b2009-08-12 21:50:08 +0000505 }
506}
507
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000508/// DeterminePrimaryBase - Determine the primary base of the given class.
Anders Carlssonc2226202010-05-26 05:58:59 +0000509void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000510 // If the class isn't dynamic, it won't have a primary base.
511 if (!RD->isDynamicClass())
512 return;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000513
Anders Carlsson81430692009-09-22 03:02:06 +0000514 // Compute all the primary virtual bases for all of our direct and
Mike Stump590a7c72009-08-13 23:26:06 +0000515 // indirect bases, and record all their primary virtual base classes.
Mike Stump590a7c72009-08-13 23:26:06 +0000516 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000517 e = RD->bases_end(); i != e; ++i) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000518 assert(!i->getType()->isDependentType() &&
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000519 "Cannot lay out class with dependent bases.");
Mike Stump11289f42009-09-09 15:08:12 +0000520 const CXXRecordDecl *Base =
Mike Stump590a7c72009-08-13 23:26:06 +0000521 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlsson81430692009-09-22 03:02:06 +0000522 IdentifyPrimaryBases(Base);
Mike Stump590a7c72009-08-13 23:26:06 +0000523 }
524
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000525 // If the record has a dynamic base class, attempt to choose a primary base
526 // class. It is the first (in direct base class order) non-virtual dynamic
Anders Carlsson81430692009-09-22 03:02:06 +0000527 // base class, if one exists.
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000528 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000529 e = RD->bases_end(); i != e; ++i) {
Anders Carlsson03ff3792009-11-27 22:05:05 +0000530 // Ignore virtual bases.
531 if (i->isVirtual())
532 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000533
Anders Carlsson03ff3792009-11-27 22:05:05 +0000534 const CXXRecordDecl *Base =
535 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
536
537 if (Base->isDynamicClass()) {
538 // We found it.
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000539 PrimaryBase = Base;
540 PrimaryBaseIsVirtual = false;
Anders Carlsson03ff3792009-11-27 22:05:05 +0000541 return;
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000542 }
543 }
544
545 // Otherwise, it is the first nearly empty virtual base that is not an
Mike Stump78696a72009-08-11 04:03:59 +0000546 // indirect primary virtual base class, if one exists.
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000547 if (RD->getNumVBases() != 0) {
548 SelectPrimaryVBase(RD);
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000549 if (PrimaryBase)
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000550 return;
551 }
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000552
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000553 // Otherwise, it is the first nearly empty virtual base that is not an
554 // indirect primary virtual base class, if one exists.
555 if (FirstNearlyEmptyVBase) {
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000556 PrimaryBase = FirstNearlyEmptyVBase;
557 PrimaryBaseIsVirtual = true;
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000558 return;
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000559 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000560
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000561 // Otherwise there is no primary base class.
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000562 assert(!PrimaryBase && "Should not get here with a primary base!");
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000563
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000564 // Allocate the virtual table pointer at offset zero.
565 assert(DataSize == 0 && "Vtable pointer must be at offset zero!");
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000566
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000567 // Update the size.
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000568 Size += Context.Target.getPointerWidth(0);
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000569 DataSize = Size;
570
571 // Update the alignment.
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000572 UpdateAlignment(Context.Target.getPointerAlign(0));
Mike Stumpd8fe7b22009-08-05 22:37:18 +0000573}
574
Anders Carlsson09ffa322010-03-10 22:21:28 +0000575void
Anders Carlssonc2226202010-05-26 05:58:59 +0000576RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000577 // First, determine the primary base class.
578 DeterminePrimaryBase(RD);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000579
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000580 // If we have a primary base class, lay it out.
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000581 if (PrimaryBase) {
582 if (PrimaryBaseIsVirtual) {
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000583 // We have a virtual primary base, insert it as an indirect primary base.
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000584 IndirectPrimaryBases.insert(PrimaryBase);
Anders Carlssonfe900962010-03-11 05:42:17 +0000585
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000586 assert(!VisitedVirtualBases.count(PrimaryBase) &&
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000587 "vbase already visited!");
588 VisitedVirtualBases.insert(PrimaryBase);
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000589
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000590 LayoutVirtualBase(PrimaryBase);
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000591 } else
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000592 LayoutNonVirtualBase(PrimaryBase);
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000593 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000594
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000595 // Now lay out the non-virtual bases.
596 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000597 E = RD->bases_end(); I != E; ++I) {
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000598
599 // Ignore virtual bases.
600 if (I->isVirtual())
601 continue;
602
603 const CXXRecordDecl *Base =
604 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
605
606 // Skip the primary base.
Anders Carlssonb48414f2010-05-26 05:31:23 +0000607 if (Base == PrimaryBase && !PrimaryBaseIsVirtual)
Anders Carlsson8630b5b2010-03-11 00:15:35 +0000608 continue;
609
610 // Lay out the base.
611 LayoutNonVirtualBase(Base);
Anders Carlsson09ffa322010-03-10 22:21:28 +0000612 }
613}
614
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000615void RecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *Base) {
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000616 // Layout the base.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000617 uint64_t Offset = LayoutBase(Base, /*BaseIsVirtual=*/false);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000618
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000619 // Add its base class offset.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000620 if (!Bases.insert(std::make_pair(Base, Offset)).second)
Anders Carlsson6a848892010-03-11 04:10:39 +0000621 assert(false && "Added same base offset more than once!");
Anders Carlsson09ffa322010-03-10 22:21:28 +0000622}
Mike Stump2b84dd32009-11-05 04:02:15 +0000623
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000624void
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000625RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD,
Anders Carlssonea7b1822010-04-15 16:12:58 +0000626 uint64_t Offset,
627 const CXXRecordDecl *MostDerivedClass) {
628 // We already have the offset for the primary base of the most derived class.
629 if (RD != MostDerivedClass) {
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000630 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonea7b1822010-04-15 16:12:58 +0000631 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
632
633 // If this is a primary virtual base and we haven't seen it before, add it.
634 if (PrimaryBase && Layout.getPrimaryBaseWasVirtual() &&
635 !VBases.count(PrimaryBase))
636 VBases.insert(std::make_pair(PrimaryBase, Offset));
637 }
638
639 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
640 E = RD->bases_end(); I != E; ++I) {
641 assert(!I->getType()->isDependentType() &&
642 "Cannot layout class with dependent bases.");
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000643
Anders Carlssonea7b1822010-04-15 16:12:58 +0000644 const CXXRecordDecl *BaseDecl =
645 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
646
647 if (!BaseDecl->getNumVBases()) {
648 // This base isn't interesting since it doesn't have any virtual bases.
649 continue;
650 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000651
Anders Carlssonea7b1822010-04-15 16:12:58 +0000652 // Compute the offset of this base.
653 uint64_t BaseOffset;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000654
Anders Carlssonea7b1822010-04-15 16:12:58 +0000655 if (I->isVirtual()) {
656 // If we don't know this vbase yet, don't visit it. It will be visited
657 // later.
658 if (!VBases.count(BaseDecl)) {
659 continue;
660 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000661
Anders Carlssonea7b1822010-04-15 16:12:58 +0000662 // Check if we've already visited this base.
663 if (!VisitedVirtualBases.insert(BaseDecl))
664 continue;
665
666 // We want the vbase offset from the class we're currently laying out.
667 BaseOffset = VBases[BaseDecl];
668 } else if (RD == MostDerivedClass) {
669 // We want the base offset from the class we're currently laying out.
670 assert(Bases.count(BaseDecl) && "Did not find base!");
671 BaseOffset = Bases[BaseDecl];
672 } else {
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000673 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonea7b1822010-04-15 16:12:58 +0000674 BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
675 }
676
677 AddPrimaryVirtualBaseOffsets(BaseDecl, BaseOffset, MostDerivedClass);
678 }
679}
680
681void
Anders Carlssonc2226202010-05-26 05:58:59 +0000682RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
Anders Carlssonea7b1822010-04-15 16:12:58 +0000683 const CXXRecordDecl *MostDerivedClass) {
Anders Carlssonde710c92010-03-11 04:33:54 +0000684 const CXXRecordDecl *PrimaryBase;
Anders Carlsson291279e2010-04-10 18:42:27 +0000685 bool PrimaryBaseIsVirtual;
Anders Carlssonfe900962010-03-11 05:42:17 +0000686
Anders Carlsson291279e2010-04-10 18:42:27 +0000687 if (MostDerivedClass == RD) {
Anders Carlssond20e7cd2010-05-26 05:20:58 +0000688 PrimaryBase = this->PrimaryBase;
689 PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;
Anders Carlsson291279e2010-04-10 18:42:27 +0000690 } else {
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000691 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonde710c92010-03-11 04:33:54 +0000692 PrimaryBase = Layout.getPrimaryBase();
Anders Carlsson291279e2010-04-10 18:42:27 +0000693 PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual();
694 }
695
Anders Carlssonf7b7a1e2010-03-11 04:24:02 +0000696 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
697 E = RD->bases_end(); I != E; ++I) {
698 assert(!I->getType()->isDependentType() &&
Sebastian Redl1054fae2009-10-25 17:03:50 +0000699 "Cannot layout class with dependent bases.");
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000700
Mike Stump11289f42009-09-09 15:08:12 +0000701 const CXXRecordDecl *Base =
Anders Carlssonf7b7a1e2010-03-11 04:24:02 +0000702 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
703
704 if (I->isVirtual()) {
Anders Carlsson291279e2010-04-10 18:42:27 +0000705 if (PrimaryBase != Base || !PrimaryBaseIsVirtual) {
706 bool IndirectPrimaryBase = IndirectPrimaryBases.count(Base);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000707
Anders Carlsson291279e2010-04-10 18:42:27 +0000708 // Only lay out the virtual base if it's not an indirect primary base.
709 if (!IndirectPrimaryBase) {
710 // Only visit virtual bases once.
711 if (!VisitedVirtualBases.insert(Base))
712 continue;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000713
Anders Carlssonfe900962010-03-11 05:42:17 +0000714 LayoutVirtualBase(Base);
Anders Carlsson6a848892010-03-11 04:10:39 +0000715 }
Mike Stump2b84dd32009-11-05 04:02:15 +0000716 }
Mike Stumpc2f591b2009-08-13 22:53:07 +0000717 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000718
Anders Carlssonf7b7a1e2010-03-11 04:24:02 +0000719 if (!Base->getNumVBases()) {
720 // This base isn't interesting since it doesn't have any virtual bases.
721 continue;
Mike Stump996576f32009-08-16 19:04:13 +0000722 }
Anders Carlssonf7b7a1e2010-03-11 04:24:02 +0000723
Anders Carlssonea7b1822010-04-15 16:12:58 +0000724 LayoutVirtualBases(Base, MostDerivedClass);
Mike Stump6b2556f2009-08-06 13:41:24 +0000725 }
726}
727
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000728void RecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *Base) {
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000729 // Layout the base.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000730 uint64_t Offset = LayoutBase(Base, /*BaseIsVirtual=*/true);
Anders Carlsson0d0b5882010-03-10 22:26:24 +0000731
732 // Add its base class offset.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000733 if (!VBases.insert(std::make_pair(Base, Offset)).second)
Anders Carlsson6a848892010-03-11 04:10:39 +0000734 assert(false && "Added same vbase offset more than once!");
Anders Carlsson09ffa322010-03-10 22:21:28 +0000735}
736
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000737uint64_t RecordLayoutBuilder::LayoutBase(const CXXRecordDecl *Base,
738 bool BaseIsVirtual) {
739 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base);
Anders Carlsson09ffa322010-03-10 22:21:28 +0000740
741 // If we have an empty base class, try to place it at offset 0.
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000742 if (Base->isEmpty() &&
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000743 EmptySubobjects->CanPlaceBaseAtOffset(Base, BaseIsVirtual, 0) &&
744 canPlaceRecordAtOffset(Base, 0, /*CheckVBases=*/false)) {
Anders Carlsson09ffa322010-03-10 22:21:28 +0000745 // We were able to place the class at offset 0.
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000746 UpdateEmptyClassOffsets(Base, 0, /*UpdateVBases=*/false);
Anders Carlsson09ffa322010-03-10 22:21:28 +0000747
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000748 Size = std::max(Size, Layout.getSize());
Anders Carlsson09ffa322010-03-10 22:21:28 +0000749
750 return 0;
751 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000752
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000753 unsigned BaseAlign = Layout.getNonVirtualAlign();
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000754
Anders Carlsson09ffa322010-03-10 22:21:28 +0000755 // Round up the current record size to the base's alignment boundary.
756 uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000757
Anders Carlsson09ffa322010-03-10 22:21:28 +0000758 // Try to place the base.
759 while (true) {
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000760 if (EmptySubobjects->CanPlaceBaseAtOffset(Base, BaseIsVirtual, Offset) &&
761 canPlaceRecordAtOffset(Base, Offset, /*CheckVBases=*/false))
Anders Carlsson09ffa322010-03-10 22:21:28 +0000762 break;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000763
Anders Carlsson09ffa322010-03-10 22:21:28 +0000764 Offset += BaseAlign;
765 }
766
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000767 if (!Base->isEmpty()) {
Anders Carlsson09ffa322010-03-10 22:21:28 +0000768 // Update the data size.
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000769 DataSize = Offset + Layout.getNonVirtualSize();
Anders Carlsson09ffa322010-03-10 22:21:28 +0000770
771 Size = std::max(Size, DataSize);
772 } else
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000773 Size = std::max(Size, Offset + Layout.getSize());
Anders Carlsson09ffa322010-03-10 22:21:28 +0000774
775 // Remember max struct/class alignment.
776 UpdateAlignment(BaseAlign);
777
Anders Carlssonc121b4e2010-05-27 00:07:01 +0000778 UpdateEmptyClassOffsets(Base, Offset, /*UpdateVBases=*/false);
Anders Carlsson09ffa322010-03-10 22:21:28 +0000779 return Offset;
780}
781
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000782bool
Anders Carlssonc2226202010-05-26 05:58:59 +0000783RecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000784 uint64_t Offset,
Anders Carlssond626cb72010-05-10 15:26:14 +0000785 bool CheckVBases) const {
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000786 // Look for an empty class with the same type at the same offset.
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000787 for (EmptyClassOffsetsTy::const_iterator I =
788 EmptyClassOffsets.lower_bound(Offset),
789 E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
790
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000791 if (I->second == RD)
792 return false;
793 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000794
Anders Carlsson82828a32010-05-09 05:03:38 +0000795 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000796
797 // Check bases.
798 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000799 E = RD->bases_end(); I != E; ++I) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000800 assert(!I->getType()->isDependentType() &&
801 "Cannot layout class with dependent bases.");
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000802 if (I->isVirtual())
803 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000804
Anders Carlsson82828a32010-05-09 05:03:38 +0000805 const CXXRecordDecl *BaseDecl =
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000806 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
807
Anders Carlsson82828a32010-05-09 05:03:38 +0000808 uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000809
Anders Carlssond626cb72010-05-10 15:26:14 +0000810 if (!canPlaceRecordAtOffset(BaseDecl, Offset + BaseOffset,
811 /*CheckVBases=*/false))
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000812 return false;
813 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000814
Anders Carlssond7d358a2009-09-25 15:39:00 +0000815 // Check fields.
816 unsigned FieldNo = 0;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000817 for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
Anders Carlssond7d358a2009-09-25 15:39:00 +0000818 I != E; ++I, ++FieldNo) {
819 const FieldDecl *FD = *I;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000820
Anders Carlsson82828a32010-05-09 05:03:38 +0000821 uint64_t FieldOffset = Layout.getFieldOffset(FieldNo);
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000822
Anders Carlssond7d358a2009-09-25 15:39:00 +0000823 if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset))
824 return false;
825 }
826
Anders Carlssond626cb72010-05-10 15:26:14 +0000827 if (CheckVBases) {
828 // FIXME: virtual bases.
829 }
830
Anders Carlsson6522b052009-09-24 03:13:30 +0000831 return true;
832}
833
Anders Carlssonc2226202010-05-26 05:58:59 +0000834bool RecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
Anders Carlsson6f95c702009-09-25 00:02:51 +0000835 uint64_t Offset) const {
Anders Carlsson4bf82142009-09-25 01:23:32 +0000836 QualType T = FD->getType();
837 if (const RecordType *RT = T->getAs<RecordType>()) {
Anders Carlsson6f95c702009-09-25 00:02:51 +0000838 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
Anders Carlssond626cb72010-05-10 15:26:14 +0000839 return canPlaceRecordAtOffset(RD, Offset, /*CheckVBases=*/true);
Anders Carlsson6f95c702009-09-25 00:02:51 +0000840 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000841
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000842 if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
843 QualType ElemTy = Context.getBaseElementType(AT);
Anders Carlsson4bf82142009-09-25 01:23:32 +0000844 const RecordType *RT = ElemTy->getAs<RecordType>();
845 if (!RT)
846 return true;
847 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
848 if (!RD)
849 return true;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000850
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000851 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlsson4bf82142009-09-25 01:23:32 +0000852
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000853 uint64_t NumElements = Context.getConstantArrayElementCount(AT);
Mike Stump2b84dd32009-11-05 04:02:15 +0000854 uint64_t ElementOffset = Offset;
Anders Carlsson4bf82142009-09-25 01:23:32 +0000855 for (uint64_t I = 0; I != NumElements; ++I) {
Anders Carlssond626cb72010-05-10 15:26:14 +0000856 if (!canPlaceRecordAtOffset(RD, ElementOffset, /*CheckVBases=*/true))
Anders Carlsson4bf82142009-09-25 01:23:32 +0000857 return false;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000858
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000859 ElementOffset += Layout.getSize();
Anders Carlsson4bf82142009-09-25 01:23:32 +0000860 }
861 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000862
Anders Carlsson6f95c702009-09-25 00:02:51 +0000863 return true;
864}
865
Anders Carlssonc2226202010-05-26 05:58:59 +0000866void RecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000867 uint64_t Offset,
868 bool UpdateVBases) {
Anders Carlssonf24b18f2009-09-24 03:22:10 +0000869 if (RD->isEmpty())
870 EmptyClassOffsets.insert(std::make_pair(Offset, RD));
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000871
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000872 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000873
874 // Update bases.
875 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000876 E = RD->bases_end(); I != E; ++I) {
Sebastian Redl1054fae2009-10-25 17:03:50 +0000877 assert(!I->getType()->isDependentType() &&
878 "Cannot layout class with dependent bases.");
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000879 if (I->isVirtual())
880 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000881
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000882 const CXXRecordDecl *Base =
883 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000884
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000885 uint64_t BaseClassOffset = Layout.getBaseClassOffset(Base);
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000886 UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset,
887 /*UpdateVBases=*/false);
Anders Carlssonbb66bc82009-09-24 05:21:31 +0000888 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000889
Anders Carlssond7d358a2009-09-25 15:39:00 +0000890 // Update fields.
891 unsigned FieldNo = 0;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000892 for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
Anders Carlssond7d358a2009-09-25 15:39:00 +0000893 I != E; ++I, ++FieldNo) {
894 const FieldDecl *FD = *I;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000895
Anders Carlsson2357bfd2010-05-08 22:35:05 +0000896 uint64_t FieldOffset = Layout.getFieldOffset(FieldNo);
Anders Carlssond7d358a2009-09-25 15:39:00 +0000897 UpdateEmptyClassOffsets(FD, Offset + FieldOffset);
898 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000899
Anders Carlsson57732052010-05-23 18:14:24 +0000900 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000901
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000902 if (UpdateVBases) {
903 // FIXME: Update virtual bases.
Anders Carlsson57732052010-05-23 18:14:24 +0000904 } else if (PrimaryBase && Layout.getPrimaryBaseWasVirtual()) {
905 // We always want to update the offsets of a primary virtual base.
906 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 &&
907 "primary base class offset must always be 0!");
908 UpdateEmptyClassOffsets(PrimaryBase, Offset, /*UpdateVBases=*/false);
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000909 }
Anders Carlsson6522b052009-09-24 03:13:30 +0000910}
911
Anders Carlssone1883102009-09-25 01:54:38 +0000912void
Anders Carlssonc2226202010-05-26 05:58:59 +0000913RecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
Anders Carlssone1883102009-09-25 01:54:38 +0000914 uint64_t Offset) {
915 QualType T = FD->getType();
916
917 if (const RecordType *RT = T->getAs<RecordType>()) {
918 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000919 UpdateEmptyClassOffsets(RD, Offset, /*UpdateVBases=*/true);
Anders Carlssone1883102009-09-25 01:54:38 +0000920 return;
921 }
922 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000923
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000924 if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
925 QualType ElemTy = Context.getBaseElementType(AT);
Anders Carlssone1883102009-09-25 01:54:38 +0000926 const RecordType *RT = ElemTy->getAs<RecordType>();
927 if (!RT)
928 return;
929 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
930 if (!RD)
931 return;
Daniel Dunbaraa423af2010-04-08 02:59:49 +0000932
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000933 const ASTRecordLayout &Info = Context.getASTRecordLayout(RD);
Anders Carlssone1883102009-09-25 01:54:38 +0000934
Anders Carlsson5efc56e2010-04-16 15:07:51 +0000935 uint64_t NumElements = Context.getConstantArrayElementCount(AT);
Mike Stump2b84dd32009-11-05 04:02:15 +0000936 uint64_t ElementOffset = Offset;
Anders Carlssone1883102009-09-25 01:54:38 +0000937
938 for (uint64_t I = 0; I != NumElements; ++I) {
Anders Carlsson5f1a1702010-05-10 15:28:59 +0000939 UpdateEmptyClassOffsets(RD, ElementOffset, /*UpdateVBases=*/true);
Anders Carlssone1883102009-09-25 01:54:38 +0000940 ElementOffset += Info.getSize();
941 }
942 }
943}
944
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000945void RecordLayoutBuilder::InitializeLayout(const RecordDecl *D) {
Anders Carlsson79474332009-07-18 20:20:21 +0000946 IsUnion = D->isUnion();
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000947
Anders Carlsson28a5fa22009-08-08 19:38:24 +0000948 Packed = D->hasAttr<PackedAttr>();
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000949
Daniel Dunbar40130442010-05-27 01:12:46 +0000950 if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
951 MaxFieldAlignment = MFAA->getAlignment();
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000952
Anders Carlsson79474332009-07-18 20:20:21 +0000953 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
Alexis Hunt96d5c762009-11-21 08:43:09 +0000954 UpdateAlignment(AA->getMaxAlignment());
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000955}
Anders Carlsson6d9f6f32009-07-19 00:18:47 +0000956
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000957void RecordLayoutBuilder::Layout(const RecordDecl *D) {
958 InitializeLayout(D);
Anders Carlsson118ce162009-07-18 21:48:39 +0000959 LayoutFields(D);
Mike Stump11289f42009-09-09 15:08:12 +0000960
Anders Carlsson79474332009-07-18 20:20:21 +0000961 // Finally, round the size of the total struct up to the alignment of the
962 // struct itself.
963 FinishLayout();
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000964}
965
966void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
967 InitializeLayout(RD);
968
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000969 // Lay out the vtable and the non-virtual bases.
970 LayoutNonVirtualBases(RD);
971
972 LayoutFields(RD);
973
974 NonVirtualSize = Size;
975 NonVirtualAlignment = Alignment;
976
977 // Lay out the virtual bases and add the primary virtual base offsets.
978 LayoutVirtualBases(RD, RD);
979
980 VisitedVirtualBases.clear();
981 AddPrimaryVirtualBaseOffsets(RD, 0, RD);
982
983 // Finally, round the size of the total struct up to the alignment of the
984 // struct itself.
985 FinishLayout();
986
Anders Carlsson5b441d72010-04-10 21:24:48 +0000987#ifndef NDEBUG
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000988 // Check that we have base offsets for all bases.
989 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
990 E = RD->bases_end(); I != E; ++I) {
991 if (I->isVirtual())
992 continue;
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000993
Anders Carlssonc28a6c92010-05-26 15:10:00 +0000994 const CXXRecordDecl *BaseDecl =
995 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
996
997 assert(Bases.count(BaseDecl) && "Did not find base offset!");
998 }
Daniel Dunbar592a85c2010-05-27 02:25:46 +0000999
Anders Carlssonc28a6c92010-05-26 15:10:00 +00001000 // And all virtual bases.
1001 for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
1002 E = RD->vbases_end(); I != E; ++I) {
1003 const CXXRecordDecl *BaseDecl =
1004 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001005
Anders Carlssonc28a6c92010-05-26 15:10:00 +00001006 assert(VBases.count(BaseDecl) && "Did not find base offset!");
Anders Carlsson5b441d72010-04-10 21:24:48 +00001007 }
1008#endif
Anders Carlsson79474332009-07-18 20:20:21 +00001009}
1010
Anders Carlssonc2226202010-05-26 05:58:59 +00001011void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
Anders Carlsson4f516282009-07-18 20:50:59 +00001012 if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001013 const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD);
Anders Carlsson4f516282009-07-18 20:50:59 +00001014
1015 UpdateAlignment(SL.getAlignment());
Mike Stump11289f42009-09-09 15:08:12 +00001016
Anders Carlsson4f516282009-07-18 20:50:59 +00001017 // We start laying out ivars not at the end of the superclass
1018 // structure, but at the next byte following the last field.
Anders Carlsson27b50132009-07-18 21:26:44 +00001019 Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8);
Anders Carlsson47680d82009-09-26 01:34:51 +00001020 DataSize = Size;
Anders Carlsson4f516282009-07-18 20:50:59 +00001021 }
Mike Stump11289f42009-09-09 15:08:12 +00001022
Anders Carlsson28a5fa22009-08-08 19:38:24 +00001023 Packed = D->hasAttr<PackedAttr>();
Mike Stump11289f42009-09-09 15:08:12 +00001024
Daniel Dunbar40130442010-05-27 01:12:46 +00001025 if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
1026 MaxFieldAlignment = MFAA->getAlignment();
Mike Stump11289f42009-09-09 15:08:12 +00001027
Anders Carlsson4f516282009-07-18 20:50:59 +00001028 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
Alexis Hunt96d5c762009-11-21 08:43:09 +00001029 UpdateAlignment(AA->getMaxAlignment());
Daniel Dunbar40130442010-05-27 01:12:46 +00001030
Anders Carlsson4f516282009-07-18 20:50:59 +00001031 // Layout each ivar sequentially.
1032 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001033 Context.ShallowCollectObjCIvars(D, Ivars);
Anders Carlsson4f516282009-07-18 20:50:59 +00001034 for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
1035 LayoutField(Ivars[i]);
Mike Stump11289f42009-09-09 15:08:12 +00001036
Anders Carlsson4f516282009-07-18 20:50:59 +00001037 // Finally, round the size of the total struct up to the alignment of the
1038 // struct itself.
1039 FinishLayout();
1040}
1041
Anders Carlssonc2226202010-05-26 05:58:59 +00001042void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
Anders Carlsson118ce162009-07-18 21:48:39 +00001043 // Layout each field, for now, just sequentially, respecting alignment. In
1044 // the future, this will need to be tweakable by targets.
Mike Stump11289f42009-09-09 15:08:12 +00001045 for (RecordDecl::field_iterator Field = D->field_begin(),
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001046 FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
Anders Carlsson118ce162009-07-18 21:48:39 +00001047 LayoutField(*Field);
1048}
1049
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001050void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
Anders Carlsson57235162010-04-16 15:57:11 +00001051 uint64_t TypeSize) {
1052 assert(Context.getLangOptions().CPlusPlus &&
1053 "Can only have wide bit-fields in C++!");
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001054
Anders Carlsson57235162010-04-16 15:57:11 +00001055 // Itanium C++ ABI 2.4:
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001056 // If sizeof(T)*8 < n, let T' be the largest integral POD type with
Anders Carlsson57235162010-04-16 15:57:11 +00001057 // sizeof(T')*8 <= n.
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001058
Anders Carlsson57235162010-04-16 15:57:11 +00001059 QualType IntegralPODTypes[] = {
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001060 Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy,
Anders Carlsson57235162010-04-16 15:57:11 +00001061 Context.UnsignedLongTy, Context.UnsignedLongLongTy
1062 };
1063
Anders Carlsson57235162010-04-16 15:57:11 +00001064 QualType Type;
1065 for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes);
1066 I != E; ++I) {
1067 uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]);
Anders Carlsson57235162010-04-16 15:57:11 +00001068
1069 if (Size > FieldSize)
1070 break;
1071
1072 Type = IntegralPODTypes[I];
1073 }
1074 assert(!Type.isNull() && "Did not find a type!");
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001075
Anders Carlsson57235162010-04-16 15:57:11 +00001076 unsigned TypeAlign = Context.getTypeAlign(Type);
1077
1078 // We're not going to use any of the unfilled bits in the last byte.
1079 UnfilledBitsInLastByte = 0;
1080
Anders Carlssonaad5fa82010-04-17 20:21:41 +00001081 uint64_t FieldOffset;
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001082
Anders Carlsson57235162010-04-16 15:57:11 +00001083 if (IsUnion) {
1084 DataSize = std::max(DataSize, FieldSize);
Anders Carlssonaad5fa82010-04-17 20:21:41 +00001085 FieldOffset = 0;
Anders Carlsson57235162010-04-16 15:57:11 +00001086 } else {
Anders Carlssonaad5fa82010-04-17 20:21:41 +00001087 // The bitfield is allocated starting at the next offset aligned appropriately
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001088 // for T', with length n bits.
Anders Carlssonaad5fa82010-04-17 20:21:41 +00001089 FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign);
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001090
Anders Carlsson57235162010-04-16 15:57:11 +00001091 uint64_t NewSizeInBits = FieldOffset + FieldSize;
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001092
Anders Carlsson57235162010-04-16 15:57:11 +00001093 DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
1094 UnfilledBitsInLastByte = DataSize - NewSizeInBits;
1095 }
1096
1097 // Place this field at the current location.
1098 FieldOffsets.push_back(FieldOffset);
1099
1100 // Update the size.
1101 Size = std::max(Size, DataSize);
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001102
Anders Carlsson57235162010-04-16 15:57:11 +00001103 // Remember max struct/class alignment.
1104 UpdateAlignment(TypeAlign);
1105}
1106
Anders Carlssonc2226202010-05-26 05:58:59 +00001107void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
Anders Carlsson07209442009-11-22 17:37:31 +00001108 bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
Anders Carlssonba958402009-11-22 19:13:51 +00001109 uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001110 uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001111
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001112 std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
Anders Carlsson07209442009-11-22 17:37:31 +00001113 uint64_t TypeSize = FieldInfo.first;
1114 unsigned FieldAlign = FieldInfo.second;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001115
Anders Carlsson57235162010-04-16 15:57:11 +00001116 if (FieldSize > TypeSize) {
1117 LayoutWideBitField(FieldSize, TypeSize);
1118 return;
1119 }
1120
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001121 if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
Anders Carlsson07209442009-11-22 17:37:31 +00001122 FieldAlign = 1;
1123 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
1124 FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
1125
1126 // The maximum field alignment overrides the aligned attribute.
1127 if (MaxFieldAlignment)
1128 FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001129
Daniel Dunbar3d9289c2010-04-15 06:18:39 +00001130 // Check if we need to add padding to give the field the correct alignment.
Anders Carlsson07209442009-11-22 17:37:31 +00001131 if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
1132 FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001133
Daniel Dunbar3d9289c2010-04-15 06:18:39 +00001134 // Padding members don't affect overall alignment.
Anders Carlsson07209442009-11-22 17:37:31 +00001135 if (!D->getIdentifier())
1136 FieldAlign = 1;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001137
Anders Carlsson07209442009-11-22 17:37:31 +00001138 // Place this field at the current location.
1139 FieldOffsets.push_back(FieldOffset);
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001140
Anders Carlssonba958402009-11-22 19:13:51 +00001141 // Update DataSize to include the last byte containing (part of) the bitfield.
1142 if (IsUnion) {
1143 // FIXME: I think FieldSize should be TypeSize here.
1144 DataSize = std::max(DataSize, FieldSize);
1145 } else {
1146 uint64_t NewSizeInBits = FieldOffset + FieldSize;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001147
Anders Carlssonba958402009-11-22 19:13:51 +00001148 DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
1149 UnfilledBitsInLastByte = DataSize - NewSizeInBits;
1150 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001151
Anders Carlssonba958402009-11-22 19:13:51 +00001152 // Update the size.
1153 Size = std::max(Size, DataSize);
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001154
Anders Carlsson07209442009-11-22 17:37:31 +00001155 // Remember max struct/class alignment.
1156 UpdateAlignment(FieldAlign);
1157}
1158
Anders Carlssonc2226202010-05-26 05:58:59 +00001159void RecordLayoutBuilder::LayoutField(const FieldDecl *D) {
Anders Carlsson07209442009-11-22 17:37:31 +00001160 if (D->isBitField()) {
1161 LayoutBitField(D);
1162 return;
1163 }
1164
Anders Carlssonba958402009-11-22 19:13:51 +00001165 // Reset the unfilled bits.
1166 UnfilledBitsInLastByte = 0;
1167
Anders Carlsson07209442009-11-22 17:37:31 +00001168 bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
Anders Carlsson47680d82009-09-26 01:34:51 +00001169 uint64_t FieldOffset = IsUnion ? 0 : DataSize;
Anders Carlsson79474332009-07-18 20:20:21 +00001170 uint64_t FieldSize;
1171 unsigned FieldAlign;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001172
Anders Carlsson07209442009-11-22 17:37:31 +00001173 if (D->getType()->isIncompleteArrayType()) {
1174 // This is a flexible array member; we can't directly
1175 // query getTypeInfo about these, so we figure it out here.
1176 // Flexible array members don't have any size, but they
1177 // have to be aligned appropriately for their element type.
1178 FieldSize = 0;
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001179 const ArrayType* ATy = Context.getAsArrayType(D->getType());
1180 FieldAlign = Context.getTypeAlign(ATy->getElementType());
Anders Carlsson07209442009-11-22 17:37:31 +00001181 } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
1182 unsigned AS = RT->getPointeeType().getAddressSpace();
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001183 FieldSize = Context.Target.getPointerWidth(AS);
1184 FieldAlign = Context.Target.getPointerAlign(AS);
Anders Carlsson79474332009-07-18 20:20:21 +00001185 } else {
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001186 std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
Anders Carlsson07209442009-11-22 17:37:31 +00001187 FieldSize = FieldInfo.first;
1188 FieldAlign = FieldInfo.second;
Anders Carlsson79474332009-07-18 20:20:21 +00001189 }
Mike Stump11289f42009-09-09 15:08:12 +00001190
Anders Carlsson07209442009-11-22 17:37:31 +00001191 if (FieldPacked)
1192 FieldAlign = 8;
1193 if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
1194 FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
1195
1196 // The maximum field alignment overrides the aligned attribute.
1197 if (MaxFieldAlignment)
1198 FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
1199
1200 // Round up the current record size to the field's alignment boundary.
1201 FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001202
Anders Carlsson07209442009-11-22 17:37:31 +00001203 if (!IsUnion) {
1204 while (true) {
1205 // Check if we can place the field at this offset.
1206 if (canPlaceFieldAtOffset(D, FieldOffset))
1207 break;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001208
Anders Carlsson07209442009-11-22 17:37:31 +00001209 // We couldn't place the field at the offset. Try again at a new offset.
1210 FieldOffset += FieldAlign;
1211 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001212
Anders Carlsson07209442009-11-22 17:37:31 +00001213 UpdateEmptyClassOffsets(D, FieldOffset);
1214 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001215
Anders Carlsson79474332009-07-18 20:20:21 +00001216 // Place this field at the current location.
1217 FieldOffsets.push_back(FieldOffset);
Mike Stump11289f42009-09-09 15:08:12 +00001218
Anders Carlsson79474332009-07-18 20:20:21 +00001219 // Reserve space for this field.
1220 if (IsUnion)
1221 Size = std::max(Size, FieldSize);
1222 else
1223 Size = FieldOffset + FieldSize;
Mike Stump11289f42009-09-09 15:08:12 +00001224
Anders Carlsson47680d82009-09-26 01:34:51 +00001225 // Update the data size.
1226 DataSize = Size;
Mike Stump11289f42009-09-09 15:08:12 +00001227
Anders Carlsson79474332009-07-18 20:20:21 +00001228 // Remember max struct/class alignment.
1229 UpdateAlignment(FieldAlign);
1230}
1231
Anders Carlssonc2226202010-05-26 05:58:59 +00001232void RecordLayoutBuilder::FinishLayout() {
Anders Carlsson79474332009-07-18 20:20:21 +00001233 // In C++, records cannot be of size 0.
Anders Carlsson5efc56e2010-04-16 15:07:51 +00001234 if (Context.getLangOptions().CPlusPlus && Size == 0)
Anders Carlsson79474332009-07-18 20:20:21 +00001235 Size = 8;
1236 // Finally, round the size of the record up to the alignment of the
1237 // record itself.
Anders Carlsson07209442009-11-22 17:37:31 +00001238 Size = llvm::RoundUpToAlignment(Size, Alignment);
Anders Carlsson79474332009-07-18 20:20:21 +00001239}
1240
Anders Carlssonc2226202010-05-26 05:58:59 +00001241void RecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
Anders Carlsson79474332009-07-18 20:20:21 +00001242 if (NewAlignment <= Alignment)
1243 return;
Mike Stump11289f42009-09-09 15:08:12 +00001244
Anders Carlsson79474332009-07-18 20:20:21 +00001245 assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2"));
Mike Stump11289f42009-09-09 15:08:12 +00001246
Anders Carlsson79474332009-07-18 20:20:21 +00001247 Alignment = NewAlignment;
1248}
Mike Stump11289f42009-09-09 15:08:12 +00001249
Anders Carlsson5ebf8b42009-12-07 04:35:11 +00001250const CXXMethodDecl *
Anders Carlssonc2226202010-05-26 05:58:59 +00001251RecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
Anders Carlsson5ebf8b42009-12-07 04:35:11 +00001252 assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
1253
Daniel Dunbarccabe482010-04-19 20:44:53 +00001254 // If a class isn't polymorphic it doesn't have a key function.
Anders Carlsson5ebf8b42009-12-07 04:35:11 +00001255 if (!RD->isPolymorphic())
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001256 return 0;
Eli Friedmanf2c79b62009-12-08 03:56:49 +00001257
1258 // A class inside an anonymous namespace doesn't have a key function. (Or
1259 // at least, there's no point to assigning a key function to such a class;
1260 // this doesn't affect the ABI.)
1261 if (RD->isInAnonymousNamespace())
1262 return 0;
1263
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001264 for (CXXRecordDecl::method_iterator I = RD->method_begin(),
1265 E = RD->method_end(); I != E; ++I) {
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001266 const CXXMethodDecl *MD = *I;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001267
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001268 if (!MD->isVirtual())
1269 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001270
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001271 if (MD->isPure())
1272 continue;
Eli Friedmanf2c79b62009-12-08 03:56:49 +00001273
Anders Carlssonf98849e2009-12-02 17:15:43 +00001274 // Ignore implicit member functions, they are always marked as inline, but
1275 // they don't have a body until they're defined.
1276 if (MD->isImplicit())
1277 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001278
Douglas Gregora318efd2010-01-05 19:06:31 +00001279 if (MD->isInlineSpecified())
1280 continue;
Eli Friedman71a26d82009-12-06 20:50:05 +00001281
1282 if (MD->hasInlineBody())
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001283 continue;
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001284
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001285 // We found it.
1286 return MD;
1287 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001288
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00001289 return 0;
1290}
1291
Anders Carlssondf291d82010-05-26 04:56:53 +00001292/// getASTRecordLayout - Get or compute information about the layout of the
1293/// specified record (struct/union/class), which indicates its size and field
1294/// position information.
1295const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
1296 D = D->getDefinition();
1297 assert(D && "Cannot get layout of forward declarations!");
1298
1299 // Look up this layout, if already laid out, return what we have.
1300 // Note that we can't save a reference to the entry because this function
1301 // is recursive.
1302 const ASTRecordLayout *Entry = ASTRecordLayouts[D];
1303 if (Entry) return *Entry;
1304
Anders Carlssond2954862010-05-26 05:10:47 +00001305 const ASTRecordLayout *NewEntry;
1306
1307 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
Anders Carlssonc121b4e2010-05-27 00:07:01 +00001308 EmptySubobjectMap EmptySubobjects(*this, RD);
Anders Carlsson439edd12010-05-27 05:41:06 +00001309
Anders Carlssonc121b4e2010-05-27 00:07:01 +00001310 RecordLayoutBuilder Builder(*this, &EmptySubobjects);
Anders Carlssond2954862010-05-26 05:10:47 +00001311 Builder.Layout(RD);
1312
1313 // FIXME: This is not always correct. See the part about bitfields at
1314 // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
1315 // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
1316 bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
1317
1318 // FIXME: This should be done in FinalizeLayout.
1319 uint64_t DataSize =
1320 IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize;
1321 uint64_t NonVirtualSize =
1322 IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
1323
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001324 NewEntry =
Anders Carlssond2954862010-05-26 05:10:47 +00001325 new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
1326 DataSize, Builder.FieldOffsets.data(),
1327 Builder.FieldOffsets.size(),
1328 NonVirtualSize,
1329 Builder.NonVirtualAlignment,
Anders Carlssonc121b4e2010-05-27 00:07:01 +00001330 EmptySubobjects.SizeOfLargestEmptySubobject,
Anders Carlssond2954862010-05-26 05:10:47 +00001331 Builder.PrimaryBase,
Anders Carlsson1d1e4cf2010-05-26 05:25:15 +00001332 Builder.PrimaryBaseIsVirtual,
Anders Carlssond2954862010-05-26 05:10:47 +00001333 Builder.Bases, Builder.VBases);
1334 } else {
Anders Carlssonc121b4e2010-05-27 00:07:01 +00001335 RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
Anders Carlssond2954862010-05-26 05:10:47 +00001336 Builder.Layout(D);
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001337
Anders Carlssond2954862010-05-26 05:10:47 +00001338 NewEntry =
1339 new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
1340 Builder.Size,
1341 Builder.FieldOffsets.data(),
1342 Builder.FieldOffsets.size());
1343 }
1344
Anders Carlssondf291d82010-05-26 04:56:53 +00001345 ASTRecordLayouts[D] = NewEntry;
1346
1347 if (getLangOptions().DumpRecordLayouts) {
1348 llvm::errs() << "\n*** Dumping AST Record Layout\n";
1349 DumpRecordLayout(D, llvm::errs());
1350 }
1351
1352 return *NewEntry;
1353}
1354
1355const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
1356 RD = cast<CXXRecordDecl>(RD->getDefinition());
1357 assert(RD && "Cannot get key function for forward declarations!");
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001358
Anders Carlssondf291d82010-05-26 04:56:53 +00001359 const CXXMethodDecl *&Entry = KeyFunctions[RD];
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001360 if (!Entry)
Anders Carlssonc2226202010-05-26 05:58:59 +00001361 Entry = RecordLayoutBuilder::ComputeKeyFunction(RD);
Anders Carlssondf291d82010-05-26 04:56:53 +00001362 else
Anders Carlssonc2226202010-05-26 05:58:59 +00001363 assert(Entry == RecordLayoutBuilder::ComputeKeyFunction(RD) &&
Anders Carlssondf291d82010-05-26 04:56:53 +00001364 "Key function changed!");
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001365
Anders Carlssondf291d82010-05-26 04:56:53 +00001366 return Entry;
1367}
1368
1369/// getInterfaceLayoutImpl - Get or compute information about the
1370/// layout of the given interface.
1371///
1372/// \param Impl - If given, also include the layout of the interface's
1373/// implementation. This may differ by including synthesized ivars.
1374const ASTRecordLayout &
1375ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
1376 const ObjCImplementationDecl *Impl) {
1377 assert(!D->isForwardDecl() && "Invalid interface decl!");
1378
1379 // Look up this layout, if already laid out, return what we have.
1380 ObjCContainerDecl *Key =
1381 Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D;
1382 if (const ASTRecordLayout *Entry = ObjCLayouts[Key])
1383 return *Entry;
1384
1385 // Add in synthesized ivar count if laying out an implementation.
1386 if (Impl) {
1387 unsigned SynthCount = CountNonClassIvars(D);
1388 // If there aren't any sythesized ivars then reuse the interface
1389 // entry. Note we can't cache this because we simply free all
1390 // entries later; however we shouldn't look up implementations
1391 // frequently.
1392 if (SynthCount == 0)
1393 return getObjCLayout(D, 0);
1394 }
1395
Anders Carlssonc121b4e2010-05-27 00:07:01 +00001396 RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
Anders Carlsson6ed3a9a2010-05-26 05:04:25 +00001397 Builder.Layout(D);
1398
Anders Carlssondf291d82010-05-26 04:56:53 +00001399 const ASTRecordLayout *NewEntry =
Anders Carlsson6ed3a9a2010-05-26 05:04:25 +00001400 new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
1401 Builder.DataSize,
1402 Builder.FieldOffsets.data(),
1403 Builder.FieldOffsets.size());
Daniel Dunbar592a85c2010-05-27 02:25:46 +00001404
Anders Carlssondf291d82010-05-26 04:56:53 +00001405 ObjCLayouts[Key] = NewEntry;
1406
1407 return *NewEntry;
1408}
1409
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001410static void PrintOffset(llvm::raw_ostream &OS,
1411 uint64_t Offset, unsigned IndentLevel) {
1412 OS << llvm::format("%4d | ", Offset);
1413 OS.indent(IndentLevel * 2);
1414}
1415
1416static void DumpCXXRecordLayout(llvm::raw_ostream &OS,
1417 const CXXRecordDecl *RD, ASTContext &C,
1418 uint64_t Offset,
1419 unsigned IndentLevel,
1420 const char* Description,
1421 bool IncludeVirtualBases) {
1422 const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
1423
1424 PrintOffset(OS, Offset, IndentLevel);
Dan Gohman145f3f12010-04-19 16:39:44 +00001425 OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString();
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001426 if (Description)
1427 OS << ' ' << Description;
1428 if (RD->isEmpty())
1429 OS << " (empty)";
1430 OS << '\n';
1431
1432 IndentLevel++;
1433
1434 const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase();
1435
1436 // Vtable pointer.
1437 if (RD->isDynamicClass() && !PrimaryBase) {
1438 PrintOffset(OS, Offset, IndentLevel);
Benjamin Kramerb11416d2010-04-17 09:33:03 +00001439 OS << '(' << RD << " vtable pointer)\n";
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001440 }
1441 // Dump (non-virtual) bases
1442 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
1443 E = RD->bases_end(); I != E; ++I) {
1444 assert(!I->getType()->isDependentType() &&
1445 "Cannot layout class with dependent bases.");
1446 if (I->isVirtual())
1447 continue;
1448
1449 const CXXRecordDecl *Base =
1450 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
1451
1452 uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8;
1453
1454 DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
1455 Base == PrimaryBase ? "(primary base)" : "(base)",
1456 /*IncludeVirtualBases=*/false);
1457 }
1458
1459 // Dump fields.
1460 uint64_t FieldNo = 0;
1461 for (CXXRecordDecl::field_iterator I = RD->field_begin(),
1462 E = RD->field_end(); I != E; ++I, ++FieldNo) {
1463 const FieldDecl *Field = *I;
1464 uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8;
1465
1466 if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
1467 if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
1468 DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
1469 Field->getNameAsCString(),
1470 /*IncludeVirtualBases=*/true);
1471 continue;
1472 }
1473 }
1474
1475 PrintOffset(OS, FieldOffset, IndentLevel);
Benjamin Kramerb11416d2010-04-17 09:33:03 +00001476 OS << Field->getType().getAsString() << ' ' << Field << '\n';
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001477 }
1478
1479 if (!IncludeVirtualBases)
1480 return;
1481
1482 // Dump virtual bases.
1483 for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
1484 E = RD->vbases_end(); I != E; ++I) {
1485 assert(I->isVirtual() && "Found non-virtual class!");
1486 const CXXRecordDecl *VBase =
1487 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
1488
1489 uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8;
1490 DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
1491 VBase == PrimaryBase ?
1492 "(primary virtual base)" : "(virtual base)",
1493 /*IncludeVirtualBases=*/false);
1494 }
Daniel Dunbaraa423af2010-04-08 02:59:49 +00001495
1496 OS << " sizeof=" << Info.getSize() / 8;
1497 OS << ", dsize=" << Info.getDataSize() / 8;
1498 OS << ", align=" << Info.getAlignment() / 8 << '\n';
1499 OS << " nvsize=" << Info.getNonVirtualSize() / 8;
1500 OS << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n';
1501 OS << '\n';
1502}
Daniel Dunbarccabe482010-04-19 20:44:53 +00001503
1504void ASTContext::DumpRecordLayout(const RecordDecl *RD,
1505 llvm::raw_ostream &OS) {
1506 const ASTRecordLayout &Info = getASTRecordLayout(RD);
1507
1508 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1509 return DumpCXXRecordLayout(OS, CXXRD, *this, 0, 0, 0,
1510 /*IncludeVirtualBases=*/true);
1511
1512 OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
1513 OS << "Record: ";
1514 RD->dump();
1515 OS << "\nLayout: ";
1516 OS << "<ASTRecordLayout\n";
1517 OS << " Size:" << Info.getSize() << "\n";
1518 OS << " DataSize:" << Info.getDataSize() << "\n";
1519 OS << " Alignment:" << Info.getAlignment() << "\n";
1520 OS << " FieldOffsets: [";
1521 for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) {
1522 if (i) OS << ", ";
1523 OS << Info.getFieldOffset(i);
1524 }
1525 OS << "]>\n";
1526}