Introduce a new kind of TemplateName that captures a substituted
template template parameter pack that cannot be fully expanded because
its enclosing pack expansion could not be expanded. This form of
TemplateName plays the same role as SubstTemplateTypeParmPackType and
SubstNonTypeTemplateParmPackExpr do for template type parameter packs
and non-type template parameter packs, respectively.

We should now handle these multi-level pack expansion substitutions
anywhere. The largest remaining gap in our variadic-templates support
is that we cannot cope with non-type template parameter packs whose
type is a pack expansion.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123521 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 73ff402..6b378a0 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/TemplateName.h"
+#include "clang/AST/TemplateBase.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
@@ -21,15 +22,33 @@
 using namespace clang;
 using namespace llvm;
 
+TemplateArgument 
+SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
+  return TemplateArgument(Arguments, size());
+}
+
+void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
+}
+
+void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID, 
+                                                   ASTContext &Context,
+                                           TemplateTemplateParmDecl *Parameter,
+                                             const TemplateArgument &ArgPack) {
+  ID.AddPointer(Parameter);
+  ArgPack.Profile(ID, Context);
+}
+
 TemplateName::NameKind TemplateName::getKind() const {
   if (Storage.is<TemplateDecl *>())
     return Template;
-  if (Storage.is<OverloadedTemplateStorage *>())
-    return OverloadedTemplate;
+  if (Storage.is<DependentTemplateName *>())
+    return DependentTemplate;
   if (Storage.is<QualifiedTemplateName *>())
     return QualifiedTemplate;
-  assert(Storage.is<DependentTemplateName *>() && "There's a case unhandled!");
-  return DependentTemplate;
+  
+  return getAsOverloadedTemplate()? OverloadedTemplate
+                                  : SubstTemplateTemplateParmPack;
 }
 
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
@@ -73,7 +92,7 @@
     return DTN->getQualifier() && 
       DTN->getQualifier()->containsUnexpandedParameterPack();
 
-  return false;
+  return getAsSubstTemplateTemplateParmPack() != 0;
 }
 
 void
@@ -96,7 +115,9 @@
       OS << DTN->getIdentifier()->getName();
     else
       OS << "operator " << getOperatorSpelling(DTN->getOperator());
-  }
+  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
+                                        = getAsSubstTemplateTemplateParmPack())
+    OS << SubstPack->getParameterPack()->getNameAsString();
 }
 
 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,