diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-04 18:33:06 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-04 18:33:06 +0000 |
commit | 1e36882b5291d5a7209be4f9c99b9713828afac4 (patch) | |
tree | cd23171fec5d69fd0390b0ad9303f51396072b5c /clang/lib/CodeGen/CGDecl.cpp | |
parent | 6153565511338f33506f4615dd5a7d2e4c4ffaa6 (diff) | |
download | llvm-1e36882b5291d5a7209be4f9c99b9713828afac4.zip llvm-1e36882b5291d5a7209be4f9c99b9713828afac4.tar.gz llvm-1e36882b5291d5a7209be4f9c99b9713828afac4.tar.bz2 |
[ObjCARC] Add an new attribute, objc_externally_retained
This attribute, called "objc_externally_retained", exposes clang's
notion of pseudo-__strong variables in ARC. Pseudo-strong variables
"borrow" their initializer, meaning that they don't retain/release
it, instead assuming that someone else is keeping their value alive.
If a function is annotated with this attribute, implicitly strong
parameters of that function aren't implicitly retained/released in
the function body, and are implicitly const. This is useful to expose
for performance reasons, most functions don't need the extra safety
of the retain/release, so programmers can opt out as needed.
This attribute can also apply to declarations of local variables,
with similar effect.
Differential revision: https://reviews.llvm.org/D55865
llvm-svn: 350422
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 2262c99..5959d88 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -797,15 +797,21 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D, case Qualifiers::OCL_None: llvm_unreachable("present but none"); + case Qualifiers::OCL_Strong: { + if (!D || !isa<VarDecl>(D) || !cast<VarDecl>(D)->isARCPseudoStrong()) { + value = EmitARCRetainScalarExpr(init); + break; + } + // If D is pseudo-strong, treat it like __unsafe_unretained here. This means + // that we omit the retain, and causes non-autoreleased return values to be + // immediately released. + LLVM_FALLTHROUGH; + } + case Qualifiers::OCL_ExplicitNone: value = EmitARCUnsafeUnretainedScalarExpr(init); break; - case Qualifiers::OCL_Strong: { - value = EmitARCRetainScalarExpr(init); - break; - } - case Qualifiers::OCL_Weak: { // If it's not accessed by the initializer, try to emit the // initialization with a copy or move. @@ -2324,15 +2330,11 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // cleanup to do the release at the end of the function. bool isConsumed = D.hasAttr<NSConsumedAttr>(); - // 'self' is always formally __strong, but if this is not an - // init method then we don't want to retain it. + // If a parameter is pseudo-strong then we can omit the implicit retain. 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; + assert(lt == Qualifiers::OCL_Strong && + "pseudo-strong variable isn't strong?"); + assert(qs.hasConst() && "pseudo-strong variable should be const!"); lt = Qualifiers::OCL_ExplicitNone; } |