101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
318fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregortemplate<typename T> void capture(const T&);
418fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor
501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregorclass NonCopyable {
601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}}
74773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregorpublic:
84773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  void foo() const;
901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor};
1001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
1187c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregorclass NonConstCopy {
1287c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregorpublic:
1387c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregor  NonConstCopy(NonConstCopy&); // expected-note{{would lose const}}
1487c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregor};
1587c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregor
1687c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregorvoid capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
174773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
184773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  (void)[=] {
194773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor    ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
204773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  }();
2187c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregor
2287c5150752baafab380e5f7837a32410fa83c7dcDouglas Gregor  [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
2301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor}
2401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
25503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregorstruct NonTrivial {
26503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  NonTrivial();
27503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  NonTrivial(const NonTrivial &);
28503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  ~NonTrivial();
29503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor};
30503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
31503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregorstruct CopyCtorDefault {
3218fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor  CopyCtorDefault();
33503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  CopyCtorDefault(const CopyCtorDefault&, NonTrivial nt = NonTrivial());
34503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
35503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  void foo() const;
36503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor};
37503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
38503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregorvoid capture_with_default_args(CopyCtorDefault cct) {
39b326ca8ffbea96f9cc8a457b0f57be880304a6f5Douglas Gregor  (void)[=] () -> void { cct.foo(); };
40503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor}
41503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
4218fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregorstruct ExpectedArrayLayout {
4318fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor  CopyCtorDefault array[3];
4418fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor};
4518fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor
4618fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregorvoid capture_array() {
4718fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor  CopyCtorDefault array[3];
48b326ca8ffbea96f9cc8a457b0f57be880304a6f5Douglas Gregor  auto x = [=]() -> void {
4918fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor    capture(array[0]);
5018fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor  };
5118fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor  static_assert(sizeof(x) == sizeof(ExpectedArrayLayout), "layout mismatch");
5218fe084d72392a5ceaa1fab7d3f3f0d0f2538069Douglas Gregor}
5320f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor
5420f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor// Check for the expected non-static data members.
5520f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor
5620f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregorstruct ExpectedLayout {
5720f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor  char a;
5820f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor  short b;
5920f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor};
6020f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor
6120f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregorvoid test_layout(char a, short b) {
62b326ca8ffbea96f9cc8a457b0f57be880304a6f5Douglas Gregor  auto x = [=] () -> void {
6320f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor    capture(a);
6420f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor    capture(b);
6520f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor  };
6620f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor  static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!");
6720f87a4cd91b8d76571dc96aece916ac0bdf8b9fDouglas Gregor}
68668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman
69668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedmanstruct ExpectedThisLayout {
70668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman  ExpectedThisLayout* a;
71668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman  void f() {
72668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman    auto x = [this]() -> void {};
73668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman    static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!");
74668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman  }
75668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman};
76c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
77c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregorstruct CaptureArrayAndThis {
78c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  int value;
79c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
80c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  void f() {
81c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor    int array[3];
82c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor    [=]() -> int {
83c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor      int result = value;
84c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor      for (unsigned i = 0; i < 3; ++i)
85c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor        result += array[i];
86c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor      return result;
87c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor    }();
88c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  }
89c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor};
90c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
91