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/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 3dac8a0..030a042 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -79,9 +79,6 @@
     
     // FIXME: Record occurrences of template template parameter packs.
 
-    // FIXME: Once we have pack expansions in the AST, block their
-    // traversal.
-
     //------------------------------------------------------------------------
     // Pruning the search for unexpanded parameter packs.
     //------------------------------------------------------------------------
@@ -299,14 +296,17 @@
                                   Arg.getLocation());
   }
 
-  case ParsedTemplateArgument::NonType:
-    Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
-      << 0;
-    return ParsedTemplateArgument();
-
+  case ParsedTemplateArgument::NonType: {
+    ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
+    if (Result.isInvalid())
+      return ParsedTemplateArgument();
+    
+    return ParsedTemplateArgument(Arg.getKind(), Result.get(), 
+                                  Arg.getLocation());
+  }
+    
   case ParsedTemplateArgument::Template:
-    Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
-      << 1;
+    Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
     return ParsedTemplateArgument();
   }
   llvm_unreachable("Unhandled template argument kind?");
@@ -352,6 +352,24 @@
   return TSResult;
 }
 
+ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
+  if (!Pattern)
+    return ExprError();
+  
+  // C++0x [temp.variadic]p5:
+  //   The pattern of a pack expansion shall name one or more
+  //   parameter packs that are not expanded by a nested pack
+  //   expansion.
+  if (!Pattern->containsUnexpandedParameterPack()) {
+    Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
+    << Pattern->getSourceRange();
+    return ExprError();
+  }
+  
+  // Create the pack expansion expression and source-location information.
+  return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
+                                               EllipsisLoc));
+}
 
 bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
                                            SourceRange PatternRange,