Merge pull request #11924 from aschwaighofer/swift-4.0-branch_fix_objc_partial_apply

[4.0] IRGen: Fix ObjectiveC partial apply forwarding stub
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index 6f3544e..2f45171 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -896,8 +896,8 @@
     // Otherwise, we have a loadable type that can either be passed directly or
     // indirectly.
     assert(info.getSILStorageType().isObject());
-    auto &ti =
-        cast<LoadableTypeInfo>(IGM.getTypeInfo(info.getSILStorageType()));
+    auto curSILType = info.getSILStorageType();
+    auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(curSILType));
 
     // Load the indirectly passed parameter.
     auto &nativeSchema = ti.nativeParameterValueSchema(IGM);
@@ -906,8 +906,16 @@
       ti.loadAsTake(subIGF, paramAddr, translatedParams);
       continue;
     }
+    // Map from the native calling convention into the explosion schema.
+    auto &nativeParamSchema = ti.nativeParameterValueSchema(IGM);
+    Explosion nativeParam;
+    params.transferInto(nativeParam, nativeParamSchema.size());
+    Explosion nonNativeParam = nativeParamSchema.mapFromNative(
+        subIGF.IGM, subIGF, nativeParam, curSILType);
+    assert(nativeParam.empty());
+
     // Pass along the value.
-    ti.reexplode(subIGF, params, translatedParams);
+    ti.reexplode(subIGF, nonNativeParam, translatedParams);
   }
 
   // Prepare the call to the underlying method.
diff --git a/test/IRGen/Inputs/usr/include/Gizmo.h b/test/IRGen/Inputs/usr/include/Gizmo.h
index 5b4e937..c9cf43e 100644
--- a/test/IRGen/Inputs/usr/include/Gizmo.h
+++ b/test/IRGen/Inputs/usr/include/Gizmo.h
@@ -23,6 +23,13 @@
   } size;
 };
 
+struct Fob {
+  unsigned long a;
+  unsigned b;
+  unsigned c;
+  unsigned long d;
+} Fob;
+
 typedef long NSInteger;
 
 @interface Gizmo : NSObject
@@ -37,6 +44,7 @@
 - (struct NSRect) frame;
 - (void) setFrame: (struct NSRect) rect;
 - (void) frob;
+- (void) test: (struct Fob) fob;
 + (void) runce;
 @end
 
diff --git a/test/IRGen/partial_apply_objc.sil b/test/IRGen/partial_apply_objc.sil
index 94f716c..ab5340d 100644
--- a/test/IRGen/partial_apply_objc.sil
+++ b/test/IRGen/partial_apply_objc.sil
@@ -196,3 +196,30 @@
   %g = partial_apply %f(%c) : $@convention(thin) Gizmo -> ()
   return %g : $@callee_owned () -> ()
 }
+
+// CHECK: define internal swiftcc void @_T0Ta.17(i64, i64, i64, %swift.refcounted* swiftself)
+// CHECK: [[TMPCOERCE:%.*]] = alloca { i64, i64, i64 }
+// CHECK: [[INDIRECTTEMP:%.*]] = alloca %TSC3FobV
+// CHECK: [[ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 0
+// CHECK:  store i64 %0, i64* [[ADDR]]
+// CHECK:  [[ADDR:%.]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 1
+// CHECK:  store i64 %1, i64* [[ADDR]]
+// CHECK:  [[ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 2
+// CHECK:  store i64 %2, i64* [[ADDR]]
+// CHECK:  load i64
+// CHECK:  load i32
+// CHECK:  load i32
+// CHECK:  load i64
+// CHECK:  store i64
+// CHECK:  store i32
+// CHECK:  store i32
+// CHECK:  store i64
+// CHECK:  objc_msgSend
+// CHECK:  ret void
+
+sil @objc_partial_apply_2 : $@convention(thin) Gizmo -> @callee_owned (Fob) -> () {
+entry(%c : $Gizmo):
+  %m = class_method [volatile] %c : $Gizmo, #Gizmo.test!1.foreign : (Gizmo) -> (Fob) -> (), $@convention(objc_method) (Fob,  Gizmo) -> ()
+  %p = partial_apply %m(%c) : $@convention(objc_method) (Fob,  Gizmo) -> ()
+  return %p : $@callee_owned (Fob) -> ()
+}