]> granicus.if.org Git - clang/commitdiff
When we're converting deduced template arguments to the type of the
authorDouglas Gregor <dgregor@apple.com>
Wed, 5 Jan 2011 20:52:18 +0000 (20:52 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 5 Jan 2011 20:52:18 +0000 (20:52 +0000)
corresponding template parameter, make sure that prior converted
template arguments are available for substitution.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122902 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateDeduction.cpp
test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp

index 5837ebd8e541ff636386bab8f7a00c54712925a9..f6dacc7ceae27ad38868052c80d7a2cf8a6dad42 100644 (file)
@@ -1402,12 +1402,19 @@ static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
     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 @@ FinishTemplateArgumentDeduction(Sema &S,
     // 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)) {
index 75181081ad908927b7b3f3f1fb317888a73164d3..5c0eb74875650985a69fbf0aec5e409c6232ca7d 100644 (file)
@@ -118,6 +118,33 @@ namespace Math {
   }
 }
 
+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;