class type (that uses a return slot), pass the return slot to the callee directly rather than allocating new storage and trying to copy the object. This appears to have been the cause of the remaining two Boost.Interprocess failures. llvm-svn: 104215
179 lines
2.4 KiB
C++
179 lines
2.4 KiB
C++
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
|
|
|
namespace Test1 {
|
|
|
|
// Check that we emit a non-virtual thunk for C::f.
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
struct B {
|
|
virtual void f();
|
|
};
|
|
|
|
struct C : A, B {
|
|
virtual void c();
|
|
|
|
virtual void f();
|
|
};
|
|
|
|
// CHECK: define void @_ZThn8_N5Test11C1fEv(
|
|
void C::f() { }
|
|
|
|
}
|
|
|
|
namespace Test2 {
|
|
|
|
// Check that we emit a thunk for B::f since it's overriding a virtual base.
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
struct B : virtual A {
|
|
virtual void b();
|
|
virtual void f();
|
|
};
|
|
|
|
// CHECK: define void @_ZTv0_n24_N5Test21B1fEv(
|
|
void B::f() { }
|
|
|
|
}
|
|
|
|
namespace Test3 {
|
|
|
|
// Check that we emit a covariant thunk for B::f.
|
|
|
|
struct V1 { };
|
|
struct V2 : virtual V1 { };
|
|
|
|
struct A {
|
|
virtual V1 *f();
|
|
};
|
|
|
|
struct B : A {
|
|
virtual void b();
|
|
|
|
virtual V2 *f();
|
|
};
|
|
|
|
// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv(
|
|
V2 *B::f() { return 0; }
|
|
|
|
}
|
|
|
|
namespace Test4 {
|
|
|
|
// Check that the thunk for 'C::f' has the same visibility as the function itself.
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
struct B {
|
|
virtual void f();
|
|
};
|
|
|
|
struct __attribute__((visibility("protected"))) C : A, B {
|
|
virtual void c();
|
|
|
|
virtual void f();
|
|
};
|
|
|
|
// CHECK: define protected void @_ZThn8_N5Test41C1fEv(
|
|
void C::f() { }
|
|
|
|
}
|
|
|
|
// Check that the thunk gets internal linkage.
|
|
namespace {
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
struct B {
|
|
virtual void f();
|
|
};
|
|
|
|
struct C : A, B {
|
|
virtual void c();
|
|
|
|
virtual void f();
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
}
|
|
|
|
// Force C::f to be used.
|
|
void f() {
|
|
C c;
|
|
|
|
c.f();
|
|
}
|
|
|
|
namespace Test5 {
|
|
|
|
// Check that the thunk for 'B::f' gets the same linkage as the function itself.
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
struct B : virtual A {
|
|
virtual void f() { }
|
|
};
|
|
|
|
void f(B b) {
|
|
b.f();
|
|
}
|
|
}
|
|
|
|
namespace Test6 {
|
|
struct X {
|
|
X();
|
|
X(const X&);
|
|
X &operator=(const X&);
|
|
~X();
|
|
};
|
|
|
|
struct P {
|
|
P();
|
|
P(const P&);
|
|
~P();
|
|
X first;
|
|
X second;
|
|
};
|
|
|
|
P getP();
|
|
|
|
struct Base1 {
|
|
int i;
|
|
|
|
virtual X f() { return X(); }
|
|
};
|
|
|
|
struct Base2 {
|
|
float real;
|
|
|
|
virtual X f() { return X(); }
|
|
};
|
|
|
|
struct Thunks : Base1, Base2 {
|
|
long l;
|
|
|
|
virtual X f();
|
|
};
|
|
|
|
// CHECK: define void @_ZThn16_N5Test66Thunks1fEv
|
|
// CHECK-NOT: memcpy
|
|
// CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}}
|
|
// CHECK: ret void
|
|
X Thunks::f() { return X(); }
|
|
}
|
|
|
|
// This is from Test5:
|
|
// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
|
|
// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
|