Skip to content

Commit 0a9d652

Browse files
committed
[arcmt] Always add '__bridge' cast when 'self' is cast to a C pointer. rdar://9644061
llvm-svn: 133480
1 parent 91da589 commit 0a9d652

File tree

3 files changed

+45
-37
lines changed

3 files changed

+45
-37
lines changed

clang/lib/ARCMigrate/Transforms.cpp

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,11 @@ namespace {
453453

454454
class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
455455
MigrationPass &Pass;
456+
IdentifierInfo *SelfII;
456457
public:
457-
NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) { }
458+
NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) {
459+
SelfII = &Pass.Ctx.Idents.get("self");
460+
}
458461

459462
bool VisitCastExpr(CastExpr *E) {
460463
if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
@@ -538,6 +541,10 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
538541
}
539542

540543
void castToObjCObject(CastExpr *E, bool retained) {
544+
rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
545+
}
546+
547+
void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
541548
TransformActions &TA = Pass.TA;
542549

543550
// We will remove the compiler diagnostic.
@@ -546,18 +553,27 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
546553
E->getLocStart()))
547554
return;
548555

556+
StringRef bridge;
557+
switch(Kind) {
558+
case OBC_Bridge:
559+
bridge = "__bridge "; break;
560+
case OBC_BridgeTransfer:
561+
bridge = "__bridge_transfer "; break;
562+
case OBC_BridgeRetained:
563+
bridge = "__bridge_retained "; break;
564+
}
565+
549566
Transaction Trans(TA);
550567
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
551568
diag::err_arc_cast_requires_bridge,
552569
E->getLocStart());
553570
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
554-
TA.insertAfterToken(CCE->getLParenLoc(), retained ? "__bridge_transfer "
555-
: "__bridge ");
571+
TA.insertAfterToken(CCE->getLParenLoc(), bridge);
556572
} else {
557573
SourceLocation insertLoc = E->getSubExpr()->getLocStart();
558574
llvm::SmallString<128> newCast;
559575
newCast += '(';
560-
newCast += retained ? "__bridge_transfer " : "__bridge ";
576+
newCast += bridge;
561577
newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
562578
newCast += ')';
563579

@@ -572,36 +588,16 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
572588
}
573589

574590
void transformObjCToNonObjCCast(CastExpr *E) {
575-
// FIXME: Handle these casts.
576-
return;
577-
#if 0
578-
TransformActions &TA = Pass.TA;
579-
580-
// We will remove the compiler diagnostic.
581-
if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
582-
diag::err_arc_cast_requires_bridge,
583-
E->getLocStart()))
584-
return;
585-
586-
Transaction Trans(TA);
587-
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
588-
diag::err_arc_cast_requires_bridge,
589-
E->getLocStart());
590-
591-
assert(!E->getType()->isObjCObjectPointerType());
591+
if (isSelf(E->getSubExpr()))
592+
return rewriteToBridgedCast(E, OBC_Bridge);
593+
}
592594

593-
bool shouldCast = !isa<CStyleCastExpr>(E) &&
594-
!E->getType()->getPointeeType().isConstQualified();
595-
SourceLocation loc = E->getSubExpr()->getLocStart();
596-
if (isa<ParenExpr>(E->getSubExpr())) {
597-
TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer"
598-
: "objc_unretainedPointer");
599-
} else {
600-
TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer("
601-
: "objc_unretainedPointer(");
602-
TA.insertAfterToken(E->getLocEnd(), ")");
603-
}
604-
#endif
595+
bool isSelf(Expr *E) {
596+
E = E->IgnoreParenLValueCasts();
597+
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
598+
if (DRE->getDecl()->getIdentifier() == SelfII)
599+
return true;
600+
return false;
605601
}
606602

607603
static bool isGlobalVar(Expr *E) {

clang/test/ARCMT/nonobjc-to-objc-cast.m

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ void f(BOOL b, id p) {
2424
str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
2525
str = (NSString *)p; // no change.
2626

27-
// FIXME: Add objc -> c examples that we can handle.
28-
2927
CFUUIDRef _uuid;
3028
NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
3129
_uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease];
3230
}
31+
32+
@implementation NSString (StrExt)
33+
- (NSString *)stringEscapedAsURI {
34+
CFStringRef str = (CFStringRef)self;
35+
CFStringRef str2 = self;
36+
return self;
37+
}
38+
@end

clang/test/ARCMT/nonobjc-to-objc-cast.m.result

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ void f(BOOL b, id p) {
2424
str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
2525
str = (NSString *)p; // no change.
2626

27-
// FIXME: Add objc -> c examples that we can handle.
28-
2927
CFUUIDRef _uuid;
3028
NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
3129
_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
3230
}
31+
32+
@implementation NSString (StrExt)
33+
- (NSString *)stringEscapedAsURI {
34+
CFStringRef str = (__bridge CFStringRef)self;
35+
CFStringRef str2 = (__bridge CFStringRef)(self);
36+
return self;
37+
}
38+
@end

0 commit comments

Comments
 (0)