2015-06-11 16:12:44 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
|
|
|
|
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
|
2013-11-16 01:24:45 +08:00
|
|
|
|
|
|
|
struct S {
|
|
|
|
int x, y, z;
|
|
|
|
};
|
|
|
|
|
2014-05-16 07:01:46 +08:00
|
|
|
// U is not trivially copyable, and requires inalloca to pass by value.
|
|
|
|
struct U {
|
|
|
|
int u;
|
|
|
|
U();
|
|
|
|
~U();
|
|
|
|
U(const U &);
|
|
|
|
};
|
|
|
|
|
2015-06-11 16:12:44 +08:00
|
|
|
struct B;
|
|
|
|
|
2013-11-16 01:24:45 +08:00
|
|
|
struct C {
|
|
|
|
virtual void foo();
|
|
|
|
virtual int bar(int, double);
|
|
|
|
virtual S baz(int);
|
2014-05-16 07:01:46 +08:00
|
|
|
virtual S qux(U);
|
2015-03-14 14:34:41 +08:00
|
|
|
virtual void thud(...);
|
2015-06-11 16:12:44 +08:00
|
|
|
virtual void (B::*plugh())();
|
2013-11-16 01:24:45 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
struct D {
|
|
|
|
virtual void foo();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void f() {
|
|
|
|
void (C::*ptr)();
|
|
|
|
ptr = &C::foo;
|
|
|
|
ptr = &C::foo; // Don't crash trying to define the thunk twice :)
|
|
|
|
|
|
|
|
int (C::*ptr2)(int, double);
|
|
|
|
ptr2 = &C::bar;
|
|
|
|
|
|
|
|
S (C::*ptr3)(int);
|
|
|
|
ptr3 = &C::baz;
|
|
|
|
|
|
|
|
void (D::*ptr4)();
|
|
|
|
ptr4 = &D::foo;
|
|
|
|
|
2014-05-16 07:01:46 +08:00
|
|
|
S (C::*ptr5)(U);
|
|
|
|
ptr5 = &C::qux;
|
|
|
|
|
2015-03-14 14:34:41 +08:00
|
|
|
void (C::*ptr6)(...);
|
|
|
|
ptr6 = &C::thud;
|
|
|
|
|
2015-06-11 16:12:44 +08:00
|
|
|
auto ptr7 = &C::plugh;
|
|
|
|
|
2014-05-16 07:01:46 +08:00
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define dso_local void @"?f@@YAXXZ"()
|
|
|
|
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AE" to i8*), i8** %ptr
|
|
|
|
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B3AE" to i8*), i8** %ptr2
|
|
|
|
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AE" to i8*), i8** %ptr3
|
[MS] Mangle a hash of the main file path into anonymous namespaces
Summary:
This is needed to avoid conflicts in mangled names for codeview types in
anonymous namespaces. In CodeView, types refer to each other typically
through forward declarations, which contain mangled names. These names
have to be unique, otherwise the debugger will look up the mangled name
and find the wrong definition.
Furthermore, ThinLTO will deduplicate the types, and debug info
verification can fail when the types have the wrong sizes. This is
PR38608.
Fixes PR38609.
Reviewers: majnemer, inglorion, hans
Subscribers: mehdi_amini, aprantl, JDevlieghere, dexonsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D50877
llvm-svn: 340079
2018-08-18 04:59:27 +08:00
|
|
|
// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AE" to i8*), i8** %ptr4
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define dso_local void @"?f@@YAXXZ"()
|
|
|
|
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AA" to i8*), i8** %ptr
|
|
|
|
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AA" to i8*), i8** %ptr2
|
|
|
|
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BBA@AA" to i8*), i8** %ptr3
|
[MS] Mangle a hash of the main file path into anonymous namespaces
Summary:
This is needed to avoid conflicts in mangled names for codeview types in
anonymous namespaces. In CodeView, types refer to each other typically
through forward declarations, which contain mangled names. These names
have to be unique, otherwise the debugger will look up the mangled name
and find the wrong definition.
Furthermore, ThinLTO will deduplicate the types, and debug info
verification can fail when the types have the wrong sizes. This is
PR38608.
Fixes PR38609.
Reviewers: majnemer, inglorion, hans
Subscribers: mehdi_amini, aprantl, JDevlieghere, dexonsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D50877
llvm-svn: 340079
2018-08-18 04:59:27 +08:00
|
|
|
// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AA" to i8*), i8** %ptr
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK64: }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Thunk for calling the 1st virtual function in C with no parameters.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BA@AE"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK32: #[[ATTR:[0-9]+]]
|
2014-08-30 06:06:20 +08:00
|
|
|
// CHECK32-NOT: unnamed_addr
|
2015-01-21 09:21:31 +08:00
|
|
|
// CHECK32: comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK32-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BA@AA"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK64: #[[ATTR:[0-9]+]]
|
2014-08-30 06:06:20 +08:00
|
|
|
// CHECK64-NOT: unnamed_addr
|
2015-01-21 09:21:31 +08:00
|
|
|
// CHECK64: comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK64-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK64: }
|
|
|
|
|
|
|
|
// Thunk for calling the 2nd virtual function in C, taking int and double as parameters, returning int.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B3AE"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK32: #[[ATTR]] comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK32-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$B7AA"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK64: #[[ATTR]] comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK64-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK64: }
|
|
|
|
|
|
|
|
// Thunk for calling the 3rd virtual function in C, taking an int parameter, returning a struct.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B7AE"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK32: #[[ATTR]] comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK32-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(%struct.C* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK64: #[[ATTR]] comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK64-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK64: }
|
|
|
|
|
|
|
|
// Thunk for calling the virtual function in internal class D.
|
[MS] Mangle a hash of the main file path into anonymous namespaces
Summary:
This is needed to avoid conflicts in mangled names for codeview types in
anonymous namespaces. In CodeView, types refer to each other typically
through forward declarations, which contain mangled names. These names
have to be unique, otherwise the debugger will look up the mangled name
and find the wrong definition.
Furthermore, ThinLTO will deduplicate the types, and debug info
verification can fail when the types have the wrong sizes. This is
PR38608.
Fixes PR38609.
Reviewers: majnemer, inglorion, hans
Subscribers: mehdi_amini, aprantl, JDevlieghere, dexonsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D50877
llvm-svn: 340079
2018-08-18 04:59:27 +08:00
|
|
|
// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A0x{{[^@]*}}@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK32: #[[ATTR]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK32-NEXT: ret void
|
2013-11-16 01:24:45 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
[MS] Mangle a hash of the main file path into anonymous namespaces
Summary:
This is needed to avoid conflicts in mangled names for codeview types in
anonymous namespaces. In CodeView, types refer to each other typically
through forward declarations, which contain mangled names. These names
have to be unique, otherwise the debugger will look up the mangled name
and find the wrong definition.
Furthermore, ThinLTO will deduplicate the types, and debug info
verification can fail when the types have the wrong sizes. This is
PR38608.
Fixes PR38609.
Reviewers: majnemer, inglorion, hans
Subscribers: mehdi_amini, aprantl, JDevlieghere, dexonsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D50877
llvm-svn: 340079
2018-08-18 04:59:27 +08:00
|
|
|
// CHECK64-LABEL: define internal void @"??_9D@?A0x{{[^@]*}}@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK64: #[[ATTR]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK64-NEXT: ret void
|
2014-05-16 07:01:46 +08:00
|
|
|
// CHECK64: }
|
|
|
|
|
2014-07-26 09:34:32 +08:00
|
|
|
// Thunk for calling the fourth virtual function in C, taking a struct parameter
|
|
|
|
// and returning a struct.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BM@AE"(%struct.C* %this, ...) {{.*}} comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-08-30 05:43:29 +08:00
|
|
|
// CHECK32-NEXT: ret void
|
2014-05-16 07:01:46 +08:00
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBI@AA"(%struct.C* %this, ...) {{.*}} comdat
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2014-07-26 09:34:32 +08:00
|
|
|
// CHECK64: ret void
|
|
|
|
// CHECK64: }
|
2015-01-22 06:18:17 +08:00
|
|
|
|
2015-03-14 14:34:41 +08:00
|
|
|
// Thunk for calling the fifth virtual function in C which uses the __cdecl calling convention.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
2015-03-14 14:34:41 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
|
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK32: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2015-03-14 14:34:41 +08:00
|
|
|
// CHECK32: ret void
|
|
|
|
// CHECK32: }
|
|
|
|
//
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BCA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
2015-03-14 14:34:41 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
|
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
2015-03-14 14:34:41 +08:00
|
|
|
// CHECK64: ret void
|
|
|
|
// CHECK64: }
|
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK32: define linkonce_odr x86_thiscallcc void @"??_9C@@$BBE@AE"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
2015-06-11 16:12:44 +08:00
|
|
|
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5
|
|
|
|
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
|
|
|
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
|
|
|
// CHECK32: ret void
|
|
|
|
// CHECK32: }
|
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK64: define linkonce_odr void @"??_9C@@$BCI@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
2015-06-11 16:12:44 +08:00
|
|
|
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5
|
|
|
|
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
|
|
|
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
|
|
|
// CHECK64: ret void
|
|
|
|
// CHECK64: }
|
|
|
|
|
2015-01-22 06:18:17 +08:00
|
|
|
// CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}
|