1 //===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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
12 #include "../ClangTidyCheck.h"
14 #include "llvm/ADT/DenseMapInfo.h"
16 namespace clang::tidy::cppcoreguidelines
{
18 /// Checks for classes where some, but not all, of the special member functions
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
{
25 SpecialMemberFunctionsCheck(StringRef Name
, ClangTidyContext
*Context
);
26 bool isLanguageVersionSupported(const LangOptions
&LangOpts
) const override
{
27 return LangOpts
.CPlusPlus
;
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 return TK_IgnoreUnlessSpelledInSource
;
36 enum class SpecialMemberFunctionKind
: uint8_t {
46 struct SpecialMemberFunctionData
{
47 SpecialMemberFunctionKind FunctionKind
;
50 bool operator==(const SpecialMemberFunctionData
&Other
) const {
51 return (Other
.FunctionKind
== FunctionKind
) &&
52 (Other
.IsDeleted
== IsDeleted
);
56 using ClassDefId
= std::pair
<SourceLocation
, std::string
>;
58 using ClassDefiningSpecialMembersMap
=
59 llvm::DenseMap
<ClassDefId
,
60 llvm::SmallVector
<SpecialMemberFunctionData
, 5>>;
63 void checkForMissingMembers(
65 llvm::ArrayRef
<SpecialMemberFunctionData
> DefinedMembers
);
67 const bool AllowMissingMoveFunctions
;
68 const bool AllowSoleDefaultDtor
;
69 const bool AllowMissingMoveFunctionsWhenCopyIsDeleted
;
70 ClassDefiningSpecialMembersMap ClassWithSpecialMembers
;
73 } // namespace clang::tidy::cppcoreguidelines
76 /// Specialization of DenseMapInfo to allow ClassDefId objects in DenseMaps
77 /// FIXME: Move this to the corresponding cpp file as is done for
78 /// clang-tidy/readability/IdentifierNamingCheck.cpp.
81 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId
> {
83 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId
;
85 static inline ClassDefId
getEmptyKey() {
86 return {DenseMapInfo
<clang::SourceLocation
>::getEmptyKey(),
90 static inline ClassDefId
getTombstoneKey() {
91 return {DenseMapInfo
<clang::SourceLocation
>::getTombstoneKey(),
95 static unsigned getHashValue(ClassDefId Val
) {
96 assert(Val
!= getEmptyKey() && "Cannot hash the empty key!");
97 assert(Val
!= getTombstoneKey() && "Cannot hash the tombstone key!");
99 std::hash
<ClassDefId::second_type
> SecondHash
;
100 return Val
.first
.getHashValue() + SecondHash(Val
.second
);
103 static bool isEqual(const ClassDefId
&LHS
, const ClassDefId
&RHS
) {
104 if (RHS
== getEmptyKey())
105 return LHS
== getEmptyKey();
106 if (RHS
== getTombstoneKey())
107 return LHS
== getTombstoneKey();
114 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H