================
@@ -45,6 +45,62 @@ bool clang::CIRGen::isEmptyFieldForLayout(const ASTContext
&context,
return isEmptyRecordForLayout(context, fd->getType());
}
+bool clang::CIRGen::isEmptyRecordForABI(const ASTContext &context, QualType t)
{
+ const auto *rd = t->getAsRecordDecl();
+ if (!rd)
+ return false;
+ if (rd->hasFlexibleArrayMember())
+ return false;
+
+ if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
+ // A vtable pointer is neither a base nor a field, so clang's predicate
+ // calls a polymorphic class empty and leans on its callers rejecting one
as
+ // non-trivially-copyable beforehand. This answer is read off the record
+ // type without that precondition, so rule it out here instead.
+ if (cxxrd->isDynamicClass())
+ return false;
+
+ for (const auto &i : cxxrd->bases())
+ if (!isEmptyRecordForABI(context, i.getType()))
+ return false;
+ }
+
+ for (const auto *i : rd->fields())
+ if (!isEmptyFieldForABI(context, i))
+ return false;
+ return true;
+}
+
+bool clang::CIRGen::isEmptyFieldForABI(const ASTContext &context,
+ const FieldDecl *fd) {
+ if (fd->isUnnamedBitField())
+ return true;
+
+ QualType ft = fd->getType();
+
+ // An array of empty records is empty, and a zero-length array always is.
+ bool wasArray = false;
+ while (const ConstantArrayType *at = context.getAsConstantArrayType(ft)) {
+ if (at->isZeroSize())
----------------
adams381 wrote:
Flexible array members do not hit this because its type is incomplete and the
loop only peels constant arrays, so it falls through and ends up as data.
I've added flexible array member tests to verify this properly.
https://github.com/llvm/llvm-project/pull/215175
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits