clang-tools  8.0.0
DeletedDefaultCheck.cpp
Go to the documentation of this file.
1 //===--- DeletedDefaultCheck.cpp - clang-tidy------------------------------===//
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 "DeletedDefaultCheck.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 
14 using namespace clang::ast_matchers;
15 
16 namespace clang {
17 namespace tidy {
18 namespace readability {
19 
20 void DeletedDefaultCheck::registerMatchers(MatchFinder *Finder) {
21  // We match constructors/assignment operators that are:
22  // - explicitly marked '= default'
23  // - actually deleted
24  // - not in template instantiation.
25  // We bind the declaration to "method-decl" and also to "constructor" when
26  // it is a constructor.
27 
28  Finder->addMatcher(
29  cxxMethodDecl(anyOf(cxxConstructorDecl().bind("constructor"),
30  isCopyAssignmentOperator(),
31  isMoveAssignmentOperator()),
32  isDefaulted(), unless(isImplicit()), isDeleted(),
33  unless(isInstantiated()))
34  .bind("method-decl"),
35  this);
36 }
37 
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->getBeginLoc(), Message);
45  if (Constructor->isDefaultConstructor()) {
46  Diag << "default constructor"
47  << "a non-static data member or a base class is lacking a default "
48  "constructor";
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 "
55  "nor movable";
56  }
57  } else if (const auto *Assignment =
58  Result.Nodes.getNodeAs<CXXMethodDecl>("method-decl")) {
59  diag(Assignment->getBeginLoc(), 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'";
64  }
65 }
66 
67 } // namespace readability
68 } // namespace tidy
69 } // namespace clang
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//