Basic support for default argument expressions for function templates.

llvm-svn: 79972
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5452963..0ddf8b0 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -117,7 +117,7 @@
   //   copy-initialization semantics (8.5).
   if (CheckInitializerTypes(Arg, ParamType, EqualLoc, 
                             Param->getDeclName(), /*DirectInit=*/false))
-    return false;
+    return true;
 
   Arg = MaybeCreateCXXExprWithTemporaries(Arg, /*DestroyTemps=*/false);
   
@@ -126,7 +126,7 @@
   
   DefaultArg.release();
   
-  return true;
+  return false;
 }
 
 /// ActOnParamDefaultArgument - Check whether the default argument
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 04a1505..013273c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2500,6 +2500,33 @@
         Diag(UnparsedDefaultArgLocs[Param], 
               diag::note_default_argument_declared_here);
       } else {
+        if (Param->hasUninstantiatedDefaultArg()) {
+          Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
+
+          // Instantiate the expression.
+          const TemplateArgumentList &ArgList = 
+            getTemplateInstantiationArgs(FDecl);
+          
+          // FIXME: We should really make a new InstantiatingTemplate ctor
+          // that has a better message - right now we're just piggy-backing 
+          // off the "default template argument" error message.
+          InstantiatingTemplate Inst(*this, Call->getSourceRange().getBegin(),
+                                     FDecl->getPrimaryTemplate(),
+                                     ArgList.getFlatArgumentList(),
+                                     ArgList.flat_size());
+
+          OwningExprResult Result
+            = InstantiateExpr(UninstExpr, 
+                              getTemplateInstantiationArgs(FDecl));
+          if (Result.isInvalid()) 
+            return true;
+          
+          if (SetParamDefaultArgument(Param, move(Result), 
+                                      /*FIXME:EqualLoc*/
+                                      UninstExpr->getSourceRange().getBegin()))
+            return true;
+        }
+        
         Expr *DefaultExpr = Param->getDefaultArg();
         
         // If the default expression creates temporaries, we need to
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index ded49b3..86b1cbd 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -591,16 +591,6 @@
 
   QualType T = SemaRef.adjustParameterType(OrigT);
 
-  if (D->getDefaultArg()) {
-    // FIXME: Leave a marker for "uninstantiated" default
-    // arguments. They only get instantiated on demand at the call
-    // site.
-    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
-        "sorry, dropping default argument during template instantiation");
-    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
-      << D->getDefaultArg()->getSourceRange();
-  }
-
   // Allocate the parameter
   ParmVarDecl *Param = 0;
   if (T == OrigT)
@@ -613,6 +603,10 @@
                                         T, D->getDeclaratorInfo(), OrigT,
                                         D->getStorageClass(), 0);
 
+  // Mark the default argument as being uninstantiated.
+  if (Expr *Arg = D->getDefaultArg())
+    Param->setUninstantiatedDefaultArg(Arg);
+  
   // Note: we don't try to instantiate function parameters until after
   // we've instantiated the function's type. Therefore, we don't have
   // to check for 'void' parameter types here.