diff options
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp new file mode 100644 index 00000000000..6b42fb5b089 --- /dev/null +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -0,0 +1,99 @@ +//===--- 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; +} |