Replace the representation of template template argument pack
expansions with something that is easier to use correctly: a new
template argment kind, rather than a bit on an existing kind. Update
all of the switch statements that deal with template arguments, fixing
a few latent bugs in the process. I"m happy with this representation,
now.

And, oh look! Template instantiation and deduction work for template
template argument pack expansions.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122896 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index b452060..6e7f7c3 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2692,7 +2692,12 @@
 
     case TemplateArgument::Template:
       return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
-      
+
+    case TemplateArgument::TemplateExpansion:
+      return TemplateArgument(getCanonicalTemplateName(
+                                         Arg.getAsTemplateOrTemplatePattern()),
+                              true);
+
     case TemplateArgument::Integral:
       return TemplateArgument(*Arg.getAsIntegral(),
                               getCanonicalType(Arg.getIntegralType()));
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 70c8632..5a94de9 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -301,7 +301,12 @@
     return IsStructurallyEquivalent(Context, 
                                     Arg1.getAsTemplate(), 
                                     Arg2.getAsTemplate());
-      
+
+  case TemplateArgument::TemplateExpansion:
+    return IsStructurallyEquivalent(Context, 
+                                    Arg1.getAsTemplateOrTemplatePattern(), 
+                                    Arg2.getAsTemplateOrTemplatePattern());
+
   case TemplateArgument::Expression:
     return IsStructurallyEquivalent(Context, 
                                     Arg1.getAsExpr(), Arg2.getAsExpr());
@@ -1785,7 +1790,16 @@
     
     return TemplateArgument(ToTemplate);
   }
-      
+
+  case TemplateArgument::TemplateExpansion: {
+    TemplateName ToTemplate 
+      = Importer.Import(From.getAsTemplateOrTemplatePattern());
+    if (ToTemplate.isNull())
+      return TemplateArgument();
+    
+    return TemplateArgument(ToTemplate, true);
+  }
+
   case TemplateArgument::Expression:
     if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
       return TemplateArgument(ToExpr);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 08272e7..5b82ddd 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -179,7 +179,9 @@
       break;
 
     case TemplateArgument::Template:
-      if (TemplateDecl *Template = Args[I].getAsTemplate().getAsTemplateDecl())
+    case TemplateArgument::TemplateExpansion:
+      if (TemplateDecl *Template 
+                = Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl())
         LV = merge(LV, getLVForDecl(Template, F));
       break;
 
diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp
index 7465ea4..65a18aa 100644
--- a/lib/AST/DumpXML.cpp
+++ b/lib/AST/DumpXML.cpp
@@ -319,6 +319,10 @@
       break;
     }
     case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion:
+      // FIXME: Implement!
+      break;
+        
     case TemplateArgument::Declaration: {
       visitDeclRef(A.getAsDecl());
       break;
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 17a9326..63c3197 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -972,7 +972,8 @@
     break;
 
   case TemplateArgument::Template:
-    VisitTemplateName(Arg.getAsTemplate());
+  case TemplateArgument::TemplateExpansion:
+    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
     break;
       
   case TemplateArgument::Declaration:
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 6eae6a4..de5531f 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -39,7 +39,10 @@
 
   case Template:
     return getAsTemplate().isDependent();
-      
+
+  case TemplateExpansion:
+    return true;
+
   case Declaration:
     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
       return DC->isDependentContext();
@@ -70,14 +73,15 @@
   case Declaration:
   case Integral:
   case Pack:    
+  case Template:
     return false;
       
+  case TemplateExpansion:
+    return true;
+      
   case Type:
     return isa<PackExpansionType>(getAsType());
-      
-  case Template:
-    return TemplateArg.PackExpansion;
-    
+          
   case Expression:
     return isa<PackExpansionExpr>(getAsExpr());
   }
@@ -90,6 +94,7 @@
   case Null:
   case Declaration:
   case Integral:
+  case TemplateExpansion:
     break;
 
   case Type:
@@ -98,8 +103,7 @@
     break;
 
   case Template:
-    if (!TemplateArg.PackExpansion && 
-        getAsTemplate().containsUnexpandedParameterPack())
+    if (getAsTemplate().containsUnexpandedParameterPack())
       return true;
     break;
         
@@ -135,20 +139,22 @@
     break;
 
   case Template:
-    ID.AddBoolean(TemplateArg.PackExpansion);
+  case TemplateExpansion: {
+    TemplateName Template = getAsTemplateOrTemplatePattern();
     if (TemplateTemplateParmDecl *TTP
           = dyn_cast_or_null<TemplateTemplateParmDecl>(
-                                       getAsTemplate().getAsTemplateDecl())) {
+                                                Template.getAsTemplateDecl())) {
       ID.AddBoolean(true);
       ID.AddInteger(TTP->getDepth());
       ID.AddInteger(TTP->getPosition());
       ID.AddBoolean(TTP->isParameterPack());
     } else {
       ID.AddBoolean(false);
-      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
-                      .getAsVoidPointer());
+      ID.AddPointer(Context.getCanonicalTemplateName(Template)
+                                                          .getAsVoidPointer());
     }
     break;
+  }
       
   case Integral:
     getAsIntegral()->Profile(ID);
@@ -173,13 +179,11 @@
   case Null:
   case Type:
   case Declaration:
-  case Expression:
+  case Expression:      
+  case Template:
+  case TemplateExpansion:
     return TypeOrValue == Other.TypeOrValue;
 
-  case Template:
-    return TemplateArg.Template == Other.TemplateArg.Template &&
-           TemplateArg.PackExpansion == Other.TemplateArg.PackExpansion;
-      
   case Integral:
     return getIntegralType() == Other.getIntegralType() &&
            *getAsIntegral() == *Other.getAsIntegral();
@@ -206,13 +210,14 @@
   case Expression:
     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
     
-  case Template:
-    return TemplateArgument(getAsTemplate(), false);
+  case TemplateExpansion:
+    return TemplateArgument(getAsTemplateOrTemplatePattern(), false);
     
   case Declaration:
   case Integral:
   case Pack:
   case Null:
+  case Template:
     return TemplateArgument();
   }
   
@@ -248,13 +253,15 @@
     break;
   }
     
-  case Template: {
+  case Template:
     getAsTemplate().print(Out, Policy);
-    if (TemplateArg.PackExpansion)
-      Out << "...";
     break;
-  }
-    
+
+  case TemplateExpansion:
+    getAsTemplateOrTemplatePattern().print(Out, Policy);
+    Out << "...";
+    break;
+      
   case Integral: {
     Out << getAsIntegral()->toString(10);
     break;
@@ -299,15 +306,18 @@
     else
       return SourceRange();
 
-  case TemplateArgument::Template: {
-    SourceLocation End = getTemplateNameLoc();
-    if (getTemplateEllipsisLoc().isValid())
-      End = getTemplateEllipsisLoc();
+  case TemplateArgument::Template:
     if (getTemplateQualifierRange().isValid())
-      return SourceRange(getTemplateQualifierRange().getBegin(), End);
-    return SourceRange(getTemplateNameLoc(), End);
-  }
-      
+      return SourceRange(getTemplateQualifierRange().getBegin(), 
+                         getTemplateNameLoc());
+    return SourceRange(getTemplateNameLoc());
+
+  case TemplateArgument::TemplateExpansion:
+    if (getTemplateQualifierRange().isValid())
+      return SourceRange(getTemplateQualifierRange().getBegin(), 
+                         getTemplateEllipsisLoc());
+    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
+
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
   case TemplateArgument::Null:
@@ -355,13 +365,14 @@
     Expr *Pattern = cast<PackExpansionExpr>(Argument.getAsExpr())->getPattern();
     return TemplateArgumentLoc(Pattern, Pattern);
   }
-      
-  case TemplateArgument::Template:
+
+  case TemplateArgument::TemplateExpansion:
     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
                                getTemplateQualifierRange(),
                                getTemplateNameLoc());
     
   case TemplateArgument::Declaration:
+  case TemplateArgument::Template:
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
   case TemplateArgument::Null:
@@ -389,11 +400,11 @@
     return DB << Arg.getAsIntegral()->toString(10);
       
   case TemplateArgument::Template:
-    DB << Arg.getAsTemplate();
-    if (Arg.isPackExpansion())
-      DB << "...";
-    return DB;
-      
+    return DB << Arg.getAsTemplate();
+
+  case TemplateArgument::TemplateExpansion:
+    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
+
   case TemplateArgument::Expression: {
     // This shouldn't actually ever happen, so it's okay that we're
     // regurgitating an expression here.