return true;
}
+bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
+ uint64_t Offset) const {
+ if (const RecordType *RT = dyn_cast<RecordType>(FD->getType())) {
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ return canPlaceRecordAtOffset(RD, Offset);
+ }
+
+ // FIXME: Arrays.
+
+ return true;
+}
+
void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
uint64_t Offset) {
if (RD->isEmpty())
// Round up the current record size to the field's alignment boundary.
FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+
+ if (!IsUnion) {
+ while (true) {
+ // Check if we can place the field at this offset.
+ if (canPlaceFieldAtOffset(D, FieldOffset))
+ break;
+
+ // We can't try again.
+ FieldOffset += FieldAlign;
+ }
+ }
}
// Place this field at the current location.
/// (direct or indirect) of the same type having the same offset.
bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
+ /// canPlaceFieldAtOffset - Return whether a field can be placed at the given
+ /// offset.
+ bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
+
/// UpdateEmptyClassOffsets - Called after a record (either a base class
/// or a field) has been placed at the given offset. Will update the
/// EmptyClassOffsets map if the class is empty or has any empty bases or