N3648: init-captures are named.
authorJason Merrill <jason@redhat.com>
Wed, 24 Apr 2013 15:03:58 +0000 (11:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 24 Apr 2013 15:03:58 +0000 (11:03 -0400)
* semantics.c (add_capture): Don't prepend "__" to init-captures.
(build_capture_proxy): Adjust.
* error.c (dump_simple_decl): Check DECL_NORMAL_CAPTURE_P.

From-SVN: r198247

gcc/cp/ChangeLog
gcc/cp/error.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp1y/lambda-init6.C [new file with mode: 0644]

index c63c9e21a194f8d428a6e8fcf49633ce405c0c8b..1c05d5dd16e75ad6e037bcf080bcf4a66378b241 100644 (file)
@@ -1,5 +1,10 @@
 2013-04-24  Jason Merrill  <jason@redhat.com>
 
+       N3648: init-captures are named.
+       * semantics.c (add_capture): Don't prepend "__" to init-captures.
+       (build_capture_proxy): Adjust.
+       * error.c (dump_simple_decl): Check DECL_NORMAL_CAPTURE_P.
+
        N3648: Allow braced and parenthesized initializers.
        * parser.c (cp_parser_lambda_introducer): Use cp_parser_initializer.
        * pt.c (tsubst) [DECLTYPE_TYPE]: Handle DECLTYPE_FOR_INIT_CAPTURE.
index 7a8c0bca3c144126057d73b31ec01629b5579a4c..4681e8420020aa3a86c7f7f0b21bcc486cb53ea6 100644 (file)
@@ -934,7 +934,7 @@ dump_simple_decl (tree t, tree type, int flags)
     pp_string (cxx_pp, "...");
   if (DECL_NAME (t))
     {
-      if (DECL_CLASS_SCOPE_P (t) && LAMBDA_TYPE_P (DECL_CONTEXT (t)))
+      if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t))
        {
          pp_character (cxx_pp, '<');
          pp_string (cxx_pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
index 4cc22597e85a231efdaaa8c1cf4d4218e35b4ebe..3566739a10ef8c2864396c7a8c1bd016975cd857 100644 (file)
@@ -9373,7 +9373,10 @@ build_capture_proxy (tree member)
     object = TREE_OPERAND (object, 0);
 
   /* Remove the __ inserted by add_capture.  */
-  name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
+  if (DECL_NORMAL_CAPTURE_P (member))
+    name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
+  else
+    name = DECL_NAME (member);
 
   type = lambda_proxy_type (object);
   var = build_decl (input_location, VAR_DECL, name, type);
@@ -9426,11 +9429,17 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
      won't find the field with name lookup.  We can't just leave the name
      unset because template instantiation uses the name to find
      instantiated fields.  */
-  buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3);
-  buf[1] = buf[0] = '_';
-  memcpy (buf + 2, IDENTIFIER_POINTER (id),
-         IDENTIFIER_LENGTH (id) + 1);
-  name = get_identifier (buf);
+  if (!explicit_init_p)
+    {
+      buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3);
+      buf[1] = buf[0] = '_';
+      memcpy (buf + 2, IDENTIFIER_POINTER (id),
+             IDENTIFIER_LENGTH (id) + 1);
+      name = get_identifier (buf);
+    }
+  else
+    /* But captures with explicit initializers are named.  */
+    name = id;
 
   /* If TREE_TYPE isn't set, we're still in the introducer, so check
      for duplicates.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init6.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init6.C
new file mode 100644 (file)
index 0000000..3ebf479
--- /dev/null
@@ -0,0 +1,12 @@
+// Test that simple captures are not named in the closure type, but
+// initialized captures are named.
+// { dg-options "-std=c++1y" }
+
+int main()
+{
+  int i;
+  auto lam = [i,j=42]{};
+  lam.j;
+  lam.j.foo;                   // { dg-error "::j" }
+  lam.i;                       // { dg-error "no member" }
+}