diff options
author | Congcong Cai <congcongcai0907@163.com> | 2024-01-15 18:19:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 18:19:47 +0800 |
commit | 8e21557d0401a0046ff110daa50f21d02b71a2ee (patch) | |
tree | dc50d5669ef94aaaba1e7c79b913ce00a54f01b8 /clang-tools-extra/clang-tidy/readability | |
parent | 3dff20cfa27e0988840d5d13a169482269aa4fa5 (diff) | |
download | llvm-8e21557d0401a0046ff110daa50f21d02b71a2ee.zip llvm-8e21557d0401a0046ff110daa50f21d02b71a2ee.tar.gz llvm-8e21557d0401a0046ff110daa50f21d02b71a2ee.tar.bz2 |
[clang-tidy]Add new check readability-avoid-nested-conditional-operator (#78022)
Finds nested conditional operator.
Nested conditional operators lead code hard to understand, so they
should be splited as several statement and stored in temporary varibale.
Diffstat (limited to 'clang-tools-extra/clang-tidy/readability')
4 files changed, 89 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.cpp b/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.cpp new file mode 100644 index 0000000..2ea03c9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.cpp @@ -0,0 +1,52 @@ +//===--- AvoidNestedConditionalOperatorCheck.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 "AvoidNestedConditionalOperatorCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/DiagnosticIDs.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void AvoidNestedConditionalOperatorCheck::registerMatchers( + MatchFinder *Finder) { + Finder->addMatcher( + conditionalOperator( + anyOf( + hasCondition(ignoringParenCasts( + conditionalOperator().bind("nested-conditional-operator"))), + hasTrueExpression(ignoringParenCasts( + conditionalOperator().bind("nested-conditional-operator"))), + hasFalseExpression(ignoringParenCasts( + conditionalOperator().bind("nested-conditional-operator"))))) + .bind("conditional-operator"), + this); +} + +void AvoidNestedConditionalOperatorCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *CO = + Result.Nodes.getNodeAs<ConditionalOperator>("conditional-operator"); + const auto *NCO = Result.Nodes.getNodeAs<ConditionalOperator>( + "nested-conditional-operator"); + assert(CO); + assert(NCO); + + if (CO->getBeginLoc().isMacroID() || NCO->getBeginLoc().isMacroID()) + return; + + diag(NCO->getBeginLoc(), + "conditional operator is used as sub-expression of parent conditional " + "operator, refrain from using nested conditional operators"); + diag(CO->getBeginLoc(), "parent conditional operator here", + DiagnosticIDs::Note); +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.h b/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.h new file mode 100644 index 0000000..9010156 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/AvoidNestedConditionalOperatorCheck.h @@ -0,0 +1,33 @@ +//===--- AvoidNestedConditionalOperatorCheck.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_READABILITY_AVOID_NESTED_CONDITIONAL_OPERATOR_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_NESTED_CONDITIONAL_OPERATOR_CHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Identifies instances of nested conditional operators in the code. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/avoid-nested-conditional-operator.html +class AvoidNestedConditionalOperatorCheck : public ClangTidyCheck { +public: + AvoidNestedConditionalOperatorCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_NESTED_CONDITIONAL_OPERATOR_CHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 408c822b..fa571d5 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyReadabilityModule AvoidConstParamsInDecls.cpp + AvoidNestedConditionalOperatorCheck.cpp AvoidReturnWithVoidValueCheck.cpp AvoidUnconditionalPreprocessorIfCheck.cpp BracesAroundStatementsCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 0b0aad7c..f769752 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -10,6 +10,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "AvoidConstParamsInDecls.h" +#include "AvoidNestedConditionalOperatorCheck.h" #include "AvoidReturnWithVoidValueCheck.h" #include "AvoidUnconditionalPreprocessorIfCheck.h" #include "BracesAroundStatementsCheck.h" @@ -64,6 +65,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<AvoidConstParamsInDecls>( "readability-avoid-const-params-in-decls"); + CheckFactories.registerCheck<AvoidNestedConditionalOperatorCheck>( + "readability-avoid-nested-conditional-operator"); CheckFactories.registerCheck<AvoidReturnWithVoidValueCheck>( "readability-avoid-return-with-void-value"); CheckFactories.registerCheck<AvoidUnconditionalPreprocessorIfCheck>( |