clang-tools  10.0.0
DeletedDefaultCheck.cpp
Go to the documentation of this file.
1 //===--- DeletedDefaultCheck.cpp - clang-tidy------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DeletedDefaultCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 
13 using namespace clang::ast_matchers;
14 
15 namespace clang {
16 namespace tidy {
17 namespace readability {
18 
19 void DeletedDefaultCheck::registerMatchers(MatchFinder *Finder) {
20  // We match constructors/assignment operators that are:
21  // - explicitly marked '= default'
22  // - actually deleted
23  // - not in template instantiation.
24  // We bind the declaration to "method-decl" and also to "constructor" when
25  // it is a constructor.
26 
27  Finder->addMatcher(
28  cxxMethodDecl(anyOf(cxxConstructorDecl().bind("constructor"),
29  isCopyAssignmentOperator(),
30  isMoveAssignmentOperator()),
31  isDefaulted(), unless(isImplicit()), isDeleted(),
32  unless(isInstantiated()))
33  .bind("method-decl"),
34  this);
35 }
36 
37 void DeletedDefaultCheck::check(const MatchFinder::MatchResult &Result) {
38  const StringRef Message = "%0 is explicitly defaulted but implicitly "
39  "deleted, probably because %1; definition can "
40  "either be removed or explicitly deleted";
41  if (const auto *Constructor =
42  Result.Nodes.getNodeAs<CXXConstructorDecl>("constructor")) {
43  auto Diag = diag(Constructor->getBeginLoc(), Message);
44  if (Constructor->isDefaultConstructor()) {
45  Diag << "default constructor"
46  << "a non-static data member or a base class is lacking a default "
47  "constructor";
48  } else if (Constructor->isCopyConstructor()) {
49  Diag << "copy constructor"
50  << "a non-static data member or a base class is not copyable";
51  } else if (Constructor->isMoveConstructor()) {
52  Diag << "move constructor"
53  << "a non-static data member or a base class is neither copyable "
54  "nor movable";
55  }
56  } else if (const auto *Assignment =
57  Result.Nodes.getNodeAs<CXXMethodDecl>("method-decl")) {
58  diag(Assignment->getBeginLoc(), Message)
59  << (Assignment->isCopyAssignmentOperator() ? "copy assignment operator"
60  : "move assignment operator")
61  << "a base class or a non-static data member is not assignable, e.g. "
62  "because the latter is marked 'const'";
63  }
64 }
65 
66 } // namespace readability
67 } // namespace tidy
68 } // namespace clang
constexpr llvm::StringLiteral Message
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//