https://github.com/Tsche updated 
https://github.com/llvm/llvm-project/pull/204682

>From 7308208bd27ab123bd6f3bcd97f15581f2e05d1e Mon Sep 17 00:00:00 2001
From: Matthias Wippich <[email protected]>
Date: Thu, 18 Jun 2026 22:57:28 +0200
Subject: [PATCH 1/5] [clang] improve diagnostics for enums

---
 clang/lib/AST/StmtPrinter.cpp                  | 15 +++++++++++++++
 .../test/Misc/diag-template-diffing-cxx11.cpp  |  2 +-
 clang/test/SemaCXX/static-assert.cpp           | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 9a97d52fd3020..938aca6b01380 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1882,6 +1882,21 @@ void 
StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
 }
 
 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
+  // special case enums to avoid producing cast expressions when naming
+  // an enumerator would suffice
+  if (QualType T = Node->getType(); T->isEnumeralType()) {
+    const auto *IL = dyn_cast<IntegerLiteral>(Node->getSubExpr());
+    const auto *ED = T->getAsEnumDecl();
+    if (IL && ED) {
+      llvm::APInt Val = IL->getValue();
+      for (const EnumConstantDecl *ECD : ED->enumerators()) {
+        if (llvm::APInt::isSameValue(ECD->getInitVal(), Val)) {
+          ECD->printQualifiedName(OS, Policy);
+          return;
+        }
+      }
+    }
+  }
   OS << '(';
   Node->getTypeAsWritten().print(OS, Policy);
   OS << ')';
diff --git a/clang/test/Misc/diag-template-diffing-cxx11.cpp 
b/clang/test/Misc/diag-template-diffing-cxx11.cpp
index 0b145475fe191..e543a3a132489 100644
--- a/clang/test/Misc/diag-template-diffing-cxx11.cpp
+++ b/clang/test/Misc/diag-template-diffing-cxx11.cpp
@@ -1451,7 +1451,7 @@ void run() {
   D<X::X1>(VectorType<X::X2>());
 }
 // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
-// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known 
conversion from 'VectorType<X::X2>' to 'const VectorType<(X)0>' for 1st argument
+// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known 
conversion from 'VectorType<X::X2>' to 'const VectorType<TypeAlias::X::X1>' for 
1st argument
 }
 
 namespace TypeAlias2 {
diff --git a/clang/test/SemaCXX/static-assert.cpp 
b/clang/test/SemaCXX/static-assert.cpp
index c48791203733b..d3f139ad625c2 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -363,4 +363,22 @@ namespace Diagnostics {
                                  // expected-note {{evaluates to '1 == 2'}}
   static_assert(1 << 3 != 8, ""); // expected-error {{failed}} \
                                  // expected-note {{evaluates to '8 != 8'}}
+  enum class TestEnum {
+    A = 0,
+    B = 1
+  };
+
+  template<TestEnum E> struct EnumTemplate {
+    static_assert(E == TestEnum::B, ""); // #enum-assert
+  };
+
+  EnumTemplate<TestEnum::A> test1;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::TestEnum::A == Diagnostics::TestEnum::B': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum::A>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '0 == 1'}}
+
+  EnumTemplate<TestEnum(42)> test2;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnum)42 == Diagnostics::TestEnum::B': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<42>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '42 == 1'}}
 }

>From 93acdf5a12a3e8fbc80d25c59bcfe2a7a16ccb81 Mon Sep 17 00:00:00 2001
From: Matthias Wippich <[email protected]>
Date: Tue, 23 Jun 2026 23:11:34 +0200
Subject: [PATCH 2/5] add tests, move comment

---
 clang/lib/AST/StmtPrinter.cpp        |  5 ++-
 clang/test/SemaCXX/static-assert.cpp | 66 +++++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 938aca6b01380..8a70fa51c07b1 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1882,9 +1882,10 @@ void 
StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
 }
 
 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
-  // special case enums to avoid producing cast expressions when naming
-  // an enumerator would suffice
   if (QualType T = Node->getType(); T->isEnumeralType()) {
+    // special case enums to avoid producing cast expressions when naming
+    // an enumerator would suffice
+
     const auto *IL = dyn_cast<IntegerLiteral>(Node->getSubExpr());
     const auto *ED = T->getAsEnumDecl();
     if (IL && ED) {
diff --git a/clang/test/SemaCXX/static-assert.cpp 
b/clang/test/SemaCXX/static-assert.cpp
index d3f139ad625c2..d17b50f730f5f 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -368,17 +368,63 @@ namespace Diagnostics {
     B = 1
   };
 
-  template<TestEnum E> struct EnumTemplate {
-    static_assert(E == TestEnum::B, ""); // #enum-assert
+  enum class WithUnderlying : unsigned{
+    A = 0,
+    B = 1
+  };
+
+  enum TestEnumUnscoped {
+    TEST_A = 0,
+    TEST_B = 1,
+    TEST_C = 3
   };
 
-  EnumTemplate<TestEnum::A> test1;
-  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::TestEnum::A == Diagnostics::TestEnum::B': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum::A>' requested here}} \
-  // expected-note@#enum-assert {{evaluates to '0 == 1'}}
+  enum WithUnderlyingUnscoped : unsigned {
+    TEST2_A = 0,
+    TEST2_B = 1
+  };
+
+  template<typename T, T E> struct EnumTemplate {
+    static_assert(E == (T)0, ""); // #enum-assert
+  };
 
-  EnumTemplate<TestEnum(42)> test2;
-  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnum)42 == Diagnostics::TestEnum::B': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<42>' requested here}} \
-  // expected-note@#enum-assert {{evaluates to '42 == 1'}}
+  EnumTemplate<TestEnum, TestEnum::B> test1;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::TestEnum::B == Diagnostics::TestEnum::A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum, Diagnostics::TestEnum::B>' 
requested here}} \
+  // expected-note@#enum-assert {{evaluates to '1 == 0'}}
+
+  EnumTemplate<TestEnum, TestEnum(42)> test2;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnum)42 == Diagnostics::TestEnum::A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum, (Diagnostics::TestEnum)42>' 
requested here}} \
+  // expected-note@#enum-assert {{evaluates to '42 == 0'}}
+
+  EnumTemplate<WithUnderlying, WithUnderlying::B> test3;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::WithUnderlying::B == Diagnostics::WithUnderlying::A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlying, 
Diagnostics::WithUnderlying::B>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '1 == 0'}}
+
+  EnumTemplate<WithUnderlying, WithUnderlying(42)> test6;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlying)42 == Diagnostics::WithUnderlying::A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlying, 
(Diagnostics::WithUnderlying)42>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '42 == 0'}}
+
+  EnumTemplate<TestEnumUnscoped, TestEnumUnscoped::TEST_B> test4;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::TEST_B == Diagnostics::TEST_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnumUnscoped, Diagnostics::TEST_B>' 
requested here}} \
+  // expected-note@#enum-assert {{evaluates to '1 == 0'}}
+
+  EnumTemplate<TestEnumUnscoped, TestEnumUnscoped(2)> test7;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnumUnscoped)2 == Diagnostics::TEST_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnumUnscoped, 
(Diagnostics::TestEnumUnscoped)2>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '2 == 0'}}
+
+  EnumTemplate<WithUnderlyingUnscoped, WithUnderlyingUnscoped::TEST2_B> test5;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'Diagnostics::TEST2_B == Diagnostics::TEST2_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlyingUnscoped, 
Diagnostics::TEST2_B>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '1 == 0'}}
+
+  EnumTemplate<WithUnderlyingUnscoped, WithUnderlyingUnscoped(42)> test8;
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlyingUnscoped)42 == Diagnostics::TEST2_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlyingUnscoped, 
(Diagnostics::WithUnderlyingUnscoped)42>' requested here}} \
+  // expected-note@#enum-assert {{evaluates to '42 == 0'}}
 }

>From 161eb562a0898d883bcf9685007f8f3d75896518 Mon Sep 17 00:00:00 2001
From: Matthias Wippich <[email protected]>
Date: Sun, 19 Jul 2026 03:48:59 +0200
Subject: [PATCH 3/5] disable enum pretty printing in ast-print mode

---
 clang/include/clang/AST/PrettyPrinter.h |  7 ++++++-
 clang/lib/AST/StmtPrinter.cpp           | 14 ++++++++------
 clang/lib/Frontend/ASTConsumers.cpp     |  1 +
 clang/test/AST/ast-print-enum-decl.c    |  3 +++
 clang/test/SemaCXX/static-assert.cpp    | 14 +++++++-------
 5 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/AST/PrettyPrinter.h 
b/clang/include/clang/AST/PrettyPrinter.h
index f95d54c0f05b9..c6555215ce20a 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -93,7 +93,7 @@ struct PrintingPolicy {
         PrintAsCanonical(false), PrintInjectedClassNameWithArguments(true),
         UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
         CleanUglifiedParameters(false), EntireContentsOfLargeArray(true),
-        UseEnumerators(true), UseHLSLTypes(LO.HLSL),
+        PrettyEnums(true), UseEnumerators(true), UseHLSLTypes(LO.HLSL),
         SuppressDeclAttributes(false), SuppressLambdaBody(false) {}
 
   /// Adjust this printing policy for cases where it's known that we're
@@ -357,6 +357,11 @@ struct PrintingPolicy {
   LLVM_PREFERRED_TYPE(bool)
   unsigned EntireContentsOfLargeArray : 1;
 
+  /// Whether to print enumerators with a matching enumerator name or via cast
+  //  of an integer.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned PrettyEnums : 1;
+
   /// Whether to print enumerator non-type template parameters with a matching
   /// enumerator name or via cast of an integer.
   LLVM_PREFERRED_TYPE(bool)
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 8a70fa51c07b1..4b709156cecad 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1882,7 +1882,7 @@ void 
StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
 }
 
 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
-  if (QualType T = Node->getType(); T->isEnumeralType()) {
+  if (QualType T = Node->getType(); Policy.PrettyEnums && T->isEnumeralType()) 
{
     // special case enums to avoid producing cast expressions when naming
     // an enumerator would suffice
 
@@ -1890,11 +1890,13 @@ void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr 
*Node) {
     const auto *ED = T->getAsEnumDecl();
     if (IL && ED) {
       llvm::APInt Val = IL->getValue();
-      for (const EnumConstantDecl *ECD : ED->enumerators()) {
-        if (llvm::APInt::isSameValue(ECD->getInitVal(), Val)) {
-          ECD->printQualifiedName(OS, Policy);
-          return;
-        }
+      const auto ECD =
+          llvm::find_if(ED->enumerators(), [&](const EnumConstantDecl *ECD) {
+            return llvm::APInt::isSameValue(ECD->getInitVal(), Val);
+          });
+      if (ECD != ED->enumerator_end()) {
+        ECD->printQualifiedName(OS, Policy);
+        return;
       }
     }
   }
diff --git a/clang/lib/Frontend/ASTConsumers.cpp 
b/clang/lib/Frontend/ASTConsumers.cpp
index ec678a71539d5..40995e32b67fa 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -99,6 +99,7 @@ namespace {
       } else if (OutputKind == Print) {
         PrintingPolicy Policy(D->getASTContext().getLangOpts());
         Policy.IncludeTagDefinition = true;
+        Policy.PrettyEnums = false;
         D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
       } else if (OutputKind != None) {
         D->dump(Out, OutputKind == DumpFull, OutputFormat);
diff --git a/clang/test/AST/ast-print-enum-decl.c 
b/clang/test/AST/ast-print-enum-decl.c
index 411467348fb11..f88af682a00f5 100644
--- a/clang/test/AST/ast-print-enum-decl.c
+++ b/clang/test/AST/ast-print-enum-decl.c
@@ -108,3 +108,6 @@ enum fixedEnum : int { fixedEnumerator };
 // PRINT-LABEL: enum fixedEnum : int {
 // PRINT-NEXT: fixedEnumerator
 // PRINT-NEXT: };
+
+enum fixedEnum fixedEnumVar = (enum fixedEnum)0;
+//PRINT-LABEL: enum fixedEnum fixedEnumVar = (enum fixedEnum)0;
diff --git a/clang/test/SemaCXX/static-assert.cpp 
b/clang/test/SemaCXX/static-assert.cpp
index d17b50f730f5f..dcaaaafd82445 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -395,7 +395,7 @@ namespace Diagnostics {
 
   EnumTemplate<TestEnum, TestEnum(42)> test2;
   // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnum)42 == Diagnostics::TestEnum::A': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum, (Diagnostics::TestEnum)42>' 
requested here}} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnum, 42>' requested here}} \
   // expected-note@#enum-assert {{evaluates to '42 == 0'}}
 
   EnumTemplate<WithUnderlying, WithUnderlying::B> test3;
@@ -404,8 +404,8 @@ namespace Diagnostics {
   // expected-note@#enum-assert {{evaluates to '1 == 0'}}
 
   EnumTemplate<WithUnderlying, WithUnderlying(42)> test6;
-  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlying)42 == Diagnostics::WithUnderlying::A': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlying, 
(Diagnostics::WithUnderlying)42>' requested here}} \
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlying)42U == Diagnostics::WithUnderlying::A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlying, 42>' requested here}} \
   // expected-note@#enum-assert {{evaluates to '42 == 0'}}
 
   EnumTemplate<TestEnumUnscoped, TestEnumUnscoped::TEST_B> test4;
@@ -414,8 +414,8 @@ namespace Diagnostics {
   // expected-note@#enum-assert {{evaluates to '1 == 0'}}
 
   EnumTemplate<TestEnumUnscoped, TestEnumUnscoped(2)> test7;
-  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnumUnscoped)2 == Diagnostics::TEST_A': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnumUnscoped, 
(Diagnostics::TestEnumUnscoped)2>' requested here}} \
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::TestEnumUnscoped)2U == Diagnostics::TEST_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::TestEnumUnscoped, 2>' requested here}} \
   // expected-note@#enum-assert {{evaluates to '2 == 0'}}
 
   EnumTemplate<WithUnderlyingUnscoped, WithUnderlyingUnscoped::TEST2_B> test5;
@@ -424,7 +424,7 @@ namespace Diagnostics {
   // expected-note@#enum-assert {{evaluates to '1 == 0'}}
 
   EnumTemplate<WithUnderlyingUnscoped, WithUnderlyingUnscoped(42)> test8;
-  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlyingUnscoped)42 == Diagnostics::TEST2_A': }} \
-  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlyingUnscoped, 
(Diagnostics::WithUnderlyingUnscoped)42>' requested here}} \
+  // expected-error@#enum-assert {{static assertion failed due to requirement 
'(Diagnostics::WithUnderlyingUnscoped)42U == Diagnostics::TEST2_A': }} \
+  // expected-note@-1 {{in instantiation of template class 
'Diagnostics::EnumTemplate<Diagnostics::WithUnderlyingUnscoped, 42>' requested 
here}} \
   // expected-note@#enum-assert {{evaluates to '42 == 0'}}
 }

>From 3fe480f148565b07ac28a59cfdce07aaa133b951 Mon Sep 17 00:00:00 2001
From: Matthias Wippich <[email protected]>
Date: Sun, 19 Jul 2026 04:04:02 +0200
Subject: [PATCH 4/5] re-add release note

---
 clang/docs/ReleaseNotes.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a39bc2dfc5b6d..a67342be595c7 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -290,6 +290,9 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
   against or converted to a null pointer, the same as a bare function name.
   (#GH46362)
 
+- Clang now attempts to print enumerator names rather than C-style cast 
expressions
+  in more diagnostics.
+
 
 ### Improvements to Clang's time-trace
 

>From 467653243f4898116c3eea063ae90fa3b3921838 Mon Sep 17 00:00:00 2001
From: Matthias Wippich <[email protected]>
Date: Mon, 20 Jul 2026 15:32:30 +0200
Subject: [PATCH 5/5] disable enum pretty printing in CGDebugInfo

---
 clang/lib/CodeGen/CGDebugInfo.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 7421733efcc24..084cfdb85c6b7 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -443,6 +443,7 @@ PrintingPolicy CGDebugInfo::getPrintingPolicy() const {
   PP.UsePreferredNames = false;
   PP.AlwaysIncludeTypeForTemplateArgument = true;
   PP.UseEnumerators = false;
+  PP.PrettyEnums = false;
 
   // Apply -fdebug-prefix-map.
   PP.Callbacks = &PrintCB;

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

Reply via email to