diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-01-31 05:19:49 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-01-31 05:19:49 +0000 |
commit | 29805ca6d278b4d9563adfee67f2478f0fecdcfc (patch) | |
tree | 6103fe65ccc1fd85a434739449974a76ec470f58 /lib/Sema | |
parent | 626799b2903a2ab7f58ed82f10153bad4e0f1b7f (diff) |
Improve 'failed template argument deduction' diagnostic for the case where we
have a direct mismatch between some component of the template and some
component of the argument. The diagnostic now says what the mismatch was, but
doesn't yet say which part of the template doesn't match.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174039 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 88 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 22 |
2 files changed, 71 insertions, 39 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index dbab739832..82fe0c9ed0 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -536,12 +536,16 @@ AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) { namespace { // Structure used by OverloadCandidate::DeductionFailureInfo to store - // template parameter and template argument information. - struct DFIParamWithArguments { - TemplateParameter Param; + // template argument information. + struct DFIArguments { TemplateArgument FirstArg; TemplateArgument SecondArg; }; + // Structure used by OverloadCandidate::DeductionFailureInfo to store + // template parameter and template argument information. + struct DFIParamWithArguments : DFIArguments { + TemplateParameter Param; + }; } /// \brief Convert from Sema's representation of template deduction information @@ -567,6 +571,15 @@ static MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Info.Param.getOpaqueValue(); break; + case Sema::TDK_NonDeducedMismatch: { + // FIXME: Should allocate from normal heap so that we can free this later. + DFIArguments *Saved = new (Context) DFIArguments; + Saved->FirstArg = Info.FirstArg; + Saved->SecondArg = Info.SecondArg; + Result.Data = Saved; + break; + } + case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. @@ -592,7 +605,7 @@ static MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Info.Expression; break; - case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_MiscellaneousDeductionFailure: break; } @@ -608,10 +621,12 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() { case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: + case Sema::TDK_FailedOverloadResolution: break; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: + case Sema::TDK_NonDeducedMismatch: // FIXME: Destroy the data? Data = 0; break; @@ -626,8 +641,7 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() { break; // Unhandled - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_MiscellaneousDeductionFailure: break; } } @@ -648,6 +662,8 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() { case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_SubstitutionFailure: + case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_FailedOverloadResolution: return TemplateParameter(); case Sema::TDK_Incomplete: @@ -659,8 +675,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() { return static_cast<DFIParamWithArguments*>(Data)->Param; // Unhandled - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_MiscellaneousDeductionFailure: break; } @@ -670,24 +685,25 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() { TemplateArgumentList * OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() { switch (static_cast<Sema::TemplateDeductionResult>(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_InvalidExplicitArguments: - case Sema::TDK_Inconsistent: - case Sema::TDK_Underqualified: - return 0; + 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_InvalidExplicitArguments: + case Sema::TDK_Inconsistent: + case Sema::TDK_Underqualified: + case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_FailedOverloadResolution: + return 0; - case Sema::TDK_SubstitutionFailure: - return static_cast<TemplateArgumentList*>(Data); + case Sema::TDK_SubstitutionFailure: + return static_cast<TemplateArgumentList*>(Data); - // Unhandled - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: - break; + // Unhandled + case Sema::TDK_MiscellaneousDeductionFailure: + break; } return 0; @@ -703,15 +719,16 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() { case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: + case Sema::TDK_FailedOverloadResolution: return 0; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: - return &static_cast<DFIParamWithArguments*>(Data)->FirstArg; + case Sema::TDK_NonDeducedMismatch: + return &static_cast<DFIArguments*>(Data)->FirstArg; // Unhandled - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_MiscellaneousDeductionFailure: break; } @@ -729,15 +746,16 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() { case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: + case Sema::TDK_FailedOverloadResolution: return 0; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: - return &static_cast<DFIParamWithArguments*>(Data)->SecondArg; + case Sema::TDK_NonDeducedMismatch: + return &static_cast<DFIArguments*>(Data)->SecondArg; // Unhandled - case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_MiscellaneousDeductionFailure: break; } @@ -8463,9 +8481,16 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, return; } + case Sema::TDK_NonDeducedMismatch: + // FIXME: Provide a source location to indicate what we couldn't match. + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) + << *Cand->DeductionFailure.getFirstArg() + << *Cand->DeductionFailure.getSecondArg(); + return; + // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. - case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_MiscellaneousDeductionFailure: S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction); MaybeEmitInheritedConstructorNote(S, Fn); return; @@ -8643,6 +8668,7 @@ RankDeductionFailure(const OverloadCandidate::DeductionFailureInfo &DFI) { case Sema::TDK_SubstitutionFailure: case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_MiscellaneousDeductionFailure: return 3; case Sema::TDK_InstantiationDepth: diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 003d0161e9..421633f389 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -488,13 +488,19 @@ DeduceTemplateArguments(Sema &S, // perform template argument deduction using its template // arguments. const RecordType *RecordArg = dyn_cast<RecordType>(Arg); - if (!RecordArg) + if (!RecordArg) { + Info.FirstArg = TemplateArgument(QualType(Param, 0)); + Info.SecondArg = TemplateArgument(Arg); return Sema::TDK_NonDeducedMismatch; + } ClassTemplateSpecializationDecl *SpecArg = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl()); - if (!SpecArg) + if (!SpecArg) { + Info.FirstArg = TemplateArgument(QualType(Param, 0)); + Info.SecondArg = TemplateArgument(Arg); return Sema::TDK_NonDeducedMismatch; + } // Perform template argument deduction for the template name. if (Sema::TemplateDeductionResult Result @@ -708,7 +714,7 @@ DeduceTemplateArguments(Sema &S, if (NumParams != NumArgs && !(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) && !(NumArgs && isa<PackExpansionType>(Args[NumArgs - 1]))) - return Sema::TDK_NonDeducedMismatch; + return Sema::TDK_MiscellaneousDeductionFailure; // C++0x [temp.deduct.type]p10: // Similarly, if P has a form that contains (T), then each parameter type @@ -725,14 +731,14 @@ DeduceTemplateArguments(Sema &S, // Make sure we have an argument. if (ArgIdx >= NumArgs) - return Sema::TDK_NonDeducedMismatch; + return Sema::TDK_MiscellaneousDeductionFailure; if (isa<PackExpansionType>(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_NonDeducedMismatch; + return Sema::TDK_MiscellaneousDeductionFailure; } if (Sema::TemplateDeductionResult Result @@ -825,7 +831,7 @@ DeduceTemplateArguments(Sema &S, // Make sure we don't have any extra arguments. if (ArgIdx < NumArgs) - return Sema::TDK_NonDeducedMismatch; + return Sema::TDK_MiscellaneousDeductionFailure; return Sema::TDK_Success; } @@ -1772,7 +1778,7 @@ DeduceTemplateArguments(Sema &S, if (Args[ArgIdx].isPackExpansion()) { // FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here, // but applied to pack expansions that are template arguments. - return Sema::TDK_NonDeducedMismatch; + return Sema::TDK_MiscellaneousDeductionFailure; } // Perform deduction for this Pi/Ai pair. @@ -3365,7 +3371,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, // specialization, template argument deduction fails. if (!ArgFunctionType.isNull() && !Context.hasSameType(ArgFunctionType, Specialization->getType())) - return TDK_NonDeducedMismatch; + return TDK_MiscellaneousDeductionFailure; return TDK_Success; } |