1// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
2
3template<typename T> void capture(const T&);
4
5class NonCopyable {
6  NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}}
7public:
8  void foo() const;
9};
10
11class NonConstCopy {
12public:
13  NonConstCopy(NonConstCopy&); // expected-note{{would lose const}}
14};
15
16void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
17  (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
18  (void)[=] {
19    ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
20  }();
21
22  [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
23}
24
25struct NonTrivial {
26  NonTrivial();
27  NonTrivial(const NonTrivial &);
28  ~NonTrivial();
29};
30
31struct CopyCtorDefault {
32  CopyCtorDefault();
33  CopyCtorDefault(const CopyCtorDefault&, NonTrivial nt = NonTrivial());
34
35  void foo() const;
36};
37
38void capture_with_default_args(CopyCtorDefault cct) {
39  (void)[=] () -> void { cct.foo(); };
40}
41
42struct ExpectedArrayLayout {
43  CopyCtorDefault array[3];
44};
45
46void capture_array() {
47  CopyCtorDefault array[3];
48  auto x = [=]() -> void {
49    capture(array[0]);
50  };
51  static_assert(sizeof(x) == sizeof(ExpectedArrayLayout), "layout mismatch");
52}
53
54// Check for the expected non-static data members.
55
56struct ExpectedLayout {
57  char a;
58  short b;
59};
60
61void test_layout(char a, short b) {
62  auto x = [=] () -> void {
63    capture(a);
64    capture(b);
65  };
66  static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!");
67}
68
69struct ExpectedThisLayout {
70  ExpectedThisLayout* a;
71  void f() {
72    auto x = [this]() -> void {};
73    static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!");
74  }
75};
76
77struct CaptureArrayAndThis {
78  int value;
79
80  void f() {
81    int array[3];
82    [=]() -> int {
83      int result = value;
84      for (unsigned i = 0; i < 3; ++i)
85        result += array[i];
86      return result;
87    }();
88  }
89};
90
91namespace rdar14468891 {
92  class X {
93  public:
94    virtual ~X() = 0; // expected-note{{unimplemented pure virtual method '~X' in 'X'}}
95  };
96
97  class Y : public X { };
98
99  void capture(X &x) {
100    [x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}}
101  }
102}
103
104namespace rdar15560464 {
105  struct X; // expected-note{{forward declaration of 'rdar15560464::X'}}
106  void foo(const X& param) {
107    auto x = ([=]() {
108        auto& y = param; // expected-error{{by-copy capture of variable 'param' with incomplete type 'const rdar15560464::X'}}
109      });
110  }
111}
112