summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-02-28 20:07:56 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-02-28 20:07:56 +0000
commitbac73acc245361c930453c4de10ca7224f8011d7 (patch)
treefa2d2f68312dc4a6339f1cc46735f43317ff636a /clang/lib/CodeGen
parent309e48695b9533db3c6e37e15dd4ebc57a0dd351 (diff)
downloadbcm5719-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.cpp2
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp2
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp42
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.h1
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;
OpenPOWER on IntegriCloud