1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t
2524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
3524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
4524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3
5524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-4
60b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-5
70b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-6
8678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
9524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
10524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirstruct Foo {
11524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  int x;
12524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  float y;
13524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  ~Foo() {}
14524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir};
15524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
16524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirstruct TestClass {
17524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  int x;
18524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
19524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  TestClass() : x(0) {};
20524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  void MemberFunc() {
21524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    Foo f;
22524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    #pragma clang __debug captured
23524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    {
24524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir      f.y = x;
25524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    }
26524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  }
27524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir};
28524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
29524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirvoid test1() {
30524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  TestClass c;
31524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  c.MemberFunc();
32524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.Foo*, %struct.TestClass* }
33524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
34524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
35524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1:   alloca %struct.anon
363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-1:   getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
37524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1:   store %struct.Foo* %f, %struct.Foo**
383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-1:   getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
39524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1:   call void @[[HelperName:[A-Za-z0-9_]+]](%[[Capture]]*
40cadfe42de2dccb4ab3c48fb127068ac2d35190d8Ben Langmuir  // CHECK-1:   call {{.*}}FooD1Ev
41524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-1:   ret
42524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir}
43524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
44524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir// CHECK-1: define internal void @[[HelperName]]
453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK-1:   getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK-1:   getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK-1:   getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
48524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
49524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirvoid test2(int x) {
50524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  int y = [&]() {
51524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    #pragma clang __debug captured
52524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    {
53524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir      x++;
54524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    }
55524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    return x;
56524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  }();
57524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
5893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-2-LABEL: define void @_Z5test2i
5952a4693e1e3943465f52e702e1731340052d5f46Ben Langmuir  // CHECK-2:   call {{.*}} @[[Lambda:["$\w]+]]
60524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  //
6152a4693e1e3943465f52e702e1731340052d5f46Ben Langmuir  // CHECK-2: define internal {{.*}} @[[Lambda]]
62524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-2:   call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
63524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  //
64524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-2: define internal void @[[HelperName]]
653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-2:   getelementptr inbounds %[[Capture]], %[[Capture]]*
663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-2:   load i32*, i32**
673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-2:   load i32, i32*
68524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir}
69524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
70524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirvoid test3(int x) {
71524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  #pragma clang __debug captured
72524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  {
73524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    x = [=]() { return x + 1; } ();
74524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  }
75524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
76524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
77524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
7893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-3-LABEL: define void @_Z5test3i
79524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-3:   store i32*
80524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-3:   call void @{{.*}}__captured_stmt
81524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-3:   ret void
82524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir}
83524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir
84524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuirvoid test4() {
85524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  #pragma clang __debug captured
86524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  {
87524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    Foo f;
88524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir    f.x = 5;
89524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  }
9093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-4-LABEL: define void @_Z5test4v
91524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-4:   call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
92524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-4:   ret void
93524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  //
94524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-4: define internal void @[[HelperName]]
95524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  // CHECK-4:   store i32 5, i32*
96cadfe42de2dccb4ab3c48fb127068ac2d35190d8Ben Langmuir  // CHECK-4:   call {{.*}}FooD1Ev
97524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir}
980b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
990b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pantemplate <typename T, int id>
1000b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panvoid touch(const T &) {}
1010b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1020b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pantemplate <typename T, unsigned id>
1030b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panvoid template_capture_var() {
1040b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  T x;
1050b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  #pragma clang __debug captured
1060b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  {
1070b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    touch<T, id>(x);
1080b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  }
1090b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan}
1100b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1110b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pantemplate <typename T, int id>
1120b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panclass Val {
1130b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  T v;
1140b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panpublic:
1150b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  void set() {
1160b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    #pragma clang __debug captured
1170b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    {
1180b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan      touch<T, id>(v);
1190b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    }
1200b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  }
1210b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1220b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  template <typename U, int id2>
1230b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  void foo(U u) {
1240b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    #pragma clang __debug captured
1250b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    {
1260b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan      touch<U, id + id2>(u);
1270b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    }
1280b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  }
1290b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan};
1300b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1310b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panvoid test_capture_var() {
1320b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
1330b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NOT: }
1340b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: store i32*
1350b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: call void @__captured_stmt
1360b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NEXT: ret void
1370b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  template_capture_var<int, 201>();
1380b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1390b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
1400b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NOT: }
1410b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: store %class.Val*
1420b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: call void @__captured_stmt
1430b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NEXT: ret void
1440b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  Val<float, 202> Obj;
1450b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  Obj.set();
1460b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1470b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
1480b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NOT: }
1490b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: store %class.Val*
1500b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: store double
1510b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5: call void @__captured_stmt
1520b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-5-NEXT: ret void
1530b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  Obj.foo<double, 203>(1.0);
1540b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan}
1550b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1560b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pantemplate <typename T>
1570b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panvoid template_capture_lambda() {
1580b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  T x, y;
1590b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  [=, &y]() {
1600b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    #pragma clang __debug captured
1610b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    {
1620b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan      y += x;
1630b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan    }
1640b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  }();
1650b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan}
1660b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan
1670b6d8469aa202d79e5eca116e2598a0673253ce2Wei Panvoid test_capture_lambda() {
1688443188a8f9cbd27612b7058cdcfc53356f024a3Eli Friedman  // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
1690b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-6-NOT: }
1700b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-6: store i32*
1710b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-6: store i32*
1720b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-6: call void @__captured_stmt
1730b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  // CHECK-6-NEXT: ret void
1740b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan  template_capture_lambda<int>();
1750b6d8469aa202d79e5eca116e2598a0673253ce2Wei Pan}
176678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman
177678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedmaninline int test_captured_linkage() {
1788443188a8f9cbd27612b7058cdcfc53356f024a3Eli Friedman  // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr global i32 0
179678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  int j;
180678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  #pragma clang __debug captured
181678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  {
182678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman    static int i = 0;
183678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman    j = ++i;
184678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  }
185678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  return j;
186678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman}
187678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedmanvoid call_test_captured_linkage() {
188678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman  test_captured_linkage();
189678eca456bc62900dc7407bdbc9fa282da9d2f8fEli Friedman}
190