Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:19

0001 //===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H
0011 
0012 #include "../ClangTidyCheck.h"
0013 
0014 #include "llvm/ADT/DenseMapInfo.h"
0015 
0016 namespace clang::tidy::cppcoreguidelines {
0017 
0018 /// Checks for classes where some, but not all, of the special member functions
0019 /// are defined.
0020 ///
0021 /// For the user-facing documentation see:
0022 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/special-member-functions.html
0023 class SpecialMemberFunctionsCheck : public ClangTidyCheck {
0024 public:
0025   SpecialMemberFunctionsCheck(StringRef Name, ClangTidyContext *Context);
0026   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
0027     return LangOpts.CPlusPlus;
0028   }
0029   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
0030   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
0031   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
0032   void onEndOfTranslationUnit() override;
0033   std::optional<TraversalKind> getCheckTraversalKind() const override;
0034 
0035   enum class SpecialMemberFunctionKind : uint8_t {
0036     Destructor,
0037     DefaultDestructor,
0038     NonDefaultDestructor,
0039     CopyConstructor,
0040     CopyAssignment,
0041     MoveConstructor,
0042     MoveAssignment
0043   };
0044 
0045   struct SpecialMemberFunctionData {
0046     SpecialMemberFunctionKind FunctionKind;
0047     bool IsDeleted;
0048     bool IsImplicit = false;
0049 
0050     bool operator==(const SpecialMemberFunctionData &Other) const {
0051       return (Other.FunctionKind == FunctionKind) &&
0052              (Other.IsDeleted == IsDeleted);
0053     }
0054   };
0055 
0056   using ClassDefId = std::pair<SourceLocation, std::string>;
0057 
0058   using ClassDefiningSpecialMembersMap =
0059       llvm::DenseMap<ClassDefId,
0060                      llvm::SmallVector<SpecialMemberFunctionData, 5>>;
0061 
0062 private:
0063   void checkForMissingMembers(
0064       const ClassDefId &ID,
0065       llvm::ArrayRef<SpecialMemberFunctionData> DefinedMembers);
0066 
0067   const bool AllowMissingMoveFunctions;
0068   const bool AllowSoleDefaultDtor;
0069   const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
0070   const bool AllowImplicitlyDeletedCopyOrMove;
0071   ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
0072 };
0073 
0074 } // namespace clang::tidy::cppcoreguidelines
0075 
0076 namespace llvm {
0077 /// Specialization of DenseMapInfo to allow ClassDefId objects in DenseMaps
0078 /// FIXME: Move this to the corresponding cpp file as is done for
0079 /// clang-tidy/readability/IdentifierNamingCheck.cpp.
0080 template <>
0081 struct DenseMapInfo<
0082     clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId> {
0083   using ClassDefId =
0084       clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId;
0085 
0086   static inline ClassDefId getEmptyKey() {
0087     return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(),
0088                       "EMPTY"};
0089   }
0090 
0091   static inline ClassDefId getTombstoneKey() {
0092     return {DenseMapInfo<clang::SourceLocation>::getTombstoneKey(),
0093                       "TOMBSTONE"};
0094   }
0095 
0096   static unsigned getHashValue(ClassDefId Val) {
0097     assert(Val != getEmptyKey() && "Cannot hash the empty key!");
0098     assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");
0099 
0100     std::hash<ClassDefId::second_type> SecondHash;
0101     return Val.first.getHashValue() + SecondHash(Val.second);
0102   }
0103 
0104   static bool isEqual(const ClassDefId &LHS, const ClassDefId &RHS) {
0105     if (RHS == getEmptyKey())
0106       return LHS == getEmptyKey();
0107     if (RHS == getTombstoneKey())
0108       return LHS == getTombstoneKey();
0109     return LHS == RHS;
0110   }
0111 };
0112 
0113 } // namespace llvm
0114 
0115 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H