1 // RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s 2 3 struct S { 4 S(); 5 S(S &&); 6 ~S(); 7 }; 8 9 void f() { 10 (void) [s(S{})] {}; 11 } 12 13 // CHECK-LABEL: define void @_Z1fv( 14 // CHECK: call void @_ZN1SC1Ev( 15 // CHECK: call void @"_ZZ1fvEN3$_0D1Ev"( 16 17 // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D1Ev"( 18 // CHECK: @"_ZZ1fvEN3$_0D2Ev"( 19 20 // D2 at end of file. 21 22 void g() { 23 [a(1), b(2)] { return a + b; } (); 24 } 25 26 // CHECK-LABEL: define void @_Z1gv( 27 // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0 28 // CHECK: store i32 1, i32* 29 // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1 30 // CHECK: store i32 2, i32* 31 // CHECK: call i32 @"_ZZ1gvENK3$_1clEv"( 32 33 // CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_1clEv"( 34 // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0 35 // CHECK: load i32, i32* 36 // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1 37 // CHECK: load i32, i32* 38 39 // CHECK: add nsw i32 40 41 // CHECK-LABEL: define void @_Z18init_capture_dtorsv 42 void init_capture_dtors() { 43 // Ensure that init-captures are not treated as separate full-expressions. 44 struct HasDtor { ~HasDtor() {} }; 45 void some_function_call(); 46 void other_function_call(); 47 // CHECK: call {{.*}}some_function_call 48 // CHECK: call {{.*}}HasDtorD 49 ([x = (HasDtor(), 0)]{}, some_function_call()); 50 // CHECK: call {{.*}}other_function_call 51 other_function_call(); 52 } 53 54 int h(int a) { 55 // CHECK-LABEL: define i32 @_Z1hi( 56 // CHECK: %[[A_ADDR:.*]] = alloca i32, 57 // CHECK: %[[OUTER:.*]] = alloca 58 // CHECK: store i32 {{.*}}, i32* %[[A_ADDR]], 59 // 60 // Initialize init-capture 'b(a)' by reference. 61 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 62 // CHECK: store i32* %[[A_ADDR]], i32** {{.*}}, 63 // 64 // Initialize init-capture 'c(a)' by copy. 65 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 66 // CHECK: load i32, i32* %[[A_ADDR]], 67 // CHECK: store i32 68 // 69 // CHECK: call i32 @"_ZZ1hiENK3$_2clEv"({{.*}}* %[[OUTER]]) 70 return [&b(a), c(a)] { 71 // CHECK-LABEL: define internal i32 @"_ZZ1hiENK3$_2clEv"( 72 // CHECK: %[[OUTER_ADDR:.*]] = alloca 73 // CHECK: %[[INNER:.*]] = alloca 74 // CHECK: store {{.*}}, {{.*}}** %[[OUTER_ADDR]], 75 // 76 // Capture outer 'c' by reference. 77 // CHECK: %[[OUTER:.*]] = load {{.*}}*, {{.*}}** %[[OUTER_ADDR]] 78 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 79 // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 80 // CHECK-NEXT: store i32* % 81 // 82 // Capture outer 'b' by copy. 83 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 84 // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 85 // CHECK-NEXT: load i32*, i32** % 86 // CHECK-NEXT: load i32, i32* % 87 // CHECK-NEXT: store i32 88 // 89 // CHECK: call i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"({{.*}}* %[[INNER]]) 90 return [=, &c] { 91 // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"( 92 // CHECK: call void @_ZN1SD1Ev( 93 94 // CHECK-LABEL: define internal i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"( 95 // CHECK: %[[INNER_ADDR:.*]] = alloca 96 // CHECK: store {{.*}}, {{.*}}** %[[INNER_ADDR]], 97 // CHECK: %[[INNER:.*]] = load {{.*}}*, {{.*}}** %[[INNER_ADDR]] 98 // 99 // Load capture of 'b' 100 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 101 // CHECK: load i32, i32* % 102 // 103 // Load capture of 'c' 104 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 105 // CHECK: load i32*, i32** % 106 // CHECK: load i32, i32* % 107 // 108 // CHECK: add nsw i32 109 return b + c; 110 } (); 111 } (); 112 } 113 114 // Ensure we can emit code for init-captures in global lambdas too. 115 auto global_lambda = [a = 0] () mutable { return ++a; }; 116 int get_incremented() { return global_lambda(); } 117