@@ -453,8 +453,11 @@ namespace {
453
453
454
454
class NonObjCToObjCCaster : public RecursiveASTVisitor <NonObjCToObjCCaster> {
455
455
MigrationPass &Pass;
456
+ IdentifierInfo *SelfII;
456
457
public:
457
- NonObjCToObjCCaster (MigrationPass &pass) : Pass(pass) { }
458
+ NonObjCToObjCCaster (MigrationPass &pass) : Pass(pass) {
459
+ SelfII = &Pass.Ctx .Idents .get (" self" );
460
+ }
458
461
459
462
bool VisitCastExpr (CastExpr *E) {
460
463
if (E->getCastKind () != CK_AnyPointerToObjCPointerCast
@@ -538,6 +541,10 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
538
541
}
539
542
540
543
void castToObjCObject (CastExpr *E, bool retained) {
544
+ rewriteToBridgedCast (E, retained ? OBC_BridgeTransfer : OBC_Bridge);
545
+ }
546
+
547
+ void rewriteToBridgedCast (CastExpr *E, ObjCBridgeCastKind Kind) {
541
548
TransformActions &TA = Pass.TA ;
542
549
543
550
// We will remove the compiler diagnostic.
@@ -546,18 +553,27 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
546
553
E->getLocStart ()))
547
554
return ;
548
555
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
+
549
566
Transaction Trans (TA);
550
567
TA.clearDiagnostic (diag::err_arc_mismatched_cast,
551
568
diag::err_arc_cast_requires_bridge,
552
569
E->getLocStart ());
553
570
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
554
- TA.insertAfterToken (CCE->getLParenLoc (), retained ? " __bridge_transfer "
555
- : " __bridge " );
571
+ TA.insertAfterToken (CCE->getLParenLoc (), bridge);
556
572
} else {
557
573
SourceLocation insertLoc = E->getSubExpr ()->getLocStart ();
558
574
llvm::SmallString<128 > newCast;
559
575
newCast += ' (' ;
560
- newCast += retained ? " __bridge_transfer " : " __bridge " ;
576
+ newCast += bridge ;
561
577
newCast += E->getType ().getAsString (Pass.Ctx .PrintingPolicy );
562
578
newCast += ' )' ;
563
579
@@ -572,36 +588,16 @@ class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
572
588
}
573
589
574
590
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
+ }
592
594
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 ;
605
601
}
606
602
607
603
static bool isGlobalVar (Expr *E) {
0 commit comments