11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 using namespace clang::ast_matchers;
18 namespace readability {
20 void DeletedDefaultCheck::registerMatchers(MatchFinder *
Finder) {
29 cxxMethodDecl(anyOf(cxxConstructorDecl().bind(
"constructor"),
30 isCopyAssignmentOperator(),
31 isMoveAssignmentOperator()),
32 isDefaulted(), unless(isImplicit()), isDeleted(),
33 unless(isInstantiated()))
38 void DeletedDefaultCheck::check(
const MatchFinder::MatchResult &
Result) {
39 const StringRef Message =
"%0 is explicitly defaulted but implicitly "
40 "deleted, probably because %1; definition can "
41 "either be removed or explicitly deleted";
42 if (
const auto *Constructor =
43 Result.Nodes.getNodeAs<CXXConstructorDecl>(
"constructor")) {
44 auto Diag = diag(Constructor->getLocStart(), Message);
45 if (Constructor->isDefaultConstructor()) {
46 Diag <<
"default constructor"
47 <<
"a non-static data member or a base class is lacking a default "
49 }
else if (Constructor->isCopyConstructor()) {
50 Diag <<
"copy constructor"
51 <<
"a non-static data member or a base class is not copyable";
52 }
else if (Constructor->isMoveConstructor()) {
53 Diag <<
"move constructor"
54 <<
"a non-static data member or a base class is neither copyable "
57 }
else if (
const auto *Assignment =
58 Result.Nodes.getNodeAs<CXXMethodDecl>(
"method-decl")) {
59 diag(Assignment->getLocStart(), Message)
60 << (Assignment->isCopyAssignmentOperator() ?
"copy assignment operator"
61 :
"move assignment operator")
62 <<
"a base class or a non-static data member is not assignable, e.g. "
63 "because the latter is marked 'const'";
std::unique_ptr< ast_matchers::MatchFinder > Finder