================
@@ -21,6 +25,94 @@ using namespace clang::CodeGen;
namespace {
+/// True if \p Ty is a record whose fields (or bases) include a field that
+/// is empty for layout, or that contain such a field transitively through
+/// member or base types.
+static bool recordTypeHasEmptyFieldForLayout(ASTContext &Ctx, QualType Ty) {
+ const RecordDecl *RD = Ty->getAsRecordDecl();
+ if (!RD)
+ return false;
+
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ for (const auto &B : CXXRD->bases()) {
+ if (recordTypeHasEmptyFieldForLayout(Ctx, B.getType()))
+ return true;
+ }
+ }
+
+ for (const FieldDecl *FD : RD->fields()) {
+ if (isEmptyFieldForLayout(Ctx, FD))
+ return true;
+ if (recordTypeHasEmptyFieldForLayout(Ctx, FD->getType()))
+ return true;
+ }
+ return false;
+}
+
+/// Build a LLVM struct for AMDGPU aggregate return coercion: one element per
+/// non-empty base subobject and per field, ordered by \c ASTRecordLayout
+/// offsets (matching in-object layout). Nested records that also need this
+/// coercion use a nested coerce type; otherwise \c ConvertType is used.
+static llvm::Type *buildAMDGPUAggregateReturnCoerceType(CodeGenTypes &CGT,
+ ASTContext &Ctx,
+ QualType Ty) {
+ if (!recordTypeHasEmptyFieldForLayout(Ctx, Ty))
+ return nullptr;
+
+ const RecordDecl *RD = Ty->getAsRecordDecl();
+ if (!RD || !RD->getDefinition() || RD->isUnion())
+ return nullptr;
+ assert(!RD->hasFlexibleArrayMember());
+
+ // Vtable and dynamic-class layout are not represented here; use the normal
+ // LLVM record type as the coerce-to type.
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ if (CXXRD->isDynamicClass())
+ return nullptr;
+
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+
+ struct CoerceMember {
+ CharUnits Offset;
+ QualType Ty;
+ };
+ llvm::SmallVector<CoerceMember, 16> Members;
+
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ for (const CXXBaseSpecifier &B : CXXRD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
+ if (!BaseDecl || BaseDecl->isEmpty())
+ continue;
+ BaseDecl = BaseDecl->getDefinition();
+ CharUnits Off = B.isVirtual() ? Layout.getVBaseClassOffset(BaseDecl)
----------------
arsenm wrote:
In particular virtual base seems untested?
https://github.com/llvm/llvm-project/pull/197004
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits