[cfe-commits] r102600 - /cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Douglas Gregor dgregor at apple.com
Wed Apr 28 23:21:43 PDT 2010


Author: dgregor
Date: Thu Apr 29 01:21:43 2010
New Revision: 102600

URL: http://llvm.org/viewvc/llvm-project?rev=102600&view=rev
Log:
For template argument deduction from class template partial
specializations, separate out the deduction part from the checking and
substitution of the deduced arguments.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=102600&r1=102599&r2=102600&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Apr 29 01:21:43 2010
@@ -961,34 +961,18 @@
   return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
 }
 
-/// \brief Perform template argument deduction to determine whether
-/// the given template arguments match the given class template
-/// partial specialization per C++ [temp.class.spec.match].
-Sema::TemplateDeductionResult
-Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
-                              const TemplateArgumentList &TemplateArgs,
-                              TemplateDeductionInfo &Info) {
-  // C++ [temp.class.spec.match]p2:
-  //   A partial specialization matches a given actual template
-  //   argument list if the template arguments of the partial
-  //   specialization can be deduced from the actual template argument
-  //   list (14.8.2).
-  SFINAETrap Trap(*this);
-  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
-  Deduced.resize(Partial->getTemplateParameters()->size());
-  if (TemplateDeductionResult Result
-        = ::DeduceTemplateArguments(*this,
-                                    Partial->getTemplateParameters(),
-                                    Partial->getTemplateArgs(),
-                                    TemplateArgs, Info, Deduced))
-    return Result;
-
-  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
-                             Deduced.data(), Deduced.size());
-  if (Inst)
-    return TDK_InstantiationDepth;
-
-  ContextRAII SavedContext(*this, Partial);
+/// Complete template argument deduction for a class template partial
+/// specialization.
+static Sema::TemplateDeductionResult
+FinishTemplateArgumentDeduction(Sema &S, 
+                                ClassTemplatePartialSpecializationDecl *Partial,
+                                const TemplateArgumentList &TemplateArgs,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                Sema::TemplateDeductionInfo &Info) {
+  // Trap errors.
+  Sema::SFINAETrap Trap(S);
+  
+  Sema::ContextRAII SavedContext(S, Partial);
 
   // C++ [temp.deduct.type]p2:
   //   [...] or if any template argument remains neither deduced nor
@@ -998,18 +982,19 @@
   for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
     if (Deduced[I].isNull()) {
       Decl *Param
-        = const_cast<NamedDecl *>(
+      = const_cast<NamedDecl *>(
                                 Partial->getTemplateParameters()->getParam(I));
       Info.Param = makeTemplateParameter(Param);
-      return TDK_Incomplete;
+      return Sema::TDK_Incomplete;
     }
-
+    
     Builder.Append(Deduced[I]);
   }
-
+  
   // Form the template argument list from the deduced template arguments.
   TemplateArgumentList *DeducedArgumentList
-    = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+    = new (S.Context) TemplateArgumentList(S.Context, Builder, 
+                                           /*TakeArgs=*/true);
   Info.reset(DeducedArgumentList);
 
   // Substitute the deduced template arguments into the template
@@ -1019,7 +1004,7 @@
   // to the class template.
   // FIXME: Do we have to correct the types of deduced non-type template 
   // arguments (in particular, integral non-type template arguments?).
-  Sema::LocalInstantiationScope InstScope(*this);
+  Sema::LocalInstantiationScope InstScope(S);
   ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
   const TemplateArgumentLoc *PartialTemplateArgs
     = Partial->getTemplateArgsAsWritten();
@@ -1032,11 +1017,11 @@
     Decl *Param = const_cast<NamedDecl *>(
                     ClassTemplate->getTemplateParameters()->getParam(I));
     TemplateArgumentLoc InstArg;
-    if (Subst(PartialTemplateArgs[I], InstArg,
-              MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
+    if (S.Subst(PartialTemplateArgs[I], InstArg,
+                MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
       Info.Param = makeTemplateParameter(Param);
       Info.FirstArg = PartialTemplateArgs[I].getArgument();
-      return TDK_SubstitutionFailure;
+      return Sema::TDK_SubstitutionFailure;
     }
     InstArgs.addArgument(InstArg);
   }
@@ -1044,10 +1029,10 @@
   TemplateArgumentListBuilder ConvertedInstArgs(
                                   ClassTemplate->getTemplateParameters(), N);
 
-  if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
+  if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
                                 InstArgs, false, ConvertedInstArgs)) {
     // FIXME: fail with more useful information?
-    return TDK_SubstitutionFailure;
+    return Sema::TDK_SubstitutionFailure;
   }
   
   for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
@@ -1063,26 +1048,60 @@
       Expr *InstExpr = InstArg.getAsExpr();
       if (NonTypeTemplateParmDecl *NTTP
             = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-        if (CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
+        if (S.CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
           Info.Param = makeTemplateParameter(Param);
           Info.FirstArg = Partial->getTemplateArgs()[I];
-          return TDK_SubstitutionFailure;
+          return Sema::TDK_SubstitutionFailure;
         }
       }
     }
 
-    if (!isSameTemplateArg(Context, TemplateArgs[I], InstArg)) {
+    if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
       Info.Param = makeTemplateParameter(Param);
       Info.FirstArg = TemplateArgs[I];
       Info.SecondArg = InstArg;
-      return TDK_NonDeducedMismatch;
+      return Sema::TDK_NonDeducedMismatch;
     }
   }
 
   if (Trap.hasErrorOccurred())
-    return TDK_SubstitutionFailure;
+    return Sema::TDK_SubstitutionFailure;
 
-  return TDK_Success;
+  return Sema::TDK_Success;
+}
+
+/// \brief Perform template argument deduction to determine whether
+/// the given template arguments match the given class template
+/// partial specialization per C++ [temp.class.spec.match].
+Sema::TemplateDeductionResult
+Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
+                              const TemplateArgumentList &TemplateArgs,
+                              TemplateDeductionInfo &Info) {
+  // C++ [temp.class.spec.match]p2:
+  //   A partial specialization matches a given actual template
+  //   argument list if the template arguments of the partial
+  //   specialization can be deduced from the actual template argument
+  //   list (14.8.2).
+  SFINAETrap Trap(*this);
+  llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
+  Deduced.resize(Partial->getTemplateParameters()->size());
+  if (TemplateDeductionResult Result
+        = ::DeduceTemplateArguments(*this,
+                                    Partial->getTemplateParameters(),
+                                    Partial->getTemplateArgs(),
+                                    TemplateArgs, Info, Deduced))
+    return Result;
+
+  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
+                             Deduced.data(), Deduced.size());
+  if (Inst)
+    return TDK_InstantiationDepth;
+
+  if (Trap.hasErrorOccurred())
+    return Sema::TDK_SubstitutionFailure;
+ 
+  return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs, 
+                                           Deduced, Info);
 }
 
 /// \brief Determine whether the given type T is a simple-template-id type.
@@ -2341,12 +2360,15 @@
   //       whose type is a class template specialization with the template 
   //       arguments of the second partial specialization.
   //
-  // Rather than synthesize function templates, we merely perform the 
-  // equivalent partial ordering by performing deduction directly on the
-  // template arguments of the class template partial specializations. This
-  // computation is slightly simpler than the general problem of function
-  // template partial ordering, because class template partial specializations
-  // are more constrained. We know that every template parameter is deduc
+  // Rather than synthesize function templates, we merely perform the
+  // equivalent partial ordering by performing deduction directly on
+  // the template arguments of the class template partial
+  // specializations. This computation is slightly simpler than the
+  // general problem of function template partial ordering, because
+  // class template partial specializations are more constrained. We
+  // know that every template parameter is deducible from the class
+  // template partial specialization's template arguments, for
+  // example.
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
   Sema::TemplateDeductionInfo Info(Context, Loc);
 





More information about the cfe-commits mailing list