diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-15 19:33:52 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-15 19:33:52 +0000 |
commit | e4e68d45f89ff4899d30cbd196603d09b7fbc150 (patch) | |
tree | 9dfe6c0e1b10bee53c490d4d5052c85078c2ddf9 /lib/Sema/SemaInit.cpp | |
parent | b622959527c07cc6b68739eac1412f75f0ca77fa (diff) |
When overload resolution picks an implicitly-deleted special member
function, provide a specialized diagnostic that indicates the kind of
special member function (default constructor, copy assignment
operator, etc.) and that it was implicitly deleted. Add a hook where
we can provide more detailed information later.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150611 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 1638693a2c..da6892e230 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -5273,6 +5273,26 @@ InitializationSequence::Perform(Sema &S, return move(CurInit); } +/// \brief Provide some notes that detail why a function was implicitly +/// deleted. +static void diagnoseImplicitlyDeletedFunction(Sema &S, CXXMethodDecl *Method) { + // FIXME: This is a work in progress. It should dig deeper to figure out + // why the function was deleted (e.g., because one of its members doesn't + // have a copy constructor, for the copy-constructor case). + if (!Method->isImplicit()) { + S.Diag(Method->getLocation(), diag::note_callee_decl) + << Method->getDeclName(); + } + + if (Method->getParent()->isLambda()) { + S.Diag(Method->getParent()->getLocation(), diag::note_lambda_decl); + return; + } + + S.Diag(Method->getParent()->getLocation(), diag::note_defined_here) + << Method->getParent(); +} + //===----------------------------------------------------------------------===// // Diagnose initialization failures //===----------------------------------------------------------------------===// @@ -5536,17 +5556,33 @@ bool InitializationSequence::Diagnose(Sema &S, break; case OR_Deleted: { - S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) - << true << DestType << ArgsRange; OverloadCandidateSet::iterator Best; OverloadingResult Ovl = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); - if (Ovl == OR_Deleted) { - S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) - << 1 << Best->Function->isDeleted(); - } else { + if (Ovl != OR_Deleted) { + S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) + << true << DestType << ArgsRange; llvm_unreachable("Inconsistent overload resolution?"); + break; } + + // If this is a defaulted or implicitly-declared function, then + // it was implicitly deleted. Make it clear that the deletion was + // implicit. + if (S.isImplicitlyDeleted(Best->Function)) { + S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init) + << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function)) + << DestType << ArgsRange; + + diagnoseImplicitlyDeletedFunction(S, + cast<CXXMethodDecl>(Best->Function)); + break; + } + + S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) + << true << DestType << ArgsRange; + S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) + << 1 << Best->Function->isDeleted(); break; } |