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
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 12ba001..5c06386 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -400,6 +400,23 @@
 /// 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 @@
 ///                   '__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 @@
       return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
     // FALL THROUGH.      
   default:
-    Diag(Tok, diag::err_expected_expression);
+    NotCastExpr = true;
     return ExprError();
   }
 
@@ -1216,6 +1235,7 @@
   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 @@
     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 ')'.