More work on type parameter packs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73281 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f20bcd9..00d8c76 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1016,7 +1016,10 @@
   unsigned NumArgs = NumTemplateArgs;
   bool Invalid = false;
 
-  if (NumArgs > NumParams ||
+  bool HasParameterPack = 
+    NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
+  
+  if ((NumArgs > NumParams && !HasParameterPack) ||
       NumArgs < Params->getMinRequiredArguments()) {
     // FIXME: point at either the first arg beyond what we can handle,
     // or the '>', depending on whether we have too many or too few
@@ -1050,6 +1053,13 @@
       // Retrieve the default template argument from the template
       // parameter.
       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
+        if (TTP->isParameterPack()) {
+          // We have an empty parameter pack.
+          Converted.BeginParameterPack();
+          Converted.EndParameterPack();
+          break;
+        }
+        
         if (!TTP->hasDefaultArgument())
           break;
 
@@ -1112,8 +1122,19 @@
 
 
     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
-      if (CheckTemplateTypeArgument(TTP, Arg, Converted))
-        Invalid = true;
+      if (TTP->isParameterPack()) {
+        Converted.BeginParameterPack();
+        // Check all the remaining arguments (if any).
+        for (; ArgIdx < NumArgs; ++ArgIdx) {
+          if (CheckTemplateTypeArgument(TTP, TemplateArgs[ArgIdx], Converted))
+            Invalid = true;
+        }
+        
+        Converted.EndParameterPack();
+      } else {
+        if (CheckTemplateTypeArgument(TTP, Arg, Converted))
+          Invalid = true;
+      }
     } else if (NonTypeTemplateParmDecl *NTTP 
                  = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       // Check non-type template parameters.