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