]> granicus.if.org Git - clang/commitdiff
ObjC migrator: Improve on hueristics.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 10 Jul 2013 21:30:22 +0000 (21:30 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 10 Jul 2013 21:30:22 +0000 (21:30 +0000)
migrate to 'copy attribute if Object
class implements NSCopying otherwise
assume implied 'strong'. Remove
lifetime qualifier on property as it has
moved to property's attribute. Added TODO
comment for future work by poking into
setter implementation.

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

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Edit/RewriteObjCFoundationAPI.cpp
test/ARCMT/objcmt-property.m
test/ARCMT/objcmt-property.m.result

index e4ca61a5c078519dc460ed6a52fcc8d26fe86269..1e7a0d7a9a912ecbbda38089f8c2f3e0e35512af 100644 (file)
@@ -1136,6 +1136,8 @@ public:
     return lookupInstanceVariable(IVarName, ClassDeclared);
   }
 
+  ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
+                          
   // Lookup a method. First, we search locally. If a method isn't
   // found, we search referenced protocols and class categories.
   ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
index 3895a520857c5e6b85c02763f4a2676414b987bd..c15f01debaf38bca9487c8192f76596c4634daf7 100644 (file)
@@ -441,6 +441,17 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
   return NULL;
 }
 
+ObjCProtocolDecl *
+ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
+  for (ObjCInterfaceDecl::all_protocol_iterator P =
+       all_referenced_protocol_begin(), PE = all_referenced_protocol_end();
+       P != PE; ++P)
+    if ((*P)->lookupProtocolNamed(Name))
+      return (*P);
+  ObjCInterfaceDecl *SuperClass = getSuperClass();
+  return SuperClass ? SuperClass->lookupNestedProtocol(Name) : NULL;
+}
+
 /// lookupMethod - This method returns an instance/class method by looking in
 /// the class, its categories, and its super classes (using a linear search).
 /// When argument category "C" is specified, any implicit method found
index e257a0b6f1c0d42b7431e31f842fd68a0c8296ad..8d24003d942721dbf87b896d4dbfccaf5a113f0d 100644 (file)
@@ -358,23 +358,38 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
 bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter,
                                  const ObjCMethodDecl *Setter,
                                  const NSAPI &NS, Commit &commit) {
+  ASTContext &Context = NS.getASTContext();
   std::string PropertyString = "@property";
   const ParmVarDecl *argDecl = *Setter->param_begin();
-  QualType ArgType = argDecl->getType();
+  QualType ArgType = Context.getCanonicalType(argDecl->getType());
   Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
   
   if (ArgType->isObjCRetainableType() &&
       propertyLifetime == Qualifiers::OCL_Strong) {
-    PropertyString += "(copy)";
+    if (const ObjCObjectPointerType *ObjPtrTy =
+          ArgType->getAs<ObjCObjectPointerType>()) {
+      ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
+      if (IDecl &&
+          IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
+        PropertyString += "(copy)";
+    }
   }
   else if (propertyLifetime == Qualifiers::OCL_Weak)
+    // TODO. More precise determination of 'weak' attribute requires
+    // looking into setter's implementation for backing weak ivar.
     PropertyString += "(weak)";
   else
     PropertyString += "(unsafe_unretained)";
-  
-  QualType PropQT = Getter->getResultType();
+
+  // strip off any ARC lifetime qualifier.
+  QualType CanResultTy = Context.getCanonicalType(Getter->getResultType());
+  if (CanResultTy.getQualifiers().hasObjCLifetime()) {
+    Qualifiers Qs = CanResultTy.getQualifiers();
+    Qs.removeObjCLifetime();
+    CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
+  }
   PropertyString += " ";
-  PropertyString += PropQT.getAsString(NS.getASTContext().getPrintingPolicy());
+  PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy());
   PropertyString += " ";
   PropertyString += Getter->getNameAsString();
   commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
index 1f0bcdd73537c5f625be808b4c9a6119994d4fa3..ca1b504dcbdb6b8d99017464cb25eed5e23aa99d 100644 (file)
@@ -4,7 +4,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
 
 @class NSString;
-@interface NSObject @end
+@protocol NSCopying @end
+
+@interface NSObject <NSCopying>
+@end
+
+@interface NSDictionary : NSObject
+@end
 
 @interface I : NSObject {
   int ivarVal;
@@ -24,6 +30,8 @@
 - (NSString *) UnavailProp2;
 - (void) setUnavailProp2  : (NSString *)Val  __attribute__((unavailable));
 
+- (NSDictionary*) undoAction;
+- (void) setUndoAction: (NSDictionary*)Arg;
 @end
 
 @implementation I
index 11912d950a28cf7c36aa79e368ab992aa6b683ce..2bcae864a0cb6fb92df8e4ddb1419b548844fae8 100644 (file)
@@ -4,15 +4,21 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
 
 @class NSString;
-@interface NSObject @end
+@protocol NSCopying @end
+
+@interface NSObject <NSCopying>
+@end
+
+@interface NSDictionary : NSObject
+@end
 
 @interface I : NSObject {
   int ivarVal;
 }
 
-@property(weak) NSString *__weak WeakProp;
+@property(weak) NSString * WeakProp;
 
-@property(copy) NSString * StrongProp;
+@property NSString * StrongProp;
 
 
 - (NSString *) UnavailProp  __attribute__((unavailable));
@@ -24,6 +30,8 @@
 - (NSString *) UnavailProp2;
 - (void) setUnavailProp2  : (NSString *)Val  __attribute__((unavailable));
 
+@property(copy) NSDictionary * undoAction;
+
 @end
 
 @implementation I
@@ -42,8 +50,8 @@
 
 
 
-@property(copy) NSArray * names2;
-@property(copy) NSArray * names3;
-@property(copy) NSArray *__strong names4;
-@property(copy) NSArray * names1;
+@property NSArray * names2;
+@property NSArray * names3;
+@property NSArray * names4;
+@property NSArray * names1;
 @end