1// RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
2
3namespace variadic_expansion {
4  int f(int &, char &) { return 0; }
5  template<class ... Ts> char fv(Ts ... ts) { return 0; }
6  // FIXME: why do we get 2 error messages
7  template <typename ... T> void g(T &... t) { //expected-note3{{declared here}}
8    f([&a(t)]()->decltype(auto) {
9      return a;
10    }() ...);
11
12    auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
13    const int y = 10;
14    auto M = [x = y,
15                &z = y](T& ... t) { };
16    auto N = [x = y,
17                &z = y, n = f(t...),
18                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) {
19                  fv([&a(t)]()->decltype(auto) {
20                    return a;
21                  }() ...);
22                };
23    auto N2 = [x = y,                     //expected-note3{{begins here}}
24                &z = y, n = f(t...),
25                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) {
26                  fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
27                    return a;
28                  }() ...);
29                };
30
31  }
32
33  void h(int i, char c) { g(i, c); } //expected-note{{in instantiation}}
34}
35
36namespace odr_use_within_init_capture {
37
38int test() {
39
40  { // no captures
41    const int x = 10;
42    auto L = [z = x + 2](int a) {
43      auto M = [y = x - 2](char b) {
44        return y;
45      };
46      return M;
47    };
48
49  }
50  { // should not capture
51    const int x = 10;
52    auto L = [&z = x](int a) {
53      return a;;
54    };
55
56  }
57  {
58    const int x = 10;
59    auto L = [k = x](char a) { //expected-note {{declared}}
60      return [](int b) { //expected-note {{begins}}
61        return [j = k](int c) { //expected-error {{cannot be implicitly captured}}
62          return c;
63        };
64      };
65    };
66  }
67  {
68    const int x = 10;
69    auto L = [k = x](char a) {
70      return [=](int b) {
71        return [j = k](int c) {
72          return c;
73        };
74      };
75    };
76  }
77  {
78    const int x = 10;
79    auto L = [k = x](char a) {
80      return [k](int b) {
81        return [j = k](int c) {
82          return c;
83        };
84      };
85    };
86  }
87
88  return 0;
89}
90
91int run = test();
92
93}
94
95namespace odr_use_within_init_capture_template {
96
97template<class T = int>
98int test(T t = T{}) {
99
100  { // no captures
101    const T x = 10;
102    auto L = [z = x](char a) {
103      auto M = [y = x](T b) {
104        return y;
105      };
106      return M;
107    };
108
109  }
110  { // should not capture
111    const T x = 10;
112    auto L = [&z = x](T a) {
113      return a;;
114    };
115
116  }
117  { // will need to capture x in outer lambda
118    const T x = 10; //expected-note {{declared}}
119    auto L = [z = x](char a) { //expected-note {{begins}}
120      auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}}
121        return y;
122      };
123      return M;
124    };
125
126  }
127  { // will need to capture x in outer lambda
128    const T x = 10;
129    auto L = [=,z = x](char a) {
130      auto M = [&y = x](T b) {
131        return y;
132      };
133      return M;
134    };
135
136  }
137  { // will need to capture x in outer lambda
138    const T x = 10;
139    auto L = [x, z = x](char a) {
140      auto M = [&y = x](T b) {
141        return y;
142      };
143      return M;
144    };
145  }
146  { // will need to capture x in outer lambda
147    const int x = 10; //expected-note 2{{declared}}
148    auto L = [z = x](char a) { //expected-note 2{{begins}}
149      auto M = [&y = x](T b) { //expected-error 2{{cannot be implicitly captured}}
150        return y;
151      };
152      return M;
153    };
154  }
155  {
156    // no captures
157    const T x = 10;
158    auto L = [z =
159                  [z = x, &y = x](char a) { return z + y; }('a')](char a)
160      { return z; };
161
162  }
163
164  return 0;
165}
166
167int run = test(); //expected-note {{instantiation}}
168
169}