diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-05-29 18:02:47 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-05-29 18:02:47 +0000 |
commit | b0f533e716ae5a21ca5682ea235a68082fd5ed28 (patch) | |
tree | 6e981fc0eeb609a4c4b6f73cb089774f33e09f2b /test/CodeGenCXX/virtual-base-cast.cpp | |
parent | c72ff4f71833c46702fbfc64a3b7743c4f2002a9 (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.cpp | 54 |
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{{.*}} } |