diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-30 20:53:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-30 20:53:28 +0000 |
commit | 6c4c36c4ed1007143f5b8655eb68b313a7e12e76 (patch) | |
tree | 0a912935dcb75afa09172e2aabf7b40a71653f2e /include | |
parent | 0f30a12ce7b3d4d86c9ca9072f587da77c8eef34 (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.td | 31 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 26 |
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. /// |