summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp75
1 files changed, 17 insertions, 58 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index ecf6181b1ce..8bd96382c9e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1392,63 +1392,6 @@ public:
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
};
-
-/// A helper class for performing the null-initialization of a return
-/// value.
-struct NullReturnState {
- llvm::BasicBlock *NullBB;
- llvm::BasicBlock *callBB;
- NullReturnState() : NullBB(0), callBB(0) {}
-
- void init(CodeGenFunction &CGF, llvm::Value *receiver) {
- // Make blocks for the null-init and call edges.
- NullBB = CGF.createBasicBlock("msgSend.nullinit");
- callBB = CGF.createBasicBlock("msgSend.call");
-
- // Check for a null receiver and, if there is one, jump to the
- // null-init test.
- llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
- CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
-
- // Otherwise, start performing the call.
- CGF.EmitBlock(callBB);
- }
-
- RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType) {
- if (!NullBB) return result;
-
- // Finish the call path.
- llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
- if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
-
- // Emit the null-init block and perform the null-initialization there.
- CGF.EmitBlock(NullBB);
- if (!resultType->isAnyComplexType()) {
- assert(result.isAggregate() && "null init of non-aggregate result?");
- CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
- // Jump to the continuation block.
- CGF.EmitBlock(contBB);
- return result;
- }
-
- // _Complex type
- // FIXME. Now easy to handle any other scalar type whose result is returned
- // in memory due to ABI limitations.
- CGF.EmitBlock(contBB);
- CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal();
- llvm::Type *MemberType = CallCV.first->getType();
- llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType);
- // Create phi instruction for scalar complex value.
- llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2);
- PHIReal->addIncoming(ZeroCV, NullBB);
- PHIReal->addIncoming(CallCV.first, callBB);
- llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2);
- PHIImag->addIncoming(ZeroCV, NullBB);
- PHIImag->addIncoming(CallCV.second, callBB);
- return RValue::getComplex(PHIReal, PHIImag);
- }
-};
-
} // end anonymous namespace
/* *** Helper Functions *** */
@@ -1655,7 +1598,23 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
llvm::Constant *Fn = NULL;
if (CGM.ReturnTypeUsesSRet(FnInfo)) {
- if (!IsSuper) nullReturn.init(CGF, Arg0);
+ if (!IsSuper) {
+ bool nullCheckAlreadyDone = false;
+ // We have already done this computation once and flag could have been
+ // passed down. But such cases are extremely rare and we do this lazily,
+ // instead of absorbing cost of passing down a flag for all cases.
+ if (CGM.getLangOptions().ObjCAutoRefCount && Method)
+ for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
+ e = Method->param_end(); i != e; ++i) {
+ if ((*i)->hasAttr<NSConsumedAttr>()) {
+ nullCheckAlreadyDone = true;
+ break;
+ }
+ }
+ if (!nullCheckAlreadyDone)
+ nullReturn.init(CGF, Arg0);
+ }
+
Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
: ObjCTypes.getSendStretFn(IsSuper);
} else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
OpenPOWER on IntegriCloud