[cfe-commits] r172686 - in /cfe/trunk: lib/AST/DeclObjC.cpp lib/Sema/SemaDeclObjC.cpp test/Modules/Inputs/category_left_sub.h test/Modules/Inputs/category_right_sub.h test/Modules/Inputs/category_top.h test/Modules/objc-categories.m

Douglas Gregor dgregor at apple.com
Wed Jan 16 16:38:46 PST 2013


Author: dgregor
Date: Wed Jan 16 18:38:46 2013
New Revision: 172686

URL: http://llvm.org/viewvc/llvm-project?rev=172686&view=rev
Log:
Treat hidden Objective-C protocol definitions as if they were
undefined, and don't find methods or protocols within those protocol
definitions. This completes <rdar://problem/10634711>.

Modified:
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/Modules/Inputs/category_left_sub.h
    cfe/trunk/test/Modules/Inputs/category_right_sub.h
    cfe/trunk/test/Modules/Inputs/category_top.h
    cfe/trunk/test/Modules/objc-categories.m

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Jan 16 18:38:46 2013
@@ -66,6 +66,14 @@
 // Get the local instance/class method declared in this interface.
 ObjCMethodDecl *
 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
+  // If this context is a hidden protocol definition, don't find any
+  // methods there.
+  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
+    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
+      if (Def->isHidden())
+        return 0;
+  }
+
   // Since instance & class methods can have the same name, the loop below
   // ensures we get the correct method.
   //
@@ -87,6 +95,13 @@
 ObjCPropertyDecl *
 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
                                    IdentifierInfo *propertyID) {
+  // If this context is a hidden protocol definition, don't find any
+  // property.
+  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
+    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
+      if (Def->isHidden())
+        return 0;
+  }
 
   DeclContext::lookup_const_result R = DC->lookup(propertyID);
   for (DeclContext::lookup_const_iterator I = R.begin(), E = R.end(); I != E;
@@ -111,6 +126,12 @@
 /// in 'PropertyId' and returns it. It returns 0, if not found.
 ObjCPropertyDecl *
 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
+  // Don't find properties within hidden protocol definitions.
+  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
+    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
+      if (Def->isHidden())
+        return 0;
+  }
 
   if (ObjCPropertyDecl *PD =
         ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
@@ -1343,6 +1364,12 @@
                                                bool isInstance) const {
   ObjCMethodDecl *MethodDecl = NULL;
 
+  // If there is no definition or the definition is hidden, we don't find
+  // anything.
+  const ObjCProtocolDecl *Def = getDefinition();
+  if (!Def || Def->isHidden())
+    return NULL;
+
   if ((MethodDecl = getMethod(Sel, isInstance)))
     return MethodDecl;
 

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Jan 16 18:38:46 2013
@@ -743,7 +743,9 @@
 
     // If this is a forward declaration and we are supposed to warn in this
     // case, do it.
-    if (WarnOnDeclarations && !PDecl->hasDefinition())
+    // FIXME: Recover nicely in the hidden case.
+    if (WarnOnDeclarations &&
+        (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()))
       Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
         << ProtocolId[i].first;
     Protocols.push_back(PDecl);

Modified: cfe/trunk/test/Modules/Inputs/category_left_sub.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/category_left_sub.h?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/category_left_sub.h (original)
+++ cfe/trunk/test/Modules/Inputs/category_left_sub.h Wed Jan 16 18:38:46 2013
@@ -1,3 +1,11 @@
 @interface Foo(LeftSub) <P1>
 - (void)left_sub;
 @end
+
+ at protocol P3 
+- (void)p3_method;
+ at property (retain) id p3_prop;
+ at end
+
+ at interface Foo(LeftP3) <P3>
+ at end

Modified: cfe/trunk/test/Modules/Inputs/category_right_sub.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/category_right_sub.h?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/category_right_sub.h (original)
+++ cfe/trunk/test/Modules/Inputs/category_right_sub.h Wed Jan 16 18:38:46 2013
@@ -7,3 +7,11 @@
   int right_sub_ivar;
 }
 @end
+
+ at protocol P4
+- (void)p4_method;
+ at property (retain) id p4_prop;
+ at end
+
+ at interface Foo(LeftP4) <P4>
+ at end

Modified: cfe/trunk/test/Modules/Inputs/category_top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/category_top.h?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/category_top.h (original)
+++ cfe/trunk/test/Modules/Inputs/category_top.h Wed Jan 16 18:38:46 2013
@@ -19,3 +19,5 @@
 @protocol P2
 @end
 
+ at protocol P3, P4;
+

Modified: cfe/trunk/test/Modules/objc-categories.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/objc-categories.m?rev=172686&r1=172685&r2=172686&view=diff
==============================================================================
--- cfe/trunk/test/Modules/objc-categories.m (original)
+++ cfe/trunk/test/Modules/objc-categories.m Wed Jan 16 18:38:46 2013
@@ -47,6 +47,14 @@
   int i = foo->right_sub_ivar; // expected-error{{'Foo' does not have a member named 'right_sub_ivar'}}
   id<P1> p1 = foo; // expected-warning{{initializing 'id<P1>' with an expression of incompatible type 'Foo *'}}
   id<P2> p2 = foo; // expected-warning{{initializing 'id<P2>' with an expression of incompatible type 'Foo *'}}
+  id<P3> p3;
+  [p3 p3_method]; // expected-warning{{instance method '-p3_method' not found (return type defaults to 'id')}}
+  id<P4> p4;
+  [p4 p4_method]; // expected-warning{{instance method '-p4_method' not found (return type defaults to 'id')}}
+  id p3p = p3.p3_prop; // expected-error{{property 'p3_prop' not found on object of type 'id<P3>'}}
+  p3p = foo.p3_prop; // expected-error{{property 'p3_prop' not found on object of type 'Foo *'}}
+  id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
+  p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'}}
 }
 
 @import category_left.sub;
@@ -55,10 +63,19 @@
   // These are okay
   [foo left_sub]; // okay
   id<P1> p1 = foo;
-  // FIXME: these should fail
+  id<P3> p3;
+  [p3 p3_method];
+  id p3p = p3.p3_prop;
+  p3p = foo.p3_prop;
+  // These should fail
   foo.right_sub_prop = foo; // expected-error{{property 'right_sub_prop' not found on object of type 'Foo *'}}
   int i = foo->right_sub_ivar; // expected-error{{'Foo' does not have a member named 'right_sub_ivar'}}
   id<P2> p2 = foo; // expected-warning{{initializing 'id<P2>' with an expression of incompatible type 'Foo *'}}
+  id<P4> p4;
+  [p4 p4_method]; // expected-warning{{instance method '-p4_method' not found (return type defaults to 'id')}}
+  id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
+  p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}}
+  // expected-note at 7{{'p3_prop' declared here}}
 }
 
 @import category_right.sub;
@@ -69,4 +86,12 @@
   int i = foo->right_sub_ivar;
   id<P1> p1 = foo;
   id<P2> p2 = foo;
+  id<P3> p3;
+  [p3 p3_method];
+  id<P4> p4;
+  [p4 p4_method];
+  id p3p = p3.p3_prop;
+  p3p = foo.p3_prop;
+  id p4p = p4.p4_prop;
+  p4p = foo.p4_prop;
 }





More information about the cfe-commits mailing list