diff options
author | Angel Garcia Gomez <angelgarcia@google.com> | 2015-10-21 12:58:15 +0000 |
---|---|---|
committer | Angel Garcia Gomez <angelgarcia@google.com> | 2015-10-21 12:58:15 +0000 |
commit | 8dedeb0230c589ca121098f8051a35eb5fb53848 (patch) | |
tree | 3f77020d05c442b64ee9b064d08d0a71f1ff8ec9 /clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp | |
parent | baf54a8ad5710d54bc6cc8fd2e7f1fcfabc9c503 (diff) | |
download | bcm5719-llvm-8dedeb0230c589ca121098f8051a35eb5fb53848.tar.gz bcm5719-llvm-8dedeb0230c589ca121098f8051a35eb5fb53848.zip |
Add modernize-use-default check to clang-tidy.
Summary:
Add a check that replaces empty bodies of special member functions with '= default;'.
For now, it is only implemented for the default constructor and the destructor, which are the easier cases.
The copy-constructor and the copy-assignment operator cases will be implemented later.
I applied this check to the llvm code base and found 627 warnings (385 in llvm, 9 in compiler-rt, 220 in clang and 13 in clang-tools-extra).
Applying the fixes didn't break any build or test, it only caused a -Wpedantic warning in lib/Target/Mips/MipsOptionRecord.h:33 becaused it replaced
virtual ~MipsOptionRecord(){}; to virtual ~MipsOptionRecord()= default;;
Reviewers: klimek
Subscribers: george.burgess.iv, Eugene.Zelenko, alexfh, cfe-commits
Differential Revision: http://reviews.llvm.org/D13871
llvm-svn: 250897
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp new file mode 100644 index 00000000000..829371b3e1e --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseDefaultCheck.cpp @@ -0,0 +1,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 |