diff options
Diffstat (limited to 'clang/test/CodeGenCXX')
-rw-r--r-- | clang/test/CodeGenCXX/constructors.cpp | 94 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/default-arguments.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/destructors.cpp | 46 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/virtual-destructor-calls.cpp | 25 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/vtable-pointer-initialization.cpp | 11 |
5 files changed, 172 insertions, 10 deletions
diff --git a/clang/test/CodeGenCXX/constructors.cpp b/clang/test/CodeGenCXX/constructors.cpp new file mode 100644 index 00000000000..2c95c91e111 --- /dev/null +++ b/clang/test/CodeGenCXX/constructors.cpp @@ -0,0 +1,94 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s + +struct Member { int x; Member(); Member(int); Member(const Member &); }; +struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); }; + +struct ValueClass { + ValueClass(int x, int y) : x(x), y(y) {} + int x; + int y; +}; // subject to ABI trickery + + + +/* Test basic functionality. */ +class A { + A(struct Undeclared &); + A(ValueClass); + Member mem; +}; + +A::A(struct Undeclared &ref) : mem(0) {} + +// Check that delegation works. +// CHECK: define void @_ZN1AC1ER10Undeclared( +// CHECK: call void @_ZN1AC2ER10Undeclared( + +// CHECK: define void @_ZN1AC2ER10Undeclared( +// CHECK: call void @_ZN6MemberC1Ei( + +A::A(ValueClass v) : mem(v.y - v.x) {} + +// CHECK: define void @_ZN1AC1E10ValueClass( +// CHECK: call void @_ZN1AC2E10ValueClass( + +// CHECK: define void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + + +/* Test that things work for inheritance. */ +struct B : A { + B(struct Undeclared &); + Member mem; +}; + +B::B(struct Undeclared &ref) : A(ref), mem(1) {} + +// CHECK: define void @_ZN1BC1ER10Undeclared( +// CHECK: call void @_ZN1BC2ER10Undeclared( + +// CHECK: define void @_ZN1BC2ER10Undeclared( +// CHECK: call void @_ZN1AC2ER10Undeclared( +// CHECK: call void @_ZN6MemberC1Ei( + + + +/* Test that the delegation optimization is disabled for classes with + virtual bases (for now). This is necessary because a vbase + initializer could access one of the parameter variables by + reference. That's a solvable problem, but let's not solve it right + now. */ +struct C : virtual A { + C(int); + Member mem; +}; +C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {} + +// CHECK: define void @_ZN1CC1Ei( +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + +// CHECK: define void @_ZN1CC2Ei( +// CHECK: call void @_ZN6MemberC1Ei( + + + +/* Test that the delegation optimization is disabled for varargs + constructors. */ +struct D : A { + D(int, ...); + Member mem; +}; + +D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} + +// CHECK: define void @_ZN1DC1Eiz( +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( + +// CHECK: define void @_ZN1DC2Eiz( +// CHECK: call void @_ZN10ValueClassC1Eii( +// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK: call void @_ZN6MemberC1Ei( diff --git a/clang/test/CodeGenCXX/default-arguments.cpp b/clang/test/CodeGenCXX/default-arguments.cpp index 282e5d0d504..2ed1567697c 100644 --- a/clang/test/CodeGenCXX/default-arguments.cpp +++ b/clang/test/CodeGenCXX/default-arguments.cpp @@ -43,11 +43,7 @@ struct C { }; // CHECK: define void @_ZN1CC1Ev( -// CHECK: call void @_ZN2A1C1Ev( -// CHECK: call void @_ZN2A2C1Ev( -// CHECK: call void @_ZN1BC1ERK2A1RK2A2( -// CHECK: call void @_ZN2A2D1Ev -// CHECK: call void @_ZN2A1D1Ev +// CHECK: call void @_ZN1CC2Ev( // CHECK: define void @_ZN1CC2Ev( // CHECK: call void @_ZN2A1C1Ev( diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp index f06661a7447..accd1b34986 100644 --- a/clang/test/CodeGenCXX/destructors.cpp +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -1,4 +1,11 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -mconstructor-aliases | FileCheck %s + +// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev +// CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev +// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev + struct A { int a; @@ -60,7 +67,7 @@ namespace test0 { // The function-try-block won't suppress -mconstructor-aliases here. A::~A() try { } catch (int i) {} -// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev +// complete destructor alias tested above // CHECK: define void @_ZN5test01AD2Ev // CHECK: invoke void @_ZN5test06MemberD1Ev @@ -89,3 +96,40 @@ namespace test0 { // CHECK: invoke void @_ZN5test04BaseD2Ev // CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] } + +// Test base-class aliasing. +namespace test1 { + struct A { ~A(); char ***m; }; // non-trivial destructor + struct B { ~B(); }; // non-trivial destructor + struct Empty { }; // trivial destructor, empty + struct NonEmpty { int x; }; // trivial destructor, non-empty + + struct M : A { ~M(); }; + M::~M() {} // alias tested above + + struct N : A, Empty { ~N(); }; + N::~N() {} // alias tested above + + struct O : Empty, A { ~O(); }; + O::~O() {} // alias tested above + + struct P : NonEmpty, A { ~P(); }; + P::~P() {} // CHECK: define void @_ZN5test11PD2Ev + + struct Q : A, B { ~Q(); }; + Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev + + struct R : A { ~R(); }; + R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev + + struct S : A { ~S(); int x; }; + S::~S() {} // alias tested above + + struct T : A { ~T(); B x; }; + T::~T() {} // CHECK: define void @_ZN5test11TD2Ev + + // The VTT parameter prevents this. We could still make this work + // for calling conventions that are safe against extra parameters. + struct U : A, virtual B { ~U(); }; + U::~U() {} // CHECK: define void @_ZN5test11UD2Ev +} diff --git a/clang/test/CodeGenCXX/virtual-destructor-calls.cpp b/clang/test/CodeGenCXX/virtual-destructor-calls.cpp index 91fd598d4c9..c5b9262a067 100644 --- a/clang/test/CodeGenCXX/virtual-destructor-calls.cpp +++ b/clang/test/CodeGenCXX/virtual-destructor-calls.cpp @@ -1,16 +1,25 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s +struct Member { + ~Member(); +}; + struct A { virtual ~A(); }; struct B : A { + Member m; virtual ~B(); }; // Complete dtor: just an alias because there are no virtual bases. // CHECK: @_ZN1BD1Ev = alias {{.*}} @_ZN1BD2Ev +// (aliases from C) +// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev +// CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev + // Deleting dtor: defers to the complete dtor. // CHECK: define void @_ZN1BD0Ev // CHECK: call void @_ZN1BD1Ev @@ -18,6 +27,22 @@ struct B : A { // Base dtor: actually calls A's base dtor. // CHECK: define void @_ZN1BD2Ev +// CHECK: call void @_ZN6MemberD1Ev // CHECK: call void @_ZN1AD2Ev B::~B() { } + +struct C : B { + ~C(); +}; + +C::~C() { } + +// Complete dtor: just an alias (checked above). + +// Deleting dtor: defers to the complete dtor. +// CHECK: define void @_ZN1CD0Ev +// CHECK: call void @_ZN1CD1Ev +// CHECK: call void @_ZdlPv + +// Base dtor: just an alias to B's base dtor. diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp index ebe531529b8..75620ab8e62 100644 --- a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp @@ -42,13 +42,16 @@ struct B : Base { void f() { B b; } // CHECK: define linkonce_odr void @_ZN1BC1Ev( -// CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) -// CHECK: call void @_ZN5FieldC1Ev -// CHECK: ret void +// CHECK: call void @_ZN1BC2Ev( // CHECK: define linkonce_odr void @_ZN1BD1Ev( // CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void + +// CHECK: define linkonce_odr void @_ZN1BC2Ev( +// CHECK: call void @_ZN4BaseC2Ev( +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) +// CHECK: call void @_ZN5FieldC1Ev +// CHECK: ret void |