]> granicus.if.org Git - clang/commitdiff
[arcmt] Always add '__bridge' cast when 'self' is cast to a C pointer. rdar://9644061
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 20 Jun 2011 23:39:20 +0000 (23:39 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 20 Jun 2011 23:39:20 +0000 (23:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133480 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ARCMigrate/Transforms.cpp
test/ARCMT/nonobjc-to-objc-cast.m
test/ARCMT/nonobjc-to-objc-cast.m.result

index 0c9096296d0e08225a847a553bda4f4904d581e8..499c8f034c7984da3257a0f7c2e9b3fd064a55a8 100644 (file)
@@ -453,8 +453,11 @@ namespace {
 
 class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
   MigrationPass &Pass;
+  IdentifierInfo *SelfII;
 public:
-  NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) { }
+  NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) {
+    SelfII = &Pass.Ctx.Idents.get("self");
+  }
 
   bool VisitCastExpr(CastExpr *E) {
     if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
@@ -538,6 +541,10 @@ private:
   }
 
   void castToObjCObject(CastExpr *E, bool retained) {
+    rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
+  }
+
+  void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
     TransformActions &TA = Pass.TA;
 
     // We will remove the compiler diagnostic.
@@ -546,18 +553,27 @@ private:
                           E->getLocStart()))
       return;
 
+    StringRef bridge;
+    switch(Kind) {
+    case OBC_Bridge:
+      bridge = "__bridge "; break;
+    case OBC_BridgeTransfer:
+      bridge = "__bridge_transfer "; break;
+    case OBC_BridgeRetained:
+      bridge = "__bridge_retained "; break;
+    }
+
     Transaction Trans(TA);
     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(), retained ? "__bridge_transfer "
-                                                        : "__bridge ");
+      TA.insertAfterToken(CCE->getLParenLoc(), bridge);
     } else {
       SourceLocation insertLoc = E->getSubExpr()->getLocStart();
       llvm::SmallString<128> newCast;
       newCast += '(';
-      newCast +=  retained ? "__bridge_transfer " : "__bridge ";
+      newCast += bridge;
       newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
       newCast += ')';
 
@@ -572,36 +588,16 @@ private:
   }
 
   void transformObjCToNonObjCCast(CastExpr *E) {
-    // FIXME: Handle these casts.
-    return;
-#if 0
-    TransformActions &TA = Pass.TA;
-
-    // We will remove the compiler diagnostic.
-    if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
-                          diag::err_arc_cast_requires_bridge,
-                          E->getLocStart()))
-      return;
-
-    Transaction Trans(TA);
-    TA.clearDiagnostic(diag::err_arc_mismatched_cast,
-                              diag::err_arc_cast_requires_bridge,
-                              E->getLocStart());
-
-    assert(!E->getType()->isObjCObjectPointerType());
+    if (isSelf(E->getSubExpr()))
+      return rewriteToBridgedCast(E, OBC_Bridge);
+  }
 
-    bool shouldCast = !isa<CStyleCastExpr>(E) &&
-                      !E->getType()->getPointeeType().isConstQualified();
-    SourceLocation loc = E->getSubExpr()->getLocStart();
-    if (isa<ParenExpr>(E->getSubExpr())) {
-      TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer"
-                                : "objc_unretainedPointer");
-    } else {
-      TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer("
-                                : "objc_unretainedPointer(");
-      TA.insertAfterToken(E->getLocEnd(), ")");
-    }
-#endif
+  bool isSelf(Expr *E) {
+    E = E->IgnoreParenLValueCasts();
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+      if (DRE->getDecl()->getIdentifier() == SelfII)
+        return true;
+    return false;
   }
 
   static bool isGlobalVar(Expr *E) {
index 4ca47f2259fcd78a8eff649b003b89a1e1fa0452..4e1e293efbac77f9590534fd22881fbed1bbc20c 100644 (file)
@@ -24,9 +24,15 @@ void f(BOOL b, id p) {
   str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
   str = (NSString *)p; // no change.
 
-  // FIXME: Add objc -> c examples that we can handle.
-
   CFUUIDRef   _uuid;
   NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
   _uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease];
 }
+
+@implementation NSString (StrExt)
+- (NSString *)stringEscapedAsURI {
+  CFStringRef str = (CFStringRef)self;
+  CFStringRef str2 = self;
+  return self;
+}
+@end
index f7127b71927b48355e52bf39bcaef4013482ba1d..53dde7553d6dace9abfe9b69855995dc90c70de6 100644 (file)
@@ -24,9 +24,15 @@ void f(BOOL b, id p) {
   str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
   str = (NSString *)p; // no change.
 
-  // FIXME: Add objc -> c examples that we can handle.
-
   CFUUIDRef   _uuid;
   NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
   _uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
 }
+
+@implementation NSString (StrExt)
+- (NSString *)stringEscapedAsURI {
+  CFStringRef str = (__bridge CFStringRef)self;
+  CFStringRef str2 = (__bridge CFStringRef)(self);
+  return self;
+}
+@end