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
