Home | History | Annotate | Download | only in CodeGenCXX
      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 int 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.
    102 auto global_lambda = [a = 0] () mutable { return ++a; };
    103 int get_incremented() { return global_lambda(); }
    104