diff options
author | Eric Fiselier <eric@efcs.ca> | 2018-05-30 01:00:41 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2018-05-30 01:00:41 +0000 |
commit | 92e523bf5508737c29b0598b11ee1d6b443bfc29 (patch) | |
tree | c0a235b7c1d5b7e0b675dadf0cb1df4ec7e29626 /clang/lib/Sema/SemaOverload.cpp | |
parent | f614422da9bdd82cd7ac3880f4dfb58b89554f72 (diff) | |
download | bcm5719-llvm-92e523bf5508737c29b0598b11ee1d6b443bfc29.tar.gz bcm5719-llvm-92e523bf5508737c29b0598b11ee1d6b443bfc29.zip |
[Sema] Use %sub to cleanup overload diagnostics
Summary:
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.
Reviewers: rsmith, EricWF
Reviewed By: EricWF
Subscribers: cfe-commits, rsmith
Differential Revision: https://reviews.llvm.org/D47101
llvm-svn: 333485
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 221 |
1 files changed, 116 insertions, 105 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 4a3018ed52c..5e74b54331f 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -9327,66 +9327,77 @@ enum OverloadCandidateKind { 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 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, } 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, // 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, 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 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, // 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 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, } 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,11 +10127,13 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { 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. @@ -10131,7 +10142,7 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { CXXRecordDecl *ParentClass = Meth->getParent(); Sema::CXXSpecialMember CSM; - switch (FnKind) { + switch (FnKindPair.first) { default: return; case oc_implicit_default_constructor: @@ -10203,12 +10214,12 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, 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 @@ private: 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()) { |