[clang] [clang] ast-dump: dump `AvailabilityAttr` fields to JSON (PR #179281)
Noam Cohen via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 5 22:11:31 PST 2026
https://github.com/noamcohen97 updated https://github.com/llvm/llvm-project/pull/179281
>From 0e04dbb6beffe10361d230875de00d3576022cc4 Mon Sep 17 00:00:00 2001
From: Noam Cohen <noam at noam.me>
Date: Mon, 2 Feb 2026 18:40:39 +0200
Subject: [PATCH 1/5] [clang] ast-dump: dump `AvailabilityAttr` fields to JSON
---
clang/include/clang/AST/JSONNodeDumper.h | 1 +
clang/lib/AST/JSONNodeDumper.cpp | 19 +++++
clang/test/AST/ast-dump-attr-json.cpp | 104 +++++++++++++++++++++++
3 files changed, 124 insertions(+)
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index b786147728058..69dbdbbdb3ecd 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -219,6 +219,7 @@ class JSONNodeDumper
void VisitSectionAttr(const SectionAttr *SA);
void VisitVisibilityAttr(const VisibilityAttr *VA);
void VisitTLSModelAttr(const TLSModelAttr *TA);
+ void VisitAvailabilityAttr(const AvailabilityAttr *AA);
void VisitTypedefType(const TypedefType *TT);
void VisitUsingType(const UsingType *TT);
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 715e1e0989422..47fee7a3624f8 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -596,6 +596,25 @@ void JSONNodeDumper::VisitTLSModelAttr(const TLSModelAttr *TA) {
JOS.attribute("tls_model", TA->getModel());
}
+void JSONNodeDumper::VisitAvailabilityAttr(const AvailabilityAttr *AA) {
+ if (const IdentifierInfo *Platform = AA->getPlatform())
+ JOS.attribute("platform", Platform->getName());
+ if (!AA->getIntroduced().empty())
+ JOS.attribute("introduced", AA->getIntroduced().getAsString());
+ if (!AA->getDeprecated().empty())
+ JOS.attribute("deprecated", AA->getDeprecated().getAsString());
+ if (!AA->getObsoleted().empty())
+ JOS.attribute("obsoleted", AA->getObsoleted().getAsString());
+ attributeOnlyIfTrue("unavailable", AA->getUnavailable());
+ if (!AA->getMessage().empty())
+ JOS.attribute("message", AA->getMessage());
+ if (!AA->getReplacement().empty())
+ JOS.attribute("replacement", AA->getReplacement());
+ attributeOnlyIfTrue("strict", AA->getStrict());
+ if (const IdentifierInfo *Env = AA->getEnvironment())
+ JOS.attribute("environment", Env->getName());
+}
+
void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
if (!TT->typeMatchesDecl())
diff --git a/clang/test/AST/ast-dump-attr-json.cpp b/clang/test/AST/ast-dump-attr-json.cpp
index 883e584bfedf0..f9825aee29ecd 100644
--- a/clang/test/AST/ast-dump-attr-json.cpp
+++ b/clang/test/AST/ast-dump-attr-json.cpp
@@ -21,6 +21,9 @@ __attribute__ ((visibility ("hidden"))) int visibility_var;
__thread __attribute__ ((tls_model ("local-exec"))) int tls_model_var;
+__attribute__((availability(macos, strict, introduced=10.15, deprecated=12.0, obsoleted=13.0, replacement="new_func"))) int availability_var_all;
+__attribute__((availability(macos, unavailable, message="use new API"))) int availability_var_unavailable;
+
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
// using --filters=VarDecl
@@ -529,3 +532,104 @@ __thread __attribute__ ((tls_model ("local-exec"))) int tls_model_var;
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK: "kind": "VarDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 888,
+// CHECK-NEXT: "line": 24,
+// CHECK-NEXT: "col": 125,
+// CHECK-NEXT: "tokLen": 20
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 764,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 13
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 888,
+// CHECK-NEXT: "col": 125,
+// CHECK-NEXT: "tokLen": 20
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "availability_var_all",
+// CHECK-NEXT: "mangledName": "availability_var_all",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "AvailabilityAttr",
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 779,
+// CHECK-NEXT: "col": 16,
+// CHECK-NEXT: "tokLen": 12
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 880,
+// CHECK-NEXT: "col": 117,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "platform": "macos",
+// CHECK-NEXT: "introduced": "10.15",
+// CHECK-NEXT: "deprecated": "12.0",
+// CHECK-NEXT: "obsoleted": "13.0",
+// CHECK-NEXT: "replacement": "new_func",
+// CHECK-NEXT: "strict": true
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK: "kind": "VarDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 987,
+// CHECK-NEXT: "line": 25,
+// CHECK-NEXT: "col": 78,
+// CHECK-NEXT: "tokLen": 28
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 910,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 13
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 987,
+// CHECK-NEXT: "col": 78,
+// CHECK-NEXT: "tokLen": 28
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "availability_var_unavailable",
+// CHECK-NEXT: "mangledName": "availability_var_unavailable",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "AvailabilityAttr",
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 925,
+// CHECK-NEXT: "col": 16,
+// CHECK-NEXT: "tokLen": 12
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 979,
+// CHECK-NEXT: "col": 70,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "platform": "macos",
+// CHECK-NEXT: "unavailable": true,
+// CHECK-NEXT: "message": "use new API"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
>From 654f9b6825fd5c679efb088784d04ba9527065fb Mon Sep 17 00:00:00 2001
From: Noam Cohen <noam at noam.me>
Date: Fri, 6 Feb 2026 07:50:11 +0200
Subject: [PATCH 2/5] correct order
---
clang/lib/AST/JSONNodeDumper.cpp | 2 +-
clang/test/AST/ast-dump-attr-json.cpp | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 47fee7a3624f8..beec308df512b 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -608,9 +608,9 @@ void JSONNodeDumper::VisitAvailabilityAttr(const AvailabilityAttr *AA) {
attributeOnlyIfTrue("unavailable", AA->getUnavailable());
if (!AA->getMessage().empty())
JOS.attribute("message", AA->getMessage());
+ attributeOnlyIfTrue("strict", AA->getStrict());
if (!AA->getReplacement().empty())
JOS.attribute("replacement", AA->getReplacement());
- attributeOnlyIfTrue("strict", AA->getStrict());
if (const IdentifierInfo *Env = AA->getEnvironment())
JOS.attribute("environment", Env->getName());
}
diff --git a/clang/test/AST/ast-dump-attr-json.cpp b/clang/test/AST/ast-dump-attr-json.cpp
index f9825aee29ecd..9d36deaa9d038 100644
--- a/clang/test/AST/ast-dump-attr-json.cpp
+++ b/clang/test/AST/ast-dump-attr-json.cpp
@@ -21,7 +21,7 @@ __attribute__ ((visibility ("hidden"))) int visibility_var;
__thread __attribute__ ((tls_model ("local-exec"))) int tls_model_var;
-__attribute__((availability(macos, strict, introduced=10.15, deprecated=12.0, obsoleted=13.0, replacement="new_func"))) int availability_var_all;
+__attribute__((availability(macos, introduced=10.15, deprecated=12.0, obsoleted=13.0, strict, replacement="new_func"))) int availability_var_all;
__attribute__((availability(macos, unavailable, message="use new API"))) int availability_var_unavailable;
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
@@ -579,8 +579,8 @@ __attribute__((availability(macos, unavailable, message="use new API"))) int ava
// CHECK-NEXT: "introduced": "10.15",
// CHECK-NEXT: "deprecated": "12.0",
// CHECK-NEXT: "obsoleted": "13.0",
-// CHECK-NEXT: "replacement": "new_func",
-// CHECK-NEXT: "strict": true
+// CHECK-NEXT: "strict": true,
+// CHECK-NEXT: "replacement": "new_func"
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
>From 55cd3cb4e5befc15648178261d61eb370e095994 Mon Sep 17 00:00:00 2001
From: Noam Cohen <noam at noam.me>
Date: Fri, 6 Feb 2026 07:53:39 +0200
Subject: [PATCH 3/5] add `priority`
---
clang/lib/AST/JSONNodeDumper.cpp | 2 +
clang/test/AST/ast-dump-attr-json.cpp | 54 +++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index beec308df512b..3138f95e6a83b 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -611,6 +611,8 @@ void JSONNodeDumper::VisitAvailabilityAttr(const AvailabilityAttr *AA) {
attributeOnlyIfTrue("strict", AA->getStrict());
if (!AA->getReplacement().empty())
JOS.attribute("replacement", AA->getReplacement());
+ if (AA->getPriority() != 0)
+ JOS.attribute("priority", AA->getPriority());
if (const IdentifierInfo *Env = AA->getEnvironment())
JOS.attribute("environment", Env->getName());
}
diff --git a/clang/test/AST/ast-dump-attr-json.cpp b/clang/test/AST/ast-dump-attr-json.cpp
index 9d36deaa9d038..454d9665dcfe2 100644
--- a/clang/test/AST/ast-dump-attr-json.cpp
+++ b/clang/test/AST/ast-dump-attr-json.cpp
@@ -24,6 +24,10 @@ __thread __attribute__ ((tls_model ("local-exec"))) int tls_model_var;
__attribute__((availability(macos, introduced=10.15, deprecated=12.0, obsoleted=13.0, strict, replacement="new_func"))) int availability_var_all;
__attribute__((availability(macos, unavailable, message="use new API"))) int availability_var_unavailable;
+#pragma clang attribute push(__attribute__((availability(macos, introduced=11.0))), apply_to=variable)
+int availability_var_pragma;
+#pragma clang attribute pop
+
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
// using --filters=VarDecl
@@ -633,3 +637,53 @@ __attribute__((availability(macos, unavailable, message="use new API"))) int ava
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK: "kind": "VarDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 1125,
+// CHECK-NEXT: "line": 28,
+// CHECK-NEXT: "col": 5,
+// CHECK-NEXT: "tokLen": 23
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 1121,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 3
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 1125,
+// CHECK-NEXT: "col": 5,
+// CHECK-NEXT: "tokLen": 23
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "availability_var_pragma",
+// CHECK-NEXT: "mangledName": "availability_var_pragma",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "AvailabilityAttr",
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 1062,
+// CHECK-NEXT: "line": 27,
+// CHECK-NEXT: "col": 45,
+// CHECK-NEXT: "tokLen": 12
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 1097,
+// CHECK-NEXT: "col": 80,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "platform": "macos",
+// CHECK-NEXT: "introduced": "11.0",
+// CHECK-NEXT: "priority": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
>From 0f969a335c80744a682511d30d120333e932a269 Mon Sep 17 00:00:00 2001
From: Noam Cohen <noam at noam.me>
Date: Fri, 6 Feb 2026 07:59:44 +0200
Subject: [PATCH 4/5] add release note
---
clang/docs/ReleaseNotes.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b4c9ae3003b1..7c6ecd0103a44 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -49,6 +49,11 @@ ABI Changes in This Version
AST Dumping Potentially Breaking Changes
----------------------------------------
+- The JSON AST dump now includes all fields from ``AvailabilityAttr``: ``platform``,
+ ``introduced``, ``deprecated``, ``obsoleted``, ``unavailable``, ``message``,
+ ``strict``, ``replacement``, ``priority``, and ``environment``. Previously, these
+ fields were missing from the JSON output.
+
Clang Frontend Potentially Breaking Changes
-------------------------------------------
>From 0435ccf002e1bfd140ef86bc167f144f9ed40ef5 Mon Sep 17 00:00:00 2001
From: Noam Cohen <noam at noam.me>
Date: Fri, 6 Feb 2026 08:09:14 +0200
Subject: [PATCH 5/5] add `environment` test
---
.../AST/HLSL/ast-dump-availability-attr.hlsl | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 clang/test/AST/HLSL/ast-dump-availability-attr.hlsl
diff --git a/clang/test/AST/HLSL/ast-dump-availability-attr.hlsl b/clang/test/AST/HLSL/ast-dump-availability-attr.hlsl
new file mode 100644
index 0000000000000..2addc84722099
--- /dev/null
+++ b/clang/test/AST/HLSL/ast-dump-availability-attr.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -ast-dump=json %s | FileCheck %s
+
+// Test AvailabilityAttr fields in JSON AST dump
+
+__attribute__((availability(shadermodel, introduced=6.0, deprecated=6.3, obsoleted=6.5, replacement="new_func", environment=compute)))
+void availability_all(void);
+
+// CHECK: "kind": "FunctionDecl",
+// CHECK: "name": "availability_all",
+// CHECK: "kind": "AvailabilityAttr",
+// CHECK: "platform": "shadermodel",
+// CHECK: "introduced": "6.0",
+// CHECK: "deprecated": "6.3",
+// CHECK: "obsoleted": "6.5",
+// CHECK: "replacement": "new_func",
+// CHECK: "environment": "compute"
More information about the cfe-commits
mailing list