1e31e606fSDouglas Gregor // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
2e31e606fSDouglas Gregor
3199cec76SDouglas Gregor template<typename T> void capture(const T&);
4199cec76SDouglas Gregor
5e31e606fSDouglas Gregor class NonCopyable {
6e31e606fSDouglas Gregor NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}}
719666fb1SDouglas Gregor public:
819666fb1SDouglas Gregor void foo() const;
9e31e606fSDouglas Gregor };
10e31e606fSDouglas Gregor
1102267a8eSDouglas Gregor class NonConstCopy {
1202267a8eSDouglas Gregor public:
1302267a8eSDouglas Gregor NonConstCopy(NonConstCopy&); // expected-note{{would lose const}}
1402267a8eSDouglas Gregor };
1502267a8eSDouglas Gregor
capture_by_copy(NonCopyable nc,NonCopyable & ncr,const NonConstCopy nco)1602267a8eSDouglas Gregor void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
1719666fb1SDouglas Gregor (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
1835d303adSVedant Kumar (void)[=] { // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
1935d303adSVedant Kumar ncr.foo();
2019666fb1SDouglas Gregor }();
2102267a8eSDouglas Gregor
2202267a8eSDouglas Gregor [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
23e31e606fSDouglas Gregor }
24e31e606fSDouglas Gregor
258c50e7c5SDouglas Gregor struct NonTrivial {
268c50e7c5SDouglas Gregor NonTrivial();
278c50e7c5SDouglas Gregor NonTrivial(const NonTrivial &);
288c50e7c5SDouglas Gregor ~NonTrivial();
298c50e7c5SDouglas Gregor };
308c50e7c5SDouglas Gregor
318c50e7c5SDouglas Gregor struct CopyCtorDefault {
32199cec76SDouglas Gregor CopyCtorDefault();
338c50e7c5SDouglas Gregor CopyCtorDefault(const CopyCtorDefault&, NonTrivial nt = NonTrivial());
348c50e7c5SDouglas Gregor
358c50e7c5SDouglas Gregor void foo() const;
368c50e7c5SDouglas Gregor };
378c50e7c5SDouglas Gregor
capture_with_default_args(CopyCtorDefault cct)388c50e7c5SDouglas Gregor void capture_with_default_args(CopyCtorDefault cct) {
39656bc62aSDouglas Gregor (void)[=] () -> void { cct.foo(); };
408c50e7c5SDouglas Gregor }
418c50e7c5SDouglas Gregor
42199cec76SDouglas Gregor struct ExpectedArrayLayout {
43199cec76SDouglas Gregor CopyCtorDefault array[3];
44199cec76SDouglas Gregor };
45199cec76SDouglas Gregor
capture_array()46199cec76SDouglas Gregor void capture_array() {
47199cec76SDouglas Gregor CopyCtorDefault array[3];
48656bc62aSDouglas Gregor auto x = [=]() -> void {
49199cec76SDouglas Gregor capture(array[0]);
50199cec76SDouglas Gregor };
51199cec76SDouglas Gregor static_assert(sizeof(x) == sizeof(ExpectedArrayLayout), "layout mismatch");
52199cec76SDouglas Gregor }
533d23f788SDouglas Gregor
543d23f788SDouglas Gregor // Check for the expected non-static data members.
553d23f788SDouglas Gregor
563d23f788SDouglas Gregor struct ExpectedLayout {
573d23f788SDouglas Gregor char a;
583d23f788SDouglas Gregor short b;
593d23f788SDouglas Gregor };
603d23f788SDouglas Gregor
test_layout(char a,short b)613d23f788SDouglas Gregor void test_layout(char a, short b) {
62656bc62aSDouglas Gregor auto x = [=] () -> void {
633d23f788SDouglas Gregor capture(a);
643d23f788SDouglas Gregor capture(b);
653d23f788SDouglas Gregor };
663d23f788SDouglas Gregor static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!");
673d23f788SDouglas Gregor }
68c9751069SEli Friedman
69c9751069SEli Friedman struct ExpectedThisLayout {
70c9751069SEli Friedman ExpectedThisLayout* a;
fExpectedThisLayout71c9751069SEli Friedman void f() {
72c9751069SEli Friedman auto x = [this]() -> void {};
73c9751069SEli Friedman static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!");
74c9751069SEli Friedman }
75c9751069SEli Friedman };
76d814a05fSDouglas Gregor
77d814a05fSDouglas Gregor struct CaptureArrayAndThis {
78d814a05fSDouglas Gregor int value;
79d814a05fSDouglas Gregor
fCaptureArrayAndThis80d814a05fSDouglas Gregor void f() {
81d814a05fSDouglas Gregor int array[3];
82d814a05fSDouglas Gregor [=]() -> int {
83d814a05fSDouglas Gregor int result = value;
84d814a05fSDouglas Gregor for (unsigned i = 0; i < 3; ++i)
85d814a05fSDouglas Gregor result += array[i];
86d814a05fSDouglas Gregor return result;
87d814a05fSDouglas Gregor }();
88d814a05fSDouglas Gregor }
89d814a05fSDouglas Gregor };
90d814a05fSDouglas Gregor
9171fe0e8aSDouglas Gregor namespace rdar14468891 {
9271fe0e8aSDouglas Gregor class X {
9371fe0e8aSDouglas Gregor public:
9471fe0e8aSDouglas Gregor virtual ~X() = 0; // expected-note{{unimplemented pure virtual method '~X' in 'X'}}
9571fe0e8aSDouglas Gregor };
9671fe0e8aSDouglas Gregor
9771fe0e8aSDouglas Gregor class Y : public X { };
9871fe0e8aSDouglas Gregor
capture(X & x)9971fe0e8aSDouglas Gregor void capture(X &x) {
100*888673b6SJonas Devlieghere [x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}}
10171fe0e8aSDouglas Gregor }
10271fe0e8aSDouglas Gregor }
103d1e3ceb5SDouglas Gregor
104d1e3ceb5SDouglas Gregor namespace rdar15560464 {
105d1e3ceb5SDouglas Gregor struct X; // expected-note{{forward declaration of 'rdar15560464::X'}}
foo(const X & param)106d1e3ceb5SDouglas Gregor void foo(const X& param) {
107d1e3ceb5SDouglas Gregor auto x = ([=]() {
108*888673b6SJonas Devlieghere auto& y = param; // expected-error{{by-copy capture of variable 'param' with incomplete type 'const rdar15560464::X'}}
109d1e3ceb5SDouglas Gregor });
110d1e3ceb5SDouglas Gregor }
111d1e3ceb5SDouglas Gregor }
112