danielmarjamaki created this revision.
danielmarjamaki added a reviewer: alexfh.
danielmarjamaki added a subscriber: cfe-commits.
Herald added subscribers: mgorny, beanz.

This is a new check that warns about redundant variable declarations.

https://reviews.llvm.org/D24656

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantDeclarationCheck.cpp
  clang-tidy/readability/RedundantDeclarationCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-declaration.rst
  test/clang-tidy/readability-redundant-declaration.cpp

Index: test/clang-tidy/readability-redundant-declaration.cpp
===================================================================
--- test/clang-tidy/readability-redundant-declaration.cpp
+++ test/clang-tidy/readability-redundant-declaration.cpp
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s readability-redundant-declaration %t
+
+extern int Xyz;
+extern int Xyz;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant variable Xyz declaration [readability-redundant-declaration]
+// CHECK-FIXES: {{^}}{{$}}
+
+extern int A;
+extern int A,B;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant variable A declaration
+// CHECK-FIXES: {{^}}extern int A,B;{{$}}
+
+extern int Buf[10];
+extern int Buf[10];
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant variable Buf declaration
+// CHECK-FIXES: {{^}}{{$}}
Index: docs/clang-tidy/checks/readability-redundant-declaration.rst
===================================================================
--- docs/clang-tidy/checks/readability-redundant-declaration.rst
+++ docs/clang-tidy/checks/readability-redundant-declaration.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - readability-redundant-declaration
+
+readability-redundant-declaration
+=================================
+
+Finds redundant variable declarations.
+
+.. code-block:: c++
+
+  extern int X;
+  extern int X;
+
+becomes
+
+.. code-block:: c++
+
+  extern int X;
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -133,6 +133,7 @@
    readability-named-parameter
    readability-non-const-parameter
    readability-redundant-control-flow
+   readability-redundant-declaration
    readability-redundant-smartptr-get
    readability-redundant-string-cstr
    readability-redundant-string-init
Index: clang-tidy/readability/RedundantDeclarationCheck.h
===================================================================
--- clang-tidy/readability/RedundantDeclarationCheck.h
+++ clang-tidy/readability/RedundantDeclarationCheck.h
@@ -0,0 +1,35 @@
+//===--- RedundantDeclarationCheck.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_DECLARATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_DECLARATION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-declaration.html
+class RedundantDeclarationCheck : public ClangTidyCheck {
+public:
+  RedundantDeclarationCheck(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_DECLARATION_H
Index: clang-tidy/readability/RedundantDeclarationCheck.cpp
===================================================================
--- clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -0,0 +1,65 @@
+//===--- RedundantDeclarationCheck.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 "RedundantDeclarationCheck.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 {
+
+void RedundantDeclarationCheck::registerMatchers(MatchFinder *Finder) {
+  // FIXME: Add matchers.
+  Finder->addMatcher(varDecl().bind("Decl"), this);
+}
+
+void RedundantDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *VD = Result.Nodes.getNodeAs<VarDecl>("Decl");
+  const auto *Prev = VD->getPreviousDecl();
+  if (!Prev)
+    return;
+  if (Prev->getStorageClass() == SC_Extern && VD->getStorageClass() != SC_Extern)
+    return;
+  if (Prev->getLocation() == VD->getLocation())
+    return;
+  const SourceManager &SM = *Result.SourceManager;
+  if (SM.isInSystemHeader(VD->getLocation()))
+    return;
+  if (!SM.isInMainFile(VD->getLocation()) && !SM.isWrittenInSameFile(Prev->getLocation(), VD->getLocation()))
+    return;
+
+  // Don't generate fixits for multivariable declarations.
+  bool MultiVar = false;
+  for (const char *Code = SM.getCharacterData(VD->getLocStart()); *Code && *Code != ';'; ++Code) {
+    if (*Code == ',') {
+      MultiVar = true;
+      break;
+    }
+  }
+
+  if (MultiVar) {
+    diag(VD->getLocation(), "redundant variable %0 declaration")
+      << VD->getName();
+    diag(VD->getPreviousDecl()->getLocation(), "previously declared here", DiagnosticIDs::Note);
+  } else {
+    SourceLocation EndLoc = Lexer::getLocForEndOfToken(VD->getLocEnd(), 0, SM, Result.Context->getLangOpts());
+    diag(VD->getLocation(), "redundant variable %0 declaration")
+      << VD->getName()
+      << FixItHint::CreateRemoval(SourceRange(VD->getLocStart(), EndLoc));
+    diag(VD->getPreviousDecl()->getLocation(), "previously declared here", DiagnosticIDs::Note);
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -23,6 +23,7 @@
 #include "NamedParameterCheck.h"
 #include "NonConstParameterCheck.h"
 #include "RedundantControlFlowCheck.h"
+#include "RedundantDeclarationCheck.h"
 #include "RedundantSmartptrGetCheck.h"
 #include "RedundantStringCStrCheck.h"
 #include "RedundantStringInitCheck.h"
@@ -57,6 +58,8 @@
         "readability-inconsistent-declaration-parameter-name");
     CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
         "readability-misplaced-array-index");
+    CheckFactories.registerCheck<RedundantDeclarationCheck>(
+        "readability-redundant-declaration");
     CheckFactories.registerCheck<StaticDefinitionInAnonymousNamespaceCheck>(
         "readability-static-definition-in-anonymous-namespace");
     CheckFactories.registerCheck<readability::NamedParameterCheck>(
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -16,6 +16,7 @@
   NonConstParameterCheck.cpp
   ReadabilityTidyModule.cpp
   RedundantControlFlowCheck.cpp
+  RedundantDeclarationCheck.cpp
   RedundantStringCStrCheck.cpp
   RedundantSmartptrGetCheck.cpp
   RedundantStringInitCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to