nullptr.cpp created this revision.
nullptr.cpp added reviewers: alexfh, aaron.ballman, njames93, balazske.
Herald added subscribers: xazax.hun, mgorny.
nullptr.cpp requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Finds redundant `using` declarations and directives.
Example:
namespace n {
void func();
}
namespace {
using n::func; // redundant using declaration, already in namespace 'n'.
}
namespace n {
using namespace n; // redundant using directive, already in namespace 'n'.
}
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D97361
Files:
clang-tools-extra/clang-tidy/misc/CMakeLists.txt
clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.cpp
clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/docs/clang-tidy/checks/misc-redundant-using.rst
clang-tools-extra/test/clang-tidy/checkers/misc-redundant-using.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/misc-redundant-using.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/misc-redundant-using.cpp
@@ -0,0 +1,114 @@
+// RUN: %check_clang_tidy %s misc-redundant-using %t
+
+namespace n1 {
+using namespace n1;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: using directive 'n1' is redundant, already in namespace 'n1' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:17: note: remove the using directive
+// CHECK-FIXES: {{^}}
+} // namespace n1
+
+namespace n2 {
+using namespace n1; // ok
+}
+
+namespace n3 {
+namespace n = n3;
+using namespace n;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: using directive 'n' is redundant, already in namespace 'n3' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:17: note: remove the using directive
+// CHECK-FIXES: {{^}}
+} // namespace n3
+
+namespace n4 {
+namespace inner {
+using namespace n4;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: using directive 'n4' is redundant, already in namespace 'n4' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:17: note: remove the using directive
+// CHECK-FIXES: {{^}}
+
+using namespace n4::inner;
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: using directive 'inner' is redundant, already in namespace 'inner' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: remove the using directive
+// CHECK-FIXES: {{^}}
+
+namespace n = n4::inner;
+using namespace n;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: using directive 'n' is redundant, already in namespace 'inner' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:17: note: remove the using directive
+// CHECK-FIXES: {{^}}
+} // namespace inner
+} // namespace n4
+
+namespace n5 {
+namespace inner {
+using namespace n4::inner; // ok
+}
+} // namespace n5
+
+namespace n6 {
+void func();
+
+using n6::func;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: using declaration 'func' is redundant, already in namespace 'n6' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:11: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+} // namespace n6
+
+namespace n7 {
+using n6::func; // ok
+}
+
+namespace n8 {
+void func();
+
+namespace n = n8;
+using n::func;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using declaration 'func' is redundant, already in namespace 'n8' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:10: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+} // namespace n8
+
+namespace n9 {
+void outerFunc();
+
+namespace inner {
+using n9::outerFunc;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: using declaration 'outerFunc' is redundant, already in namespace 'n9' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:11: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+
+void innerFunc();
+using inner::innerFunc;
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: using declaration 'innerFunc' is redundant, already in namespace 'inner' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:14: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+
+using n9::inner::innerFunc;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: using declaration 'innerFunc' is redundant, already in namespace 'inner' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+
+namespace n = n9::inner;
+using n::innerFunc;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using declaration 'innerFunc' is redundant, already in namespace 'inner' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:10: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+} // namespace inner
+} // namespace n9
+
+namespace n10 {
+namespace inner {
+using n9::inner::innerFunc; // ok
+}
+} // namespace n10
+
+namespace n11 {
+void func();
+}
+
+namespace n11 {
+using n11::func;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: using declaration 'func' is redundant, already in namespace 'n11' [misc-redundant-using]
+// CHECK-MESSAGES: :[[@LINE-2]]:12: note: remove the using declaration
+// CHECK-FIXES: {{^}}
+} // namespace n11
Index: clang-tools-extra/docs/clang-tidy/checks/misc-redundant-using.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/misc-redundant-using.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - misc-redundant-using
+
+misc-redundant-using
+====================
+
+Finds redundant ``using`` declarations and directives.
+
+Example:
+
+.. code-block:: c++
+
+ namespace n {
+ void func();
+ }
+
+ namespace {
+ using n::func; // redundant using declaration, already in namespace 'n'.
+ }
+
+.. code-block:: c++
+
+ namespace n {
+ using namespace n; // redundant using directive, already in namespace 'n'.
+ }
+
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -208,6 +208,7 @@
`misc-non-copyable-objects <misc-non-copyable-objects.html>`_,
`misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_,
`misc-redundant-expression <misc-redundant-expression.html>`_, "Yes"
+ `misc-redundant-using <misc-redundant-using.html>`_, "Yes"
`misc-static-assert <misc-static-assert.html>`_, "Yes"
`misc-throw-by-value-catch-by-reference <misc-throw-by-value-catch-by-reference.html>`_,
`misc-unconventional-assign-operator <misc-unconventional-assign-operator.html>`_,
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -85,6 +85,11 @@
Finds member initializations in the constructor body which can be placed into
the initialization list instead.
+- New :doc:`misc-redundant-using
+ <clang-tidy/checks/misc-redundant-using>` check.
+
+ Finds redundant ``using`` declarations and directives.
+
New check aliases
^^^^^^^^^^^^^^^^^
Index: clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.h
@@ -0,0 +1,44 @@
+//===--- RedundantUsingCheck.h - clang-tidy ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANTUSINGCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANTUSINGCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Finds redundant using declarations and directives.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-redundant-using.html
+class RedundantUsingCheck : public ClangTidyCheck {
+public:
+ RedundantUsingCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ void checkUsingDecl(const UsingDecl *Declaration,
+ const ast_matchers::MatchFinder::MatchResult &Result);
+ void
+ checkUsingDirective(const UsingDirectiveDecl *Directive,
+ const ast_matchers::MatchFinder::MatchResult &Result);
+ void diagUsing(const char *Type, const Decl *Using, const NamedDecl *ND,
+ const NamespaceDecl *NSD,
+ const ast_matchers::MatchFinder::MatchResult &Result);
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANTUSINGCHECK_H
Index: clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/RedundantUsingCheck.cpp
@@ -0,0 +1,86 @@
+//===--- RedundantUsingCheck.cpp - clang-tidy
+//--------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantUsingCheck.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 misc {
+
+void RedundantUsingCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ usingDecl(isExpansionInMainFile()).bind("using-declaration"), this);
+ Finder->addMatcher(
+ usingDirectiveDecl(isExpansionInMainFile()).bind("using-directive"),
+ this);
+}
+
+void RedundantUsingCheck::check(const MatchFinder::MatchResult &Result) {
+ if (const auto *Declaration =
+ Result.Nodes.getNodeAs<UsingDecl>("using-declaration")) {
+ checkUsingDecl(Declaration, Result);
+ }
+
+ if (const auto *Directive =
+ Result.Nodes.getNodeAs<UsingDirectiveDecl>("using-directive")) {
+ checkUsingDirective(Directive, Result);
+ }
+}
+
+void RedundantUsingCheck::checkUsingDecl(
+ const UsingDecl *Declaration, const MatchFinder::MatchResult &Result) {
+ const DeclContext *DC = Declaration->getDeclContext();
+
+ for (const auto *UsingShadow : Declaration->shadows()) {
+ const Decl *TargetDecl = UsingShadow->getTargetDecl()->getCanonicalDecl();
+
+ if (TargetDecl->getDeclContext()->Encloses(DC)) {
+ const auto *NSD = cast<NamespaceDecl>(TargetDecl->getDeclContext());
+ diagUsing("declaration", Declaration, Declaration, NSD, Result);
+ }
+ }
+}
+
+void RedundantUsingCheck::checkUsingDirective(
+ const UsingDirectiveDecl *Directive,
+ const MatchFinder::MatchResult &Result) {
+ const NamespaceDecl *NDNominated = Directive->getNominatedNamespace();
+ const DeclContext *DC = Directive->getDeclContext();
+
+ if (NDNominated->Encloses(DC)) {
+ const NamedDecl *NDAsWritten = Directive->getNominatedNamespaceAsWritten();
+
+ diagUsing("directive", Directive, NDAsWritten, NDNominated, Result);
+ }
+}
+void RedundantUsingCheck::diagUsing(const char *Type, const Decl *Using,
+ const NamedDecl *ND,
+ const NamespaceDecl *NSD,
+ const MatchFinder::MatchResult &Result) {
+ SourceLocation End =
+ Lexer::findLocationAfterToken(Using->getEndLoc(), tok::semi,
+ *Result.SourceManager, getLangOpts(), true);
+ CharSourceRange RemoveRange =
+ CharSourceRange::getCharRange(Using->getBeginLoc(), End);
+
+ diag(Using->getLocation(),
+ "using %0 %1 is redundant, already in namespace %2")
+ << Type << ND << NSD;
+ diag(Using->getLocation(), "remove the using %0", DiagnosticIDs::Note)
+ << Type << FixItHint::CreateRemoval(RemoveRange);
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -16,6 +16,7 @@
#include "NonCopyableObjects.h"
#include "NonPrivateMemberVariablesInClassesCheck.h"
#include "RedundantExpressionCheck.h"
+#include "RedundantUsingCheck.h"
#include "StaticAssertCheck.h"
#include "ThrowByValueCatchByReferenceCheck.h"
#include "UnconventionalAssignOperatorCheck.h"
@@ -43,6 +44,7 @@
"misc-non-private-member-variables-in-classes");
CheckFactories.registerCheck<RedundantExpressionCheck>(
"misc-redundant-expression");
+ CheckFactories.registerCheck<RedundantUsingCheck>("misc-redundant-using");
CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert");
CheckFactories.registerCheck<ThrowByValueCatchByReferenceCheck>(
"misc-throw-by-value-catch-by-reference");
Index: clang-tools-extra/clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -12,6 +12,7 @@
NonCopyableObjects.cpp
NonPrivateMemberVariablesInClassesCheck.cpp
RedundantExpressionCheck.cpp
+ RedundantUsingCheck.cpp
StaticAssertCheck.cpp
ThrowByValueCatchByReferenceCheck.cpp
UnconventionalAssignOperatorCheck.cpp
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits