 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
91.3% |
230 / 252 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
98.4% |
248 / 252 |
| |
|
Line Coverage: |
97.6% |
367 / 376 |
| |
 |
|
 |
1 : //=== 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"
14 : #include "clang/AST/DeclCXX.h"
15 : #include "clang/AST/DeclObjC.h"
16 : #include "clang/AST/Expr.h"
17 : #include "clang/Basic/TargetInfo.h"
18 : #include <llvm/ADT/SmallSet.h>
19 : #include <llvm/Support/MathExtras.h>
20 :
21 : using namespace clang;
22 :
23 1800: ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
24 : : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
25 : MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0),
26 1800: NonVirtualAlignment(8) { }
27 :
28 : /// LayoutVtable - Lay out the vtable and set PrimaryBase.
29 862: void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
509: branch 1 taken
353: branch 2 taken
30 862: if (!RD->isDynamicClass()) {
31 : // There is no primary base in this case.
32 509: return;
33 : }
34 :
35 353: SelectPrimaryBase(RD);
216: branch 1 taken
137: branch 2 taken
36 353: if (!PrimaryBase.getBase()) {
37 216: int AS = 0;
38 216: UpdateAlignment(Ctx.Target.getPointerAlign(AS));
39 216: Size += Ctx.Target.getPointerWidth(AS);
40 216: DataSize = Size;
41 : }
42 : }
43 :
44 : void
45 862: ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
412: branch 1 taken
862: branch 2 taken
46 2136: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
47 862: e = RD->bases_end(); i != e; ++i) {
257: branch 1 taken
155: branch 2 taken
48 412: if (!i->isVirtual()) {
49 : assert(!i->getType()->isDependentType() &&
257: branch 3 taken
0: branch 4 not taken
50 257: "Cannot layout class with dependent bases.");
51 : const CXXRecordDecl *Base =
52 257: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
53 : // Skip the PrimaryBase here, as it is laid down first.
91: branch 1 taken
166: branch 2 taken
0: branch 4 not taken
91: branch 5 taken
166: branch 6 taken
91: branch 7 taken
54 348: if (Base != PrimaryBase.getBase() || PrimaryBase.isVirtual())
55 166: LayoutBaseNonVirtually(Base, false);
56 : }
57 : }
58 862: }
59 :
60 : // Helper routines related to the abi definition from:
61 : // http://www.codesourcery.com/public/cxx-abi/abi.html
62 : //
63 : /// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
64 : /// no other data.
65 151: bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
66 : // FIXME: Audit the corners
27: branch 1 taken
124: branch 2 taken
67 151: if (!RD->isDynamicClass())
68 27: return false;
69 124: const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
47: branch 2 taken
77: branch 3 taken
70 124: if (BaseInfo.getNonVirtualSize() == Ctx.Target.getPointerWidth(0))
71 47: return true;
72 77: return false;
73 : }
74 :
75 341: void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
76 : const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
77 341: Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo();
78 :
79 : // If the record has a primary base class that is virtual, add it to the set
80 : // of primary bases.
42: branch 1 taken
299: branch 2 taken
81 341: if (BaseInfo.isVirtual())
82 42: IndirectPrimaryBases.insert(BaseInfo.getBase());
83 :
84 : // Now traverse all bases and find primary bases for them.
240: branch 1 taken
341: branch 2 taken
85 922: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
86 341: e = RD->bases_end(); i != e; ++i) {
87 : assert(!i->getType()->isDependentType() &&
240: branch 3 taken
0: branch 4 not taken
88 240: "Cannot layout class with dependent bases.");
89 : const CXXRecordDecl *Base =
90 240: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
91 :
92 : // Only bases with virtual bases participate in computing the
93 : // indirect primary virtual base classes.
46: branch 1 taken
194: branch 2 taken
94 240: if (Base->getNumVBases())
95 46: IdentifyPrimaryBases(Base);
96 : }
97 341: }
98 :
99 : void
100 : ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
101 257: const CXXRecordDecl *&FirstPrimary) {
207: branch 1 taken
209: branch 2 taken
102 673: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
103 257: e = RD->bases_end(); i != e; ++i) {
104 : assert(!i->getType()->isDependentType() &&
207: branch 3 taken
0: branch 4 not taken
105 207: "Cannot layout class with dependent bases.");
106 : const CXXRecordDecl *Base =
107 207: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
56: branch 1 taken
151: branch 2 taken
108 207: if (!i->isVirtual()) {
109 56: SelectPrimaryVBase(Base, FirstPrimary);
0: branch 1 not taken
56: branch 2 taken
110 56: if (PrimaryBase.getBase())
111 0: return;
112 56: continue;
113 : }
47: branch 1 taken
104: branch 2 taken
114 151: if (IsNearlyEmpty(Base)) {
46: branch 0 taken
1: branch 1 taken
115 47: if (FirstPrimary==0)
116 46: FirstPrimary = Base;
46: branch 1 taken
1: branch 2 taken
117 47: if (!IndirectPrimaryBases.count(Base)) {
118 46: setPrimaryBase(Base, /*IsVirtual=*/true);
119 46: return;
120 : }
121 : }
105: branch 1 taken
0: branch 2 not taken
122 105: if (i->isVirtual()) {
123 105: SelectPrimaryVBase(Base, FirstPrimary);
2: branch 1 taken
103: branch 2 taken
124 105: if (PrimaryBase.getBase())
125 2: return;
126 : }
127 : }
128 : }
129 :
130 : /// SelectPrimaryBase - Selects the primary base for the given class and
131 : /// record that with setPrimaryBase. We also calculate the IndirectPrimaries.
132 353: void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
133 : // Compute all the primary virtual bases for all of our direct and
134 : // indirect bases, and record all their primary virtual base classes.
295: branch 1 taken
353: branch 2 taken
135 1649: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
136 353: e = RD->bases_end(); i != e; ++i) {
137 : assert(!i->getType()->isDependentType() &&
295: branch 3 taken
0: branch 4 not taken
138 295: "Cannot layout class with dependent bases.");
139 : const CXXRecordDecl *Base =
140 295: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
141 295: IdentifyPrimaryBases(Base);
142 : }
143 :
144 : // If the record has a dynamic base class, attempt to choose a primary base
145 : // class. It is the first (in direct base class order) non-virtual dynamic
146 : // base class, if one exists.
241: branch 1 taken
262: branch 2 taken
147 856: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
148 353: e = RD->bases_end(); i != e; ++i) {
149 : // Ignore virtual bases.
108: branch 1 taken
133: branch 2 taken
150 241: if (i->isVirtual())
151 133: continue;
152 :
153 : const CXXRecordDecl *Base =
154 108: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
155 :
91: branch 1 taken
17: branch 2 taken
156 108: if (Base->isDynamicClass()) {
157 : // We found it.
158 91: PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
159 91: return;
160 : }
161 : }
162 :
163 : // Otherwise, it is the first nearly empty virtual base that is not an
164 : // indirect primary virtual base class, if one exists.
165 :
166 : // If we have no virtual bases at this point, bail out as the searching below
167 : // is expensive.
166: branch 1 taken
96: branch 2 taken
168 262: if (RD->getNumVBases() == 0)
169 166: return;
170 :
171 : // Then we can search for the first nearly empty virtual base itself.
172 96: const CXXRecordDecl *FirstPrimary = 0;
173 96: SelectPrimaryVBase(RD, FirstPrimary);
174 :
175 : // Otherwise if is the first nearly empty virtual base, if one exists,
176 : // otherwise there is no primary base class.
50: branch 1 taken
46: branch 2 taken
177 96: if (!PrimaryBase.getBase())
178 50: setPrimaryBase(FirstPrimary, /*IsVirtual=*/true);
179 : }
180 :
181 207: void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
182 207: LayoutBaseNonVirtually(RD, true);
183 207: }
184 :
185 257: uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) {
338: branch 1 taken
0: branch 2 not taken
186 338: for (size_t i = 0; i < Bases.size(); ++i) {
257: branch 1 taken
81: branch 2 taken
187 338: if (Bases[i].first == Base)
188 257: return Bases[i].second;
189 : }
0: branch 1 not taken
0: branch 2 not taken
190 0: for (size_t i = 0; i < VBases.size(); ++i) {
0: branch 1 not taken
0: branch 2 not taken
191 0: if (VBases[i].first == Base)
192 0: return VBases[i].second;
193 : }
194 0: assert(0 && "missing base");
195 : return 0;
196 : }
197 :
198 :
199 : void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
200 : const CXXRecordDecl *RD,
201 : const CXXRecordDecl *PB,
202 : uint64_t Offset,
203 : llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
204 998: llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
616: branch 1 taken
998: branch 2 taken
205 2612: for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
206 998: e = RD->bases_end(); i != e; ++i) {
207 : assert(!i->getType()->isDependentType() &&
616: branch 3 taken
0: branch 4 not taken
208 616: "Cannot layout class with dependent bases.");
209 : const CXXRecordDecl *Base =
210 616: cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
211 616: uint64_t BaseOffset = Offset;
316: branch 1 taken
300: branch 2 taken
212 616: if (i->isVirtual()) {
86: branch 0 taken
230: branch 1 taken
213 316: if (Base == PB) {
214 : // Only lay things out once.
0: branch 1 not taken
86: branch 2 taken
215 86: if (mark.count(Base))
216 0: continue;
217 : // Mark it so we don't lay it out twice.
218 86: mark.insert(Base);
86: branch 1 taken
0: branch 2 not taken
219 86: assert (IndirectPrimary.count(Base) && "IndirectPrimary was wrong");
220 86: VBases.push_back(std::make_pair(Base, Offset));
227: branch 1 taken
3: branch 2 taken
221 230: } else if (IndirectPrimary.count(Base)) {
222 : // Someone else will eventually lay this out.
223 : ;
224 : } else {
225 : // Only lay things out once.
20: branch 1 taken
207: branch 2 taken
226 227: if (mark.count(Base))
227 20: continue;
228 : // Mark it so we don't lay it out twice.
229 207: mark.insert(Base);
230 207: LayoutVirtualBase(Base);
231 207: BaseOffset = VBases.back().second;
232 : }
233 : } else {
257: branch 0 taken
43: branch 1 taken
234 300: if (RD == Class)
235 257: BaseOffset = getBaseOffset(Base);
236 : else {
237 43: const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
238 43: BaseOffset = Offset + Layout.getBaseClassOffset(Base);
239 : }
240 : }
241 :
136: branch 1 taken
460: branch 2 taken
242 596: if (Base->getNumVBases()) {
243 136: const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
244 136: const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().getBase();
245 : LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark,
246 136: IndirectPrimary);
247 : }
248 : }
249 998: }
250 :
251 : bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
252 1165: uint64_t Offset) const {
253 : // Look for an empty class with the same type at the same offset.
92: branch 2 taken
1137: branch 3 taken
254 1229: for (EmptyClassOffsetsTy::const_iterator I =
255 1165: EmptyClassOffsets.lower_bound(Offset),
256 1165: E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
257 :
28: branch 1 taken
64: branch 2 taken
258 92: if (I->second == RD)
259 28: return false;
260 : }
261 :
262 1137: const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
263 :
264 : // Check bases.
456: branch 1 taken
1097: branch 2 taken
265 2690: for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
266 1137: E = RD->bases_end(); I != E; ++I) {
267 : assert(!I->getType()->isDependentType() &&
456: branch 3 taken
0: branch 4 not taken
268 456: "Cannot layout class with dependent bases.");
313: branch 1 taken
143: branch 2 taken
269 456: if (I->isVirtual())
270 143: continue;
271 :
272 : const CXXRecordDecl *Base =
273 313: cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
274 :
275 313: uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
276 :
40: branch 1 taken
273: branch 2 taken
277 313: if (!canPlaceRecordAtOffset(Base, Offset + BaseClassOffset))
278 40: return false;
279 : }
280 :
281 : // Check fields.
282 1097: unsigned FieldNo = 0;
805: branch 4 taken
1096: branch 5 taken
283 1901: for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
284 : I != E; ++I, ++FieldNo) {
285 805: const FieldDecl *FD = *I;
286 :
287 805: uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
288 :
1: branch 1 taken
804: branch 2 taken
289 805: if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset))
290 1: return false;
291 : }
292 :
293 : // FIXME: virtual bases.
294 1096: return true;
295 : }
296 :
297 : bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
298 2948: uint64_t Offset) const {
299 2948: QualType T = FD->getType();
175: branch 2 taken
2773: branch 3 taken
300 2948: if (const RecordType *RT = T->getAs<RecordType>()) {
112: branch 2 taken
63: branch 3 taken
301 175: if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
302 112: return canPlaceRecordAtOffset(RD, Offset);
303 : }
304 :
162: branch 1 taken
2674: branch 2 taken
305 2836: if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
306 162: QualType ElemTy = Ctx.getBaseElementType(AT);
307 162: const RecordType *RT = ElemTy->getAs<RecordType>();
127: branch 0 taken
35: branch 1 taken
308 162: if (!RT)
309 127: return true;
310 35: const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
9: branch 0 taken
26: branch 1 taken
311 35: if (!RD)
312 9: return true;
313 :
314 26: const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
315 :
316 26: uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
317 26: uint64_t ElementOffset = Offset;
204: branch 0 taken
25: branch 1 taken
318 229: for (uint64_t I = 0; I != NumElements; ++I) {
1: branch 1 taken
203: branch 2 taken
319 204: if (!canPlaceRecordAtOffset(RD, ElementOffset))
320 1: return false;
321 :
322 203: ElementOffset += Info.getSize();
323 : }
324 : }
325 :
326 2699: return true;
327 : }
328 :
329 : void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
330 1080: uint64_t Offset) {
303: branch 1 taken
777: branch 2 taken
331 1080: if (RD->isEmpty())
332 303: EmptyClassOffsets.insert(std::make_pair(Offset, RD));
333 :
334 1080: const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
335 :
336 : // Update bases.
400: branch 1 taken
1080: branch 2 taken
337 2560: for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
338 1080: E = RD->bases_end(); I != E; ++I) {
339 : assert(!I->getType()->isDependentType() &&
400: branch 3 taken
0: branch 4 not taken
340 400: "Cannot layout class with dependent bases.");
143: branch 1 taken
257: branch 2 taken
341 400: if (I->isVirtual())
342 143: continue;
343 :
344 : const CXXRecordDecl *Base =
345 257: cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
346 :
347 257: uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
348 257: UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset);
349 : }
350 :
351 : // Update fields.
352 1080: unsigned FieldNo = 0;
804: branch 4 taken
1080: branch 5 taken
353 1884: for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
354 : I != E; ++I, ++FieldNo) {
355 804: const FieldDecl *FD = *I;
356 :
357 804: uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
358 804: UpdateEmptyClassOffsets(FD, Offset + FieldOffset);
359 : }
360 :
361 : // FIXME: Update virtual bases.
362 1080: }
363 :
364 : void
365 : ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
366 2945: uint64_t Offset) {
367 2945: QualType T = FD->getType();
368 :
173: branch 2 taken
2772: branch 3 taken
369 2945: if (const RecordType *RT = T->getAs<RecordType>()) {
110: branch 2 taken
63: branch 3 taken
370 173: if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
371 110: UpdateEmptyClassOffsets(RD, Offset);
372 110: return;
373 : }
374 : }
375 :
161: branch 1 taken
2674: branch 2 taken
376 2835: if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
377 161: QualType ElemTy = Ctx.getBaseElementType(AT);
378 161: const RecordType *RT = ElemTy->getAs<RecordType>();
127: branch 0 taken
34: branch 1 taken
379 161: if (!RT)
380 127: return;
381 34: const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
9: branch 0 taken
25: branch 1 taken
382 34: if (!RD)
383 9: return;
384 :
385 25: const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
386 :
387 25: uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
388 25: uint64_t ElementOffset = Offset;
389 :
203: branch 0 taken
25: branch 1 taken
390 228: for (uint64_t I = 0; I != NumElements; ++I) {
391 203: UpdateEmptyClassOffsets(RD, ElementOffset);
392 203: ElementOffset += Info.getSize();
393 : }
394 : }
395 : }
396 :
397 510: uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
398 510: const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
399 :
400 : // If we have an empty base class, try to place it at offset 0.
95: branch 1 taken
415: branch 2 taken
81: branch 4 taken
14: branch 5 taken
81: branch 6 taken
429: branch 7 taken
401 510: if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
402 : // We were able to place the class at offset 0.
403 81: UpdateEmptyClassOffsets(RD, 0);
404 :
405 81: Size = std::max(Size, BaseInfo.getSize());
406 :
407 81: return 0;
408 : }
409 :
410 429: unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
411 :
412 : // Round up the current record size to the base's alignment boundary.
413 429: uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign);
414 :
415 : // Try to place the base.
416 12: while (true) {
12: branch 1 taken
429: branch 2 taken
417 441: if (canPlaceRecordAtOffset(RD, Offset))
418 429: break;
419 :
420 12: Offset += BaseAlign;
421 : }
422 :
415: branch 1 taken
14: branch 2 taken
423 429: if (!RD->isEmpty()) {
424 : // Update the data size.
425 415: DataSize = Offset + BaseInfo.getNonVirtualSize();
426 :
427 415: Size = std::max(Size, DataSize);
428 : } else
429 14: Size = std::max(Size, Offset + BaseInfo.getSize());
430 :
431 : // Remember max struct/class alignment.
432 429: UpdateAlignment(BaseAlign);
433 :
434 429: UpdateEmptyClassOffsets(RD, Offset);
435 429: return Offset;
436 : }
437 :
438 : void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
439 510: bool IsVirtualBase) {
440 : // Layout the base.
441 510: uint64_t Offset = LayoutBase(RD);
442 :
443 : // Add base class offsets.
253: branch 0 taken
257: branch 1 taken
444 510: if (IsVirtualBase)
445 253: VBases.push_back(std::make_pair(RD, Offset));
446 : else
447 257: Bases.push_back(std::make_pair(RD, Offset));
448 510: }
449 :
450 1598: void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
451 1598: IsUnion = D->isUnion();
452 :
453 1598: Packed = D->hasAttr<PackedAttr>();
454 :
455 : // The #pragma pack attribute specifies the maximum field alignment.
24: branch 1 taken
1574: branch 2 taken
456 1598: if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
457 24: MaxFieldAlignment = PPA->getAlignment();
458 :
5: branch 1 taken
1593: branch 2 taken
459 1598: if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
460 5: UpdateAlignment(AA->getMaxAlignment());
461 :
462 : // If this is a C++ class, lay out the vtable and the non-virtual bases.
463 1598: const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
862: branch 0 taken
736: branch 1 taken
464 1598: if (RD) {
465 862: LayoutVtable(RD);
466 : // PrimaryBase goes first.
137: branch 1 taken
725: branch 2 taken
467 862: if (PrimaryBase.getBase()) {
46: branch 1 taken
91: branch 2 taken
468 137: if (PrimaryBase.isVirtual())
469 46: IndirectPrimaryBases.insert(PrimaryBase.getBase());
470 137: LayoutBaseNonVirtually(PrimaryBase.getBase(), PrimaryBase.isVirtual());
471 : }
472 862: LayoutNonVirtualBases(RD);
473 : }
474 :
475 1598: LayoutFields(D);
476 :
477 1598: NonVirtualSize = Size;
478 1598: NonVirtualAlignment = Alignment;
479 :
862: branch 0 taken
736: branch 1 taken
480 1598: if (RD) {
481 862: llvm::SmallSet<const CXXRecordDecl*, 32> mark;
482 : LayoutVirtualBases(RD, RD, PrimaryBase.getBase(),
483 862: 0, mark, IndirectPrimaryBases);
484 : }
485 :
486 : // Finally, round the size of the total struct up to the alignment of the
487 : // struct itself.
488 1598: FinishLayout();
489 1598: }
490 :
491 : void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
492 202: const ObjCImplementationDecl *Impl) {
73: branch 1 taken
129: branch 2 taken
493 202: if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
494 73: const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD);
495 :
496 73: UpdateAlignment(SL.getAlignment());
497 :
498 : // We start laying out ivars not at the end of the superclass
499 : // structure, but at the next byte following the last field.
500 73: Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8);
501 73: DataSize = Size;
502 : }
503 :
504 202: Packed = D->hasAttr<PackedAttr>();
505 :
506 : // The #pragma pack attribute specifies the maximum field alignment.
0: branch 1 not taken
202: branch 2 taken
507 202: if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
508 0: MaxFieldAlignment = PPA->getAlignment();
509 :
0: branch 1 not taken
202: branch 2 taken
510 202: if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
511 0: UpdateAlignment(AA->getMaxAlignment());
512 :
513 : // Layout each ivar sequentially.
514 202: llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
515 202: Ctx.ShallowCollectObjCIvars(D, Ivars, Impl);
261: branch 1 taken
202: branch 2 taken
516 463: for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
517 261: LayoutField(Ivars[i]);
518 :
519 : // Finally, round the size of the total struct up to the alignment of the
520 : // struct itself.
521 202: FinishLayout();
522 202: }
523 :
524 1598: void ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
525 : // Layout each field, for now, just sequentially, respecting alignment. In
526 : // the future, this will need to be tweakable by targets.
2181: branch 3 taken
1598: branch 4 taken
527 5377: for (RecordDecl::field_iterator Field = D->field_begin(),
528 1598: FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
529 2181: LayoutField(*Field);
530 1598: }
531 :
532 206: void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
202: branch 0 taken
4: branch 1 taken
3: branch 3 taken
199: branch 4 taken
533 206: bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
5: branch 0 taken
201: branch 1 taken
534 206: uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
535 206: uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
536 :
537 206: std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
538 206: uint64_t TypeSize = FieldInfo.first;
539 206: unsigned FieldAlign = FieldInfo.second;
540 :
7: branch 0 taken
199: branch 1 taken
541 206: if (FieldPacked)
542 7: FieldAlign = 1;
3: branch 1 taken
203: branch 2 taken
543 206: if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
544 3: FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
545 :
546 : // The maximum field alignment overrides the aligned attribute.
0: branch 0 not taken
206: branch 1 taken
547 206: if (MaxFieldAlignment)
548 0: FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
549 :
550 : // Check if we need to add padding to give the field the correct
551 : // alignment.
179: branch 0 taken
27: branch 1 taken
7: branch 2 taken
172: branch 3 taken
552 206: if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
553 34: FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
554 :
555 : // Padding members don't affect overall alignment
32: branch 1 taken
174: branch 2 taken
556 206: if (!D->getIdentifier())
557 32: FieldAlign = 1;
558 :
559 : // Place this field at the current location.
560 206: FieldOffsets.push_back(FieldOffset);
561 :
562 : // Update DataSize to include the last byte containing (part of) the bitfield.
5: branch 0 taken
201: branch 1 taken
563 206: if (IsUnion) {
564 : // FIXME: I think FieldSize should be TypeSize here.
565 5: DataSize = std::max(DataSize, FieldSize);
566 : } else {
567 201: uint64_t NewSizeInBits = FieldOffset + FieldSize;
568 :
569 201: DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
570 201: UnfilledBitsInLastByte = DataSize - NewSizeInBits;
571 : }
572 :
573 : // Update the size.
574 206: Size = std::max(Size, DataSize);
575 :
576 : // Remember max struct/class alignment.
577 206: UpdateAlignment(FieldAlign);
578 206: }
579 :
580 2442: void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
206: branch 1 taken
2236: branch 2 taken
581 2442: if (D->isBitField()) {
582 206: LayoutBitField(D);
583 206: return;
584 : }
585 :
586 : // Reset the unfilled bits.
587 2236: UnfilledBitsInLastByte = 0;
588 :
2206: branch 0 taken
30: branch 1 taken
3: branch 3 taken
2203: branch 4 taken
589 2236: bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
95: branch 0 taken
2141: branch 1 taken
590 2236: uint64_t FieldOffset = IsUnion ? 0 : DataSize;
591 : uint64_t FieldSize;
592 : unsigned FieldAlign;
593 :
9: branch 3 taken
2227: branch 4 taken
594 2236: if (D->getType()->isIncompleteArrayType()) {
595 : // This is a flexible array member; we can't directly
596 : // query getTypeInfo about these, so we figure it out here.
597 : // Flexible array members don't have any size, but they
598 : // have to be aligned appropriately for their element type.
599 9: FieldSize = 0;
600 9: const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
601 9: FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
12: branch 3 taken
2215: branch 4 taken
602 2227: } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
603 12: unsigned AS = RT->getPointeeType().getAddressSpace();
604 12: FieldSize = Ctx.Target.getPointerWidth(AS);
605 12: FieldAlign = Ctx.Target.getPointerAlign(AS);
606 : } else {
607 2215: std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
608 2215: FieldSize = FieldInfo.first;
609 2215: FieldAlign = FieldInfo.second;
610 : }
611 :
33: branch 0 taken
2203: branch 1 taken
612 2236: if (FieldPacked)
613 33: FieldAlign = 8;
22: branch 1 taken
2214: branch 2 taken
614 2236: if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
615 22: FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
616 :
617 : // The maximum field alignment overrides the aligned attribute.
54: branch 0 taken
2182: branch 1 taken
618 2236: if (MaxFieldAlignment)
619 54: FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
620 :
621 : // Round up the current record size to the field's alignment boundary.
622 2236: FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
623 :
2141: branch 0 taken
95: branch 1 taken
624 2236: if (!IsUnion) {
625 2: while (true) {
626 : // Check if we can place the field at this offset.
2: branch 1 taken
2141: branch 2 taken
627 2143: if (canPlaceFieldAtOffset(D, FieldOffset))
628 2141: break;
629 :
630 : // We couldn't place the field at the offset. Try again at a new offset.
631 2: FieldOffset += FieldAlign;
632 : }
633 :
634 2141: UpdateEmptyClassOffsets(D, FieldOffset);
635 : }
636 :
637 : // Place this field at the current location.
638 2236: FieldOffsets.push_back(FieldOffset);
639 :
640 : // Reserve space for this field.
95: branch 0 taken
2141: branch 1 taken
641 2236: if (IsUnion)
642 95: Size = std::max(Size, FieldSize);
643 : else
644 2141: Size = FieldOffset + FieldSize;
645 :
646 : // Update the data size.
647 2236: DataSize = Size;
648 :
649 : // Remember max struct/class alignment.
650 2236: UpdateAlignment(FieldAlign);
651 : }
652 :
653 1800: void ASTRecordLayoutBuilder::FinishLayout() {
654 : // In C++, records cannot be of size 0.
865: branch 1 taken
935: branch 2 taken
221: branch 3 taken
644: branch 4 taken
221: branch 5 taken
1579: branch 6 taken
655 1800: if (Ctx.getLangOptions().CPlusPlus && Size == 0)
656 221: Size = 8;
657 : // Finally, round the size of the record up to the alignment of the
658 : // record itself.
659 1800: Size = llvm::RoundUpToAlignment(Size, Alignment);
660 1800: }
661 :
662 3165: void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
1831: branch 0 taken
1334: branch 1 taken
663 3165: if (NewAlignment <= Alignment)
664 1831: return;
665 :
0: branch 1 not taken
1334: branch 2 taken
666 1334: assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2"));
667 :
668 1334: Alignment = NewAlignment;
669 : }
670 :
671 : const ASTRecordLayout *
672 : ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
673 1598: const RecordDecl *D) {
674 1598: ASTRecordLayoutBuilder Builder(Ctx);
675 :
676 1598: Builder.Layout(D);
677 :
736: branch 1 taken
862: branch 2 taken
678 1598: if (!isa<CXXRecordDecl>(D))
679 : return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size,
680 : Builder.FieldOffsets.data(),
681 736: Builder.FieldOffsets.size());
682 :
683 : // FIXME: This is not always correct. See the part about bitfields at
684 : // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
685 : // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
686 862: bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
687 :
688 : // FIXME: This should be done in FinalizeLayout.
689 : uint64_t DataSize =
218: branch 0 taken
644: branch 1 taken
690 862: IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize;
691 : uint64_t NonVirtualSize =
218: branch 0 taken
644: branch 1 taken
692 862: IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
693 :
694 : return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
695 : Builder.FieldOffsets.data(),
696 : Builder.FieldOffsets.size(),
697 : NonVirtualSize,
698 : Builder.NonVirtualAlignment,
699 : Builder.PrimaryBase,
700 : Builder.Bases.data(),
701 : Builder.Bases.size(),
702 : Builder.VBases.data(),
703 862: Builder.VBases.size());
704 : }
705 :
706 : const ASTRecordLayout *
707 : ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
708 : const ObjCInterfaceDecl *D,
709 202: const ObjCImplementationDecl *Impl) {
710 202: ASTRecordLayoutBuilder Builder(Ctx);
711 :
712 202: Builder.Layout(D, Impl);
713 :
714 : return new ASTRecordLayout(Builder.Size, Builder.Alignment,
715 : Builder.DataSize,
716 : Builder.FieldOffsets.data(),
717 202: Builder.FieldOffsets.size());
718 : }
719 :
720 : const CXXMethodDecl *
721 2359: ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
2359: branch 1 taken
0: branch 2 not taken
722 2359: assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
723 :
724 : // If a class isnt' polymorphic it doesn't have a key function.
137: branch 1 taken
2222: branch 2 taken
725 2359: if (!RD->isPolymorphic())
726 137: return 0;
727 :
728 : // A class inside an anonymous namespace doesn't have a key function. (Or
729 : // at least, there's no point to assigning a key function to such a class;
730 : // this doesn't affect the ABI.)
11: branch 1 taken
2211: branch 2 taken
731 2222: if (RD->isInAnonymousNamespace())
732 11: return 0;
733 :
9477: branch 3 taken
1414: branch 4 taken
734 13102: for (CXXRecordDecl::method_iterator I = RD->method_begin(),
735 2211: E = RD->method_end(); I != E; ++I) {
736 9477: const CXXMethodDecl *MD = *I;
737 :
3330: branch 1 taken
6147: branch 2 taken
738 9477: if (!MD->isVirtual())
739 6147: continue;
740 :
53: branch 1 taken
3277: branch 2 taken
741 3330: if (MD->isPure())
742 53: continue;
743 :
744 : // Ignore implicit member functions, they are always marked as inline, but
745 : // they don't have a body until they're defined.
47: branch 1 taken
3230: branch 2 taken
746 3277: if (MD->isImplicit())
747 47: continue;
748 :
8: branch 1 taken
3222: branch 2 taken
749 3230: if (MD->isInlineSpecified())
750 8: continue;
751 :
2425: branch 1 taken
797: branch 2 taken
752 3222: if (MD->hasInlineBody())
753 2425: continue;
754 :
755 : // We found it.
756 797: return MD;
757 : }
758 :
759 1414: return 0;
760 : }
761 :
Generated: 2010-02-10 01:31 by zcov