const CGFunctionInfo &fnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
fnType->getReturnType(), args, fnType->getExtInfo(),
fnType->isVariadic());
- if (CGM.ReturnTypeUsesSRet(fnInfo))
+ if (CGM.ReturnSlotInterferesWithArgs(fnInfo))
blockInfo.UsesStret = true;
llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
return FI.getReturnInfo().isIndirect();
}
+bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
+ return ReturnTypeUsesSRet(FI) &&
+ getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();
+}
+
bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
switch (BT->getKind()) {
NullReturnState nullReturn;
llvm::Constant *Fn = NULL;
- if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
+ if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
if (!IsSuper) nullReturn.init(CGF, Arg0);
Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
: ObjCTypes.getSendStretFn(IsSuper);
Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
: ObjCTypes.getSendFp2retFn(IsSuper);
} else {
+ // arm64 uses objc_msgSend for stret methods and yet null receiver check
+ // must be made for it.
+ if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
+ nullReturn.init(CGF, Arg0);
Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
: ObjCTypes.getSendFn(IsSuper);
}
// FIXME: don't use this for that.
llvm::Constant *fn = 0;
std::string messageRefName("\01l_");
- if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
+ if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
if (isSuper) {
fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
messageRefName += "objc_msgSendSuper2_stret_fixup";
/// as a return type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
+ /// ReturnSlotInterferesWithArgs - Return true iff the given type uses an
+ /// argument slot when 'sret' is used as a return type.
+ bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);
+
/// ReturnTypeUsesFPRet - Return true iff the given type uses 'fpret' when
/// used as a return type.
bool ReturnTypeUsesFPRet(QualType ResultType);
return Ty;
}
+ /// doesReturnSlotInterfereWithArgs - Return true if the target uses an
+ /// argument slot for an 'sret' type.
+ virtual bool doesReturnSlotInterfereWithArgs() const { return true; }
+
/// Retrieve the address of a function to call immediately before
/// calling objc_retainAutoreleasedReturnValue. The
/// implementation of objc_autoreleaseReturnValue sniffs the