]> granicus.if.org Git - clang/commitdiff
ObjectiveC. When issuing property implementation is
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Jan 2014 19:02:20 +0000 (19:02 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Jan 2014 19:02:20 +0000 (19:02 +0000)
not using backing ivar warning, ignore when
property is not being synthesized (user declared its
implementation @dynamic). // rdar://1583425

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

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/unused-backing-ivar-warning.m

index 9c6dbc93172ccfb72a711b4a571fa50d4deac053..a454cc17b320789732685bfa388ee92a8805b04c 100644 (file)
@@ -1405,6 +1405,10 @@ public:
 
   bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
                                       ObjCProtocolDecl *rProto) const;
+  
+  ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
+                                                  const ObjCPropertyDecl *PD,
+                                                  const Decl *Container) const;
 
   /// \brief Return the size of type \p T for Objective-C encoding purpose,
   /// in characters.
index acff54bba269792a3a4b542cec99b1b3dd75deba..c3914d34198980e88c210842c2b2bae577c2be32 100644 (file)
@@ -4960,6 +4960,34 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
   return false;
 }
 
+ObjCPropertyImplDecl *
+ASTContext::getObjCPropertyImplDeclForPropertyDecl(
+                                      const ObjCPropertyDecl *PD,
+                                      const Decl *Container) const {
+  if (!Container)
+    return 0;
+  if (const ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(Container)) {
+    for (ObjCCategoryImplDecl::propimpl_iterator
+         i = CID->propimpl_begin(), e = CID->propimpl_end();
+         i != e; ++i) {
+      ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD)
+          return PID;
+      }
+    } else {
+      const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+      for (ObjCCategoryImplDecl::propimpl_iterator
+           i = OID->propimpl_begin(), e = OID->propimpl_end();
+           i != e; ++i) {
+        ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD)
+          return PID;
+      }
+    }
+  return 0;
+}
+
 /// getObjCEncodingForPropertyDecl - Return the encoded type for this
 /// property declaration. If non-NULL, Container must be either an
 /// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
@@ -4992,37 +5020,12 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
   bool Dynamic = false;
   ObjCPropertyImplDecl *SynthesizePID = 0;
 
-  // FIXME: Duplicated code due to poor abstraction.
-  if (Container) {
-    if (const ObjCCategoryImplDecl *CID =
-        dyn_cast<ObjCCategoryImplDecl>(Container)) {
-      for (ObjCCategoryImplDecl::propimpl_iterator
-             i = CID->propimpl_begin(), e = CID->propimpl_end();
-           i != e; ++i) {
-        ObjCPropertyImplDecl *PID = *i;
-        if (PID->getPropertyDecl() == PD) {
-          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
-            Dynamic = true;
-          } else {
-            SynthesizePID = PID;
-          }
-        }
-      }
-    } else {
-      const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
-      for (ObjCCategoryImplDecl::propimpl_iterator
-             i = OID->propimpl_begin(), e = OID->propimpl_end();
-           i != e; ++i) {
-        ObjCPropertyImplDecl *PID = *i;
-        if (PID->getPropertyDecl() == PD) {
-          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
-            Dynamic = true;
-          } else {
-            SynthesizePID = PID;
-          }
-        }
-      }
-    }
+  if (ObjCPropertyImplDecl *PropertyImpDecl =
+      getObjCPropertyImplDeclForPropertyDecl(PD, Container)) {
+    if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      Dynamic = true;
+    else
+      SynthesizePID = PropertyImpDecl;
   }
 
   // FIXME: This is not very efficient.
index f7f1b4b5653f415709332a668015a54aa5b5a891..78c26d38a9f2364fb999fc2ec369a682811c5dc1 100644 (file)
@@ -3514,6 +3514,13 @@ void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S,
     const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
     if (!IV)
       continue;
+    // Property declared as @dynamic must be ignored.
+    if (ObjCPropertyImplDecl *PropertyImpDecl =
+          Context.getObjCPropertyImplDeclForPropertyDecl(PDecl, ImplD))
+      if (PropertyImpDecl->getPropertyImplementation() ==
+            ObjCPropertyImplDecl::Dynamic)
+        continue;
+      
 
     UnusedBackingIvarChecker Checker(*this, CurMethod, IV);
     Checker.TraverseStmt(CurMethod->getBody());
index acdf8b11c6fa1019019acaf5970cebc118cf8ee5..59fbc85d609a91e25e4dd543dcc5bf1c4520fd62 100644 (file)
@@ -147,3 +147,26 @@ typedef char BOOL;
   return [o Meth];
 }
 @end
+
+// rdar://15873425
+@protocol MyProtocol
+@property (nonatomic, readonly) int myProperty;
+@end
+
+@interface MyFirstClass : NSObject <MyProtocol>
+@end
+
+@interface MySecondClass : NSObject <MyProtocol>
+@end
+
+@implementation MyFirstClass
+@synthesize myProperty;
+@end
+
+@implementation MySecondClass
+@dynamic myProperty;
+-(int)myProperty  // should not warn; property is dynamic
+{
+    return 0;
+}
+@end