aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-25 23:02:36 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-25 23:02:36 +0000
commit3965b7be250de002d8744331631b9901941666a0 (patch)
treebb44455ae531d916159cbd3bc5f40d513cdaa589 /lib/Parse/ParseExpr.cpp
parentce87b929703cac0b3f236b0b0d1c7b78d8af38f2 (diff)
Cope with use of the token '>>' inside a template argument list, e.g.,
vector<vector<double>> Matrix; In C++98/03, this token always means "right shift". However, if we're in a context where we know that it can't mean "right shift", provide a friendly reminder to put a space between the two >'s and then treat it as two >'s as part of recovery. In C++0x, this token is always broken into two '>' tokens. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65484 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index b6c2a71e08..d0808a5f97 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -56,16 +56,29 @@ namespace prec {
/// token. This returns:
///
static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
- bool GreaterThanIsOperator) {
+ bool GreaterThanIsOperator,
+ bool CPlusPlus0x) {
switch (Kind) {
case tok::greater:
- // The '>' token can act as either an operator or as the ending
- // token for a template argument list.
- // FIXME: '>>' is similar, for error recovery and C++0x.
+ // C++ [temp.names]p3:
+ // [...] When parsing a template-argument-list, the first
+ // non-nested > is taken as the ending delimiter rather than a
+ // greater-than operator. [...]
if (GreaterThanIsOperator)
return prec::Relational;
return prec::Unknown;
+ case tok::greatergreater:
+ // C++0x [temp.names]p3:
+ //
+ // [...] Similarly, the first non-nested >> is treated as two
+ // consecutive but distinct > tokens, the first of which is
+ // taken as the end of the template-argument-list and completes
+ // the template-id. [...]
+ if (GreaterThanIsOperator || !CPlusPlus0x)
+ return prec::Shift;
+ return prec::Unknown;
+
default: return prec::Unknown;
case tok::comma: return prec::Comma;
case tok::equal:
@@ -90,8 +103,7 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
case tok::lessequal:
case tok::less:
case tok::greaterequal: return prec::Relational;
- case tok::lessless:
- case tok::greatergreater: return prec::Shift;
+ case tok::lessless: return prec::Shift;
case tok::plus:
case tok::minus: return prec::Additive;
case tok::percent:
@@ -274,7 +286,9 @@ Parser::OwningExprResult Parser::ParseConstantExpression() {
/// LHS and has a precedence of at least MinPrec.
Parser::OwningExprResult
Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
- unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
+ unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(),
+ GreaterThanIsOperator,
+ getLang().CPlusPlus0x);
SourceLocation ColonLoc;
while (1) {
@@ -324,7 +338,8 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
// Remember the precedence of this operator and get the precedence of the
// operator immediately to the right of the RHS.
unsigned ThisPrec = NextTokPrec;
- NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
+ NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
+ getLang().CPlusPlus0x);
// Assignment and conditional expressions are right-associative.
bool isRightAssoc = ThisPrec == prec::Conditional ||
@@ -343,7 +358,8 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
if (RHS.isInvalid())
return move(RHS);
- NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
+ NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
+ getLang().CPlusPlus0x);
}
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");