lambda-expressions.mm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -fblocks -fobjc-arc -fobjc-runtime-has-weak -DWEAK_SUPPORTED | FileCheck -check-prefix=ARC %s
  2. // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -fblocks | FileCheck -check-prefix=MRC %s
  3. typedef int (^fp)();
  4. fp f() { auto x = []{ return 3; }; return x; }
  5. // ARC: %[[LAMBDACLASS:.*]] = type { i32 }
  6. // MRC: @OBJC_METH_VAR_NAME{{.*}} = private unnamed_addr constant [5 x i8] c"copy\00"
  7. // MRC: @OBJC_METH_VAR_NAME{{.*}} = private unnamed_addr constant [12 x i8] c"autorelease\00"
  8. // MRC-LABEL: define i32 ()* @_Z1fv(
  9. // MRC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
  10. // MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
  11. // MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
  12. // MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
  13. // MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
  14. // MRC: ret i32 ()*
  15. // ARC-LABEL: define i32 ()* @_Z1fv(
  16. // ARC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
  17. // ARC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
  18. // ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
  19. // ARC: call i8* @objc_retainBlock
  20. // ARC: call i8* @objc_autoreleaseReturnValue
  21. typedef int (^fp)();
  22. fp global;
  23. void f2() { global = []{ return 3; }; }
  24. // MRC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
  25. // MRC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
  26. // MRC-NOT: call
  27. // MRC: ret void
  28. // ("global" contains a dangling pointer after this function runs.)
  29. // ARC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
  30. // ARC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
  31. // ARC: call i8* @objc_retainBlock
  32. // ARC: call void @objc_release
  33. // ARC-LABEL: define internal i32 @___Z2f2v_block_invoke
  34. // ARC: call i32 @"_ZZ2f2vENK3$_1clEv
  35. template <class T> void take_lambda(T &&lambda) { lambda(); }
  36. void take_block(void (^block)()) { block(); }
  37. // rdar://13800041
  38. @interface A
  39. - (void) test;
  40. @end
  41. @interface B : A @end
  42. @implementation B
  43. - (void) test {
  44. take_block(^{
  45. take_lambda([=]{
  46. take_block(^{
  47. take_lambda([=] {
  48. [super test];
  49. });
  50. });
  51. });
  52. });
  53. }
  54. @end
  55. // ARC: define void @_ZN13LambdaCapture4foo1ERi(i32* dereferenceable(4) %{{.*}})
  56. // ARC: %[[CAPTURE0:.*]] = getelementptr inbounds %[[LAMBDACLASS]], %[[LAMBDACLASS]]* %{{.*}}, i32 0, i32 0
  57. // ARC: store i32 %{{.*}}, i32* %[[CAPTURE0]]
  58. // ARC: define internal void @"_ZZN13LambdaCapture4foo1ERiENK3$_3clEv"(%[[LAMBDACLASS]]* %{{.*}})
  59. // ARC: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>
  60. // ARC: %[[CAPTURE1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5
  61. // ARC: store i32 %{{.*}}, i32* %[[CAPTURE1]]
  62. // ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"(
  63. // ARC-NOT: @objc_storeStrong(
  64. // ARC: ret void
  65. // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke"
  66. // ARC: %[[CAPTURE2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5
  67. // ARC: store i32 %{{.*}}, i32* %[[CAPTURE2]]
  68. // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke_2"(i8* %{{.*}})
  69. // ARC: %[[CAPTURE3:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5
  70. // ARC: %[[V1:.*]] = load i32, i32* %[[CAPTURE3]]
  71. // ARC: store i32 %[[V1]], i32* @_ZN13LambdaCapture1iE
  72. namespace LambdaCapture {
  73. int i;
  74. void foo1(int &a) {
  75. auto lambda = [a]{
  76. auto block1 = ^{
  77. auto block2 = ^{
  78. i = a;
  79. };
  80. block2();
  81. };
  82. block1();
  83. };
  84. lambda();
  85. }
  86. }
  87. // ARC-LABEL: define linkonce_odr i32 ()* @_ZZNK13StaticMembersIfE1fMUlvE_clEvENKUlvE_cvU13block_pointerFivEEv
  88. // Check lines for BlockInLambda test below
  89. // ARC-LABEL: define internal i32 @___ZZN13BlockInLambda1X1fEvENKUlvE_clEv_block_invoke
  90. // ARC: [[Y:%.*]] = getelementptr inbounds %"struct.BlockInLambda::X", %"struct.BlockInLambda::X"* {{.*}}, i32 0, i32 1
  91. // ARC-NEXT: [[YVAL:%.*]] = load i32, i32* [[Y]], align 4
  92. // ARC-NEXT: ret i32 [[YVAL]]
  93. typedef int (^fptr)();
  94. template<typename T> struct StaticMembers {
  95. static fptr f;
  96. };
  97. template<typename T>
  98. fptr StaticMembers<T>::f = [] { auto f = []{return 5;}; return fptr(f); }();
  99. template fptr StaticMembers<float>::f;
  100. namespace BlockInLambda {
  101. struct X {
  102. int x,y;
  103. void f() {
  104. [this]{return ^{return y;}();}();
  105. };
  106. };
  107. void g(X& x) {
  108. x.f();
  109. };
  110. }
  111. @interface NSObject @end
  112. @interface Foo : NSObject @end
  113. @implementation Foo
  114. - (void)foo {
  115. [&] {
  116. ^{ (void)self; }();
  117. }();
  118. }
  119. @end
  120. // Check that the delegating invoke function doesn't destruct the Weak object
  121. // that is passed.
  122. // ARC-LABEL: define internal void @"_ZZN14LambdaDelegate4testEvEN3$_58__invokeENS_4WeakE"(
  123. // ARC: call void @"_ZZN14LambdaDelegate4testEvENK3$_5clENS_4WeakE"(
  124. // ARC-NEXT: ret void
  125. // ARC-LABEL: define internal void @"_ZZN14LambdaDelegate4testEvENK3$_5clENS_4WeakE"(
  126. // ARC: call void @_ZN14LambdaDelegate4WeakD1Ev(
  127. #ifdef WEAK_SUPPORTED
  128. namespace LambdaDelegate {
  129. struct Weak {
  130. __weak id x;
  131. };
  132. void test() {
  133. void (*p)(Weak) = [](Weak a) { };
  134. }
  135. };
  136. #endif
  137. // ARC: attributes [[NUW]] = { noinline nounwind{{.*}} }
  138. // MRC: attributes [[NUW]] = { noinline nounwind{{.*}} }