bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
uint64_t Offset);
void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
- uint64_t Offset);
+ uint64_t Offset, bool PlacingEmptyBase);
bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
const CXXRecordDecl *Class,
}
void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
- uint64_t Offset) {
+ uint64_t Offset,
+ bool PlacingEmptyBase) {
+ if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {
+ // We know that the only empty subobjects that can conflict with empty
+ // subobject of non-empty bases, are empty bases that can be placed at
+ // offset zero. Because of this, we only need to keep track of empty base
+ // subobjects with offsets less than the size of the largest empty
+ // subobject for our class.
+ return;
+ }
+
AddSubobjectAtOffset(Info->Class, Offset);
// Traverse all non-virtual bases.
continue;
uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
- UpdateEmptyBaseSubobjects(Base, BaseOffset);
+ UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase);
}
if (Info->PrimaryVirtualBaseInfo) {
BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
if (Info == PrimaryVirtualBaseInfo->Derived)
- UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset);
+ UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,
+ PlacingEmptyBase);
}
// Traverse all member variables.
// We are able to place the base at this offset. Make sure to update the
// empty base subobject map.
- UpdateEmptyBaseSubobjects(Info, Offset);
+ UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());
return true;
}
const CXXRecordDecl *Class,
uint64_t Offset) {
// We know that the only empty subobjects that can conflict with empty
- // field subobjects are subobjects empty bases that can be placed at offset
+ // field subobjects are subobjects of empty bases that can be placed at offset
// zero. Because of this, we only need to keep track of empty field
// subobjects with offsets less than the size of the largest empty
// subobject for our class.
for (uint64_t I = 0; I != NumElements; ++I) {
// We know that the only empty subobjects that can conflict with empty
- // field subobjects are subobjects empty bases that can be placed at
+ // field subobjects are subobjects of empty bases that can be placed at
// offset zero. Because of this, we only need to keep track of empty field
// subobjects with offsets less than the size of the largest empty
// subobject for our class.