bool IgnoreResult;
bool IsInitializer;
bool RequiresGCollection;
+
+ ReturnValueSlot getReturnValueSlot() const {
+ return ReturnValueSlot(DestPtr, VolatileDest);
+ }
public:
AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
bool ignore, bool isinit, bool requiresGCollection)
// If the struct doesn't require GC, we can just pass the destination
// directly to EmitCall.
if (!RequiresGCollection) {
- CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
+ CGF.EmitCallExpr(E, getReturnValueSlot());
return;
}
}
void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- RValue RV = CGF.EmitObjCMessageExpr(E);
- EmitFinalDestCopy(E, RV);
+ CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
}
void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- RValue RV = CGF.EmitObjCPropertyGet(E);
- EmitFinalDestCopy(E, RV);
+ CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
}
void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E) {
- RValue RV = CGF.EmitObjCPropertyGet(E);
- EmitFinalDestCopy(E, RV);
+ CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
}
void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
}
-RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
+RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
+ ReturnValueSlot Return) {
// Only the lookup mechanism and first two arguments of the method
// implementation vary between runtimes. We can get the receiver and
// arguments in generic code.
// super is only valid in an Objective-C method
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
- return Runtime.GenerateMessageSendSuper(*this, E->getType(),
+ return Runtime.GenerateMessageSendSuper(*this, Return, E->getType(),
E->getSelector(),
OMD->getClassInterface(),
isCategoryImpl,
E->getMethodDecl());
}
- return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
+ return Runtime.GenerateMessageSend(*this, Return, E->getType(),
+ E->getSelector(),
Receiver, Args, OID,
E->getMethodDecl());
}
}
RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
- const Selector &S) {
+ const Selector &S,
+ ReturnValueSlot Return) {
llvm::Value *Receiver = LoadObjCSelf();
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
bool isClassMessage = OMD->isClassMethod();
bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
return CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+ Return,
Exp->getType(),
S,
OMD->getClassInterface(),
}
-RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp,
+ ReturnValueSlot Return) {
Exp = Exp->IgnoreParens();
// FIXME: Split it into two separate routines.
if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
Selector S = E->getProperty()->getGetterName();
if (isa<ObjCSuperExpr>(E->getBase()))
- return EmitObjCSuperPropertyGet(E, S);
+ return EmitObjCSuperPropertyGet(E, S, Return);
return CGM.getObjCRuntime().
- GenerateMessageSend(*this, Exp->getType(), S,
+ GenerateMessageSend(*this, Return, Exp->getType(), S,
EmitScalarExpr(E->getBase()),
CallArgList());
} else {
const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
} else if (isa<ObjCSuperExpr>(KE->getBase()))
- return EmitObjCSuperPropertyGet(KE, S);
+ return EmitObjCSuperPropertyGet(KE, S, Return);
else
Receiver = EmitScalarExpr(KE->getBase());
return CGM.getObjCRuntime().
- GenerateMessageSend(*this, Exp->getType(), S,
+ GenerateMessageSend(*this, Return, Exp->getType(), S,
Receiver,
CallArgList(), KE->getInterfaceDecl());
}
bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
Args.push_back(std::make_pair(Src, Exp->getType()));
CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
+ ReturnValueSlot(),
Exp->getType(),
S,
OMD->getClassInterface(),
}
CallArgList Args;
Args.push_back(std::make_pair(Src, E->getType()));
- CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+ getContext().VoidTy, S,
EmitScalarExpr(E->getBase()),
Args);
} else if (const ObjCImplicitSetterGetterRefExpr *E =
} else
Receiver = EmitScalarExpr(E->getBase());
Args.push_back(std::make_pair(Src, E->getType()));
- CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+ getContext().VoidTy, S,
Receiver,
Args, E->getInterfaceDecl());
} else
getContext().UnsignedLongTy));
RValue CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this,
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
getContext().UnsignedLongTy,
FastEnumSel,
Collection, Args);
EmitBlock(FetchMore);
CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this,
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
getContext().UnsignedLongTy,
FastEnumSel,
Collection, Args);
virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
virtual CodeGen::RValue
GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
///should be called.
CodeGen::RValue
CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
llvm::Instruction *call;
- RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
+ RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
0, &call);
call->setMetadata(msgSendMDKind, node);
return msgRet;
/// Generate code for a message send expression.
CodeGen::RValue
CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
}
llvm::Instruction *call;
- RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
+ RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
0, &call);
call->setMetadata(msgSendMDKind, node);
bool AddToUsed);
CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
llvm::Value *Sel,
llvm::Value *Arg0,
llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Arg0,
virtual llvm::Function *ModuleInitFunction();
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
ObjCProtocolDecl::protocol_iterator end);
CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
virtual llvm::Function *ModuleInitFunction();
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
/// which class's method should be called.
CodeGen::RValue
CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
Target = CGF.Builder.CreateBitCast(Target, ClassTy);
CGF.Builder.CreateStore(Target,
CGF.Builder.CreateStructGEP(ObjCSuper, 1));
- return EmitLegacyMessageSend(CGF, ResultType,
+ return EmitLegacyMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, ObjCTypes);
/// Generate code for a message send expression.
CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
const CallArgList &CallArgs,
const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
- return EmitLegacyMessageSend(CGF, ResultType,
+ return EmitLegacyMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs, Method, ObjCTypes);
CodeGen::RValue
CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
llvm::Value *Sel,
llvm::Value *Arg0,
assert(Fn && "EmitLegacyMessageSend - unknown API");
Fn = llvm::ConstantExpr::getBitCast(Fn,
llvm::PointerType::getUnqual(FTy));
- return CGF.EmitCall(FnInfo, Fn, ReturnValueSlot(), ActualArgs);
+ return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
}
llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
Callee = CGF.Builder.CreateBitCast(Callee,
llvm::PointerType::getUnqual(FTy));
- return CGF.EmitCall(FnInfo1, Callee, ReturnValueSlot(), ActualArgs);
+ return CGF.EmitCall(FnInfo1, Callee, Return, ActualArgs);
}
/// Generate code for a message send expression in the nonfragile abi.
CodeGen::RValue
CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return LegacyDispatchedSelector(Sel)
- ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
+ ? EmitLegacyMessageSend(CGF, Return, ResultType,
+ EmitSelector(CGF.Builder, Sel),
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs, Method, ObjCTypes)
- : EmitMessageSend(CGF, ResultType, Sel,
+ : EmitMessageSend(CGF, Return, ResultType, Sel,
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs);
}
/// which class's method should be called.
CodeGen::RValue
CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
CGF.Builder.CreateStructGEP(ObjCSuper, 1));
return (LegacyDispatchedSelector(Sel))
- ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel),
+ ? EmitLegacyMessageSend(CGF, Return, ResultType,
+ EmitSelector(CGF.Builder, Sel),
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, ObjCTypes)
- : EmitMessageSend(CGF, ResultType, Sel,
+ : EmitMessageSend(CGF, Return, ResultType, Sel,
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs);
}
/// a property setter or getter.
virtual CodeGen::RValue
GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot ReturnSlot,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
/// a property setter or getter.
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+ ReturnValueSlot ReturnSlot,
QualType ResultType,
Selector Sel,
const ObjCInterfaceDecl *Class,
llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
- RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
- RValue EmitObjCPropertyGet(const Expr *E);
- RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S);
+ RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
+ ReturnValueSlot Return = ReturnValueSlot());
+ RValue EmitObjCPropertyGet(const Expr *E,
+ ReturnValueSlot Return = ReturnValueSlot());
+ RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S,
+ ReturnValueSlot Return = ReturnValueSlot());
void EmitObjCPropertySet(const Expr *E, RValue Src);
void EmitObjCSuperPropertySet(const Expr *E, const Selector &S, RValue Src);