> Yes, I was just trying exactly that improvement.
How about this?

> I'm going to let the committee know that option 5 has been
> implemented.  Thanks very much!

Cool! Thank you.
--
Rodrigo
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9523fdc..aab9294 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1871,6 +1871,8 @@ static tree cp_parser_c_for
   (cp_parser *, tree, tree);
 static tree cp_parser_range_for
   (cp_parser *, tree, tree, tree);
+static tree cp_parser_perform_range_for_lookup
+  (const char *, tree, int*);
 static tree cp_parser_jump_statement
   (cp_parser *);
 static void cp_parser_declaration_statement
@@ -8870,32 +8872,34 @@ cp_convert_range_for (tree statement, tree range_decl, 
tree range_expr)
       else
        {
          /* If it is not an array, we must call begin(__range)/end__range() */
-         VEC(tree,gc) *vec;
-
-         begin_expr = get_identifier ("begin");
-         vec = make_tree_vector ();
-         VEC_safe_push (tree, gc, vec, range_temp);
-         begin_expr = perform_koenig_lookup (begin_expr, vec,
-                                             /*include_std=*/true);
-         begin_expr = finish_call_expr (begin_expr, &vec, false, true,
-                                        tf_warning_or_error);
-         release_tree_vector (vec);
-
-         end_expr = get_identifier ("end");
-         vec = make_tree_vector ();
-         VEC_safe_push (tree, gc, vec, range_temp);
-         end_expr = perform_koenig_lookup (end_expr, vec,
-                                           /*include_std=*/true);
-         end_expr = finish_call_expr (end_expr, &vec, false, true,
-                                      tf_warning_or_error);
-         release_tree_vector (vec);
-
-         /* The unqualified type of the __begin and __end temporaries should
-          * be the same as required by the multiple auto declaration */
-         iter_type = cv_unqualified (TREE_TYPE (begin_expr));
-         if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (end_expr))))
-           error ("inconsistent begin/end types in range-based for: %qT and 
%qT",
-                  TREE_TYPE (begin_expr), TREE_TYPE (end_expr));
+         int begin_is_member = 0;
+         begin_expr = cp_parser_perform_range_for_lookup("begin", range_temp, 
&begin_is_member);
+         int end_is_member = 0;
+         end_expr = cp_parser_perform_range_for_lookup("end", range_temp, 
&end_is_member);
+
+         if (begin_expr == error_mark_node || end_expr == error_mark_node)
+           /* If one of the expressions is an error do no more checks.  */
+           begin_expr = end_expr = iter_type = error_mark_node;
+         else
+           {
+             iter_type = cv_unqualified (TREE_TYPE (begin_expr));
+             /* Check that the __begin and __end expressions are consistent.  
*/
+             if (begin_is_member != end_is_member)
+               {
+                 error ("range-based for found %s %<begin%> and %s %<end%>",
+                        (begin_is_member ? "member" : "non-member"),
+                        (end_is_member ? "member" : "non-member"));
+               }
+             else
+               {
+                 /* The unqualified type of the __begin and __end temporaries 
should
+                  * be the same as required by the multiple auto declaration */
+                 if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE 
(end_expr))))
+                   error ("inconsistent begin/end types in range-based for: "
+                          "%qT and %qT",
+                          TREE_TYPE (begin_expr), TREE_TYPE (end_expr));
+               }
+           }
        }
     }
 
@@ -8940,6 +8944,44 @@ cp_convert_range_for (tree statement, tree range_decl, 
tree range_expr)
   return statement;
 }
 
+static tree
+cp_parser_perform_range_for_lookup (const char *name, tree range, int* 
is_member)
+{
+  tree ident, expr;
+
+  ident = get_identifier (name);
+  expr = build_qualified_name (/*type=*/NULL_TREE,
+                              TREE_TYPE (range),
+                              ident,
+                              /*template_p=*/false);
+  expr = finish_class_member_access_expr(range, expr, false, tf_none);
+
+  if (expr != error_mark_node)
+    {
+      tree instance, fn;
+      instance = TREE_OPERAND (expr, 0);
+      fn = TREE_OPERAND (expr, 1);
+
+      expr = build_new_method_call (instance, fn, NULL, NULL, LOOKUP_NORMAL,
+                                   NULL, tf_warning_or_error);
+      *is_member = 1;
+    }
+  else
+    {
+      VEC(tree,gc) *vec;
+      vec = make_tree_vector ();
+      VEC_safe_push (tree, gc, vec, range);
+      expr = get_identifier (name);
+      expr = perform_koenig_lookup (expr, vec,
+                                   /*include_std=*/true);
+      expr = finish_call_expr (expr, &vec, false, true,
+                              tf_warning_or_error);
+      release_tree_vector (vec);
+      *is_member = 0;
+    }
+  return expr;
+}
+
 
 /* Parse an iteration-statement.
 

Reply via email to