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]

Re: C++ Patch Pings


GMail is at it again :(

On 3/28/07, Nathan Sidwell <nathan@codesourcery.com> wrote:
>  - C++0x right angle brackets:
> http://gcc.gnu.org/ml/gcc-patches/2007-02/msg01155.html

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

Got it, thanks.


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

is easier to follow (with possible additional factorization of
!parser->greater_than_is_operator_p)

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:

static_cast<int<int>>(0)

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.

 Cheers,
 Doug

// { 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]