This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++0x] avoid extra tentative parse in range-based for loops


Hi.

I've been thinking for a time about the issue discussed in
http://gcc.gnu.org/ml/gcc/2010-09/msg00379.html
and I think I've got a solution!

The attached patch accomplishes the following:

1. It avoids the additional tentative parse for a range-for.

2. The following code compiles in both C++98 and C++0x modes, just as before.

for (struct S {} s; ; ) ;

3. It emits a helpful error message "range-based-for loops are not
allowed in C++98 mode" if the user tries to compile a range-for in
C++98.

Known side effects of this patch are:
1. The following code:

int a[5];
for (struct S {} s : a) ;

emits "error: expected initializer before : token" both in C++98 and
C++0x, instead of "types may not be defined in range-based for loops".

2. When parsing a for loop, some parser errors previously detected in
cp_parser_simple_declaration are delayed, and so the message may be
different:

for (int a ! ;;) ;

Will say "error: expected â;â before â!â token" instead of "error:
expected initializer before â!â token".


The parsing code for the 'for' statement is now somewhat simpler, but
that's because some of the complexity is moved to
cp_parser_simple_declaration and cp_parser_init_declarator.

Instead of dividing cp_parser_simple_declaration into pieces (too many
and too complex) I decided to add a new parameter and use it as a flag
to skip or modify certain code.
So, if this new parameter, named "just_one_declarator" is NULL, it
behaves exactly as before. But if it is not NULL it will recognize and
return only declarations suitable for a range-for. Again if the
declaration is not suitable for a range-for it will fall back to the
standard behavior.

Then, another tricky part is that the declaration is parsed before we
know if it will be a c-for or a range-for, but it must be declared
into the for scope, and this scope is created at the same time than
the statement. So I created a new function, begin_for_scope, that
creates the scope without the statement, and added the corresponding
parameters to begin_for_stmt and begin_range_for_stmt.

Also, I corrected two typos in a testcase, but that makes no difference.

Jason, what do you think or this?

Regards.
Rodrigo

gcc/cp/

2010-10-29  Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>

	* cp-tree.h (begin_for_scope): New prototype.
	(begin_for_stmt): Update prototype.
	(begin_range_for_stmt): Update prototype.
	* init.c (build_vec_init): Update call to begin_for_stmt.
	* parser.c (enum kind_of_for_loop): New.
	(cp_parser_for): New.
	(cp_parser_c_for): Add three new parameters.
	(cp_parser_range_for): Likewise. Most parsing code removed.
	(cp_parser_iteration_statement): Call cp_parser_for instead of
	cp_parser_c_for and cp_parser_range_for.
	(cp_parser_for_init_statement): Add new parameter and return type.
	(cp_parser_block_declaration): Update call to
	cp_parser_simple_declaration.
	(cp_parser_simple_declaration): Add new parameter.
	Update call to cp_parser_init_declarator.
	(cp_parser_init_declarator): Add new parameter.
	* pt.c (tsubst_expr): Update call to begin_for_stmt.
	* semantics.c (begin_for_scope): New.
	(begin_for_stmt): Add two new parameters.
	(begin_range_for_stmt): Likewise.

gcc/testsuite/

2010-10-20  Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>

	* g++.dg/cpp0x/range-for4.C: Delete include.
	Delete duplicated comment.

Attachment: range-for2.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]