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"
18 namespace cppcoreguidelines
{
20 /// Checks for classes where some, but not all, of the special member functions
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
{
27 SpecialMemberFunctionsCheck(StringRef Name
, ClangTidyContext
*Context
);
28 bool isLanguageVersionSupported(const LangOptions
&LangOpts
) const override
{
29 return LangOpts
.CPlusPlus
;
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
;
35 llvm::Optional
<TraversalKind
> getCheckTraversalKind() const override
{
36 return TK_IgnoreUnlessSpelledInSource
;
38 enum class SpecialMemberFunctionKind
: uint8_t {
48 struct SpecialMemberFunctionData
{
49 SpecialMemberFunctionKind FunctionKind
;
52 bool operator==(const SpecialMemberFunctionData
&Other
) {
53 return (Other
.FunctionKind
== FunctionKind
) &&
54 (Other
.IsDeleted
== IsDeleted
);
58 using ClassDefId
= std::pair
<SourceLocation
, std::string
>;
60 using ClassDefiningSpecialMembersMap
=
61 llvm::DenseMap
<ClassDefId
,
62 llvm::SmallVector
<SpecialMemberFunctionData
, 5>>;
65 void checkForMissingMembers(
67 llvm::ArrayRef
<SpecialMemberFunctionData
> DefinedSpecialMembers
);
69 const bool AllowMissingMoveFunctions
;
70 const bool AllowSoleDefaultDtor
;
71 const bool AllowMissingMoveFunctionsWhenCopyIsDeleted
;
72 ClassDefiningSpecialMembersMap ClassWithSpecialMembers
;
75 } // namespace cppcoreguidelines
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.
85 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId
> {
87 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId
;
89 static inline ClassDefId
getEmptyKey() {
90 return ClassDefId(DenseMapInfo
<clang::SourceLocation
>::getEmptyKey(),
94 static inline ClassDefId
getTombstoneKey() {
95 return ClassDefId(DenseMapInfo
<clang::SourceLocation
>::getTombstoneKey(),
99 static unsigned getHashValue(ClassDefId Val
) {
100 assert(Val
!= getEmptyKey() && "Cannot hash the empty key!");
101 assert(Val
!= getTombstoneKey() && "Cannot hash the tombstone key!");
103 std::hash
<ClassDefId::second_type
> SecondHash
;
104 return Val
.first
.getHashValue() + SecondHash(Val
.second
);
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();
118 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H