[cfe-commits] r93224 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp test/SemaCXX/overload-call.cpp
John McCall
rjmccall at apple.com
Mon Jan 11 18:15:36 PST 2010
Author: rjmccall
Date: Mon Jan 11 20:15:36 2010
New Revision: 93224
URL: http://llvm.org/viewvc/llvm-project?rev=93224&view=rev
Log:
Reorganize some of the code to note overload candidates. Improves the
fidelity with which we note them as functions/constructors and templates
thereof. Also will be helpful when reporting bad conversions (next).
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/overload-call.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93224&r1=93223&r2=93224&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 11 20:15:36 2010
@@ -895,23 +895,23 @@
"call to member function %0 is ambiguous">;
def err_ovl_deleted_member_call : Error<
"call to %select{unavailable|deleted}0 member function %1">;
-def note_ovl_candidate : Note<"candidate function">;
+def note_ovl_candidate : Note<"candidate "
+ "%select{function|function|constructor|"
+ "is the implicit default constructor|"
+ "is the implicit copy constructor|"
+ "is the implicit copy assignment operator}0">;
+def note_ovl_template_candidate : Note<
+ "candidate function template specialization %0">;
+def note_ovl_candidate_deleted : Note<
+ "candidate %select{function|function|constructor}0 has been explicitly "
+ "%select{made unavailable|deleted}1">;
+def note_ovl_template_candidate_deleted : Note<
+ "candidate function template specialization %0 has been explicit "
+ "&select{made unavailable|deleted}1">;
def note_ovl_candidate_not_viable : Note<"function not viable because"
" of ambiguity in conversion of argument %0">;
-def note_ovl_candidate_ctor : Note<"candidate constructor">;
-def note_ovl_candidate_implicit_copy_ctor : Note<
- "candidate is the implicit copy constructor">;
-def note_ovl_candidate_implicit_default_ctor : Note<
- "candidate is the implicit default constructor">;
-def note_ovl_candidate_meth : Note<"candidate function">;
-def note_ovl_candidate_implicit_copy_assign : Note<
- "candidate is the implicit copy assignment operator">;
def note_ambiguous_type_conversion: Note<
"because of ambiguity in conversion of %0 to %1">;
-def note_ovl_template_candidate : Note<
- "candidate function template specialization %0">;
-def note_ovl_candidate_deleted : Note<
- "candidate function has been explicitly %select{made unavailable|deleted}0">;
def note_ovl_builtin_binary_candidate : Note<
"built-in candidate %0">;
def note_ovl_builtin_unary_candidate : Note<
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93224&r1=93223&r2=93224&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 20:15:36 2010
@@ -4263,42 +4263,62 @@
return OR_Success;
}
-/// Notes the location of an overload candidate.
-void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
+namespace {
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {
- // At least call it a 'constructor'.
- if (!Ctor->isImplicit()) {
- Diag(Ctor->getLocation(), diag::note_ovl_candidate_ctor);
- return;
- }
+enum OverloadCandidateKind {
+ oc_function,
+ oc_method,
+ oc_constructor,
+ oc_implicit_default_constructor,
+ oc_implicit_copy_constructor,
+ oc_implicit_copy_assignment,
+ oc_template_specialization // function, constructor, or conversion template
+};
- CXXRecordDecl *Record = Ctor->getParent();
- if (Ctor->isCopyConstructor()) {
- Diag(Record->getLocation(), diag::note_ovl_candidate_implicit_copy_ctor);
- return;
- }
+OverloadCandidateKind ClassifyOverloadCandidate(FunctionDecl *Fn) {
+ if (Fn->getPrimaryTemplate())
+ return oc_template_specialization;
- Diag(Record->getLocation(), diag::note_ovl_candidate_implicit_default_ctor);
- return;
+ if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {
+ if (!Ctor->isImplicit())
+ return oc_constructor;
+
+ return Ctor->isCopyConstructor() ? oc_implicit_copy_constructor
+ : oc_implicit_default_constructor;
}
if (CXXMethodDecl *Meth = dyn_cast<CXXMethodDecl>(Fn)) {
// This actually gets spelled 'candidate function' for now, but
// it doesn't hurt to split it out.
- if (!Meth->isImplicit()) {
- Diag(Meth->getLocation(), diag::note_ovl_candidate_meth);
- return;
- }
+ if (!Meth->isImplicit())
+ return oc_method;
assert(Meth->isCopyAssignment()
&& "implicit method is not copy assignment operator?");
- Diag(Meth->getParent()->getLocation(),
- diag::note_ovl_candidate_implicit_copy_assign);
+ return oc_implicit_copy_assignment;
+ }
+
+ return oc_function;
+}
+
+std::string DescribeFunctionTemplate(Sema &S, FunctionDecl *Fn) {
+ FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate();
+ return S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(),
+ *Fn->getTemplateSpecializationArgs());
+}
+
+} // end anonymous namespace
+
+// Notes the location of an overload candidate.
+void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
+ OverloadCandidateKind K = ClassifyOverloadCandidate(Fn);
+ if (K == oc_template_specialization) {
+ Diag(Fn->getLocation(), diag::note_ovl_template_candidate)
+ << DescribeFunctionTemplate(*this, Fn);
return;
}
- Diag(Fn->getLocation(), diag::note_ovl_candidate);
+ Diag(Fn->getLocation(), diag::note_ovl_candidate) << (unsigned) K;
}
/// Diagnoses an ambiguous conversion. The partial diagnostic is the
@@ -4318,26 +4338,23 @@
namespace {
void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) {
+ FunctionDecl *Fn = Cand->Function;
+
// Note deleted candidates, but only if they're viable.
- if (Cand->Viable &&
- (Cand->Function->isDeleted() ||
- Cand->Function->hasAttr<UnavailableAttr>())) {
- S.Diag(Cand->Function->getLocation(), diag::note_ovl_candidate_deleted)
- << Cand->Function->isDeleted();
- return;
- }
+ if (Cand->Viable && (Fn->isDeleted() || Fn->hasAttr<UnavailableAttr>())) {
+ OverloadCandidateKind FnKind = ClassifyOverloadCandidate(Fn);
+
+ if (FnKind == oc_template_specialization) {
+ S.Diag(Fn->getLocation(), diag::note_ovl_template_candidate_deleted)
+ << DescribeFunctionTemplate(S, Fn) << Fn->isDeleted();
+ return;
+ }
- if (FunctionTemplateDecl *FunTmpl
- = Cand->Function->getPrimaryTemplate()) {
- // Function template specialization
- // FIXME: Give a better reason!
- S.Diag(Cand->Function->getLocation(), diag::note_ovl_template_candidate)
- << S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(),
- *Cand->Function->getTemplateSpecializationArgs());
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
+ << FnKind << Fn->isDeleted();
return;
}
- // Normal function
bool errReported = false;
if (!Cand->Viable && Cand->Conversions.size() > 0) {
for (int i = Cand->Conversions.size()-1; i >= 0; i--) {
@@ -4347,14 +4364,14 @@
if (!Conversion.isAmbiguous())
continue;
- S.DiagnoseAmbiguousConversion(Conversion, Cand->Function->getLocation(),
+ S.DiagnoseAmbiguousConversion(Conversion, Fn->getLocation(),
PDiag(diag::note_ovl_candidate_not_viable) << (i+1));
errReported = true;
}
}
if (!errReported)
- S.NoteOverloadCandidate(Cand->Function);
+ S.NoteOverloadCandidate(Fn);
}
void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
Modified: cfe/trunk/test/SemaCXX/overload-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=93224&r1=93223&r2=93224&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overload-call.cpp (original)
+++ cfe/trunk/test/SemaCXX/overload-call.cpp Mon Jan 11 20:15:36 2010
@@ -301,3 +301,13 @@
(void)ir;
}
}
+
+// Tests the exact text used to note the candidates
+namespace test1 {
+ template <class T> void foo(T t, unsigned N); // expected-note {{candidate function template specialization [with T = int]}}
+ void foo(int n, char N); // expected-note {{candidate function}}
+
+ void test() {
+ foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}}
+ }
+}
More information about the cfe-commits
mailing list