https://github.com/grigorypas updated 
https://github.com/llvm/llvm-project/pull/205449

>From 10cd335568bd5c75d72f85da14c1fdf4f5da1f50 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <[email protected]>
Date: Tue, 23 Jun 2026 16:12:06 -0700
Subject: [PATCH 1/2] [clang-tidy] Move isStdInitializerList to
 utils::type_traits and add unit tests

---
 .../misc/ExplicitConstructorCheck.cpp         | 24 +-------
 .../clang-tidy/utils/TypeTraits.cpp           | 22 +++++++
 .../clang-tidy/utils/TypeTraits.h             |  3 +
 .../unittests/clang-tidy/CMakeLists.txt       |  1 +
 .../unittests/clang-tidy/TypeTraitsTest.cpp   | 60 +++++++++++++++++++
 5 files changed, 88 insertions(+), 22 deletions(-)
 create mode 100644 clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp

diff --git a/clang-tools-extra/clang-tidy/misc/ExplicitConstructorCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/ExplicitConstructorCheck.cpp
index 8c6f8ef978991..23261fe5af61b 100644
--- a/clang-tools-extra/clang-tidy/misc/ExplicitConstructorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ExplicitConstructorCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "ExplicitConstructorCheck.h"
 #include "../utils/LexerUtils.h"
+#include "../utils/TypeTraits.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
@@ -31,27 +32,6 @@ void ExplicitConstructorCheck::registerMatchers(MatchFinder 
*Finder) {
       this);
 }
 
-static bool declIsStdInitializerList(const NamedDecl *D) {
-  // First use the fast getName() method to avoid unnecessary calls to the
-  // slow getQualifiedNameAsString().
-  return D->getName() == "initializer_list" &&
-         D->getQualifiedNameAsString() == "std::initializer_list";
-}
-
-static bool isStdInitializerList(QualType Type) {
-  Type = Type.getCanonicalType();
-  if (const auto *TS = Type->getAs<TemplateSpecializationType>()) {
-    if (const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
-      return declIsStdInitializerList(TD);
-  }
-  if (const auto *RT = Type->getAs<RecordType>()) {
-    if (const auto *Specialization =
-            dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
-      return 
declIsStdInitializerList(Specialization->getSpecializedTemplate());
-  }
-  return false;
-}
-
 void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
   constexpr char NoExpressionWarningMessage[] =
       "%0 must be marked explicit to avoid unintentional implicit conversions";
@@ -79,7 +59,7 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
 
   const ExplicitSpecifier ExplicitSpec = Ctor->getExplicitSpecifier();
 
-  const bool TakesInitializerList = isStdInitializerList(
+  const bool TakesInitializerList = utils::type_traits::isStdInitializerList(
       Ctor->getParamDecl(0)->getType().getNonReferenceType());
   if (ExplicitSpec.isExplicit() &&
       (Ctor->isCopyOrMoveConstructor() || TakesInitializerList)) {
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp 
b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index c15d90b19d359..06d489129cd43 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -9,6 +9,7 @@
 #include "TypeTraits.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include <optional>
 
 namespace clang::tidy::utils::type_traits {
@@ -146,4 +147,25 @@ bool hasNonTrivialMoveAssignment(QualType Type) {
          Record->hasNonTrivialMoveAssignment();
 }
 
+static bool declIsStdInitializerList(const NamedDecl *D) {
+  // First use the fast getName() method to avoid unnecessary calls to the
+  // slow getQualifiedNameAsString().
+  return D->getName() == "initializer_list" &&
+         D->getQualifiedNameAsString() == "std::initializer_list";
+}
+
+bool isStdInitializerList(QualType Type) {
+  Type = Type.getCanonicalType();
+  if (const auto *TS = Type->getAs<TemplateSpecializationType>()) {
+    if (const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
+      return declIsStdInitializerList(TD);
+  }
+  if (const auto *RT = Type->getAs<RecordType>()) {
+    if (const auto *Specialization =
+            dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
+      return 
declIsStdInitializerList(Specialization->getSpecializedTemplate());
+  }
+  return false;
+}
+
 } // namespace clang::tidy::utils::type_traits
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.h 
b/clang-tools-extra/clang-tidy/utils/TypeTraits.h
index 98a4a99bf8d4d..03711461b51ac 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.h
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.h
@@ -34,6 +34,9 @@ bool hasNonTrivialMoveConstructor(QualType Type);
 /// Return true if `Type` has a non-trivial move assignment operator.
 bool hasNonTrivialMoveAssignment(QualType Type);
 
+/// Returns `true` if `Type` is a `std::initializer_list<...>` specialization.
+bool isStdInitializerList(QualType Type);
+
 } // namespace clang::tidy::utils::type_traits
 
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_TYPETRAITS_H
diff --git a/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt 
b/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
index 26ceb977d27a6..00498813d1e52 100644
--- a/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
+++ b/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
@@ -35,6 +35,7 @@ add_extra_unittest(ClangTidyTests
   UsingInserterTest.cpp
   ReadabilityModuleTest.cpp
   TransformerClangTidyCheckTest.cpp
+  TypeTraitsTest.cpp
   )
 
 clang_target_link_libraries(ClangTidyTests
diff --git a/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp 
b/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp
new file mode 100644
index 0000000000000..3c4f4b5726251
--- /dev/null
+++ b/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp
@@ -0,0 +1,60 @@
+//===--- TypeTraitsTest.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 "../clang-tidy/utils/TypeTraits.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+namespace clang::tidy::test {
+namespace {
+
+using namespace ast_matchers;
+
+// Returns whether the type of the declaration named `DeclName` in `Code` is a
+// std::initializer_list specialization.
+bool declTypeIsStdInitializerList(StringRef Code, StringRef DeclName) {
+  std::unique_ptr<ASTUnit> AST =
+      tooling::buildASTFromCodeWithArgs(Code, {"-std=c++17"});
+  EXPECT_NE(AST, nullptr);
+  auto Matches =
+      match(valueDecl(hasName(DeclName)).bind("d"), AST->getASTContext());
+  EXPECT_EQ(Matches.size(), 1u);
+  const auto *D = Matches[0].getNodeAs<ValueDecl>("d");
+  return utils::type_traits::isStdInitializerList(D->getType());
+}
+
+constexpr char InitializerListDecl[] =
+    "namespace std { template <typename T> class initializer_list {}; }\n";
+
+TEST(IsStdInitializerListTest, MatchesSpecialization) {
+  EXPECT_TRUE(declTypeIsStdInitializerList(
+      std::string(InitializerListDecl) + "std::initializer_list<int> v;", 
"v"));
+}
+
+TEST(IsStdInitializerListTest, MatchesDependentSpecialization) {
+  EXPECT_TRUE(declTypeIsStdInitializerList(
+      std::string(InitializerListDecl) +
+          "template <typename T> void f(std::initializer_list<T> p);",
+      "p"));
+}
+
+TEST(IsStdInitializerListTest, RejectsBuiltin) {
+  EXPECT_FALSE(declTypeIsStdInitializerList("int v;", "v"));
+}
+
+TEST(IsStdInitializerListTest, RejectsNonStdInitializerList) {
+  EXPECT_FALSE(declTypeIsStdInitializerList(
+      "template <typename T> class initializer_list {}; "
+      "initializer_list<int> v;",
+      "v"));
+}
+
+} // namespace
+} // namespace clang::tidy::test

>From a7db3cd6adae7f16e680b5c3f9983e649555680e Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <[email protected]>
Date: Wed, 24 Jun 2026 09:14:19 -0700
Subject: [PATCH 2/2] Update
 clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp

Co-authored-by: Zeyi Xu <[email protected]>
---
 clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp 
b/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp
index 3c4f4b5726251..13261c3aa9e52 100644
--- a/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp
+++ b/clang-tools-extra/unittests/clang-tidy/TypeTraitsTest.cpp
@@ -1,4 +1,4 @@
-//===--- TypeTraitsTest.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.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to