Implement virtual dispatch. :-) This is self-consistent with clang,
but not yet necessarily perfectly consistent with gcc. Also addressed
Doug and John's comments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80137 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index 89411de..4d63ab0 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -91,6 +91,76 @@
// CHECK-LP64: movl $1, 12(%rax)
// CHECK-LP64: movl $2, 8(%rax)
+struct test12_A {
+ virtual void foo0() { }
+ virtual void foo();
+} *test12_pa;
+
+struct test12_B : public test12_A {
+ virtual void foo() { }
+} *test12_pb;
+
+struct test12_D : public test12_B {
+} *test12_pd;
+void test12_foo() {
+ test12_pa->foo0();
+ test12_pb->foo0();
+ test12_pd->foo0();
+ test12_pa->foo();
+ test12_pb->foo();
+ test12_pd->foo();
+ test12_pa->test12_A::foo();
+}
+
+// CHECK-LPOPT32:__Z10test12_foov:
+// CHECK-LPOPT32: movl _test12_pa, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pa, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// FIXME: See EmitCXXMemberCallExpr
+// CHECK-LPOPT32-NEXT call __ZN8test12_A3fooEv
+
+// CHECK-LPOPT64:__Z10test12_foov:
+// CHECK-LPOPT64: movq _test12_pa(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pa(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// FIXME: See EmitCXXMemberCallExpr
+// CHECK-LPOPT64-NEXT call __ZN8test12_A3fooEv
struct test6_B2 { virtual void funcB2(); char b[1000]; };
struct test6_B1 : virtual test6_B2 { virtual void funcB1(); };
@@ -115,7 +185,7 @@
struct test3_B2 : virtual test3_B3 { virtual void funcB2(); };
struct test3_B1 : virtual test3_B2 { virtual void funcB1(); };
-struct test3_D : virtual test3_B1 {
+struct test3_D : virtual test3_B1 {
virtual void funcD() { }
};
@@ -652,7 +722,6 @@
// CHECK-LP64-NEXT: .quad __ZN8test11_D2D2Ev
-
// CHECK-LP64: __ZTV1B:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI1B