OSDN Git Service

PR c++/41896
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Feb 2010 02:12:53 +0000 (02:12 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Feb 2010 02:12:53 +0000 (02:12 +0000)
* semantics.c (outer_lambda_capture_p): Revert.
(add_capture): Only finish_member_declaration if
we're in the lambda class.
(register_capture_members): New.
* cp-tree.h: Declare it.
* parser.c (cp_parser_lambda_expression): Call it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156678 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/semantics.c

index 7a6e78a..f42f59e 100644 (file)
@@ -1,6 +1,16 @@
 2010-02-10  Jason Merrill  <jason@redhat.com>
 
        PR c++/41896
+       * semantics.c (outer_lambda_capture_p): Revert.
+       (add_capture): Only finish_member_declaration if
+       we're in the lambda class.
+       (register_capture_members): New.
+       * cp-tree.h: Declare it.
+       * parser.c (cp_parser_lambda_expression): Call it.
+
+2010-02-10  Jason Merrill  <jason@redhat.com>
+
+       PR c++/41896
        * semantics.c (outer_lambda_capture_p): Use current_function_decl
        instead of current_class_type.
 
index 27c820b..f32c6e8 100644 (file)
@@ -5193,6 +5193,7 @@ extern tree lambda_function                       (tree);
 extern void apply_lambda_return_type            (tree, tree);
 extern tree add_capture                         (tree, tree, tree, bool, bool);
 extern tree add_default_capture                 (tree, tree, tree);
+extern void register_capture_members           (tree);
 extern tree lambda_expr_this_capture            (tree);
 extern void maybe_add_lambda_conv_op            (tree);
 
index 5256883..690f2c0 100644 (file)
@@ -7072,6 +7072,8 @@ cp_parser_lambda_expression (cp_parser* parser)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  cp_parser_lambda_introducer (parser, lambda_expr);
+
   type = begin_lambda_type (lambda_expr);
 
   record_lambda_scope (lambda_expr);
@@ -7079,6 +7081,10 @@ cp_parser_lambda_expression (cp_parser* parser)
   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   determine_visibility (TYPE_NAME (type));
 
+  /* Now that we've started the type, add the capture fields for any
+     explicit captures.  */
+  register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
   {
     /* Inside the class, surrounding template-parameter-lists do not apply.  */
     unsigned int saved_num_template_parameter_lists
@@ -7086,8 +7092,6 @@ cp_parser_lambda_expression (cp_parser* parser)
 
     parser->num_template_parameter_lists = 0;
 
-    cp_parser_lambda_introducer (parser, lambda_expr);
-
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
 
index 796b789..985e2c0 100644 (file)
@@ -2714,9 +2714,8 @@ outer_lambda_capture_p (tree decl)
 {
   return (TREE_CODE (decl) == FIELD_DECL
          && LAMBDA_TYPE_P (DECL_CONTEXT (decl))
-         /* Using current_class_type here causes problems with uses in a
-            nested lambda-introducer; see 41896.  */
-         && DECL_CONTEXT (current_function_decl) != DECL_CONTEXT (decl));
+         && (!current_class_type
+             || !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type)));
 }
 
 /* ID_EXPRESSION is a representation of parsed, but unprocessed,
@@ -5690,8 +5689,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
        always visible.  */
     DECL_NORMAL_CAPTURE_P (member) = true;
 
-  /* Add it to the appropriate closure class.  */
-  finish_member_declaration (member);
+  /* Add it to the appropriate closure class if we've started it.  */
+  if (current_class_type && current_class_type == TREE_TYPE (lambda))
+    finish_member_declaration (member);
 
   LAMBDA_EXPR_CAPTURE_LIST (lambda)
     = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
@@ -5706,6 +5706,18 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
   return member;
 }
 
+/* Register all the capture members on the list CAPTURES, which is the
+   LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer.  */
+
+void register_capture_members (tree captures)
+{
+  if (captures)
+    {
+      register_capture_members (TREE_CHAIN (captures));
+      finish_member_declaration (TREE_PURPOSE (captures));
+    }
+}
+
 /* Given a FIELD_DECL decl belonging to a closure type, return a
    COMPONENT_REF of it relative to the 'this' parameter of the op() for
    that type.  */