Introduce a new expression type, CXXUnresolvedConstructExpr, to
describe the construction of a value of a given type using function
syntax, e.g.,
  
  T(a1, a2, ..., aN)

when the type or any of its arguments are type-dependent. In this
case, we don't know what kind of type-construction this will be: it
might construct a temporary of type 'T' (which might be a class or
non-class type) or might perform a conversion to type 'T'. Also,
implement printing of and template instantiation for this new
expression type. Due to the change in Sema::ActOnCXXTypeConstructExpr,
our existing tests cover template instantiation of this new expression
node.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72176 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index a0e2941..1dad862 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -93,6 +93,8 @@
     // FIXME: UnaryTypeTraitExpr
     // FIXME: QualifiedDeclRefExpr
     // FIXME: CXXExprWithTemporaries
+    OwningExprResult VisitCXXUnresolvedConstructExpr(
+                                               CXXUnresolvedConstructExpr *E);
     OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
     OwningExprResult VisitUnresolvedFunctionNameExpr(
                                               UnresolvedFunctionNameExpr *E);
@@ -834,6 +836,45 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr(
+                                              CXXUnresolvedConstructExpr *E) {
+  QualType T = SemaRef.InstantiateType(E->getTypeAsWritten(), TemplateArgs,
+                                       E->getTypeBeginLoc(), 
+                                       DeclarationName());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  llvm::SmallVector<Expr *, 8> Args;
+  llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
+  for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
+                                             ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    OwningExprResult InstArg = Visit(*Arg);
+    if (InstArg.isInvalid()) {
+      for (unsigned I = 0; I != Args.size(); ++I)
+        Args[I]->Destroy(SemaRef.Context);
+      return SemaRef.ExprError();
+    }
+
+    FakeCommaLocs.push_back(
+           SemaRef.PP.getLocForEndOfToken((*Arg)->getSourceRange().getEnd()));
+    Args.push_back(InstArg.takeAs<Expr>());
+  }
+
+  // FIXME: The end of the type range isn't exactly correct.
+  // FIXME: we're faking the locations of the commas
+  return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc(),
+                                                       E->getLParenLoc()),
+                                           T.getAsOpaquePtr(),
+                                           E->getLParenLoc(),
+                                           Sema::MultiExprArg(SemaRef, 
+                                                       (void **)&Args.front(),
+                                                              Args.size()),
+                                           &FakeCommaLocs.front(),
+                                           E->getRParenLoc());
+}
+
+Sema::OwningExprResult 
 Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
   if (!E)
     return Owned((Expr *)0);