[cfe-commits] r159788 - in /cfe/trunk: lib/Edit/RewriteObjCFoundationAPI.cpp test/ARCMT/objcmt-subscripting-literals.m test/ARCMT/objcmt-subscripting-literals.m.result
Argyrios Kyrtzidis
akyrtzi at gmail.com
Thu Jul 5 17:07:09 PDT 2012
Author: akirtzidis
Date: Thu Jul 5 19:07:09 2012
New Revision: 159788
URL: http://llvm.org/viewvc/llvm-project?rev=159788&view=rev
Log:
[objcmt] Check for classes that accept 'objectForKey:' (or the other selectors
that the migrator handles) but return their instances as 'id', resulting
in the compiler resolving 'objectForKey:' as the method from NSDictionary.
When checking if we can convert to subscripting syntax, check whether
the receiver is a result of a class method from a hardcoded list of
such classes. In such a case return the specific class as the interface
of the receiver.
Modified:
cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
Modified: cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp?rev=159788&r1=159787&r2=159788&view=diff
==============================================================================
--- cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp (original)
+++ cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp Thu Jul 5 19:07:09 2012
@@ -94,8 +94,73 @@
// rewriteToObjCSubscriptSyntax.
//===----------------------------------------------------------------------===//
-static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *IFace,
+/// \brief Check for classes that accept 'objectForKey:' (or the other selectors
+/// that the migrator handles) but return their instances as 'id', resulting
+/// in the compiler resolving 'objectForKey:' as the method from NSDictionary.
+///
+/// When checking if we can convert to subscripting syntax, check whether
+/// the receiver is a result of a class method from a hardcoded list of
+/// such classes. In such a case return the specific class as the interface
+/// of the receiver.
+///
+/// FIXME: Remove this when these classes start using 'instancetype'.
+static const ObjCInterfaceDecl *
+maybeAdjustInterfaceForSubscriptingCheck(const ObjCInterfaceDecl *IFace,
+ const Expr *Receiver,
+ ASTContext &Ctx) {
+ assert(IFace && Receiver);
+
+ // If the receiver has type 'id'...
+ if (!Ctx.isObjCIdType(Receiver->getType().getUnqualifiedType()))
+ return IFace;
+
+ const ObjCMessageExpr *
+ InnerMsg = dyn_cast<ObjCMessageExpr>(Receiver->IgnoreParenCasts());
+ if (!InnerMsg)
+ return IFace;
+
+ QualType ClassRec;
+ switch (InnerMsg->getReceiverKind()) {
+ case ObjCMessageExpr::Instance:
+ case ObjCMessageExpr::SuperInstance:
+ return IFace;
+
+ case ObjCMessageExpr::Class:
+ ClassRec = InnerMsg->getClassReceiver();
+ break;
+ case ObjCMessageExpr::SuperClass:
+ ClassRec = InnerMsg->getSuperType();
+ break;
+ }
+
+ if (ClassRec.isNull())
+ return IFace;
+
+ // ...and it is the result of a class message...
+
+ const ObjCObjectType *ObjTy = ClassRec->getAs<ObjCObjectType>();
+ if (!ObjTy)
+ return IFace;
+ const ObjCInterfaceDecl *OID = ObjTy->getInterface();
+
+ // ...and the receiving class is NSMapTable or NSLocale, return that
+ // class as the receiving interface.
+ if (OID->getName() == "NSMapTable" ||
+ OID->getName() == "NSLocale")
+ return OID;
+
+ return IFace;
+}
+
+static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *&IFace,
+ const ObjCMessageExpr *Msg,
+ ASTContext &Ctx,
Selector subscriptSel) {
+ const Expr *Rec = Msg->getInstanceReceiver();
+ if (!Rec)
+ return false;
+ IFace = maybeAdjustInterfaceForSubscriptingCheck(IFace, Rec, Ctx);
+
if (const ObjCMethodDecl *MD = IFace->lookupInstanceMethod(subscriptSel)) {
if (!MD->isUnavailable())
return true;
@@ -138,7 +203,7 @@
const ObjCMessageExpr *Msg,
const NSAPI &NS,
Commit &commit) {
- if (!canRewriteToSubscriptSyntax(IFace,
+ if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
NS.getObjectAtIndexedSubscriptSelector()))
return false;
return rewriteToSubscriptGetCommon(Msg, commit);
@@ -148,7 +213,7 @@
const ObjCMessageExpr *Msg,
const NSAPI &NS,
Commit &commit) {
- if (!canRewriteToSubscriptSyntax(IFace,
+ if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
NS.getObjectForKeyedSubscriptSelector()))
return false;
return rewriteToSubscriptGetCommon(Msg, commit);
@@ -158,7 +223,7 @@
const ObjCMessageExpr *Msg,
const NSAPI &NS,
Commit &commit) {
- if (!canRewriteToSubscriptSyntax(IFace,
+ if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
NS.getSetObjectAtIndexedSubscriptSelector()))
return false;
@@ -192,7 +257,7 @@
const ObjCMessageExpr *Msg,
const NSAPI &NS,
Commit &commit) {
- if (!canRewriteToSubscriptSyntax(IFace,
+ if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
NS.getSetObjectForKeyedSubscriptSelector()))
return false;
Modified: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m?rev=159788&r1=159787&r2=159788&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m (original)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m Thu Jul 5 19:07:09 2012
@@ -211,3 +211,13 @@
o = [mutcunaval objectAtIndex:4];
[mutcunaval replaceObjectAtIndex:2 withObject:@"val"];
}
+
+ at interface NSLocale : NSObject
++ (id)systemLocale;
++ (id)currentLocale;
+- (id)objectForKey:(id)key;
+ at end
+
+void test3(id key) {
+ id o = [[NSLocale currentLocale] objectForKey:key];
+}
Modified: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result?rev=159788&r1=159787&r2=159788&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result (original)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result Thu Jul 5 19:07:09 2012
@@ -211,3 +211,13 @@
o = [mutcunaval objectAtIndex:4];
[mutcunaval replaceObjectAtIndex:2 withObject:@"val"];
}
+
+ at interface NSLocale : NSObject
++ (id)systemLocale;
++ (id)currentLocale;
+- (id)objectForKey:(id)key;
+ at end
+
+void test3(id key) {
+ id o = [[NSLocale currentLocale] objectForKey:key];
+}
More information about the cfe-commits
mailing list