// Find the receiver
llvm::Value *Receiver;
if (!ReceiverExpr) {
- const char * classname = E->getClassName()->getName();
- if (!strcmp(classname, "super")) {
- classname = E->getMethodDecl()->getClassInterface()->getName();
+ const ObjCInterfaceDecl *OID = E->getClassInfo().first;
+
+ // Very special case, super send in class method. The receiver is
+ // self (the class object) and the send uses super semantics.
+ if (!OID) {
+ assert(!strcmp(E->getClassName()->getName(), "super") &&
+ "Unexpected missing class interface in message send.");
+ OID = E->getMethodDecl()->getClassInterface();
+ isSuperMessage = true;
}
- llvm::Value *ClassName = CGM.GetAddrOfConstantCString(classname);
- ClassName = Builder.CreateStructGEP(ClassName, 0);
- Receiver = Runtime.LookupClass(Builder, ClassName);
+
+ Receiver = Runtime.GetClass(Builder, OID);
} else if (const PredefinedExpr *PDE =
dyn_cast<PredefinedExpr>(E->getReceiver())) {
assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper);
if (isSuperMessage) {
// super is only valid in an Objective-C method
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
- const char *SuperClass =
- OMD->getClassInterface()->getSuperClass()->getName();
return Runtime.GenerateMessageSendSuper(Builder, ConvertType(E->getType()),
- SuperClass,
+ OMD->getClassInterface()->getSuperClass(),
Receiver, E->getSelector(),
&Args[0], Args.size());
}
unsigned ArgC);
virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
const llvm::Type *ReturnTy,
- const char *SuperClassName,
+ const ObjCInterfaceDecl *SuperClass,
llvm::Value *Receiver,
Selector Sel,
llvm::Value** ArgV,
unsigned ArgC);
- virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
- llvm::Value *ClassName);
+ virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
+ const ObjCInterfaceDecl *OID);
virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
}
// This has to perform the lookup every time, since posing and related
// techniques can modify the name -> class mapping.
-llvm::Value *CGObjCGNU::LookupClass(llvm::IRBuilder<> &Builder,
- llvm::Value *ClassName) {
+llvm::Value *CGObjCGNU::GetClass(llvm::IRBuilder<> &Builder,
+ const ObjCInterfaceDecl *OID) {
+ llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getName());
+ ClassName = Builder.CreateStructGEP(ClassName, 0);
+
llvm::Constant *ClassLookupFn =
TheModule.getOrInsertFunction("objc_lookup_class", IdTy, PtrToInt8Ty,
NULL);
///should be called.
llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
const llvm::Type *ReturnTy,
- const char *SuperClassName,
+ const ObjCInterfaceDecl *SuperClass,
llvm::Value *Receiver,
Selector Sel,
llvm::Value** ArgV,
unsigned ArgC) {
// TODO: This should be cached, not looked up every time.
- llvm::Value *ReceiverClass = LookupClass(Builder,
- MakeConstantString(SuperClassName));
+ llvm::Value *ReceiverClass = GetClass(Builder, SuperClass);
llvm::Value *cmd = GetSelector(Builder, Sel);
std::vector<const llvm::Type*> impArgTypes;
impArgTypes.push_back(Receiver->getType());
llvm::Value** ArgV,
unsigned ArgC);
- virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
- const llvm::Type *ReturnTy,
- const char *SuperClassName,
- llvm::Value *Receiver,
- Selector Sel,
- llvm::Value** ArgV,
- unsigned ArgC);
-
- virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
- llvm::Value *ClassName);
+ virtual llvm::Value *
+ GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
+ const llvm::Type *ReturnTy,
+ const ObjCInterfaceDecl *SuperClass,
+ llvm::Value *Receiver,
+ Selector Sel,
+ llvm::Value** ArgV,
+ unsigned ArgC);
+
+ virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
+ const ObjCInterfaceDecl *SuperClass);
virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
EmitImageInfo();
}
-// This has to perform the lookup every time, since posing and related
-// techniques can modify the name -> class mapping.
-llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
- llvm::Value *ClassName) {
+/// GetClass - Return a reference to the class for the given interface
+/// decl.
+llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
+ const ObjCInterfaceDecl *OID) {
assert(0 && "Cannot lookup classes on Mac runtime.");
return 0;
}
/// Generates a message send where the super is the receiver. This is
/// a message send to self with special delivery semantics indicating
/// which class's method should be called.
-llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
- const llvm::Type *ReturnTy,
- const char *SuperClassName,
- llvm::Value *Receiver,
- Selector Sel,
- llvm::Value** ArgV,
- unsigned ArgC) {
+llvm::Value *
+CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
+ const llvm::Type *ReturnTy,
+ const ObjCInterfaceDecl *SuperClass,
+ llvm::Value *Receiver,
+ Selector Sel,
+ llvm::Value** ArgV,
+ unsigned ArgC) {
assert(0 && "Cannot generate message send to super for Mac runtime.");
return 0;
}
namespace clang {
class ObjCCategoryImplDecl;
class ObjCImplementationDecl;
+ class ObjCInterfaceDecl;
class ObjCMethodDecl;
class ObjCProtocolDecl;
class Selector;
/// Generate an Objective-C message send operation to the super
/// class.
- virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder,
- const llvm::Type *ReturnTy,
- const char *SuperClassName,
- llvm::Value *Receiver,
- Selector Sel,
- llvm::Value** ArgV,
- unsigned ArgC) = 0;
+ virtual llvm::Value *
+ GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder,
+ const llvm::Type *ReturnTy,
+ const ObjCInterfaceDecl *SuperClassName,
+ llvm::Value *Receiver,
+ Selector Sel,
+ llvm::Value** ArgV,
+ unsigned ArgC) = 0;
/// Emit the code to return the named protocol as an object, as in a
/// @protocol expression.
// parameters are passed.
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD) = 0;
- /// Look up the class for the specified name
- virtual llvm::Value *LookupClass(BuilderType &Builder,
- llvm::Value *ClassName) = 0;
+ /// GetClass - Return a reference to the class for the given
+ /// interface decl.
+ virtual llvm::Value *GetClass(BuilderType &Builder,
+ const ObjCInterfaceDecl *OID) = 0;
/// If instance variable addresses are determined at runtime then this should
/// return true, otherwise instance variables will be accessed directly from