diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 30 | ||||
-rw-r--r-- | test/SemaTemplate/overload-candidates.cpp | 17 |
3 files changed, 48 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 95c9c804f3..d93de39f14 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2370,6 +2370,11 @@ def note_ovl_candidate_failed_overload_resolution : Note< "function %0">; def note_ovl_candidate_non_deduced_mismatch : Note< "candidate template ignored: could not match %diff{$ against $|types}0,1">; +// This note is needed because the above note would sometimes print two +// different types with the same name. Remove this note when the above note +// can handle that case properly. +def note_ovl_candidate_non_deduced_mismatch_qualified : Note< + "candidate template ignored: could not match %q0 against %q1">; // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 89d495ddc1..805fdd8b57 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -8508,13 +8508,35 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, return; } - case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. + TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg(); + TemplateArgument SecondTA = *Cand->DeductionFailure.getSecondArg(); + if (FirstTA.getKind() == TemplateArgument::Template && + SecondTA.getKind() == TemplateArgument::Template) { + TemplateName FirstTN = FirstTA.getAsTemplate(); + TemplateName SecondTN = SecondTA.getAsTemplate(); + if (FirstTN.getKind() == TemplateName::Template && + SecondTN.getKind() == TemplateName::Template) { + if (FirstTN.getAsTemplateDecl()->getName() == + SecondTN.getAsTemplateDecl()->getName()) { + // FIXME: This fixes a bad diagnostic where both templates are named + // the same. This particular case is a bit difficult since: + // 1) It is passed as a string to the diagnostic printer. + // 2) The diagnostic printer only attempts to find a better + // name for types, not decls. + // Ideally, this should folded into the diagnostic printer. + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_non_deduced_mismatch_qualified) + << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl(); + return; + } + } + } S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) - << *Cand->DeductionFailure.getFirstArg() - << *Cand->DeductionFailure.getSecondArg(); + << FirstTA << SecondTA; return; - + } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp index dc6d2a51ec..ad65397865 100644 --- a/test/SemaTemplate/overload-candidates.cpp +++ b/test/SemaTemplate/overload-candidates.cpp @@ -62,3 +62,20 @@ template<typename T> struct NonTemplateFunction { typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}} }; NonTemplateFunction<char> NTFC; // expected-note{{here}} + +namespace NS1 { + template <class A> + class array {}; +} + +namespace NS2 { + template <class A> + class array {}; +} + +template <class A> +void foo(NS2::array<A>); // expected-note{{candidate template ignored: could not match 'NS2::array' against 'NS1::array'}} + +void test() { + foo(NS1::array<int>()); // expected-error{{no matching function for call to 'foo'}} +} |