]> granicus.if.org Git - clang/commitdiff
This patch adds support for declaraing properties in categories,
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 16 Apr 2008 21:08:45 +0000 (21:08 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 16 Apr 2008 21:08:45 +0000 (21:08 +0000)
just as they are declared in objc classes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49817 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/ASTConsumers.cpp
include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaDeclObjC.cpp

index 16299c46c4740b3c503c0be223565e26a4799574..596fefc8e575c7849845df8f1647102b71cf6202 100644 (file)
@@ -345,6 +345,69 @@ void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) {
   Out << "@interface " 
       << PID->getClassInterface()->getName()
       << '(' << PID->getName() << ");\n";
+  // Output property declarations.
+  int NumProperties = PID->getNumPropertyDecl();
+  if (NumProperties > 0) {
+    for (int i = 0; i < NumProperties; i++) {
+      ObjCPropertyDecl *PDecl = PID->getPropertyDecl()[i];
+      Out << "@property";
+      if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
+        bool first = true;
+        Out << " (";
+        if (PDecl->getPropertyAttributes() & 
+            ObjCPropertyDecl::OBJC_PR_readonly) {
+          Out << (first ? ' ' : ',') << "readonly";
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+          Out << (first ? ' ' : ',') << "getter = "
+          << PDecl->getGetterName()->getName();
+          first = false;
+        }
+        if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+          Out << (first ? ' ' : ',') << "setter = "
+          << PDecl->getSetterName()->getName();
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
+          Out << (first ? ' ' : ',') << "assign";
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() &
+            ObjCPropertyDecl::OBJC_PR_readwrite) {
+          Out << (first ? ' ' : ',') << "readwrite";
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
+          Out << (first ? ' ' : ',') << "retain";
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
+          Out << (first ? ' ' : ',') << "copy";
+          first = false;
+        }
+        
+        if (PDecl->getPropertyAttributes() & 
+            ObjCPropertyDecl::OBJC_PR_nonatomic) {
+          Out << (first ? ' ' : ',') << "nonatomic";
+          first = false;
+        }
+        Out << " )";
+      }
+      Out << ' ' << PDecl->getType().getAsString()
+      << ' ' << PDecl->getName();
+      
+      Out << ";\n";
+    }
+  }
+  
+  Out << "@end\n";
+  
   // FIXME: implement the rest...
 }
 
index bed6ac581287e343b564469a7ff12c79d33a3b17..89261d9f5378a23fb9f1d56120e50df7ab14e269 100644 (file)
@@ -672,6 +672,10 @@ class ObjCCategoryDecl : public NamedDecl {
   /// Next category belonging to this class
   ObjCCategoryDecl *NextClassCategory;
   
+  /// category properties
+  ObjCPropertyDecl **PropertyDecl;  // Null if no property
+  unsigned NumPropertyDecl;  // 0 if none  
+  
   SourceLocation EndLoc; // marks the '>' or identifier.
   SourceLocation AtEndLoc; // marks the end of the entire interface.
   
@@ -680,7 +684,7 @@ class ObjCCategoryDecl : public NamedDecl {
       ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(0),
       InstanceMethods(0), NumInstanceMethods(0),
       ClassMethods(0), NumClassMethods(0),
-      NextClassCategory(0) {
+      NextClassCategory(0), PropertyDecl(0),  NumPropertyDecl(0) {
   }
 public:
   
@@ -705,6 +709,11 @@ public:
   unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
   unsigned getNumClassMethods() const { return NumClassMethods; }
 
+  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
+  unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
+  
+  ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
+  
   typedef ObjCMethodDecl * const * instmeth_iterator;
   instmeth_iterator instmeth_begin() const { return InstanceMethods; }
   instmeth_iterator instmeth_end() const {
index 7a99f0f5498b6beb523d7cdd4186e60c1542fec2..c9c5132e29b69e02114c6d80f2b47d3478fff132 100644 (file)
@@ -185,8 +185,8 @@ void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
   AtEndLoc = endLoc;
 }
 
-/// addMethods - Insert instance and methods declarations into
-/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
+/// addProperties - Insert property declaration AST nodes into
+/// ObjCInterfaceDecl's PropertyDecl field.
 ///
 void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties, 
                                       unsigned NumProperties) {
@@ -197,6 +197,18 @@ void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
   memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
 }                                   
 
+/// addProperties - Insert property declaration AST nodes into
+/// ObjCProtocolDecl's PropertyDecl field.
+///
+void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties, 
+                                     unsigned NumProperties) {
+  if (NumProperties == 0) return;
+  
+  NumPropertyDecl = NumProperties;
+  PropertyDecl = new ObjCPropertyDecl*[NumProperties];
+  memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
+}
+
 /// addMethods - Insert instance and methods declarations into
 /// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
 ///
index bf9af85a6c6c1cab20afe4ff9e2defc9bbb75912..3b6f8eccdb2f2488e5799e0009967113ce79b63c 100644 (file)
@@ -699,6 +699,9 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
   if (pNum != 0)
     if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
       IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
+    else
+      if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
+        CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
   
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjCMethodDecl *Method =