r189707 - ObjectiveC migrator: If we find a method that returns a C pointer

Fariborz Jahanian fjahanian at apple.com
Fri Aug 30 16:52:08 PDT 2013


Author: fjahanian
Date: Fri Aug 30 18:52:08 2013
New Revision: 189707

URL: http://llvm.org/viewvc/llvm-project?rev=189707&view=rev
Log:
ObjectiveC migrator: If we find a method that returns a C pointer 
of some sort (but not an object, block pointer or CF pointers), 
and is not annotated with the objc_returns_inner_pointer attribute, 
we should suggest NS_RETURNS_INNER_POINTER annotation for these methods. 

Added:
    cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m
    cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result
Modified:
    cfe/trunk/lib/ARCMigrate/ObjCMT.cpp

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=189707&r1=189706&r2=189707&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Fri Aug 30 18:52:08 2013
@@ -48,9 +48,10 @@ class ObjCMigrateASTConsumer : public AS
                                   const ObjCImplementationDecl *ImpDecl);
   void migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl,
                      const TypedefDecl *TypedefDcl);
-  void migrateInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl);
+  void migrateMethods(ASTContext &Ctx, ObjCContainerDecl *CDecl);
   void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl,
                                  ObjCMethodDecl *OM);
+  void migrateNsReturnsInnerPointer(ASTContext &Ctx, ObjCMethodDecl *OM);
   void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl,
                             ObjCMethodDecl *OM,
                             ObjCInstanceTypeFamily OIT_Family = OIT_None);
@@ -737,7 +738,31 @@ void ObjCMigrateASTConsumer::migrateMeth
   ReplaceWithInstancetype(*this, OM);
 }
 
-void ObjCMigrateASTConsumer::migrateInstanceType(ASTContext &Ctx,
+static bool TypeIsInnerPointer(QualType T) {
+  if (!T->isAnyPointerType())
+    return false;
+  if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() ||
+      T->isBlockPointerType() || ento::coreFoundation::isCFObjectRef(T))
+    return false;
+  return true;
+}
+
+void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
+                                                          ObjCMethodDecl *OM) {
+  if (OM->hasAttr<ObjCReturnsInnerPointerAttr>())
+    return;
+  
+  QualType RT = OM->getResultType();
+  if (!TypeIsInnerPointer(RT) ||
+      !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
+    return;
+  
+  edit::Commit commit(*Editor);
+  commit.insertBefore(OM->getLocEnd(), " NS_RETURNS_INNER_POINTER");
+  Editor->commit(commit);
+}
+
+void ObjCMigrateASTConsumer::migrateMethods(ASTContext &Ctx,
                                                  ObjCContainerDecl *CDecl) {
   // migrate methods which can have instancetype as their result type.
   for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
@@ -745,6 +770,7 @@ void ObjCMigrateASTConsumer::migrateInst
        M != MEnd; ++M) {
     ObjCMethodDecl *Method = (*M);
     migrateMethodInstanceType(Ctx, CDecl, Method);
+    migrateNsReturnsInnerPointer(Ctx, Method);
   }
 }
 
@@ -1151,7 +1177,7 @@ void ObjCMigrateASTConsumer::HandleTrans
       
       if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
         // migrate methods which can have instancetype as their result type.
-        migrateInstanceType(Ctx, CDecl);
+        migrateMethods(Ctx, CDecl);
         // annotate methods with CF annotations.
         migrateARCSafeAnnotation(Ctx, CDecl);
       }

Added: cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m?rev=189707&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m Fri Aug 30 18:52:08 2013
@@ -0,0 +1,96 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// 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
+
+#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure
+#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer))
+#endif
+
+#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin")
+
+#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end")
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
+#if __has_feature(attribute_ns_consumes_self)
+#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
+#endif
+#if __has_feature(attribute_ns_consumed)
+#define NS_CONSUMED __attribute__((ns_consumed))
+#endif
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#endif
+#if __has_attribute(ns_returns_autoreleased)
+#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
+#endif
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
+
+typedef signed long CFIndex; /*AnyObj*/
+typedef const struct __CFArray * CFArrayRef;
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+
+typedef void (*CFArrayApplierFunction)(const void *value, void *context);
+
+typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex {
+    kCFCompareLessThan = -1L,
+    kCFCompareEqualTo = 0,
+    kCFCompareGreaterThan = 1
+};
+
+
+typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context);
+
+typedef struct __CFArray * CFMutableArrayRef;
+
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+typedef const struct __CFString * CFStringRef;
+typedef struct __CFString * CFMutableStringRef;
+
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+
+typedef struct CGImage *CGImageRef;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
+ at interface I
+- (void*) ReturnsInnerPointer;
+- (int*)  AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER;
+ at end
+
+ at interface UIImage
+- (CGImageRef)CGImage;
+ at end
+
+ at interface NSData
+- (void *)bytes;
+- (void **) ptr_bytes __attribute__((availability(macosx,unavailable)));
+ at end
+
+ at interface NSMutableData
+- (void *)mutableBytes  __attribute__((deprecated)) __attribute__((unavailable));
+ at end

Added: cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result?rev=189707&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result Fri Aug 30 18:52:08 2013
@@ -0,0 +1,102 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// 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
+
+#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure
+#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer))
+#endif
+
+#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin")
+
+#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end")
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
+#if __has_feature(attribute_ns_consumes_self)
+#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
+#endif
+#if __has_feature(attribute_ns_consumed)
+#define NS_CONSUMED __attribute__((ns_consumed))
+#endif
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#endif
+#if __has_attribute(ns_returns_autoreleased)
+#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
+#endif
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
+
+typedef signed long CFIndex; /*AnyObj*/
+typedef const struct __CFArray * CFArrayRef;
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+
+typedef void (*CFArrayApplierFunction)(const void *value, void *context);
+
+typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex {
+    kCFCompareLessThan = -1L,
+    kCFCompareEqualTo = 0,
+    kCFCompareGreaterThan = 1
+};
+
+
+typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context);
+
+typedef struct __CFArray * CFMutableArrayRef;
+
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+typedef const struct __CFString * CFStringRef;
+typedef struct __CFString * CFMutableStringRef;
+
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+
+typedef struct CGImage *CGImageRef;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
+ at interface I
+- (void*) ReturnsInnerPointer NS_RETURNS_INNER_POINTER;
+- (int*)  AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER;
+ at end
+
+ at interface UIImage
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
+- (CGImageRef)CGImage;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
+ at end
+
+ at interface NSData
+- (void *)bytes NS_RETURNS_INNER_POINTER;
+- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))) NS_RETURNS_INNER_POINTER;
+ at end
+
+ at interface NSMutableData
+- (void *)mutableBytes  __attribute__((deprecated)) __attribute__((unavailable)) NS_RETURNS_INNER_POINTER;
+ at end





More information about the cfe-commits mailing list