summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-27 01:07:15 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-27 01:07:15 +0000
commit538482373bba8f268b179eabde85652f630af826 (patch)
tree6ec28341ca229e59b56dde319ce3b726a6d17b1c /clang/lib/CodeGen/CGObjC.cpp
parentb23dc0950b61d560b276d25654a4627dbbb666e7 (diff)
downloadbcm5719-llvm-538482373bba8f268b179eabde85652f630af826.tar.gz
bcm5719-llvm-538482373bba8f268b179eabde85652f630af826.zip
Clean up the analysis of the collection operand to ObjC
for-in statements; specifically, make sure to close over any temporaries or cleanups it might require. In ARC, this has implications for the lifetime of the collection, so emit it with a retain and release it upon exit from the loop. rdar://problem/9817306 llvm-svn: 136204
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index c817115cbe5..f81b6b75e3f 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1020,8 +1020,16 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
ArrayType::Normal, 0);
llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
- // Emit the collection pointer.
- llvm::Value *Collection = EmitScalarExpr(S.getCollection());
+ // Emit the collection pointer. In ARC, we do a retain.
+ llvm::Value *Collection;
+ if (getLangOptions().ObjCAutoRefCount) {
+ Collection = EmitARCRetainScalarExpr(S.getCollection());
+
+ // Enter a cleanup to do the release.
+ EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
+ } else {
+ Collection = EmitScalarExpr(S.getCollection());
+ }
// Send it our message:
CallArgList Args;
@@ -1236,6 +1244,10 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
DI->EmitRegionEnd(Builder);
}
+ // Leave the cleanup we entered in ARC.
+ if (getLangOptions().ObjCAutoRefCount)
+ PopCleanupBlock();
+
EmitBlock(LoopEnd.getBlock());
}
@@ -1967,6 +1979,12 @@ static llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
+ // Look through cleanups.
+ if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
+ CodeGenFunction::RunCleanupsScope scope(CGF);
+ return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr());
+ }
+
// The desired result type, if it differs from the type of the
// ultimate opaque expression.
llvm::Type *resultType = 0;
OpenPOWER on IntegriCloud