summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenObjCXX/lambda-expressions.mm
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-03-01 04:01:32 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-03-01 04:01:32 +0000
commit98b01edc8cf20eb305f4cb1d5dde431518e19264 (patch)
treefeeeb02d1ee51891c9c395cbeba519173d7ddf9a /clang/test/CodeGenObjCXX/lambda-expressions.mm
parentf9196a259c72ae841bfa1ad51b4327482944845c (diff)
downloadbcm5719-llvm-98b01edc8cf20eb305f4cb1d5dde431518e19264.tar.gz
bcm5719-llvm-98b01edc8cf20eb305f4cb1d5dde431518e19264.zip
Implement "optimization" for lambda-to-block conversion which inlines the generated block literal for lambdas which are immediately converted to block pointer type. This simplifies the AST, avoids an unnecessary copy of the lambda and makes it much easier to avoid copying the result onto the heap.
Note that this transformation has a substantial semantic effect outside of ARC: it gives the converted lambda lifetime semantics similar to a block literal. With ARC, the effect is much less obvious because the lifetime of blocks is already managed. llvm-svn: 151797
Diffstat (limited to 'clang/test/CodeGenObjCXX/lambda-expressions.mm')
-rw-r--r--clang/test/CodeGenObjCXX/lambda-expressions.mm19
1 files changed, 19 insertions, 0 deletions
diff --git a/clang/test/CodeGenObjCXX/lambda-expressions.mm b/clang/test/CodeGenObjCXX/lambda-expressions.mm
index c55699a2319..36a1996ee87 100644
--- a/clang/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/clang/test/CodeGenObjCXX/lambda-expressions.mm
@@ -4,6 +4,7 @@
typedef int (^fp)();
fp f() { auto x = []{ return 3; }; return x; }
+// MRC: define i32 ()* @_Z1fv(
// MRC: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
// MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
// MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke_0" to i8*)
@@ -11,8 +12,26 @@ fp f() { auto x = []{ return 3; }; return x; }
// MRC: call i32 ()* (i8*, i8*)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
// MRC: ret i32 ()*
+// ARC: define i32 ()* @_Z1fv(
// ARC: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
// ARC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
// ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke_0" to i8*)
// ARC: call i8* @objc_retainBlock
// ARC: call i8* @objc_autoreleaseReturnValue
+
+typedef int (^fp)();
+fp global;
+void f2() { global = []{ return 3; }; }
+
+// MRC: define void @_Z2f2v() nounwind {
+// MRC: store i8* bitcast (i32 (i8*)* @__f2_block_invoke_0 to i8*),
+// MRC-NOT: call
+// MRC: ret void
+// ("global" contains a dangling pointer after this function runs.)
+
+// ARC: define void @_Z2f2v() nounwind {
+// ARC: store i8* bitcast (i32 (i8*)* @__f2_block_invoke_0 to i8*),
+// ARC: call i8* @objc_retainBlock
+// ARC: call void @objc_release
+// ARC: define internal i32 @__f2_block_invoke_0
+// ARC: call i32 @"_ZZ2f2vENK3$_1clEv
OpenPOWER on IntegriCloud