Implement support for pack expansions whose pattern is a non-type
template argument (described by an expression, of course). For
example:

  template<int...> struct int_tuple { };

  template<int ...Values>
  struct square {
    typedef int_tuple<(Values*Values)...> type;
  };

It also lays the foundation for pack expansions in an initializer-list.
  



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122751 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index cbd33f2..4592e5f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1025,3 +1025,15 @@
 Stmt::child_iterator CXXNoexceptExpr::child_end() {
   return child_iterator(&Operand + 1);
 }
+
+SourceRange PackExpansionExpr::getSourceRange() const {
+  return SourceRange(Pattern->getLocStart(), EllipsisLoc);
+}
+
+Stmt::child_iterator PackExpansionExpr::child_begin() {
+  return child_iterator(&Pattern);
+}
+
+Stmt::child_iterator PackExpansionExpr::child_end() {
+  return child_iterator(&Pattern + 1);
+}
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 4cf393d..f437804 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -304,6 +304,9 @@
       
   case Expr::CXXUuidofExprClass:
     return Cl::CL_LValue;
+      
+  case Expr::PackExpansionExprClass:
+    return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());
   }
   
   llvm_unreachable("unhandled expression kind in classification");
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 8797880..c39b398 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2634,6 +2634,7 @@
   case Expr::BlockDeclRefExprClass:
   case Expr::NoStmtClass:
   case Expr::OpaqueValueExprClass:
+  case Expr::PackExpansionExprClass:
     return ICEDiag(2, E->getLocStart());
 
   case Expr::GNUNullExprClass:
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 6bbe8f9..cc90526 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1246,6 +1246,11 @@
   OS << ")";
 }
 
+void StmtPrinter::VisitPackExpansionExpr(clang::PackExpansionExpr *E) {
+  PrintExpr(E->getPattern());
+  OS << "...";
+}
+
 // Obj-C
 
 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 66c067b..820eb06 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -832,6 +832,10 @@
   VisitExpr(S);
 }
 
+void StmtProfiler::VisitPackExpansionExpr(PackExpansionExpr *S) {
+  VisitExpr(S);
+}
+
 void StmtProfiler::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   VisitExpr(E);  
 }
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 04e8a38..c971519 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -72,15 +73,14 @@
     return false;
       
   case Type:
-    return llvm::isa<PackExpansionType>(getAsType());
+    return isa<PackExpansionType>(getAsType());
       
   case Template:
     // FIXME: Template template pack expansions.
     break;
     
   case Expression:
-    // FIXME: Expansion pack expansions.
-    break;  
+    return isa<PackExpansionExpr>(getAsExpr());
   }
   
   return false;
@@ -199,9 +199,11 @@
       return getAsType()->getAs<PackExpansionType>()->getPattern();
       
     case Expression:
+      return cast<PackExpansionExpr>(getAsExpr())->getPattern();
+      
     case Template:
       // FIXME: Variadic templates.
-      llvm_unreachable("Expression and template pack expansions unsupported");
+      llvm_unreachable("Template pack expansions unsupported");
       
     case Declaration:
     case Integral:
@@ -343,10 +345,14 @@
                                PatternTSInfo);
   }
       
-  case TemplateArgument::Expression:
+  case TemplateArgument::Expression: {
+    Expr *Pattern = cast<PackExpansionExpr>(Argument.getAsExpr())->getPattern();
+    return TemplateArgumentLoc(Pattern, Pattern);
+  }
+      
   case TemplateArgument::Template:
     // FIXME: Variadic templates.
-      llvm_unreachable("Expression and template pack expansions unsupported");
+      llvm_unreachable("Template pack expansions unsupported");
     
   case TemplateArgument::Declaration:
   case TemplateArgument::Integral: