aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/TypePrinter.cpp10
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp6
-rw-r--r--lib/Sema/SemaInit.cpp48
-rw-r--r--lib/Sema/SemaOverload.cpp23
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();