Obscure code gen bug related to sending

message to 'super' in a class method declared in
cateogy (darwin specific).

llvm-svn: 65709
This commit is contained in:
Fariborz Jahanian 2009-02-28 20:07:56 +00:00
parent 309e48695b
commit bac73acc24
5 changed files with 53 additions and 7 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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.

View File

@ -98,6 +98,7 @@ public:
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
bool isCategoryImpl,
llvm::Value *Self,
bool IsClassMessage,
const CallArgList &CallArgs) = 0;

View File

@ -0,0 +1,13 @@
// RUN: clang -fnext-runtime -emit-llvm -o %t %s
@interface SUPER
+ (void)Meth;
@end
@interface CURRENT : SUPER
+ (void)Meth;
@end
@implementation CURRENT(CAT)
+ (void)Meth { [super Meth]; }
@end