[cfe-commits] r157785 - in /cfe/trunk: include/clang/Sema/Sema.h lib/ARCMigrate/Internals.h lib/ARCMigrate/TransUnbridgedCasts.cpp lib/ARCMigrate/Transforms.cpp lib/Sema/SemaExprObjC.cpp test/ARCMT/Common.h test/ARCMT/autoreleases.m.result test/ARCMT/nonobjc-to-objc-cast.m.result

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu May 31 17:10:47 PDT 2012


Author: akirtzidis
Date: Thu May 31 19:10:47 2012
New Revision: 157785

URL: http://llvm.org/viewvc/llvm-project?rev=157785&view=rev
Log:
[arcmt] Use CFBridgingRetain/CFBridgingRelease instead of __bridge_retained/__bridge_transfer
when migrating.

rdar://11569198

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/ARCMigrate/Internals.h
    cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp
    cfe/trunk/lib/ARCMigrate/Transforms.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/ARCMT/Common.h
    cfe/trunk/test/ARCMT/autoreleases.m.result
    cfe/trunk/test/ARCMT/nonobjc-to-objc-cast.m.result

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu May 31 19:10:47 2012
@@ -2107,6 +2107,7 @@
   LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
                                                     ArrayRef<QualType> ArgTys,
                                                     bool AllowRawAndTemplate);
+  bool isKnownName(StringRef name);
 
   void ArgumentDependentLookup(DeclarationName Name, bool Operator,
                                SourceLocation Loc,

Modified: cfe/trunk/lib/ARCMigrate/Internals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Internals.h?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Internals.h (original)
+++ cfe/trunk/lib/ARCMigrate/Internals.h Thu May 31 19:10:47 2012
@@ -12,6 +12,7 @@
 
 #include "clang/ARCMigrate/ARCMT.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
 
 namespace clang {
   class Sema;
@@ -144,6 +145,7 @@
   Sema &SemaRef;
   TransformActions &TA;
   std::vector<SourceLocation> &ARCMTMacroLocs;
+  llvm::Optional<bool> EnableCFBridgeFns;
 
   MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode,
                 Sema &sema, TransformActions &TA,
@@ -157,6 +159,8 @@
   void setNSAllocReallocError(bool val) { MigOptions.NoNSAllocReallocError = val; }
   bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; }
   void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; }
+
+  bool CFBridgingFunctionsDefined();
 };
 
 static inline StringRef getARCMTMacroName() {

Modified: cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp Thu May 31 19:10:47 2012
@@ -12,7 +12,7 @@
 // A cast of non-objc pointer to an objc one is checked. If the non-objc pointer
 // is from a file-level variable, __bridge cast is used to convert it.
 // For the result of a function call that we know is +1/+0,
-// __bridge/__bridge_transfer is used.
+// __bridge/CFBridgingRelease is used.
 //
 //  NSString *str = (NSString *)kUTTypePlainText;
 //  str = b ? kUTTypeRTF : kUTTypePlainText;
@@ -21,8 +21,8 @@
 // ---->
 //  NSString *str = (__bridge NSString *)kUTTypePlainText;
 //  str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
-// NSString *_uuidString = (__bridge_transfer NSString *)
-//                               CFUUIDCreateString(kCFAllocatorDefault, _uuid);
+// NSString *_uuidString = (NSString *)
+//            CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid));
 //
 // For a C pointer to ObjC, for casting 'self', __bridge is used.
 //
@@ -191,22 +191,42 @@
     TA.clearDiagnostic(diag::err_arc_mismatched_cast,
                        diag::err_arc_cast_requires_bridge,
                        E->getLocStart());
-    if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
-      TA.insertAfterToken(CCE->getLParenLoc(), bridge);
-    } else {
-      SourceLocation insertLoc = E->getSubExpr()->getLocStart();
-      SmallString<128> newCast;
-      newCast += '(';
-      newCast += bridge;
-      newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
-      newCast += ')';
-
-      if (isa<ParenExpr>(E->getSubExpr())) {
-        TA.insert(insertLoc, newCast.str());
+    if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) {
+      if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
+        TA.insertAfterToken(CCE->getLParenLoc(), bridge);
       } else {
+        SourceLocation insertLoc = E->getSubExpr()->getLocStart();
+        SmallString<128> newCast;
         newCast += '(';
-        TA.insert(insertLoc, newCast.str());
-        TA.insertAfterToken(E->getLocEnd(), ")");
+        newCast += bridge;
+        newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
+        newCast += ')';
+
+        if (isa<ParenExpr>(E->getSubExpr())) {
+          TA.insert(insertLoc, newCast.str());
+        } else {
+          newCast += '(';
+          TA.insert(insertLoc, newCast.str());
+          TA.insertAfterToken(E->getLocEnd(), ")");
+        }
+      }
+    } else {
+      assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained);
+      StringRef cfBridging;
+      if (Kind == OBC_BridgeTransfer)
+        cfBridging = "CFBridgingRelease";
+      else
+        cfBridging = "CFBridgingRetain";
+
+      Expr *WrapE = E->getSubExpr();
+      SourceLocation insertLoc = WrapE->getLocStart();
+      if (isa<ParenExpr>(WrapE)) {
+        TA.insert(insertLoc, cfBridging);
+      } else {
+        std::string withParens = cfBridging;
+        withParens += '(';
+        TA.insert(insertLoc, withParens);
+        TA.insertAfterToken(WrapE->getLocEnd(), ")");
       }
     }
   }

Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Thu May 31 19:10:47 2012
@@ -10,6 +10,7 @@
 #include "Transforms.h"
 #include "Internals.h"
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/Sema.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Lexer.h"
@@ -25,6 +26,13 @@
 
 ASTTraverser::~ASTTraverser() { }
 
+bool MigrationPass::CFBridgingFunctionsDefined() {
+  if (!EnableCFBridgeFns.hasValue())
+    EnableCFBridgeFns = SemaRef.isKnownName("CFBridgingRetain") &&
+                        SemaRef.isKnownName("CFBridgingRelease");
+  return *EnableCFBridgeFns;
+}
+
 //===----------------------------------------------------------------------===//
 // Helpers.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu May 31 19:10:47 2012
@@ -2771,11 +2771,12 @@
   };
 }
 
-static bool
-KnownName(Sema &S, const char *name) {
-  LookupResult R(S, &S.Context.Idents.get(name), SourceLocation(),
+bool Sema::isKnownName(StringRef name) {
+  if (name.empty())
+    return false;
+  LookupResult R(*this, &Context.Idents.get(name), SourceLocation(),
                  Sema::LookupOrdinaryName);
-  return S.LookupName(R, S.TUScope, false);
+  return LookupName(R, TUScope, false);
 }
 
 static void addFixitForObjCARCConversion(Sema &S,
@@ -2884,7 +2885,7 @@
       << castType
       << castRange
       << castExpr->getSourceRange();
-    bool br = KnownName(S, "CFBridgingRelease");
+    bool br = S.isKnownName("CFBridgingRelease");
     {
       DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
@@ -2903,7 +2904,7 @@
     
   // Bridge from a CF type to an ARC type.
   if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
-    bool br = KnownName(S, "CFBridgingRetain");
+    bool br = S.isKnownName("CFBridgingRetain");
     S.Diag(loc, diag::err_arc_cast_requires_bridge)
       << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit
       << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
@@ -3156,7 +3157,7 @@
       break;
       
     case OBC_BridgeRetained: {
-      bool br = KnownName(*this, "CFBridgingRelease");
+      bool br = isKnownName("CFBridgingRelease");
       Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
         << 2
         << FromType
@@ -3199,7 +3200,7 @@
       break;
       
     case OBC_BridgeTransfer: {
-      bool br = KnownName(*this, "CFBridgingRetain");
+      bool br = isKnownName("CFBridgingRetain");
       Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
         << (FromType->isBlockPointerType()? 1 : 0)
         << FromType

Modified: cfe/trunk/test/ARCMT/Common.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/Common.h?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/Common.h (original)
+++ cfe/trunk/test/ARCMT/Common.h Thu May 31 19:10:47 2012
@@ -6,6 +6,7 @@
 
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
 #define CF_CONSUMED __attribute__((cf_consumed))
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 
 #define NS_INLINE static __inline__ __attribute__((always_inline))
 #define nil ((void*) 0)
@@ -21,7 +22,7 @@
 
 typedef const void * CFTypeRef;
 CFTypeRef CFRetain(CFTypeRef cf);
-id CFBridgingRelease(CFTypeRef CF_CONSUMED X);
+CFTypeRef CFMakeCollectable(CFTypeRef cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
 
 NS_INLINE NS_RETURNS_RETAINED id NSMakeCollectable(CFTypeRef CF_CONSUMED cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
 
@@ -79,3 +80,25 @@
 
 void _dispatch_object_validate(dispatch_object_t object);
 void _xpc_object_validate(xpc_object_t object);
+
+#if __has_feature(objc_arc)
+
+NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) {
+    return (__bridge_retained CFTypeRef)X;
+}
+
+NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) {
+    return (__bridge_transfer id)X;
+}
+
+#else
+
+NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) {
+    return X ? CFRetain((CFTypeRef)X) : NULL;
+}
+
+NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) {
+    return [(id)CFMakeCollectable(X) autorelease];
+}
+
+#endif

Modified: cfe/trunk/test/ARCMT/autoreleases.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/autoreleases.m.result?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/autoreleases.m.result (original)
+++ cfe/trunk/test/ARCMT/autoreleases.m.result Thu May 31 19:10:47 2012
@@ -35,7 +35,7 @@
   _prop = newVal;
 }
 -(void) setProp2:(CFTypeRef) newVal {
-  _prop = (__bridge_transfer id)CFRetain(newVal);
+  _prop = (id)CFBridgingRelease(CFRetain(newVal));
 }
 
 -(id) xpc_prop {

Modified: cfe/trunk/test/ARCMT/nonobjc-to-objc-cast.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/nonobjc-to-objc-cast.m.result?rev=157785&r1=157784&r2=157785&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/nonobjc-to-objc-cast.m.result (original)
+++ cfe/trunk/test/ARCMT/nonobjc-to-objc-cast.m.result Thu May 31 19:10:47 2012
@@ -28,9 +28,9 @@
   str = (NSString *)p; // no change.
 
   CFUUIDRef   _uuid;
-  NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
-  _uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
-  _uuidString = (__bridge_transfer NSString *)(CFRetain(_uuid));
+  NSString *_uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid));
+  _uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid));
+  _uuidString = CFBridgingRelease(CFRetain(_uuid));
 }
 
 @implementation NSString (StrExt)
@@ -47,16 +47,16 @@
   CFStringRef ref = (__bridge CFStringRef)([s string]);
   ref = (__bridge CFStringRef)[s string];
   ref = (__bridge CFStringRef)(s.string);
-  ref = (__bridge_retained CFStringRef)([NSString new]);
-  ref = (__bridge_retained CFStringRef)([s newString]);
-  ref = (__bridge_retained CFStringRef)[NSString new];
-  ref = (__bridge_retained CFStringRef)([[NSString alloc] init]);
-  ref = (__bridge_retained CFStringRef)([s string]);
-  ref = (__bridge_retained CFStringRef)[s string];
-  ref = (__bridge_retained CFTypeRef)([s string]);
-  ref = (__bridge_retained CFTypeRef)(s);
-  ref = (__bridge_retained CFStringRef)(s);
+  ref = CFBridgingRetain([NSString new]);
+  ref = CFBridgingRetain([s newString]);
+  ref = (CFStringRef)CFBridgingRetain([NSString new]);
+  ref = CFBridgingRetain([[NSString alloc] init]);
+  ref = CFBridgingRetain([s string]);
+  ref = (CFStringRef)CFBridgingRetain([s string]);
+  ref = CFBridgingRetain([s string]);
+  ref = CFBridgingRetain(s);
+  ref = CFBridgingRetain(s);
 
-  consumeParam((__bridge_retained CFStringRef)s);
-  consumeParam((__bridge_retained CFStringRef)(s));
+  consumeParam((CFStringRef)CFBridgingRetain(s));
+  consumeParam(CFBridgingRetain(s));
 }





More information about the cfe-commits mailing list