| //===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the Expression parsing implementation for C++. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Basic/Diagnostic.h" |
| #include "clang/Parse/Parser.h" |
| using namespace clang; |
| |
| /// ParseCXXCasts - This handles the various ways to cast expressions to another |
| /// type. |
| /// |
| /// postfix-expression: [C++ 5.2p1] |
| /// 'dynamic_cast' '<' type-name '>' '(' expression ')' |
| /// 'static_cast' '<' type-name '>' '(' expression ')' |
| /// 'reinterpret_cast' '<' type-name '>' '(' expression ')' |
| /// 'const_cast' '<' type-name '>' '(' expression ')' |
| /// |
| Parser::ExprResult Parser::ParseCXXCasts() { |
| tok::TokenKind Kind = Tok.getKind(); |
| const char *CastName = 0; // For error messages |
| |
| switch (Kind) { |
| default: assert(0 && "Unknown C++ cast!"); abort(); |
| case tok::kw_const_cast: CastName = "const_cast"; break; |
| case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; |
| case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; |
| case tok::kw_static_cast: CastName = "static_cast"; break; |
| } |
| |
| SourceLocation OpLoc = ConsumeToken(); |
| SourceLocation LAngleBracketLoc = Tok.getLocation(); |
| |
| if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) |
| return ExprResult(true); |
| |
| TypeTy *CastTy = ParseTypeName(); |
| SourceLocation RAngleBracketLoc = Tok.getLocation(); |
| |
| if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) { |
| Diag(LAngleBracketLoc, diag::err_matching, "<"); |
| return ExprResult(true); |
| } |
| |
| SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; |
| |
| if (Tok.isNot(tok::l_paren)) { |
| Diag(Tok, diag::err_expected_lparen_after, CastName); |
| return ExprResult(true); |
| } |
| |
| ExprResult Result = ParseSimpleParenExpression(RParenLoc); |
| |
| if (!Result.isInvalid) |
| Result = Actions.ActOnCXXCasts(OpLoc, Kind, |
| LAngleBracketLoc, CastTy, RAngleBracketLoc, |
| LParenLoc, Result.Val, RParenLoc); |
| |
| return Result; |
| } |
| |
| /// ParseCXXBoolLiteral - This handles the C++ Boolean literals. |
| /// |
| /// boolean-literal: [C++ 2.13.5] |
| /// 'true' |
| /// 'false' |
| Parser::ExprResult Parser::ParseCXXBoolLiteral() { |
| tok::TokenKind Kind = Tok.getKind(); |
| return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); |
| } |
| |
| /// ParseThrowExpression - This handles the C++ throw expression. |
| /// |
| /// throw-expression: [C++ 15] |
| /// 'throw' assignment-expression[opt] |
| Parser::ExprResult Parser::ParseThrowExpression() { |
| assert(Tok.is(tok::kw_throw) && "Not throw!"); |
| |
| ExprResult Expr; |
| |
| SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. |
| // FIXME: Anything that isn't an assignment-expression should bail out now. |
| if (Tok.is(tok::semi) || Tok.is(tok::r_paren) || Tok.is(tok::colon) || |
| Tok.is(tok::comma)) |
| return Actions.ActOnCXXThrow(ThrowLoc); |
| |
| Expr = ParseAssignmentExpression(); |
| if (!Expr.isInvalid) |
| Expr = Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); |
| return Expr; |
| } |