From 952eddef9aff85b1e92626e89baaf7a360e2ac85 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Sun, 22 Dec 2013 00:07:40 +0000
Subject: Vendor import of clang release_34 branch r197841 (effectively, 3.4
 RC3): https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841

---
 test/CodeGenCXX/virtual-base-cast.cpp | 54 +++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

(limited to 'test/CodeGenCXX/virtual-base-cast.cpp')

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{{.*}} }
-- 
cgit v1.1