[clang-tidy] Add check readability-redundant-declaration
Finds redundant variable and function declarations. extern int X; extern int X; // <- redundant Differential Revision: https://reviews.llvm.org/D24656 llvm-svn: 285689
This commit is contained in:
parent
62f516f590
commit
399a50cf35
|
@ -16,6 +16,7 @@ add_clang_library(clangTidyReadabilityModule
|
|||
NonConstParameterCheck.cpp
|
||||
ReadabilityTidyModule.cpp
|
||||
RedundantControlFlowCheck.cpp
|
||||
RedundantDeclarationCheck.cpp
|
||||
RedundantMemberInitCheck.cpp
|
||||
RedundantStringCStrCheck.cpp
|
||||
RedundantSmartptrGetCheck.cpp
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "NamedParameterCheck.h"
|
||||
#include "NonConstParameterCheck.h"
|
||||
#include "RedundantControlFlowCheck.h"
|
||||
#include "RedundantDeclarationCheck.h"
|
||||
#include "RedundantMemberInitCheck.h"
|
||||
#include "RedundantSmartptrGetCheck.h"
|
||||
#include "RedundantStringCStrCheck.h"
|
||||
|
@ -68,6 +69,8 @@ public:
|
|||
"readability-non-const-parameter");
|
||||
CheckFactories.registerCheck<RedundantControlFlowCheck>(
|
||||
"readability-redundant-control-flow");
|
||||
CheckFactories.registerCheck<RedundantDeclarationCheck>(
|
||||
"readability-redundant-declaration");
|
||||
CheckFactories.registerCheck<RedundantSmartptrGetCheck>(
|
||||
"readability-redundant-smartptr-get");
|
||||
CheckFactories.registerCheck<RedundantStringCStrCheck>(
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
//===--- 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) {
|
||||
Finder->addMatcher(namedDecl(anyOf(varDecl(), functionDecl())).bind("Decl"), this);
|
||||
}
|
||||
|
||||
void RedundantDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
const NamedDecl *D = Result.Nodes.getNodeAs<NamedDecl>("Decl");
|
||||
const auto *Prev = D->getPreviousDecl();
|
||||
if (!Prev)
|
||||
return;
|
||||
if (Prev->getLocation() == D->getLocation())
|
||||
return;
|
||||
|
||||
const SourceManager &SM = *Result.SourceManager;
|
||||
|
||||
const bool DifferentHeaders =
|
||||
!SM.isInMainFile(D->getLocation()) &&
|
||||
!SM.isWrittenInSameFile(Prev->getLocation(), D->getLocation());
|
||||
|
||||
bool MultiVar = false;
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
if (VD->getPreviousDecl()->getStorageClass() == SC_Extern &&
|
||||
VD->getStorageClass() != SC_Extern)
|
||||
return;
|
||||
// Is this a multivariable declaration?
|
||||
for (const auto Other : VD->getDeclContext()->decls()) {
|
||||
if (Other != D && Other->getLocStart() == VD->getLocStart()) {
|
||||
MultiVar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto *FD = cast<FunctionDecl>(D);
|
||||
if (FD->isThisDeclarationADefinition())
|
||||
return;
|
||||
}
|
||||
|
||||
SourceLocation EndLoc = Lexer::getLocForEndOfToken(
|
||||
D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts());
|
||||
{
|
||||
auto Diag = diag(D->getLocation(), "redundant %0 declaration")
|
||||
<< D;
|
||||
if (!MultiVar && !DifferentHeaders)
|
||||
Diag << FixItHint::CreateRemoval(
|
||||
SourceRange(D->getSourceRange().getBegin(), EndLoc));
|
||||
}
|
||||
diag(Prev->getLocation(), "previously declared here", DiagnosticIDs::Note);
|
||||
}
|
||||
|
||||
} // namespace readability
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
|
@ -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 {
|
||||
|
||||
/// Find redundant variable declarations.
|
||||
///
|
||||
/// 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
|
|
@ -129,6 +129,11 @@ Improvements to clang-tidy
|
|||
Flags member initializations that are unnecessary because the same default
|
||||
constructor would be called if they were not present.
|
||||
|
||||
- New `readability-redundant-declaration
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-declaration.html>`_ check
|
||||
|
||||
Warns about duplicate variable declarations.
|
||||
|
||||
Fixed bugs:
|
||||
|
||||
- `modernize-make-unique
|
||||
|
|
|
@ -133,6 +133,7 @@ Clang-Tidy Checks
|
|||
readability-named-parameter
|
||||
readability-non-const-parameter
|
||||
readability-redundant-control-flow
|
||||
readability-redundant-declaration
|
||||
readability-redundant-member-init
|
||||
readability-redundant-smartptr-get
|
||||
readability-redundant-string-cstr
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
.. title:: clang-tidy - readability-redundant-declaration
|
||||
|
||||
readability-redundant-declaration
|
||||
=================================
|
||||
|
||||
Finds redundant variable and function declarations.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
extern int X;
|
||||
extern int X;
|
||||
|
||||
becomes
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
extern int X;
|
||||
|
||||
Such redundant declarations can be removed without changing program behaviour.
|
||||
They can for instance be unintentional left overs from previous refactorings
|
||||
when code has been moved around. Having redundant declarations could in worst
|
||||
case mean that there are typos in the code that cause bugs.
|
||||
|
||||
Normally the code can be automatically fixed, clang-tidy can remove the second
|
||||
declaration. However there are 2 cases when you need to fix the code manually:
|
||||
* When the declarations are in different header files.
|
||||
* When multiple variables are declared together.
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %check_clang_tidy %s readability-redundant-declaration %t
|
||||
|
||||
extern int Xyz;
|
||||
extern int Xyz;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Xyz' declaration [readability-redundant-declaration]
|
||||
// CHECK-FIXES: {{^}}{{$}}
|
||||
int Xyz = 123;
|
||||
|
||||
extern int A;
|
||||
extern int A, B;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'A' declaration
|
||||
// CHECK-FIXES: {{^}}extern int A, B;{{$}}
|
||||
|
||||
extern int Buf[10];
|
||||
extern int Buf[10];
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Buf' declaration
|
||||
// CHECK-FIXES: {{^}}{{$}}
|
||||
|
||||
static int f();
|
||||
static int f();
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'f' declaration
|
||||
// CHECK-FIXES: {{^}}{{$}}
|
||||
static int f() {}
|
Loading…
Reference in New Issue