[cfe-commits] r55225 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Fri Aug 22 21:28:30 PDT 2008
Author: ddunbar
Date: Fri Aug 22 23:28:29 2008
New Revision: 55225
URL: http://llvm.org/viewvc/llvm-project?rev=55225&view=rev
Log:
NeXT: Implement super message sends.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55225&r1=55224&r2=55225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Aug 22 23:28:29 2008
@@ -40,7 +40,7 @@
const llvm::StructType *CFStringType;
llvm::Constant *CFConstantStringClassReference;
- llvm::Function *MessageSendFn;
+ llvm::Function *MessageSendFn, *MessageSendSuperFn;
public:
const llvm::Type *ShortTy, *IntTy, *LongTy;
@@ -54,6 +54,9 @@
/// (typeof(Protocol))
const llvm::Type *ExternalProtocolPtrTy;
+ /// SuperTy - LLVM type for struct objc_super.
+ const llvm::StructType *SuperTy;
+
/// SymtabTy - LLVM type for struct objc_symtab.
const llvm::StructType *SymtabTy;
/// SymtabPtrTy - LLVM type for struct objc_symtab *.
@@ -126,6 +129,7 @@
llvm::Constant *getCFConstantStringClassReference();
const llvm::StructType *getCFStringType();
llvm::Function *getMessageSendFn();
+ llvm::Function *getMessageSendSuperFn();
};
class CGObjCMac : public CodeGen::CGObjCRuntime {
@@ -421,8 +425,39 @@
const ObjCMessageExpr *E,
const ObjCInterfaceDecl *SuperClass,
llvm::Value *Receiver) {
- assert(0 && "Cannot generate message send to super for Mac runtime.");
- return CodeGen::RValue::get(0);
+ // FIXME: This should be cached, not looked up every time. Meh. We
+ // should just make sure the optimizer hits it.
+ llvm::Value *ReceiverClass = EmitClassRef(CGF.Builder, SuperClass);
+
+ // Create and init a super structure; this is a (receiver, class)
+ // pair we will pass to objc_msgSendSuper.
+ llvm::Value *ObjCSuper =
+ CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
+ llvm::Value *ReceiverAsObject =
+ CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
+ CGF.Builder.CreateStore(ReceiverAsObject,
+ CGF.Builder.CreateStructGEP(ObjCSuper, 0));
+ CGF.Builder.CreateStore(ReceiverClass,
+ CGF.Builder.CreateStructGEP(ObjCSuper, 1));
+
+ const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
+ llvm::Function *F = ObjCTypes.getMessageSendSuperFn();
+ llvm::Value *Args[2];
+ Args[0] = ObjCSuper;
+ Args[1] = EmitSelector(CGF.Builder, E->getSelector());
+
+ std::vector<const llvm::Type*> Params(2);
+ Params[0] = llvm::PointerType::getUnqual(ObjCTypes.SuperTy);
+ Params[1] = ObjCTypes.SelectorPtrTy;
+ llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
+ Params,
+ true);
+ llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
+ llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
+ return CGF.EmitCallExprExt(C, E->getType(),
+ E->arg_begin(),
+ E->arg_end(),
+ Args, 2);
}
/// Generate code for a message send expression.
@@ -435,9 +470,9 @@
Args[0] = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
Args[1] = EmitSelector(CGF.Builder, E->getSelector());
- std::vector<const llvm::Type*> Params;
- Params.push_back(ObjCTypes.ObjectPtrTy);
- Params.push_back(ObjCTypes.SelectorPtrTy);
+ std::vector<const llvm::Type*> Params(2);
+ Params[0] = ObjCTypes.ObjectPtrTy;
+ Params[1] = ObjCTypes.SelectorPtrTy;
llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
Params,
true);
@@ -1661,6 +1696,13 @@
NULL);
CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
+ SuperTy =
+ llvm::StructType::get(ObjectPtrTy,
+ ClassPtrTy,
+ NULL);
+ CGM.getModule().addTypeName("struct._objc_super",
+ SuperTy);
+
// Global metadata structures
SymtabTy = llvm::StructType::get(LongTy,
@@ -1731,6 +1773,23 @@
return MessageSendFn;
}
+llvm::Function *ObjCTypesHelper::getMessageSendSuperFn() {
+ if (!MessageSendSuperFn) {
+ std::vector<const llvm::Type*> Params;
+ Params.push_back(llvm::PointerType::getUnqual(SuperTy));
+ Params.push_back(SelectorPtrTy);
+ MessageSendSuperFn =
+ llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
+ Params,
+ true),
+ llvm::Function::ExternalLinkage,
+ "objc_msgSendSuper",
+ &CGM.getModule());
+ }
+
+ return MessageSendSuperFn;
+}
+
/* *** */
CodeGen::CGObjCRuntime *
More information about the cfe-commits
mailing list