Sema: print qualified name for overload candidates

Print the fully qualified names for the overload candidates.  This makes
it easier to tell what the ambiguity is.  Especially if a template
is instantiated after a using namespace, it will not inherit the
namespace where it was declared.  The specialization will give a message
about a partial order being ambiguous for the same (unqualified) name,
which does not help identify the failure.

Addresses PR31450!

llvm-svn: 290315
This commit is contained in:
Saleem Abdulrasool 2016-12-22 04:26:57 +00:00
parent 9d3248b765
commit 78704fb6dc
4 changed files with 33 additions and 17 deletions

View File

@ -3318,18 +3318,18 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit copy assignment operator|"
"is the implicit move assignment operator|"
"inherited constructor|"
"inherited constructor }0%1"
"%select{| has different class%diff{ (expected $ but has $)|}3,4"
"| has different number of parameters (expected %3 but has %4)"
"| has type mismatch at %ordinal3 parameter"
"%diff{ (expected $ but has $)|}4,5"
"| has different return type%diff{ ($ expected but has $)|}3,4"
"inherited constructor }0%2"
"%select{| has different class%diff{ (expected $ but has $)|}4,5"
"| has different number of parameters (expected %4 but has %5)"
"| has type mismatch at %ordinal4 parameter"
"%diff{ (expected $ but has $)|}5,6"
"| has different return type%diff{ ($ expected but has $)|}4,5"
"| has different qualifiers (expected "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
"|volatile and restrict|const, volatile, and restrict}3 but found "
"|volatile and restrict|const, volatile, and restrict}4 but found "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
"|volatile and restrict|const, volatile, and restrict}4)"
"| has different exception specification}2">;
"|volatile and restrict|const, volatile, and restrict}5)"
"| has different exception specification}3">;
def note_ovl_candidate_inherited_constructor : Note<
"constructor from base class %0 inherited here">;
@ -4076,7 +4076,7 @@ def err_function_template_spec_ambiguous : Error<
"function template; explicitly specify%select{| additional}1 template "
"arguments to identify a particular function template">;
def note_function_template_spec_matched : Note<
"function template matches specialization %0">;
"function template %q0 matches specialization %1">;
def err_function_template_partial_spec : Error<
"function template partial specialization is not allowed">;
@ -4214,7 +4214,7 @@ def err_explicit_instantiation_member_function_not_instantiated : Error<
def err_explicit_instantiation_ambiguous : Error<
"partial ordering for explicit instantiation of %0 is ambiguous">;
def note_explicit_instantiation_candidate : Note<
"explicit instantiation candidate function template here %0">;
"explicit instantiation candidate function %q0 template here %1">;
def err_explicit_instantiation_inline : Error<
"explicit instantiation cannot be 'inline'">;
def warn_explicit_instantiation_inline_0x : Warning<

View File

@ -9160,7 +9160,7 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
std::string FnDesc;
OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc);
PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)
<< (unsigned) K << FnDesc;
<< (unsigned) K << Fn << FnDesc;
HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
Diag(Fn->getLocation(), PD);

View File

@ -4581,12 +4581,12 @@ UnresolvedSetIterator Sema::getMostSpecialized(
// FIXME: Can we order the candidates in some sane way?
for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
PartialDiagnostic PD = CandidateDiag;
PD << getTemplateArgumentBindingsText(
cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
*cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
const auto *FD = cast<FunctionDecl>(*I);
PD << FD << getTemplateArgumentBindingsText(
FD->getPrimaryTemplate()->getTemplateParameters(),
*FD->getTemplateSpecializationArgs());
if (!TargetType.isNull())
HandleFunctionTypeMismatch(PD, cast<FunctionDecl>(*I)->getType(),
TargetType);
HandleFunctionTypeMismatch(PD, FD->getType(), TargetType);
Diag((*I)->getLocation(), PD);
}
}

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace n {
template <int>
void f(); // expected-note{{explicit instantiation candidate function 'n::f<0>' template here [with $0 = 0]}}
extern template void f<0>();
}
using namespace n;
template <int>
void f() {} // expected-note{{explicit instantiation candidate function 'f<0>' template here [with $0 = 0]}}
template void f<0>(); // expected-error{{partial ordering for explicit instantiation of 'f' is ambiguous}}