forked from OSchip/llvm-project
[arcmt] Always add '__bridge' cast when 'self' is cast to a C pointer. rdar://9644061
llvm-svn: 133480
This commit is contained in:
parent
91da589d7e
commit
0a9d652331
|
@ -453,8 +453,11 @@ namespace {
|
||||||
|
|
||||||
class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
|
class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
|
||||||
MigrationPass &Pass;
|
MigrationPass &Pass;
|
||||||
|
IdentifierInfo *SelfII;
|
||||||
public:
|
public:
|
||||||
NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) { }
|
NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) {
|
||||||
|
SelfII = &Pass.Ctx.Idents.get("self");
|
||||||
|
}
|
||||||
|
|
||||||
bool VisitCastExpr(CastExpr *E) {
|
bool VisitCastExpr(CastExpr *E) {
|
||||||
if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
|
if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
|
||||||
|
@ -538,6 +541,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void castToObjCObject(CastExpr *E, bool retained) {
|
void castToObjCObject(CastExpr *E, bool retained) {
|
||||||
|
rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
|
||||||
TransformActions &TA = Pass.TA;
|
TransformActions &TA = Pass.TA;
|
||||||
|
|
||||||
// We will remove the compiler diagnostic.
|
// We will remove the compiler diagnostic.
|
||||||
|
@ -546,18 +553,27 @@ private:
|
||||||
E->getLocStart()))
|
E->getLocStart()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
StringRef bridge;
|
||||||
|
switch(Kind) {
|
||||||
|
case OBC_Bridge:
|
||||||
|
bridge = "__bridge "; break;
|
||||||
|
case OBC_BridgeTransfer:
|
||||||
|
bridge = "__bridge_transfer "; break;
|
||||||
|
case OBC_BridgeRetained:
|
||||||
|
bridge = "__bridge_retained "; break;
|
||||||
|
}
|
||||||
|
|
||||||
Transaction Trans(TA);
|
Transaction Trans(TA);
|
||||||
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
|
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
|
||||||
diag::err_arc_cast_requires_bridge,
|
diag::err_arc_cast_requires_bridge,
|
||||||
E->getLocStart());
|
E->getLocStart());
|
||||||
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
|
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
|
||||||
TA.insertAfterToken(CCE->getLParenLoc(), retained ? "__bridge_transfer "
|
TA.insertAfterToken(CCE->getLParenLoc(), bridge);
|
||||||
: "__bridge ");
|
|
||||||
} else {
|
} else {
|
||||||
SourceLocation insertLoc = E->getSubExpr()->getLocStart();
|
SourceLocation insertLoc = E->getSubExpr()->getLocStart();
|
||||||
llvm::SmallString<128> newCast;
|
llvm::SmallString<128> newCast;
|
||||||
newCast += '(';
|
newCast += '(';
|
||||||
newCast += retained ? "__bridge_transfer " : "__bridge ";
|
newCast += bridge;
|
||||||
newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
|
newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
|
||||||
newCast += ')';
|
newCast += ')';
|
||||||
|
|
||||||
|
@ -572,36 +588,16 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void transformObjCToNonObjCCast(CastExpr *E) {
|
void transformObjCToNonObjCCast(CastExpr *E) {
|
||||||
// FIXME: Handle these casts.
|
if (isSelf(E->getSubExpr()))
|
||||||
return;
|
return rewriteToBridgedCast(E, OBC_Bridge);
|
||||||
#if 0
|
}
|
||||||
TransformActions &TA = Pass.TA;
|
|
||||||
|
|
||||||
// We will remove the compiler diagnostic.
|
bool isSelf(Expr *E) {
|
||||||
if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
|
E = E->IgnoreParenLValueCasts();
|
||||||
diag::err_arc_cast_requires_bridge,
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
|
||||||
E->getLocStart()))
|
if (DRE->getDecl()->getIdentifier() == SelfII)
|
||||||
return;
|
return true;
|
||||||
|
return false;
|
||||||
Transaction Trans(TA);
|
|
||||||
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
|
|
||||||
diag::err_arc_cast_requires_bridge,
|
|
||||||
E->getLocStart());
|
|
||||||
|
|
||||||
assert(!E->getType()->isObjCObjectPointerType());
|
|
||||||
|
|
||||||
bool shouldCast = !isa<CStyleCastExpr>(E) &&
|
|
||||||
!E->getType()->getPointeeType().isConstQualified();
|
|
||||||
SourceLocation loc = E->getSubExpr()->getLocStart();
|
|
||||||
if (isa<ParenExpr>(E->getSubExpr())) {
|
|
||||||
TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer"
|
|
||||||
: "objc_unretainedPointer");
|
|
||||||
} else {
|
|
||||||
TA.insert(loc, shouldCast ? "(void*)objc_unretainedPointer("
|
|
||||||
: "objc_unretainedPointer(");
|
|
||||||
TA.insertAfterToken(E->getLocEnd(), ")");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isGlobalVar(Expr *E) {
|
static bool isGlobalVar(Expr *E) {
|
||||||
|
|
|
@ -24,9 +24,15 @@ void f(BOOL b, id p) {
|
||||||
str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
|
str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
|
||||||
str = (NSString *)p; // no change.
|
str = (NSString *)p; // no change.
|
||||||
|
|
||||||
// FIXME: Add objc -> c examples that we can handle.
|
|
||||||
|
|
||||||
CFUUIDRef _uuid;
|
CFUUIDRef _uuid;
|
||||||
NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
||||||
_uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease];
|
_uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@implementation NSString (StrExt)
|
||||||
|
- (NSString *)stringEscapedAsURI {
|
||||||
|
CFStringRef str = (CFStringRef)self;
|
||||||
|
CFStringRef str2 = self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
|
@ -24,9 +24,15 @@ void f(BOOL b, id p) {
|
||||||
str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
|
str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
|
||||||
str = (NSString *)p; // no change.
|
str = (NSString *)p; // no change.
|
||||||
|
|
||||||
// FIXME: Add objc -> c examples that we can handle.
|
|
||||||
|
|
||||||
CFUUIDRef _uuid;
|
CFUUIDRef _uuid;
|
||||||
NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
||||||
_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@implementation NSString (StrExt)
|
||||||
|
- (NSString *)stringEscapedAsURI {
|
||||||
|
CFStringRef str = (__bridge CFStringRef)self;
|
||||||
|
CFStringRef str2 = (__bridge CFStringRef)(self);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue