aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-05-08 15:39:58 +0000
committerChris Lattner <sabre@nondot.org>2009-05-08 15:39:58 +0000
commit48e6e7e8106f2404bfdd2d8abe7a840aeeaf047b (patch)
treec25a26e494fd8e7a2213e3b8de66407e53e44be6 /lib/CodeGen
parente7ac0a94f1dee3fae9292eb8372962b6d70b3e0d (diff)
"This patch fixes message sends to super in categories for the GNU runtime. This used to work, but I broke it when I modified the code to emit the same thing as GCC for message sends to super in classes."
Patch by David Chisnall! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71220 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp48
1 files changed, 31 insertions, 17 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 32e8430782..2a2c1ab6ae 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -329,27 +329,41 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
-
- // Set up global aliases for the metaclass or class pointer if they do not
- // already exist. These will are forward-references which will be set to
- // pointers to the class and metaclass structure created for the runtime load
- // function. To send a message to super, we look up the value of the
- // super_class pointer from either the class or metaclass structure.
llvm::Value *ReceiverClass = 0;
- if (IsClassMessage) {
- if (!MetaClassPtrAlias) {
- MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
- llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
- Class->getNameAsString(), NULL, &TheModule);
+ if (isCategoryImpl) {
+ llvm::Constant *classLookupFunction = 0;
+ std::vector<const llvm::Type*> Params;
+ Params.push_back(PtrTy);
+ if (IsClassMessage) {
+ classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+ IdTy, Params, true), "objc_get_meta_class");
+ } else {
+ classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+ IdTy, Params, true), "objc_get_class");
}
- ReceiverClass = MetaClassPtrAlias;
+ ReceiverClass = CGF.Builder.CreateCall(classLookupFunction,
+ MakeConstantString(Class->getNameAsString()));
} else {
- if (!ClassPtrAlias) {
- ClassPtrAlias = new llvm::GlobalAlias(IdTy,
- llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
- Class->getNameAsString(), NULL, &TheModule);
+ // Set up global aliases for the metaclass or class pointer if they do not
+ // already exist. These will are forward-references which will be set to
+ // pointers to the class and metaclass structure created for the runtime load
+ // function. To send a message to super, we look up the value of the
+ // super_class pointer from either the class or metaclass structure.
+ if (IsClassMessage) {
+ if (!MetaClassPtrAlias) {
+ MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
+ llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
+ Class->getNameAsString(), NULL, &TheModule);
+ }
+ ReceiverClass = MetaClassPtrAlias;
+ } else {
+ if (!ClassPtrAlias) {
+ ClassPtrAlias = new llvm::GlobalAlias(IdTy,
+ llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
+ Class->getNameAsString(), NULL, &TheModule);
+ }
+ ReceiverClass = ClassPtrAlias;
}
- ReceiverClass = ClassPtrAlias;
}
// Cast the pointer to a simplified version of the class structure
ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,