[clang] [CIR] Fix incorrect CIR_GlobalOp.global_visibility assembly format (PR #189673)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 2 02:30:07 PDT 2026


================
@@ -2849,7 +2849,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
 
   let assemblyFormat = [{
     ($sym_visibility^)?
-    (`` $global_visibility^)?
+    (custom<VisibilityAttr>($global_visibility)^)?
----------------
NotLebedev wrote:

Unfortunately it would not, because default parser breaks when multiple default/optional attributes in row need to be parsed.

<img width="843" height="229" alt="image" src="https://github.com/user-attachments/assets/efda18b7-cd67-4b1b-8d68-96d30efea058" />

It seems like it skips all optional arguments and goes straight to parsing linkage attribute and fails. But using cusotm parser works fine.

I looked into generated code and it seems that problem is the following:
1. By default `Parser::parseOptionalAttribute` is used when parsing optional attributes
2. It has four specializations [here](https://github.com/llvm/llvm-project/blob/dc9be4ee30d07060a21273bdf8c64e4f34165562/mlir/lib/AsmParser/AttributeParser.cpp#L245). For arrays, strings, symbol refs and default for generic `Attribute`
3. Generic attribute accepts all kinds of `Token`, but if it is `bare_identifier` (which I assume literal `hidden` is) it tries to parse it as type with `parseOptionalType` (which it is not)


So straightforward fix here is to use custom parser in which case this code is generated:
```
if (auto optResult = [&]() -> ::mlir::OptionalParseResult {
  {
    auto odsResult = parseVisibilityAttr(parser, global_visibilityAttr);
    if (!odsResult.has_value()) return {};
    if (::mlir::failed(*odsResult)) return ::mlir::failure();
    if (global_visibilityAttr)
      result.getOrAddProperties<GlobalOp::Properties>().global_visibility = global_visibilityAttr;
  }
    return ::mlir::success();
  }(); optResult.has_value() && ::mlir::failed(*optResult)) {
    return ::mlir::failure();
  } else if (optResult.has_value()) {
  }
```
It does not use `parseOptionalAttribute` and uses `parseVisibilityAttr` directly. This is ultimately because `CIR_VisibilityAttr` uses custom assembly format 
```
let assemblyFormat = [{
    $value
  }];
```
which does not work well with default implementation of `parseOptionalType`.

https://github.com/llvm/llvm-project/pull/189673


More information about the cfe-commits mailing list