Make thunk this/return adjustment ABI-specific. Also, fix the return adjustment when using -cxx-abi microsoft

Reviewed at http://llvm-reviews.chandlerc.com/D2026

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193679 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/microsoft-abi-thunks.cpp b/test/CodeGenCXX/microsoft-abi-thunks.cpp
index 3b4281f..6b8270b 100644
--- a/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -61,14 +61,14 @@
 
 C::C() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
-// CODEGEN:   getelementptr inbounds i8* {{.*}}, i64 -4
+// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
+// CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // FIXME: should actually call _EC, not _GC.
 // CODEGEN:   call x86_thiscallcc void @"\01??_GC@@UAEPAXI@Z"
 // CODEGEN: ret
 
-// CODEGEN: define weak x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
-// CODEGEN:   getelementptr inbounds i8* {{.*}}, i64 -4
+// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
+// CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // CODEGEN:   call x86_thiscallcc void @"\01?public_f@C@@UAEXXZ"(%struct.C*
 // CODEGEN: ret
 
@@ -81,6 +81,7 @@
 };
 
 struct E : D {
+  E();
   virtual C* goo();
   // MANGLING-DAG: @"\01?goo@E@@UAEPAUC@@XZ"
   // MANGLING-DAG: @"\01?goo@E@@QAEPAUB@@XZ"
@@ -88,14 +89,15 @@
   // MANGLING-X64-DAG: @"\01?goo@E@@QEAAPEAUB@@XZ"
 };
 
-E e;  // Emits vftable and forces thunk generation.
+E::E() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN: define weak x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
 // CODEGEN:   call x86_thiscallcc %struct.C* @"\01?goo@E@@UAEPAUC@@XZ"
-// CODEGEN:   getelementptr inbounds i8* {{.*}}, i64 4
+// CODEGEN:   getelementptr inbounds i8* {{.*}}, i32 4
 // CODEGEN: ret
 
 struct F : virtual A, virtual B {
+  virtual void own_method();
   virtual ~F();
 };
 
@@ -115,6 +117,27 @@
 
 H h;
 
+struct I : D {
+  I();
+  virtual F* goo();
+};
+
+I::I() {}  // Emits vftable and forces thunk generation.
+
+// CODEGEN-LABEL: define weak x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ"
+// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo@I@@UAEPAUF@@XZ"
+// CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
+// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4
+// CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i8**
+// CODEGEN: %[[VBTABLE:.*]] = load i8** %[[VBPTR]]
+// CODEGEN: %[[VBASE_OFFSET_PTR_i8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 8
+// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = bitcast i8* %[[VBASE_OFFSET_PTR_i8]] to i32*
+// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32* %[[VBASE_OFFSET_PTR]]
+// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
+// CODEGEN: %[[RES:.*]] = bitcast i8* %[[RES_i8]] to %struct.F*
+// CODEGEN: phi %struct.F* {{.*}} %[[RES]]
+// CODEGEN: ret %struct.{{[BF]}}*
+
 // FIXME: Write vtordisp adjusting thunk tests
 
 namespace CrashOnThunksForAttributedType {
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
index 11f5654..c3f1ab0 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
@@ -275,7 +275,7 @@
   // THIS-THUNKS-Test1-NEXT:     [this adjustment: -4 non-virtual]
 
   // THIS-THUNKS-Test1: Thunks for 'void this_adjustment::Test1::g()' (1 entry).
-  // THIS-THUNKS-Test1-NEXT: 0 | this adjustment: -4 non-virtual
+  // THIS-THUNKS-Test1-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // THIS-THUNKS-Test1: VFTable indices for 'this_adjustment::Test1' (1 entries).
   // THIS-THUNKS-Test1-NEXT: 0 | void this_adjustment::Test1::g()
@@ -301,7 +301,7 @@
   // THIS-THUNKS-Test2-NEXT:     [this adjustment: -4 non-virtual]
 
   // THIS-THUNKS-Test2: Thunks for 'void this_adjustment::Test2::g()' (1 entry).
-  // THIS-THUNKS-Test2-NEXT: 0 | this adjustment: -4 non-virtual
+  // THIS-THUNKS-Test2-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // THIS-THUNKS-Test2: VFTable indices for 'this_adjustment::Test2' (1 entries).
   // THIS-THUNKS-Test2-NEXT: via vfptr at offset 4
@@ -327,18 +327,18 @@
 
   // THIS-THUNKS-Test3: VFTable for 'A' in 'no_thunks::Test2' in 'this_adjustment::Test3' (1 entries).
   // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::f()
-  // THIS-THUNKS-Test3-NEXT: [this adjustment: -8 non-virtual]
+  // THIS-THUNKS-Test3-NEXT:     [this adjustment: -8 non-virtual]
 
   // THIS-THUNKS-Test3: Thunks for 'void this_adjustment::Test3::f()' (1 entry).
-  // THIS-THUNKS-Test3-NEXT: 0 | this adjustment: -8 non-virtual
+  // THIS-THUNKS-Test3-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // THIS-THUNKS-Test3: VFTable for 'B' in 'no_thunks::Test2' in 'this_adjustment::Test3' (2 entries).
   // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::g()
-  // THIS-THUNKS-Test3-NEXT: [this adjustment: -8 non-virtual]
+  // THIS-THUNKS-Test3-NEXT:     [this adjustment: -8 non-virtual]
   // THIS-THUNKS-Test3-NEXT: 1 | void B::h()
 
   // THIS-THUNKS-Test3: Thunks for 'void this_adjustment::Test3::g()' (1 entry).
-  // THIS-THUNKS-Test3-NEXT: 0 | this adjustment: -8 non-virtual
+  // THIS-THUNKS-Test3-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // THIS-THUNKS-Test3: VFTable indices for 'this_adjustment::Test3' (2 entries).
   // THIS-THUNKS-Test3-NEXT: via vfptr at offset 0
@@ -373,7 +373,7 @@
   // VDTOR-THUNKS-Test3-NEXT:     [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test3: Thunks for 'vdtor::Test3::~Test3()' (1 entry).
-  // VDTOR-THUNKS-Test3-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTOR-THUNKS-Test3-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test3: VFTable indices for 'vdtor::Test3' (1 entries).
   // VDTOR-THUNKS-Test3-NEXT: 0 | vdtor::Test3::~Test3() [scalar deleting]
@@ -398,7 +398,7 @@
   // VDTOR-THUNKS-Test5-NEXT:     [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test5: Thunks for 'vdtor::Test5::~Test5()' (1 entry).
-  // VDTOR-THUNKS-Test5-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTOR-THUNKS-Test5-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test5: VFTable indices for 'vdtor::Test5' (1 entries).
   // VDTOR-THUNKS-Test5-NEXT: -- accessible via vfptr at offset 4 --
@@ -418,7 +418,7 @@
   // VDTOR-THUNKS-Test6-NEXT:     [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test6: Thunks for 'vdtor::Test6::~Test6()' (1 entry).
-  // VDTOR-THUNKS-Test6-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTOR-THUNKS-Test6-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test6: VFTable indices for 'vdtor::Test6' (1 entries).
   // VDTOR-THUNKS-Test6-NEXT: -- accessible via vfptr at offset 4 --
@@ -436,7 +436,7 @@
   // VDTOR-THUNKS-Test7-NEXT:     [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test7: Thunks for 'vdtor::Test7::~Test7()' (1 entry).
-  // VDTOR-THUNKS-Test7-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTOR-THUNKS-Test7-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTOR-THUNKS-Test7: VFTable indices for 'vdtor::Test7' (1 entries).
   // VDTOR-THUNKS-Test7-NEXT: -- accessible via vfptr at offset 4 --
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index cfbdad9..781e4ad 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -22,6 +22,7 @@
 // RUN: FileCheck --check-prefix=VDTORS-P %s < %t
 // RUN: FileCheck --check-prefix=RET-W %s < %t
 // RUN: FileCheck --check-prefix=RET-T %s < %t
+// RUN: FileCheck --check-prefix=RET-V %s < %t
 
 // RUN: FileCheck --check-prefix=MANGLING %s < %t
 
@@ -152,7 +153,7 @@
 
   // TEST4: VFTable for 'A' in 'C' in 'Test4::X' (2 entries).
   // TEST4-NEXT: 0 | void C::f()
-  // TEST4-NEXT: [this adjustment: 8 non-virtual]
+  // TEST4-NEXT:     [this adjustment: 8 non-virtual]
   // TEST4-NEXT: 1 | void A::z()
 
   // TEST4-NOT: VFTable indices for 'Test4::X'
@@ -223,7 +224,7 @@
   // TEST7-NEXT: 1 | void A::z()
 
   // TEST7: Thunks for 'void C::f()' (1 entry).
-  // TEST7-NEXT: 0 | this adjustment: 8 non-virtual
+  // TEST7-NEXT: 0 | [this adjustment: 8 non-virtual]
 
   // TEST7-NOT: VFTable indices for 'Test7::Y'
 
@@ -338,7 +339,7 @@
   // TEST9-W-NEXT: 1 | void A::z()
 
   // TEST9-W: Thunks for 'void D::f()' (1 entry).
-  // TEST9-W-NEXT: 0 | this adjustment: -8 non-virtual
+  // TEST9-W-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // TEST9-W-NOT: VFTable indices for 'Test9::W'
 
@@ -371,7 +372,7 @@
   // TEST9-T-NEXT:     [this adjustment: -8 non-virtual]
 
   // TEST9-T: Thunks for 'void Test9::T::h()' (1 entry).
-  // TEST9-T-NEXT: 0 | this adjustment: -8 non-virtual
+  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // TEST9-T: VFTable for 'A' in 'D' in 'Test9::T' (2 entries).
   // TEST9-T-NEXT: 0 | void Test9::T::f()
@@ -380,10 +381,10 @@
   // TEST9-T-NEXT:     [this adjustment: -8 non-virtual]
 
   // TEST9-T: Thunks for 'void Test9::T::f()' (1 entry).
-  // TEST9-T-NEXT: 0 | this adjustment: -8 non-virtual
+  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // TEST9-T: Thunks for 'void Test9::T::z()' (1 entry).
-  // TEST9-T-NEXT: 0 | this adjustment: -8 non-virtual
+  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // TEST9-T: VFTable indices for 'Test9::T' (4 entries).
   // TEST9-T-NEXT: via vfptr at offset 0
@@ -464,7 +465,7 @@
   // VDTORS-U-NEXT: 1 | void vdtors::X::zzz()
 
   // VDTORS-U: Thunks for 'vdtors::W::~W()' (1 entry).
-  // VDTORS-U-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTORS-U-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTORS-U: VFTable indices for 'vdtors::U' (1 entries).
   // VDTORS-U-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
@@ -484,7 +485,7 @@
   // VDTORS-V-NEXT: 1 | void vdtors::X::zzz()
 
   // VDTORS-V: Thunks for 'vdtors::W::~W()' (1 entry).
-  // VDTORS-V-NEXT: 0 | this adjustment: -4 non-virtual
+  // VDTORS-V-NEXT: 0 | [this adjustment: -4 non-virtual]
 
   // VDTORS-V: VFTable indices for 'vdtors::V' (1 entries).
   // VDTORS-V-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
@@ -553,4 +554,22 @@
 };
 
 T t;
+
+struct U : virtual A {
+  virtual void g();  // adds a vfptr
+};
+
+struct V : Z {
+  // RET-V: VFTable for 'return_adjustment::Z' in 'return_adjustment::V' (2 entries).
+  // RET-V-NEXT: 0 | return_adjustment::U *return_adjustment::V::foo()
+  // RET-V-NEXT:     [return adjustment: vbptr at offset 4, vbase #1, 0 non-virtual]
+  // RET-V-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+
+  // RET-V: VFTable indices for 'return_adjustment::V' (1 entries).
+  // RET-V-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+
+  virtual U* foo();
+};
+
+V v;
 }