summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/virtual-base-cast.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-05-29 18:02:47 +0000
committerReid Kleckner <reid@kleckner.net>2013-05-29 18:02:47 +0000
commitb0f533e716ae5a21ca5682ea235a68082fd5ed28 (patch)
tree6e981fc0eeb609a4c4b6f73cb089774f33e09f2b /test/CodeGenCXX/virtual-base-cast.cpp
parentc72ff4f71833c46702fbfc64a3b7743c4f2002a9 (diff)
[ms-cxxabi] Implement MSVC virtual base adjustment
While we can't yet emit vbtables, this allows us to find virtual bases of objects constructed in other TUs. This make iostream hello world work, since basic_ostream virtually inherits from basic_ios. Differential Revision: http://llvm-reviews.chandlerc.com/D795 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182870 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/virtual-base-cast.cpp')
-rw-r--r--test/CodeGenCXX/virtual-base-cast.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
index f469636b22..40e68f6722 100644
--- a/test/CodeGenCXX/virtual-base-cast.cpp
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -cxx-abi microsoft -emit-llvm %s -o - -triple i686-pc-win32 | FileCheck -check-prefix MSVC %s
struct A { int a; virtual int aa(); };
struct B { int b; virtual int bb(); };
@@ -17,6 +18,16 @@ A* a() { return x; }
// CHECK: load i32* [[CASTVBASEOFFSETPTRA]]
// CHECK: }
+// MSVC: @"\01?a@@YAPAUA@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
+// MSVC: %[[vbtable:.*]] = load i8** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 4
+// MSVC: %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
+// MSVC: %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
B* b() { return x; }
// CHECK: @_Z1bv() [[NUW]]
// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -20
@@ -24,6 +35,18 @@ B* b() { return x; }
// CHECK: load i32* [[CASTVBASEOFFSETPTRA]]
// CHECK: }
+// Same as 'a' except we use a different vbtable offset.
+// MSVC: @"\01?b@@YAPAUB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
+// MSVC: %[[vbtable:.*]] = load i8** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 8
+// MSVC: %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
+// MSVC: %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
+
BB* c() { return x; }
// CHECK: @_Z1cv() [[NUW]]
// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -24
@@ -32,4 +55,35 @@ BB* c() { return x; }
// CHECK: add i32 [[VBASEOFFSETC]], 8
// CHECK: }
+// Same as 'a' except we use a different vbtable offset.
+// MSVC: @"\01?c@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
+// MSVC: %[[vbtable:.*]] = load i8** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 16
+// MSVC: %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
+// MSVC: %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
+// Put the vbptr at a non-zero offset inside a non-virtual base.
+struct E { int e; };
+struct F : E, D { int f; };
+
+F* y;
+
+BB* d() { return y; }
+
+// Same as 'c' except the vbptr offset is 4, changing the initial GEP and the
+// final add.
+// MSVC: @"\01?d@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 4
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
+// MSVC: %[[vbtable:.*]] = load i8** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 16
+// MSVC: %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
+// MSVC: %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC: add nsw i32 4, %[[offset]]
+// MSVC: }
+
// CHECK: attributes [[NUW]] = { nounwind{{.*}} }