1// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s 2 3struct S { 4 S(); 5 S(S &&); 6 ~S(); 7}; 8 9void 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 22void 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 41int h(int a) { 42 // CHECK-LABEL: define i32 @_Z1hi( 43 // CHECK: %[[A_ADDR:.*]] = alloca i32, 44 // CHECK: %[[OUTER:.*]] = alloca 45 // CHECK: store i32 {{.*}}, i32* %[[A_ADDR]], 46 // 47 // Initialize init-capture 'b(a)' by reference. 48 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 49 // CHECK: store i32* %[[A_ADDR]], i32** {{.*}}, 50 // 51 // Initialize init-capture 'c(a)' by copy. 52 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 53 // CHECK: load i32, i32* %[[A_ADDR]], 54 // CHECK: store i32 55 // 56 // CHECK: call i32 @"_ZZ1hiENK3$_2clEv"({{.*}}* %[[OUTER]]) 57 return [&b(a), c(a)] { 58 // CHECK-LABEL: define internal i32 @"_ZZ1hiENK3$_2clEv"( 59 // CHECK: %[[OUTER_ADDR:.*]] = alloca 60 // CHECK: %[[INNER:.*]] = alloca 61 // CHECK: store {{.*}}, {{.*}}** %[[OUTER_ADDR]], 62 // 63 // Capture outer 'c' by reference. 64 // CHECK: %[[OUTER:.*]] = load {{.*}}*, {{.*}}** %[[OUTER_ADDR]] 65 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 66 // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 67 // CHECK-NEXT: store i32* % 68 // 69 // Capture outer 'b' by copy. 70 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 71 // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 72 // CHECK-NEXT: load i32*, i32** % 73 // CHECK-NEXT: load i32, i32* % 74 // CHECK-NEXT: store i32 75 // 76 // CHECK: call i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"({{.*}}* %[[INNER]]) 77 return [=, &c] { 78 // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"( 79 // CHECK: call void @_ZN1SD1Ev( 80 81 // CHECK-LABEL: define internal i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"( 82 // CHECK: %[[INNER_ADDR:.*]] = alloca 83 // CHECK: store {{.*}}, {{.*}}** %[[INNER_ADDR]], 84 // CHECK: %[[INNER:.*]] = load {{.*}}*, {{.*}}** %[[INNER_ADDR]] 85 // 86 // Load capture of 'b' 87 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 88 // CHECK: load i32, i32* % 89 // 90 // Load capture of 'c' 91 // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 92 // CHECK: load i32*, i32** % 93 // CHECK: load i32, i32* % 94 // 95 // CHECK: add nsw i32 96 return b + c; 97 } (); 98 } (); 99} 100 101// Ensure we can emit code for init-captures in global lambdas too. 102auto global_lambda = [a = 0] () mutable { return ++a; }; 103int get_incremented() { return global_lambda(); } 104