[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