Template instantiation for the various kinds of AST nodes that occur
due to C++ type construction of the form T(a1, a2, ..., aN).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72183 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 1dad862..1b2fa46 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -85,9 +85,9 @@
     // FIXME: CXXTypeIdExpr
     // FIXME: CXXThrowExpr
     // FIXME: CXXDefaultArgExpr
-    // FIXME: CXXConstructExpr
-    // FIXME: CXXFunctionalCastExpr
-    // FIXME: CXXZeroInitValueExpr
+    OwningExprResult VisitCXXConstructExpr(CXXConstructExpr *E);
+    OwningExprResult VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+    OwningExprResult VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
     // FIXME: CXXNewExpr
     // FIXME: CXXDeleteExpr
     // FIXME: UnaryTypeTraitExpr
@@ -836,6 +836,87 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext())
+           ->isDependentType() && "Dependent constructor shouldn't be here");
+
+  QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+                                       /*FIXME*/E->getSourceRange().getBegin(),
+                                       DeclarationName());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  bool Invalid = false;
+  llvm::SmallVector<Expr *, 8> Args;
+  for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(), 
+                                   ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    OwningExprResult ArgInst = Visit(*Arg);
+    if (ArgInst.isInvalid()) {
+      Invalid = true;
+      break;
+    }
+
+    Args.push_back(ArgInst.takeAs<Expr>());
+  }
+
+
+  VarDecl *Var = 0;
+  if (!Invalid) {
+    Var = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
+                                                        SemaRef.CurContext,
+                                                        TemplateArgs));
+    if (!Var)
+      Invalid = true;
+  }
+
+  if (Invalid) {
+    for (unsigned I = 0, N = Args.size(); I != N; ++I)
+      Args[I]->Destroy(SemaRef.Context);
+
+    return SemaRef.ExprError();
+  }
+
+  return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, Var, T,
+                                                E->getConstructor(), 
+                                                E->isElidable(),
+                                                &Args.front(), Args.size()));
+}
+
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXFunctionalCastExpr(
+                                                   CXXFunctionalCastExpr *E) {
+  // Instantiate the type that we're casting to.
+  QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
+                                                TemplateArgs,
+                                                E->getTypeBeginLoc(),
+                                                DeclarationName());
+  if (ExplicitTy.isNull())
+    return SemaRef.ExprError();
+
+  // Instantiate the subexpression.
+  OwningExprResult SubExpr = Visit(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+  
+  // FIXME: The end of the type's source range is wrong
+  Expr *Sub = SubExpr.takeAs<Expr>();
+  return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()),
+                                           ExplicitTy.getAsOpaquePtr(),
+                                           /*FIXME:*/E->getTypeBeginLoc(),
+                                           Sema::MultiExprArg(SemaRef,
+                                                              (void **)&Sub,
+                                                              1),
+                                           0, 
+                                           E->getRParenLoc());
+}
+
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult 
 TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr(
                                               CXXUnresolvedConstructExpr *E) {
   QualType T = SemaRef.InstantiateType(E->getTypeAsWritten(), TemplateArgs,