diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-05-11 18:58:49 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-05-11 18:58:49 +0000 |
commit | 573b907e8ba3b74fc69cddaf63496c7bb5994196 (patch) | |
tree | 28ff67b0d68438c54583b0236bf7d7030f9d2ad2 | |
parent | ebd5a2dc1a3743fed9157379d89e5eb26293c9d6 (diff) |
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
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 46 | ||||
-rw-r--r-- | 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 |