summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc
diff options
context:
space:
mode:
authorSamuel Benzaquen <sbenza@google.com>2014-03-27 17:42:26 +0000
committerSamuel Benzaquen <sbenza@google.com>2014-03-27 17:42:26 +0000
commit3a571019c8b17e6f5896c5b2a80e3a854011eb32 (patch)
tree6a7f609f79d924e428298252097304d9167f26d3 /clang-tools-extra/clang-tidy/misc
parentb517c8128e8255a205d2e2da65a26f38e2474fcb (diff)
downloadbcm5719-llvm-3a571019c8b17e6f5896c5b2a80e3a854011eb32.tar.gz
bcm5719-llvm-3a571019c8b17e6f5896c5b2a80e3a854011eb32.zip
Add clang-tidy check to remove redundant .get() calls on smart pointers.
Summary: This check finds and removes redundant .get() calls on smart pointers. Example: ptr.get()->Foo() ==> ptr->Foo() Reviewers: alexfh CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D3186 llvm-svn: 204947
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc')
-rw-r--r--clang-tools-extra/clang-tidy/misc/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp10
-rw-r--r--clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.cpp88
-rw-r--r--clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.h34
4 files changed, 130 insertions, 3 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index 8c9b5dd3c0b..3dd97bf0b4f 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyMiscModule
ArgumentCommentCheck.cpp
MiscTidyModule.cpp
+ RedundantSmartptrGet.cpp
LINK_LIBS
clangAST
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index f7f657addfa..b89e2dcad48 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -11,6 +11,7 @@
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "ArgumentCommentCheck.h"
+#include "RedundantSmartptrGet.h"
namespace clang {
namespace tidy {
@@ -18,9 +19,12 @@ namespace tidy {
class MiscModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
- CheckFactories.addCheckFactory(
- "misc-argument-comment",
- new ClangTidyCheckFactory<ArgumentCommentCheck>());
+ CheckFactories.addCheckFactory(
+ "misc-argument-comment",
+ new ClangTidyCheckFactory<ArgumentCommentCheck>());
+ CheckFactories.addCheckFactory(
+ "misc-redundant-smartptr-get",
+ new ClangTidyCheckFactory<RedundantSmartptrGet>());
}
};
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.cpp b/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.cpp
new file mode 100644
index 00000000000..ec08c142c18
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.cpp
@@ -0,0 +1,88 @@
+//===--- RedundantSmartptrGet.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 "RedundantSmartptrGet.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void RedundantSmartptrGet::registerMatchers(MatchFinder *Finder) {
+ const auto QuacksLikeASmartptr = recordDecl(
+ has(methodDecl(hasName("operator->"),
+ returns(qualType(pointsTo(type().bind("op->Type")))))),
+ has(methodDecl(hasName("operator*"),
+ returns(qualType(references(type().bind("op*Type")))))),
+ has(methodDecl(hasName("get"),
+ returns(qualType(pointsTo(type().bind("getType")))))));
+
+ const auto CallToGet =
+ memberCallExpr(on(expr(hasType(recordDecl(QuacksLikeASmartptr)))
+ .bind("smart_pointer")),
+ callee(methodDecl(hasName("get")))).bind("redundant_get");
+
+ const auto ArrowCallToGet =
+ memberCallExpr(
+ on(expr(hasType(qualType(pointsTo(recordDecl(QuacksLikeASmartptr)))))
+ .bind("smart_pointer")),
+ callee(methodDecl(hasName("get")))).bind("redundant_get");
+
+ // Catch 'ptr.get()->Foo()'
+ Finder->addMatcher(
+ memberExpr(isArrow(), hasObjectExpression(ignoringImpCasts(CallToGet))),
+ this);
+
+ // Catch '*ptr.get()'
+ Finder->addMatcher(
+ unaryOperator(hasOperatorName("*"), hasUnaryOperand(CallToGet)), this);
+
+ // Catch '*ptr->get()'
+ Finder->addMatcher(
+ unaryOperator(hasOperatorName("*"), hasUnaryOperand(ArrowCallToGet))
+ .bind("ptr_to_ptr"),
+ this);
+}
+
+namespace {
+bool allReturnTypesMatch(const MatchFinder::MatchResult &Result) {
+ // Verify that the types match.
+ // We can't do this on the matcher because the type nodes can be different,
+ // even though they represent the same type. This difference comes from how
+ // the type is referenced (eg. through a typedef, a type trait, etc).
+ const Type *OpArrowType =
+ Result.Nodes.getNodeAs<Type>("op->Type")->getUnqualifiedDesugaredType();
+ const Type *OpStarType =
+ Result.Nodes.getNodeAs<Type>("op*Type")->getUnqualifiedDesugaredType();
+ const Type *GetType =
+ Result.Nodes.getNodeAs<Type>("getType")->getUnqualifiedDesugaredType();
+ return OpArrowType == OpStarType && OpArrowType == GetType;
+}
+} // namespace
+
+void RedundantSmartptrGet::check(const MatchFinder::MatchResult &Result) {
+ if (!allReturnTypesMatch(Result)) return;
+
+ bool IsPtrToPtr = Result.Nodes.getNodeAs<Expr>("ptr_to_ptr") != nullptr;
+ const Expr *GetCall = Result.Nodes.getNodeAs<Expr>("redundant_get");
+ const Expr *Smartptr = Result.Nodes.getNodeAs<Expr>("smart_pointer");
+
+ StringRef SmartptrText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(Smartptr->getSourceRange()),
+ *Result.SourceManager, LangOptions());
+ // Replace *foo->get() with **foo, and foo.get() with foo.
+ std::string Replacement = Twine(IsPtrToPtr ? "*" : "", SmartptrText).str();
+ diag(GetCall->getLocStart(), "Redundant get() call on smart pointer.")
+ << FixItHint::CreateReplacement(GetCall->getSourceRange(), Replacement);
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.h b/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.h
new file mode 100644
index 00000000000..32268c2dab1
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/RedundantSmartptrGet.h
@@ -0,0 +1,34 @@
+//===--- RedundantSmartptrGet.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_MISC_REDUNDANT_SMARTPTR_GET_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANT_SMARTPTR_GET_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// \brief Find and remove redundant calls to smart pointer's .get() method.
+///
+/// Examples:
+/// ptr.get()->Foo() ==> ptr->Foo()
+/// *ptr.get() ==> *ptr
+/// *ptr->get() ==> **ptr
+class RedundantSmartptrGet : public ClangTidyCheck {
+public:
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANT_SMARTPTR_GET_H
+
OpenPOWER on IntegriCloud