N3994 Ranged-based for-loops: The Next Generation
authorJason Merrill <jason@redhat.com>
Thu, 26 Jun 2014 18:15:36 +0000 (14:15 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 26 Jun 2014 18:15:36 +0000 (14:15 -0400)
N3994 Ranged-based for-loops: The Next Generation
* parser.c (cp_lexer_nth_token_is): New.
(cp_parser_for_init_statement): Allow "for (id : init)".

From-SVN: r212043

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp1z/range-for1.C [new file with mode: 0644]

index 124f4d6e30bd98304b5e07de01ea991a3f88635d..669e7144f6869343ac993ba1898278fccdc5d559 100644 (file)
@@ -1,3 +1,9 @@
+2014-06-26  Jason Merrill  <jason@redhat.com>
+
+       N3994 Ranged-based for-loops: The Next Generation
+       * parser.c (cp_lexer_nth_token_is): New.
+       (cp_parser_for_init_statement): Allow "for (id : init)".
+
 2014-06-26  Adam Butcher  <adam@jessamine.co.uk>
 
        PR c++/61537
index c440c9937bab9c3fcb017dfd5484f2a4d5cf5350..426dca439de4b29050a43cc086d26f47b4c3f8a6 100644 (file)
@@ -891,6 +891,12 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
   return cp_lexer_peek_token (lexer)->keyword == keyword;
 }
 
+static inline bool
+cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type)
+{
+  return cp_lexer_peek_nth_token (lexer, n)->type == type;
+}
+
 static inline bool
 cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
 {
@@ -10607,6 +10613,23 @@ cp_parser_for_init_statement (cp_parser* parser, tree *decl)
       bool is_range_for = false;
       bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
 
+      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
+       {
+         /* N3994 -- for (id : init) ... */
+         if (cxx_dialect < cxx1z)
+           pedwarn (input_location, 0, "range-based for loop without a "
+                    "type-specifier only available with "
+                    "-std=c++1z or -std=gnu++1z");
+         tree name = cp_parser_identifier (parser);
+         tree type = cp_build_reference_type (make_auto (), /*rval*/true);
+         *decl = build_decl (input_location, VAR_DECL, name, type);
+         pushdecl (*decl);
+         cp_lexer_consume_token (parser->lexer);
+         return true;
+       }
+
+      /* A colon is used in range-based for.  */
       parser->colon_corrects_to_scope_p = false;
 
       /* We're going to speculatively look for a declaration, falling back
diff --git a/gcc/testsuite/g++.dg/cpp1z/range-for1.C b/gcc/testsuite/g++.dg/cpp1z/range-for1.C
new file mode 100644 (file)
index 0000000..7e6d055
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-options "-std=c++1z -pedantic-errors" }
+
+extern "C" int printf (const char *, ...);
+#include <initializer_list>
+
+int main()
+{
+  for (i : {1,2})
+    {
+      printf ("%d ", i);
+    }
+}