diff options
Diffstat (limited to 'clang/lib/ARCMigrate')
-rw-r--r-- | clang/lib/ARCMigrate/Internals.h | 4 | ||||
-rw-r--r-- | clang/lib/ARCMigrate/TransUnbridgedCasts.cpp | 54 | ||||
-rw-r--r-- | clang/lib/ARCMigrate/Transforms.cpp | 8 |
3 files changed, 49 insertions, 17 deletions
diff --git a/clang/lib/ARCMigrate/Internals.h b/clang/lib/ARCMigrate/Internals.h index 59177c483ea..935fc9b5253 100644 --- a/clang/lib/ARCMigrate/Internals.h +++ b/clang/lib/ARCMigrate/Internals.h @@ -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 @@ public: 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 @@ public: 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() { diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp index 48437c795fa..37cebc9e3ad 100644 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -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 @@ private: 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(), ")"); } } } diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp index 24b650561c6..71598362b52 100644 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ b/clang/lib/ARCMigrate/Transforms.cpp @@ -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 @@ using namespace trans; ASTTraverser::~ASTTraverser() { } +bool MigrationPass::CFBridgingFunctionsDefined() { + if (!EnableCFBridgeFns.hasValue()) + EnableCFBridgeFns = SemaRef.isKnownName("CFBridgingRetain") && + SemaRef.isKnownName("CFBridgingRelease"); + return *EnableCFBridgeFns; +} + //===----------------------------------------------------------------------===// // Helpers. //===----------------------------------------------------------------------===// |