diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-28 20:07:56 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-28 20:07:56 +0000 |
| commit | bac73acc245361c930453c4de10ca7224f8011d7 (patch) | |
| tree | fa2d2f68312dc4a6339f1cc46735f43317ff636a /clang/lib/CodeGen | |
| parent | 309e48695b9533db3c6e37e15dd4ebc57a0dd351 (diff) | |
| download | bcm5719-llvm-bac73acc245361c930453c4de10ca7224f8011d7.tar.gz bcm5719-llvm-bac73acc245361c930453c4de10ca7224f8011d7.zip | |
Obscure code gen bug related to sending
message to 'super' in a class method declared in
cateogy (darwin specific).
llvm-svn: 65709
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 42 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.h | 1 |
4 files changed, 40 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index ec11edb3492..cebaa1eb030 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -89,9 +89,11 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { 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); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index b41f76db63b..7877baaf3ec 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -107,6 +107,7 @@ public: QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs); @@ -269,6 +270,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs) { diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 3beb91a29ed..549a6b9f524 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -559,6 +559,7 @@ private: QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs); @@ -711,6 +712,7 @@ public: QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs); @@ -821,6 +823,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CodeGen::CallArgList &CallArgs) { @@ -836,10 +839,23 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, // 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 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage, const CodeGen::CallArgList &CallArgs) { @@ -4631,9 +4648,20 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 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. diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 15131579a7d..63a7630dc00 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -98,6 +98,7 @@ public: QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, + bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs) = 0; |

