diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-12-31 02:02:54 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-12-31 02:02:54 +0000 |
| commit | 9b534547250a37b0cdf9fd4ac1b10dc37d3cfe4a (patch) | |
| tree | bbb5e1d3b72fa8753c0f6a214a570b6a8cf12616 /clang/lib/Sema | |
| parent | 9c1b6aad77ae19cb730c41487cc971fde43865e1 (diff) | |
| download | bcm5719-llvm-9b534547250a37b0cdf9fd4ac1b10dc37d3cfe4a.tar.gz bcm5719-llvm-9b534547250a37b0cdf9fd4ac1b10dc37d3cfe4a.zip | |
Improve diagnostic for the case where a function template candidate is rejected
by overload resolution because deduction succeeds, but the substituted
parameter type for some parameter (with deduced type) doesn't exactly match the
corresponding adjusted argument type.
llvm-svn: 256657
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 56 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 8 |
2 files changed, 58 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1caa94c9a45..e0c10e4479e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -543,6 +543,12 @@ namespace { struct DFIParamWithArguments : DFIArguments { TemplateParameter Param; }; + // Structure used by DeductionFailureInfo to store template argument + // information and the index of the problematic call argument. + struct DFIDeducedMismatchArgs : DFIArguments { + TemplateArgumentList *TemplateArgs; + unsigned CallArgIndex; + }; } /// \brief Convert from Sema's representation of template deduction information @@ -554,13 +560,14 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, DeductionFailureInfo Result; Result.Result = static_cast<unsigned>(TDK); Result.HasDiagnostic = false; - Result.Data = nullptr; switch (TDK) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: + case Sema::TDK_MiscellaneousDeductionFailure: + Result.Data = nullptr; break; case Sema::TDK_Incomplete: @@ -568,6 +575,17 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Info.Param.getOpaqueValue(); break; + case Sema::TDK_DeducedMismatch: { + // FIXME: Should allocate from normal heap so that we can free this later. + auto *Saved = new (Context) DFIDeducedMismatchArgs; + Saved->FirstArg = Info.FirstArg; + Saved->SecondArg = Info.SecondArg; + Saved->TemplateArgs = Info.take(); + Saved->CallArgIndex = Info.CallArgIndex; + Result.Data = Saved; + break; + } + case Sema::TDK_NonDeducedMismatch: { // FIXME: Should allocate from normal heap so that we can free this later. DFIArguments *Saved = new (Context) DFIArguments; @@ -601,9 +619,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, case Sema::TDK_FailedOverloadResolution: Result.Data = Info.Expression; break; - - case Sema::TDK_MiscellaneousDeductionFailure: - break; } return Result; @@ -623,6 +638,7 @@ void DeductionFailureInfo::Destroy() { case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: + case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: // FIXME: Destroy the data? Data = nullptr; @@ -657,6 +673,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_SubstitutionFailure: + case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_FailedOverloadResolution: return TemplateParameter(); @@ -692,6 +709,9 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { case Sema::TDK_FailedOverloadResolution: return nullptr; + case Sema::TDK_DeducedMismatch: + return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs; + case Sema::TDK_SubstitutionFailure: return static_cast<TemplateArgumentList*>(Data); @@ -718,6 +738,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: + case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: return &static_cast<DFIArguments*>(Data)->FirstArg; @@ -744,6 +765,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: + case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: return &static_cast<DFIArguments*>(Data)->SecondArg; @@ -763,6 +785,14 @@ Expr *DeductionFailureInfo::getExpr() { return nullptr; } +llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() { + if (static_cast<Sema::TemplateDeductionResult>(Result) == + Sema::TDK_DeducedMismatch) + return static_cast<DFIDeducedMismatchArgs*>(Data)->CallArgIndex; + + return llvm::None; +} + void OverloadCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) @@ -9397,6 +9427,23 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, return; } + case Sema::TDK_DeducedMismatch: { + // Format the template argument list into the argument string. + SmallString<128> TemplateArgString; + if (TemplateArgumentList *Args = + DeductionFailure.getTemplateArgumentList()) { + TemplateArgString = " "; + TemplateArgString += S.getTemplateArgumentBindingsText( + getDescribedTemplate(Templated)->getTemplateParameters(), *Args); + } + + S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch) + << (*DeductionFailure.getCallArgIndex() + 1) + << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() + << TemplateArgString; + break; + } + case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. TemplateArgument FirstTA = *DeductionFailure.getFirstArg(); @@ -9686,6 +9733,7 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { return 2; case Sema::TDK_SubstitutionFailure: + case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_MiscellaneousDeductionFailure: return 3; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 837e0de4038..cd54920b08c 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2954,8 +2954,12 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, continue; QualType DeducedA = Specialization->getParamDecl(ParamIdx)->getType(); - if (CheckOriginalCallArgDeduction(*this, OriginalArg, DeducedA)) - return Sema::TDK_SubstitutionFailure; + if (CheckOriginalCallArgDeduction(*this, OriginalArg, DeducedA)) { + Info.FirstArg = TemplateArgument(DeducedA); + Info.SecondArg = TemplateArgument(OriginalArg.OriginalArgType); + Info.CallArgIndex = OriginalArg.ArgIdx; + return TDK_DeducedMismatch; + } } } |

