From f3321c5f68744f2a4188dc49da9d279597e929fe Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Fri, 28 Jul 2017 12:46:02 +0000 Subject: [PATCH] [clang-tidy] readability-redundant-declaration: ignore friends and macros llvm-svn: 309379 --- .../readability/RedundantDeclarationCheck.cpp | 18 ++++++++++-- .../readability/RedundantDeclarationCheck.h | 6 ++-- ...ty-redundant-declaration-ignore-macros.cpp | 22 +++++++++++++++ .../readability-redundant-declaration.cpp | 28 ++++++++++++++++++- 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp index 29d43c7b779f..1df3f0555b89 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -18,11 +18,16 @@ namespace clang { namespace tidy { namespace readability { +RedundantDeclarationCheck::RedundantDeclarationCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} + void RedundantDeclarationCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - namedDecl( - anyOf(varDecl(unless(isDefinition())), - functionDecl(unless(anyOf(isDefinition(), isDefaulted()))))) + namedDecl(anyOf(varDecl(unless(isDefinition())), + functionDecl(unless(anyOf(isDefinition(), isDefaulted(), + hasParent(friendDecl())))))) .bind("Decl"), this); } @@ -36,6 +41,13 @@ void RedundantDeclarationCheck::check(const MatchFinder::MatchResult &Result) { return; if (Prev->getLocation() == D->getLocation()) return; + if (IgnoreMacros && + (D->getLocation().isMacroID() || Prev->getLocation().isMacroID())) + return; + // Don't complain when the previous declaration is a friend declaration. + for (const auto &Parent : Result.Context->getParents(*Prev)) + if (Parent.get()) + return; const SourceManager &SM = *Result.SourceManager; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.h index 96c483062fab..9be79b848185 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.h @@ -22,10 +22,12 @@ namespace readability { /// 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) {} + RedundantDeclarationCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool IgnoreMacros; }; } // namespace readability diff --git a/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp new file mode 100644 index 000000000000..2dc86182606b --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp @@ -0,0 +1,22 @@ +// RUN: %check_clang_tidy %s readability-redundant-declaration %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: readability-redundant-declaration.IgnoreMacros, \ +// RUN: value: 1}]}" \ +// RUN: -- -std=c++11 + +extern int Xyz; +extern int Xyz; // Xyz +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Xyz' declaration [readability-redundant-declaration] +// CHECK-FIXES: {{^}}// Xyz{{$}} + +namespace macros { +#define DECLARE(x) extern int x +#define DEFINE(x) extern int x; int x = 42 +DECLARE(test); +DEFINE(test); +// CHECK-FIXES: {{^}}#define DECLARE(x) extern int x{{$}} +// CHECK-FIXES: {{^}}#define DEFINE(x) extern int x; int x = 42{{$}} +// CHECK-FIXES: {{^}}DECLARE(test);{{$}} +// CHECK-FIXES: {{^}}DEFINE(test);{{$}} + +} // namespace macros diff --git a/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp b/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp index e1b8023acbfa..83d1b5bccb25 100644 --- a/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp +++ b/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp @@ -1,4 +1,8 @@ -// RUN: %check_clang_tidy %s readability-redundant-declaration %t +// RUN: %check_clang_tidy %s readability-redundant-declaration %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: readability-redundant-declaration.IgnoreMacros, \ +// RUN: value: 0}]}" \ +// RUN: -- -std=c++11 extern int Xyz; extern int Xyz; // Xyz @@ -42,3 +46,25 @@ struct C2 { template C2::C2() = default; + +void best_friend(); + +struct Friendly { + friend void best_friend(); + friend void enemy(); +}; + +void enemy(); + +namespace macros { +#define DECLARE(x) extern int x +#define DEFINE(x) extern int x; int x = 42 +DECLARE(test); +DEFINE(test); +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant 'test' declaration +// CHECK-FIXES: {{^}}#define DECLARE(x) extern int x{{$}} +// CHECK-FIXES: {{^}}#define DEFINE(x) extern int x; int x = 42{{$}} +// CHECK-FIXES: {{^}}DECLARE(test);{{$}} +// CHECK-FIXES: {{^}}DEFINE(test);{{$}} + +} // namespace macros