From 573b907e8ba3b74fc69cddaf63496c7bb5994196 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 11 May 2009 18:58:49 +0000 Subject: [PATCH] Darwin x86_32: Treat records with unnamed bit-fields as "empty". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71461 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCall.cpp | 46 +++++++++++++++++++-------------- test/CodeGen/x86_32-arguments.c | 6 +++++ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 2223f65acf..36b6b92ab8 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -157,8 +157,25 @@ void ABIArgInfo::dump() const { /***/ -/// isEmptyRecord - Return true iff a structure has no non-empty -/// members. Note that a structure with a flexible array member is not +static bool isEmptyRecord(ASTContext &Context, QualType T); + +/// isEmptyField - Return true iff a the field is "empty", that is it +/// is an unnamed bit-field or an (array of) empty record(s). +static bool isEmptyField(ASTContext &Context, const FieldDecl *FD) { + if (FD->isUnnamedBitfield()) + return true; + + QualType FT = FD->getType(); + // Arrays of empty records count as empty. + if (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) + if (isEmptyRecord(Context, AT->getElementType())) + return true; + + return isEmptyRecord(Context, FT); +} + +/// isEmptyRecord - Return true iff a structure contains only empty +/// fields. Note that a structure with a flexible array member is not /// considered empty. static bool isEmptyRecord(ASTContext &Context, QualType T) { const RecordType *RT = T->getAsRecordType(); @@ -168,11 +185,9 @@ static bool isEmptyRecord(ASTContext &Context, QualType T) { if (RD->hasFlexibleArrayMember()) return false; for (RecordDecl::field_iterator i = RD->field_begin(Context), - e = RD->field_end(Context); i != e; ++i) { - const FieldDecl *FD = *i; - if (!isEmptyRecord(Context, FD->getType())) + e = RD->field_end(Context); i != e; ++i) + if (!isEmptyField(Context, *i)) return false; - } return true; } @@ -199,15 +214,15 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { const FieldDecl *FD = *i; QualType FT = FD->getType(); + // Ignore empty fields. + if (isEmptyField(Context, FD)) + continue; + // Treat single element arrays as the element if (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) if (AT->getSize().getZExtValue() == 1) FT = AT->getElementType(); - // Ignore empty records and padding bit-fields. - if (isEmptyRecord(Context, FT) || FD->isUnnamedBitfield()) - continue; - if (Found) return 0; @@ -345,17 +360,10 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, e = RT->getDecl()->field_end(Context); i != e; ++i) { const FieldDecl *FD = *i; - // Empty structures are ignored. - if (isEmptyRecord(Context, FD->getType())) + // Empty fields are ignored. + if (isEmptyField(Context, FD)) continue; - // As are arrays of empty structures, but not generally, so we - // can't add this test higher in this routine. - if (const ConstantArrayType *AT = - Context.getAsConstantArrayType(FD->getType())) - if (isEmptyRecord(Context, AT->getElementType())) - continue; - // Check fields recursively. if (!shouldReturnTypeInRegister(FD->getType(), Context)) return false; diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c index 0690639ab1..b9853d809e 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments.c @@ -139,4 +139,10 @@ struct s32 { char a; unsigned : 0; } f32(void) {} // RUN: grep 'define float @f33()' %t && struct s33 { float a; long long : 0; } f33(void) {} +// RUN: grep 'define float @f34()' %t && +struct s34 { struct { int : 0 } a; float b; } f34(void) {} + +// RUN: grep 'define i16 @f35()' %t && +struct s35 { struct { int : 0 } a; char b; char c; } f35(void) {} + // RUN: true -- 2.40.0