[clang] [Sema] Include nullability attributes when written (PR #179703)
Prajwal Nadig via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 4 08:11:40 PST 2026
https://github.com/snprajwal created https://github.com/llvm/llvm-project/pull/179703
Clang's AST builder provides the `getPropertyAttributesAsWritten()` method that contains the bitmasks of only the attributes present in the source, and not the default attributes that are present in `getPropertyAttributes()`. However, the bitmasks for nullability attributes were not being set when written, leading to them being dropped in the declaration fragments in ExtractAPI. This patch updates the AST node for ObjC properties to correctly store nullability information.
rdar://131053727
>From 4a419d3d21f40931e344c84d4b5a8d0839820ac7 Mon Sep 17 00:00:00 2001
From: Prajwal Nadig <pnadig at apple.com>
Date: Wed, 4 Feb 2026 15:55:22 +0000
Subject: [PATCH] [Sema] Include nullability attributes when written
Clang's AST builder provides the `getPropertyAttributesAsWritten()`
method that contains the bitmasks of only the attributes present in the
source, and not the default attributes that are present in
`getPropertyAttributes()`. However, the bitmasks for nullability
attributes were not being set when written, leading to them being
dropped in the declaration fragments in ExtractAPI. This patch updates
the AST node for ObjC properties to correctly store nullability
information.
rdar://131053727
---
clang/lib/Sema/SemaObjCProperty.cpp | 4 +++
clang/test/ExtractAPI/objc_property.m | 50 ++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index 67c554c50a8ce..d1acbb959a4cb 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -300,6 +300,10 @@ makePropertyAttributesAsWritten(unsigned Attributes) {
attributesAsWritten |= ObjCPropertyAttribute::kind_class;
if (Attributes & ObjCPropertyAttribute::kind_direct)
attributesAsWritten |= ObjCPropertyAttribute::kind_direct;
+ if (Attributes & ObjCPropertyAttribute::kind_nullability)
+ attributesAsWritten |= ObjCPropertyAttribute::kind_nullability;
+ if (Attributes & ObjCPropertyAttribute::kind_null_resettable)
+ attributesAsWritten |= ObjCPropertyAttribute::kind_null_resettable;
return (ObjCPropertyAttribute::Kind)attributesAsWritten;
}
diff --git a/clang/test/ExtractAPI/objc_property.m b/clang/test/ExtractAPI/objc_property.m
index 68869295f8c04..757c13d13564e 100644
--- a/clang/test/ExtractAPI/objc_property.m
+++ b/clang/test/ExtractAPI/objc_property.m
@@ -1,6 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
-// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o - -verify | FileCheck %s
+// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o %t/output.symbols.json -verify
+// RUN: FileCheck %s --input-file %t/output.symbols.json
@protocol Protocol
@property(class) int myProtocolTypeProp;
@@ -14,6 +15,53 @@ @interface Interface
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(cpy)myInterfaceTypeProp $ c:objc(cs)Interface"
@property int myInterfaceInstanceProp;
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(py)myInterfaceInstanceProp $ c:objc(cs)Interface"
+//
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix NULLABLE
+ at property(nullable, strong) id myNullableProp;
+// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(py)myNullableProp $ c:objc(cs)Interface"
+// NULLABLE: "!testLabel": "c:objc(cs)Interface(py)myNullableProp"
+// NULLABLE: "declarationFragments": [
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "keyword",
+// NULLABLE-NEXT: "spelling": "@property"
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "text",
+// NULLABLE-NEXT: "spelling": " ("
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "keyword",
+// NULLABLE-NEXT: "spelling": "strong"
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "text",
+// NULLABLE-NEXT: "spelling": ", "
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "keyword",
+// NULLABLE-NEXT: "spelling": "nullable"
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "text",
+// NULLABLE-NEXT: "spelling": ") "
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "keyword",
+// NULLABLE-NEXT: "spelling": "id"
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "text",
+// NULLABLE-NEXT: "spelling": " "
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "identifier",
+// NULLABLE-NEXT: "spelling": "myNullableProp"
+// NULLABLE-NEXT: },
+// NULLABLE-NEXT: {
+// NULLABLE-NEXT: "kind": "text",
+// NULLABLE-NEXT: "spelling": ";"
+// NULLABLE-NEXT: }
+// NULLABLE-NEXT: ],
@end
@interface Interface (Category) <Protocol>
More information about the cfe-commits
mailing list