1 //===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H 11 12 #include "../ClangTidyCheck.h" 13 14 #include "llvm/ADT/DenseMapInfo.h" 15 16 namespace clang::tidy::cppcoreguidelines { 17 18 /// Checks for classes where some, but not all, of the special member functions 19 /// are defined. 20 /// 21 /// For the user-facing documentation see: 22 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/special-member-functions.html 23 class SpecialMemberFunctionsCheck : public ClangTidyCheck { 24 public: 25 SpecialMemberFunctionsCheck(StringRef Name, ClangTidyContext *Context); isLanguageVersionSupported(const LangOptions & LangOpts)26 bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { 27 return LangOpts.CPlusPlus; 28 } 29 void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 30 void registerMatchers(ast_matchers::MatchFinder *Finder) override; 31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 32 void onEndOfTranslationUnit() override; 33 std::optional<TraversalKind> getCheckTraversalKind() const override; 34 35 enum class SpecialMemberFunctionKind : uint8_t { 36 Destructor, 37 DefaultDestructor, 38 NonDefaultDestructor, 39 CopyConstructor, 40 CopyAssignment, 41 MoveConstructor, 42 MoveAssignment 43 }; 44 45 struct SpecialMemberFunctionData { 46 SpecialMemberFunctionKind FunctionKind; 47 bool IsDeleted; 48 bool IsImplicit = false; 49 50 bool operator==(const SpecialMemberFunctionData &Other) const { 51 return (Other.FunctionKind == FunctionKind) && 52 (Other.IsDeleted == IsDeleted); 53 } 54 }; 55 56 using ClassDefId = std::pair<SourceLocation, std::string>; 57 58 using ClassDefiningSpecialMembersMap = 59 llvm::DenseMap<ClassDefId, 60 llvm::SmallVector<SpecialMemberFunctionData, 5>>; 61 62 private: 63 void checkForMissingMembers( 64 const ClassDefId &ID, 65 llvm::ArrayRef<SpecialMemberFunctionData> DefinedMembers); 66 67 const bool AllowMissingMoveFunctions; 68 const bool AllowSoleDefaultDtor; 69 const bool AllowMissingMoveFunctionsWhenCopyIsDeleted; 70 const bool AllowImplicitlyDeletedCopyOrMove; 71 ClassDefiningSpecialMembersMap ClassWithSpecialMembers; 72 }; 73 74 } // namespace clang::tidy::cppcoreguidelines 75 76 namespace llvm { 77 /// Specialization of DenseMapInfo to allow ClassDefId objects in DenseMaps 78 /// FIXME: Move this to the corresponding cpp file as is done for 79 /// clang-tidy/readability/IdentifierNamingCheck.cpp. 80 template <> 81 struct DenseMapInfo< 82 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId> { 83 using ClassDefId = 84 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId; 85 86 static inline ClassDefId getEmptyKey() { 87 return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(), 88 "EMPTY"}; 89 } 90 91 static inline ClassDefId getTombstoneKey() { 92 return {DenseMapInfo<clang::SourceLocation>::getTombstoneKey(), 93 "TOMBSTONE"}; 94 } 95 96 static unsigned getHashValue(ClassDefId Val) { 97 assert(Val != getEmptyKey() && "Cannot hash the empty key!"); 98 assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!"); 99 100 std::hash<ClassDefId::second_type> SecondHash; 101 return Val.first.getHashValue() + SecondHash(Val.second); 102 } 103 104 static bool isEqual(const ClassDefId &LHS, const ClassDefId &RHS) { 105 if (RHS == getEmptyKey()) 106 return LHS == getEmptyKey(); 107 if (RHS == getTombstoneKey()) 108 return LHS == getTombstoneKey(); 109 return LHS == RHS; 110 } 111 }; 112 113 } // namespace llvm 114 115 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H 116