aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-05-22 10:24:42 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-05-22 10:24:42 +0000
commitf58f45e6d76792df8c643ce1c6d364dce5db4826 (patch)
tree54a05a54efa7adea73c568d67e8bec7340ac8849 /lib/Parse/ParseExpr.cpp
parentd974a7b72eb84cdc735b189bcea56fd37e13ebf6 (diff)
Handle correctly a very ugly part of the C++ syntax. We cannot disambiguate between a parenthesized type-id and
a paren expression without considering the context past the parentheses. Behold: (T())x; - type-id (T())*x; - type-id (T())/x; - expression (T()); - expression git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72260 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp37
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 12ba001f0e..5c063868bb 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -400,6 +400,23 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
/// id-expression that is the operand of address-of gets special treatment
/// due to member pointers.
///
+Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
+ bool isAddressOfOperand) {
+ bool NotCastExpr;
+ OwningExprResult Res = ParseCastExpression(isUnaryExpression,
+ isAddressOfOperand,
+ NotCastExpr);
+ if (NotCastExpr)
+ Diag(Tok, diag::err_expected_expression);
+ return move(Res);
+}
+
+/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
+/// true, parse a unary-expression. isAddressOfOperand exists because an
+/// id-expression that is the operand of address-of gets special treatment
+/// due to member pointers. NotCastExpr is set to true if the token is not the
+/// start of a cast-expression, and no diagnostic is emitted in this case.
+///
/// cast-expression: [C99 6.5.4]
/// unary-expression
/// '(' type-name ')' cast-expression
@@ -506,9 +523,11 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
/// '__is_base_of' [TODO]
///
Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
- bool isAddressOfOperand) {
+ bool isAddressOfOperand,
+ bool &NotCastExpr) {
OwningExprResult Res(Actions);
tok::TokenKind SavedKind = Tok.getKind();
+ NotCastExpr = false;
// This handles all of cast-expression, unary-expression, postfix-expression,
// and primary-expression. We handle them together like this for efficiency
@@ -797,7 +816,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
// FALL THROUGH.
default:
- Diag(Tok, diag::err_expected_expression);
+ NotCastExpr = true;
return ExprError();
}
@@ -1216,6 +1235,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
SourceLocation OpenLoc = ConsumeParen();
OwningExprResult Result(Actions, true);
+ bool isAmbiguousTypeId;
CastTy = 0;
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
@@ -1227,9 +1247,20 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation());
- } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
+ } else if (ExprType >= CompoundLiteral &&
+ isTypeIdInParens(isAmbiguousTypeId)) {
// Otherwise, this is a compound literal expression or cast expression.
+
+ // In C++, if the type-id is ambiguous we disambiguate based on context.
+ // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
+ // in which case we should treat it as type-id.
+ // if stopIfCastExpr is false, we need to determine the context past the
+ // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
+ if (isAmbiguousTypeId && !stopIfCastExpr)
+ return ParseCXXAmbiguousParenExpression(ExprType, CastTy,
+ OpenLoc, RParenLoc);
+
TypeResult Ty = ParseTypeName();
// Match the ')'.