summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-06-17 06:42:21 +0000
committerJohn McCall <rjmccall@apple.com>2011-06-17 06:42:21 +0000
commitd463132f2727d75d9dce681591e1b9dcd7850563 (patch)
treec3cd2a7b0c2e859be44aada36c6747ae3e4f9668 /clang/lib/CodeGen/CGDecl.cpp
parentdef1949c004610bced78e9468cb4682fcda8efe0 (diff)
downloadbcm5719-llvm-d463132f2727d75d9dce681591e1b9dcd7850563.tar.gz
bcm5719-llvm-d463132f2727d75d9dce681591e1b9dcd7850563.zip
Objective-C fast enumeration loop variables are not retained in ARC, but
they should still be officially __strong for the purposes of errors, block capture, etc. Make a new bit on variables, isARCPseudoStrong(), and set this for 'self' and these enumeration-loop variables. Change the code that was looking for the old patterns to look for this bit, and change IR generation to find this bit and treat the resulting variable as __unsafe_unretained for the purposes of init/destroy in the two places it can come up. llvm-svn: 133243
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp42
1 files changed, 38 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index daa37eea8f0..a79f031ec0a 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -562,6 +562,37 @@ void CodeGenFunction::EmitScalarInit(const Expr *init,
EmitStoreOfScalar(value, lvalue);
}
+/// EmitScalarInit - Initialize the given lvalue with the given object.
+void CodeGenFunction::EmitScalarInit(llvm::Value *init, LValue lvalue) {
+ Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
+ if (!lifetime)
+ return EmitStoreThroughLValue(RValue::get(init), lvalue, lvalue.getType());
+
+ switch (lifetime) {
+ case Qualifiers::OCL_None:
+ llvm_unreachable("present but none");
+
+ case Qualifiers::OCL_ExplicitNone:
+ // nothing to do
+ break;
+
+ case Qualifiers::OCL_Strong:
+ init = EmitARCRetain(lvalue.getType(), init);
+ break;
+
+ case Qualifiers::OCL_Weak:
+ // Initialize and then skip the primitive store.
+ EmitARCInitWeak(lvalue.getAddress(), init);
+ return;
+
+ case Qualifiers::OCL_Autoreleasing:
+ init = EmitARCRetainAutorelease(lvalue.getType(), init);
+ break;
+ }
+
+ EmitStoreOfScalar(init, lvalue);
+}
+
/// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the
/// non-zero parts of the specified initializer with equal or fewer than
/// NumStores scalar stores.
@@ -995,8 +1026,10 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
if (Qualifiers::ObjCLifetime lifetime
= D.getType().getQualifiers().getObjCLifetime()) {
- llvm::Value *loc = emission.getObjectAddress(*this);
- EmitAutoVarWithLifetime(*this, D, loc, lifetime);
+ if (!D.isARCPseudoStrong()) {
+ llvm::Value *loc = emission.getObjectAddress(*this);
+ EmitAutoVarWithLifetime(*this, D, loc, lifetime);
+ }
}
// Handle the cleanup attribute.
@@ -1081,10 +1114,11 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
// 'self' is always formally __strong, but if this is not an
// init method then we don't want to retain it.
- if (lt == Qualifiers::OCL_Strong && qs.hasConst() &&
- isa<ImplicitParamDecl>(D)) {
+ if (D.isARCPseudoStrong()) {
const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CurCodeDecl);
assert(&D == method->getSelfDecl());
+ assert(lt == Qualifiers::OCL_Strong);
+ assert(qs.hasConst());
assert(method->getMethodFamily() != OMF_init);
(void) method;
lt = Qualifiers::OCL_ExplicitNone;
OpenPOWER on IntegriCloud