Per latest drafting, switch to implementing init-captures as if by declaring
and capturing a variable declaration, and complete the implementation of them.

llvm-svn: 191605
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
index be39ded..6be200d 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
@@ -1,34 +1,26 @@
 // RUN: %clang_cc1 -std=c++1y %s -verify
 
-// For every init-capture a non-static data member named by the identifier of
-// the init-capture is declared in the closure type.
-const char *has_member_x = [x("hello")] {}.x;
-// This member is not a bit-field...
-auto capturing_lambda = [n(0)] {};
-int decltype(capturing_lambda)::*mem_ptr = &decltype(capturing_lambda)::n;
-// ... and not mutable.
-const auto capturing_lambda_copy = capturing_lambda;
-int &n = capturing_lambda_copy.n; // expected-error {{drops qualifiers}}
+const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
 
-// The type of that member [...is that of a...] variable declaration of the form
-// "auto init-capture ;"...
-auto with_float = [f(1.0f)] {};
-float &f = with_float.f;
-// ... except that the variable name is replaced by a unique identifier.
-auto with_float_2 = [&f(f)] {}; // ok, refers to outer f
-float &f2 = with_float_2.f;
+double f;
+auto with_float = [f(1.0f)] {
+  using T = decltype(f);
+  using T = float;
+};
+auto with_float_2 = [&f(f)] { // ok, refers to outer f
+  using T = decltype(f);
+  using T = double&;
+};
 
-// Within the lambda-expression's lambda-declarator (FIXME) and
-// compound-statement, the identifier in the init-capture hides any declaration
+// Within the lambda-expression's compound-statement,
+// the identifier in the init-capture hides any declaration
 // of the same name in scopes enclosing the lambda-expression.
 void hiding() {
   char c;
   (void) [c("foo")] {
     static_assert(sizeof(c) == sizeof(const char*), "");
   };
-  (void) [c("bar")] () -> decltype(c) {
-    // FIXME: the 'c' in the return type should be the init-capture, not the
-    // outer c.
+  (void) [c("bar")] () -> decltype(c) { // outer c, not init-capture
     return "baz"; // expected-error {{cannot initialize}}
   };
 }
@@ -54,22 +46,16 @@
 auto bad_init_1 = [a()] {}; // expected-error {{expected expression}}
 auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}}
 auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}}
-auto bad_init_4 = [a(void_fn())] {}; // expected-error {{field has incomplete type 'void'}}
+auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}}
 auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}}
 auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}}
 
-template<typename...T> void pack_1(T...t) { [a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
+template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
 template void pack_1<>(); // expected-note {{instantiation of}}
 
-auto multi_return(int a, int b) {
-  return [n(a + 2*b), m(a - 2*b)] {};
-}
-auto use_multi_return() {
-  auto nm = multi_return(5, 9);
-  return nm.n + nm.m;
-}
-
-auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] { // expected-warning {{binding reference member 'c' to a temporary value}} expected-note {{here}}
+// FIXME: Might need lifetime extension for the temporary here.
+// See DR1695.
+auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] {
   static_assert(sizeof(a) == sizeof(int), "");
   static_assert(sizeof(b) == sizeof(int), "");
   using T = decltype(c);
@@ -82,3 +68,10 @@
 template<typename T> struct remove_reference<T&> { typedef T type; };
 template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); }
 auto s = [s(move(S()))] {};
+
+template<typename T> T instantiate_test(T t) {
+  [x(&t)]() { *x = 1; } (); // expected-error {{assigning to 'const char *'}}
+  return t;
+}
+int instantiate_test_1 = instantiate_test(0);
+const char *instantiate_test_2 = instantiate_test("foo"); // expected-note {{here}}
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
index 174ae6d..083ca1b 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
@@ -66,7 +66,7 @@
 
 template<typename ...Args>
 void init_capture_pack_multi(Args ...args) {
-  [as(args...)] {} (); // expected-error {{initializer missing}} expected-error {{multiple}}
+  [as(args...)] {} (); // expected-error {{initializer missing for lambda capture 'as'}} expected-error {{multiple}}
 }
 template void init_capture_pack_multi(); // expected-note {{instantiation}}
 template void init_capture_pack_multi(int);