CGObjCRuntime &Runtime = CGM.getObjCRuntime();
bool isSuperMessage = false;
bool isClassMessage = false;
+ ObjCInterfaceDecl *OID = 0;
// Find the receiver
llvm::Value *Receiver = 0;
switch (E->getReceiverKind()) {
case ObjCMessageExpr::Class: {
const ObjCInterfaceType *IFace
= E->getClassReceiver()->getAs<ObjCInterfaceType>();
+ OID = IFace->getDecl();
assert(IFace && "Invalid Objective-C class message send");
- Receiver = Runtime.GetClass(Builder, IFace->getDecl());
+ Receiver = Runtime.GetClass(Builder, OID);
isClassMessage = true;
break;
}
}
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
- Receiver, isClassMessage, Args,
+ Receiver, Args, OID,
E->getMethodDecl());
}
return CGM.getObjCRuntime().
GenerateMessageSend(*this, Exp->getType(), S,
EmitScalarExpr(E->getBase()),
- false, CallArgList());
+ CallArgList());
} else {
const ObjCImplicitSetterGetterRefExpr *KE =
cast<ObjCImplicitSetterGetterRefExpr>(Exp);
return CGM.getObjCRuntime().
GenerateMessageSend(*this, Exp->getType(), S,
Receiver,
- KE->getInterfaceDecl() != 0, CallArgList());
+ CallArgList(), KE->getInterfaceDecl());
}
}
Args.push_back(std::make_pair(Src, E->getType()));
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
EmitScalarExpr(E->getBase()),
- false, Args);
+ Args);
} else if (const ObjCImplicitSetterGetterRefExpr *E =
dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
Selector S = E->getSetterMethod()->getSelector();
Args.push_back(std::make_pair(Src, E->getType()));
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
Receiver,
- E->getInterfaceDecl() != 0, Args);
+ Args, E->getInterfaceDecl());
} else
assert (0 && "bad expression node in EmitObjCPropertySet");
}
CGM.getObjCRuntime().GenerateMessageSend(*this,
getContext().UnsignedLongTy,
FastEnumSel,
- Collection, false, Args);
+ Collection, Args);
llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
"limit.ptr");
CGM.getObjCRuntime().GenerateMessageSend(*this,
getContext().UnsignedLongTy,
FastEnumSel,
- Collection, false, Args);
+ Collection, Args);
Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
Limit = Builder.CreateLoad(LimitPtr);
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
+#include "llvm/LLVMContext.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Compiler.h"
llvm::Constant *Zeros[2];
llvm::Constant *NULLPtr;
llvm::LLVMContext &VMContext;
+ /// Metadata kind used to tie method lookups to message sends.
+ unsigned msgSendMDKind;
private:
llvm::Constant *GenerateIvarList(
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
: CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
+
+ msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
+
IntTy = cast<llvm::IntegerType>(
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
LongTy = cast<llvm::IntegerType>(
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
// Strip out message sends to retain / release in GC mode
if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
LookupFn->setDoesNotCapture(1);
}
- llvm::Value *slot =
+ llvm::Instruction *slot =
Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
+ llvm::Value *impMD[] = {
+ llvm::MDString::get(VMContext, Sel.getAsString()),
+ llvm::MDString::get(VMContext, Class ? Class->getNameAsString() :""),
+ };
+ llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 2);
+ cast<llvm::Instruction>(imp)->setMetadata(msgSendMDKind, node);
+
// The lookup function may have changed the receiver, so make sure we use
// the new one.
ActualArgs[0] =
imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
}
-
RValue msgRet =
CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return EmitLegacyMessageSend(CGF, ResultType,
EmitSelector(CGF.Builder, Sel),
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return LegacyDispatchedSelector(Sel)
? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class = 0,
const ObjCMethodDecl *Method = 0) = 0;
/// Generate an Objective-C message send operation to the super