[cfe-commits] r65709 - in /cfe/trunk: lib/CodeGen/CGObjC.cpp lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CGObjCRuntime.h test/CodeGenObjC/super-classmethod-category.m

Fariborz Jahanian fjahanian at apple.com
Sat Feb 28 12:07:56 PST 2009


Author: fjahanian
Date: Sat Feb 28 14:07:56 2009
New Revision: 65709

URL: http://llvm.org/viewvc/llvm-project?rev=65709&view=rev
Log:
Obscure code gen bug related to sending  
message to 'super' in a class method declared in
cateogy (darwin specific).

Added:
    cfe/trunk/test/CodeGenObjC/super-classmethod-category.m
Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.h

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=65709&r1=65708&r2=65709&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Sat Feb 28 14:07:56 2009
@@ -89,9 +89,11 @@
   if (isSuperMessage) {
     // super is only valid in an Objective-C method
     const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
     return Runtime.GenerateMessageSendSuper(*this, E->getType(),
                                             E->getSelector(),
                                             OMD->getClassInterface(),
+                                            isCategoryImpl,
                                             Receiver,
                                             isClassMessage,
                                             Args);

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=65709&r1=65708&r2=65709&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sat Feb 28 14:07:56 2009
@@ -107,6 +107,7 @@
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
                            llvm::Value *Receiver,
                            bool IsClassMessage,
                            const CallArgList &CallArgs);
@@ -269,6 +270,7 @@
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
+                                    bool isCategoryImpl,
                                     llvm::Value *Receiver,
                                     bool IsClassMessage,
                                     const CallArgList &CallArgs) {

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=65709&r1=65708&r2=65709&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat Feb 28 14:07:56 2009
@@ -559,6 +559,7 @@
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
                            llvm::Value *Receiver,
                            bool IsClassMessage,
                            const CallArgList &CallArgs);
@@ -711,6 +712,7 @@
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
                            llvm::Value *Receiver,
                            bool IsClassMessage,
                            const CallArgList &CallArgs);
@@ -821,6 +823,7 @@
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
+                                    bool isCategoryImpl,
                                     llvm::Value *Receiver,
                                     bool IsClassMessage,
                                     const CodeGen::CallArgList &CallArgs) {
@@ -836,10 +839,23 @@
   // If this is a class message the metaclass is passed as the target.
   llvm::Value *Target;
   if (IsClassMessage) {
-    llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
-    llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
-    llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
-    Target = Super;
+    if (isCategoryImpl) {
+      // Message sent to 'super' in a class method defined in a category
+      // implementation requires an odd treatment.
+      // If we are in a class method, we must retrieve the
+      // _metaclass_ for the current class, pointed at by
+      // the class's "isa" pointer.  The following assumes that
+      // isa" is the first ivar in a class (which it must be).
+      Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
+      Target = CGF.Builder.CreateStructGEP(Target, 0);
+      Target = CGF.Builder.CreateLoad(Target);
+    }
+    else {
+      llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
+      llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
+      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
+      Target = Super;
+   }
   } else {
     Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
   }
@@ -4616,6 +4632,7 @@
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
+                                    bool isCategoryImpl,
                                     llvm::Value *Receiver,
                                     bool IsClassMessage,
                                     const CodeGen::CallArgList &CallArgs) {
@@ -4631,9 +4648,20 @@
                           CGF.Builder.CreateStructGEP(ObjCSuper, 0));
   
   // If this is a class message the metaclass is passed as the target.
-  llvm::Value *Target = 
-    IsClassMessage ? EmitMetaClassRef(CGF.Builder, Class) 
-                   : EmitClassRef(CGF.Builder, Class, true);
+  llvm::Value *Target;
+  if (IsClassMessage) {
+    if (isCategoryImpl) {
+      // Message sent to "super' in a class method defined in
+      // a category implementation.
+      Target = EmitClassRef(CGF.Builder, Class, false);
+      Target = CGF.Builder.CreateStructGEP(Target, 0);
+      Target = CGF.Builder.CreateLoad(Target);
+    }
+    else
+      Target = EmitMetaClassRef(CGF.Builder, Class);
+  }
+  else
+    Target = EmitClassRef(CGF.Builder, Class, true);
     
   // FIXME: We shouldn't need to do this cast, rectify the ASTContext
   // and ObjCTypes types.

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=65709&r1=65708&r2=65709&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Sat Feb 28 14:07:56 2009
@@ -98,6 +98,7 @@
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl,
                            llvm::Value *Self,
                            bool IsClassMessage,
                            const CallArgList &CallArgs) = 0;

Added: cfe/trunk/test/CodeGenObjC/super-classmethod-category.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/super-classmethod-category.m?rev=65709&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenObjC/super-classmethod-category.m (added)
+++ cfe/trunk/test/CodeGenObjC/super-classmethod-category.m Sat Feb 28 14:07:56 2009
@@ -0,0 +1,13 @@
+// RUN: clang -fnext-runtime -emit-llvm -o %t %s
+
+ at interface SUPER
++ (void)Meth;
+ at end
+
+ at interface CURRENT : SUPER
++ (void)Meth;
+ at end
+
+ at implementation CURRENT(CAT)
++ (void)Meth { [super Meth]; }
+ at end





More information about the cfe-commits mailing list