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 <[email protected]>
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
+@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>

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

Reply via email to