[clang-tools-extra] r250897 - Add modernize-use-default check to clang-tidy.
Angel Garcia Gomez via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 21 05:58:16 PDT 2015
Author: angelgarcia
Date: Wed Oct 21 07:58:15 2015
New Revision: 250897
URL: http://llvm.org/viewvc/llvm-project?rev=250897&view=rev
Log:
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
Added:
clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h
clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst
clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=250897&r1=250896&r2=250897&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Wed Oct 21 07:58:15 2015
@@ -9,6 +9,7 @@ add_clang_library(clangTidyModernizeModu
ReplaceAutoPtrCheck.cpp
ShrinkToFitCheck.cpp
UseAutoCheck.cpp
+ UseDefaultCheck.cpp
UseNullptrCheck.cpp
UseOverrideCheck.cpp
Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=250897&r1=250896&r2=250897&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Wed Oct 21 07:58:15 2015
@@ -16,6 +16,7 @@
#include "ReplaceAutoPtrCheck.h"
#include "ShrinkToFitCheck.h"
#include "UseAutoCheck.h"
+#include "UseDefaultCheck.h"
#include "UseNullptrCheck.h"
#include "UseOverrideCheck.h"
@@ -29,13 +30,13 @@ class ModernizeModule : public ClangTidy
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert");
- CheckFactories.registerCheck<MakeUniqueCheck>(
- "modernize-make-unique");
+ CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique");
CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value");
CheckFactories.registerCheck<ReplaceAutoPtrCheck>(
"modernize-replace-auto-ptr");
CheckFactories.registerCheck<ShrinkToFitCheck>("modernize-shrink-to-fit");
CheckFactories.registerCheck<UseAutoCheck>("modernize-use-auto");
+ CheckFactories.registerCheck<UseDefaultCheck>("modernize-use-default");
CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr");
CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
}
@@ -45,7 +46,7 @@ public:
auto &Opts = Options.CheckOptions;
Opts["modernize-loop-convert.MinConfidence"] = "reasonable";
Opts["modernize-loop-convert.NamingStyle"] = "CamelCase";
- Opts["modernize-pass-by-value.IncludeStyle"] = "llvm"; // Also: "google".
+ Opts["modernize-pass-by-value.IncludeStyle"] = "llvm"; // Also: "google".
Opts["modernize-replace-auto-ptr.IncludeStyle"] = "llvm"; // Also: "google".
// Comma-separated list of macros that behave like NULL.
Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp?rev=250897&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp Wed Oct 21 07:58:15 2015
@@ -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
Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h?rev=250897&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h Wed Oct 21 07:58:15 2015
@@ -0,0 +1,51 @@
+//===--- UseDefaultCheck.h - clang-tidy--------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// \brief Replace default bodies of special member functions with '= default;'.
+/// \code
+/// struct A {
+/// A() {}
+/// ~A();
+/// };
+/// A::~A() {}
+/// \endcode
+/// Is converted to:
+/// \code
+/// struct A {
+/// A() = default;
+/// ~A();
+/// };
+/// A::~A() = default;
+/// \endcode
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-default.html
+class UseDefaultCheck : public ClangTidyCheck {
+public:
+ UseDefaultCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_H
+
Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=250897&r1=250896&r2=250897&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Oct 21 07:58:15 2015
@@ -55,6 +55,7 @@ List of clang-tidy Checks
modernize-replace-auto-ptr
modernize-shrink-to-fit
modernize-use-auto
+ modernize-use-default
modernize-use-nullptr
modernize-use-override
readability-braces-around-statements
Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst?rev=250897&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst Wed Oct 21 07:58:15 2015
@@ -0,0 +1,27 @@
+modernize-use-default
+=====================
+
+This check replaces default bodies of special member functions with ``=
+default;``. The explicitly defaulted function declarations enable more
+opportunities in optimization, because the compiler might treat explicitly
+defaulted functions as trivial.
+
+.. code-block:: c++
+
+ struct A {
+ A() {}
+ ~A();
+ };
+ A::~A() {}
+
+ // becomes
+
+ struct A {
+ A() = default;
+ ~A();
+ };
+ A::~A() = default;
+
+.. note::
+ Copy-constructor, copy-assignment operator, move-constructor and
+ move-assignment operator are not supported yet.
Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp?rev=250897&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp Wed Oct 21 07:58:15 2015
@@ -0,0 +1,137 @@
+// RUN: %python %S/check_clang_tidy.py %s modernize-use-default %t
+
+class A {
+public:
+ A();
+ ~A();
+};
+
+A::A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor [modernize-use-default]
+// CHECK-FIXES: A::A() = default;
+A::~A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial destructor [modernize-use-default]
+// CHECK-FIXES: A::~A() = default;
+
+// Inline definitions.
+class B {
+public:
+ B() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: B() = default;
+ ~B() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~B() = default;
+};
+
+void f();
+
+class C {
+public:
+ // Non-empty constructor body.
+ C() { f(); }
+ // Non-empty destructor body.
+ ~C() { f(); }
+};
+
+class D {
+public:
+ // Constructor with initializer.
+ D() : Field(5) {}
+ // Constructor with arguments.
+ D(int Arg1, int Arg2) {}
+ int Field;
+};
+
+// Private constructor/destructor.
+class E {
+ E() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: E() = default;
+ ~E() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~E() = default;
+};
+
+// struct.
+struct F {
+ F() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: F() = default;
+ ~F() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: F() = default;
+};
+
+// Deleted constructor/destructor.
+class G {
+public:
+ G() = delete;
+ ~G() = delete;
+};
+
+// Do not remove other keywords.
+class H {
+public:
+ explicit H() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: explicit H() = default;
+ virtual ~H() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: virtual ~H() = default;
+};
+
+// Nested class.
+struct I {
+ struct II {
+ II() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+ // CHECK-FIXES: II() = default;
+ ~II() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+ // CHECK-FIXES: ~II() = default;
+ };
+ int Int;
+};
+
+// Class template.
+template <class T>
+class J {
+public:
+ J() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: J() = default;
+ ~J() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~J() = default;
+};
+
+// Non user-provided constructor/destructor.
+struct K {
+ int Int;
+};
+void g() {
+ K *PtrK = new K();
+ PtrK->~K();
+ delete PtrK;
+}
+
+// Already using default.
+struct L {
+ L() = default;
+ ~L() = default;
+};
+struct M {
+ M();
+ ~M();
+};
+M::M() = default;
+M::~M() = default;
+
+// Delegating constructor and overriden destructor.
+struct N : H {
+ N() : H() {}
+ ~N() override {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~N() override = default;
+};
More information about the cfe-commits
mailing list