]> granicus.if.org Git - clang/commitdiff
Darwin x86_32: Treat records with unnamed bit-fields as "empty".
authorDaniel Dunbar <daniel@zuster.org>
Mon, 11 May 2009 18:58:49 +0000 (18:58 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Mon, 11 May 2009 18:58:49 +0000 (18:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71461 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGen/x86_32-arguments.c

index 2223f65acf468ab02b3733f7bd0079990d4b909d..36b6b92ab8213a9983957d1370e2c65e097c886e 100644 (file)
@@ -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;
index 0690639ab17c3624e54aa43c251bce68f64b2624..b9853d809e9b75f78b904fe24e1255c29e06449e 100644 (file)
@@ -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