diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-05-23 21:50:04 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-05-23 21:50:04 +0000 |
commit | 1b8fbd3601e009803565e74d2ec54abecb5cbf73 (patch) | |
tree | e2078743be9ffbdc3ed4eac0e8b607984d4a93d8 /lib/ARCMigrate/Transforms.cpp | |
parent | f0fab767c8c272fc77699e82fd581ddf4d9d71fa (diff) |
[arcmt] Remove an unused -autorelease, without failing with error, for this
idiom that is used commonly in setters:
[backingValue autorelease];
backingValue = [newValue retain]; // in general a +1 assign
rdar://9914061
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157347 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate/Transforms.cpp')
-rw-r--r-- | lib/ARCMigrate/Transforms.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 50bea95f12..24b650561c 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -14,6 +14,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/Lex/Lexer.h" #include "clang/Basic/SourceManager.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/DenseSet.h" #include <map> @@ -56,6 +57,47 @@ bool trans::canApplyWeak(ASTContext &Ctx, QualType type, return true; } +bool trans::isPlusOneAssign(const BinaryOperator *E) { + if (E->getOpcode() != BO_Assign) + return false; + + if (const ObjCMessageExpr * + ME = dyn_cast<ObjCMessageExpr>(E->getRHS()->IgnoreParenCasts())) + if (ME->getMethodFamily() == OMF_retain) + return true; + + if (const CallExpr * + callE = dyn_cast<CallExpr>(E->getRHS()->IgnoreParenCasts())) { + if (const FunctionDecl *FD = callE->getDirectCallee()) { + if (FD->getAttr<CFReturnsRetainedAttr>()) + return true; + + if (FD->isGlobal() && + FD->getIdentifier() && + FD->getParent()->isTranslationUnit() && + FD->getLinkage() == ExternalLinkage && + ento::cocoa::isRefType(callE->getType(), "CF", + FD->getIdentifier()->getName())) { + StringRef fname = FD->getIdentifier()->getName(); + if (fname.endswith("Retain") || + fname.find("Create") != StringRef::npos || + fname.find("Copy") != StringRef::npos) { + return true; + } + } + } + } + + const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getRHS()); + while (implCE && implCE->getCastKind() == CK_BitCast) + implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); + + if (implCE && implCE->getCastKind() == CK_ARCConsumeObject) + return true; + + return false; +} + /// \brief 'Loc' is the end of a statement range. This returns the location /// immediately after the semicolon following the statement. /// If no semicolon is found or the location is inside a macro, the returned |