[cfe-commits] r123210 - in /cfe/trunk: lib/AST/Decl.cpp lib/AST/Type.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp

Douglas Gregor dgregor at apple.com
Mon Jan 10 17:52:23 PST 2011


Author: dgregor
Date: Mon Jan 10 19:52:23 2011
New Revision: 123210

URL: http://llvm.org/viewvc/llvm-project?rev=123210&view=rev
Log:
Implement the last bullet of [temp.deduct.type]p5 and part of the last
sentence of [temp.deduct.call]p1, both of which concern the
non-deducibility of parameter packs not at the end of a
parameter-type-list. The latter isn't fully implemented yet; see the
new FIXME.

Added:
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=123210&r1=123209&r2=123210&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Jan 10 19:52:23 2011
@@ -1444,6 +1444,9 @@
 /// function parameters, if some of the parameters have default
 /// arguments (in C++) or the last parameter is a parameter pack.
 unsigned FunctionDecl::getMinRequiredArguments() const {
+  if (!getASTContext().getLangOptions().CPlusPlus)
+    return getNumParams();
+  
   unsigned NumRequiredArgs = getNumParams();  
   
   // If the last parameter is a parameter pack, we don't need an argument for 
@@ -1458,6 +1461,16 @@
          getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
     --NumRequiredArgs;
 
+  // We might have parameter packs before the end. These can't be deduced,
+  // but they can still handle multiple arguments.
+  unsigned ArgIdx = NumRequiredArgs;
+  while (ArgIdx > 0) {
+    if (getParamDecl(ArgIdx - 1)->isParameterPack())
+      NumRequiredArgs = ArgIdx;
+    
+    --ArgIdx;
+  }
+  
   return NumRequiredArgs;
 }
 

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=123210&r1=123209&r2=123210&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Jan 10 19:52:23 2011
@@ -1144,7 +1144,11 @@
 }
 
 bool FunctionProtoType::isTemplateVariadic() const {
-  return getNumArgs() && isa<PackExpansionType>(getArgType(getNumArgs() - 1));
+  for (unsigned ArgIdx = getNumArgs(); ArgIdx; --ArgIdx)
+    if (isa<PackExpansionType>(getArgType(ArgIdx - 1)))
+      return true;
+  
+  return false;
 }
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=123210&r1=123209&r2=123210&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Jan 10 19:52:23 2011
@@ -666,6 +666,13 @@
       continue;
     }
     
+    // C++0x [temp.deduct.type]p5:
+    //   The non-deduced contexts are:
+    //     - A function parameter pack that does not occur at the end of the 
+    //       parameter-declaration-clause.
+    if (ParamIdx + 1 < NumParams)
+      return Sema::TDK_Success;
+
     // C++0x [temp.deduct.type]p10:
     //   If the parameter-declaration corresponding to Pi is a function 
     //   parameter pack, then the type of its declarator- id is compared with
@@ -2483,7 +2490,12 @@
     //   the call is compared with the type P of the declarator-id of the 
     //   function parameter pack. Each comparison deduces template arguments 
     //   for subsequent positions in the template parameter packs expanded by 
-    //   the function parameter pack.
+    //   the function parameter pack. For a function parameter pack that does
+    //   not occur at the end of the parameter-declaration-list, the type of 
+    //   the parameter pack is a non-deduced context.
+    if (ParamIdx + 1 < NumParams)
+      break;
+    
     QualType ParamPattern = ParamExpansion->getPattern();
     llvm::SmallVector<unsigned, 2> PackIndices;
     {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=123210&r1=123209&r2=123210&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jan 10 19:52:23 2011
@@ -1894,6 +1894,8 @@
         // Parameter pack: make the instantiation an argument pack.
         SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(
                                                                       OldParam);
+        // FIXME: Variadic templates. Figure out how many arguments are in the
+        // expansion of OldParam, so we don't gobble all of the arguments here.
         while (NewIdx < NumNewParams) {
           ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++);
           Params.push_back(NewParam);

Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp?rev=123210&r1=123209&r2=123210&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp Mon Jan 10 19:52:23 2011
@@ -74,3 +74,18 @@
 
   first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
 }
+
+// For a function parameter pack that does not occur at the end of the
+// parameter-declaration-list, the type of the parameter pack is a
+// non-deduced context.
+// FIXME: We're not in a position to handle this yet.
+#if 0
+template<typename ...Types> struct tuple { };
+
+template<typename ...Types>
+void pack_not_at_end(tuple<Types...>, Types... values, int);
+
+void test_pack_not_at_end(tuple<int*, double*> t2) {
+  pack_not_at_end(t2, 0, 0, 0);
+}
+#endif

Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp?rev=123210&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp Mon Jan 10 19:52:23 2011
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// FIXME: More bullets to go!
+
+template<typename T, typename U>
+struct has_nondeduced_pack_test {
+  static const bool value = false;
+};
+
+template<typename R, typename FirstType, typename ...Types>
+struct has_nondeduced_pack_test<R(FirstType, Types..., int), 
+                                R(FirstType, Types...)> {
+  static const bool value = true;
+};
+
+// - A function parameter pack that does not occur at the end of the
+//   parameter-declaration-clause.
+int check_nondeduced_pack_test0[
+                   has_nondeduced_pack_test<int(float, double, int),
+                                            int(float, double)>::value? 1 : -1];
+
+





More information about the cfe-commits mailing list