diff options
Diffstat (limited to 'lib/ARCMigrate/TransAPIUses.cpp')
-rw-r--r-- | lib/ARCMigrate/TransAPIUses.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp index 228ca3e091..781ad7742d 100644 --- a/lib/ARCMigrate/TransAPIUses.cpp +++ b/lib/ARCMigrate/TransAPIUses.cpp @@ -9,17 +9,19 @@ // // checkAPIUses: // -// Emits error with some API uses that are not safe in ARC mode: +// Emits error/fix with some API uses that are obsolete or not safe in ARC mode: // // - NSInvocation's [get/set]ReturnValue and [get/set]Argument are only safe // with __unsafe_unretained objects. // - When a NSData's 'bytes' family of methods are used on a local var, // add __attribute__((objc_precise_lifetime)) to make it safer. +// - Calling -zone gets replaced with 'nil'. // //===----------------------------------------------------------------------===// #include "Transforms.h" #include "Internals.h" +#include "clang/Sema/SemaDiagnostic.h" using namespace clang; using namespace arcmt; @@ -35,6 +37,8 @@ class APIChecker : public RecursiveASTVisitor<APIChecker> { Selector bytesSel, getBytesSel, getBytesLengthSel, getBytesRangeSel; + Selector zoneSel; + llvm::DenseSet<VarDecl *> ChangedNSDataVars; public: APIChecker(MigrationPass &pass) : Pass(pass) { @@ -57,9 +61,12 @@ public: getBytesLengthSel = sels.getSelector(2, selIds); selIds[1] = &ids.get("range"); getBytesRangeSel = sels.getSelector(2, selIds); + + zoneSel = sels.getNullarySelector(&ids.get("zone")); } bool VisitObjCMessageExpr(ObjCMessageExpr *E) { + // NSInvocation. if (E->isInstanceMessage() && E->getReceiverInterface() && E->getReceiverInterface()->getName() == "NSInvocation") { @@ -91,6 +98,7 @@ public: return true; } + // NSData. if (E->isInstanceMessage() && E->getReceiverInterface() && E->getReceiverInterface()->getName() == "NSData" && @@ -111,6 +119,20 @@ public: } } + // -zone. + if (E->isInstanceMessage() && + E->getInstanceReceiver() && + E->getSelector() == zoneSel && + Pass.TA.hasDiagnostic(diag::err_unavailable, + diag::err_unavailable_message, + E->getInstanceReceiver()->getExprLoc())) { + // Calling -zone is meaningless in ARC, change it to nil. + Transaction Trans(Pass.TA); + Pass.TA.clearDiagnostic(diag::err_unavailable, + diag::err_unavailable_message, + E->getInstanceReceiver()->getExprLoc()); + Pass.TA.replace(E->getSourceRange(), getNilString(Pass.Ctx)); + } return true; } }; |