]> granicus.if.org Git - clang/commitdiff
Added property decl support for protocols.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 17 Apr 2008 18:25:18 +0000 (18:25 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 17 Apr 2008 18:25:18 +0000 (18:25 +0000)
Added assertion if unexpected property decls are found where they don't belong.
Consolidated property decl. printing by using a helper function.

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

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

index 596fefc8e575c7849845df8f1647102b71cf6202..e6e8f45eb61e0c646ca4799d3caf03d3f0f96b0b 100644 (file)
@@ -52,6 +52,7 @@ namespace {
     void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID);    
     void PrintObjCCategoryDecl(ObjCCategoryDecl *PID);    
     void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID);
+    void PrintObjCPropertyDecl(ObjCPropertyDecl *PD);
   };
 } // end anonymous namespace
 
@@ -264,65 +265,9 @@ void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
     Out << "}\n";
   }
   
-  int NumProperties = OID->getNumPropertyDecl();
-  if (NumProperties > 0) {
-    for (int i = 0; i < NumProperties; i++) {
-      ObjCPropertyDecl *PDecl = OID->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";
-    }
-  }
+  for (ObjCInterfaceDecl::classprop_iterator I = OID->classprop_begin(),
+       E = OID->classprop_end(); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
   
   Out << "@end\n";
   // FIXME: implement the rest...
@@ -330,6 +275,11 @@ void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
 
 void DeclPrinter::PrintObjCProtocolDecl(ObjCProtocolDecl *PID) {
   Out << "@protocol " << PID->getName() << '\n';
+  
+  for (ObjCProtocolDecl::classprop_iterator I = PID->classprop_begin(),
+       E = PID->classprop_end(); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
+  Out << "@end\n";
   // FIXME: implement the rest...
 }
 
@@ -346,66 +296,9 @@ void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) {
       << 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";
-    }
-  }
-  
+  for (ObjCCategoryDecl::classprop_iterator I = PID->classprop_begin(),
+       E = PID->classprop_end(); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
   Out << "@end\n";
   
   // FIXME: implement the rest...
@@ -416,6 +309,65 @@ void DeclPrinter::PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
       << ' ' << AID->getClassInterface()->getName() << ";\n";  
 }
 
+/// PrintObjCPropertyDecl - print a property declaration.
+///
+void DeclPrinter::PrintObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
+    
+  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";
+}
+    
 //===----------------------------------------------------------------------===//
 /// ASTPrinter - Pretty-printer of ASTs
 
index 80634fe760147805797e1aa1a57297e0b18e47b6..55115055aef0f53134d72fffdd7717e5a2d45acd 100644 (file)
@@ -309,6 +309,11 @@ public:
   
   void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
   
+  typedef ObjCPropertyDecl * const * classprop_iterator;
+  classprop_iterator classprop_begin() const { return PropertyDecl; }
+  classprop_iterator classprop_end() const {
+    return PropertyDecl+NumPropertyDecl;
+  }
   
   bool isForwardDecl() const { return ForwardDecl; }
   void setForwardDecl(bool val) { ForwardDecl = val; }
@@ -463,7 +468,11 @@ class ObjCProtocolDecl : public NamedDecl {
   /// protocol class methods
   ObjCMethodDecl **ClassMethods;  // Null if not defined
   unsigned NumClassMethods;  // 0 if none
-
+  
+  /// protocol properties
+  ObjCPropertyDecl **PropertyDecl;  // Null if no property
+  unsigned NumPropertyDecl;  // 0 if none
+  
   bool isForwardProtoDecl; // declared with @protocol.
   
   SourceLocation EndLoc; // marks the '>' or identifier.
@@ -474,6 +483,7 @@ class ObjCProtocolDecl : public NamedDecl {
       ReferencedProtocols(0), NumReferencedProtocols(0),
       InstanceMethods(0), NumInstanceMethods(0), 
       ClassMethods(0), NumClassMethods(0),
+      PropertyDecl(0), NumPropertyDecl(0),
       isForwardProtoDecl(true) {
     AllocReferencedProtocols(numRefProtos);
   }
@@ -504,6 +514,19 @@ public:
   unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
   unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
   unsigned getNumClassMethods() const { return NumClassMethods; }
+  
+  unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
+  
+  ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
+  ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
+  
+  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
+  
+  typedef ObjCPropertyDecl * const * classprop_iterator;
+  classprop_iterator classprop_begin() const { return PropertyDecl; }
+  classprop_iterator classprop_end() const {
+    return PropertyDecl+NumPropertyDecl;
+  }
 
   typedef ObjCMethodDecl * const * instmeth_iterator;
   instmeth_iterator instmeth_begin() const { return InstanceMethods; }
@@ -709,11 +732,18 @@ 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; }
   
+  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
+  
+  typedef ObjCPropertyDecl * const * classprop_iterator;
+  classprop_iterator classprop_begin() const { return PropertyDecl; }
+  classprop_iterator classprop_end() const {
+    return PropertyDecl+NumPropertyDecl;
+  }
+  
   typedef ObjCMethodDecl * const * instmeth_iterator;
   instmeth_iterator instmeth_begin() const { return InstanceMethods; }
   instmeth_iterator instmeth_end() const {
index 2d959445d4abfd752c42250c7fddaf5ef7624ff1..a5eb07a84c4dfff7cc95f39a6560707c7cfedfa3 100644 (file)
@@ -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 ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties, 
+                                     unsigned NumProperties) {
+  if (NumProperties == 0) return;
+  
+  NumPropertyDecl = NumProperties;
+  PropertyDecl = new ObjCPropertyDecl*[NumProperties];
+  memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
+}
+
 /// addProperties - Insert property declaration AST nodes into
 /// ObjCCategoryDecl's PropertyDecl field.
 ///
index 3b6f8eccdb2f2488e5799e0009967113ce79b63c..eb9fa433d970fa8afed6b535fc7a6548017edcb4 100644 (file)
@@ -695,13 +695,15 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
          || isa<ObjCProtocolDecl>(ClassDecl);
   bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
   
-  // TODO: property declaration in category and protocols.
   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);
+    else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(ClassDecl))
+          PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
     else
-      if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
-        CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
+      assert(false && "ActOnAtEnd - property declaration misplaced");
   
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjCMethodDecl *Method =