Index: clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tidy/readability/CMakeLists.txt +++ clang-tidy/readability/CMakeLists.txt @@ -20,6 +20,7 @@ RedundantControlFlowCheck.cpp RedundantDeclarationCheck.cpp RedundantFunctionPtrDereferenceCheck.cpp + RedundantKeywordCheck.cpp RedundantMemberInitCheck.cpp RedundantStringCStrCheck.cpp RedundantSmartptrGetCheck.cpp Index: clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tidy/readability/ReadabilityTidyModule.cpp @@ -27,6 +27,7 @@ #include "RedundantControlFlowCheck.h" #include "RedundantDeclarationCheck.h" #include "RedundantFunctionPtrDereferenceCheck.h" +#include "RedundantKeywordCheck.h" #include "RedundantMemberInitCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" @@ -68,6 +69,8 @@ "readability-misplaced-array-index"); CheckFactories.registerCheck( "readability-redundant-function-ptr-dereference"); + CheckFactories.registerCheck( + "readability-redundant-keyword"); CheckFactories.registerCheck( "readability-redundant-member-init"); CheckFactories.registerCheck( Index: clang-tidy/readability/RedundantKeywordCheck.h =================================================================== --- /dev/null +++ clang-tidy/readability/RedundantKeywordCheck.h @@ -0,0 +1,35 @@ +//===--- RedundantKeywordCheck.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_READABILITY_REDUNDANT_KEYWORD_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_KEYWORD_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// Finds redundant 'extern' and 'inline' keywords +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-keyword.html +class RedundantKeywordCheck : public ClangTidyCheck { +public: + RedundantKeywordCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_KEYWORD_H Index: clang-tidy/readability/RedundantKeywordCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/readability/RedundantKeywordCheck.cpp @@ -0,0 +1,75 @@ +//===--- RedundantKeywordCheck.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 "RedundantKeywordCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +template +static bool startsWith(const T &Node, StringRef Value) { + Token Result; + Lexer::getRawToken(Node.getLocStart(), Result, + Node.getASTContext().getSourceManager(), + Node.getASTContext().getLangOpts()); + return Result.isAnyIdentifier() && Result.getRawIdentifier() == Value; +} + +AST_MATCHER(FunctionDecl, hasExternKeyword) { + return startsWith(Node, "extern"); +} + +AST_MATCHER(CXXMethodDecl, hasInlineKeyword) { + return startsWith(Node, "inline"); +} + +void RedundantKeywordCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxMethodDecl(hasParent(cxxRecordDecl()), isDefinition(), hasInlineKeyword()) + .bind("redundant_inline"), + this); + Finder->addMatcher( + functionDecl(hasExternKeyword(), unless(anyOf(isDefinition(), isExternC()))).bind("redundant_extern"), + this); +} + +void RedundantKeywordCheck::check(const MatchFinder::MatchResult &Result) { + auto *RedKeyword = + Result.Nodes.getNodeAs("redundant_inline"); + auto IsInline = true; + + if (!RedKeyword) { + RedKeyword = + Result.Nodes.getNodeAs("redundant_extern"); + IsInline = false; + } + + if (RedKeyword->getLocStart().isMacroID()) + return; + + auto Diag = diag(RedKeyword->getLocStart(), "redundant '%select{inline|extern}0' keyword") << (IsInline ? 0 : 1); + Token TokenToRemove; + + Lexer::getRawToken(RedKeyword->getLocStart(), TokenToRemove, + *Result.SourceManager, + Result.Context->getLangOpts()); + Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( + RedKeyword->getLocStart(), + TokenToRemove.getEndLoc())); +} + +} // namespace readability +} // namespace tidy +} // namespace clang \ No newline at end of file Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -164,6 +164,7 @@ readability-redundant-control-flow readability-redundant-declaration readability-redundant-function-ptr-dereference + readability-redundant-keyword readability-redundant-member-init readability-redundant-smartptr-get readability-redundant-string-cstr Index: docs/clang-tidy/checks/readability-redundant-keyword.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/readability-redundant-keyword.rst @@ -0,0 +1,21 @@ +.. title:: clang-tidy - readability-redundant-keyword + +readability-redundant-keyword +============================= + +This checker removes the redundant `extern` and `inline` keywords from code. + +`extern` is redundant in function declarations + +.. code-block:: c++ + + extern void h(); + + +`inline` is redundant in function definitions within class declaration. + +.. code-block:: c++ + + class X { + inline int f() { .... } + }; \ No newline at end of file Index: test/clang-tidy/readability-redundant-keyword.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability-redundant-keyword.cpp @@ -0,0 +1,23 @@ +// RUN: %check_clang_tidy %s readability-redundant-keyword %t + +extern void h(); +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: redundant 'extern' keyword [readability-redundant-keyword] + +void h2(); + +class Foo { + inline int f() { return 0; } + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant 'inline' keyword [readability-redundant-keyword] +}; + +class X { + int f() { return 0; } + int g(); +}; + +inline int X::g() { return 0; } + +extern int g() { return 0; } + +extern "C" void ok(); +