[cfe-commits] r103944 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGenCXX/x86_32-arguments.cpp

Daniel Dunbar daniel at zuster.org
Mon May 17 09:46:00 PDT 2010


Author: ddunbar
Date: Mon May 17 11:46:00 2010
New Revision: 103944

URL: http://llvm.org/viewvc/llvm-project?rev=103944&view=rev
Log:
C++/Darwin/i386 ABI: Fix some problems with empty record handling.
 - Check bases as part of isEmptyRecord().

 - C++ record fields are never empty in the Itanium ABI.

Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=103944&r1=103943&r2=103944&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Mon May 17 11:46:00 2010
@@ -71,6 +71,17 @@
     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT))
       FT = AT->getElementType();
 
+  const RecordType *RT = FT->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  // C++ record fields are never empty, at least in the Itanium ABI.
+  //
+  // FIXME: We should use a predicate for whether this behavior is true in the
+  // current ABI.
+  if (isa<CXXRecordDecl>(RT->getDecl()))
+    return false;
+
   return isEmptyRecord(Context, FT, AllowArrays);
 }
 
@@ -84,6 +95,14 @@
   const RecordDecl *RD = RT->getDecl();
   if (RD->hasFlexibleArrayMember())
     return false;
+
+  // If this is a C++ record, check the bases first.
+  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+    for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
+           e = CXXRD->bases_end(); i != e; ++i)
+      if (!isEmptyRecord(Context, i->getType(), true))
+        return false;
+
   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
          i != e; ++i)
     if (!isEmptyField(Context, *i, AllowArrays))
@@ -135,10 +154,8 @@
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
     for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
            e = CXXRD->bases_end(); i != e; ++i) {
-      const CXXRecordDecl *Base =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       // Ignore empty records.
-      if (Base->isEmpty())
+      if (isEmptyRecord(Context, i->getType(), true))
         continue;
 
       // If we already found an element then this isn't a single-element struct.

Modified: cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp?rev=103944&r1=103943&r2=103944&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp Mon May 17 11:46:00 2010
@@ -96,3 +96,21 @@
 typedef int (s6::*s6_mfp)();
 s6_mdp f6_0(s6_mdp a) { return a; }
 s6_mfp f6_1(s6_mfp a) { return a; }
+
+// CHECK: define double @_Z2f7v()
+struct s7_0 { unsigned : 0; };
+struct s7_1 { double x; };
+struct s7 : s7_0, s7_1 { };
+s7 f7() { return s7(); }
+
+// CHECK: define void @_Z2f8v(%struct.s8* sret %agg.result)
+struct s8_0 { };
+struct s8_1 { double x; };
+struct s8 { s8_0 a; s8_1 b; };
+s8 f8() { return s8(); }
+
+// CHECK: define void @_Z2f9v(%struct.s9* sret %agg.result)
+struct s9_0 { unsigned : 0; };
+struct s9_1 { double x; };
+struct s9 { s9_0 a; s9_1 b; };
+s9 f9() { return s9(); }





More information about the cfe-commits mailing list