diff options
| author | John McCall <rjmccall@apple.com> | 2010-01-12 02:15:36 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-01-12 02:15:36 +0000 |
| commit | 53262c96d9a90253523108084cf773865fd1c62b (patch) | |
| tree | 00074732aa53406e49b9cd212dd575862e35b18d /clang/lib/Sema/SemaOverload.cpp | |
| parent | 5631d2d1a1fa2defdd8b037f321f3f109b4a3e02 (diff) | |
| download | bcm5719-llvm-53262c96d9a90253523108084cf773865fd1c62b.tar.gz bcm5719-llvm-53262c96d9a90253523108084cf773865fd1c62b.zip | |
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).
llvm-svn: 93224
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a7d4f372d10..26f8c8edda5 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4263,42 +4263,62 @@ OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, 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 @@ void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS, 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 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) { 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) { |

