Patch for objc2's property ASTs, as well as pretty-priting the ASTs.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43778 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 7eec3b0..4892847 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1916,6 +1916,7 @@
 
 void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
                                      DeclTy **allMethods, unsigned allNum,
+                                     DeclTy **allProperties, unsigned pNum,
                                      SourceLocation AtEndLoc) {
   Decl *ClassDecl = static_cast<Decl *>(classDecl);
 
@@ -1931,11 +1932,19 @@
   llvm::DenseMap<Selector, const ObjcMethodDecl*> InsMap;
   llvm::DenseMap<Selector, const ObjcMethodDecl*> ClsMap;
   
-  bool checkDuplicateMethods = 
+  bool isInterfaceDeclKind = 
         (isa<ObjcInterfaceDecl>(ClassDecl) || isa<ObjcCategoryDecl>(ClassDecl)
          || isa<ObjcProtocolDecl>(ClassDecl));
   bool checkIdenticalMethods = isa<ObjcImplementationDecl>(ClassDecl);
   
+  // TODO: property declaration in category and protocols.
+  if (pNum != 0 && isa<ObjcInterfaceDecl>(ClassDecl)) {
+    ObjcPropertyDecl **properties = new ObjcPropertyDecl*[pNum];
+    memcpy(properties, allProperties, pNum*sizeof(ObjcPropertyDecl*));
+    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setPropertyDecls(properties);
+    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setNumPropertyDecl(pNum);
+  }
+  
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjcMethodDecl *Method =
       cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
@@ -1946,7 +1955,7 @@
       const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
                               : false;
-      if (checkDuplicateMethods && PrevMethod && !match 
+      if (isInterfaceDeclKind && PrevMethod && !match 
           || checkIdenticalMethods && match) {
           Diag(Method->getLocation(), diag::error_duplicate_method_decl,
                Method->getSelector().getName());
@@ -1963,7 +1972,7 @@
       const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
                               : false;
-      if (checkDuplicateMethods && PrevMethod && !match 
+      if (isInterfaceDeclKind && PrevMethod && !match 
           || checkIdenticalMethods && match) {
         Diag(Method->getLocation(), diag::error_duplicate_method_decl,
              Method->getSelector().getName());
@@ -2077,6 +2086,47 @@
   return ObjcMethod;
 }
 
+Sema::DeclTy *Sema::ActOnAddObjcProperties(SourceLocation AtLoc, 
+  DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
+  ObjcPropertyDecl *PDecl = new ObjcPropertyDecl(AtLoc);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readonly)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readonly);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_getter) {
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_getter);
+    PDecl->setGetterName(DS.getGetterName());
+  }
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_setter) {
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_setter);
+    PDecl->setSetterName(DS.getSetterName());
+  }
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_assign)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_assign);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readwrite)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readwrite);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_retain)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_retain);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_copy)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_copy);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_nonatomic)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_nonatomic);
+  
+  PDecl->setNumPropertyDecls(NumProperties);
+  if (NumProperties != 0) {
+    ObjcIvarDecl **properties = new ObjcIvarDecl*[NumProperties];
+    memcpy(properties, allProperties, NumProperties*sizeof(ObjcIvarDecl*));
+    PDecl->setPropertyDecls(properties);
+  }
+  return PDecl;
+}
+
 Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
                                       DeclTy *lastEnumConst,
                                       SourceLocation IdLoc, IdentifierInfo *Id,