https://github.com/xlauko updated 
https://github.com/llvm/llvm-project/pull/220878

>From a07851564325bd2037715cdbb0bb54a1886339fc Mon Sep 17 00:00:00 2001
From: Henrich Lauko <[email protected]>
Date: Thu, 3 Sep 2026 12:44:31 +0000
Subject: [PATCH] [CIR] Give the cleanup kind a proper standalone attribute
 spelling

CleanupKindAttr overrode its assembly format to a bare `$value` so
`cir.cleanup.scope` would print `cleanup all`. The cost was that the
attribute had no readable standalone form, falling back to
`#cir<cleanup_kind all>`.

The `enum($attr)` operation directive removes the tradeoff. The attribute
keeps CIR_EnumAttr's bracketed default and now spells `#cir.cleanup<all>`,
while the operations ask for the bare keyword. The mnemonic drops the `_kind`
suffix the C++ class name carries.

Operation syntax is unchanged. invalid-loop-cleanup.cir now gets one
diagnostic from the enum parser instead of two.
---
 .../clang/CIR/Dialect/IR/CIREnumAttr.td       |  5 +++++
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 12 ++++-------
 clang/test/CIR/IR/cleanup-scope.cir           | 21 +++++++++++++++++++
 clang/test/CIR/IR/invalid-loop-cleanup.cir    |  6 ++----
 4 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td 
b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
index f75598d6ca75c..966ab85698325 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
@@ -32,6 +32,11 @@ class CIR_I32BitEnumAttr<string name, string summary,
   let cppNamespace = "::cir";
 }
 
+// Upstream `EnumAttr` defaults to a bare `$value`, so a standalone attribute
+// falls back to the generic `#cir<cleanup all>` form. Keeping the `<` `>`
+// delimiters gets the dialect's own `#cir.cleanup<all>` instead. Operations
+// that want the bare keyword wrap the argument in the `enum` directive, as in
+// `enum($cleanupKind)`. Naming the argument directly prints `<all>`.
 class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = 
[]>
     : EnumAttr<CIR_Dialect, info, name, traits> {
   let assemblyFormat = "`<` $value `>`";
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 70d34884c70a4..2f334da9acf2c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1345,7 +1345,7 @@ def CIR_CleanupKind : CIR_I32EnumAttr<"CleanupKind", 
"cleanup kind", [
   let genSpecializedAttr = 0;
 }
 
-def CIR_CleanupKindAttr : CIR_EnumAttr<CIR_CleanupKind, "cleanup_kind"> {
+def CIR_CleanupKindAttr : CIR_EnumAttr<CIR_CleanupKind, "cleanup"> {
   let summary = "Cleanup kind attribute";
   let description = [{
     Cleanup kind attributes.
@@ -1361,10 +1361,6 @@ def CIR_CleanupKindAttr : CIR_EnumAttr<CIR_CleanupKind, 
"cleanup_kind"> {
     }]>
   ];
 
-  let assemblyFormat = [{
-    $value
-  }];
-
   let extraClassDeclaration = [{
     bool isNormal() const {
       return getValue() == CleanupKind::Normal ||
@@ -1427,7 +1423,7 @@ def CIR_CleanupScopeOp : CIR_Op<"cleanup.scope", [
   let skipDefaultBuilders = 1;
 
   let assemblyFormat = [{
-    $bodyRegion `cleanup` $cleanupKind $cleanupRegion attr-dict
+    $bodyRegion `cleanup` enum($cleanupKind) $cleanupRegion attr-dict
   }];
 
   let builders = [
@@ -2296,7 +2292,7 @@ def CIR_WhileOp : CIR_WhileOpBase<"while"> {
   let regions = (region MinSizedRegion<1>:$cond, MinSizedRegion<1>:$body,
                         MaxSizedRegion<1>:$cleanup);
   let assemblyFormat = [{
-    $cond `do` $body (`cleanup` $cleanupKind $cleanup^)? attr-dict
+    $cond `do` $body (`cleanup` enum($cleanupKind) $cleanup^)? attr-dict
   }];
 
   let description = [{
@@ -2456,7 +2452,7 @@ def CIR_ForOp : CIR_LoopOpBase<"for"> {
     `:` `cond` $cond
     `body` $body
     `step` $step
-    (`cleanup` $cleanupKind $cleanup^)?
+    (`cleanup` enum($cleanupKind) $cleanup^)?
     attr-dict
   }];
 
diff --git a/clang/test/CIR/IR/cleanup-scope.cir 
b/clang/test/CIR/IR/cleanup-scope.cir
index 614a753d5abd7..db08dc32112f5 100644
--- a/clang/test/CIR/IR/cleanup-scope.cir
+++ b/clang/test/CIR/IR/cleanup-scope.cir
@@ -133,4 +133,25 @@ cir.func @return_within_cleanup() {
 // CHECK:   cir.return
 // CHECK: }
 
+// Test that the cleanup kind attribute keeps its own delimiters when it is
+// printed standalone, while the operation still prints a bare keyword.
+cir.func @cleanup_attr_standalone() {
+  cir.cleanup.scope {
+    cir.yield
+  } cleanup all {
+    cir.yield
+  } {cir.test = [#cir.cleanup<normal>, #cir.cleanup<eh>,
+                 #cir.cleanup<all>]}
+  cir.return
+}
+
+// CHECK: cir.func @cleanup_attr_standalone() {
+// CHECK:   cir.cleanup.scope {
+// CHECK:     cir.yield
+// CHECK:   } cleanup all {
+// CHECK:     cir.yield
+// CHECK:   } {cir.test = [#cir.cleanup<normal>, #cir.cleanup<eh>, 
#cir.cleanup<all>]}
+// CHECK:   cir.return
+// CHECK: }
+
 }
diff --git a/clang/test/CIR/IR/invalid-loop-cleanup.cir 
b/clang/test/CIR/IR/invalid-loop-cleanup.cir
index ea07513bde788..2a4f6582d5581 100644
--- a/clang/test/CIR/IR/invalid-loop-cleanup.cir
+++ b/clang/test/CIR/IR/invalid-loop-cleanup.cir
@@ -16,8 +16,7 @@ cir.func @while_cleanup_missing_kind() {
     cir.condition(%cond)
   } do {
     cir.yield
-  // expected-error @below {{expected valid keyword or string}}
-  // expected-error @below {{failed to parse CIR_CleanupKindAttr}}
+  // expected-error @below {{expected string or keyword containing one of the 
following enum values for attribute 'cleanupKind' [normal, eh, all]}}
   } cleanup {
     cir.call @dtor(%s) nothrow : (!cir.ptr<!rec_S>) -> ()
     cir.yield
@@ -45,8 +44,7 @@ cir.func @for_cleanup_missing_kind() {
     cir.yield
   } step {
     cir.yield
-  // expected-error @below {{expected valid keyword or string}}
-  // expected-error @below {{failed to parse CIR_CleanupKindAttr}}
+  // expected-error @below {{expected string or keyword containing one of the 
following enum values for attribute 'cleanupKind' [normal, eh, all]}}
   } cleanup {
     cir.call @dtor(%s) nothrow : (!cir.ptr<!rec_S>) -> ()
     cir.yield

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

Reply via email to