This is the mail archive of the 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]

Re: C++ Patch Pings

GMail is at it again :(

On 3/28/07, Nathan Sidwell <> wrote:
>  - C++0x right angle brackets:

typo in changelog:
        (cp_parser_parameter_declaration): Treate `>>' like `>' in C++0x

Got it, thanks.

   ((token->type == CPP_GREATER && !parser->greater_than_is_operator_p)
    || ((flag_cpp0x && token->type == CPP_RSHIFT &&
    ? PREC_NOT_OPERATOR                                               \
      : binops_by_token[token->type].prec))

is easier to follow (with possible additional factorization of

Yes. Factoring out !parser->greater_than_is_operator_p helps clarify it further:

+#define TOKEN_PRECEDENCE(token)                                         \
+  ((token->type == CPP_GREATER && !parser->greater_than_is_operator_p)  \
+   ? PREC_NOT_OPERATOR                                                  \
+   : ((token->type == CPP_RSHIFT                                        \
+       && flag_cpp0x                                                    \
+       && !parser->greater_than_is_operator_p)                          \
+      ? PREC_NOT_OPERATOR                                               \
+      : binops_by_token[token->type].prec))

+          /* In C++0x, a `>>' in a template argument list or cast
+             expression is considered to be two separate `>'
+             tokens. So, change the current token to a `>', but don't
+             consume it: it will be consumed later when the outer
+             template argument list (or cast expression) is
+             parsed.  */
+         cp_token *token = cp_lexer_peek_token (parser->lexer);
+          token->type = CPP_GREATER;

What if we're parsing tentatively here?  That'll fail on a subsequent parse
because we'll have changed the input token stream.  I think
        gcc_assert (!cp_parser_uncommitted_to_tentative_parse_p (parser));
is necessary to make sure that never happens.

Interestingly enough, it *does* happen, but it's okay. There are only three places where we call cp_parser_enclosed_template_argument_list and can have '>>' changed to '>'. In all of the cases, we throw away the entire template argument list, either because it was erroneous (cp_parser_check_for_invalid_template_id and cp_parser_template_name act this way) or because we're replacing it with a CPP_TEMPLATE_ID (cp_parser_template_id does this). In either case, it's actually important that the change from '>>' to '>' "stick", because that '>' might still need to be parsed to close a new-style cast expression, even in an error case:


After auditing these calls to
cp_parser_enclosed_template_argument_list, I'm certain that we're
doing the righ tthing by *not* trying to back out the change from '>>'
to '>', and that the patch is correct as written. I've added another
test case (see below) that tests some of the more interesting cases.


// { dg-do "compile" }
// { dg-options "-std=c++0x" }

template<typename T>
struct vector {

struct X {
 template<typename T>
 struct tmpl {
   operator T() const;

template<typename T>
void g()
 T::template tmpl<vector<int>>() + 2;

template<typename T>
void operator+(vector<T>, int);

void f()
 vector<vector<int>>() + 2;

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