Add support for C++'s "type-specifier ( expression-list )" expression:

-The Parser calls a new "ActOnCXXTypeConstructExpr" action.
-Sema, depending on the type and expressions number:
   -If the type is a class, it will treat it as a class constructor. [TODO]
   -If there's only one expression (i.e. "int(0.5)" ), creates a new "CXXFunctionalCastExpr" Expr node
   -If there are no expressions (i.e "int()" ), creates a new "CXXZeroInitValueExpr" Expr node.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55177 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 86e3345..1c723e6 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -68,3 +68,67 @@
 
   return Diag(ThisLoc, diag::err_invalid_this_use);
 }
+
+/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
+/// Can be interpreted either as function-style casting ("int(x)")
+/// or class type construction ("ClassType(x,y,z)")
+/// or creation of a value-initialized type ("int()").
+Action::ExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+                                SourceLocation LParenLoc,
+                                ExprTy **ExprTys, unsigned NumExprs,
+                                SourceLocation *CommaLocs,
+                                SourceLocation RParenLoc) {
+  assert(TypeRep && "Missing type!");
+  QualType Ty = QualType::getFromOpaquePtr(TypeRep);
+  Expr **Exprs = (Expr**)ExprTys;
+  SourceLocation TyBeginLoc = TypeRange.getBegin();
+  SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
+
+  if (const RecordType *RT = Ty->getAsRecordType()) {
+    // C++ 5.2.3p1:
+    // If the simple-type-specifier specifies a class type, the class type shall
+    // be complete.
+    //
+    if (!RT->getDecl()->isDefinition())
+      return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
+                  Ty.getAsString(), FullRange);
+
+    // "class constructors are not supported yet"
+    return Diag(TyBeginLoc, diag::err_unsupported_class_constructor, FullRange);
+  }
+
+  // C++ 5.2.3p1:
+  // If the expression list is a single expression, the type conversion
+  // expression is equivalent (in definedness, and if defined in meaning) to the
+  // corresponding cast expression.
+  //
+  if (NumExprs == 1) {
+    if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
+      return true;
+    return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
+  }
+
+  // C++ 5.2.3p1:
+  // If the expression list specifies more than a single value, the type shall
+  // be a class with a suitably declared constructor.
+  //
+  if (NumExprs > 1)
+    return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg,
+                FullRange);
+
+  assert(NumExprs == 0 && "Expected 0 expressions");
+
+  // C++ 5.2.3p2:
+  // The expression T(), where T is a simple-type-specifier for a non-array
+  // complete object type or the (possibly cv-qualified) void type, creates an
+  // rvalue of the specified type, which is value-initialized.
+  //
+  if (Ty->isArrayType())
+    return Diag(TyBeginLoc, diag::err_value_init_for_array_type, FullRange);
+  if (Ty->isIncompleteType() && !Ty->isVoidType())
+    return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
+                Ty.getAsString(), FullRange);
+
+  return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
+}