clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

AssignOperatorSignatureCheck.cpp
Go to the documentation of this file.
1 //===--- AssignOperatorSignatureCheck.cpp - clang-tidy ----------*- C++ -*-===//
2 //
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 #include "AssignOperatorSignatureCheck.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
13
14 using namespace clang::ast_matchers;
15
16 namespace clang {
17 namespace tidy {
18 namespace misc {
19
20 void AssignOperatorSignatureCheck::registerMatchers(
21 ast_matchers::MatchFinder *Finder) {
22 // Only register the matchers for C++; the functionality currently does not
23 // provide any benefit to other languages, despite being benign.
24 if (!getLangOpts().CPlusPlus)
25 return;
26
27 const auto HasGoodReturnType = cxxMethodDecl(returns(
28 lValueReferenceType(pointee(unless(isConstQualified()),
29 hasDeclaration(equalsBoundNode("class"))))));
30
31 const auto IsSelf = qualType(
32 anyOf(hasDeclaration(equalsBoundNode("class")),
33 referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
34 const auto IsSelfAssign =
35 cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
36 hasName("operator="), ofClass(recordDecl().bind("class")),
37 hasParameter(0, parmVarDecl(hasType(IsSelf))))
38 .bind("method");
39
40 Finder->addMatcher(
41 cxxMethodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"),
42 this);
43
44 const auto BadSelf = referenceType(
45 anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
46 rValueReferenceType(pointee(isConstQualified()))));
47
48 Finder->addMatcher(
49 cxxMethodDecl(IsSelfAssign,
50 hasParameter(0, parmVarDecl(hasType(BadSelf))))
51 .bind("ArgumentType"),
52 this);
53
54 Finder->addMatcher(
55 cxxMethodDecl(IsSelfAssign, anyOf(isConst(), isVirtual())).bind("cv"),
56 this);
57 }
58
59 void AssignOperatorSignatureCheck::check(
60 const MatchFinder::MatchResult &Result) {
61 const auto* Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method");
62 std::string Name = Method->getParent()->getName();
63
64 static const char *const Messages[][2] = {
65 {"ReturnType", "operator=() should return '%0&'"},
66 {"ArgumentType", "operator=() should take '%0 const&', '%0&&' or '%0'"},
67 {"cv", "operator=() should not be marked '%1'"}
68 };
69
70 for (const auto &Message : Messages) {
71 if (Result.Nodes.getNodeAs<Decl>(Message[0]))
72 diag(Method->getLocStart(), Message[1])
73 << Name << (Method->isConst() ? "const" : "virtual");
74 }
75 }
76
77 } // namespace misc
78 } // namespace tidy
79 } // namespace clang
Name
StringHandle Name
Definition: PreprocessorTracker.cpp:525
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
AssignOperatorSignatureCheck.h
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121