]> granicus.if.org Git - clang/commitdiff
Class objects passed by value follow the same rules as structure objects.
authorAkira Hatanaka <ahatanaka@mips.com>
Thu, 9 Feb 2012 19:54:16 +0000 (19:54 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Thu, 9 Feb 2012 19:54:16 +0000 (19:54 +0000)
Double fields of by-value class objects should be passed in floating point
registers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150200 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TargetInfo.cpp
test/CodeGen/mips64-class-return.cpp

index b48bff8a1e7fe5a7d7fc7384c7cb99dbfe3b037e..cae8f5fb1a0f3e5c0f9b2d3de1d4aa7dc686dad2 100644 (file)
@@ -3065,9 +3065,10 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const {
   if (Ty->isComplexType())
     return CGT.ConvertType(Ty);
 
-  const RecordType *RT = Ty->getAsStructureType();
+  const RecordType *RT = Ty->getAs<RecordType>();
 
-  if (!RT)
+  // Unions are passed in integer registers.
+  if (!RT || !RT->isStructureOrClassType())
     return 0;
 
   const RecordDecl *RD = RT->getDecl();
@@ -3080,6 +3081,8 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const {
   llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
   SmallVector<llvm::Type*, 8> ArgList;
 
+  // Iterate over fields in the struct/class and check if there are any aligned
+  // double fields.
   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
        i != e; ++i, ++idx) {
     const QualType Ty = (*i)->getType();
@@ -3101,7 +3104,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const {
     LastOffset = Offset + 64;
   }
 
-  // This structure doesn't have an aligned double field.
+  // This struct/class doesn't have an aligned double field.
   if (!LastOffset)
     return 0;
 
index eca8d5b2f727139208136db70cf5bb5f84df328d..dc9ec0f5be4e66e90d6fc0a09468840fc733005c 100644 (file)
@@ -16,8 +16,13 @@ class D1 : public B1 {
   float f;
 };
 
+class D2 : public B0 {
+  double d2;
+};
+
 extern D0 gd0;
 extern D1 gd1;
+extern D2 gd2;
 
 // CHECK: define { i64, i64 } @_Z4foo1v() 
 D0 foo1(void) {
@@ -29,3 +34,13 @@ D1 foo2(void) {
   return gd1;
 }
 
+// CHECK: define void @_Z4foo32D2(i64 %a0.coerce0, double %a0.coerce1) 
+void foo3(D2 a0) {
+  gd2 = a0;
+}
+
+// CHECK: define void @_Z4foo42D0(%class.D0* nocapture byval %a0)
+void foo4(D0 a0) {
+  gd0 = a0;
+}
+