From: Argyrios Kyrtzidis Date: Mon, 14 May 2012 22:01:53 +0000 (+0000) Subject: [objcmt] When rewriting to array/dictionary literals, add an explicit X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=055b395294d190a432e9d87bb665634636a1418a;p=clang [objcmt] When rewriting to array/dictionary literals, add an explicit cast to 'id' for any argument that requires it. Part of rdar://11438360. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156782 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Edit/EditedSource.cpp b/lib/Edit/EditedSource.cpp index 5b7fa4ad1b..b2a16635d0 100644 --- a/lib/Edit/EditedSource.cpp +++ b/lib/Edit/EditedSource.cpp @@ -100,8 +100,11 @@ bool EditedSource::commitInsertFromRange(SourceLocation OrigLoc, FileOffset B = I->first; FileOffset E = B.getWithOffset(FA.RemoveLen); + if (BeginOffs == B) + break; + if (BeginOffs < E) { - if (BeginOffs >= B) { + if (BeginOffs > B) { BeginOffs = E; ++I; } diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp index 24a0db1875..8c3c7a5bf3 100644 --- a/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -229,6 +229,9 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, // 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(); @@ -244,6 +247,7 @@ static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg, 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, "]"); @@ -257,6 +261,9 @@ static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg, 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; @@ -291,6 +298,10 @@ static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg, 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. @@ -319,6 +330,9 @@ static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg, } 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. @@ -585,3 +599,52 @@ static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg, } return true; } + +static bool castOperatorNeedsParens(const Expr *FullExpr) { + const Expr* Expr = FullExpr->IgnoreImpCasts(); + if (isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(Expr) || + isa(FullExpr) || + isa(Expr) || + isa(Expr) || + isa(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(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)"); +} diff --git a/test/ARCMT/objcmt-numeric-literals.m b/test/ARCMT/objcmt-numeric-literals.m index b86af4d056..7f33dc2799 100644 --- a/test/ARCMT/objcmt-numeric-literals.m +++ b/test/ARCMT/objcmt-numeric-literals.m @@ -1,6 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ // 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 #define YES __objc_yes #define NO __objc_no diff --git a/test/ARCMT/objcmt-numeric-literals.m.result b/test/ARCMT/objcmt-numeric-literals.m.result index 1c4187aaef..8e343455fd 100644 --- a/test/ARCMT/objcmt-numeric-literals.m.result +++ b/test/ARCMT/objcmt-numeric-literals.m.result @@ -1,6 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ // 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 #define YES __objc_yes #define NO __objc_no diff --git a/test/ARCMT/objcmt-subscripting-literals.m b/test/ARCMT/objcmt-subscripting-literals.m index 3d26efefda..147595182d 100644 --- a/test/ARCMT/objcmt-subscripting-literals.m +++ b/test/ARCMT/objcmt-subscripting-literals.m @@ -1,10 +1,13 @@ // 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 @@ -135,3 +138,17 @@ typedef signed char BOOL; 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]; +} diff --git a/test/ARCMT/objcmt-subscripting-literals.m.result b/test/ARCMT/objcmt-subscripting-literals.m.result index 8ac6dcc207..5c8a4ecc40 100644 --- a/test/ARCMT/objcmt-subscripting-literals.m.result +++ b/test/ARCMT/objcmt-subscripting-literals.m.result @@ -1,10 +1,13 @@ // 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 @@ -135,3 +138,17 @@ typedef signed char BOOL; 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]; +}