r258834 - Class Property: parse property attribute (class).

Manman Ren via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 26 10:52:43 PST 2016


Author: mren
Date: Tue Jan 26 12:52:43 2016
New Revision: 258834

URL: http://llvm.org/viewvc/llvm-project?rev=258834&view=rev
Log:
Class Property: parse property attribute (class).

This is the third patch in a series of patches to support class properties
in addition to instance properties in objective-c.

rdar://23891898

Added:
    cfe/trunk/test/Parser/objc-class-property.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/AST/ASTDumper.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Jan 26 12:52:43 2016
@@ -716,12 +716,13 @@ public:
     /// property attribute rather than a type qualifier.
     OBJC_PR_nullability = 0x1000,
     OBJC_PR_null_resettable = 0x2000,
+    OBJC_PR_class = 0x4000
     // Adding a property should change NumPropertyAttrsBits
   };
 
   enum {
     /// \brief Number of bits fitting all the property attributes.
-    NumPropertyAttrsBits = 14
+    NumPropertyAttrsBits = 15
   };
 
   enum SetterKind { Assign, Retain, Copy, Weak };
@@ -823,6 +824,9 @@ public:
             (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
   }
 
+  bool isInstanceProperty() const { return !isClassProperty(); }
+  bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
+
   /// getSetterKind - Return the method used for doing assignment in
   /// the property setter. This is only valid if the property has been
   /// defined to have a setter.
@@ -899,21 +903,49 @@ public:
                     SourceLocation atStartLoc)
     : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
 
-  // Iterator access to properties.
+  // Iterator access to instance/class properties.
   typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
   typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
     prop_range;
 
-  prop_range instance_properties() const {
-    return prop_range(instprop_begin(), instprop_end());
-  }
-  prop_iterator instprop_begin() const {
+  prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
+  prop_iterator prop_begin() const {
     return prop_iterator(decls_begin());
   }
-  prop_iterator instprop_end() const {
+  prop_iterator prop_end() const {
     return prop_iterator(decls_end());
   }
 
+  typedef filtered_decl_iterator<ObjCPropertyDecl,
+                                 &ObjCPropertyDecl::isInstanceProperty>
+    instprop_iterator;
+  typedef llvm::iterator_range<instprop_iterator> instprop_range;
+
+  instprop_range instance_properties() const {
+    return instprop_range(instprop_begin(), instprop_end());
+  }
+  instprop_iterator instprop_begin() const {
+    return instprop_iterator(decls_begin());
+  }
+  instprop_iterator instprop_end() const {
+    return instprop_iterator(decls_end());
+  }
+
+  typedef filtered_decl_iterator<ObjCPropertyDecl,
+                                 &ObjCPropertyDecl::isClassProperty>
+    classprop_iterator;
+  typedef llvm::iterator_range<classprop_iterator> classprop_range;
+
+  classprop_range class_properties() const {
+    return classprop_range(classprop_begin(), classprop_end());
+  }
+  classprop_iterator classprop_begin() const {
+    return classprop_iterator(decls_begin());
+  }
+  classprop_iterator classprop_end() const {
+    return classprop_iterator(decls_end());
+  }
+
   // Iterator access to instance/class methods.
   typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
   typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Tue Jan 26 12:52:43 2016
@@ -800,7 +800,8 @@ public:
     DQ_PR_strong = 0x400,
     DQ_PR_unsafe_unretained = 0x800,
     DQ_PR_nullability = 0x1000,
-    DQ_PR_null_resettable = 0x2000
+    DQ_PR_null_resettable = 0x2000,
+    DQ_PR_class = 0x4000
   };
 
   ObjCDeclSpec()
@@ -860,7 +861,7 @@ private:
   ObjCDeclQualifier objcDeclQualifier : 7;
 
   // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
-  unsigned PropertyAttributes : 14;
+  unsigned PropertyAttributes : 15;
 
   unsigned Nullability : 2;
 

Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Tue Jan 26 12:52:43 2016
@@ -1597,6 +1597,8 @@ void ASTDumper::VisitObjCPropertyDecl(co
       OS << " strong";
     if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
       OS << " unsafe_unretained";
+    if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
+      OS << " class";
     if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
       dumpDeclRef(D->getGetterMethodDecl(), "getter");
     if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Jan 26 12:52:43 2016
@@ -1301,6 +1301,11 @@ void DeclPrinter::VisitObjCPropertyDecl(
       }
     }
 
+    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) {
+      Out << (first ? ' ' : ',') << "class";
+      first = false;
+    }
+
     (void) first; // Silence dead store warning due to idiomatic code.
     Out << " )";
   }

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Jan 26 12:52:43 2016
@@ -847,6 +847,7 @@ static void diagnoseRedundantPropertyNul
 ///     nullable
 ///     null_unspecified
 ///     null_resettable
+///     class
 ///
 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
   assert(Tok.getKind() == tok::l_paren);
@@ -962,6 +963,8 @@ void Parser::ParseObjCPropertyAttribute(
 
       // Also set the null_resettable bit.
       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_null_resettable);
+    } else if (II->isStr("class")) {
+      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_class);
     } else {
       Diag(AttrName, diag::err_objc_expected_property_attr) << II;
       SkipUntil(tok::r_paren, StopAtSemi);

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=258834&r1=258833&r2=258834&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Jan 26 12:52:43 2016
@@ -303,6 +303,8 @@ makePropertyAttributesAsWritten(unsigned
     attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
   if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
     attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
+  if (Attributes & ObjCDeclSpec::DQ_PR_class)
+    attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_class;
   
   return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten;
 }
@@ -691,6 +693,9 @@ ObjCPropertyDecl *Sema::CreatePropertyDe
   if (Attributes & ObjCDeclSpec::DQ_PR_null_resettable)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_null_resettable);
 
+ if (Attributes & ObjCDeclSpec::DQ_PR_class)
+    PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class);
+
   return PDecl;
 }
 

Added: cfe/trunk/test/Parser/objc-class-property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-class-property.m?rev=258834&view=auto
==============================================================================
--- cfe/trunk/test/Parser/objc-class-property.m (added)
+++ cfe/trunk/test/Parser/objc-class-property.m Tue Jan 26 12:52:43 2016
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+ at interface Root
+-(id) alloc;
+-(id) init;
+ at end
+
+ at interface A : Root {
+  int x;
+  int z;
+}
+ at property int x;
+ at property int y;
+ at property int z;
+ at property(readonly) int ro, ro2;
+ at property (class) int c;
+ at property (class) int c2;
+ at end
+
+ at implementation A
+ at dynamic x;
+ at synthesize z;
+ at dynamic c;
+ at end
+
+int test() {
+  A *a = [[A alloc] init];
+  return a.x;
+}




More information about the cfe-commits mailing list