EricWF created this revision. EricWF added a reviewer: rsmith. This patch adds the newly added `%sub` diagnostic modifier to cleanup repetition in the overload candidate diagnostics.
I think this should be good to go. @rsmith: Some of the notes now emit `function template` where they only said `function` previously. It seems OK to me, but I would like your sign off on it. Repository: rC Clang https://reviews.llvm.org/D47101 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp test/CXX/drs/dr4xx.cpp test/CXX/special/class.inhctor/p1.cpp test/SemaCXX/attr-noreturn.cpp test/SemaCXX/cxx1y-generic-lambdas.cpp test/SemaCXX/overload-call.cpp test/SemaCXX/overload-member-call.cpp
Index: test/SemaCXX/overload-member-call.cpp =================================================================== --- test/SemaCXX/overload-member-call.cpp +++ test/SemaCXX/overload-member-call.cpp @@ -70,7 +70,8 @@ // Tests the exact text used to note the candidates namespace test1 { class A { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} + template <class T> + void foo(T t, unsigned N); // expected-note {{candidate function template not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} Index: test/SemaCXX/overload-call.cpp =================================================================== --- test/SemaCXX/overload-call.cpp +++ test/SemaCXX/overload-call.cpp @@ -338,22 +338,23 @@ // Tests the exact text used to note the candidates namespace test1 { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} - void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} - void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} - void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} - void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} - - // PR 11857 - void foo(int n); // expected-note {{candidate function not viable: requires single argument 'n', but 2 arguments were provided}} - void foo(unsigned n = 10); // expected-note {{candidate function not viable: allows at most single argument 'n', but 2 arguments were provided}} - void bar(int n, int u = 0); // expected-note {{candidate function not viable: requires at least argument 'n', but no arguments were provided}} - void baz(int n = 0, int u = 0); // expected-note {{candidate function not viable: requires at most 2 arguments, but 3 were provided}} - - void test() { - foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}} - bar(); //expected-error {{no matching function for call to 'bar'}} - baz(3, 4, 5); // expected-error {{no matching function for call to 'baz'}} +template <class T> +void foo(T t, unsigned N); // expected-note {{candidate function template not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} +void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} +void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} +void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} +void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + +// PR 11857 +void foo(int n); // expected-note {{candidate function not viable: requires single argument 'n', but 2 arguments were provided}} +void foo(unsigned n = 10); // expected-note {{candidate function not viable: allows at most single argument 'n', but 2 arguments were provided}} +void bar(int n, int u = 0); // expected-note {{candidate function not viable: requires at least argument 'n', but no arguments were provided}} +void baz(int n = 0, int u = 0); // expected-note {{candidate function not viable: requires at most 2 arguments, but 3 were provided}} + +void test() { + foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}} + bar(); //expected-error {{no matching function for call to 'bar'}} + baz(3, 4, 5); // expected-error {{no matching function for call to 'baz'}} } } Index: test/SemaCXX/cxx1y-generic-lambdas.cpp =================================================================== --- test/SemaCXX/cxx1y-generic-lambdas.cpp +++ test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -181,7 +181,7 @@ int (*fp2)(int) = [](auto b) -> int { return b; }; int (*fp3)(char) = [](auto c) -> int { return c; }; char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\ - //expected-note{{candidate function[with $0 = int]}} + //expected-note{{candidate function [with $0 = int]}} char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\ //expected-note{{candidate template ignored}} Index: test/SemaCXX/attr-noreturn.cpp =================================================================== --- test/SemaCXX/attr-noreturn.cpp +++ test/SemaCXX/attr-noreturn.cpp @@ -244,11 +244,11 @@ template <typename T> void qux(T) {} - // expected-note@+5 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+4 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+3 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+2 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} - // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + // expected-note@+5 {{candidate function template not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+4 {{candidate function template not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+3 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+2 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + // expected-note@+1 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} template <typename T> void accept_T(T) {} // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} Index: test/CXX/special/class.inhctor/p1.cpp =================================================================== --- test/CXX/special/class.inhctor/p1.cpp +++ test/CXX/special/class.inhctor/p1.cpp @@ -3,7 +3,7 @@ // Note: [class.inhctor] was removed by P0136R1. This tests the new behavior // for the wording that used to be there. -struct A { // expected-note 4{{candidate is the implicit}} +struct A { // expected-note 4{{candidate constructor (the implicit}} A(...); // expected-note 4{{candidate constructor}} expected-note 4{{candidate inherited constructor}} A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}} A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}} @@ -14,7 +14,7 @@ template<typename T, int N> A(const T (&)[N], int = 0); // expected-note {{candidate constructor}} expected-note {{candidate inherited constructor}} }; -struct B : A { // expected-note 4{{candidate is the implicit}} +struct B : A { // expected-note 4{{candidate constructor (the implicit}} using A::A; // expected-note 15{{inherited here}} B(void*); }; Index: test/CXX/drs/dr4xx.cpp =================================================================== --- test/CXX/drs/dr4xx.cpp +++ test/CXX/drs/dr4xx.cpp @@ -533,10 +533,10 @@ namespace dr444 { // dr444: yes struct D; - struct B { // expected-note {{candidate is the implicit copy}} expected-note 0-1 {{implicit move}} + struct B { // expected-note {{candidate function (the implicit copy}} expected-note 0-1 {{implicit move}} D &operator=(D &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}} }; - struct D : B { // expected-note {{candidate is the implicit}} expected-note 0-1 {{implicit move}} + struct D : B { // expected-note {{candidate function (the implicit copy}} expected-note 0-1 {{implicit move}} using B::operator=; } extern d; void f() { Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -9327,66 +9327,77 @@ oc_function, oc_method, oc_constructor, - oc_function_template, - oc_method_template, - oc_constructor_template, oc_implicit_default_constructor, oc_implicit_copy_constructor, oc_implicit_move_constructor, oc_implicit_copy_assignment, oc_implicit_move_assignment, - oc_inherited_constructor, - oc_inherited_constructor_template + oc_inherited_constructor }; -static OverloadCandidateKind +enum OverloadCandidateSelect { + ocs_non_template, + ocs_template, + ocs_described_template, +}; + +static std::pair<OverloadCandidateKind, OverloadCandidateSelect> ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, std::string &Description) { - bool isTemplate = false; + bool isTemplate = Fn->isTemplateDecl() || Found->isTemplateDecl(); if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) { isTemplate = true; Description = S.getTemplateArgumentBindingsText( - FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs()); + FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs()); } - if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) { - if (!Ctor->isImplicit()) { - if (isa<ConstructorUsingShadowDecl>(Found)) - return isTemplate ? oc_inherited_constructor_template - : oc_inherited_constructor; - else - return isTemplate ? oc_constructor_template : oc_constructor; - } + OverloadCandidateSelect Select = [&]() { + if (!Description.empty()) + return ocs_described_template; + return isTemplate ? ocs_template : ocs_non_template; + }(); - if (Ctor->isDefaultConstructor()) - return oc_implicit_default_constructor; + OverloadCandidateKind Kind = [&]() { + if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) { + if (!Ctor->isImplicit()) { + if (isa<ConstructorUsingShadowDecl>(Found)) + return oc_inherited_constructor; + else + return oc_constructor; + } - if (Ctor->isMoveConstructor()) - return oc_implicit_move_constructor; + if (Ctor->isDefaultConstructor()) + return oc_implicit_default_constructor; - assert(Ctor->isCopyConstructor() && - "unexpected sort of implicit constructor"); - return oc_implicit_copy_constructor; - } + if (Ctor->isMoveConstructor()) + return oc_implicit_move_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()) - return isTemplate ? oc_method_template : oc_method; + assert(Ctor->isCopyConstructor() && + "unexpected sort of implicit constructor"); + return oc_implicit_copy_constructor; + } - if (Meth->isMoveAssignmentOperator()) - return oc_implicit_move_assignment; + 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()) + return oc_method; - if (Meth->isCopyAssignmentOperator()) - return oc_implicit_copy_assignment; + if (Meth->isMoveAssignmentOperator()) + return oc_implicit_move_assignment; - assert(isa<CXXConversionDecl>(Meth) && "expected conversion"); - return oc_method; - } + if (Meth->isCopyAssignmentOperator()) + return oc_implicit_copy_assignment; + + assert(isa<CXXConversionDecl>(Meth) && "expected conversion"); + return oc_method; + } - return isTemplate ? oc_function_template : oc_function; + return oc_function; + }(); + + return std::make_pair(Kind, Select); } void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) { @@ -9478,9 +9489,11 @@ return; std::string FnDesc; - OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); + std::pair<OverloadCandidateKind, OverloadCandidateSelect> KSPair = + ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) - << (unsigned) K << Fn << FnDesc; + << (unsigned)KSPair.first << (unsigned)KSPair.second + << Fn << FnDesc; HandleFunctionTypeMismatch(PD, Fn->getType(), DestType); Diag(Fn->getLocation(), PD); @@ -9554,7 +9567,7 @@ } std::string FnDesc; - OverloadCandidateKind FnKind = + std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); Expr *FromExpr = Conv.Bad.FromExpr; @@ -9569,9 +9582,9 @@ DeclarationName Name = cast<OverloadExpr>(E)->getName(); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << ToTy << Name << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << ToTy + << Name << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9598,43 +9611,40 @@ if (FromQs.getAddressSpace() != ToQs.getAddressSpace()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy - << FromQs.getAddressSpaceAttributePrintValue() - << ToQs.getAddressSpaceAttributePrintValue() - << (unsigned) isObjectArgument << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << FromQs.getAddressSpaceAttributePrintValue() + << ToQs.getAddressSpaceAttributePrintValue() + << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_ownership) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy - << FromQs.getObjCLifetime() << ToQs.getObjCLifetime() - << (unsigned) isObjectArgument << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << FromQs.getObjCLifetime() << ToQs.getObjCLifetime() + << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCGCAttr() != ToQs.getObjCGCAttr()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_gc) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy - << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr() - << (unsigned) isObjectArgument << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr() + << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.hasUnaligned() != ToQs.hasUnaligned()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_unaligned) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << FromQs.hasUnaligned() << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << FromQs.hasUnaligned() << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9644,14 +9654,14 @@ if (isObjectArgument) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr_this) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << (CVR - 1); + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << (CVR - 1); } else { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << (CVR - 1) << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << (CVR - 1) << I + 1; } MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; @@ -9661,9 +9671,9 @@ // telling the user that it has type void is not useful. if (FromExpr && isa<InitListExpr>(FromExpr)) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_list_argument) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << ToTy << (unsigned) isObjectArgument << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9677,10 +9687,10 @@ if (TempFromTy->isIncompleteType()) { // Emit the generic diagnostic and, optionally, add the hints to it. S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << ToTy << (unsigned) isObjectArgument << I+1 - << (unsigned) (Cand->Fix.Kind); + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << ToTy << (unsigned)isObjectArgument << I + 1 + << (unsigned)(Cand->Fix.Kind); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; @@ -9718,21 +9728,19 @@ ToTy.getNonReferenceType().getCanonicalType() == FromTy.getNonReferenceType().getCanonicalType()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_lvalue) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << (unsigned) isObjectArgument << I + 1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (unsigned)isObjectArgument << I + 1 + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } if (BaseToDerivedConversion) { - S.Diag(Fn->getLocation(), - diag::note_ovl_candidate_bad_base_to_derived_conv) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << (BaseToDerivedConversion - 1) - << FromTy << ToTy << I+1; + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_base_to_derived_conv) + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) + << (BaseToDerivedConversion - 1) << FromTy << ToTy << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9743,9 +9751,9 @@ Qualifiers ToQs = CToTy.getQualifiers(); if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_arc_conv) - << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << ToTy << (unsigned) isObjectArgument << I+1; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second + << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) + << FromTy << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9757,10 +9765,10 @@ // Emit the generic diagnostic and, optionally, add the hints to it. PartialDiagnostic FDiag = S.PDiag(diag::note_ovl_candidate_bad_conv); - FDiag << (unsigned) FnKind << FnDesc - << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << ToTy << (unsigned) isObjectArgument << I + 1 - << (unsigned) (Cand->Fix.Kind); + FDiag << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy + << ToTy << (unsigned)isObjectArgument << I + 1 + << (unsigned)(Cand->Fix.Kind); // If we can fix the conversion, suggest the FixIts. for (std::vector<FixItHint>::iterator HI = Cand->Fix.Hints.begin(), @@ -9833,17 +9841,18 @@ } std::string Description; - OverloadCandidateKind FnKind = + std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = ClassifyOverloadCandidate(S, Found, Fn, Description); if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) - << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != nullptr) - << mode << Fn->getParamDecl(0) << NumFormalArgs; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second + << Description << mode << Fn->getParamDecl(0) << NumFormalArgs; else S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) - << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != nullptr) - << mode << modeCount << NumFormalArgs; + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second + << Description << mode << modeCount << NumFormalArgs; + MaybeEmitInheritedConstructorNote(S, Found); } @@ -10118,20 +10127,22 @@ CalleeTarget = S.IdentifyCUDATarget(Callee); std::string FnDesc; - OverloadCandidateKind FnKind = + std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, FnDesc); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) - << (unsigned)FnKind << CalleeTarget << CallerTarget; + << (unsigned)FnKindPair.first << (unsigned)ocs_non_template + << FnDesc /* Ignored */ + << CalleeTarget << CallerTarget; // This could be an implicit constructor for which we could not infer the // target due to a collsion. Diagnose that case. CXXMethodDecl *Meth = dyn_cast<CXXMethodDecl>(Callee); if (Meth != nullptr && Meth->isImplicit()) { CXXRecordDecl *ParentClass = Meth->getParent(); Sema::CXXSpecialMember CSM; - switch (FnKind) { + switch (FnKindPair.first) { default: return; case oc_implicit_default_constructor: @@ -10203,12 +10214,12 @@ if (Cand->Viable) { if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) { std::string FnDesc; - OverloadCandidateKind FnKind = - ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); + std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) - << FnKind << FnDesc - << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); + << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc + << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -11102,9 +11113,9 @@ MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates, SourceExpr->getLocStart(), S.PDiag(), S.PDiag(diag::err_addr_ovl_ambiguous) - << Matches[0].second->getDeclName(), + << Matches[0].second->getDeclName(), S.PDiag(diag::note_ovl_candidate) - << (unsigned)oc_function_template, + << (unsigned)oc_function << (unsigned)ocs_described_template, Complain, TargetFunctionType); if (Result != MatchesCopy.end()) { Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -3525,27 +3525,29 @@ def note_ovl_too_many_candidates : Note< "remaining %0 candidate%s0 omitted; " "pass -fshow-overloads=all to show them">; -def note_ovl_candidate : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "is the implicit default constructor|" - "is the implicit copy constructor|" - "is the implicit move constructor|" - "is the implicit copy assignment operator|" - "is the implicit move assignment operator|" - "inherited constructor|" - "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" + +def select_ovl_candidate_kind : TextSubstitution< + "%select{function|function|constructor|" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "inherited constructor}0%select{| template| %2}1">; + +def note_ovl_candidate : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,3" + "%select{| has different class%diff{ (expected $ but has $)|}5,6" + "| has different number of parameters (expected %5 but has %6)" + "| has type mismatch at %ordinal5 parameter" + "%diff{ (expected $ but has $)|}6,7" + "| has different return type%diff{ ($ expected but has $)|}5,6" "| has different qualifiers (expected " "%select{none|const|restrict|const and restrict|volatile|const and volatile" - "|volatile and restrict|const, volatile, and restrict}4 but found " + "|volatile and restrict|const, volatile, and restrict}5 but found " "%select{none|const|restrict|const and restrict|volatile|const and volatile" - "|volatile and restrict|const, volatile, and restrict}5)" - "| has different exception specification}3">; + "|volatile and restrict|const, volatile, and restrict}6)" + "| has different exception specification}4">; def note_ovl_candidate_inherited_constructor : Note< "constructor from base class %0 inherited here">; @@ -3615,225 +3617,97 @@ // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " - "%select{function|function|constructor|function|function|constructor|" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor}0 %select{|template }1" - "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 " - "%plural{1:was|:were}4 provided">; + "%sub{select_ovl_candidate_kind}0,1,2 not viable: " + "requires%select{ at least| at most|}3 %4 argument%s4, but %5 " + "%plural{1:was|:were}5 provided">; def note_ovl_candidate_arity_one : Note<"candidate " - "%select{function|function|constructor|function|function|constructor|" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor}0 %select{|template }1not viable: " - "%select{requires at least|allows at most single|requires single}2 " - "argument %3, but %plural{0:no|:%4}4 arguments were provided">; + "%sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%select{requires at least|allows at most single|requires single}3 " + "argument %4, but %plural{0:no|:%5}5 arguments were provided">; def note_ovl_candidate_deleted : Note< - "candidate %select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 has been " + "candidate %sub{select_ovl_candidate_kind}0,1,2 has been " "%select{explicitly made unavailable|explicitly deleted|" - "implicitly deleted}2">; + "implicitly deleted}3">; // Giving the index of the bad argument really clutters this message, and // it's relatively unimportant because 1) it's generally obvious which // argument(s) are of the given object type and 2) the fix is usually // to complete the type, which doesn't involve changes to the call line // anyway. If people complain, we can change it. -def note_ovl_candidate_bad_conv_incomplete : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 " - "not viable: cannot convert argument of incomplete type " - "%diff{$ to $|to parameter type}2,3 for " - "%select{%ordinal5 argument|object argument}4" +def note_ovl_candidate_bad_conv_incomplete : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "cannot convert argument of incomplete type " + "%diff{$ to $|to parameter type}3,4 for " + "%select{%ordinal6 argument|object argument}5" "%select{|; dereference the argument with *|" "; take the address of the argument with &|" "; remove *|" - "; remove &}6">; -def note_ovl_candidate_bad_list_argument : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 " - "not viable: cannot convert initializer list argument to %3">; -def note_ovl_candidate_bad_overload : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1" - " not viable: no overload of %3 matching %2 for %ordinal4 argument">; -def note_ovl_candidate_bad_conv : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1" - " not viable: no known conversion " - "%diff{from $ to $|from argument type to parameter type}2,3 for " - "%select{%ordinal5 argument|object argument}4" + "; remove &}7">; +def note_ovl_candidate_bad_list_argument : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "cannot convert initializer list argument to %4">; +def note_ovl_candidate_bad_overload : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "no overload of %4 matching %3 for %ordinal5 argument">; +def note_ovl_candidate_bad_conv : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "no known conversion " + "%diff{from $ to $|from argument type to parameter type}3,4 for " + "%select{%ordinal6 argument|object argument}5" "%select{|; dereference the argument with *|" "; take the address of the argument with &|" "; remove *|" - "; remove &}6">; -def note_ovl_candidate_bad_arc_conv : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1" - " not viable: cannot implicitly convert argument " - "%diff{of type $ to $|type to parameter type}2,3 for " - "%select{%ordinal5 argument|object argument}4 under ARC">; -def note_ovl_candidate_bad_lvalue : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1" - " not viable: expects an l-value for " - "%select{%ordinal3 argument|object argument}2">; -def note_ovl_candidate_bad_addrspace : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "%select{%ordinal6|'this'}5 argument (%2) is in " - "address space %3, but parameter must be in address space %4">; -def note_ovl_candidate_bad_gc : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 " - "ownership, but parameter has %select{no|__weak|__strong}4 ownership">; -def note_ovl_candidate_bad_ownership : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "%select{%ordinal6|'this'}5 argument (%2) has " - "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership," + "; remove &}7">; +def note_ovl_candidate_bad_arc_conv : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "cannot implicitly convert argument " + "%diff{of type $ to $|type to parameter type}3,4 for " + "%select{%ordinal6 argument|object argument}5 under ARC">; +def note_ovl_candidate_bad_lvalue : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "expects an l-value for " + "%select{%ordinal4 argument|object argument}3">; +def note_ovl_candidate_bad_addrspace : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%select{%ordinal7|'this'}6 argument (%3) is in " + "address space %4, but parameter must be in address space %5">; +def note_ovl_candidate_bad_gc : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%select{%ordinal7|'this'}6 argument (%3) has %select{no|__weak|__strong}4 " + "ownership, but parameter has %select{no|__weak|__strong}5 ownership">; +def note_ovl_candidate_bad_ownership : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%select{%ordinal7|'this'}6 argument (%3) has " + "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}4 ownership," " but parameter has %select{no|__unsafe_unretained|__strong|__weak|" - "__autoreleasing}4 ownership">; -def note_ovl_candidate_bad_cvr_this : Note<"candidate " - "%select{|function|||function|||||" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)||}0 not viable: " - "'this' argument has type %2, but method is not marked " + "__autoreleasing}5 ownership">; +def note_ovl_candidate_bad_cvr_this : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "'this' argument has type %3, but method is not marked " "%select{const|restrict|const or restrict|volatile|const or volatile|" - "volatile or restrict|const, volatile, or restrict}3">; -def note_ovl_candidate_bad_cvr : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "%ordinal4 argument (%2) would lose " + "volatile or restrict|const, volatile, or restrict}4">; +def note_ovl_candidate_bad_cvr : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%ordinal5 argument (%3) would lose " "%select{const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}3 qualifier" - "%select{||s||s|s|s}3">; -def note_ovl_candidate_bad_unaligned : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "%ordinal4 argument (%2) would lose __unaligned qualifier">; -def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " - "%select{function|function|constructor|" - "function |function |constructor |" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor }0%1 not viable: " - "cannot %select{convert from|convert from|bind}2 " - "%select{base class pointer|superclass|base class object of type}2 %3 to " - "%select{derived class pointer|subclass|derived class reference}2 %4 for " - "%ordinal5 argument">; + "volatile and restrict|const, volatile, and restrict}4 qualifier" + "%select{||s||s|s|s}4">; +def note_ovl_candidate_bad_unaligned : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "%ordinal5 argument (%3) would lose __unaligned qualifier">; +def note_ovl_candidate_bad_base_to_derived_conv : Note< + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " + "cannot %select{convert from|convert from|bind}3 " + "%select{base class pointer|superclass|base class object of type}3 %4 to " + "%select{derived class pointer|subclass|derived class reference}3 %5 for " + "%ordinal6 argument">; def note_ovl_candidate_bad_target : Note< - "candidate %select{function|function|constructor|" - "function|function|constructor|" - "constructor (the implicit default constructor)|" - "constructor (the implicit copy constructor)|" - "constructor (the implicit move constructor)|" - "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|" - "inherited constructor|" - "inherited constructor}0 not viable: " + "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: " "call to " - "%select{__device__|__global__|__host__|__host__ __device__|invalid}1 function from" - " %select{__device__|__global__|__host__|__host__ __device__|invalid}2 function">; + "%select{__device__|__global__|__host__|__host__ __device__|invalid}3 function from" + " %select{__device__|__global__|__host__|__host__ __device__|invalid}4 function">; def note_implicit_member_target_infer_collision : Note< "implicit %sub{select_special_member_kind}0 inferred target collision: call to both " "%select{__device__|__global__|__host__|__host__ __device__}1 and "
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits