10#include "clang/AST/ASTContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
18 if (
Node.needsOverloadResolutionForCopyConstructor() &&
19 Node.needsImplicitCopyConstructor()) {
21 for (CXXBaseSpecifier
const &BS :
Node.bases()) {
22 CXXRecordDecl
const *BRD = BS.getType()->getAsCXXRecordDecl();
27 if (
Node.hasSimpleCopyConstructor())
29 for (CXXConstructorDecl
const *Ctor :
Node.ctors())
30 if (Ctor->isCopyConstructor())
31 return !Ctor->isDeleted();
36 if (
Node.needsOverloadResolutionForMoveConstructor() &&
37 Node.needsImplicitMoveConstructor()) {
39 for (CXXBaseSpecifier
const &BS :
Node.bases()) {
40 CXXRecordDecl
const *BRD = BS.getType()->getAsCXXRecordDecl();
45 if (
Node.hasSimpleMoveConstructor())
47 for (CXXConstructorDecl
const *Ctor :
Node.ctors())
48 if (Ctor->isMoveConstructor())
49 return !Ctor->isDeleted();
54 if (
Node.needsOverloadResolutionForCopyAssignment() &&
55 Node.needsImplicitCopyAssignment()) {
57 for (CXXBaseSpecifier
const &BS :
Node.bases()) {
58 CXXRecordDecl
const *BRD = BS.getType()->getAsCXXRecordDecl();
63 if (
Node.hasSimpleCopyAssignment())
65 for (CXXMethodDecl
const *Method :
Node.methods())
66 if (Method->isCopyAssignmentOperator())
67 return !Method->isDeleted();
72 if (
Node.needsOverloadResolutionForMoveAssignment() &&
73 Node.needsImplicitMoveAssignment()) {
75 for (CXXBaseSpecifier
const &BS :
Node.bases()) {
76 CXXRecordDecl
const *BRD = BS.getType()->getAsCXXRecordDecl();
81 if (
Node.hasSimpleMoveAssignment())
83 for (CXXMethodDecl
const *Method :
Node.methods())
84 if (Method->isMoveAssignmentOperator())
85 return !Method->isDeleted();
92 return Node.getParent()->isLambda();
105 unless(isMemberOfLambda()),
107 fieldDecl(hasType(hasCanonicalType(referenceType()))).bind(
"ref"),
108 fieldDecl(hasType(qualType(isConstQualified()))).bind(
"const")),
109 hasDeclContext(cxxRecordDecl(isCopyableOrMovable()))),
114 const MatchFinder::MatchResult &Result) {
115 if (
const auto *MatchedDecl = Result.Nodes.getNodeAs<FieldDecl>(
"ref"))
116 diag(MatchedDecl->getLocation(),
"member %0 of type %1 is a reference")
117 << MatchedDecl << MatchedDecl->getType();
118 if (
const auto *MatchedDecl = Result.Nodes.getNodeAs<FieldDecl>(
"const"))
119 diag(MatchedDecl->getLocation(),
"member %0 of type %1 is const qualified")
120 << MatchedDecl << MatchedDecl->getType();
::clang::DynTypedNode Node
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
static bool isMoveAssignable(CXXRecordDecl const &Node)
AST_MATCHER(CXXRecordDecl, hasPublicVirtualOrProtectedNonVirtualDestructor)
static bool isCopyAssignable(CXXRecordDecl const &Node)
static bool isCopyConstructible(CXXRecordDecl const &Node)
static bool isMoveConstructible(CXXRecordDecl const &Node)