forked from OSchip/llvm-project
Replace "failed template argument deduction" diagnostic with something useful
in the one case where we've already factored out a reason code. llvm-svn: 174036
This commit is contained in:
parent
b0944392aa
commit
8c6eeb9599
|
@ -2331,6 +2331,9 @@ def note_ovl_candidate_substitution_failure : Note<
|
|||
"candidate template ignored: substitution failure%0%1">;
|
||||
def note_ovl_candidate_disabled_by_enable_if : Note<
|
||||
"candidate template ignored: disabled by %0%1">;
|
||||
def note_ovl_candidate_failed_overload_resolution : Note<
|
||||
"candidate template ignored: couldn't resolve reference to overloaded "
|
||||
"function %0">;
|
||||
|
||||
// Note that we don't treat templates differently for this diagnostic.
|
||||
def note_ovl_candidate_arity : Note<"candidate "
|
||||
|
|
|
@ -694,6 +694,10 @@ namespace clang {
|
|||
/// \brief Return the second template argument this deduction failure
|
||||
/// refers to, if any.
|
||||
const TemplateArgument *getSecondArg();
|
||||
|
||||
/// \brief Return the expression this deduction failure refers to,
|
||||
/// if any.
|
||||
Expr *getExpr();
|
||||
|
||||
/// \brief Free any memory associated with this deduction failure.
|
||||
void Destroy();
|
||||
|
|
|
@ -47,7 +47,7 @@ class TemplateDeductionInfo {
|
|||
|
||||
public:
|
||||
TemplateDeductionInfo(SourceLocation Loc)
|
||||
: Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { }
|
||||
: Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
|
||||
|
||||
/// \brief Returns the location at which template argument is
|
||||
/// occurring.
|
||||
|
@ -150,6 +150,13 @@ public:
|
|||
///
|
||||
/// FIXME: Finish documenting this.
|
||||
TemplateArgument SecondArg;
|
||||
|
||||
/// \brief The expression which caused a deduction failure.
|
||||
///
|
||||
/// TDK_FailedOverloadResolution: this argument is the reference to
|
||||
// an overloaded function which could not be resolved to a specific
|
||||
// function.
|
||||
Expr *Expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -588,8 +588,11 @@ static MakeDeductionFailureInfo(ASTContext &Context,
|
|||
}
|
||||
break;
|
||||
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
Result.Data = Info.Expression;
|
||||
break;
|
||||
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -741,6 +744,15 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Expr *
|
||||
OverloadCandidate::DeductionFailureInfo::getExpr() {
|
||||
if (static_cast<Sema::TemplateDeductionResult>(Result) ==
|
||||
Sema::TDK_FailedOverloadResolution)
|
||||
return static_cast<Expr*>(Data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OverloadCandidateSet::destroyCandidates() {
|
||||
for (iterator i = begin(), e = end(); i != e; ++i) {
|
||||
for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii)
|
||||
|
@ -8442,10 +8454,18 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
return;
|
||||
}
|
||||
|
||||
case Sema::TDK_FailedOverloadResolution: {
|
||||
OverloadExpr::FindResult R =
|
||||
OverloadExpr::find(Cand->DeductionFailure.getExpr());
|
||||
S.Diag(Fn->getLocation(),
|
||||
diag::note_ovl_candidate_failed_overload_resolution)
|
||||
<< R.Expression->getName();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: diagnose these individually, then kill off
|
||||
// note_ovl_candidate_bad_deduction, which is uselessly vague.
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
|
||||
MaybeEmitInheritedConstructorNote(S, Fn);
|
||||
return;
|
||||
|
|
|
@ -2879,7 +2879,8 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
|
|||
/// described in C++ [temp.deduct.call].
|
||||
///
|
||||
/// \returns true if the caller should not attempt to perform any template
|
||||
/// argument deduction based on this P/A pair.
|
||||
/// argument deduction based on this P/A pair because the argument is an
|
||||
/// overloaded function set that could not be resolved.
|
||||
static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
|
||||
TemplateParameterList *TemplateParams,
|
||||
QualType &ParamType,
|
||||
|
@ -2895,7 +2896,7 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
|
|||
if (ParamRefType) {
|
||||
QualType PointeeType = ParamRefType->getPointeeType();
|
||||
|
||||
// If the argument has incomplete array type, try to complete it's type.
|
||||
// If the argument has incomplete array type, try to complete its type.
|
||||
if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0))
|
||||
ArgType = Arg->getType();
|
||||
|
||||
|
@ -2993,8 +2994,8 @@ static bool hasDeducibleTemplateParameters(Sema &S,
|
|||
|
||||
/// \brief Perform template argument deduction by matching a parameter type
|
||||
/// against a single expression, where the expression is an element of
|
||||
/// an initializer list that was originally matched against the argument
|
||||
/// type.
|
||||
/// an initializer list that was originally matched against a parameter
|
||||
/// of type \c initializer_list\<ParamType\>.
|
||||
static Sema::TemplateDeductionResult
|
||||
DeduceTemplateArgumentByListElement(Sema &S,
|
||||
TemplateParameterList *TemplateParams,
|
||||
|
@ -3023,8 +3024,10 @@ DeduceTemplateArgumentByListElement(Sema &S,
|
|||
// For all other cases, just match by type.
|
||||
QualType ArgType = Arg->getType();
|
||||
if (AdjustFunctionParmAndArgTypesForDeduction(S, TemplateParams, ParamType,
|
||||
ArgType, Arg, TDF))
|
||||
ArgType, Arg, TDF)) {
|
||||
Info.Expression = Arg;
|
||||
return Sema::TDK_FailedOverloadResolution;
|
||||
}
|
||||
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
|
||||
ArgType, Info, Deduced, TDF);
|
||||
}
|
||||
|
|
|
@ -199,3 +199,12 @@ namespace initlist_of_array {
|
|||
f({{1,2},{3,4}});
|
||||
}
|
||||
}
|
||||
|
||||
namespace init_list_deduction_failure {
|
||||
void f();
|
||||
void f(int);
|
||||
template<typename T> void g(std::initializer_list<T>);
|
||||
// expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}}
|
||||
void h() { g({f}); }
|
||||
// expected-error@-1 {{no matching function for call to 'g'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue