Add an AST representation for non-type template parameter
packs, e.g.,

  template<typename T, unsigned ...Dims> struct multi_array;

along with semantic analysis support for finding unexpanded non-type
template parameter packs in types, expressions, and so on.

Template instantiation involving non-type template parameter packs
probably doesn't work yet. That'll come soon.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122527 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index d9c7e72..fe30ba5 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -63,8 +63,21 @@
       return true;
     }
 
-    // FIXME: Record occurrences of non-type and template template
-    // parameter packs.
+    /// \brief Record occurrences of (FIXME: function and) non-type template
+    /// parameter packs in an expression.
+    bool VisitDeclRefExpr(DeclRefExpr *E) {
+      if (NonTypeTemplateParmDecl *NTTP 
+                            = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
+        if (NTTP->isParameterPack())
+          Unexpanded.push_back(std::make_pair(NTTP, E->getLocation()));
+      }
+      
+      // FIXME: Function parameter packs.
+      
+      return true;
+    }
+    
+    // FIXME: Record occurrences of template template parameter packs.
 
     // FIXME: Once we have pack expansions in the AST, block their
     // traversal.
@@ -95,8 +108,8 @@
     /// \brief Suppress traversel into types with location information
     /// that do not contain unexpanded parameter packs.
     bool TraverseTypeLoc(TypeLoc TL) {
-      if (!TL.getType().isNull() && TL.
-          getType()->containsUnexpandedParameterPack())
+      if (!TL.getType().isNull() && 
+          TL.getType()->containsUnexpandedParameterPack())
         return inherited::TraverseTypeLoc(TL);
 
       return true;