diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-05 20:52:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-05 20:52:18 +0000 |
commit | d53e16abd1dcaa2942d5183f48e7f63d0e75b35a (patch) | |
tree | 9511181c171a8ec025a39e323ea90958e4fc8058 | |
parent | b1fa3dc2f914aaa8b5a851c6b5115ec239d20495 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122902 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 30 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp | 27 |
2 files changed, 54 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 5837ebd8e5..f6dacc7cea 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -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)) { diff --git a/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp index 75181081ad..5c0eb74875 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp @@ -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; |