diff options
author | John McCall <rjmccall@apple.com> | 2010-08-31 07:33:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-31 07:33:07 +0000 |
commit | 4c40d98ab7acf5f27fa89b17bd8fc0ef7683df37 (patch) | |
tree | d4d40dc8719612b86724f6df0f0850057ec3b843 /test/CodeGenCXX/arm.cpp | |
parent | 1baf2f778c26a71d1353ff2cc1701fcd1dbeaf76 (diff) |
Teach IR generation to return 'this' from constructors and destructors
under the ARM ABI.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112588 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/arm.cpp')
-rw-r--r-- | test/CodeGenCXX/arm.cpp | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index 1d4085ca23..b4c8c835e4 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s class foo { public: @@ -13,7 +13,89 @@ public: // The global dtor needs the right calling conv with -fno-use-cxa-atexit // rdar://7817590 +// Checked at end of file. bar baz; +// Destructors and constructors must return this. +namespace test1 { + void foo(); + + struct A { + A(int i) { foo(); } + ~A() { foo(); } + void bar() { foo(); } + }; + + // CHECK: define void @_ZN5test14testEv() + void test() { + // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1 + // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10) + // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]]) + // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]]) + // CHECK: ret void + A a = 10; + a.bar(); + } + + // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* + // CHECK: [[RET:%.*]] = alloca [[A]]*, align 4 + // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 + // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] + // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] + // CHECK: store [[A]]* [[THIS1]], [[A]]** [[RET]] + // CHECK: call [[A]]* @_ZN5test11AC2Ei( + // CHECK: [[THIS2:%.*]] = load [[A]]** [[RET]] + // CHECK: ret [[A]]* [[THIS2]] + + // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* + // CHECK: [[RET:%.*]] = alloca [[A]]*, align 4 + // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 + // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] + // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] + // CHECK: store [[A]]* [[THIS1]], [[A]]** [[RET]] + // CHECK: call [[A]]* @_ZN5test11AD2Ev( + // CHECK: [[THIS2:%.*]] = load [[A]]** [[RET]] + // CHECK: ret [[A]]* [[THIS2]] +} + +// Awkward virtual cases. +namespace test2 { + void foo(); + + struct A { + int x; + + A(int); + virtual ~A() { foo(); } + }; + + struct B { + int y; + int z; + + B(int); + virtual ~B() { foo(); } + }; + + struct C : A, virtual B { + int q; + + C(int i) : A(i), B(i) { foo(); } + ~C() { foo(); } + }; + + void test() { + C c = 10; + } + + // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev( + // CHECK: call [[C]]* @_ZN5test21CD1Ev( + // CHECK: ret [[C]]* undef + + // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev( + // CHECK: call void @_ZN5test21CD0Ev( + // CHECK: ret void +} + // CHECK: @_GLOBAL__D_a() -// CHECK: call void @_ZN3barD1Ev(%class.bar* @baz) +// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz) |