[cfe-commits] r123188 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp lib/Sema/TreeTransform.h test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp

Douglas Gregor dgregor at apple.com
Mon Jan 10 12:53:55 PST 2011


Author: dgregor
Date: Mon Jan 10 14:53:55 2011
New Revision: 123188

URL: http://llvm.org/viewvc/llvm-project?rev=123188&view=rev
Log:
Implement more of C++0x [temp.arg.explicit]p9, allowing extension of
pack expansions in template argument lists and function parameter
lists. The implementation of this paragraph should be complete
*except* for cases where we're substituting into one of the unexpanded
packs in a pack expansion; that's a general issue I haven't solved yet.


Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=123188&r1=123187&r2=123188&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Jan 10 14:53:55 2011
@@ -636,8 +636,7 @@
   if (NumParams != NumArgs &&
       !(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) &&
       !(NumArgs && isa<PackExpansionType>(Args[NumArgs - 1])))
-    return NumArgs < NumParams ? Sema::TDK_TooFewArguments 
-                               : Sema::TDK_TooManyArguments;
+    return Sema::TDK_NonDeducedMismatch;
   
   // C++0x [temp.deduct.type]p10:
   //   Similarly, if P has a form that contains (T), then each parameter type 
@@ -654,7 +653,7 @@
       
       // Make sure we have an argument.
       if (ArgIdx >= NumArgs)
-        return Sema::TDK_TooFewArguments;
+        return Sema::TDK_NonDeducedMismatch;
           
       if (Sema::TemplateDeductionResult Result
           = DeduceTemplateArguments(S, TemplateParams,
@@ -736,7 +735,7 @@
   
   // Make sure we don't have any extra arguments.
   if (ArgIdx < NumArgs)
-    return Sema::TDK_TooManyArguments;
+    return Sema::TDK_NonDeducedMismatch;
   
   return Sema::TDK_Success;
 }
@@ -788,10 +787,8 @@
 
   // If the parameter type is not dependent, there is nothing to deduce.
   if (!Param->isDependentType()) {
-    if (!(TDF & TDF_SkipNonDependent) && Param != Arg) {
-      
+    if (!(TDF & TDF_SkipNonDependent) && Param != Arg)
       return Sema::TDK_NonDeducedMismatch;
-    }
     
     return Sema::TDK_Success;
   }
@@ -1365,7 +1362,7 @@
       
       // Check whether we have enough arguments.
       if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
-        return NumberOfArgumentsMustMatch? Sema::TDK_TooFewArguments 
+        return NumberOfArgumentsMustMatch? Sema::TDK_NonDeducedMismatch
                                          : Sema::TDK_Success;
       
       // Perform deduction for this Pi/Ai pair.
@@ -1459,7 +1456,7 @@
   // If there is an argument remaining, then we had too many arguments.
   if (NumberOfArgumentsMustMatch &&
       hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
-    return Sema::TDK_TooManyArguments;
+    return Sema::TDK_NonDeducedMismatch;
   
   return Sema::TDK_Success;
 }

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=123188&r1=123187&r2=123188&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jan 10 14:53:55 2011
@@ -2850,7 +2850,20 @@
         Outputs.addArgument(Out);
       }
       
-      // FIXME: Variadic templates retain expansion!
+      // If we're supposed to retain a pack expansion, do so by temporarily
+      // forgetting the partially-substituted parameter pack.
+      if (RetainExpansion) {
+        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+        
+        if (getDerived().TransformTemplateArgument(Pattern, Out))
+          return true;
+        
+        Out = getDerived().RebuildPackExpansion(Out, Ellipsis);
+        if (Out.getArgument().isNull())
+          return true;
+        
+        Outputs.addArgument(Out);
+      }
       
       continue;
     }
@@ -3564,7 +3577,18 @@
         continue;
       }
       
-      // FIXME: Variadic templates retain pack expansion!
+      // If we're supposed to retain a pack expansion, do so by temporarily
+      // forgetting the partially-substituted parameter pack.
+      if (RetainExpansion) {
+        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+        QualType NewType = getDerived().TransformType(Pattern);
+        if (NewType.isNull())
+          return true;
+        
+        OutParamTypes.push_back(NewType);
+        if (PVars)
+          PVars->push_back(0);
+      }
 
       // We'll substitute the parameter now without expanding the pack 
       // expansion.

Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp?rev=123188&r1=123187&r2=123188&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp Mon Jan 10 14:53:55 2011
@@ -43,3 +43,26 @@
   double *dp1 = first_arg<>(dp);
 }
 
+template<typename ...Types> 
+struct tuple { };
+
+template<typename ...Types>
+void accept_tuple(tuple<Types...>);
+
+void test_explicit_spec_extension_targs(tuple<int, float, double> t3) {
+  accept_tuple(t3);
+  accept_tuple<int, float, double>(t3);
+  accept_tuple<int>(t3);
+  accept_tuple<int, float>(t3);
+}
+
+template<typename R, typename ...ParmTypes>
+void accept_function_ptr(R(*)(ParmTypes...));
+
+void test_explicit_spec_extension_funcparms(int (*f3)(int, float, double)) {
+  accept_function_ptr(f3);
+  accept_function_ptr<int>(f3);
+  accept_function_ptr<int, int>(f3);
+  accept_function_ptr<int, int, float>(f3);
+  accept_function_ptr<int, int, float, double>(f3);
+}





More information about the cfe-commits mailing list