CodeGen::RValue
CGObjCJit::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
                           ReturnValueSlot Return,
                           QualType ResultType,
                           Selector Sel,
                           llvm::Value *Arg0,
                           llvm::Value *Arg0Class,
                           const CallArgList &CallArgs,
                           const ObjCMethodDecl *Method) {

  llvm::Value *Arg1 = GetSelector(CGF, Sel);

  CallArgList ActualArgs;
  ActualArgs.add(RValue::get(Arg0), CGF.getContext().getObjCIdType());
  ActualArgs.add(RValue::get(Arg1), CGF.getContext().getObjCSelType());
  ActualArgs.addFrom(CallArgs);

  if (Method)
    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
           CGM.getContext().getCanonicalType(ResultType) &&
           "Result type mismatch!");

  // Perform the following:
  //   imp = class_getMethodImplementation( Arg0Class, Arg1 );
  //   (*imp)( Arg0, Arg1, CallArgs );
  llvm::CallInst *getImp;

  // Unfortunately, using the GNU runtime version of
  // class_getMethodImplementation and then calling the resulting
  // IMP doesn't work unless objc_msg_lookup was already
  // called first. TODO: avoid doing this every time
  //
  if (fn_objc_msg_lookup.isValid()) {
    getImp = CGF.Builder.CreateCall2(fn_objc_msg_lookup,
                                     Arg0,
                                     Arg1);
  } else { // use the universal way
    getImp = CGF.Builder.CreateCall2(fn_class_getMethodImplementation,
                                     Arg0Class,
                                     Arg1);
  }

  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
  llvm::Value *theImp = CGF.Builder.CreateBitCast(getImp, MSI.MessengerType);
  return CGF.EmitCall(MSI.CallInfo, theImp, Return, ActualArgs);
}