Added property decl support for protocols.
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
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp
index 596fefc..e6e8f45 100644
--- a/Driver/ASTConsumers.cpp
+++ b/Driver/ASTConsumers.cpp
@@ -52,6 +52,7 @@
     void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID);    
     void PrintObjCCategoryDecl(ObjCCategoryDecl *PID);    
     void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID);
+    void PrintObjCPropertyDecl(ObjCPropertyDecl *PD);
   };
 } // end anonymous namespace
 
@@ -264,65 +265,9 @@
     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::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 @@
       << 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 @@
       << ' ' << 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