blob: 829371b3e1e978081000858ee862455d16b9c86c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
//===--- UseDefaultCheck.cpp - clang-tidy----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "UseDefaultCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace modernize {
static const char CtorDtor[] = "CtorDtorDecl";
void UseDefaultCheck::registerMatchers(MatchFinder *Finder) {
if (getLangOpts().CPlusPlus) {
Finder->addMatcher(
cxxConstructorDecl(isDefinition(),
unless(hasAnyConstructorInitializer(anything())),
parameterCountIs(0))
.bind(CtorDtor),
this);
Finder->addMatcher(cxxDestructorDecl(isDefinition()).bind(CtorDtor), this);
}
}
void UseDefaultCheck::check(const MatchFinder::MatchResult &Result) {
// Both CXXConstructorDecl and CXXDestructorDecl inherit from CXXMethodDecl.
const auto *CtorDtorDecl = Result.Nodes.getNodeAs<CXXMethodDecl>(CtorDtor);
// Discard explicitly deleted/defaulted constructors/destructors, those that
// are not user-provided (automatically generated constructor/destructor), and
// those with non-empty bodies.
if (CtorDtorDecl->isDeleted() || CtorDtorDecl->isExplicitlyDefaulted() ||
!CtorDtorDecl->isUserProvided() || !CtorDtorDecl->hasTrivialBody())
return;
const auto *Body = dyn_cast<CompoundStmt>(CtorDtorDecl->getBody());
// This should never happen, since 'hasTrivialBody' checks that this is
// actually a CompoundStmt.
assert(Body && "Definition body is not a CompoundStmt");
diag(CtorDtorDecl->getLocStart(),
"use '= default' to define a trivial " +
std::string(dyn_cast<CXXConstructorDecl>(CtorDtorDecl)
? "default constructor"
: "destructor"))
<< FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(Body->getLBracLoc(),
Body->getRBracLoc()),
"= default;");
}
} // namespace modernize
} // namespace tidy
} // namespace clang
|