Add an implementation of thunks for varargs methods.  The implementation is a bit messy, but it is correct as long as the method in question doesn't use indirect gotos.  A couple of possible alternative implementations are outlined in FIXME's in this patch. rdar://problem/8077308 .



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130993 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index a74cc05..7c80b96 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -265,18 +265,42 @@
   struct C : B         { virtual C* f(); };
   C* C::f() { return 0; }
 
+  //  C::f itself.
+  // CHECK: define {{.*}} @_ZN6Test111C1fEv(
+
   //  The this-adjustment and return-adjustment thunk required when
   //  C::f appears in a vtable where A is at a nonzero offset from C.
   // CHECK: define {{.*}} @_ZTcv0_n24_v0_n32_N6Test111C1fEv(
 
-  //  C::f itself.
-  // CHECK: define {{.*}} @_ZN6Test111C1fEv(
-
   //  The return-adjustment thunk required when C::f appears in a vtable
   //  where A is at a zero offset from C.
   // CHECK: define {{.*}} @_ZTch0_v0_n32_N6Test111C1fEv(
 }
 
+// Varargs thunk test.
+namespace Test12 {
+  struct A {
+    virtual A* f(int x, ...);
+  };
+  struct B {
+    virtual B* f(int x, ...);
+  };
+  struct C : A, B {
+    virtual void c();
+    virtual C* f(int x, ...);
+  };
+  C* C::f(int x, ...) { return this; }
+
+  // C::f
+  // CHECK: define {{.*}} @_ZN6Test121C1fEiz
+
+  // Varargs thunk; check that both the this and covariant adjustments
+  // are generated.
+  // CHECK: define {{.*}} @_ZTchn8_h8_N6Test121C1fEiz
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 8
+}
+
 /**** The following has to go at the end of the file ****/
 
 // This is from Test5: