r290310 - Only substitute into type of non-type template parameter once, rather than

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 21 19:52:37 PST 2016


Author: rsmith
Date: Wed Dec 21 21:52:37 2016
New Revision: 290310

URL: http://llvm.org/viewvc/llvm-project?rev=290310&view=rev
Log:
Only substitute into type of non-type template parameter once, rather than
twice, in finalization of template argumetn deduction.

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=290310&r1=290309&r2=290310&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Dec 21 21:52:37 2016
@@ -2059,7 +2059,8 @@ static bool isSameTemplateArg(ASTContext
 ///
 /// \param NTTPType For a declaration template argument, the type of
 /// the non-type template parameter that corresponds to this template
-/// argument.
+/// argument. Can be null if no type sugar is available to add to the
+/// type from the template argument.
 ///
 /// \param Loc The source location to use for the resulting template
 /// argument.
@@ -2075,12 +2076,16 @@ Sema::getTrivialTemplateArgumentLoc(cons
         Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
 
   case TemplateArgument::Declaration: {
+    if (NTTPType.isNull())
+      NTTPType = Arg.getParamTypeForDecl();
     Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
                   .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
   case TemplateArgument::NullPtr: {
+    if (NTTPType.isNull())
+      NTTPType = Arg.getNullPtrType();
     Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
                   .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
@@ -2131,31 +2136,13 @@ ConvertDeducedTemplateArgument(Sema &S,
                                TemplateDeductionInfo &Info,
                                bool InFunctionTemplate,
                                SmallVectorImpl<TemplateArgument> &Output) {
-  // First, for a non-type template parameter type that is
-  // initialized by a declaration, we need the type of the
-  // corresponding non-type template parameter.
-  QualType NTTPType;
-  if (NonTypeTemplateParmDecl *NTTP =
-          dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-    NTTPType = NTTP->getType();
-    if (NTTPType->isDependentType()) {
-      TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
-      NTTPType = S.SubstType(NTTPType,
-                             MultiLevelTemplateArgumentList(TemplateArgs),
-                             NTTP->getLocation(),
-                             NTTP->getDeclName());
-      if (NTTPType.isNull())
-        return true;
-    }
-  }
-
   auto ConvertArg = [&](DeducedTemplateArgument Arg,
                         unsigned ArgumentPackIndex) {
     // Convert the deduced template argument into a template
     // argument that we can check, almost as if the user had written
     // the template argument explicitly.
     TemplateArgumentLoc ArgLoc =
-        S.getTrivialTemplateArgumentLoc(Arg, NTTPType, Info.getLocation());
+        S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation());
 
     // Check the template argument, converting it as necessary.
     return S.CheckTemplateArgument(
@@ -2187,22 +2174,28 @@ ConvertDeducedTemplateArgument(Sema &S,
     }
 
     // If the pack is empty, we still need to substitute into the parameter
-    // itself, in case that substitution fails. For non-type parameters, we did
-    // this above. For type parameters, no substitution is ever required.
-    auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param);
-    if (TTP && PackedArgsBuilder.empty()) {
-      // Set up a template instantiation context.
+    // itself, in case that substitution fails.
+    if (PackedArgsBuilder.empty()) {
       LocalInstantiationScope Scope(S);
-      Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
-                                       TTP, Output,
-                                       Template->getSourceRange());
-      if (Inst.isInvalid())
-        return true;
-
       TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
-      if (!S.SubstDecl(TTP, S.CurContext,
-                       MultiLevelTemplateArgumentList(TemplateArgs)))
-        return true;
+      MultiLevelTemplateArgumentList Args(TemplateArgs);
+
+      if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+        Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+                                         NTTP, Output,
+                                         Template->getSourceRange());
+        if (Inst.isInvalid() || 
+            S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
+                        NTTP->getDeclName()).isNull())
+          return true;
+      } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+        Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+                                         TTP, Output,
+                                         Template->getSourceRange());
+        if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
+          return true;
+      }
+      // For type parameters, no substitution is ever required.
     }
 
     // Create the resulting argument pack.




More information about the cfe-commits mailing list