r219424 - Objective-C SDK modernization. convert message expression
Fariborz Jahanian
fjahanian at apple.com
Thu Oct 9 11:30:56 PDT 2014
Author: fjahanian
Date: Thu Oct 9 13:30:56 2014
New Revision: 219424
URL: http://llvm.org/viewvc/llvm-project?rev=219424&view=rev
Log:
Objective-C SDK modernization. convert message expression
to Objective-C dot-syntax. rdar://18498572
Added:
cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m
cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result
Modified:
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=219424&r1=219423&r2=219424&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Thu Oct 9 13:30:56 2014
@@ -211,6 +211,104 @@ bool ObjCMigrateAction::BeginInvocation(
}
namespace {
+ // FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp
+ bool subscriptOperatorNeedsParens(const Expr *FullExpr) {
+ const Expr* Expr = FullExpr->IgnoreImpCasts();
+ if (isa<ArraySubscriptExpr>(Expr) ||
+ isa<CallExpr>(Expr) ||
+ isa<DeclRefExpr>(Expr) ||
+ isa<CXXNamedCastExpr>(Expr) ||
+ isa<CXXConstructExpr>(Expr) ||
+ isa<CXXThisExpr>(Expr) ||
+ isa<CXXTypeidExpr>(Expr) ||
+ isa<CXXUnresolvedConstructExpr>(Expr) ||
+ isa<ObjCMessageExpr>(Expr) ||
+ isa<ObjCPropertyRefExpr>(Expr) ||
+ isa<ObjCProtocolExpr>(Expr) ||
+ isa<MemberExpr>(Expr) ||
+ isa<ObjCIvarRefExpr>(Expr) ||
+ isa<ParenExpr>(FullExpr) ||
+ isa<ParenListExpr>(Expr) ||
+ isa<SizeOfPackExpr>(Expr))
+ return false;
+
+ return true;
+ }
+
+ /// \brief - Rewrite message expression for Objective-C setter and getters into
+ /// property-dot syntax.
+ bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg,
+ Preprocessor &PP,
+ const NSAPI &NS, edit::Commit &commit,
+ const ParentMap *PMap) {
+ if (!Msg || Msg->isImplicit() ||
+ Msg->getReceiverKind() != ObjCMessageExpr::Instance)
+ return false;
+ const ObjCMethodDecl *Method = Msg->getMethodDecl();
+ if (!Method)
+ return false;
+ if (!Method->isPropertyAccessor())
+ return false;
+
+ const ObjCInterfaceDecl *IFace =
+ NS.getASTContext().getObjContainingInterface(Method);
+ if (!IFace)
+ return false;
+
+ const ObjCPropertyDecl *Prop = Method->findPropertyDecl();
+ if (!Prop)
+ return false;
+
+ SourceRange MsgRange = Msg->getSourceRange();
+ const Expr *receiver = Msg->getInstanceReceiver();
+ bool NeedsParen = subscriptOperatorNeedsParens(receiver);
+ bool IsGetter = (Msg->getNumArgs() == 0);
+ if (IsGetter) {
+ // Find space location range between receiver expression and getter method.
+ SourceLocation BegLoc = receiver->getLocEnd();
+ BegLoc = PP.getLocForEndOfToken(BegLoc);
+ SourceLocation EndLoc = Msg->getSelectorLoc(0);
+ SourceRange SpaceRange(BegLoc, EndLoc);
+ std::string PropertyDotString;
+ // rewrite getter method expression into: receiver.property or
+ // (receiver).property
+ if (NeedsParen) {
+ commit.insertBefore(receiver->getLocStart(), "(");
+ PropertyDotString = ").";
+ }
+ else
+ PropertyDotString = ".";
+ PropertyDotString += Prop->getName();
+ commit.replace(SpaceRange, PropertyDotString);
+
+ // remove '[' ']'
+ commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
+ commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
+ } else {
+ SourceRange ReceiverRange = receiver->getSourceRange();
+ if (NeedsParen)
+ commit.insertWrap("(", ReceiverRange, ")");
+ std::string PropertyDotString = ".";
+ PropertyDotString += Prop->getName();
+ PropertyDotString += " =";
+ const Expr*const* Args = Msg->getArgs();
+ const Expr *RHS = Args[0];
+ if (!RHS)
+ return false;
+ SourceLocation BegLoc = ReceiverRange.getEnd();
+ BegLoc = PP.getLocForEndOfToken(BegLoc);
+ SourceLocation EndLoc = RHS->getLocStart();
+ EndLoc = EndLoc.getLocWithOffset(-1);
+ SourceRange Range(BegLoc, EndLoc);
+ commit.replace(Range, PropertyDotString);
+ // remove '[' ']'
+ commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
+ commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
+ }
+ return true;
+ }
+
+
class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
ObjCMigrateASTConsumer &Consumer;
ParentMap &PMap;
@@ -235,6 +333,13 @@ public:
Consumer.Editor->commit(commit);
}
+ if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Property) {
+ edit::Commit commit(*Consumer.Editor);
+ rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj,
+ commit, &PMap);
+ Consumer.Editor->commit(commit);
+ }
+
return true;
}
Added: cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m?rev=219424&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m Thu Oct 9 13:30:56 2014
@@ -0,0 +1,39 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result
+
+// rdar://18498572
+ at interface NSObject @end
+
+ at interface P : NSObject
+{
+ P* obj;
+ int i1, i2, i3;
+}
+ at property int count;
+ at property (copy) P* PropertyReturnsPObj;
+- (P*) MethodReturnsPObj;
+ at end
+
+P* fun();
+
+ at implementation P
+- (int) Meth : (P*)array {
+ [obj setCount : 100];
+
+ [(P*)0 setCount : [array count]];
+
+ [[obj PropertyReturnsPObj] setCount : [array count]];
+
+ [obj setCount : (i1+i2*i3 - 100)];
+
+ return [obj count] -
+ [(P*)0 count] + [array count] +
+ [fun() count] -
+ [[obj PropertyReturnsPObj] count] +
+ [self->obj count];
+}
+
+- (P*) MethodReturnsPObj { return 0; }
+ at end
Added: cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result?rev=219424&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result Thu Oct 9 13:30:56 2014
@@ -0,0 +1,39 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result
+
+// rdar://18498572
+ at interface NSObject @end
+
+ at interface P : NSObject
+{
+ P* obj;
+ int i1, i2, i3;
+}
+ at property int count;
+ at property (copy) P* PropertyReturnsPObj;
+ at property (nonatomic, readonly, strong) P *MethodReturnsPObj;
+ at end
+
+P* fun();
+
+ at implementation P
+- (int) Meth : (P*)array {
+ obj.count = 100;
+
+ ((P*)0).count = array.count;
+
+ obj.PropertyReturnsPObj.count = array.count;
+
+ obj.count = (i1+i2*i3 - 100);
+
+ return obj.count -
+ ((P*)0).count + array.count +
+ fun().count -
+ obj.PropertyReturnsPObj.count +
+ self->obj.count;
+}
+
+- (P*) MethodReturnsPObj { return 0; }
+ at end
More information about the cfe-commits
mailing list