diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 32f7202f68958..ed933f27f8df6 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -353,6 +353,72 @@ class PreferredTypeBuilder { llvm::function_ref ComputeType; }; +/// Describes the result of template argument deduction. +/// +/// The TemplateDeductionResult enumeration describes the result of +/// template argument deduction, as returned from +/// DeduceTemplateArguments(). The separate TemplateDeductionInfo +/// structure provides additional information about the results of +/// template argument deduction, e.g., the deduced template argument +/// list (if successful) or the specific template parameters or +/// deduced arguments that were involved in the failure. +enum class TemplateDeductionResult { + /// Template argument deduction was successful. + Success = 0, + /// The declaration was invalid; do nothing. + Invalid, + /// Template argument deduction exceeded the maximum template + /// instantiation depth (which has already been diagnosed). + InstantiationDepth, + /// Template argument deduction did not deduce a value + /// for every template parameter. + Incomplete, + /// Template argument deduction did not deduce a value for every + /// expansion of an expanded template parameter pack. + IncompletePack, + /// Template argument deduction produced inconsistent + /// deduced values for the given template parameter. + Inconsistent, + /// Template argument deduction failed due to inconsistent + /// cv-qualifiers on a template parameter type that would + /// otherwise be deduced, e.g., we tried to deduce T in "const T" + /// but were given a non-const "X". + Underqualified, + /// Substitution of the deduced template argument values + /// resulted in an error. + SubstitutionFailure, + /// After substituting deduced template arguments, a dependent + /// parameter type did not match the corresponding argument. + DeducedMismatch, + /// After substituting deduced template arguments, an element of + /// a dependent parameter type did not match the corresponding element + /// of the corresponding argument (when deducing from an initializer list). + DeducedMismatchNested, + /// A non-depnedent component of the parameter did not match the + /// corresponding component of the argument. + NonDeducedMismatch, + /// When performing template argument deduction for a function + /// template, there were too many call arguments. + TooManyArguments, + /// When performing template argument deduction for a function + /// template, there were too few call arguments. + TooFewArguments, + /// The explicitly-specified template arguments were not valid + /// template arguments for the given template. + InvalidExplicitArguments, + /// Checking non-dependent argument conversions failed. + NonDependentConversionFailure, + /// The deduced arguments did not satisfy the constraints associated + /// with the template. + ConstraintsNotSatisfied, + /// Deduction failed; that's all we know. + MiscellaneousDeductionFailure, + /// CUDA Target attributes do not match. + CUDATargetMismatch, + /// Some error which was already diagnosed. + AlreadyDiagnosed +}; + /// Sema - This implements semantic analysis and AST building for C. class Sema final { Sema(const Sema &) = delete; @@ -9261,72 +9327,6 @@ class Sema final { QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec = false); - /// Describes the result of template argument deduction. - /// - /// The TemplateDeductionResult enumeration describes the result of - /// template argument deduction, as returned from - /// DeduceTemplateArguments(). The separate TemplateDeductionInfo - /// structure provides additional information about the results of - /// template argument deduction, e.g., the deduced template argument - /// list (if successful) or the specific template parameters or - /// deduced arguments that were involved in the failure. - enum TemplateDeductionResult { - /// Template argument deduction was successful. - TDK_Success = 0, - /// The declaration was invalid; do nothing. - TDK_Invalid, - /// Template argument deduction exceeded the maximum template - /// instantiation depth (which has already been diagnosed). - TDK_InstantiationDepth, - /// Template argument deduction did not deduce a value - /// for every template parameter. - TDK_Incomplete, - /// Template argument deduction did not deduce a value for every - /// expansion of an expanded template parameter pack. - TDK_IncompletePack, - /// Template argument deduction produced inconsistent - /// deduced values for the given template parameter. - TDK_Inconsistent, - /// Template argument deduction failed due to inconsistent - /// cv-qualifiers on a template parameter type that would - /// otherwise be deduced, e.g., we tried to deduce T in "const T" - /// but were given a non-const "X". - TDK_Underqualified, - /// Substitution of the deduced template argument values - /// resulted in an error. - TDK_SubstitutionFailure, - /// After substituting deduced template arguments, a dependent - /// parameter type did not match the corresponding argument. - TDK_DeducedMismatch, - /// After substituting deduced template arguments, an element of - /// a dependent parameter type did not match the corresponding element - /// of the corresponding argument (when deducing from an initializer list). - TDK_DeducedMismatchNested, - /// A non-depnedent component of the parameter did not match the - /// corresponding component of the argument. - TDK_NonDeducedMismatch, - /// When performing template argument deduction for a function - /// template, there were too many call arguments. - TDK_TooManyArguments, - /// When performing template argument deduction for a function - /// template, there were too few call arguments. - TDK_TooFewArguments, - /// The explicitly-specified template arguments were not valid - /// template arguments for the given template. - TDK_InvalidExplicitArguments, - /// Checking non-dependent argument conversions failed. - TDK_NonDependentConversionFailure, - /// The deduced arguments did not satisfy the constraints associated - /// with the template. - TDK_ConstraintsNotSatisfied, - /// Deduction failed; that's all we know. - TDK_MiscellaneousDeductionFailure, - /// CUDA Target attributes do not match. - TDK_CUDATargetMismatch, - /// Some error which was already diagnosed. - TDK_AlreadyDiagnosed - }; - TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef TemplateArgs, @@ -14444,7 +14444,7 @@ class Sema final { }; DeductionFailureInfo -MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, +MakeDeductionFailureInfo(ASTContext &Context, TemplateDeductionResult TDK, sema::TemplateDeductionInfo &Info); /// Contains a late templated function. diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index 85691c66a0443..28b014fd84e4b 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -33,6 +33,7 @@ namespace clang { class Decl; struct DeducedPack; class Sema; +enum class TemplateDeductionResult; namespace sema { @@ -295,6 +296,10 @@ struct DeductionFailureInfo { /// Free any memory associated with this deduction failure. void Destroy(); + + TemplateDeductionResult getResult() const { + return static_cast(Result); + } }; /// TemplateSpecCandidate - This is a generalization of OverloadCandidate diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 529fbcbfeff8e..be23c0fffe057 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13070,7 +13070,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, TemplateDeductionInfo Info(DeduceInit->getExprLoc()); TemplateDeductionResult Result = DeduceAutoType(TSI->getTypeLoc(), DeduceInit, DeducedType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) { + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) { if (!IsInitCapture) DiagnoseAutoDeductionFailure(VDecl, DeduceInit); else if (isa(Init)) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 246d2313e089f..f2b89135af21c 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1554,12 +1554,13 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, TemplateDeductionInfo Info(Deduce->getExprLoc()); TemplateDeductionResult Result = DeduceAutoType(TInfo->getTypeLoc(), Deduce, DeducedType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure) << Ty << Deduce->getType() << FullRange << Deduce->getSourceRange()); if (DeducedType.isNull()) { - assert(Result == TDK_AlreadyDiagnosed); + assert(Result == TemplateDeductionResult::AlreadyDiagnosed); return ExprError(); } @@ -2098,12 +2099,13 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, TemplateDeductionInfo Info(Deduce->getExprLoc()); TemplateDeductionResult Result = DeduceAutoType(AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); if (DeducedType.isNull()) { - assert(Result == TDK_AlreadyDiagnosed); + assert(Result == TemplateDeductionResult::AlreadyDiagnosed); return ExprError(); } AllocType = DeducedType; @@ -2883,7 +2885,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // expected function type. TemplateDeductionInfo Info(StartLoc); if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn, - Info)) + Info) != TemplateDeductionResult::Success) continue; } else Fn = cast((*D)->getUnderlyingDecl()); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 02b1a045df44c..d3a9c7abd0e94 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1200,8 +1200,8 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) { // Perform template argument deduction against the type that we would // expect the function to have. if (R.getSema().DeduceTemplateArguments(ConvTemplate, nullptr, ExpectedType, - Specialization, Info) - == Sema::TDK_Success) { + Specialization, Info) == + TemplateDeductionResult::Success) { R.addDecl(Specialization); Found = true; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 42960c229077c..9381b8c6626b6 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -628,28 +628,28 @@ namespace { /// to the form used in overload-candidate information. DeductionFailureInfo clang::MakeDeductionFailureInfo(ASTContext &Context, - Sema::TemplateDeductionResult TDK, + TemplateDeductionResult TDK, TemplateDeductionInfo &Info) { DeductionFailureInfo Result; Result.Result = static_cast(TDK); Result.HasDiagnostic = false; switch (TDK) { - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_CUDATargetMismatch: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::CUDATargetMismatch: Result.Data = nullptr; break; - case Sema::TDK_Incomplete: - case Sema::TDK_InvalidExplicitArguments: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::InvalidExplicitArguments: Result.Data = Info.Param.getOpaqueValue(); break; - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: { + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. auto *Saved = new (Context) DFIDeducedMismatchArgs; Saved->FirstArg = Info.FirstArg; @@ -660,7 +660,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } - case Sema::TDK_NonDeducedMismatch: { + case TemplateDeductionResult::NonDeducedMismatch: { // FIXME: Should allocate from normal heap so that we can free this later. DFIArguments *Saved = new (Context) DFIArguments; Saved->FirstArg = Info.FirstArg; @@ -669,10 +669,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } - case Sema::TDK_IncompletePack: + case TemplateDeductionResult::IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: { + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; Saved->Param = Info.Param; @@ -682,7 +682,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } - case Sema::TDK_SubstitutionFailure: + case TemplateDeductionResult::SubstitutionFailure: Result.Data = Info.takeSugared(); if (Info.hasSFINAEDiagnostic()) { PartialDiagnosticAt *Diag = new (Result.Diagnostic) PartialDiagnosticAt( @@ -692,7 +692,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, } break; - case Sema::TDK_ConstraintsNotSatisfied: { + case TemplateDeductionResult::ConstraintsNotSatisfied: { CNSInfo *Saved = new (Context) CNSInfo; Saved->TemplateArgs = Info.takeSugared(); Saved->Satisfaction = Info.AssociatedConstraintsSatisfaction; @@ -700,9 +700,9 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } - case Sema::TDK_Success: - case Sema::TDK_NonDependentConversionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::Success: + case TemplateDeductionResult::NonDependentConversionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: llvm_unreachable("not a deduction failure"); } @@ -710,29 +710,29 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, } void DeductionFailureInfo::Destroy() { - switch (static_cast(Result)) { - case Sema::TDK_Success: - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_Incomplete: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_InvalidExplicitArguments: - case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: + switch (static_cast(Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::CUDATargetMismatch: + case TemplateDeductionResult::NonDependentConversionFailure: break; - case Sema::TDK_IncompletePack: - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: - case Sema::TDK_NonDeducedMismatch: + case TemplateDeductionResult::IncompletePack: + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: + case TemplateDeductionResult::NonDeducedMismatch: // FIXME: Destroy the data? Data = nullptr; break; - case Sema::TDK_SubstitutionFailure: + case TemplateDeductionResult::SubstitutionFailure: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { @@ -741,7 +741,7 @@ void DeductionFailureInfo::Destroy() { } break; - case Sema::TDK_ConstraintsNotSatisfied: + case TemplateDeductionResult::ConstraintsNotSatisfied: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { @@ -751,8 +751,8 @@ void DeductionFailureInfo::Destroy() { break; // Unhandled - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: break; } } @@ -764,33 +764,33 @@ PartialDiagnosticAt *DeductionFailureInfo::getSFINAEDiagnostic() { } TemplateParameter DeductionFailureInfo::getTemplateParameter() { - switch (static_cast(Result)) { - case Sema::TDK_Success: - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_SubstitutionFailure: - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: - case Sema::TDK_ConstraintsNotSatisfied: + switch (static_cast(Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::SubstitutionFailure: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: + case TemplateDeductionResult::NonDeducedMismatch: + case TemplateDeductionResult::CUDATargetMismatch: + case TemplateDeductionResult::NonDependentConversionFailure: + case TemplateDeductionResult::ConstraintsNotSatisfied: return TemplateParameter(); - case Sema::TDK_Incomplete: - case Sema::TDK_InvalidExplicitArguments: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::InvalidExplicitArguments: return TemplateParameter::getFromOpaqueValue(Data); - case Sema::TDK_IncompletePack: - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: + case TemplateDeductionResult::IncompletePack: + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: return static_cast(Data)->Param; // Unhandled - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: break; } @@ -798,35 +798,35 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { } TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { - switch (static_cast(Result)) { - case Sema::TDK_Success: - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_Incomplete: - case Sema::TDK_IncompletePack: - case Sema::TDK_InvalidExplicitArguments: - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: + switch (static_cast(Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::IncompletePack: + case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: + case TemplateDeductionResult::NonDeducedMismatch: + case TemplateDeductionResult::CUDATargetMismatch: + case TemplateDeductionResult::NonDependentConversionFailure: return nullptr; - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: return static_cast(Data)->TemplateArgs; - case Sema::TDK_SubstitutionFailure: + case TemplateDeductionResult::SubstitutionFailure: return static_cast(Data); - case Sema::TDK_ConstraintsNotSatisfied: + case TemplateDeductionResult::ConstraintsNotSatisfied: return static_cast(Data)->TemplateArgs; // Unhandled - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: break; } @@ -834,31 +834,31 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { } const TemplateArgument *DeductionFailureInfo::getFirstArg() { - switch (static_cast(Result)) { - case Sema::TDK_Success: - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_Incomplete: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_InvalidExplicitArguments: - case Sema::TDK_SubstitutionFailure: - case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: - case Sema::TDK_ConstraintsNotSatisfied: + switch (static_cast(Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::SubstitutionFailure: + case TemplateDeductionResult::CUDATargetMismatch: + case TemplateDeductionResult::NonDependentConversionFailure: + case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; - case Sema::TDK_IncompletePack: - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: - case Sema::TDK_NonDeducedMismatch: + case TemplateDeductionResult::IncompletePack: + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: + case TemplateDeductionResult::NonDeducedMismatch: return &static_cast(Data)->FirstArg; // Unhandled - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: break; } @@ -866,31 +866,31 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { } const TemplateArgument *DeductionFailureInfo::getSecondArg() { - switch (static_cast(Result)) { - case Sema::TDK_Success: - case Sema::TDK_Invalid: - case Sema::TDK_InstantiationDepth: - case Sema::TDK_Incomplete: - case Sema::TDK_IncompletePack: - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: - case Sema::TDK_InvalidExplicitArguments: - case Sema::TDK_SubstitutionFailure: - case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: - case Sema::TDK_ConstraintsNotSatisfied: + switch (static_cast(Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::InstantiationDepth: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::IncompletePack: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: + case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::SubstitutionFailure: + case TemplateDeductionResult::CUDATargetMismatch: + case TemplateDeductionResult::NonDependentConversionFailure: + case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: - case Sema::TDK_NonDeducedMismatch: + case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: + case TemplateDeductionResult::NonDeducedMismatch: return &static_cast(Data)->SecondArg; // Unhandled - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_AlreadyDiagnosed: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: break; } @@ -898,9 +898,9 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { } std::optional DeductionFailureInfo::getCallArgIndex() { - switch (static_cast(Result)) { - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: + switch (static_cast(Result)) { + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: return static_cast(Data)->CallArgIndex; default: @@ -7548,12 +7548,14 @@ void Sema::AddMethodTemplateCandidate( if (TemplateDeductionResult Result = DeduceTemplateArguments( MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, PartialOverloading, /*AggregateDeductionCandidate=*/false, ObjectType, - ObjectClassification, [&](ArrayRef ParamTypes) { + ObjectClassification, + [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, ActingContext, ObjectType, ObjectClassification, PO); - })) { + }); + Result != TemplateDeductionResult::Success) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; @@ -7566,7 +7568,7 @@ void Sema::AddMethodTemplateCandidate( cast(Candidate.Function)->isStatic() || ObjectType.isNull(); Candidate.ExplicitCallArguments = Args.size(); - if (Result == TDK_NonDependentConversionFailure) + if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; @@ -7639,7 +7641,8 @@ void Sema::AddTemplateOverloadCandidate( return CheckNonDependentConversions( FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, nullptr, QualType(), {}, PO); - })) { + }); + Result != TemplateDeductionResult::Success) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; @@ -7655,7 +7658,7 @@ void Sema::AddTemplateOverloadCandidate( isa(Candidate.Function) && !isa(Candidate.Function); Candidate.ExplicitCallArguments = Args.size(); - if (Result == TDK_NonDependentConversionFailure) + if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; @@ -8042,7 +8045,8 @@ void Sema::AddTemplateConversionCandidate( CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result = DeduceTemplateArguments( FunctionTemplate, ObjectType, ObjectClassification, ToType, - Specialization, Info)) { + Specialization, Info); + Result != TemplateDeductionResult::Success) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); @@ -10655,7 +10659,8 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations( bool OverloadCandidate::NotValidBecauseConstraintExprHasError() const { return FailureKind == ovl_fail_bad_deduction && - DeductionFailure.Result == Sema::TDK_ConstraintsNotSatisfied && + static_cast(DeductionFailure.Result) == + TemplateDeductionResult::ConstraintsNotSatisfied && static_cast(DeductionFailure.Data) ->Satisfaction.ContainsErrors; } @@ -11358,11 +11363,13 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, if (NumArgs < MinParams) { assert((Cand->FailureKind == ovl_fail_too_few_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && - Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments)); + Cand->DeductionFailure.getResult() == + TemplateDeductionResult::TooFewArguments)); } else { assert((Cand->FailureKind == ovl_fail_too_many_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && - Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments)); + Cand->DeductionFailure.getResult() == + TemplateDeductionResult::TooManyArguments)); } return false; @@ -11445,11 +11452,18 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); - switch (DeductionFailure.Result) { - case Sema::TDK_Success: - llvm_unreachable("TDK_success while diagnosing bad deduction"); + switch (DeductionFailure.getResult()) { + case TemplateDeductionResult::Success: + llvm_unreachable( + "TemplateDeductionResult::Success while diagnosing bad deduction"); + case TemplateDeductionResult::NonDependentConversionFailure: + llvm_unreachable("TemplateDeductionResult::NonDependentConversionFailure " + "while diagnosing bad deduction"); + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::AlreadyDiagnosed: + return; - case Sema::TDK_Incomplete: { + case TemplateDeductionResult::Incomplete: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction) @@ -11458,7 +11472,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_IncompletePack: { + case TemplateDeductionResult::IncompletePack: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction_pack) @@ -11469,7 +11483,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_Underqualified: { + case TemplateDeductionResult::Underqualified: { assert(ParamD && "no parameter found for bad qualifiers deduction result"); TemplateTypeParmDecl *TParam = cast(ParamD); @@ -11494,7 +11508,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_Inconsistent: { + case TemplateDeductionResult::Inconsistent: { assert(ParamD && "no parameter found for inconsistent deduction result"); int which = 0; if (isa(ParamD)) @@ -11539,7 +11553,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_InvalidExplicitArguments: + case TemplateDeductionResult::InvalidExplicitArguments: assert(ParamD && "no parameter found for invalid explicit arguments"); if (ParamD->getDeclName()) S.Diag(Templated->getLocation(), @@ -11561,7 +11575,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, MaybeEmitInheritedConstructorNote(S, Found); return; - case Sema::TDK_ConstraintsNotSatisfied: { + case TemplateDeductionResult::ConstraintsNotSatisfied: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList(); @@ -11578,18 +11592,18 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, static_cast(DeductionFailure.Data)->Satisfaction); return; } - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: DiagnoseArityMismatch(S, Found, Templated, NumArgs); return; - case Sema::TDK_InstantiationDepth: + case TemplateDeductionResult::InstantiationDepth: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_instantiation_depth); MaybeEmitInheritedConstructorNote(S, Found); return; - case Sema::TDK_SubstitutionFailure: { + case TemplateDeductionResult::SubstitutionFailure: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = @@ -11639,8 +11653,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_DeducedMismatch: - case Sema::TDK_DeducedMismatchNested: { + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::DeducedMismatchNested: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = @@ -11656,11 +11670,12 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, << (*DeductionFailure.getCallArgIndex() + 1) << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() << TemplateArgString - << (DeductionFailure.Result == Sema::TDK_DeducedMismatchNested); + << (DeductionFailure.getResult() == + TemplateDeductionResult::DeducedMismatchNested); break; } - case Sema::TDK_NonDeducedMismatch: { + case TemplateDeductionResult::NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. TemplateArgument FirstTA = *DeductionFailure.getFirstArg(); TemplateArgument SecondTA = *DeductionFailure.getSecondArg(); @@ -11701,11 +11716,11 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. - case Sema::TDK_MiscellaneousDeductionFailure: + case TemplateDeductionResult::MiscellaneousDeductionFailure: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction); MaybeEmitInheritedConstructorNote(S, Found); return; - case Sema::TDK_CUDATargetMismatch: + case TemplateDeductionResult::CUDATargetMismatch: S.Diag(Templated->getLocation(), diag::note_cuda_ovl_candidate_target_mismatch); return; @@ -11716,8 +11731,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress) { - unsigned TDK = Cand->DeductionFailure.Result; - if (TDK == Sema::TDK_TooFewArguments || TDK == Sema::TDK_TooManyArguments) { + TemplateDeductionResult TDK = Cand->DeductionFailure.getResult(); + if (TDK == TemplateDeductionResult::TooFewArguments || + TDK == TemplateDeductionResult::TooManyArguments) { if (CheckArityMismatch(S, Cand, NumArgs)) return; } @@ -12051,38 +12067,38 @@ static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { } static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { - switch ((Sema::TemplateDeductionResult)DFI.Result) { - case Sema::TDK_Success: - case Sema::TDK_NonDependentConversionFailure: - case Sema::TDK_AlreadyDiagnosed: + switch (static_cast(DFI.Result)) { + case TemplateDeductionResult::Success: + case TemplateDeductionResult::NonDependentConversionFailure: + case TemplateDeductionResult::AlreadyDiagnosed: llvm_unreachable("non-deduction failure while diagnosing bad deduction"); - case Sema::TDK_Invalid: - case Sema::TDK_Incomplete: - case Sema::TDK_IncompletePack: + case TemplateDeductionResult::Invalid: + case TemplateDeductionResult::Incomplete: + case TemplateDeductionResult::IncompletePack: return 1; - case Sema::TDK_Underqualified: - case Sema::TDK_Inconsistent: + case TemplateDeductionResult::Underqualified: + case TemplateDeductionResult::Inconsistent: return 2; - case Sema::TDK_SubstitutionFailure: - case Sema::TDK_DeducedMismatch: - case Sema::TDK_ConstraintsNotSatisfied: - case Sema::TDK_DeducedMismatchNested: - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_MiscellaneousDeductionFailure: - case Sema::TDK_CUDATargetMismatch: + case TemplateDeductionResult::SubstitutionFailure: + case TemplateDeductionResult::DeducedMismatch: + case TemplateDeductionResult::ConstraintsNotSatisfied: + case TemplateDeductionResult::DeducedMismatchNested: + case TemplateDeductionResult::NonDeducedMismatch: + case TemplateDeductionResult::MiscellaneousDeductionFailure: + case TemplateDeductionResult::CUDATargetMismatch: return 3; - case Sema::TDK_InstantiationDepth: + case TemplateDeductionResult::InstantiationDepth: return 4; - case Sema::TDK_InvalidExplicitArguments: + case TemplateDeductionResult::InvalidExplicitArguments: return 5; - case Sema::TDK_TooManyArguments: - case Sema::TDK_TooFewArguments: + case TemplateDeductionResult::TooManyArguments: + case TemplateDeductionResult::TooFewArguments: return 6; } llvm_unreachable("Unhandled deduction result"); @@ -12810,11 +12826,10 @@ class AddressOfFunctionResolver { // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(FailedCandidates.getLocation()); - if (Sema::TemplateDeductionResult Result - = S.DeduceTemplateArguments(FunctionTemplate, - &OvlExplicitTemplateArgs, - TargetFunctionType, Specialization, - Info, /*IsAddressOfFunction*/true)) { + if (TemplateDeductionResult Result = S.DeduceTemplateArguments( + FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, + Specialization, Info, /*IsAddressOfFunction*/ true); + Result != TemplateDeductionResult::Success) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), @@ -13305,10 +13320,10 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization( // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(ovl->getNameLoc()); - if (TemplateDeductionResult Result - = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, - Specialization, Info, - /*IsAddressOfFunction*/true)) { + if (TemplateDeductionResult Result = DeduceTemplateArguments( + FunctionTemplate, &ExplicitTemplateArgs, Specialization, Info, + /*IsAddressOfFunction*/ true); + Result != TemplateDeductionResult::Success) { // Make a note of the failed deduction for diagnostics. if (FailedTSC) FailedTSC->addCandidate().set( diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index d9aaea8edd641..dde3bd84e89f8 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2326,7 +2326,8 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, FirstType = QualType(); TemplateDeductionResult Result = DeduceAutoType( D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) DiagnoseAutoDeductionFailure(D, DeducedInit); if (FirstType.isNull()) { D->setInvalidDecl(); @@ -2394,9 +2395,10 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SemaRef.Diag(Loc, DiagID) << Init->getType(); } else { TemplateDeductionInfo Info(Init->getExprLoc()); - Sema::TemplateDeductionResult Result = SemaRef.DeduceAutoType( + TemplateDeductionResult Result = SemaRef.DeduceAutoType( Decl->getTypeSourceInfo()->getTypeLoc(), Init, InitType, Info); - if (Result != Sema::TDK_Success && Result != Sema::TDK_AlreadyDiagnosed) + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) SemaRef.Diag(Loc, DiagID) << Init->getType(); } @@ -3865,14 +3867,14 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, TemplateDeductionResult Res = DeduceAutoType( OrigResultType, RetExpr, Deduced, Info, /*DependentDeduction=*/false, /*IgnoreConstraints=*/false, &FailedTSC); - if (Res != TDK_Success && FD->isInvalidDecl()) + if (Res != TemplateDeductionResult::Success && FD->isInvalidDecl()) return true; switch (Res) { - case TDK_Success: + case TemplateDeductionResult::Success: break; - case TDK_AlreadyDiagnosed: + case TemplateDeductionResult::AlreadyDiagnosed: return true; - case TDK_Inconsistent: { + case TemplateDeductionResult::Inconsistent: { // If a function with a declared return type that contains a placeholder // type has multiple return statements, the return type is deduced for // each return statement. [...] if the type deduced is not the same in diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index cf781e0e1bf3f..9e516da2aa27a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4863,7 +4863,8 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (TemplateDeductionResult Result = - DeduceTemplateArguments(Partial, CanonicalConverted, Info)) { + DeduceTemplateArguments(Partial, CanonicalConverted, Info); + Result != TemplateDeductionResult::Success) { // Store the failed-deduction information for use in diagnostics, later. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate().set( @@ -7243,10 +7244,10 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // along with the other associated constraints after // checking the template argument list. /*IgnoreConstraints=*/true); - if (Result == TDK_AlreadyDiagnosed) { + if (Result == TemplateDeductionResult::AlreadyDiagnosed) { if (ParamType.isNull()) return ExprError(); - } else if (Result != TDK_Success) { + } else if (Result != TemplateDeductionResult::Success) { Diag(Arg->getExprLoc(), diag::err_non_type_template_parm_type_deduction_failure) << Param->getDeclName() << Param->getType() << Arg->getType() @@ -9644,8 +9645,8 @@ bool Sema::CheckFunctionTemplateSpecialization( FunctionDecl *Specialization = nullptr; if (TemplateDeductionResult TDK = DeduceTemplateArguments( cast(FunTmpl->getFirstDecl()), - ExplicitTemplateArgs ? &Args : nullptr, FT, Specialization, - Info)) { + ExplicitTemplateArgs ? &Args : nullptr, FT, Specialization, Info); + TDK != TemplateDeductionResult::Success) { // Template argument deduction failed; record why it failed, so // that we can provide nifty diagnostics. FailedCandidates.addCandidate().set( @@ -9666,7 +9667,8 @@ bool Sema::CheckFunctionTemplateSpecialization( IdentifyCUDATarget(FD, /* IgnoreImplicitHDAttr = */ true)) { FailedCandidates.addCandidate().set( I.getPair(), FunTmpl->getTemplatedDecl(), - MakeDeductionFailureInfo(Context, TDK_CUDATargetMismatch, Info)); + MakeDeductionFailureInfo( + Context, TemplateDeductionResult::CUDATargetMismatch, Info)); continue; } @@ -10816,11 +10818,10 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, TemplateDeductionInfo Info(FailedCandidates.getLocation()); FunctionDecl *Specialization = nullptr; - if (TemplateDeductionResult TDK - = DeduceTemplateArguments(FunTmpl, - (HasExplicitTemplateArgs ? &TemplateArgs - : nullptr), - R, Specialization, Info)) { + if (TemplateDeductionResult TDK = DeduceTemplateArguments( + FunTmpl, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr), R, + Specialization, Info); + TDK != TemplateDeductionResult::Success) { // Keep track of almost-matches. FailedCandidates.addCandidate() .set(P.getPair(), FunTmpl->getTemplatedDecl(), @@ -10840,7 +10841,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, IdentifyCUDATarget(D.getDeclSpec().getAttributes())) { FailedCandidates.addCandidate().set( P.getPair(), FunTmpl->getTemplatedDecl(), - MakeDeductionFailureInfo(Context, TDK_CUDATargetMismatch, Info)); + MakeDeductionFailureInfo( + Context, TemplateDeductionResult::CUDATargetMismatch, Info)); continue; } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index a54ad27975890..994c997b9f6ac 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -133,13 +133,13 @@ static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) { return X == Y; } -static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( +static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( Sema &S, TemplateParameterList *TemplateParams, QualType Param, QualType Arg, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced, unsigned TDF, bool PartialOrdering = false, bool DeducedFromArrayBound = false); -static Sema::TemplateDeductionResult +static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef Ps, ArrayRef As, @@ -393,10 +393,11 @@ checkDeducedTemplateArguments(ASTContext &Context, /// Deduce the value of the given non-type template parameter /// as the given deduced template argument. All non-type template parameter /// deduction is funneled through here. -static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( +static TemplateDeductionResult DeduceNonTypeTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, - const NonTypeTemplateParmDecl *NTTP, const DeducedTemplateArgument &NewDeduced, - QualType ValueType, TemplateDeductionInfo &Info, + const NonTypeTemplateParmDecl *NTTP, + const DeducedTemplateArgument &NewDeduced, QualType ValueType, + TemplateDeductionInfo &Info, SmallVectorImpl &Deduced) { assert(NTTP->getDepth() == Info.getDeducedDepth() && "deducing non-type template argument with wrong depth"); @@ -407,19 +408,19 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( Info.Param = const_cast(NTTP); Info.FirstArg = Deduced[NTTP->getIndex()]; Info.SecondArg = NewDeduced; - return Sema::TDK_Inconsistent; + return TemplateDeductionResult::Inconsistent; } Deduced[NTTP->getIndex()] = Result; if (!S.getLangOpts().CPlusPlus17) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (NTTP->isExpandedParameterPack()) // FIXME: We may still need to deduce parts of the type here! But we // don't have any way to find which slice of the type to use, and the // type stored on the NTTP itself is nonsense. Perhaps the type of an // expanded NTTP should be a pack expansion type? - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Get the type of the parameter for deduction. If it's a (dependent) array // or function type, we will not have decayed it yet, so do that now. @@ -446,7 +447,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( /// Deduce the value of the given non-type template parameter /// from the given integral constant. -static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( +static TemplateDeductionResult DeduceNonTypeTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value, QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo &Info, @@ -460,7 +461,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( /// Deduce the value of the given non-type template parameter /// from the given null pointer template argument type. -static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument( +static TemplateDeductionResult DeduceNullPtrTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, @@ -481,9 +482,10 @@ static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument( /// from the given type- or value-dependent expression. /// /// \returns true if deduction succeeded, false otherwise. -static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( +static TemplateDeductionResult DeduceNonTypeTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, - const NonTypeTemplateParmDecl *NTTP, Expr *Value, TemplateDeductionInfo &Info, + const NonTypeTemplateParmDecl *NTTP, Expr *Value, + TemplateDeductionInfo &Info, SmallVectorImpl &Deduced) { return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, DeducedTemplateArgument(Value), @@ -494,7 +496,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( /// from the given declaration. /// /// \returns true if deduction succeeded, false otherwise. -static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( +static TemplateDeductionResult DeduceNonTypeTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *NTTP, ValueDecl *D, QualType T, TemplateDeductionInfo &Info, @@ -505,25 +507,23 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced); } -static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, - TemplateName Param, - TemplateName Arg, +static TemplateDeductionResult +DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, + TemplateName Param, TemplateName Arg, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced) { TemplateDecl *ParamDecl = Param.getAsTemplateDecl(); if (!ParamDecl) { // The parameter type is dependent and is not a template template parameter, // so there is nothing that we can deduce. - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } if (TemplateTemplateParmDecl *TempParam = dyn_cast(ParamDecl)) { // If we're not deducing at this depth, there's nothing to deduce. if (TempParam->getDepth() != Info.getDeducedDepth()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; DeducedTemplateArgument NewDeduced(S.Context.getCanonicalTemplateName(Arg)); DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, @@ -533,21 +533,21 @@ DeduceTemplateArguments(Sema &S, Info.Param = TempParam; Info.FirstArg = Deduced[TempParam->getIndex()]; Info.SecondArg = NewDeduced; - return Sema::TDK_Inconsistent; + return TemplateDeductionResult::Inconsistent; } Deduced[TempParam->getIndex()] = Result; - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } // Verify that the two template names are equivalent. if (S.Context.hasSameTemplateName(Param, Arg)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Mismatch of non-dependent template parameter to argument. Info.FirstArg = TemplateArgument(Param); Info.SecondArg = TemplateArgument(Arg); - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } /// Deduce the template arguments by comparing the template parameter @@ -568,7 +568,7 @@ DeduceTemplateArguments(Sema &S, /// \returns the result of template argument deduction so far. Note that a /// "success" result means that template argument deduction has not yet failed, /// but it may still fail, later, for other reasons. -static Sema::TemplateDeductionResult +static TemplateDeductionResult DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType P, QualType A, TemplateDeductionInfo &Info, @@ -583,7 +583,7 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, // If the parameter is an alias template, there is nothing to deduce. if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; ArrayRef PResolved = TP->template_arguments(); @@ -600,11 +600,12 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, // If the argument is an alias template, there is nothing to deduce. if (const auto *TD = TNA.getAsTemplateDecl(); TD && TD->isTypeAlias()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Perform template argument deduction for the template name. if (auto Result = - DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info, Deduced)) + DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info, Deduced); + Result != TemplateDeductionResult::Success) return Result; // Perform template argument deduction on each template // argument. Ignore any missing/extra arguments, since they could be @@ -623,13 +624,14 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, if (!SA) { Info.FirstArg = TemplateArgument(P); Info.SecondArg = TemplateArgument(A); - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // Perform template argument deduction for the template name. if (auto Result = DeduceTemplateArguments( S, TemplateParams, TP->getTemplateName(), - TemplateName(SA->getSpecializedTemplate()), Info, Deduced)) + TemplateName(SA->getSpecializedTemplate()), Info, Deduced); + Result != TemplateDeductionResult::Success) return Result; // Perform template argument deduction for the template arguments. @@ -919,7 +921,7 @@ class PackDeductionScope { /// Finish template argument deduction for a set of argument packs, /// producing the argument packs and checking for consistency with prior /// deductions. - Sema::TemplateDeductionResult finish() { + TemplateDeductionResult finish() { // Build argument packs for each of the parameter packs expanded by this // pack expansion. for (auto &Pack : Packs) { @@ -996,7 +998,7 @@ class PackDeductionScope { Info.Param = makeTemplateParameter(Param); Info.FirstArg = OldPack; Info.SecondArg = NewPack; - return Sema::TDK_Inconsistent; + return TemplateDeductionResult::Inconsistent; } // If we have a pre-expanded pack and we didn't deduce enough elements @@ -1005,14 +1007,14 @@ class PackDeductionScope { if (*Expansions != PackElements) { Info.Param = makeTemplateParameter(Param); Info.FirstArg = Result; - return Sema::TDK_IncompletePack; + return TemplateDeductionResult::IncompletePack; } } *Loc = Result; } - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } private: @@ -1062,15 +1064,13 @@ class PackDeductionScope { /// \returns the result of template argument deduction so far. Note that a /// "success" result means that template argument deduction has not yet failed, /// but it may still fail, later, for other reasons. -static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, +static TemplateDeductionResult +DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType *Params, unsigned NumParams, const QualType *Args, unsigned NumArgs, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced, - unsigned TDF, - bool PartialOrdering = false) { + unsigned TDF, bool PartialOrdering = false) { // C++0x [temp.deduct.type]p10: // Similarly, if P has a form that contains (T), then each parameter type // Pi of the respective parameter-type- list of P is compared with the @@ -1086,22 +1086,22 @@ DeduceTemplateArguments(Sema &S, // Make sure we have an argument. if (ArgIdx >= NumArgs) - return Sema::TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; if (isa(Args[ArgIdx])) { // C++0x [temp.deduct.type]p22: // If the original function parameter associated with A is a function // parameter pack and the function parameter associated with P is not // a function parameter pack, then template argument deduction fails. - return Sema::TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; } - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, Params[ParamIdx].getUnqualifiedType(), - Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, - PartialOrdering, - /*DeducedFromArrayBound=*/false)) + if (TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, Params[ParamIdx].getUnqualifiedType(), + Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, + PartialOrdering, + /*DeducedFromArrayBound=*/false); + Result != TemplateDeductionResult::Success) return Result; ++ArgIdx; @@ -1123,11 +1123,11 @@ DeduceTemplateArguments(Sema &S, if (ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) { for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) { // Deduce template arguments from the pattern. - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, Pattern.getUnqualifiedType(), - Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, - PartialOrdering, /*DeducedFromArrayBound=*/false)) + if (TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, Pattern.getUnqualifiedType(), + Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, + PartialOrdering, /*DeducedFromArrayBound=*/false); + Result != TemplateDeductionResult::Success) return Result; PackScope.nextPackElement(); @@ -1160,7 +1160,8 @@ DeduceTemplateArguments(Sema &S, // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish()) + if (auto Result = PackScope.finish(); + Result != TemplateDeductionResult::Success) return Result; } @@ -1172,13 +1173,13 @@ DeduceTemplateArguments(Sema &S, // Ai is ignored; if (PartialOrdering && ArgIdx + 1 == NumArgs && isa(Args[ArgIdx])) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Make sure we don't have any extra arguments. if (ArgIdx < NumArgs) - return Sema::TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Determine whether the parameter has qualifiers that the argument @@ -1286,7 +1287,7 @@ static CXXRecordDecl *getCanonicalRD(QualType T) { /// \returns the result of template argument deduction with the bases. "invalid" /// means no matches, "success" found a single item, and the /// "MiscellaneousDeductionFailure" result happens when the match is ambiguous. -static Sema::TemplateDeductionResult +static TemplateDeductionResult DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, TemplateParameterList *TemplateParams, QualType P, TemplateDeductionInfo &Info, @@ -1338,13 +1339,13 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, SmallVector DeducedCopy(Deduced.begin(), Deduced.end()); TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info); - Sema::TemplateDeductionResult BaseResult = DeduceTemplateSpecArguments( + TemplateDeductionResult BaseResult = DeduceTemplateSpecArguments( S, TemplateParams, P, NextT, BaseInfo, DeducedCopy); // If this was a successful deduction, add it to the list of matches, // otherwise we need to continue searching its bases. const CXXRecordDecl *RD = ::getCanonicalRD(NextT); - if (BaseResult == Sema::TDK_Success) + if (BaseResult == TemplateDeductionResult::Success) Matches.insert({RD, DeducedCopy}); else AddBases(RD); @@ -1374,12 +1375,12 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, } if (Matches.empty()) - return Sema::TDK_Invalid; + return TemplateDeductionResult::Invalid; if (Matches.size() > 1) - return Sema::TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; std::swap(Matches.front().second, Deduced); - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Deduce the template arguments by comparing the parameter type and @@ -1406,7 +1407,7 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, /// \returns the result of template argument deduction so far. Note that a /// "success" result means that template argument deduction has not yet failed, /// but it may still fail, later, for other reasons. -static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( +static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( Sema &S, TemplateParameterList *TemplateParams, QualType P, QualType A, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced, unsigned TDF, @@ -1460,7 +1461,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( PQuals.withoutObjCLifetime() == AQuals.withoutObjCLifetime())) { Info.FirstArg = TemplateArgument(P); Info.SecondArg = TemplateArgument(A); - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } } Qualifiers DiscardedQuals; @@ -1514,7 +1515,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Just skip any attempts to deduce from a placeholder type or a parameter // at a different depth. if (A->isPlaceholderType() || Info.getDeducedDepth() != TTP->getDepth()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; unsigned Index = TTP->getIndex(); @@ -1534,13 +1535,13 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( Info.Param = cast(TemplateParams->getParam(Index)); Info.FirstArg = TemplateArgument(P); Info.SecondArg = TemplateArgument(A); - return Sema::TDK_Underqualified; + return TemplateDeductionResult::Underqualified; } // Do not match a function type with a cv-qualified type. // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584 if (A->isFunctionType() && P.hasQualifiers()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; assert(TTP->getDepth() == Info.getDeducedDepth() && "saw template type parameter with wrong depth"); @@ -1568,7 +1569,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( Info.Param = cast(TemplateParams->getParam(Index)); Info.FirstArg = TemplateArgument(P); Info.SecondArg = TemplateArgument(A); - return Sema::TDK_Underqualified; + return TemplateDeductionResult::Underqualified; } // Objective-C ARC: @@ -1588,11 +1589,11 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( Info.Param = cast(TemplateParams->getParam(Index)); Info.FirstArg = Deduced[Index]; Info.SecondArg = NewDeduced; - return Sema::TDK_Inconsistent; + return TemplateDeductionResult::Inconsistent; } Deduced[Index] = Result; - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } // Set up the template argument deduction information for a failure. @@ -1604,19 +1605,19 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // at, so we have to wait until all of the parameter packs in this // expansion have arguments. if (P->getAs()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Check the cv-qualifiers on the parameter and argument types. if (!(TDF & TDF_IgnoreQualifiers)) { if (TDF & TDF_ParamWithReferenceType) { if (hasInconsistentOrSupersetQualifiersOf(P, A)) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } else if (TDF & TDF_ArgWithReferenceType) { // C++ [temp.deduct.conv]p4: // If the original A is a reference type, A can be more cv-qualified // than the deduced A if (!A.getQualifiers().compatiblyIncludes(P.getQualifiers())) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Strip out all extra qualifiers from the argument to figure out the // type we're converting to, prior to the qualification conversion. @@ -1625,22 +1626,22 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( A = S.Context.getQualifiedType(A, P.getQualifiers()); } else if (!IsPossiblyOpaquelyQualifiedType(P)) { if (P.getCVRQualifiers() != A.getCVRQualifiers()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } } // If the parameter type is not dependent, there is nothing to deduce. if (!P->isDependentType()) { if (TDF & TDF_SkipNonDependent) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A) : S.Context.hasSameType(P, A)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (TDF & TDF_AllowCompatibleFunctionType && S.isSameOrCompatibleFunctionType(P, A)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (!(TDF & TDF_IgnoreQualifiers)) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Otherwise, when ignoring qualifiers, the types not having the same // unqualified type does not mean they do not match, so in this case we // must keep going and analyze with a non-dependent parameter type. @@ -1664,7 +1665,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // There's no corresponding wording for [temp.deduct.decl], but we treat // it the same to match other compilers. if (P->isDependentType()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; [[fallthrough]]; case Type::Builtin: case Type::VariableArray: @@ -1680,14 +1681,14 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A) : S.Context.hasSameType(P, A)) - ? Sema::TDK_Success - : Sema::TDK_NonDeducedMismatch; + ? TemplateDeductionResult::Success + : TemplateDeductionResult::NonDeducedMismatch; // _Complex T [placeholder extension] case Type::Complex: { const auto *CP = P->castAs(), *CA = A->getAs(); if (!CA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, CP->getElementType(), CA->getElementType(), Info, Deduced, TDF); @@ -1697,7 +1698,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( case Type::Atomic: { const auto *PA = P->castAs(), *AA = A->getAs(); if (!AA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, PA->getValueType(), AA->getValueType(), Info, Deduced, TDF); @@ -1711,7 +1712,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( } else if (const auto *PA = A->getAs()) { PointeeType = PA->getPointeeType(); } else { - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, P->castAs()->getPointeeType(), @@ -1724,7 +1725,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *RP = P->castAs(), *RA = A->getAs(); if (!RA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info, @@ -1736,7 +1737,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *RP = P->castAs(), *RA = A->getAs(); if (!RA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info, @@ -1747,7 +1748,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( case Type::IncompleteArray: { const auto *IAA = S.Context.getAsIncompleteArrayType(A); if (!IAA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; const auto *IAP = S.Context.getAsIncompleteArrayType(P); assert(IAP && "Template parameter not of incomplete array type"); @@ -1763,7 +1764,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( *CAP = S.Context.getAsConstantArrayType(P); assert(CAP); if (!CAA || CAA->getSize() != CAP->getSize()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info, @@ -1774,21 +1775,22 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( case Type::DependentSizedArray: { const auto *AA = S.Context.getAsArrayType(A); if (!AA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Check the element type of the arrays const auto *DAP = S.Context.getAsDependentSizedArrayType(P); assert(DAP); if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, DAP->getElementType(), AA->getElementType(), - Info, Deduced, TDF & TDF_IgnoreQualifiers)) + Info, Deduced, TDF & TDF_IgnoreQualifiers); + Result != TemplateDeductionResult::Success) return Result; // Determine the array bound is something we can deduce. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, DAP->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // We can perform template argument deduction for the given non-type // template parameter. @@ -1806,7 +1808,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, NTTP, DAA->getSizeExpr(), Info, Deduced); // Incomplete type does not match a dependently-sized array type - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // type(*)(T) @@ -1816,30 +1818,32 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *FPP = P->castAs(), *FPA = A->getAs(); if (!FPA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; if (FPP->getMethodQuals() != FPA->getMethodQuals() || FPP->getRefQualifier() != FPA->getRefQualifier() || FPP->isVariadic() != FPA->isVariadic()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Check return types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(), Info, Deduced, 0, /*PartialOrdering=*/false, - /*DeducedFromArrayBound=*/false)) + /*DeducedFromArrayBound=*/false); + Result != TemplateDeductionResult::Success) return Result; // Check parameter types. if (auto Result = DeduceTemplateArguments( S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(), FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced, - TDF & TDF_TopLevelParameterTypeList, PartialOrdering)) + TDF & TDF_TopLevelParameterTypeList, PartialOrdering); + Result != TemplateDeductionResult::Success) return Result; if (TDF & TDF_AllowCompatibleFunctionType) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit // deducing through the noexcept-specifier if it's part of the canonical @@ -1877,7 +1881,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Careful about [temp.deduct.call] and [temp.deduct.conv], which allow // top-level differences in noexcept-specifications. - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } case Type::InjectedClassName: @@ -1901,7 +1905,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( auto Result = DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info, Deduced); - if (Result == Sema::TDK_Success) + if (Result == TemplateDeductionResult::Success) return Result; // We cannot inspect base classes as part of deduction when the type @@ -1916,7 +1920,8 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Check bases according to C++14 [temp.deduct.call] p4b3: auto BaseResult = DeduceTemplateBases(S, getCanonicalRD(A), TemplateParams, P, Info, Deduced); - return BaseResult != Sema::TDK_Invalid ? BaseResult : Result; + return BaseResult != TemplateDeductionResult::Invalid ? BaseResult + : Result; } // T type::* @@ -1932,7 +1937,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *MPP = P->castAs(), *MPA = A->getAs(); if (!MPA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; QualType PPT = MPP->getPointeeType(); if (PPT->isFunctionType()) @@ -1945,7 +1950,8 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( unsigned SubTDF = TDF & TDF_IgnoreQualifiers; if (auto Result = DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, PPT, APT, Info, Deduced, SubTDF)) + S, TemplateParams, PPT, APT, Info, Deduced, SubTDF); + Result != TemplateDeductionResult::Success) return Result; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, QualType(MPP->getClass(), 0), @@ -1961,7 +1967,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *BPP = P->castAs(), *BPA = A->getAs(); if (!BPA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info, Deduced, 0); @@ -1976,7 +1982,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( if (const auto *VA = A->getAs()) { // Make sure that the vectors have the same number of elements. if (VP->getNumElements() != VA->getNumElements()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; ElementType = VA->getElementType(); } else if (const auto *VA = A->getAs()) { // We can't check the number of elements, since the argument has a @@ -1984,7 +1990,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // ordering. ElementType = VA->getElementType(); } else { - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // Perform deduction on the element types. return DeduceTemplateArgumentsByTypeMatch( @@ -1999,14 +2005,15 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the element types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, VP->getElementType(), VA->getElementType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); ArgSize = VA->getNumElements(); @@ -2022,20 +2029,21 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the element types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, VP->getElementType(), VA->getElementType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, VA->getSizeExpr(), Info, Deduced); } - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // (clang extension) @@ -2048,14 +2056,15 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the element types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, VP->getElementType(), VA->getElementType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); ArgSize = VA->getNumElements(); @@ -2071,20 +2080,21 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the element types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, VP->getElementType(), VA->getElementType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, VA->getSizeExpr(), Info, Deduced); } - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // (clang extension) @@ -2095,12 +2105,12 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *MP = P->castAs(), *MA = A->getAs(); if (!MA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Check that the dimensions are the same if (MP->getNumRows() != MA->getNumRows() || MP->getNumColumns() != MA->getNumColumns()) { - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } // Perform deduction on element types. return DeduceTemplateArgumentsByTypeMatch( @@ -2112,12 +2122,13 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( const auto *MP = P->castAs(); const auto *MA = A->getAs(); if (!MA) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; // Check the element type of the matrixes. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, MP->getElementType(), MA->getElementType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Try to deduce a matrix dimension. @@ -2132,26 +2143,26 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( std::optional ParamConst = ParamExpr->getIntegerConstantExpr(S.Context); if (!ParamConst) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; if (ACM) { if ((ACM->*GetArgDimension)() == *ParamConst) - return Sema::TDK_Success; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::Success; + return TemplateDeductionResult::NonDeducedMismatch; } Expr *ArgExpr = (ADM->*GetArgDimensionExpr)(); if (std::optional ArgConst = ArgExpr->getIntegerConstantExpr(S.Context)) if (*ArgConst == *ParamConst) - return Sema::TDK_Success; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::Success; + return TemplateDeductionResult::NonDeducedMismatch; } const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, ParamExpr); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (ACM) { llvm::APSInt ArgConst( @@ -2169,7 +2180,8 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( if (auto Result = DeduceMatrixArg(MP->getRowExpr(), MA, &ConstantMatrixType::getNumRows, - &DependentSizedMatrixType::getRowExpr)) + &DependentSizedMatrixType::getRowExpr); + Result != TemplateDeductionResult::Success) return Result; return DeduceMatrixArg(MP->getColumnExpr(), MA, @@ -2187,14 +2199,15 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the pointer type. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(), - Info, Deduced, TDF)) + Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the address space, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced); @@ -2208,33 +2221,34 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( // Perform deduction on the pointer types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, ASP->getPointeeType(), - S.Context.removeAddrSpaceQualType(A), Info, Deduced, TDF)) + S.Context.removeAddrSpaceQualType(A), Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Perform deduction on the address space, if we can. const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgAddressSpace, S.Context.IntTy, true, Info, Deduced); } - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } case Type::DependentBitInt: { const auto *IP = P->castAs(); if (const auto *IA = A->getAs()) { if (IP->isUnsigned() != IA->isUnsigned()) - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, IP->getNumBitsExpr()); if (!NTTP) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); ArgSize = IA->getNumBits(); @@ -2246,11 +2260,11 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( if (const auto *IA = A->getAs()) { if (IP->isUnsigned() != IA->isUnsigned()) - return Sema::TDK_NonDeducedMismatch; - return Sema::TDK_Success; + return TemplateDeductionResult::NonDeducedMismatch; + return TemplateDeductionResult::Success; } - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } case Type::TypeOfExpr: @@ -2264,7 +2278,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( case Type::PackExpansion: case Type::Pipe: // No template argument deduction for these types - return Sema::TDK_Success; + return TemplateDeductionResult::Success; case Type::PackIndexing: { const PackIndexingType *PIT = P->getAs(); @@ -2272,14 +2286,14 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, PIT->getSelectedType(), A, Info, Deduced, TDF); } - return Sema::TDK_IncompletePack; + return TemplateDeductionResult::IncompletePack; } } llvm_unreachable("Invalid Type Class!"); } -static Sema::TemplateDeductionResult +static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, const TemplateArgument &P, TemplateArgument A, TemplateDeductionInfo &Info, @@ -2300,7 +2314,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, S, TemplateParams, P.getAsType(), A.getAsType(), Info, Deduced, 0); Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::Template: if (A.getKind() == TemplateArgument::Template) @@ -2308,7 +2322,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, A.getAsTemplate(), Info, Deduced); Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::TemplateExpansion: llvm_unreachable("caller should handle pack expansions"); @@ -2316,38 +2330,38 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, case TemplateArgument::Declaration: if (A.getKind() == TemplateArgument::Declaration && isSameDeclaration(P.getAsDecl(), A.getAsDecl())) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::NullPtr: if (A.getKind() == TemplateArgument::NullPtr && S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType())) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::Integral: if (A.getKind() == TemplateArgument::Integral) { if (hasSameExtendedValue(P.getAsIntegral(), A.getAsIntegral())) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::StructuralValue: if (A.getKind() == TemplateArgument::StructuralValue && A.structurallyEquals(P)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::Expression: if (const NonTypeTemplateParmDecl *NTTP = @@ -2376,13 +2390,13 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, case TemplateArgument::Pack: Info.FirstArg = P; Info.SecondArg = A; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } llvm_unreachable("Unknown template argument kind"); } // Can't deduce anything, but that's okay. - return Sema::TDK_Success; + return TemplateDeductionResult::Success; case TemplateArgument::Pack: llvm_unreachable("Argument packs should be expanded by the caller!"); } @@ -2433,7 +2447,7 @@ static bool hasPackExpansionBeforeEnd(ArrayRef Args) { return false; } -static Sema::TemplateDeductionResult +static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef Ps, ArrayRef As, @@ -2445,7 +2459,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // the last template argument, the entire template argument list is a // non-deduced context. if (hasPackExpansionBeforeEnd(Ps)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // C++0x [temp.deduct.type]p9: // If P has a form that contains or , then each argument Pi of the @@ -2460,18 +2474,19 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Check whether we have enough arguments. if (!hasTemplateArgumentForDeduction(As, ArgIdx)) return NumberOfArgumentsMustMatch - ? Sema::TDK_MiscellaneousDeductionFailure - : Sema::TDK_Success; + ? TemplateDeductionResult::MiscellaneousDeductionFailure + : TemplateDeductionResult::Success; // C++1z [temp.deduct.type]p9: // During partial ordering, if Ai was originally a pack expansion [and] // Pi is not a pack expansion, template argument deduction fails. if (As[ArgIdx].isPackExpansion()) - return Sema::TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; // Perform deduction for this Pi/Ai pair. if (auto Result = DeduceTemplateArguments(S, TemplateParams, P, - As[ArgIdx], Info, Deduced)) + As[ArgIdx], Info, Deduced); + Result != TemplateDeductionResult::Success) return Result; // Move to the next argument. @@ -2499,7 +2514,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ++ArgIdx) { // Deduce template arguments from the pattern. if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pattern, - As[ArgIdx], Info, Deduced)) + As[ArgIdx], Info, Deduced); + Result != TemplateDeductionResult::Success) return Result; PackScope.nextPackElement(); @@ -2507,11 +2523,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish()) + if (auto Result = PackScope.finish(); + Result != TemplateDeductionResult::Success) return Result; } - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Determine whether two template arguments are the same. @@ -2773,7 +2790,7 @@ static bool ConvertDeducedTemplateArgument( // ClassTemplatePartialSpecializationDecl sadly does not derive from // TemplateDecl. template -static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( +static TemplateDeductionResult ConvertDeducedTemplateArguments( Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl &Deduced, TemplateDeductionInfo &Info, @@ -2792,7 +2809,8 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( // FIXME: Where did the word "trailing" come from? if (Deduced[I].isNull() && Param->isTemplateParameterPack()) { if (auto Result = - PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish()) + PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish(); + Result != TemplateDeductionResult::Success) return Result; } @@ -2829,7 +2847,7 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( Info.reset( TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder), TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } continue; @@ -2841,7 +2859,7 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( if (!TD) { assert(isa(Template) || isa(Template)); - return Sema::TDK_Incomplete; + return TemplateDeductionResult::Incomplete; } TemplateArgumentLoc DefArg; @@ -2871,8 +2889,8 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); if (PartialOverloading) break; - return HasDefaultArg ? Sema::TDK_SubstitutionFailure - : Sema::TDK_Incomplete; + return HasDefaultArg ? TemplateDeductionResult::SubstitutionFailure + : TemplateDeductionResult::Incomplete; } // Check whether we can actually use the default argument. @@ -2884,13 +2902,13 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( // FIXME: These template arguments are temporary. Free them! Info.reset(TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder), TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } // If we get here, we successfully used the default template argument. } - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } static DeclContext *getAsDeclContextOrEnclosing(Decl *D) { @@ -2926,7 +2944,7 @@ bool DeducedArgsNeedReplacement( } template -static Sema::TemplateDeductionResult +static TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, ArrayRef SugaredDeducedArgs, ArrayRef CanonicalDeducedArgs, @@ -2959,15 +2977,15 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, Info.reset( TemplateArgumentList::CreateCopy(S.Context, SugaredDeducedArgs), TemplateArgumentList::CreateCopy(S.Context, CanonicalDeducedArgs)); - return Sema::TDK_ConstraintsNotSatisfied; + return TemplateDeductionResult::ConstraintsNotSatisfied; } - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Complete template argument deduction for a partial specialization. template static std::enable_if_t::value, - Sema::TemplateDeductionResult> + TemplateDeductionResult> FinishTemplateArgumentDeduction( Sema &S, T *Partial, bool IsPartialOrdering, ArrayRef TemplateArgs, @@ -2986,7 +3004,8 @@ FinishTemplateArgumentDeduction( SmallVector SugaredBuilder, CanonicalBuilder; if (auto Result = ConvertDeducedTemplateArguments( S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder, - CanonicalBuilder)) + CanonicalBuilder); + Result != TemplateDeductionResult::Success) return Result; // Form the template argument list from the deduced template arguments. @@ -3023,7 +3042,7 @@ FinishTemplateArgumentDeduction( Partial->getTemplateParameters()->getParam(ParamIdx)); Info.Param = makeTemplateParameter(Param); Info.FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument(); - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } bool ConstraintsNotSatisfied; @@ -3033,8 +3052,9 @@ FinishTemplateArgumentDeduction( Template, Partial->getLocation(), InstArgs, false, SugaredConvertedInstArgs, CanonicalConvertedInstArgs, /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied)) - return ConstraintsNotSatisfied ? Sema::TDK_ConstraintsNotSatisfied - : Sema::TDK_SubstitutionFailure; + return ConstraintsNotSatisfied + ? TemplateDeductionResult::ConstraintsNotSatisfied + : TemplateDeductionResult::SubstitutionFailure; TemplateParameterList *TemplateParams = Template->getTemplateParameters(); for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) { @@ -3044,24 +3064,25 @@ FinishTemplateArgumentDeduction( Info.Param = makeTemplateParameter(TemplateParams->getParam(I)); Info.FirstArg = TemplateArgs[I]; Info.SecondArg = InstArg; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } } if (Trap.hasErrorOccurred()) - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; if (auto Result = CheckDeducedArgumentConstraints(S, Partial, SugaredBuilder, - CanonicalBuilder, Info)) + CanonicalBuilder, Info); + Result != TemplateDeductionResult::Success) return Result; - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Complete template argument deduction for a class or variable template, /// when partial ordering against a partial specialization. // FIXME: Factor out duplication with partial specialization version above. -static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( +static TemplateDeductionResult FinishTemplateArgumentDeduction( Sema &S, TemplateDecl *Template, bool PartialOrdering, ArrayRef TemplateArgs, SmallVectorImpl &Deduced, @@ -3081,7 +3102,8 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( S, Template, /*IsDeduced*/ PartialOrdering, Deduced, Info, SugaredBuilder, CanonicalBuilder, /*CurrentInstantiationScope=*/nullptr, - /*NumAlreadyConverted=*/0U, /*PartialOverloading=*/false)) + /*NumAlreadyConverted=*/0U, /*PartialOverloading=*/false); + Result != TemplateDeductionResult::Success) return Result; // Check that we produced the correct argument list. @@ -3093,29 +3115,30 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( Info.Param = makeTemplateParameter(TemplateParams->getParam(I)); Info.FirstArg = TemplateArgs[I]; Info.SecondArg = InstArg; - return Sema::TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } } if (Trap.hasErrorOccurred()) - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; if (auto Result = CheckDeducedArgumentConstraints(S, Template, SugaredBuilder, - CanonicalBuilder, Info)) + CanonicalBuilder, Info); + Result != TemplateDeductionResult::Success) return Result; - return Sema::TDK_Success; + 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]. -Sema::TemplateDeductionResult +TemplateDeductionResult Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef TemplateArgs, TemplateDeductionInfo &Info) { if (Partial->isInvalidDecl()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; // C++ [temp.class.spec.match]p2: // A partial specialization matches a given actual template @@ -3137,17 +3160,18 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, if (TemplateDeductionResult Result = ::DeduceTemplateArguments( *this, Partial->getTemplateParameters(), Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced, - /*NumberOfArgumentsMustMatch=*/false)) + /*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 TDK_InstantiationDepth; + return TemplateDeductionResult::InstantiationDepth; if (Trap.hasErrorOccurred()) - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; TemplateDeductionResult Result; runWithSufficientStackSpace(Info.getLocation(), [&] { @@ -3161,12 +3185,12 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, /// Perform template argument deduction to determine whether /// the given template arguments match the given variable template /// partial specialization per C++ [temp.class.spec.match]. -Sema::TemplateDeductionResult +TemplateDeductionResult Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, ArrayRef TemplateArgs, TemplateDeductionInfo &Info) { if (Partial->isInvalidDecl()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; // C++ [temp.class.spec.match]p2: // A partial specialization matches a given actual template @@ -3188,17 +3212,18 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, if (TemplateDeductionResult Result = ::DeduceTemplateArguments( *this, Partial->getTemplateParameters(), Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced, - /*NumberOfArgumentsMustMatch=*/false)) + /*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 TDK_InstantiationDepth; + return TemplateDeductionResult::InstantiationDepth; if (Trap.hasErrorOccurred()) - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; TemplateDeductionResult Result; runWithSufficientStackSpace(Info.getLocation(), [&] { @@ -3251,9 +3276,9 @@ static bool isSimpleTemplateIdType(QualType T) { /// \param Info if substitution fails for any reason, this object will be /// populated with more information about the failure. /// -/// \returns TDK_Success if substitution was successful, or some failure -/// condition. -Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( +/// \returns TemplateDeductionResult::Success if substitution was successful, or +/// some failure condition. +TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl &Deduced, @@ -3271,7 +3296,7 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( if (FunctionType) *FunctionType = Function->getType(); - return TDK_Success; + return TemplateDeductionResult::Success; } // Unevaluated SFINAE context. @@ -3294,7 +3319,7 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( *this, Info.getLocation(), FunctionTemplate, DeducedArgs, CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info); if (Inst.isInvalid()) - return TDK_InstantiationDepth; + return TemplateDeductionResult::InstantiationDepth; if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(), ExplicitTemplateArgs, true, SugaredBuilder, @@ -3303,9 +3328,9 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( Trap.hasErrorOccurred()) { unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); - return TDK_InvalidExplicitArguments; + return TemplateDeductionResult::InvalidExplicitArguments; } // Form the template argument list from the explicitly-specified @@ -3364,7 +3389,7 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( if (SubstParmTypes(Function->getLocation(), Function->parameters(), Proto->getExtParameterInfosOrNull(), MLTAL, ParamTypes, /*params=*/nullptr, ExtParamInfos)) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } // Instantiate the return type. @@ -3390,13 +3415,13 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SubstType(Proto->getReturnType(), MLTAL, Function->getTypeSpecStartLoc(), Function->getDeclName()); if (ResultType.isNull() || Trap.hasErrorOccurred()) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; // CUDA: Kernel function must have 'void' return type. if (getLangOpts().CUDA) if (Function->hasAttr() && !ResultType->isVoidType()) { Diag(Function->getLocation(), diag::err_kern_type_not_void_return) << Function->getType() << Function->getSourceRange(); - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } } @@ -3406,7 +3431,7 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SubstParmTypes(Function->getLocation(), Function->parameters(), Proto->getExtParameterInfosOrNull(), MLTAL, ParamTypes, /*params*/ nullptr, ExtParamInfos)) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; if (FunctionType) { auto EPI = Proto->getExtProtoInfo(); @@ -3426,14 +3451,14 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/false, /*SkipForSpecialization=*/true))) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; *FunctionType = BuildFunctionType(ResultType, ParamTypes, Function->getLocation(), Function->getDeclName(), EPI); if (FunctionType->isNull() || Trap.hasErrorOccurred()) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } // C++ [temp.arg.explicit]p2: @@ -3455,23 +3480,24 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( Deduced.push_back(Arg); } - return TDK_Success; + return TemplateDeductionResult::Success; } /// Check whether the deduced argument type for a call to a function /// template matches the actual argument type per C++ [temp.deduct.call]p4. -static Sema::TemplateDeductionResult +static TemplateDeductionResult CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, Sema::OriginalCallArg OriginalArg, QualType DeducedA) { ASTContext &Context = S.Context; - auto Failed = [&]() -> Sema::TemplateDeductionResult { + auto Failed = [&]() -> TemplateDeductionResult { Info.FirstArg = TemplateArgument(DeducedA); Info.SecondArg = TemplateArgument(OriginalArg.OriginalArgType); Info.CallArgIndex = OriginalArg.ArgIdx; - return OriginalArg.DecomposedParam ? Sema::TDK_DeducedMismatchNested - : Sema::TDK_DeducedMismatch; + return OriginalArg.DecomposedParam + ? TemplateDeductionResult::DeducedMismatchNested + : TemplateDeductionResult::DeducedMismatch; }; QualType A = OriginalArg.OriginalArgType; @@ -3479,7 +3505,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, // Check for type equality (top-level cv-qualifiers are ignored). if (Context.hasSameUnqualifiedType(A, DeducedA)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Strip off references on the argument types; they aren't needed for // the following checks. @@ -3503,7 +3529,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, // the deduced A can be F. QualType Tmp; if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA, Tmp)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; Qualifiers AQuals = A.getQualifiers(); Qualifiers DeducedAQuals = DeducedA.getQualifiers(); @@ -3544,7 +3570,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, (S.IsQualificationConversion(A, DeducedA, false, ObjCLifetimeConversion) || S.IsFunctionConversion(A, DeducedA, ResultTy))) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // - If P is a class and P has the form simple-template-id, then the // transformed A can be a derived class of the deduced A. [...] @@ -3565,11 +3591,11 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, } if (Context.hasSameUnqualifiedType(A, DeducedA)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (A->isRecordType() && isSimpleTemplateIdType(OriginalParamType) && S.IsDerivedFrom(Info.getLocation(), A, DeducedA)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; return Failed(); } @@ -3607,7 +3633,7 @@ static unsigned getPackIndexForParam(Sema &S, // if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl`, // we'll try to instantiate and update its explicit specifier after constraint // checking. -static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( +static TemplateDeductionResult instantiateExplicitSpecifierDeferred( Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, @@ -3626,24 +3652,24 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( ExplicitSpecifier ES = GetExplicitSpecifier(Specialization); Expr *ExplicitExpr = ES.getExpr(); if (!ExplicitExpr) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (!ExplicitExpr->isValueDependent()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; Sema::InstantiatingTemplate Inst( S, Info.getLocation(), FunctionTemplate, DeducedArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); if (Inst.isInvalid()) - return Sema::TDK_InstantiationDepth; + return TemplateDeductionResult::InstantiationDepth; Sema::SFINAETrap Trap(S); const ExplicitSpecifier InstantiatedES = S.instantiateExplicitSpecifier(SubstArgs, ES); if (InstantiatedES.isInvalid() || Trap.hasErrorOccurred()) { Specialization->setInvalidDecl(true); - return Sema::TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } SetExplicitSpecifier(Specialization, InstantiatedES); - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Finish template argument deduction for a function template, @@ -3652,7 +3678,7 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( /// /// \param OriginalCallArgs If non-NULL, the original call arguments against /// which the deduced argument types should be compared. -Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( +TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, @@ -3671,7 +3697,7 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( *this, Info.getLocation(), FunctionTemplate, DeducedArgs, CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); if (Inst.isInvalid()) - return TDK_InstantiationDepth; + return TemplateDeductionResult::InstantiationDepth; ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl()); @@ -3682,7 +3708,8 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( if (auto Result = ConvertDeducedTemplateArguments( *this, FunctionTemplate, /*IsDeduced*/ true, Deduced, Info, SugaredBuilder, CanonicalBuilder, CurrentInstantiationScope, - NumExplicitlySpecified, PartialOverloading)) + NumExplicitlySpecified, PartialOverloading); + Result != TemplateDeductionResult::Success) return Result; // C++ [temp.deduct.call]p10: [DR1391] @@ -3695,7 +3722,7 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // explicitly-specified template arguments, if the corresponding argument // A cannot be implicitly converted to P, deduction fails. if (CheckNonDependent()) - return TDK_NonDependentConversionFailure; + return TemplateDeductionResult::NonDependentConversionFailure; // Form the template argument list from the deduced template arguments. TemplateArgumentList *SugaredDeducedArgumentList = @@ -3732,7 +3759,7 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( Specialization = cast_or_null( SubstDecl(FD, Owner, SubstArgs)); if (!Specialization || Specialization->isInvalidDecl()) - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() == FunctionTemplate->getCanonicalDecl()); @@ -3749,7 +3776,7 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // failure. if (Trap.hasErrorOccurred()) { Specialization->setInvalidDecl(true); - return TDK_SubstitutionFailure; + return TemplateDeductionResult::SubstitutionFailure; } // C++2a [temp.deduct]p5 @@ -3766,12 +3793,12 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( if (CheckInstantiatedFunctionTemplateConstraints( Info.getLocation(), Specialization, CanonicalBuilder, Info.AssociatedConstraintsSatisfaction)) - return TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) { Info.reset(Info.takeSugared(), TemplateArgumentList::CreateCopy(Context, CanonicalBuilder)); - return TDK_ConstraintsNotSatisfied; + return TemplateDeductionResult::ConstraintsNotSatisfied; } } @@ -3779,10 +3806,11 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // substitution of `FD` before. So, we try to instantiate it back if // `Specialization` is either a constructor or a conversion function. if (isa(Specialization)) { - if (TDK_Success != instantiateExplicitSpecifierDeferred( - *this, Specialization, SubstArgs, Info, - FunctionTemplate, DeducedArgs)) { - return TDK_SubstitutionFailure; + if (TemplateDeductionResult::Success != + instantiateExplicitSpecifierDeferred(*this, Specialization, SubstArgs, + Info, FunctionTemplate, + DeducedArgs)) { + return TemplateDeductionResult::SubstitutionFailure; } } @@ -3829,7 +3857,8 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( } if (auto TDK = - CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA)) + CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA); + TDK != TemplateDeductionResult::Success) return TDK; } } @@ -3846,7 +3875,7 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( .append(Info.diag_begin(), Info.diag_end()); } - return TDK_Success; + return TemplateDeductionResult::Success; } /// Gets the type of a function for template-argument-deducton @@ -3938,7 +3967,8 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(Ovl->getNameLoc()); if (S.DeduceTemplateArguments(FunTmpl, &ExplicitTemplateArgs, - Specialization, Info)) + Specialization, + Info) != TemplateDeductionResult::Success) continue; D = Specialization; @@ -3968,10 +3998,10 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, SmallVector Deduced(TemplateParams->size()); TemplateDeductionInfo Info(Ovl->getNameLoc()); - Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType, - ArgType, Info, Deduced, TDF); - if (Result) continue; + TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF); + if (Result != TemplateDeductionResult::Success) + continue; if (!Match.isNull()) return {}; Match = ArgType; @@ -4084,7 +4114,7 @@ static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T); -static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( +static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, @@ -4096,7 +4126,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( /// Attempt template argument deduction from an initializer list /// deemed to be an argument in a function call. -static Sema::TemplateDeductionResult DeduceFromInitializerList( +static TemplateDeductionResult DeduceFromInitializerList( Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, InitListExpr *ILE, TemplateDeductionInfo &Info, SmallVectorImpl &Deduced, @@ -4111,7 +4141,7 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( // // We've already removed references and cv-qualifiers here. if (!ILE->getNumInits()) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; QualType ElTy; auto *ArrTy = S.Context.getAsArrayType(AdjustedParamType); @@ -4120,14 +4150,14 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( else if (!S.isStdInitializerList(AdjustedParamType, &ElTy)) { // Otherwise, an initializer list argument causes the parameter to be // considered a non-deduced context - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } // Resolving a core issue: a braced-init-list containing any designators is // a non-deduced context. for (Expr *E : ILE->inits()) if (isa(E)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // Deduction only needs to be done for dependent types. if (ElTy->isDependentType()) { @@ -4135,7 +4165,8 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( if (auto Result = DeduceTemplateArgumentsFromCallArgument( S, TemplateParams, 0, ElTy, E->getType(), E->Classify(S.getASTContext()), E, Info, Deduced, - OriginalCallArgs, true, ArgIdx, TDF)) + OriginalCallArgs, true, ArgIdx, TDF); + Result != TemplateDeductionResult::Success) return Result; } } @@ -4154,17 +4185,18 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( llvm::APInt Size(S.Context.getIntWidth(T), ILE->getNumInits()); if (auto Result = DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, llvm::APSInt(Size), T, - /*ArrayBound=*/true, Info, Deduced)) + /*ArrayBound=*/true, Info, Deduced); + Result != TemplateDeductionResult::Success) return Result; } } - return Sema::TDK_Success; + return TemplateDeductionResult::Success; } /// Perform template argument deduction per [temp.deduct.call] for a /// single parameter / argument pair. -static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( +static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, @@ -4181,7 +4213,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( if (AdjustFunctionParmAndArgTypesForDeduction( S, TemplateParams, FirstInnerIndex, ParamType, ArgType, ArgClassification, Arg, TDF, FailedTSC)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; // If [...] the argument is a non-empty initializer list [...] if (InitListExpr *ILE = dyn_cast_if_present(Arg)) @@ -4221,11 +4253,11 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( /// \param CheckNonDependent A callback to invoke to check conversions for /// non-dependent parameters, between deduction and substitution, per DR1391. /// If this returns true, substitution will be skipped and we return -/// TDK_NonDependentConversionFailure. The callback is passed the parameter -/// types (after substituting explicit template arguments). +/// TemplateDeductionResult::NonDependentConversionFailure. The callback is +/// passed the parameter types (after substituting explicit template arguments). /// /// \returns the result of template argument deduction. -Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( +TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, FunctionDecl *&Specialization, TemplateDeductionInfo &Info, @@ -4233,7 +4265,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( QualType ObjectType, Expr::Classification ObjectClassification, llvm::function_ref)> CheckNonDependent) { if (FunctionTemplate->isInvalidDecl()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); unsigned NumParams = Function->getNumParams(); @@ -4252,14 +4284,14 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // of the call (call it A) as described below. if (Args.size() < Function->getMinRequiredExplicitArguments() && !PartialOverloading) - return TDK_TooFewArguments; + return TemplateDeductionResult::TooFewArguments; else if (TooManyArguments(NumParams, Args.size() + ExplicitObjectOffset, PartialOverloading)) { const auto *Proto = Function->getType()->castAs(); if (Proto->isTemplateVariadic()) /* Do nothing */; else if (!Proto->isVariadic()) - return TDK_TooManyArguments; + return TemplateDeductionResult::TooManyArguments; } // The types of the parameters from which we will perform template argument @@ -4277,7 +4309,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr, Info); }); - if (Result) + if (Result != TemplateDeductionResult::Success) return Result; NumExplicitlySpecified = Deduced.size(); @@ -4297,7 +4329,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // parameter that contains template-parameters that participate in // template argument deduction ... if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) - return Sema::TDK_Success; + return TemplateDeductionResult::Success; if (ExplicitObjetArgument) { // ... with the type of the corresponding argument @@ -4334,13 +4366,15 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( if (ParamIdx == 0 && HasExplicitObject) { if (auto Result = DeduceCallArgument(ParamType, 0, - /*ExplicitObjetArgument=*/true)) + /*ExplicitObjetArgument=*/true); + Result != TemplateDeductionResult::Success) return Result; continue; } if (auto Result = DeduceCallArgument(ParamType, ArgIdx++, - /*ExplicitObjetArgument=*/false)) + /*ExplicitObjetArgument=*/false); + Result != TemplateDeductionResult::Success) return Result; continue; @@ -4374,7 +4408,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( PackScope.nextPackElement(), ++ArgIdx) { ParamTypesForArgChecking.push_back(ParamPattern); if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, - /*ExplicitObjetArgument=*/false)) + /*ExplicitObjetArgument=*/false); + Result != TemplateDeductionResult::Success) return Result; } } else { @@ -4414,7 +4449,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) { ParamTypesForArgChecking.push_back(ParamPattern); if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, - /*ExplicitObjetArgument=*/false)) + /*ExplicitObjetArgument=*/false); + Result != TemplateDeductionResult::Success) return Result; PackScope.nextPackElement(); @@ -4424,7 +4460,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish()) + if (auto Result = PackScope.finish(); + Result != TemplateDeductionResult::Success) return Result; } @@ -4508,13 +4545,13 @@ QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, /// specialization based on its signature, per [temp.deduct.decl]. /// /// \returns the result of template argument deduction. -Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( +TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ArgFunctionType, FunctionDecl *&Specialization, TemplateDeductionInfo &Info, bool IsAddressOfFunction) { if (FunctionTemplate->isInvalidDecl()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); TemplateParameterList *TemplateParams @@ -4533,7 +4570,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, &FunctionType, Info); }); - if (Result) + if (Result != TemplateDeductionResult::Success) return Result; NumExplicitlySpecified = Deduced.size(); @@ -4566,10 +4603,10 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( unsigned TDF = TDF_TopLevelParameterTypeList | TDF_AllowCompatibleFunctionType; // Deduce template arguments from the function type. - if (TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, - FunctionType, ArgFunctionType, - Info, Deduced, TDF)) + if (TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch( + *this, TemplateParams, FunctionType, ArgFunctionType, Info, Deduced, + TDF); + Result != TemplateDeductionResult::Success) return Result; } @@ -4579,7 +4616,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( NumExplicitlySpecified, Specialization, Info); }); - if (Result) + if (Result != TemplateDeductionResult::Success) return Result; // If the function has a deduced return type, deduce it now, so we can check @@ -4587,13 +4624,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( if (HasDeducedReturnType && IsAddressOfFunction && Specialization->getReturnType()->isUndeducedType() && DeduceReturnType(Specialization, Info.getLocation(), false)) - return TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; if (IsAddressOfFunction && getLangOpts().CPlusPlus20 && Specialization->isImmediateEscalating() && CheckIfFunctionSpecializationIsImmediate(Specialization, Info.getLocation())) - return TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; // If the function has a dependent exception specification, resolve it now, // so we can check that the exception specification matches. @@ -4602,7 +4639,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( if (getLangOpts().CPlusPlus17 && isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) && !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT)) - return TDK_MiscellaneousDeductionFailure; + return TemplateDeductionResult::MiscellaneousDeductionFailure; // Adjust the exception specification of the argument to match the // substituted and resolved type we just formed. (Calling convention and @@ -4632,22 +4669,22 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( : !Context.hasSameType(SpecializationType, ArgFunctionType)) { Info.FirstArg = TemplateArgument(SpecializationType); Info.SecondArg = TemplateArgument(ArgFunctionType); - return TDK_NonDeducedMismatch; + return TemplateDeductionResult::NonDeducedMismatch; } } - return TDK_Success; + return TemplateDeductionResult::Success; } /// Deduce template arguments for a templated conversion /// function (C++ [temp.deduct.conv]) and, if successful, produce a /// conversion function template specialization. -Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( +TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplateDecl *ConversionTemplate, QualType ObjectType, Expr::Classification ObjectClassification, QualType ToType, CXXConversionDecl *&Specialization, TemplateDeductionInfo &Info) { if (ConversionTemplate->isInvalidDecl()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; CXXConversionDecl *ConversionGeneric = cast(ConversionTemplate->getTemplatedDecl()); @@ -4749,13 +4786,14 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( *this, TemplateParams, getFirstInnerIndex(ConversionTemplate), ParamType, ObjectType, ObjectClassification, /*Arg=*/nullptr, Info, Deduced, OriginalCallArgs, - /*Decomposed*/ false, 0, /*TDF*/ 0)) + /*Decomposed*/ false, 0, /*TDF*/ 0); + Result != TemplateDeductionResult::Success) return Result; } - if (TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, - P, A, Info, Deduced, TDF)) + if (TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch( + *this, TemplateParams, P, A, Info, Deduced, TDF); + Result != TemplateDeductionResult::Success) return Result; // Create an Instantiation Scope for finalizing the operator. @@ -4796,11 +4834,12 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( /// naming a function template specialization. /// /// \returns the result of template argument deduction. -Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( - FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo *ExplicitTemplateArgs, - FunctionDecl *&Specialization, TemplateDeductionInfo &Info, - bool IsAddressOfFunction) { +TemplateDeductionResult +Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, + TemplateArgumentListInfo *ExplicitTemplateArgs, + FunctionDecl *&Specialization, + TemplateDeductionInfo &Info, + bool IsAddressOfFunction) { return DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, QualType(), Specialization, Info, IsAddressOfFunction); @@ -4962,14 +5001,14 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, /// should be specified in the 'Info' parameter. /// \param IgnoreConstraints Set if we should not fail if the deduced type does /// not satisfy the type-constraint in the auto type. -Sema::TemplateDeductionResult +TemplateDeductionResult Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, TemplateDeductionInfo &Info, bool DependentDeduction, bool IgnoreConstraints, TemplateSpecCandidateSet *FailedTSC) { assert(DependentDeduction || Info.getDeducedDepth() == 0); if (Init->containsErrors()) - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; const AutoType *AT = Type.getType()->getContainedAutoType(); assert(AT); @@ -4977,7 +5016,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, if (Init->getType()->isNonOverloadPlaceholderType() || AT->isDecltypeAuto()) { ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); if (NonPlaceholder.isInvalid()) - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; Init = NonPlaceholder.get(); } @@ -4989,7 +5028,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, Init->containsUnexpandedParameterPack())) { Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); - return TDK_Success; + return TemplateDeductionResult::Success; } // Make sure that we treat 'char[]' equaly as 'char*' in C23 mode. @@ -4999,7 +5038,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, TypeLoc TL = TypeLoc(Init->getType(), Type.getOpaqueData()); Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(TL); assert(!Result.isNull() && "substituting DependentTy can't fail"); - return TDK_Success; + return TemplateDeductionResult::Success; } // Emit a warning if 'auto*' is used in pedantic and in C23 mode. @@ -5011,7 +5050,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, if (!getLangOpts().CPlusPlus && InitList) { Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c) << (int)AT->getKeyword() << getLangOpts().C23; - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; } // Deduce type of TemplParam in Func(Init) @@ -5025,7 +5064,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); - return TDK_Success; + return TemplateDeductionResult::Success; } return TDK; }; @@ -5037,7 +5076,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, if (AT->isDecltypeAuto()) { if (InitList) { Diag(Init->getBeginLoc(), diag::err_decltype_auto_initializer_list); - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; } DeducedType = getDecltypeForExpr(Init); @@ -5060,24 +5099,25 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, // deduce against that. Such deduction only succeeds if removing // cv-qualifiers and references results in std::initializer_list. if (!Type.getType().getNonReferenceType()->getAs()) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; SourceRange DeducedFromInitRange; for (Expr *Init : InitList->inits()) { // Resolving a core issue: a braced-init-list containing any designators // is a non-deduced context. if (isa(Init)) - return TDK_Invalid; + return TemplateDeductionResult::Invalid; if (auto TDK = DeduceTemplateArgumentsFromCallArgument( *this, TemplateParamsSt.get(), 0, TemplArg, Init->getType(), Init->Classify(getASTContext()), Init, Info, Deduced, OriginalCallArgs, /*Decomposed=*/true, - /*ArgIdx=*/0, /*TDF=*/0)) { - if (TDK == TDK_Inconsistent) { + /*ArgIdx=*/0, /*TDF=*/0); + TDK != TemplateDeductionResult::Success) { + if (TDK == TemplateDeductionResult::Inconsistent) { Diag(Info.getLocation(), diag::err_auto_inconsistent_deduction) << Info.FirstArg << Info.SecondArg << DeducedFromInitRange << Init->getSourceRange(); - return DeductionFailed(TDK_AlreadyDiagnosed); + return DeductionFailed(TemplateDeductionResult::AlreadyDiagnosed); } return DeductionFailed(TDK); } @@ -5089,7 +5129,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, } else { if (!getLangOpts().CPlusPlus && Init->refersToBitField()) { Diag(Loc, diag::err_auto_bitfield); - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; } QualType FuncParam = SubstituteDeducedTypeTransform(*this, TemplArg).Apply(Type); @@ -5099,19 +5139,20 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, *this, TemplateParamsSt.get(), 0, FuncParam, Init->getType(), Init->Classify(getASTContext()), Init, Info, Deduced, OriginalCallArgs, /*Decomposed=*/false, /*ArgIdx=*/0, /*TDF=*/0, - FailedTSC)) + FailedTSC); + TDK != TemplateDeductionResult::Success) return DeductionFailed(TDK); } // Could be null if somehow 'auto' appears in a non-deduced context. if (Deduced[0].getKind() != TemplateArgument::Type) - return DeductionFailed(TDK_Incomplete); + return DeductionFailed(TemplateDeductionResult::Incomplete); DeducedType = Deduced[0].getAsType(); if (InitList) { DeducedType = BuildStdInitializerList(DeducedType, Loc); if (DeducedType.isNull()) - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; } } @@ -5119,7 +5160,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, if (!Context.hasSameType(DeducedType, Result)) { Info.FirstArg = Result; Info.SecondArg = DeducedType; - return DeductionFailed(TDK_Inconsistent); + return DeductionFailed(TemplateDeductionResult::Inconsistent); } DeducedType = Context.getCommonSugaredType(Result, DeducedType); } @@ -5127,11 +5168,11 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, if (AT->isConstrained() && !IgnoreConstraints && CheckDeducedPlaceholderConstraints( *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType)) - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type); if (Result.isNull()) - return TDK_AlreadyDiagnosed; + return TemplateDeductionResult::AlreadyDiagnosed; // Check that the deduced argument type is compatible with the original // argument type per C++ [temp.deduct.call]p4. @@ -5140,13 +5181,14 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, assert((bool)InitList == OriginalArg.DecomposedParam && "decomposed non-init-list in auto deduction?"); if (auto TDK = - CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA)) { + CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA); + TDK != TemplateDeductionResult::Success) { Result = QualType(); return DeductionFailed(TDK); } } - return TDK_Success; + return TemplateDeductionResult::Success; } QualType Sema::SubstAutoType(QualType TypeWithAuto, @@ -5403,7 +5445,8 @@ static bool isAtLeastAsSpecializedAs(Sema &S, if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(), Args1.data(), Args1.size(), Info, Deduced, - TDF_None, /*PartialOrdering=*/true)) + TDF_None, /*PartialOrdering=*/true) != + TemplateDeductionResult::Success) return false; break; @@ -5415,17 +5458,17 @@ static bool isAtLeastAsSpecializedAs(Sema &S, if (DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(), Info, Deduced, TDF_None, - /*PartialOrdering=*/true)) + /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; case TPOC_Other: // - In other contexts (14.6.6.2) the function template's function type // is used. - if (DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - FD2->getType(), FD1->getType(), - Info, Deduced, TDF_None, - /*PartialOrdering=*/true)) + if (DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced, + TDF_None, + /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; } @@ -5776,9 +5819,9 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, // Determine whether P1 is at least as specialized as P2. Deduced.resize(P2->getTemplateParameters()->size()); - if (DeduceTemplateArgumentsByTypeMatch(S, P2->getTemplateParameters(), - T2, T1, Info, Deduced, TDF_None, - /*PartialOrdering=*/true)) + if (DeduceTemplateArgumentsByTypeMatch( + S, P2->getTemplateParameters(), T2, T1, Info, Deduced, TDF_None, + /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; SmallVector DeducedArgs(Deduced.begin(), @@ -5791,9 +5834,10 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, const auto *TST1 = cast(T1); bool AtLeastAsSpecialized; S.runWithSufficientStackSpace(Info.getLocation(), [&] { - AtLeastAsSpecialized = !FinishTemplateArgumentDeduction( - S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(), Deduced, - Info); + AtLeastAsSpecialized = + FinishTemplateArgumentDeduction( + S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(), + Deduced, Info) == TemplateDeductionResult::Success; }); return AtLeastAsSpecialized; } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 6d59180bc446d..371378485626c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3693,9 +3693,9 @@ bool Sema::usesPartialOrExplicitSpecialization( ->getPartialSpecializations(PartialSpecs); for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) { TemplateDeductionInfo Info(Loc); - if (!DeduceTemplateArguments(PartialSpecs[I], - ClassTemplateSpec->getTemplateArgs().asArray(), - Info)) + if (DeduceTemplateArguments(PartialSpecs[I], + ClassTemplateSpec->getTemplateArgs().asArray(), + Info) == TemplateDeductionResult::Success) return true; } @@ -3739,8 +3739,9 @@ getPatternForClassTemplateSpecialization( for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) { ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I]; TemplateDeductionInfo Info(FailedCandidates.getLocation()); - if (Sema::TemplateDeductionResult Result = S.DeduceTemplateArguments( - Partial, ClassTemplateSpec->getTemplateArgs().asArray(), Info)) { + if (TemplateDeductionResult Result = S.DeduceTemplateArguments( + Partial, ClassTemplateSpec->getTemplateArgs().asArray(), Info); + Result != TemplateDeductionResult::Success) { // Store the failed-deduction information for use in diagnostics, later. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate().set(