@@ -201,7 +201,7 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD,
201
201
ClassVectorTy& Classes = EmptyClassOffsets[Offset];
202
202
assert (std::find (Classes.begin (), Classes.end (), RD) == Classes.end () &&
203
203
" Duplicate empty class detected!" );
204
-
204
+
205
205
Classes.push_back (RD);
206
206
207
207
// Update the empty class offset.
@@ -332,6 +332,19 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
332
332
return false ;
333
333
}
334
334
335
+ if (RD == Class) {
336
+ // This is the most derived class, traverse virtual bases as well.
337
+ for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin (),
338
+ E = RD->vbases_end (); I != E; ++I) {
339
+ const CXXRecordDecl *VBaseDecl =
340
+ cast<CXXRecordDecl>(I->getType ()->getAs <RecordType>()->getDecl ());
341
+
342
+ uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset (VBaseDecl);
343
+ if (!CanPlaceFieldSubobjectAtOffset (VBaseDecl, Class, VBaseOffset))
344
+ return false ;
345
+ }
346
+ }
347
+
335
348
// Traverse all member variables.
336
349
unsigned FieldNo = 0 ;
337
350
for (CXXRecordDecl::field_iterator I = RD->field_begin (), E = RD->field_end ();
@@ -402,6 +415,7 @@ EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) {
402
415
void EmptySubobjectMap::UpdateEmptyFieldSubobjects (const CXXRecordDecl *RD,
403
416
const CXXRecordDecl *Class,
404
417
uint64_t Offset) {
418
+
405
419
AddSubobjectAtOffset (RD, Offset);
406
420
407
421
const ASTRecordLayout &Layout = Context.getASTRecordLayout (RD);
@@ -419,6 +433,18 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD,
419
433
UpdateEmptyFieldSubobjects (BaseDecl, Class, BaseOffset);
420
434
}
421
435
436
+ if (RD == Class) {
437
+ // This is the most derived class, traverse virtual bases as well.
438
+ for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin (),
439
+ E = RD->vbases_end (); I != E; ++I) {
440
+ const CXXRecordDecl *VBaseDecl =
441
+ cast<CXXRecordDecl>(I->getType ()->getAs <RecordType>()->getDecl ());
442
+
443
+ uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset (VBaseDecl);
444
+ UpdateEmptyFieldSubobjects (VBaseDecl, Class, VBaseOffset);
445
+ }
446
+ }
447
+
422
448
// Traverse all member variables.
423
449
unsigned FieldNo = 0 ;
424
450
for (CXXRecordDecl::field_iterator I = RD->field_begin (), E = RD->field_end ();
0 commit comments