summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-03-30 20:53:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-03-30 20:53:28 +0000
commit6c4c36c4ed1007143f5b8655eb68b313a7e12e76 (patch)
tree0a912935dcb75afa09172e2aabf7b40a71653f2e /include
parent0f30a12ce7b3d4d86c9ca9072f587da77c8eef34 (diff)
PR10217: Provide diagnostics explaining why an implicitly-deleted special
member function is deleted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153773 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td31
-rw-r--r--include/clang/Sema/Sema.h26
2 files changed, 48 insertions, 9 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 30780104d6..32ac7be9e5 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2821,6 +2821,37 @@ def warn_cxx98_compat_friend_redefinition : Warning<
"friend function %0 would be implicitly redefined in C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def note_deleted_dtor_no_operator_delete : Note<
+ "virtual destructor requires an unambiguous, accessible 'operator delete'">;
+def note_deleted_special_member_class_subobject : Note<
+ "%select{default constructor|copy constructor|move constructor|"
+ "copy assignment operator|move assignment operator|destructor}0 of "
+ "%select{||||union }4%1 is implicitly deleted because "
+ "%select{base class %3|field %3}2 has "
+ "%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
+ "%select{%select{default constructor|copy constructor|move constructor|copy "
+ "assignment operator|move assignment operator|destructor}0|destructor}5"
+ "%select{||s||}4">;
+def note_deleted_default_ctor_uninit_field : Note<
+ "default constructor of %0 is implicitly deleted because field %1 of "
+ "%select{reference|const-qualified}3 type %2 would not be initialized">;
+def note_deleted_default_ctor_all_const : Note<
+ "default constructor of %0 is implicitly deleted because all "
+ "%select{data members|data members of an anonymous union member}1"
+ " are const-qualified">;
+def note_deleted_copy_ctor_rvalue_reference : Note<
+ "copy constructor of %0 is implicitly deleted because field %1 is of "
+ "rvalue reference type %2">;
+def note_deleted_copy_user_declared_move : Note<
+ "copy %select{constructor|assignment operator}0 is implicitly deleted because"
+ " %1 has a user-declared move %select{constructor|assignment operator}2">;
+def note_deleted_assign_field : Note<
+ "%select{copy|move}0 assignment operator of %0 is implicitly deleted "
+ "because field %1 is of %select{reference|const-qualified}3 type %2">;
+def note_deleted_move_assign_virtual_base : Note<
+ "move assignment operator of %0 is implicitly deleted because it has a "
+ "virtual base class %1">;
+
// This should eventually be an error.
def warn_undefined_internal : Warning<
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index cd8b1e96d9..045b2fa69a 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -660,7 +660,17 @@ public:
/// This is used for determining parameter types of other objects and is
/// utterly meaningless on other types of special members.
class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
+ public:
+ enum Kind {
+ NoMemberOrDeleted,
+ Ambiguous,
+ SuccessNonConst,
+ SuccessConst
+ };
+
+ private:
llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
+
public:
SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
: FastFoldingSetNode(ID)
@@ -669,15 +679,11 @@ public:
CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
- bool hasSuccess() const { return Pair.getInt() & 0x1; }
- void setSuccess(bool B) {
- Pair.setInt(unsigned(B) | hasConstParamMatch() << 1);
- }
+ Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
+ void setKind(Kind K) { Pair.setInt(K); }
- bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
- void setConstParamMatch(bool B) {
- Pair.setInt(B << 1 | unsigned(hasSuccess()));
- }
+ bool hasSuccess() const { return getKind() >= SuccessNonConst; }
+ bool hasConstParamMatch() const { return getKind() == SuccessConst; }
};
/// \brief A cache of special member function overload resolution results
@@ -2421,6 +2427,7 @@ public:
bool CanUseDecl(NamedDecl *D);
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass=0);
+ void NoteDeletedFunction(FunctionDecl *FD);
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
ObjCMethodDecl *Getter,
@@ -3127,7 +3134,8 @@ public:
/// \brief Determine if a special member function should have a deleted
/// definition when it is defaulted.
- bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM);
+ bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+ bool Diagnose = false);
/// \brief Declare the implicit default constructor for the given class.
///