From 1bd2556cccdb1336bf05e2e34d2d972ea484046e Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 24 Jun 2011 23:21:27 +0000 Subject: Honor objc_precise_lifetime in GC mode by feeding the value in the variable to an inline asm which gets run when the variable goes out of scope. llvm-svn: 133840 --- clang/lib/CodeGen/CGDecl.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'clang/lib/CodeGen/CGDecl.cpp') diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index b6ad130a403..7e126d95e18 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -364,6 +364,20 @@ namespace { } }; + struct ExtendGCLifetime : EHScopeStack::Cleanup { + const VarDecl &Var; + ExtendGCLifetime(const VarDecl *var) : Var(*var) {} + + void Emit(CodeGenFunction &CGF, bool forEH) { + // Compute the address of the local variable, in case it's a + // byref or something. + DeclRefExpr DRE(const_cast(&Var), Var.getType(), VK_LValue, + SourceLocation()); + llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE)); + CGF.EmitExtendGCLifetime(value); + } + }; + struct CallCleanupFunction : EHScopeStack::Cleanup { llvm::Constant *CleanupFn; const CGFunctionInfo &FnInfo; @@ -1029,6 +1043,12 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { } } + // In GC mode, honor objc_precise_lifetime. + if (getLangOptions().getGCMode() != LangOptions::NonGC && + D.hasAttr()) { + EHStack.pushCleanup(NormalCleanup, &D); + } + // Handle the cleanup attribute. if (const CleanupAttr *CA = D.getAttr()) { const FunctionDecl *FD = CA->getFunctionDecl(); -- cgit v1.2.3