[cfe-commits] r50781 - /cfe/trunk/Driver/RewriteObjC.cpp

Steve Naroff snaroff at apple.com
Tue May 6 16:20:07 PDT 2008


Author: snaroff
Date: Tue May  6 18:20:07 2008
New Revision: 50781

URL: http://llvm.org/viewvc/llvm-project?rev=50781&view=rev
Log:
Fix <rdar://problem/5879237> clang objc rewriter: ivars not accessible in structure generated for class

Modified:
    cfe/trunk/Driver/RewriteObjC.cpp

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=50781&r1=50780&r2=50781&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Tue May  6 18:20:07 2008
@@ -850,9 +850,35 @@
       }
     }
   } else { // we are outside a method.
-    if (IV->isFreeIvar())
-      assert(1 && "Cannot have a free standing ivar outside a method");
-    // Explicit ivar refs do not need to be rewritten. Do nothing.
+    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+      
+    // Explicit ivar refs need to have a cast inserted.
+    // FIXME: consider sharing some of this code with the code above.
+    if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
+      ObjCInterfaceType *intT = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = 0;
+      intT->getDecl()->lookupInstanceVariable(D->getIdentifier(), clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+      RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, TUDecl,
+                                          SourceLocation(), II, 0);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = new CastExpr(castT, IV->getBase(), SourceLocation());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), castExpr);
+      ReplaceStmt(IV->getBase(), PE);
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE); 
+      return IV;
+    }
   }
   return IV;
 }





More information about the cfe-commits mailing list