[arcmt] Remove rewriteAllocCopyWithZone transformation; not needed anymore.

llvm-svn: 133762
This commit is contained in:
Argyrios Kyrtzidis 2011-06-23 21:21:28 +00:00
parent 63b45fef45
commit 795550691e
7 changed files with 0 additions and 404 deletions

View File

@ -1,223 +0,0 @@
//===--- TransAllocCopyWithZone.cpp - Tranformations to ARC mode ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// rewriteAllocCopyWithZone:
//
// Calls to +allocWithZone/-copyWithZone/-mutableCopyWithZone are changed to
// +alloc/-copy/-mutableCopy if we can safely remove the given parameter.
//
// Foo *foo1 = [[Foo allocWithZone:[self zone]] init];
// ---->
// Foo *foo1 = [[Foo alloc] init];
//
//===----------------------------------------------------------------------===//
#include "Transforms.h"
#include "Internals.h"
#include "clang/Sema/SemaDiagnostic.h"
using namespace clang;
using namespace arcmt;
using namespace trans;
using llvm::StringRef;
namespace {
class AllocCopyWithZoneRewriter :
public RecursiveASTVisitor<AllocCopyWithZoneRewriter> {
Decl *Dcl;
Stmt *Body;
MigrationPass &Pass;
Selector allocWithZoneSel;
Selector copyWithZoneSel;
Selector mutableCopyWithZoneSel;
Selector zoneSel;
IdentifierInfo *NSZoneII;
std::vector<DeclStmt *> NSZoneVars;
std::vector<Expr *> Removals;
public:
AllocCopyWithZoneRewriter(Decl *D, MigrationPass &pass)
: Dcl(D), Body(0), Pass(pass) {
SelectorTable &sels = pass.Ctx.Selectors;
IdentifierTable &ids = pass.Ctx.Idents;
allocWithZoneSel = sels.getUnarySelector(&ids.get("allocWithZone"));
copyWithZoneSel = sels.getUnarySelector(&ids.get("copyWithZone"));
mutableCopyWithZoneSel = sels.getUnarySelector(
&ids.get("mutableCopyWithZone"));
zoneSel = sels.getNullarySelector(&ids.get("zone"));
NSZoneII = &ids.get("_NSZone");
}
void transformBody(Stmt *body) {
Body = body;
// Don't change allocWithZone/copyWithZone messages inside
// custom implementations of such methods, it can lead to infinite loops.
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Dcl)) {
Selector sel = MD->getSelector();
if (sel == allocWithZoneSel ||
sel == copyWithZoneSel ||
sel == mutableCopyWithZoneSel ||
sel == zoneSel)
return;
}
TraverseStmt(body);
}
~AllocCopyWithZoneRewriter() {
for (std::vector<DeclStmt *>::reverse_iterator
I = NSZoneVars.rbegin(), E = NSZoneVars.rend(); I != E; ++I) {
DeclStmt *DS = *I;
DeclGroupRef group = DS->getDeclGroup();
std::vector<Expr *> varRemovals = Removals;
bool areAllVarsUnused = true;
for (std::reverse_iterator<DeclGroupRef::iterator>
DI(group.end()), DE(group.begin()); DI != DE; ++DI) {
VarDecl *VD = cast<VarDecl>(*DI);
if (isNSZoneVarUsed(VD, varRemovals)) {
areAllVarsUnused = false;
break;
}
varRemovals.push_back(VD->getInit());
}
if (areAllVarsUnused) {
Transaction Trans(Pass.TA);
clearUnavailableDiags(DS);
Pass.TA.removeStmt(DS);
Removals.swap(varRemovals);
}
}
}
bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
if (!isAllocCopyWithZoneCall(E))
return true;
Expr *arg = E->getArg(0);
if (paramToAllocWithZoneHasSideEffects(arg))
return true;
Pass.TA.startTransaction();
clearUnavailableDiags(arg);
Pass.TA.clearDiagnostic(diag::err_unavailable_message,
E->getReceiverRange().getBegin());
Pass.TA.remove(SourceRange(E->getSelectorLoc(), arg->getLocEnd()));
StringRef rewrite;
if (E->getSelector() == allocWithZoneSel)
rewrite = "alloc";
else if (E->getSelector() == copyWithZoneSel)
rewrite = "copy";
else {
assert(E->getSelector() == mutableCopyWithZoneSel);
rewrite = "mutableCopy";
}
Pass.TA.insert(E->getSelectorLoc(), rewrite);
bool failed = Pass.TA.commitTransaction();
if (!failed)
Removals.push_back(arg);
return true;
}
bool VisitDeclStmt(DeclStmt *DS) {
DeclGroupRef group = DS->getDeclGroup();
if (group.begin() == group.end())
return true;
for (DeclGroupRef::iterator
DI = group.begin(), DE = group.end(); DI != DE; ++DI)
if (!isRemovableNSZoneVar(*DI))
return true;
NSZoneVars.push_back(DS);
return true;
}
private:
bool isRemovableNSZoneVar(Decl *D) {
if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (isNSZone(VD->getType()))
return !paramToAllocWithZoneHasSideEffects(VD->getInit());
}
return false;
}
bool isNSZone(RecordDecl *RD) {
return RD && RD->getIdentifier() == NSZoneII;
}
bool isNSZone(QualType Ty) {
QualType pointee = Ty->getPointeeType();
if (pointee.isNull())
return false;
if (const RecordType *recT = pointee->getAsStructureType())
return isNSZone(recT->getDecl());
return false;
}
bool isNSZoneVarUsed(VarDecl *D, std::vector<Expr *> &removals) {
ExprSet refs;
collectRefs(D, Body, refs);
clearRefsIn(removals.begin(), removals.end(), refs);
return !refs.empty();
}
bool isAllocCopyWithZoneCall(ObjCMessageExpr *E) {
if (E->getNumArgs() == 1 &&
E->getSelector() == allocWithZoneSel &&
(E->isClassMessage() ||
Pass.TA.hasDiagnostic(diag::err_unavailable_message,
E->getReceiverRange().getBegin())))
return true;
return E->isInstanceMessage() &&
E->getNumArgs() == 1 &&
(E->getSelector() == copyWithZoneSel ||
E->getSelector() == mutableCopyWithZoneSel);
}
bool isZoneCall(ObjCMessageExpr *E) {
return E->isInstanceMessage() &&
E->getNumArgs() == 0 &&
E->getSelector() == zoneSel;
}
bool paramToAllocWithZoneHasSideEffects(Expr *E) {
if (!hasSideEffects(E, Pass.Ctx))
return false;
E = E->IgnoreParenCasts();
ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
if (!ME)
return true;
if (!isZoneCall(ME))
return true;
return hasSideEffects(ME->getInstanceReceiver(), Pass.Ctx);
}
void clearUnavailableDiags(Stmt *S) {
if (S)
Pass.TA.clearDiagnostic(diag::err_unavailable,
diag::err_unavailable_message,
S->getSourceRange());
}
};
} // end anonymous namespace
void trans::rewriteAllocCopyWithZone(MigrationPass &pass) {
BodyTransform<AllocCopyWithZoneRewriter> trans(pass);
trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
}

View File

@ -218,7 +218,6 @@ static void independentTransforms(MigrationPass &pass) {
makeAssignARCSafe(pass); makeAssignARCSafe(pass);
rewriteUnbridgedCasts(pass); rewriteUnbridgedCasts(pass);
rewriteBlockObjCVariable(pass); rewriteBlockObjCVariable(pass);
rewriteAllocCopyWithZone(pass);
} }
std::vector<TransformFn> arcmt::getAllTransformations() { std::vector<TransformFn> arcmt::getAllTransformations() {

View File

@ -31,7 +31,6 @@ namespace trans {
void rewriteAutoreleasePool(MigrationPass &pass); void rewriteAutoreleasePool(MigrationPass &pass);
void rewriteUnbridgedCasts(MigrationPass &pass); void rewriteUnbridgedCasts(MigrationPass &pass);
void rewriteAllocCopyWithZone(MigrationPass &pass);
void makeAssignARCSafe(MigrationPass &pass); void makeAssignARCSafe(MigrationPass &pass);
void removeRetainReleaseDealloc(MigrationPass &pass); void removeRetainReleaseDealloc(MigrationPass &pass);
void removeZeroOutPropsInDealloc(MigrationPass &pass); void removeZeroOutPropsInDealloc(MigrationPass &pass);

View File

@ -4,7 +4,6 @@
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE
#endif #endif
typedef struct _NSZone NSZone;
typedef int BOOL; typedef int BOOL;
typedef unsigned NSUInteger; typedef unsigned NSUInteger;
typedef int int32_t; typedef int int32_t;
@ -18,23 +17,12 @@ typedef unsigned char UChar;
- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
@end
@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(NSZone *)zone;
@end @end
@interface NSObject <NSObject> {} @interface NSObject <NSObject> {}
- (id)init; - (id)init;
+ (id)new; + (id)new;
+ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (id)alloc; + (id)alloc;
- (void)dealloc; - (void)dealloc;
@ -42,13 +30,8 @@ typedef unsigned char UChar;
- (id)copy; - (id)copy;
- (id)mutableCopy; - (id)mutableCopy;
+ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
@end @end
extern void NSRecycleZone(NSZone *zone);
NS_AUTOMATED_REFCOUNT_UNAVAILABLE NS_AUTOMATED_REFCOUNT_UNAVAILABLE
@interface NSAutoreleasePool : NSObject { @interface NSAutoreleasePool : NSObject {
@private @private

View File

@ -1,80 +0,0 @@
// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s
#if __has_feature(objc_arr)
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
#else
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE
#endif
typedef struct _NSZone NSZone;
typedef int BOOL;
typedef unsigned NSUInteger;
@protocol NSObject
- (BOOL)isEqual:(id)object;
- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{marked unavailable here}}
@end
@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(NSZone *)zone;
@end
@interface NSObject <NSObject> {}
- (id)init;
+ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note 2 {{marked unavailable here}}
+ (id)alloc;
- (void)dealloc;
- (void)finalize;
- (id)copy;
- (id)mutableCopy;
+ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
@end
extern void NSRecycleZone(NSZone *zone);
id IhaveSideEffect();
@interface Foo : NSObject <NSCopying, NSMutableCopying> {
id bar;
}
@property (retain) id bar;
-(id)test:(id)obj;
@end
@implementation Foo
@synthesize bar;
-(id)test:(id)obj {
Foo *foo1 = [[Foo allocWithZone:[self zone]] init];
Foo *foo2 = [[Foo allocWithZone:[super zone]] init];
Foo *foo3 = [[Foo allocWithZone:[IhaveSideEffect() zone]] init]; // expected-error {{not available}}
NSRecycleZone([self zone]); // expected-error {{not available}}
foo1 = [foo1 copyWithZone:[self zone]];
foo2 = [foo1 copyWithZone:[super zone]];
foo3 = [foo1 copyWithZone:[IhaveSideEffect() zone]];
foo1 = [foo1 mutableCopyWithZone:[self zone]];
return foo1;
}
+(id)allocWithZone:(NSZone *)zone {
return [super allocWithZone:zone]; // expected-error {{not available in automatic reference counting mode}}
}
@end

View File

@ -1,42 +0,0 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: diff %t %s.result
#include "Common.h"
@interface Foo : NSObject <NSCopying, NSMutableCopying> {
id bar;
}
@property (retain) id bar;
-(id)test:(NSZone *)z;
@end
@implementation Foo
@synthesize bar;
+(id)class_test:(NSZone *)z {
return [self allocWithZone:z];
}
-(id)test:(NSZone *)z {
NSZone *z2 = [self zone], *z3 = z2;
NSZone *z4 = z3;
Foo *foo1 = [[Foo allocWithZone:[self zone]] init];
Foo *foo2 = [[Foo allocWithZone:[super zone]] init];
Foo *foo3 = [[Foo allocWithZone:z] init];
Foo *foo4 = [[Foo allocWithZone:z2] init];
Foo *foo5 = [[Foo allocWithZone:z3] init];
Foo *foo6 = [[Foo allocWithZone:z4] init];
foo1 = [foo1 copyWithZone:[self zone]];
foo2 = [foo1 copyWithZone:[super zone]];
foo3 = [foo1 copyWithZone:z];
foo1 = [foo1 mutableCopyWithZone:[self zone]];
return foo1;
}
@end

View File

@ -1,40 +0,0 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: diff %t %s.result
#include "Common.h"
@interface Foo : NSObject <NSCopying, NSMutableCopying> {
id bar;
}
@property (retain) id bar;
-(id)test:(NSZone *)z;
@end
@implementation Foo
@synthesize bar;
+(id)class_test:(NSZone *)z {
return [self alloc];
}
-(id)test:(NSZone *)z {
Foo *foo1 = [[Foo alloc] init];
Foo *foo2 = [[Foo alloc] init];
Foo *foo3 = [[Foo alloc] init];
Foo *foo4 = [[Foo alloc] init];
Foo *foo5 = [[Foo alloc] init];
Foo *foo6 = [[Foo alloc] init];
foo1 = [foo1 copy];
foo2 = [foo1 copy];
foo3 = [foo1 copy];
foo1 = [foo1 mutableCopy];
return foo1;
}
@end