diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 716660244537b..0b6375001f532 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3140,13 +3140,15 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( return TemplateDeductionResult::Success; } -/// Perform template argument deduction to determine whether -/// the given template arguments match the given class template -/// partial specialization per C++ [temp.class.spec.match]. -TemplateDeductionResult -Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, - ArrayRef TemplateArgs, - TemplateDeductionInfo &Info) { +/// Perform template argument deduction to determine whether the given template +/// arguments match the given class or variable template partial specialization +/// per C++ [temp.class.spec.match]. +template +static std::enable_if_t::value, + TemplateDeductionResult> +DeduceTemplateArguments(Sema &S, T *Partial, + ArrayRef TemplateArgs, + TemplateDeductionInfo &Info) { if (Partial->isInvalidDecl()) return TemplateDeductionResult::Invalid; @@ -3158,25 +3160,25 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, // Unevaluated SFINAE context. EnterExpressionEvaluationContext Unevaluated( - *this, Sema::ExpressionEvaluationContext::Unevaluated); - SFINAETrap Trap(*this); + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap Trap(S); // This deduction has no relation to any outer instantiation we might be // performing. - LocalInstantiationScope InstantiationScope(*this); + LocalInstantiationScope InstantiationScope(S); SmallVector Deduced; Deduced.resize(Partial->getTemplateParameters()->size()); if (TemplateDeductionResult Result = ::DeduceTemplateArguments( - *this, Partial->getTemplateParameters(), + S, Partial->getTemplateParameters(), Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced, /*NumberOfArgumentsMustMatch=*/false); Result != TemplateDeductionResult::Success) return Result; SmallVector DeducedArgs(Deduced.begin(), Deduced.end()); - InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs, - Info); + Sema::InstantiatingTemplate Inst(S, Info.getLocation(), Partial, DeducedArgs, + Info); if (Inst.isInvalid()) return TemplateDeductionResult::InstantiationDepth; @@ -3184,64 +3186,25 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, return TemplateDeductionResult::SubstitutionFailure; TemplateDeductionResult Result; - runWithSufficientStackSpace(Info.getLocation(), [&] { - Result = ::FinishTemplateArgumentDeduction(*this, Partial, + S.runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = ::FinishTemplateArgumentDeduction(S, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); }); return Result; } -/// Perform template argument deduction to determine whether -/// the given template arguments match the given variable template -/// partial specialization per C++ [temp.class.spec.match]. +TemplateDeductionResult +Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, + ArrayRef TemplateArgs, + TemplateDeductionInfo &Info) { + return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info); +} TemplateDeductionResult Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, ArrayRef TemplateArgs, TemplateDeductionInfo &Info) { - if (Partial->isInvalidDecl()) - return TemplateDeductionResult::Invalid; - - // C++ [temp.class.spec.match]p2: - // A partial specialization matches a given actual template - // argument list if the template arguments of the partial - // specialization can be deduced from the actual template argument - // list (14.8.2). - - // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated( - *this, Sema::ExpressionEvaluationContext::Unevaluated); - SFINAETrap Trap(*this); - - // This deduction has no relation to any outer instantiation we might be - // performing. - LocalInstantiationScope InstantiationScope(*this); - - SmallVector Deduced; - Deduced.resize(Partial->getTemplateParameters()->size()); - if (TemplateDeductionResult Result = ::DeduceTemplateArguments( - *this, Partial->getTemplateParameters(), - Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced, - /*NumberOfArgumentsMustMatch=*/false); - Result != TemplateDeductionResult::Success) - return Result; - - SmallVector DeducedArgs(Deduced.begin(), Deduced.end()); - InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs, - Info); - if (Inst.isInvalid()) - return TemplateDeductionResult::InstantiationDepth; - - if (Trap.hasErrorOccurred()) - return TemplateDeductionResult::SubstitutionFailure; - - TemplateDeductionResult Result; - runWithSufficientStackSpace(Info.getLocation(), [&] { - Result = ::FinishTemplateArgumentDeduction(*this, Partial, - /*IsPartialOrdering=*/false, - TemplateArgs, Deduced, Info); - }); - return Result; + return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info); } /// Determine whether the given type T is a simple-template-id type.