blob: c4e31c2f4573203a107a404f30fe4f0ad446b806 [file] [log] [blame]
Jonathan Coe77ec2632016-08-02 21:18:37 +00001//===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===//
Jonathan Coe5d304b22016-07-30 08:58:54 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H
12
13#include "../ClangTidy.h"
14
15#include "llvm/ADT/DenseMapInfo.h"
16
17namespace clang {
18namespace tidy {
19namespace cppcoreguidelines {
20
21/// Checks for classes where some, but not all, of the special member functions
22/// are defined.
23///
24/// For the user-facing documentation see:
25/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-special-member-functions.html
26class SpecialMemberFunctionsCheck : public ClangTidyCheck {
27public:
28 SpecialMemberFunctionsCheck(StringRef Name, ClangTidyContext *Context)
29 : ClangTidyCheck(Name, Context) {}
30 void registerMatchers(ast_matchers::MatchFinder *Finder) override;
31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
32 void onEndOfTranslationUnit() override;
Kirill Bobyrev11cea452016-08-01 12:06:18 +000033
Justin Lebarae90ad22016-10-21 20:13:39 +000034 enum class SpecialMemberFunctionKind : uint8_t {
Jonathan Coe5d304b22016-07-30 08:58:54 +000035 Destructor,
36 CopyConstructor,
37 CopyAssignment,
38 MoveConstructor,
39 MoveAssignment
40 };
41
42 using ClassDefId = std::pair<SourceLocation, std::string>;
43
Jonathan Coe77ec2632016-08-02 21:18:37 +000044 using ClassDefiningSpecialMembersMap =
45 llvm::DenseMap<ClassDefId,
Justin Lebarae90ad22016-10-21 20:13:39 +000046 llvm::SmallVector<SpecialMemberFunctionKind, 5>>;
Jonathan Coe5d304b22016-07-30 08:58:54 +000047
48private:
Jonathan Coe5d304b22016-07-30 08:58:54 +000049 ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
50};
51
52} // namespace cppcoreguidelines
53} // namespace tidy
54} // namespace clang
55
56namespace llvm {
57/// Specialisation of DenseMapInfo to allow ClassDefId objects in DenseMaps
58/// FIXME: Move this to the corresponding cpp file as is done for
Kirill Bobyrev11cea452016-08-01 12:06:18 +000059/// clang-tidy/readability/IdentifierNamingCheck.cpp.
Jonathan Coe5d304b22016-07-30 08:58:54 +000060template <>
61struct DenseMapInfo<
62 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId> {
63 using ClassDefId =
Jonathan Coe77ec2632016-08-02 21:18:37 +000064 clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId;
Jonathan Coe5d304b22016-07-30 08:58:54 +000065
66 static inline ClassDefId getEmptyKey() {
67 return ClassDefId(
68 clang::SourceLocation::getFromRawEncoding(static_cast<unsigned>(-1)),
69 "EMPTY");
70 }
71
72 static inline ClassDefId getTombstoneKey() {
73 return ClassDefId(
74 clang::SourceLocation::getFromRawEncoding(static_cast<unsigned>(-2)),
75 "TOMBSTONE");
76 }
77
78 static unsigned getHashValue(ClassDefId Val) {
79 assert(Val != getEmptyKey() && "Cannot hash the empty key!");
80 assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");
81
82 std::hash<ClassDefId::second_type> SecondHash;
83 return Val.first.getRawEncoding() + SecondHash(Val.second);
84 }
85
86 static bool isEqual(ClassDefId LHS, ClassDefId RHS) {
87 if (RHS == getEmptyKey())
88 return LHS == getEmptyKey();
89 if (RHS == getTombstoneKey())
90 return LHS == getTombstoneKey();
91 return LHS == RHS;
92 }
93};
94
95} // namespace llvm
96
97#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H