https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/146830
>From 9eb58438d2b4061ad7a6bdbd1db82a5fd4043948 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 3 Jul 2025 00:19:52 -0700 Subject: [PATCH 01/11] [clang-tidy] Add new check: `modernize-use-concise-preprocessor-directives` Rewrites preprocessor conditions like `#if defined(MEOW)` as `#ifdef MEOW` and `#elif !defined(MEOW)` as `#elifndef MEOW`. Closes #132561. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../UseConcisePreprocessorDirectivesCheck.cpp | 105 ++++++++++++++ .../UseConcisePreprocessorDirectivesCheck.h | 37 +++++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../use-concise-preprocessor-directives.rst | 28 ++++ .../use-concise-preprocessor-directives.cpp | 134 ++++++++++++++++++ 8 files changed, 315 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 619a27b2f9bb6..22d5214b61441 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -30,6 +30,7 @@ add_clang_library(clangTidyModernizeModule STATIC UnaryStaticAssertCheck.cpp UseAutoCheck.cpp UseBoolLiteralsCheck.cpp + UseConcisePreprocessorDirectivesCheck.cpp UseConstraintsCheck.cpp UseDefaultMemberInitCheck.cpp UseDesignatedInitializersCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index fdf38bc4b6308..28c5467f7b3e0 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -31,6 +31,7 @@ #include "UnaryStaticAssertCheck.h" #include "UseAutoCheck.h" #include "UseBoolLiteralsCheck.h" +#include "UseConcisePreprocessorDirectivesCheck.h" #include "UseConstraintsCheck.h" #include "UseDefaultMemberInitCheck.h" #include "UseDesignatedInitializersCheck.h" @@ -76,6 +77,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck<MinMaxUseInitializerListCheck>( "modernize-min-max-use-initializer-list"); CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value"); + CheckFactories.registerCheck<UseConcisePreprocessorDirectivesCheck>( + "modernize-use-concise-preprocessor-directives"); CheckFactories.registerCheck<UseDesignatedInitializersCheck>( "modernize-use-designated-initializers"); CheckFactories.registerCheck<UseIntegerSignComparisonCheck>( diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp new file mode 100644 index 0000000000000..56ed1b3cc879d --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp @@ -0,0 +1,105 @@ +//===--- UseConcisePreprocessorDirectivesCheck.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 "UseConcisePreprocessorDirectivesCheck.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" + +namespace clang::tidy::modernize { + +namespace { + +class IfPreprocessorCallbacks final : public PPCallbacks { +public: + IfPreprocessorCallbacks(ClangTidyCheck &Check, Preprocessor &PP) + : Check(Check), PP(PP) {} + + void If(SourceLocation Loc, SourceRange ConditionRange, + ConditionValueKind) override { + impl(Loc, ConditionRange, {"ifdef", "ifndef"}); + } + + void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind, + SourceLocation) override { + if (PP.getLangOpts().C23 || PP.getLangOpts().CPlusPlus23) { + impl(Loc, ConditionRange, {"elifdef", "elifndef"}); + } + } + +private: + void impl(SourceLocation DirectiveLoc, SourceRange ConditionRange, + const llvm::StringLiteral (&Replacements)[2]) { + StringRef Condition = + Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange), + PP.getSourceManager(), PP.getLangOpts()); + Lexer Lex(DirectiveLoc, PP.getLangOpts(), Condition.data(), + Condition.data(), Condition.data() + Condition.size()); + Token Tok; + bool Inverted = false; // The inverted form of #*def is #*ndef. + std::size_t ParensNestingDepth = 0; + for (;;) { + if (Lex.LexFromRawLexer(Tok)) + return; + + if (Tok.is(tok::TokenKind::exclaim) || + (PP.getLangOpts().CPlusPlus && + Tok.is(tok::TokenKind::raw_identifier) && + Tok.getRawIdentifier() == "not")) + Inverted = !Inverted; + else if (Tok.is(tok::TokenKind::l_paren)) + ++ParensNestingDepth; + else + break; + } + + if (Tok.isNot(tok::TokenKind::raw_identifier) || + Tok.getRawIdentifier() != "defined") + return; + + bool NoMoreTokens = Lex.LexFromRawLexer(Tok); + if (Tok.is(tok::TokenKind::l_paren)) { + if (NoMoreTokens) + return; + ++ParensNestingDepth; + NoMoreTokens = Lex.LexFromRawLexer(Tok); + } + + if (Tok.isNot(tok::TokenKind::raw_identifier)) + return; + StringRef Macro = Tok.getRawIdentifier(); + + while (!NoMoreTokens) { + NoMoreTokens = Lex.LexFromRawLexer(Tok); + if (Tok.isNot(tok::TokenKind::r_paren)) + return; + --ParensNestingDepth; + } + + if (ParensNestingDepth != 0) + return; + + Check.diag(DirectiveLoc, + "preprocessor condition can be written more concisely") + << FixItHint::CreateReplacement(DirectiveLoc, Replacements[Inverted]) + << FixItHint::CreateReplacement(ConditionRange, Macro); + } + + ClangTidyCheck &Check; + const Preprocessor &PP; +}; + +} // namespace + +void UseConcisePreprocessorDirectivesCheck::registerPPCallbacks( + const SourceManager &, Preprocessor *PP, Preprocessor *) { + PP->addPPCallbacks(std::make_unique<IfPreprocessorCallbacks>(*this, *PP)); +} + +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h new file mode 100644 index 0000000000000..cbc96dc930f82 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h @@ -0,0 +1,37 @@ +//===--- UseConcisePreprocessorDirectivesCheck.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_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// Shortens `#if` preprocessor conditions: +/// +/// #if defined(MEOW) -> #ifdef MEOW +/// #if !defined(MEOW) -> #ifndef MEOW +/// +/// And, since C23 and C++23, shortens `#elif` conditions too: +/// +/// #elif defined(MEOW) -> #elifdef MEOW +/// #elif !defined(MEOW) -> #elifndef MEOW +/// +/// User-facing documentation: +/// https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-concise-preprocessor-directives.html +class UseConcisePreprocessorDirectivesCheck : public ClangTidyCheck { +public: + using ClangTidyCheck::ClangTidyCheck; + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 198efee7754de..331ef618a443b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -142,6 +142,12 @@ New checks Finds unscoped (non-class) ``enum`` declarations and suggests using ``enum class`` instead. +- New :doc:`modernize-use-concise-preprocessor-directives + <clang-tidy/checks/modernize/use-concise-preprocessor-directives>` check. + + Rewrites preprocessor conditions like ``#if defined(MEOW)`` as ``#ifdef MEOW`` + and ``#elif !defined(MEOW)`` as ``#elifndef MEOW``. + - New :doc:`modernize-use-scoped-lock <clang-tidy/checks/modernize/use-scoped-lock>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 5098582d0c42b..e0227b0478d99 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -300,6 +300,7 @@ Clang-Tidy Checks :doc:`modernize-unary-static-assert <modernize/unary-static-assert>`, "Yes" :doc:`modernize-use-auto <modernize/use-auto>`, "Yes" :doc:`modernize-use-bool-literals <modernize/use-bool-literals>`, "Yes" + :doc:`modernize-use-concise-preprocessor-directives <modernize/use-concise-preprocessor-directives>`, "Yes" :doc:`modernize-use-constraints <modernize/use-constraints>`, "Yes" :doc:`modernize-use-default-member-init <modernize/use-default-member-init>`, "Yes" :doc:`modernize-use-designated-initializers <modernize/use-designated-initializers>`, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst new file mode 100644 index 0000000000000..04c8e8af38153 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst @@ -0,0 +1,28 @@ +.. title:: clang-tidy - modernize-use-concise-preprocessor-directives + +modernize-use-concise-preprocessor-directives +============================================= + +Shortens `#if` preprocessor conditions: + +.. code-block:: c++ + + #if defined(MEOW) + #if !defined(MEOW) + + // becomes + + #ifdef MEOW + #ifndef MEOW + +And, since C23 and C++23, shortens `#elif` conditions too: + +.. code-block:: c++ + + #elif defined(MEOW) + #elif !defined(MEOW) + + // becomes + + #elifdef MEOW + #elifndef MEOW diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp new file mode 100644 index 0000000000000..3262bd0388680 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp @@ -0,0 +1,134 @@ +// RUN: %check_clang_tidy -std=c++98 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++11 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++14 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++17 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=ALL,23,CXX,CXX23 %s modernize-use-concise-preprocessor-directives %t + +// RUN: %check_clang_tidy -std=c99 -check-suffix=ALL %s modernize-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c11 -check-suffix=ALL %s modernize-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c23-or-later -check-suffix=ALL,23 %s modernize-use-concise-preprocessor-directives %t -- -- -x c + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifdef FOO +#if defined(FOO) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifdef BAR +#elif defined(BAR) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifdef FOO +#if defined FOO +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifdef BAR +#elif defined BAR +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifdef FOO +#if (defined(FOO)) +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: # elifdef BAR +# elif (defined(BAR)) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifdef FOO +#if (defined FOO) +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: # elifdef BAR +# elif (defined BAR) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !defined(FOO) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif !defined(BAR) +#endif + +#ifdef __cplusplus +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-CXX: #ifndef FOO +#if not defined(FOO) +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-CXX23: #elifndef BAR +#elif not defined(BAR) +#endif +#endif // __cplusplus + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !defined FOO +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif !defined BAR +#endif + +#ifdef __cplusplus +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-CXX: #ifndef FOO +#if not defined FOO +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-CXX23: #elifndef BAR +#elif not defined BAR +#endif +#endif // __cplusplus + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if (!defined(FOO)) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif (!defined(BAR)) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if (!defined FOO) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif (!defined BAR) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !(defined(FOO)) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif !(defined(BAR)) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !(defined FOO) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifndef BAR +#elif !(defined BAR) +#endif + +// These cases with many parentheses and negations are unrealistic, but +// handling them doesn't really add any complexity to the implementation. +// Test them for good measure. + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !((!!(defined(FOO)))) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifdef BAR +#elif ((!(!(defined(BAR))))) +#endif + +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-ALL: #ifndef FOO +#if !((!!(defined FOO))) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifdef BAR +#elif ((!(!(defined BAR)))) +#endif + +#if FOO +#elif BAR +#endif >From 8e1c675c1655236e2aba61b1f4e7ff37226af33b Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 3 Jul 2025 13:17:24 -0700 Subject: [PATCH 02/11] Specify `isLanguageVersionSupported` --- .../modernize/UseConcisePreprocessorDirectivesCheck.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h index cbc96dc930f82..9550238266b9d 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h @@ -30,6 +30,9 @@ class UseConcisePreprocessorDirectivesCheck : public ClangTidyCheck { using ClangTidyCheck::ClangTidyCheck; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus || LangOpts.C99; + } }; } // namespace clang::tidy::modernize >From 7d42a2fb5f179667c6c84c2102a62bc82663efcd Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 3 Jul 2025 13:20:55 -0700 Subject: [PATCH 03/11] Const correctness --- .../modernize/UseConcisePreprocessorDirectivesCheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp index 56ed1b3cc879d..c9d043f672e2c 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp @@ -18,7 +18,7 @@ namespace { class IfPreprocessorCallbacks final : public PPCallbacks { public: - IfPreprocessorCallbacks(ClangTidyCheck &Check, Preprocessor &PP) + IfPreprocessorCallbacks(ClangTidyCheck &Check, const Preprocessor &PP) : Check(Check), PP(PP) {} void If(SourceLocation Loc, SourceRange ConditionRange, @@ -36,7 +36,7 @@ class IfPreprocessorCallbacks final : public PPCallbacks { private: void impl(SourceLocation DirectiveLoc, SourceRange ConditionRange, const llvm::StringLiteral (&Replacements)[2]) { - StringRef Condition = + const StringRef Condition = Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange), PP.getSourceManager(), PP.getLangOpts()); Lexer Lex(DirectiveLoc, PP.getLangOpts(), Condition.data(), @@ -73,7 +73,7 @@ class IfPreprocessorCallbacks final : public PPCallbacks { if (Tok.isNot(tok::TokenKind::raw_identifier)) return; - StringRef Macro = Tok.getRawIdentifier(); + const StringRef Macro = Tok.getRawIdentifier(); while (!NoMoreTokens) { NoMoreTokens = Lex.LexFromRawLexer(Tok); >From 43de4574d2a638dd8b086b9183663bb02f85e28f Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 3 Jul 2025 13:42:03 -0700 Subject: [PATCH 04/11] Align release notes and docs --- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++-- .../modernize/use-concise-preprocessor-directives.rst | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 331ef618a443b..c3967e86e2557 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -145,8 +145,9 @@ New checks - New :doc:`modernize-use-concise-preprocessor-directives <clang-tidy/checks/modernize/use-concise-preprocessor-directives>` check. - Rewrites preprocessor conditions like ``#if defined(MEOW)`` as ``#ifdef MEOW`` - and ``#elif !defined(MEOW)`` as ``#elifndef MEOW``. + Finds uses of ``#if`` that be simplified to ``#ifdef`` or ``#ifndef`` and, + since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` + or ``#elifndef``. - New :doc:`modernize-use-scoped-lock <clang-tidy/checks/modernize/use-scoped-lock>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst index 04c8e8af38153..a486fce3b0f66 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst @@ -3,7 +3,9 @@ modernize-use-concise-preprocessor-directives ============================================= -Shortens `#if` preprocessor conditions: +Finds uses of ``#if`` that be simplified to ``#ifdef`` or ``#ifndef`` and, +since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` +or ``#elifndef``: .. code-block:: c++ @@ -15,7 +17,7 @@ Shortens `#if` preprocessor conditions: #ifdef MEOW #ifndef MEOW -And, since C23 and C++23, shortens `#elif` conditions too: +Since C23 and C++23: .. code-block:: c++ >From 3ef8a8dd8e0bf5304ca3313a34d37cf5e4b82656 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 3 Jul 2025 15:13:17 -0700 Subject: [PATCH 05/11] Fix assert failure --- .../modernize/UseConcisePreprocessorDirectivesCheck.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp index c9d043f672e2c..94686772d7931 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp @@ -36,11 +36,13 @@ class IfPreprocessorCallbacks final : public PPCallbacks { private: void impl(SourceLocation DirectiveLoc, SourceRange ConditionRange, const llvm::StringLiteral (&Replacements)[2]) { - const StringRef Condition = + // Lexer requires its input range to be null-terminated. + SmallString<128> Condition = Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange), PP.getSourceManager(), PP.getLangOpts()); + Condition.push_back('\0'); Lexer Lex(DirectiveLoc, PP.getLangOpts(), Condition.data(), - Condition.data(), Condition.data() + Condition.size()); + Condition.data(), Condition.data() + Condition.size() - 1); Token Tok; bool Inverted = false; // The inverted form of #*def is #*ndef. std::size_t ParensNestingDepth = 0; >From ce0e9353b58309d2af1314f6a7f556c227d6f2ac Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sat, 5 Jul 2025 02:19:14 -0700 Subject: [PATCH 06/11] Update message, add test --- .../UseConcisePreprocessorDirectivesCheck.cpp | 5 +- .../use-concise-preprocessor-directives.cpp | 60 ++++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp index 94686772d7931..994e2bd08cf10 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp @@ -88,9 +88,10 @@ class IfPreprocessorCallbacks final : public PPCallbacks { return; Check.diag(DirectiveLoc, - "preprocessor condition can be written more concisely") + "preprocessor condition can be written more concisely using #%0") << FixItHint::CreateReplacement(DirectiveLoc, Replacements[Inverted]) - << FixItHint::CreateReplacement(ConditionRange, Macro); + << FixItHint::CreateReplacement(ConditionRange, Macro) + << Replacements[Inverted]; } ClangTidyCheck &Check; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp index 3262bd0388680..47f48b03817ab 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp @@ -9,102 +9,102 @@ // RUN: %check_clang_tidy -std=c11 -check-suffix=ALL %s modernize-use-concise-preprocessor-directives %t -- -- -x c // RUN: %check_clang_tidy -std=c23-or-later -check-suffix=ALL,23 %s modernize-use-concise-preprocessor-directives %t -- -- -x c -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifdef FOO #if defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined(BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifdef FOO #if defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined BAR #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifdef FOO #if (defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifdef FOO #if (defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined(BAR) #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined(FOO) -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined(BAR) #endif #endif // __cplusplus -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined BAR #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined FOO -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined BAR #endif #endif // __cplusplus -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if (!defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if (!defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !(defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !(defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined BAR) #endif @@ -113,18 +113,18 @@ // handling them doesn't really add any complexity to the implementation. // Test them for good measure. -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !((!!(defined(FOO)))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined(BAR))))) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-ALL: #ifndef FOO #if !((!!(defined FOO))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined BAR)))) #endif @@ -132,3 +132,7 @@ #if FOO #elif BAR #endif + +#if defined(FOO) && defined(BAR) +#elif defined(FOO) && defined(BAR) +#endif >From 8bad4062dffbb4ee83f785a70d526bf50b4d96da Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sat, 5 Jul 2025 02:26:27 -0700 Subject: [PATCH 07/11] Make tests more readable --- .../use-concise-preprocessor-directives.cpp | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp index 47f48b03817ab..cf4563531e302 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp @@ -1,48 +1,48 @@ -// RUN: %check_clang_tidy -std=c++98 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++11 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++14 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++17 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++20 -check-suffixes=ALL,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=ALL,23,CXX,CXX23 %s modernize-use-concise-preprocessor-directives %t - -// RUN: %check_clang_tidy -std=c99 -check-suffix=ALL %s modernize-use-concise-preprocessor-directives %t -- -- -x c -// RUN: %check_clang_tidy -std=c11 -check-suffix=ALL %s modernize-use-concise-preprocessor-directives %t -- -- -x c -// RUN: %check_clang_tidy -std=c23-or-later -check-suffix=ALL,23 %s modernize-use-concise-preprocessor-directives %t -- -- -x c - -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifdef FOO +// RUN: %check_clang_tidy -std=c++98 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++11 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++14 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,23,CXX,CXX23 %s modernize-use-concise-preprocessor-directives %t + +// RUN: %check_clang_tidy -std=c99 %s modernize-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c11 %s modernize-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=,23 %s modernize-use-concise-preprocessor-directives %t -- -- -x c + +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifdef FOO #if defined(FOO) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined(BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifdef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifdef FOO #if defined FOO // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined BAR #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifdef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifdef FOO #if (defined(FOO)) // CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifdef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifdef FOO #if (defined FOO) // CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !defined(FOO) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR @@ -59,8 +59,8 @@ #endif #endif // __cplusplus -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !defined FOO // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR @@ -77,32 +77,32 @@ #endif #endif // __cplusplus -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if (!defined(FOO)) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if (!defined FOO) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined BAR) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !(defined(FOO)) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined(BAR)) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !(defined FOO) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR @@ -113,16 +113,16 @@ // handling them doesn't really add any complexity to the implementation. // Test them for good measure. -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !((!!(defined(FOO)))) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined(BAR))))) #endif -// CHECK-MESSAGES-ALL: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] -// CHECK-FIXES-ALL: #ifndef FOO +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO #if !((!!(defined FOO))) // CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR >From 36719c8a5ca7fb1202a64da388b237abe248876e Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sat, 5 Jul 2025 02:51:21 -0700 Subject: [PATCH 08/11] Move to `readability` category --- .../clang-tidy/modernize/CMakeLists.txt | 1 - .../modernize/ModernizeTidyModule.cpp | 3 - .../clang-tidy/readability/CMakeLists.txt | 1 + .../readability/ReadabilityTidyModule.cpp | 3 + .../UseConcisePreprocessorDirectivesCheck.cpp | 4 +- .../UseConcisePreprocessorDirectivesCheck.h | 12 +-- clang-tools-extra/docs/ReleaseNotes.rst | 14 ++-- .../docs/clang-tidy/checks/list.rst | 2 +- .../use-concise-preprocessor-directives.rst | 6 +- .../use-concise-preprocessor-directives.cpp | 78 +++++++++---------- 10 files changed, 62 insertions(+), 62 deletions(-) rename clang-tools-extra/clang-tidy/{modernize => readability}/UseConcisePreprocessorDirectivesCheck.cpp (97%) rename clang-tools-extra/clang-tidy/{modernize => readability}/UseConcisePreprocessorDirectivesCheck.h (72%) rename clang-tools-extra/docs/clang-tidy/checks/{modernize => readability}/use-concise-preprocessor-directives.rst (66%) rename clang-tools-extra/test/clang-tidy/checkers/{modernize => readability}/use-concise-preprocessor-directives.cpp (51%) diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 22d5214b61441..619a27b2f9bb6 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -30,7 +30,6 @@ add_clang_library(clangTidyModernizeModule STATIC UnaryStaticAssertCheck.cpp UseAutoCheck.cpp UseBoolLiteralsCheck.cpp - UseConcisePreprocessorDirectivesCheck.cpp UseConstraintsCheck.cpp UseDefaultMemberInitCheck.cpp UseDesignatedInitializersCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 28c5467f7b3e0..fdf38bc4b6308 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -31,7 +31,6 @@ #include "UnaryStaticAssertCheck.h" #include "UseAutoCheck.h" #include "UseBoolLiteralsCheck.h" -#include "UseConcisePreprocessorDirectivesCheck.h" #include "UseConstraintsCheck.h" #include "UseDefaultMemberInitCheck.h" #include "UseDesignatedInitializersCheck.h" @@ -77,8 +76,6 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck<MinMaxUseInitializerListCheck>( "modernize-min-max-use-initializer-list"); CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value"); - CheckFactories.registerCheck<UseConcisePreprocessorDirectivesCheck>( - "modernize-use-concise-preprocessor-directives"); CheckFactories.registerCheck<UseDesignatedInitializersCheck>( "modernize-use-designated-initializers"); CheckFactories.registerCheck<UseIntegerSignComparisonCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 4be1a8f831339..4b4c49d3b17d1 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -58,6 +58,7 @@ add_clang_library(clangTidyReadabilityModule STATIC UniqueptrDeleteReleaseCheck.cpp UppercaseLiteralSuffixCheck.cpp UseAnyOfAllOfCheck.cpp + UseConcisePreprocessorDirectivesCheck.cpp UseStdMinMaxCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index d59b0312673b9..12f8cdb289dd2 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -61,6 +61,7 @@ #include "UniqueptrDeleteReleaseCheck.h" #include "UppercaseLiteralSuffixCheck.h" #include "UseAnyOfAllOfCheck.h" +#include "UseConcisePreprocessorDirectivesCheck.h" #include "UseStdMinMaxCheck.h" namespace clang::tidy { @@ -173,6 +174,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-uppercase-literal-suffix"); CheckFactories.registerCheck<UseAnyOfAllOfCheck>( "readability-use-anyofallof"); + CheckFactories.registerCheck<UseConcisePreprocessorDirectivesCheck>( + "readability-use-concise-preprocessor-directives"); CheckFactories.registerCheck<UseStdMinMaxCheck>( "readability-use-std-min-max"); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp similarity index 97% rename from clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp rename to clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp index 994e2bd08cf10..55e5b30dfcbda 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp @@ -12,7 +12,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" -namespace clang::tidy::modernize { +namespace clang::tidy::readability { namespace { @@ -105,4 +105,4 @@ void UseConcisePreprocessorDirectivesCheck::registerPPCallbacks( PP->addPPCallbacks(std::make_unique<IfPreprocessorCallbacks>(*this, *PP)); } -} // namespace clang::tidy::modernize +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h similarity index 72% rename from clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h rename to clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h index 9550238266b9d..68d4668957914 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConcisePreprocessorDirectivesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H #include "../ClangTidyCheck.h" -namespace clang::tidy::modernize { +namespace clang::tidy::readability { /// Shortens `#if` preprocessor conditions: /// @@ -24,7 +24,7 @@ namespace clang::tidy::modernize { /// #elif !defined(MEOW) -> #elifndef MEOW /// /// User-facing documentation: -/// https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-concise-preprocessor-directives.html +/// https://clang.llvm.org/extra/clang-tidy/checks/readability/use-concise-preprocessor-directives.html class UseConcisePreprocessorDirectivesCheck : public ClangTidyCheck { public: using ClangTidyCheck::ClangTidyCheck; @@ -35,6 +35,6 @@ class UseConcisePreprocessorDirectivesCheck : public ClangTidyCheck { } }; -} // namespace clang::tidy::modernize +} // namespace clang::tidy::readability -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USECONCISEPREPROCESSORDIRECTIVESCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index c3967e86e2557..09d10f91a229b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -142,13 +142,6 @@ New checks Finds unscoped (non-class) ``enum`` declarations and suggests using ``enum class`` instead. -- New :doc:`modernize-use-concise-preprocessor-directives - <clang-tidy/checks/modernize/use-concise-preprocessor-directives>` check. - - Finds uses of ``#if`` that be simplified to ``#ifdef`` or ``#ifndef`` and, - since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` - or ``#elifndef``. - - New :doc:`modernize-use-scoped-lock <clang-tidy/checks/modernize/use-scoped-lock>` check. @@ -167,6 +160,13 @@ New checks Finds potentially erroneous calls to ``reset`` method on smart pointers when the pointee type also has a ``reset`` method. +- New :doc:`readability-use-concise-preprocessor-directives + <clang-tidy/checks/readability/use-concise-preprocessor-directives>` check. + + Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef`` and, + since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` + or ``#elifndef``. + New check aliases ^^^^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index e0227b0478d99..d6ab9f334ac0a 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -300,7 +300,6 @@ Clang-Tidy Checks :doc:`modernize-unary-static-assert <modernize/unary-static-assert>`, "Yes" :doc:`modernize-use-auto <modernize/use-auto>`, "Yes" :doc:`modernize-use-bool-literals <modernize/use-bool-literals>`, "Yes" - :doc:`modernize-use-concise-preprocessor-directives <modernize/use-concise-preprocessor-directives>`, "Yes" :doc:`modernize-use-constraints <modernize/use-constraints>`, "Yes" :doc:`modernize-use-default-member-init <modernize/use-default-member-init>`, "Yes" :doc:`modernize-use-designated-initializers <modernize/use-designated-initializers>`, "Yes" @@ -411,6 +410,7 @@ Clang-Tidy Checks :doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes" :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes" :doc:`readability-use-anyofallof <readability/use-anyofallof>`, + :doc:`readability-use-concise-preprocessor-directives <readability/use-concise-preprocessor-directives>`, "Yes" :doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes" :doc:`zircon-temporary-objects <zircon/temporary-objects>`, diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst similarity index 66% rename from clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst rename to clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst index a486fce3b0f66..9f09cfcad88ab 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-concise-preprocessor-directives.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst @@ -1,9 +1,9 @@ -.. title:: clang-tidy - modernize-use-concise-preprocessor-directives +.. title:: clang-tidy - readability-use-concise-preprocessor-directives -modernize-use-concise-preprocessor-directives +readability-use-concise-preprocessor-directives ============================================= -Finds uses of ``#if`` that be simplified to ``#ifdef`` or ``#ifndef`` and, +Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef`` and, since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` or ``#elifndef``: diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp similarity index 51% rename from clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp rename to clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp index cf4563531e302..dc7200ccbde24 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-concise-preprocessor-directives.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp @@ -1,110 +1,110 @@ -// RUN: %check_clang_tidy -std=c++98 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++11 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++14 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX %s modernize-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,23,CXX,CXX23 %s modernize-use-concise-preprocessor-directives %t - -// RUN: %check_clang_tidy -std=c99 %s modernize-use-concise-preprocessor-directives %t -- -- -x c -// RUN: %check_clang_tidy -std=c11 %s modernize-use-concise-preprocessor-directives %t -- -- -x c -// RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=,23 %s modernize-use-concise-preprocessor-directives %t -- -- -x c - -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// RUN: %check_clang_tidy -std=c++98 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++11 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++14 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,23,CXX,CXX23 %s readability-use-concise-preprocessor-directives %t + +// RUN: %check_clang_tidy -std=c99 %s readability-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c11 %s readability-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=,23 %s readability-use-concise-preprocessor-directives %t -- -- -x c + +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined(BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined BAR #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if (defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if (defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined(BAR) #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined(FOO) -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined(BAR) #endif #endif // __cplusplus -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined BAR #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined FOO -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined BAR #endif #endif // __cplusplus -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if (!defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if (!defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !(defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !(defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined BAR) #endif @@ -113,18 +113,18 @@ // handling them doesn't really add any complexity to the implementation. // Test them for good measure. -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !((!!(defined(FOO)))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined(BAR))))) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !((!!(defined FOO))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [modernize-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined BAR)))) #endif >From 212e5e41f66292c6c3b47e25a6a509eabf3b4cfa Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sat, 5 Jul 2025 07:13:35 -0700 Subject: [PATCH 09/11] Fix docs --- .../checks/readability/use-concise-preprocessor-directives.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst index 9f09cfcad88ab..30ec7e6b89936 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-concise-preprocessor-directives.rst @@ -1,7 +1,7 @@ .. title:: clang-tidy - readability-use-concise-preprocessor-directives readability-use-concise-preprocessor-directives -============================================= +=============================================== Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef`` and, since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef`` >From a2d0a592c9b3088386a8de372460911837a3a8a3 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sun, 6 Jul 2025 03:27:00 -0700 Subject: [PATCH 10/11] Address feedback --- .../UseConcisePreprocessorDirectivesCheck.cpp | 5 +- .../UseConcisePreprocessorDirectivesCheck.h | 12 +-- .../use-concise-preprocessor-directives.cpp | 76 ++++++++++--------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp index 55e5b30dfcbda..e7a25dd59d1c3 100644 --- a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp @@ -87,8 +87,9 @@ class IfPreprocessorCallbacks final : public PPCallbacks { if (ParensNestingDepth != 0) return; - Check.diag(DirectiveLoc, - "preprocessor condition can be written more concisely using #%0") + Check.diag( + DirectiveLoc, + "preprocessor condition can be written more concisely using '#%0'") << FixItHint::CreateReplacement(DirectiveLoc, Replacements[Inverted]) << FixItHint::CreateReplacement(ConditionRange, Macro) << Replacements[Inverted]; diff --git a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h index 68d4668957914..83fd39af448b7 100644 --- a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.h @@ -13,15 +13,9 @@ namespace clang::tidy::readability { -/// Shortens `#if` preprocessor conditions: -/// -/// #if defined(MEOW) -> #ifdef MEOW -/// #if !defined(MEOW) -> #ifndef MEOW -/// -/// And, since C23 and C++23, shortens `#elif` conditions too: -/// -/// #elif defined(MEOW) -> #elifdef MEOW -/// #elif !defined(MEOW) -> #elifndef MEOW +/// Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef`` +/// and, since C23 and C++23, uses of ``#elif`` that can be simplified to +/// ``#elifdef`` or ``#elifndef``. /// /// User-facing documentation: /// https://clang.llvm.org/extra/clang-tidy/checks/readability/use-concise-preprocessor-directives.html diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp index dc7200ccbde24..5f04b466a0310 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-concise-preprocessor-directives.cpp @@ -1,110 +1,105 @@ -// RUN: %check_clang_tidy -std=c++98 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++11 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++14 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t +// RUN: %check_clang_tidy -std=c++98,c++11,c++14,c++17,c++20 -check-suffixes=,CXX %s readability-use-concise-preprocessor-directives %t // RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,23,CXX,CXX23 %s readability-use-concise-preprocessor-directives %t -// RUN: %check_clang_tidy -std=c99 %s readability-use-concise-preprocessor-directives %t -- -- -x c -// RUN: %check_clang_tidy -std=c11 %s readability-use-concise-preprocessor-directives %t -- -- -x c +// RUN: %check_clang_tidy -std=c99,c17,c11 %s readability-use-concise-preprocessor-directives %t -- -- -x c // RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=,23 %s readability-use-concise-preprocessor-directives %t -- -- -x c -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined(BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif defined BAR #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if (defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifdef FOO #if (defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:4: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: # elifdef BAR # elif (defined BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !defined(FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined(BAR) #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined(FOO) -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined(BAR) #endif #endif // __cplusplus -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !defined FOO -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !defined BAR #endif #ifdef __cplusplus -// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX: #ifndef FOO #if not defined FOO -// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-CXX23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-CXX23: #elifndef BAR #elif not defined BAR #endif #endif // __cplusplus -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if (!defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if (!defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif (!defined BAR) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !(defined(FOO)) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined(BAR)) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !(defined FOO) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifndef BAR #elif !(defined BAR) #endif @@ -113,22 +108,30 @@ // handling them doesn't really add any complexity to the implementation. // Test them for good measure. -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !((!!(defined(FOO)))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined(BAR))))) #endif -// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #ifndef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES: #ifndef FOO #if !((!!(defined FOO))) -// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using #elifdef [readability-use-concise-preprocessor-directives] +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] // CHECK-FIXES-23: #elifdef BAR #elif ((!(!(defined BAR)))) #endif +// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#ifndef' [readability-use-concise-preprocessor-directives] +// CHECK-FIXES: #ifndef FOO +#if !( (!! ( defined FOO )) ) +// CHECK-MESSAGES-23: :[[@LINE+2]]:2: warning: preprocessor condition can be written more concisely using '#elifdef' [readability-use-concise-preprocessor-directives] +// CHECK-FIXES-23: #elifdef BAR +#elif ( ( !(!( defined BAR) ) )) +#endif + #if FOO #elif BAR #endif @@ -136,3 +139,6 @@ #if defined(FOO) && defined(BAR) #elif defined(FOO) && defined(BAR) #endif + +#if defined FOO && BAR +#endif >From 491d304ac6c287bdfb49a23cf5c08d4ddfc785f0 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sun, 6 Jul 2025 03:36:09 -0700 Subject: [PATCH 11/11] Use `std::array` --- .../readability/UseConcisePreprocessorDirectivesCheck.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp index e7a25dd59d1c3..7e584ed58d721 100644 --- a/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UseConcisePreprocessorDirectivesCheck.cpp @@ -12,6 +12,8 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" +#include <array> + namespace clang::tidy::readability { namespace { @@ -35,7 +37,7 @@ class IfPreprocessorCallbacks final : public PPCallbacks { private: void impl(SourceLocation DirectiveLoc, SourceRange ConditionRange, - const llvm::StringLiteral (&Replacements)[2]) { + const std::array<llvm::StringLiteral, 2> &Replacements) { // Lexer requires its input range to be null-terminated. SmallString<128> Condition = Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits