https://github.com/localspook created 
https://github.com/llvm/llvm-project/pull/146830

Closes #132561.

This is a check that rewrites `#if`s and `#elif`s like so:

```cpp
#if  defined(MEOW) // -> #ifdef  MEOW
#if !defined(MEOW) // -> #ifndef MEOW
```

And, since C23 and C++23:

```cpp
#elif  defined(MEOW) // -> #elifdef  MEOW
#elif !defined(MEOW) // -> #elifndef MEOW
```

We can bikeshed the name and category. For example, `modernize` isn't *ideal*; 
rewriting `#if defined(A)` as `#ifdef A` isn't
really "modernizing", because `#ifdef` has always existed, but rewriting `#elif 
defined(A)` as `#elifdef A`
certainly is.

>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] [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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to