//===--- 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!"); SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. // 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: return Actions.ActOnCXXThrow(ThrowLoc); default: ExprResult Expr = ParseAssignmentExpression(); if (Expr.isInvalid) return Expr; return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); } }