diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/TypePrinter.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 48 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 23 |
5 files changed, 74 insertions, 14 deletions
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 7d30b7ff8b..664a658160 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -672,8 +672,14 @@ void TypePrinter::printTag(TagDecl *D, std::string &InnerString) { // Make an unambiguous representation for anonymous types, e.g. // <anonymous enum at /usr/include/string.h:120:9> llvm::raw_string_ostream OS(Buffer); - OS << "<anonymous"; - + + if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) { + OS << "<lambda"; + HasKindDecoration = true; + } else { + OS << "<anonymous"; + } + if (Policy.AnonymousTagLocations) { // Suppress the redundant tag keyword if we just printed one. // We don't have to worry about ElaboratedTypes here because you can't diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 2d609001d4..bcb138118d 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -219,7 +219,6 @@ struct CheckFallThroughDiagnostics { unsigned diag_AlwaysFallThrough_ReturnsNonVoid; unsigned diag_NeverFallThroughOrReturn; enum { Function, Block, Lambda } funMode; - bool IsLambda; SourceLocation FuncLoc; static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 624dc5d1e6..447a4b4257 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -9045,6 +9045,12 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, } } +bool Sema::isImplicitlyDeleted(FunctionDecl *FD) { + return FD->isDeleted() && + (FD->isDefaulted() || FD->isImplicit()) && + isa<CXXMethodDecl>(FD); +} + ExprResult Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, 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; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index b20dc955c1..2b025da088 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9984,11 +9984,24 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return ExprError(); case OR_Deleted: - Diag(OpLoc, diag::err_ovl_deleted_oper) - << Best->Function->isDeleted() - << BinaryOperator::getOpcodeStr(Opc) - << getDeletedOrUnavailableSuffix(Best->Function) - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); + if (isImplicitlyDeleted(Best->Function)) { + CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function); + Diag(OpLoc, diag::err_ovl_deleted_special_oper) + << getSpecialMember(Method) + << BinaryOperator::getOpcodeStr(Opc) + << getDeletedOrUnavailableSuffix(Best->Function); + + if (Method->getParent()->isLambda()) { + Diag(Method->getParent()->getLocation(), diag::note_lambda_decl); + return ExprError(); + } + } else { + Diag(OpLoc, diag::err_ovl_deleted_oper) + << Best->Function->isDeleted() + << BinaryOperator::getOpcodeStr(Opc) + << getDeletedOrUnavailableSuffix(Best->Function) + << Args[0]->getSourceRange() << Args[1]->getSourceRange(); + } CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); |