[cfe-commits] r68339 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCMac.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/ContClassPropertyLookup.m

Fariborz Jahanian fjahanian at apple.com
Thu Apr 2 11:44:20 PDT 2009


Author: fjahanian
Date: Thu Apr  2 13:44:20 2009
New Revision: 68339

URL: http://llvm.org/viewvc/llvm-project?rev=68339&view=rev
Log:
Fix up lookup rules for properties declared in
objc's continuation class.

Added:
    cfe/trunk/test/SemaObjC/ContClassPropertyLookup.m
Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68339&r1=68338&r2=68339&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Apr  2 13:44:20 2009
@@ -614,17 +614,6 @@
     if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
       Fields.push_back(cast<FieldDecl>(IV));
   }
-  // look into continuation class.
-  for (ObjCCategoryDecl *Categories = OI->getCategoryList();
-       Categories; Categories = Categories->getNextClassCategory())
-    if (!Categories->getIdentifier()) {
-      for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-           E = Categories->prop_end(); I != E; ++I) {
-        if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
-          Fields.push_back(cast<FieldDecl>(IV));      
-      }
-      break;
-    }
 }
 
 /// addRecordToClass - produces record info. for the class for its
@@ -722,17 +711,6 @@
     if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
       NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this);
   }
-  // Also continuation class.
-  for (ObjCCategoryDecl *Categories = D->getCategoryList();
-       Categories; Categories = Categories->getNextClassCategory())
-    if (!Categories->getIdentifier()) {
-      for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-           E = Categories->prop_end(); I != E; ++I) {
-        if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
-          NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this);
-      }
-      break;
-    }
   
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=68339&r1=68338&r2=68339&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Apr  2 13:44:20 2009
@@ -91,16 +91,6 @@
   for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
     if ((*I)->getIdentifier() == PropertyId)
       return *I;
-  // Also look for property declared in its continuation class.
-  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this))
-    for (ObjCCategoryDecl *Categories = OID->getCategoryList();
-         Categories; Categories = Categories->getNextClassCategory())
-      if (!Categories->getIdentifier()) {
-        for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-             E = Categories->prop_end(); I != E; ++I)
-          if ((*I)->getIdentifier() == PropertyId)
-            return *I;
-      }
   
   const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
   if (PID) {
@@ -157,22 +147,6 @@
           return IV;
         }
     }
-    // look into continuation class.
-    for (ObjCCategoryDecl *Categories = ClassDecl->getCategoryList();
-         Categories; Categories = Categories->getNextClassCategory())
-      if (!Categories->getIdentifier()) {
-        for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-             E = Categories->prop_end(); I != E; ++I) {
-          ObjCPropertyDecl *PDecl = (*I);
-          if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
-            if (IV->getIdentifier() == ID) {
-              clsDeclared = ClassDecl;
-              return IV;
-            }          
-        }
-        break;
-      }
-    
     ClassDecl = ClassDecl->getSuperClass();
   }
   return NULL;

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=68339&r1=68338&r2=68339&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Apr  2 13:44:20 2009
@@ -1674,18 +1674,6 @@
     if ((*I)->getPropertyIvarDecl())
       ++count;
   }
-  // look into continuation class.
-  for (ObjCCategoryDecl *Categories = OI->getCategoryList();
-       Categories; Categories = Categories->getNextClassCategory()) {
-    if (!Categories->getIdentifier()) {
-      for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-           E = Categories->prop_end(); I != E; ++I) {
-        if ((*I)->getPropertyIvarDecl())
-          ++count;
-      }
-      break;
-    }
-  }
   return count;
 }
 
@@ -1714,20 +1702,6 @@
       if (IV->getIdentifier() == IVD->getIdentifier())
         return OI;
   }
-  // look into continuation class.
-  for (ObjCCategoryDecl *Categories = OI->getCategoryList();
-       Categories; Categories = Categories->getNextClassCategory()) {
-    if (!Categories->getIdentifier()) {
-      for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-           E = Categories->prop_end(); I != E; ++I) {
-        ObjCPropertyDecl *PDecl = (*I);
-        if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
-          if (IV->getIdentifier() == IVD->getIdentifier())
-            return OI;
-      }
-      break;
-    }
-  }
   return getInterfaceDeclForIvar(OI->getSuperClass(), IVD);
 }
 
@@ -4592,17 +4566,6 @@
        E = OID->prop_end(); I != E; ++I)
     if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
       OIvars.push_back(IV);
-  // look into continuation class.
-  for (ObjCCategoryDecl *Categories = OID->getCategoryList();
-       Categories; Categories = Categories->getNextClassCategory())
-    if (!Categories->getIdentifier()) {
-      for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
-           E = Categories->prop_end(); I != E; ++I) {
-        if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
-          OIvars.push_back(IV);
-      }
-      break;
-    }
     
   unsigned iv = 0;
   for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) {

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=68339&r1=68338&r2=68339&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Apr  2 13:44:20 2009
@@ -1592,18 +1592,25 @@
                     !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
   QualType T = GetTypeForDeclarator(FD.D, S);
   Decl *ClassDecl = ClassCategory.getAs<Decl>();
-
+  ObjCInterfaceDecl *CCPrimary = 0; // continuation class's primary class
   // May modify Attributes.
   CheckObjCPropertyAttributes(T, AtLoc, Attributes);
-  
-  ObjCMethodDecl *SetterDecl = 0;
   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
     if (!CDecl->getIdentifier()) {
       // This is a continuation class. property requires special 
       // handling.
-      if (ObjCInterfaceDecl *ICDecl = CDecl->getClassInterface()) {
-        if (ObjCPropertyDecl *PIDecl =
-            ICDecl->FindPropertyDeclaration(FD.D.getIdentifier())) {
+      if ((CCPrimary = CDecl->getClassInterface())) {
+        // Find the property in continuation class's primary class only.
+        ObjCPropertyDecl *PIDecl = 0;
+        IdentifierInfo *PropertyId = FD.D.getIdentifier();
+        for (ObjCInterfaceDecl::prop_iterator I = CCPrimary->prop_begin(), 
+             E = CCPrimary->prop_end(); I != E; ++I)
+          if ((*I)->getIdentifier() == PropertyId) {
+            PIDecl = *I;
+            break;
+          }
+            
+        if (PIDecl) {
           // property 'PIDecl's readonly attribute will be over-ridden
           // with continuation class's readwrite property attribute!
           unsigned PIkind = PIDecl->getPropertyAttributes();
@@ -1611,38 +1618,40 @@
             if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) !=
                 (PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic))
               Diag(AtLoc, diag::warn_property_attr_mismatch);
-            // Make the continuation class property attribute Read/Write
-            Attributes &= ~ObjCPropertyDecl::OBJC_PR_readonly;
-            Attributes |= ObjCPropertyDecl::OBJC_PR_readwrite;    
+            PIDecl->makeitReadWriteAttribute();
+            if (Attributes & ObjCDeclSpec::DQ_PR_retain)
+              PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
+            if (Attributes & ObjCDeclSpec::DQ_PR_copy)
+              PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
+            PIDecl->setSetterName(SetterSel);
             // FIXME: use a common routine with addPropertyMethods.
-            SetterDecl =
+            ObjCMethodDecl *SetterDecl =
               ObjCMethodDecl::Create(Context, AtLoc, AtLoc, SetterSel,
                                      Context.VoidTy,
-                                     ICDecl,
+                                     CCPrimary,
                                      true, false, true, 
                                      ObjCMethodDecl::Required);
             ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterDecl,
                                                         SourceLocation(),
-                                                        FD.D.getIdentifier(),
+                                                        PropertyId,
                                                         T, VarDecl::None, 0);
             SetterDecl->setMethodParams(&Argument, 1, Context);
+            PIDecl->setSetterMethodDecl(SetterDecl);
           }
-          else {
-            Diag(AtLoc, 
-                 diag::err_use_continuation_class) << ICDecl->getDeclName();
-            *isOverridingProperty = true;
-            return DeclPtrTy();
-          }
+          else
+            Diag(AtLoc, diag::err_use_continuation_class) 
+              << CCPrimary->getDeclName();
+          *isOverridingProperty = true;
+          return DeclPtrTy();
         }
-        // No matching property found in the main class. Just fall thru
-        // and add property to the anonymous category. It looks like
-        // it works as is. This category becomes just like a category
-        // for its primary class.
+        // No matching property found in the primary class. Just fall thru
+        // and add property to continuation class's primary class.
+        ClassDecl = CCPrimary;
       } else {
         Diag(CDecl->getLocation(), diag::err_continuation_class);
         *isOverridingProperty = true;
         return DeclPtrTy();
-      }
+      } 
     }
 
   Type *t = T.getTypePtr();
@@ -1659,7 +1668,6 @@
 
   // Regardless of setter/getter attribute, we save the default getter/setter
   // selector names in anticipation of declaration of setter/getter methods.
-  PDecl->setSetterMethodDecl(SetterDecl);
   PDecl->setGetterName(GetterSel);
   PDecl->setSetterName(SetterSel);
   
@@ -1691,6 +1699,11 @@
     PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
   else if (MethodImplKind == tok::objc_optional)
     PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
+  // A case of continuation class adding a new property in the class. This
+  // is not what it was meant for. However, gcc supports it and so should we.
+  // Make sure setter/getters are declared here.
+  if (CCPrimary)
+    ProcessPropertyDecl(PDecl, CCPrimary);
   
   return DeclPtrTy::make(PDecl);
 }

Added: cfe/trunk/test/SemaObjC/ContClassPropertyLookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/ContClassPropertyLookup.m?rev=68339&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/ContClassPropertyLookup.m (added)
+++ cfe/trunk/test/SemaObjC/ContClassPropertyLookup.m Thu Apr  2 13:44:20 2009
@@ -0,0 +1,18 @@
+// RUN: clang-cc  -fsyntax-only -verify %s
+
+ at interface MyObject {
+    int _foo;
+}
+ at end
+
+ at interface MyObject(whatever)
+ at property (assign) int foo;
+ at end
+
+ at interface MyObject()
+ at property (assign) int foo;
+ at end
+
+ at implementation MyObject
+ at synthesize foo = _foo;
+ at end





More information about the cfe-commits mailing list