ParseExprCXX.cpp revision bda0b626e74513950405c27525af87e214e605e2
1//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Expression parsing implementation for C++.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/Diagnostic.h"
15#include "clang/Parse/Parser.h"
16using namespace clang;
17
18/// ParseCXXCasts - This handles the various ways to cast expressions to another
19/// type.
20///
21///       postfix-expression: [C++ 5.2p1]
22///         'dynamic_cast' '<' type-name '>' '(' expression ')'
23///         'static_cast' '<' type-name '>' '(' expression ')'
24///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
25///         'const_cast' '<' type-name '>' '(' expression ')'
26///
27Parser::ExprResult Parser::ParseCXXCasts() {
28  tok::TokenKind Kind = Tok.getKind();
29  const char *CastName = 0;     // For error messages
30
31  switch (Kind) {
32  default: assert(0 && "Unknown C++ cast!"); abort();
33  case tok::kw_const_cast:       CastName = "const_cast";       break;
34  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
35  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
36  case tok::kw_static_cast:      CastName = "static_cast";      break;
37  }
38
39  SourceLocation OpLoc = ConsumeToken();
40  SourceLocation LAngleBracketLoc = Tok.getLocation();
41
42  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
43    return ExprResult(true);
44
45  TypeTy *CastTy = ParseTypeName();
46  SourceLocation RAngleBracketLoc = Tok.getLocation();
47
48  if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) {
49    Diag(LAngleBracketLoc, diag::err_matching, "<");
50    return ExprResult(true);
51  }
52
53  SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
54
55  if (Tok.isNot(tok::l_paren)) {
56    Diag(Tok, diag::err_expected_lparen_after, CastName);
57    return ExprResult(true);
58  }
59
60  ExprResult Result = ParseSimpleParenExpression(RParenLoc);
61
62  if (!Result.isInvalid)
63    Result = Actions.ActOnCXXCasts(OpLoc, Kind,
64                                   LAngleBracketLoc, CastTy, RAngleBracketLoc,
65                                   LParenLoc, Result.Val, RParenLoc);
66
67  return Result;
68}
69
70/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
71///
72///       boolean-literal: [C++ 2.13.5]
73///         'true'
74///         'false'
75Parser::ExprResult Parser::ParseCXXBoolLiteral() {
76  tok::TokenKind Kind = Tok.getKind();
77  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
78}
79
80/// ParseThrowExpression - This handles the C++ throw expression.
81///
82///       throw-expression: [C++ 15]
83///         'throw' assignment-expression[opt]
84Parser::ExprResult Parser::ParseThrowExpression() {
85  assert(Tok.is(tok::kw_throw) && "Not throw!");
86
87  ExprResult Expr;
88
89  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
90  // FIXME: Anything that isn't an assignment-expression should bail out now.
91  if (Tok.is(tok::semi) || Tok.is(tok::r_paren) || Tok.is(tok::colon) ||
92      Tok.is(tok::comma))
93    return Actions.ActOnCXXThrow(ThrowLoc);
94
95  Expr = ParseAssignmentExpression();
96  if (!Expr.isInvalid)
97    Expr = Actions.ActOnCXXThrow(ThrowLoc, Expr.Val);
98  return Expr;
99}
100