diff options
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 f469636..40e68f6 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{{.*}} } |