// rewriteToArrayLiteral.
//===----------------------------------------------------------------------===//
+/// \brief Adds an explicit cast to 'id' if the type is not objc object.
+static void objectifyExpr(const Expr *E, Commit &commit);
+
static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg,
const NSAPI &NS, Commit &commit) {
Selector Sel = Msg->getSelector();
if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObject)) {
if (Msg->getNumArgs() != 1)
return false;
+ objectifyExpr(Msg->getArg(0), commit);
SourceRange ArgRange = Msg->getArg(0)->getSourceRange();
commit.replaceWithInner(MsgRange, ArgRange);
commit.insertWrap("@[", ArgRange, "]");
if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
return false;
+ for (unsigned i = 0, e = Msg->getNumArgs() - 1; i != e; ++i)
+ objectifyExpr(Msg->getArg(i), commit);
+
if (Msg->getNumArgs() == 1) {
commit.replace(MsgRange, "@[]");
return true;
NSAPI::NSDict_dictionaryWithObjectForKey)) {
if (Msg->getNumArgs() != 2)
return false;
+
+ objectifyExpr(Msg->getArg(0), commit);
+ objectifyExpr(Msg->getArg(1), commit);
+
SourceRange ValRange = Msg->getArg(0)->getSourceRange();
SourceRange KeyRange = Msg->getArg(1)->getSourceRange();
// Insert key before the value.
}
for (unsigned i = 0; i < SentinelIdx; i += 2) {
+ objectifyExpr(Msg->getArg(i), commit);
+ objectifyExpr(Msg->getArg(i+1), commit);
+
SourceRange ValRange = Msg->getArg(i)->getSourceRange();
SourceRange KeyRange = Msg->getArg(i+1)->getSourceRange();
// Insert value after key.
}
return true;
}
+
+static bool castOperatorNeedsParens(const Expr *FullExpr) {
+ const Expr* Expr = FullExpr->IgnoreImpCasts();
+ if (isa<ArraySubscriptExpr>(Expr) ||
+ isa<CallExpr>(Expr) ||
+ isa<DeclRefExpr>(Expr) ||
+ isa<CastExpr>(Expr) ||
+ isa<CXXNewExpr>(Expr) ||
+ isa<CXXConstructExpr>(Expr) ||
+ isa<CXXDeleteExpr>(Expr) ||
+ isa<CXXNoexceptExpr>(Expr) ||
+ isa<CXXPseudoDestructorExpr>(Expr) ||
+ isa<CXXScalarValueInitExpr>(Expr) ||
+ isa<CXXThisExpr>(Expr) ||
+ isa<CXXTypeidExpr>(Expr) ||
+ isa<CXXUnresolvedConstructExpr>(Expr) ||
+ isa<ObjCMessageExpr>(Expr) ||
+ isa<ObjCPropertyRefExpr>(Expr) ||
+ isa<ObjCProtocolExpr>(Expr) ||
+ isa<MemberExpr>(Expr) ||
+ isa<ParenExpr>(FullExpr) ||
+ isa<ParenListExpr>(Expr) ||
+ isa<SizeOfPackExpr>(Expr) ||
+ isa<UnaryOperator>(Expr))
+ return false;
+
+ return true;
+}
+
+static void objectifyExpr(const Expr *E, Commit &commit) {
+ if (!E) return;
+
+ QualType T = E->getType();
+ if (T->isObjCObjectPointerType()) {
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() != CK_CPointerToObjCPointerCast)
+ return;
+ } else {
+ return;
+ }
+ } else if (!T->isPointerType()) {
+ return;
+ }
+
+ SourceRange Range = E->getSourceRange();
+ if (castOperatorNeedsParens(E))
+ commit.insertWrap("(", Range, ")");
+ commit.insertBefore(Range.getBegin(), "(id)");
+}
// RUN: rm -rf %t
// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
typedef signed char BOOL;
#define nil ((void*) 0)
+typedef const struct __CFString * CFStringRef;
+
@interface NSObject
+ (id)alloc;
@end
o = [*parr objectAtIndex:2];
}
@end
+
+extern const CFStringRef globStr;
+
+void test1(NSString *str) {
+ NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: str, globStr, nil];
+ dict = [NSDictionary dictionaryWithObjectsAndKeys: globStr, str, nil];
+ dict = [NSDictionary dictionaryWithObject:str forKey:globStr];
+ dict = [NSDictionary dictionaryWithObject:globStr forKey:str];
+
+ NSArray *arr = [NSArray arrayWithObjects: globStr, globStr, nil];
+ arr = [NSArray arrayWithObjects: str, globStr, nil];
+ arr = [NSArray arrayWithObjects: globStr, str, nil];
+ arr = [NSArray arrayWithObject:globStr];
+}
// RUN: rm -rf %t
// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
typedef signed char BOOL;
#define nil ((void*) 0)
+typedef const struct __CFString * CFStringRef;
+
@interface NSObject
+ (id)alloc;
@end
o = (*parr)[2];
}
@end
+
+extern const CFStringRef globStr;
+
+void test1(NSString *str) {
+ NSDictionary *dict = @{(id)globStr: str};
+ dict = @{str: (id)globStr};
+ dict = @{(id)globStr: str};
+ dict = @{str: (id)globStr};
+
+ NSArray *arr = @[(id)globStr, (id)globStr];
+ arr = @[str, (id)globStr];
+ arr = @[(id)globStr, str];
+ arr = @[(id)globStr];
+}