Author: Prajwal Nadig
Date: 2026-02-06T15:01:50Z
New Revision: 85eb10e2707c9b9b4da1f8cfde64e9478dad258a

URL: 
https://github.com/llvm/llvm-project/commit/85eb10e2707c9b9b4da1f8cfde64e9478dad258a
DIFF: 
https://github.com/llvm/llvm-project/commit/85eb10e2707c9b9b4da1f8cfde64e9478dad258a.diff

LOG: [Sema] Directly use written attributes in ObjC (#179703)

Clang's AST builder uses 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()`. This method was relevant in the past when two
separate enums existed for Objective-C property attributes, and had to
be updated whenever new property attributes were introduced. As of this
commit, nullability attributes are not present when written due to the
method not containing the bitmask comparison for the `nullable` and
`null_resettable` attributes.

9721fbf85b83c1cb67cea542c5558f99a07766cf consolidated the two property
attribute enums into a single
enum. With this change, the AST can directly store the written
attributes without having to construct the bitmask again. This commit
removes the `getPropertyAttributesAsWritten()` method and updates the
AST to directly store the written attributes instead.

rdar://131053727

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/DeclObjCCommon.h
    clang/lib/Sema/SemaObjCProperty.cpp
    clang/test/ExtractAPI/objc_property.m

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 24d4e07ca68b3..02e2034624e4a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -246,6 +246,7 @@ Bug Fixes to C++ Support
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a bug where explicit nullability property attributes were not stored 
in AST nodes in Objective-C. (#GH179703)
 
 Miscellaneous Bug Fixes
 ^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/include/clang/AST/DeclObjCCommon.h 
b/clang/include/clang/AST/DeclObjCCommon.h
index 42c97204a6130..ddb373cf01bf5 100644
--- a/clang/include/clang/AST/DeclObjCCommon.h
+++ b/clang/include/clang/AST/DeclObjCCommon.h
@@ -43,7 +43,7 @@ enum Kind {
   // Also, don't forget to update the Clang C API at CXObjCPropertyAttrKind and
   // clang_Cursor_getObjCPropertyAttributes.
 };
-} // namespace ObjCPropertyAttribute::Kind
+} // namespace ObjCPropertyAttribute
 
 enum {
   /// Number of bits fitting all the property attributes.

diff  --git a/clang/lib/Sema/SemaObjCProperty.cpp 
b/clang/lib/Sema/SemaObjCProperty.cpp
index 67c554c50a8ce..4d7efed23939e 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -269,41 +269,6 @@ Decl *SemaObjC::ActOnProperty(Scope *S, SourceLocation 
AtLoc,
   return Res;
 }
 
-static ObjCPropertyAttribute::Kind
-makePropertyAttributesAsWritten(unsigned Attributes) {
-  unsigned attributesAsWritten = 0;
-  if (Attributes & ObjCPropertyAttribute::kind_readonly)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_readonly;
-  if (Attributes & ObjCPropertyAttribute::kind_readwrite)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_readwrite;
-  if (Attributes & ObjCPropertyAttribute::kind_getter)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_getter;
-  if (Attributes & ObjCPropertyAttribute::kind_setter)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_setter;
-  if (Attributes & ObjCPropertyAttribute::kind_assign)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_assign;
-  if (Attributes & ObjCPropertyAttribute::kind_retain)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_retain;
-  if (Attributes & ObjCPropertyAttribute::kind_strong)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_strong;
-  if (Attributes & ObjCPropertyAttribute::kind_weak)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_weak;
-  if (Attributes & ObjCPropertyAttribute::kind_copy)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_copy;
-  if (Attributes & ObjCPropertyAttribute::kind_unsafe_unretained)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_unsafe_unretained;
-  if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_nonatomic;
-  if (Attributes & ObjCPropertyAttribute::kind_atomic)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_atomic;
-  if (Attributes & ObjCPropertyAttribute::kind_class)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_class;
-  if (Attributes & ObjCPropertyAttribute::kind_direct)
-    attributesAsWritten |= ObjCPropertyAttribute::kind_direct;
-
-  return (ObjCPropertyAttribute::Kind)attributesAsWritten;
-}
-
 static bool LocPropertyAttribute( ASTContext &Context, const char *attrName,
                                  SourceLocation LParenLoc, SourceLocation 
&Loc) {
   if (LParenLoc.isMacroID())
@@ -629,7 +594,7 @@ ObjCPropertyDecl *SemaObjC::CreatePropertyDecl(
   PDecl->setGetterName(GetterSel, GetterNameLoc);
   PDecl->setSetterName(SetterSel, SetterNameLoc);
   PDecl->setPropertyAttributesAsWritten(
-                          
makePropertyAttributesAsWritten(AttributesAsWritten));
+      static_cast<ObjCPropertyAttribute::Kind>(AttributesAsWritten));
 
   SemaRef.ProcessDeclAttributes(S, PDecl, FD.D);
 

diff  --git a/clang/test/ExtractAPI/objc_property.m 
b/clang/test/ExtractAPI/objc_property.m
index 68869295f8c04..9e6b40f77370c 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,30 @@ @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:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "@property"
+// NULLABLE:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "strong"
+// NULLABLE:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "nullable"
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix 
NULLRESETTABLE
+@property(null_resettable, strong) id myNullResettableProp;
+// CHECK-DAG: "!testRelLabel": "memberOf $ 
c:objc(cs)Interface(py)myNullResettableProp $ c:objc(cs)Interface"
+// NULLRESETTABLE: "!testLabel": "c:objc(cs)Interface(py)myNullResettableProp"
+// NULLABLE:      "declarationFragments": [
+// NULLABLE:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "@property"
+// NULLABLE:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "strong"
+// NULLABLE:          "kind": "keyword",
+// NULLABLE-NEXT:     "spelling": "null_resettable"
 @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