diff options
| author | John McCall <rjmccall@apple.com> | 2011-02-08 03:07:00 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-02-08 03:07:00 +0000 |
| commit | b0a3ecb41c296454868fe9c8968a7649212b2818 (patch) | |
| tree | 013df0e84005bd0df6acc05a2f8d65c7ca9757c2 /clang/test/CodeGenCXX/blocks.cpp | |
| parent | 7012049c7fd4d6b04b21a98dad6498b88e30182b (diff) | |
| download | bcm5719-llvm-b0a3ecb41c296454868fe9c8968a7649212b2818.tar.gz bcm5719-llvm-b0a3ecb41c296454868fe9c8968a7649212b2818.zip | |
Extend the const capture optimization to C++ record types with no
mutable fields and with trivial destructors and copy constructors.
llvm-svn: 125073
Diffstat (limited to 'clang/test/CodeGenCXX/blocks.cpp')
| -rw-r--r-- | clang/test/CodeGenCXX/blocks.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/blocks.cpp b/clang/test/CodeGenCXX/blocks.cpp index 568f9b1e4b5..ea174b57e44 100644 --- a/clang/test/CodeGenCXX/blocks.cpp +++ b/clang/test/CodeGenCXX/blocks.cpp @@ -8,3 +8,50 @@ namespace test0 { ^{ ^{ (void) x; }; }; } } + +extern void (^out)(); + +namespace test1 { + // Capturing const objects doesn't require a local block. + // CHECK: define void @_ZN5test15test1Ev() + // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out + void test1() { + const int NumHorsemen = 4; + out = ^{ (void) NumHorsemen; }; + } + + // That applies to structs too... + // CHECK: define void @_ZN5test15test2Ev() + // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out + struct loc { double x, y; }; + void test2() { + const loc target = { 5, 6 }; + out = ^{ (void) target; }; + } + + // ...unless they have mutable fields... + // CHECK: define void @_ZN5test15test3Ev() + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]], + // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* + // CHECK: store void ()* [[T0]], void ()** @out + struct mut { mutable int x; }; + void test3() { + const mut obj = { 5 }; + out = ^{ (void) obj; }; + } + + // ...or non-trivial destructors... + // CHECK: define void @_ZN5test15test4Ev() + // CHECK: [[OBJ:%.*]] = alloca + // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]], + // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* + // CHECK: store void ()* [[T0]], void ()** @out + struct scope { int x; ~scope(); }; + void test4() { + const scope obj = { 5 }; + out = ^{ (void) obj; }; + } + + // ...or non-trivial copy constructors, but it's not clear how to do + // that and still have a constant initializer in '03. +} |

