Author: rsmith Date: Wed Feb 3 14:15:01 2016 New Revision: 259687 URL: http://llvm.org/viewvc/llvm-project?rev=259687&view=rev Log: Refactor conversion of deduced template arguments to reduce repetition.
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=259687&r1=259686&r2=259687&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Feb 3 14:15:01 2016 @@ -2060,11 +2060,46 @@ static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, - QualType NTTPType, - unsigned ArgumentPackIndex, 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.data(), Output.size()); + 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 = + getTrivialTemplateArgumentLoc(S, Arg, NTTPType, Info.getLocation()); + + // Check the template argument, converting it as necessary. + return S.CheckTemplateArgument( + Param, ArgLoc, Template, Template->getLocation(), + Template->getSourceRange().getEnd(), ArgumentPackIndex, Output, + InFunctionTemplate + ? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound + : Sema::CTAK_Deduced) + : Sema::CTAK_Specified); + }; + if (Arg.getKind() == TemplateArgument::Pack) { // This is a template argument pack, so check each of its arguments against // the template parameter. @@ -2075,39 +2110,25 @@ ConvertDeducedTemplateArgument(Sema &S, // checking logic has all of the prior template arguments available. DeducedTemplateArgument InnerArg(P); InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound()); - if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template, - NTTPType, PackedArgsBuilder.size(), - Info, InFunctionTemplate, Output)) + assert(InnerArg.getKind() != TemplateArgument::Pack && + "deduced nested pack"); + if (ConvertArg(InnerArg, PackedArgsBuilder.size())) return true; // Move the converted template argument into our argument pack. PackedArgsBuilder.push_back(Output.pop_back_val()); } + // FIXME: If the pack is empty and this is a template template parameter, + // we still need to substitute into the parameter itself. + // Create the resulting argument pack. Output.push_back( TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder)); return false; } - // 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 = getTrivialTemplateArgumentLoc(S, Arg, NTTPType, - Info.getLocation()); - - // Check the template argument, converting it as necessary. - return S.CheckTemplateArgument(Param, ArgLoc, - Template, - Template->getLocation(), - Template->getSourceRange().getEnd(), - ArgumentPackIndex, - Output, - InFunctionTemplate - ? (Arg.wasDeducedFromArrayBound() - ? Sema::CTAK_DeducedFromArrayBound - : Sema::CTAK_Deduced) - : Sema::CTAK_Specified); + return ConvertArg(Arg, 0); } /// Complete template argument deduction for a class template partial @@ -2138,34 +2159,8 @@ FinishTemplateArgumentDeduction(Sema &S, // We have deduced this argument, so it still needs to be // checked and converted. - - // 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, - 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, 0, Info, false, + Partial, Info, false, Builder)) { Info.Param = makeTemplateParameter(Param); // FIXME: These template arguments are temporary. Free them! @@ -2306,32 +2301,8 @@ static Sema::TemplateDeductionResult Fin // We have deduced this argument, so it still needs to be // checked and converted. - - // 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, - 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, - 0, Info, false, Builder)) { + if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial, + Info, false, Builder)) { Info.Param = makeTemplateParameter(Param); // FIXME: These template arguments are temporary. Free them! Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(), @@ -2804,36 +2775,11 @@ Sema::FinishTemplateArgumentDeduction(Fu } continue; } + // We have deduced this argument, so it still needs to be // checked and converted. - - // 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, - Builder.data(), Builder.size()); - NTTPType = 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(Context, - Builder.data(), - Builder.size())); - return TDK_SubstitutionFailure; - } - } - } - if (ConvertDeducedTemplateArgument(*this, Param, Deduced[I], - FunctionTemplate, NTTPType, 0, Info, + FunctionTemplate, Info, true, Builder)) { Info.Param = makeTemplateParameter(Param); // FIXME: These template arguments are temporary. Free them! _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits