Doing diffs in .: --- ./include/clang/Parse/Parser.h.~1~ 2008-05-20 12:43:37.000000000 -0700 +++ ./include/clang/Parse/Parser.h 2008-05-22 18:48:20.000000000 -0700 @@ -338,7 +338,8 @@ private: ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok); ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec); - ExprResult ParseCastExpression(bool isUnaryExpression); + ExprResult ParseCastExpression(bool isUnaryExpression, + bool AllowThrow = false); ExprResult ParsePostfixExpressionSuffix(ExprResult LHS); ExprResult ParseSizeofAlignofExpression(); ExprResult ParseBuiltinPrimaryExpression(); --- ./lib/Parse/ParseExpr.cpp.~1~ 2008-05-20 12:43:37.000000000 -0700 +++ ./lib/Parse/ParseExpr.cpp 2008-05-22 18:48:20.000000000 -0700 @@ -167,10 +167,7 @@ static prec::Level getBinOpPrecedence(to /// expression ',' assignment-expression /// Parser::ExprResult Parser::ParseExpression() { - if (Tok.is(tok::kw_throw)) - return ParseThrowExpression(); - - ExprResult LHS = ParseCastExpression(false); + ExprResult LHS = ParseCastExpression(false, true); if (LHS.isInvalid) return LHS; return ParseRHSOfBinaryExpression(LHS, prec::Comma); @@ -191,17 +188,14 @@ Parser::ExprResult Parser::ParseExpressi /// ParseAssignmentExpression - Parse an expr that doesn't include commas. /// Parser::ExprResult Parser::ParseAssignmentExpression() { - if (Tok.is(tok::kw_throw)) - return ParseThrowExpression(); - - ExprResult LHS = ParseCastExpression(false); + ExprResult LHS = ParseCastExpression(false, true); if (LHS.isInvalid) return LHS; return ParseRHSOfBinaryExpression(LHS, prec::Assignment); } Parser::ExprResult Parser::ParseConstantExpression() { - ExprResult LHS = ParseCastExpression(false); + ExprResult LHS = ParseCastExpression(false, true); if (LHS.isInvalid) return LHS; return ParseRHSOfBinaryExpression(LHS, prec::Conditional); @@ -321,7 +315,7 @@ Parser::ParseRHSOfBinaryExpression(ExprR } // Parse another leaf here for the RHS of the operator. - ExprResult RHS = ParseCastExpression(false); + ExprResult RHS = ParseCastExpression(false, MinPrec <= prec::Assignment); if (RHS.isInvalid) { Actions.DeleteExpr(LHS.Val); Actions.DeleteExpr(TernaryMiddle.Val); @@ -398,7 +392,6 @@ Parser::ParseRHSOfBinaryExpression(ExprR /// identifier /// constant /// string-literal -/// [C++] boolean-literal [C++ 2.13.5] /// '(' expression ')' /// '__func__' [C99 6.4.2.2] /// [GNU] '__FUNCTION__' @@ -424,11 +417,18 @@ Parser::ParseRHSOfBinaryExpression(ExprR /// floating-constant /// enumeration-constant -> identifier /// character-constant +/// [C++] boolean-literal [C++ 2.13.5] /// -Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) { +Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression, + bool AllowThrow) { ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); + // We also handle 'throw' as it represents a leaf or unary operator. + if (AllowThrow && Tok.is(tok::kw_throw)) { + return ParseThrowExpression(); + } + // This handles all of cast-expression, unary-expression, postfix-expression, // and primary-expression. We handle them together like this for efficiency // and to simplify handling of an expression starting with a '(' token: which @@ -441,8 +441,8 @@ Parser::ExprResult Parser::ParseCastExpr // return without invoking ParsePostfixExpressionSuffix. switch (SavedKind) { case tok::l_paren: { - // If this expression is limited to being a unary-expression, the parent can - // not start a cast expression. + // If this expression is limited to being a unary-expression, the + // parent can not start a cast expression. ParenParseOption ParenExprType = isUnaryExpression ? CompoundLiteral : CastExpr; TypeTy *CastTy; @@ -483,6 +483,7 @@ Parser::ExprResult Parser::ParseCastExpr // These can be followed by postfix-expr pieces. return ParsePostfixExpressionSuffix(Res); + // constant (aka C++ literal): boolean-literal case tok::kw_true: case tok::kw_false: return ParseCXXBoolLiteral(); --- ./lib/Parse/ParseExprCXX.cpp.~1~ 2008-05-20 12:53:42.000000000 -0700 +++ ./lib/Parse/ParseExprCXX.cpp 2008-05-22 18:49:32.000000000 -0700 @@ -77,6 +77,34 @@ Parser::ExprResult Parser::ParseCXXBoolL return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); } +/// Returns true is Tok starts an expression. +/// FIXME: Any added support for Objective-C or C++ will need updates +/// to the below. +bool TokenStartsExpression(Token Tok) { + return (Tok.is(tok::kw_throw) || Tok.is(tok::l_paren) || + Tok.is(tok::plusplus) || Tok.is(tok::minusminus) || + Tok.is(tok::amp) || Tok.is(tok::star) || + Tok.is(tok::plus) || Tok.is(tok::minus) || + Tok.is(tok::tilde) || Tok.is(tok::exclaim) || + Tok.is(tok::kw___real) || Tok.is(tok::kw___imag) || + Tok.is(tok::kw___extension__) || Tok.is(tok::kw_sizeof) || + Tok.is(tok::kw___alignof) || Tok.is(tok::ampamp) || + Tok.is(tok::identifier) || Tok.is(tok::numeric_constant) || + Tok.is(tok::char_constant) || Tok.is(tok::kw_true) || + Tok.is(tok::kw_false) || Tok.is(tok::kw___func__) || + Tok.is(tok::kw___FUNCTION__) || + Tok.is(tok::kw___PRETTY_FUNCTION__) || + Tok.is(tok::string_literal) || Tok.is(tok::wide_string_literal) || + Tok.is(tok::kw___builtin_va_arg) || + Tok.is(tok::kw___builtin_offsetof) || + Tok.is(tok::kw___builtin_choose_expr) || + Tok.is(tok::kw___builtin_overload) || + Tok.is(tok::kw___builtin_types_compatible_p) || + Tok.is(tok::kw_const_cast) || Tok.is(tok::kw_dynamic_cast) || + Tok.is(tok::kw_reinterpret_cast) || Tok.is(tok::kw_static_cast) || + Tok.is(tok::at) || Tok.is(tok::l_square)); +} + /// ParseThrowExpression - This handles the C++ throw expression. /// /// throw-expression: [C++ 15] @@ -88,18 +116,10 @@ Parser::ExprResult Parser::ParseThrowExp // If the current token isn't the start of an assignment-expression, // then the expression is not present. This handles things like: // "C ? throw : (void)42", which is crazy but legal. - switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. - case tok::semi: - case tok::r_paren: - case tok::r_square: - case tok::r_brace: - case tok::colon: - case tok::comma: + if (!TokenStartsExpression(Tok)) return Actions.ActOnCXXThrow(ThrowLoc); - default: - ExprResult Expr = ParseAssignmentExpression(); - if (Expr.isInvalid) return Expr; - return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); - } + ExprResult Expr = ParseAssignmentExpression(); + if (Expr.isInvalid) return Expr; + return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); } --------------