[cfe-commits] r73281 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/variadic-class-template-2.cpp

Anders Carlsson andersca at mac.com
Fri Jun 12 19:08:00 PDT 2009


Author: andersca
Date: Fri Jun 12 21:08:00 2009
New Revision: 73281

URL: http://llvm.org/viewvc/llvm-project?rev=73281&view=rev
Log:
More work on type parameter packs.

Added:
    cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=73281&r1=73280&r2=73281&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Fri Jun 12 21:08:00 2009
@@ -87,7 +87,7 @@
   /// \btief Returns the minimum number of arguments needed to form a
   /// template specialization. This may be fewer than the number of
   /// template parameters, if some of the parameters have default
-  /// arguments.
+  /// arguments or if there is a parameter pack.
   unsigned getMinRequiredArguments() const;
 
   SourceLocation getTemplateLoc() const { return TemplateLoc; }
@@ -610,7 +610,7 @@
     assert(!isAddingFromParameterPack() && 
            "Size is not valid when adding from a parameter pack");
     
-    return Args.size(); 
+    return Indices.size() / 2;
   }
   
   size_t flatSize() const { return Args.size(); }
@@ -770,6 +770,7 @@
   static void 
   Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs, 
           unsigned NumTemplateArgs) {
+    ID.AddInteger(NumTemplateArgs);
     for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
       TemplateArgs[Arg].Profile(ID);
   }

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=73281&r1=73280&r2=73281&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Fri Jun 12 21:08:00 2009
@@ -50,7 +50,9 @@
       ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
   while (Param != ParamBegin) {
     --Param;
-    if (!(isa<TemplateTypeParmDecl>(*Param) && 
+    
+    if (!(*Param)->isTemplateParameterPack() &&
+        !(isa<TemplateTypeParmDecl>(*Param) && 
           cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
         !(isa<NonTypeTemplateParmDecl>(*Param) &&
           cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=73281&r1=73280&r2=73281&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jun 12 21:08:00 2009
@@ -1016,7 +1016,10 @@
   unsigned NumArgs = NumTemplateArgs;
   bool Invalid = false;
 
-  if (NumArgs > NumParams ||
+  bool HasParameterPack = 
+    NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
+  
+  if ((NumArgs > NumParams && !HasParameterPack) ||
       NumArgs < Params->getMinRequiredArguments()) {
     // FIXME: point at either the first arg beyond what we can handle,
     // or the '>', depending on whether we have too many or too few
@@ -1050,6 +1053,13 @@
       // Retrieve the default template argument from the template
       // parameter.
       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
+        if (TTP->isParameterPack()) {
+          // We have an empty parameter pack.
+          Converted.BeginParameterPack();
+          Converted.EndParameterPack();
+          break;
+        }
+        
         if (!TTP->hasDefaultArgument())
           break;
 
@@ -1112,8 +1122,19 @@
 
 
     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
-      if (CheckTemplateTypeArgument(TTP, Arg, Converted))
-        Invalid = true;
+      if (TTP->isParameterPack()) {
+        Converted.BeginParameterPack();
+        // Check all the remaining arguments (if any).
+        for (; ArgIdx < NumArgs; ++ArgIdx) {
+          if (CheckTemplateTypeArgument(TTP, TemplateArgs[ArgIdx], Converted))
+            Invalid = true;
+        }
+        
+        Converted.EndParameterPack();
+      } else {
+        if (CheckTemplateTypeArgument(TTP, Arg, Converted))
+          Invalid = true;
+      }
     } else if (NonTypeTemplateParmDecl *NTTP 
                  = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       // Check non-type template parameters.

Added: cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp?rev=73281&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp (added)
+++ cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp Fri Jun 12 21:08:00 2009
@@ -0,0 +1,19 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+// Type parameters packs
+template <typename ...> struct TS1 {}; // expected-note{{template parameter is declared here}}
+template struct TS1<>;
+template struct TS1<int>;
+template struct TS1<int, int>;
+template struct TS1<int, 10>; // expected-error{{template argument for template type parameter must be a type}}
+
+template <typename, typename ...> struct TS2 {}; // expected-note{{template is declared here}}
+template struct TS2<>; // expected-error{{too few template arguments for class template 'TS2'}}
+template struct TS2<int>;
+template struct TS2<int, int>;
+
+template <typename = int, typename ...> struct TS3 {}; // expected-note{{template parameter is declared here}}
+template struct TS3<>; // expected-note{{previous explicit instantiation is here}}
+template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3<>'}}
+template struct TS3<int, int>;
+template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}}





More information about the cfe-commits mailing list