[cfe-commits] r122902 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp

Douglas Gregor dgregor at apple.com
Wed Jan 5 12:52:18 PST 2011


Author: dgregor
Date: Wed Jan  5 14:52:18 2011
New Revision: 122902

URL: http://llvm.org/viewvc/llvm-project?rev=122902&view=rev
Log:
When we're converting deduced template arguments to the type of the
corresponding template parameter, make sure that prior converted
template arguments are available for substitution.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=122902&r1=122901&r2=122902&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Jan  5 14:52:18 2011
@@ -1402,12 +1402,19 @@
     for (TemplateArgument::pack_iterator PA = Arg.pack_begin(), 
          PAEnd = Arg.pack_end();
          PA != PAEnd; ++PA) {
+      // When converting the deduced template argument, append it to the
+      // general output list. We need to do this so that the template argument
+      // checking logic has all of the prior template arguments available.
       DeducedTemplateArgument InnerArg(*PA);
       InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
       if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template, 
                                          NTTPType, Info, 
-                                         InFunctionTemplate, PackedArgsBuilder))
+                                         InFunctionTemplate, Output))
         return true;
+      
+      // Move the converted template argument into our argument pack.
+      PackedArgsBuilder.push_back(Output.back());
+      Output.pop_back();
     }
     
     // Create the resulting argument pack.
@@ -1472,9 +1479,26 @@
     // corresponding non-type template parameter.
     QualType NTTPType;
     if (NonTypeTemplateParmDecl *NTTP 
-                                     = dyn_cast<NonTypeTemplateParmDecl>(Param))
+                                  = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
       NTTPType = NTTP->getType();
-    
+      if (NTTPType->isDependentType()) {
+        TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, 
+                                          Builder.data(), Builder.size());
+        NTTPType = S.SubstType(NTTPType,
+                               MultiLevelTemplateArgumentList(TemplateArgs),
+                               NTTP->getLocation(),
+                               NTTP->getDeclName());
+        if (NTTPType.isNull()) {
+          Info.Param = makeTemplateParameter(Param);
+          // FIXME: These template arguments are temporary. Free them!
+          Info.reset(TemplateArgumentList::CreateCopy(S.Context, 
+                                                      Builder.data(), 
+                                                      Builder.size()));
+          return Sema::TDK_SubstitutionFailure;
+        }
+      }
+    }
+
     if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
                                        Partial, NTTPType, Info, false,
                                        Builder)) {

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp?rev=122902&r1=122901&r2=122902&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp Wed Jan  5 14:52:18 2011
@@ -118,6 +118,33 @@
   }
 }
 
+namespace ListMath {
+  template<typename T, T ... V> struct add;
+
+  template<typename T, T i, T ... V>
+  struct add<T, i, V...> {
+    static const T value = i + add<T, V...>::value; 
+  };
+
+  template<typename T>
+  struct add<T> {
+    static const T value = T(); 
+  };
+
+  template<typename T, T ... V>
+  struct List {
+    struct sum {
+      static const T value = add<T, V...>::value;
+    };
+  };
+
+  template<int ... V>
+  struct ListI : public List<int, V...> {
+  };
+
+  int check0[ListI<1, 2, 3>::sum::value == 6? 1 : -1];
+}
+
 namespace Indices {
   template<unsigned I, unsigned N, typename IntTuple>
   struct build_indices_impl;





More information about the cfe-commits mailing list