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.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133840 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2011-06-24 23:21:27 +00:00
Родитель 537c346116
Коммит 0c24c808e4
3 изменённых файлов: 42 добавлений и 0 удалений

Просмотреть файл

@ -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<VarDecl*>(&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<ObjCPreciseLifetimeAttr>()) {
EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D);
}
// Handle the cleanup attribute.
if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
const FunctionDecl *FD = CA->getFunctionDecl();

Просмотреть файл

@ -2484,4 +2484,22 @@ void CodeGenFunction::EmitObjCAutoreleasePoolStmt(
DI->EmitRegionEnd(Builder);
}
}
/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
/// make sure it survives garbage collection until this point.
void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
// We just use an inline assembly.
const llvm::Type *paramTypes[] = { VoidPtrTy };
llvm::FunctionType *extenderType
= llvm::FunctionType::get(VoidTy, paramTypes, /*variadic*/ false);
llvm::Value *extender
= llvm::InlineAsm::get(extenderType,
/* assembly */ "",
/* constraints */ "r",
/* side effects */ true);
object = Builder.CreateBitCast(object, VoidPtrTy);
Builder.CreateCall(extender, object)->setDoesNotThrow();
}
CGObjCRuntime::~CGObjCRuntime() {}

Просмотреть файл

@ -2146,6 +2146,10 @@ public:
void EmitGCMemmoveCollectable(llvm::Value *DestPtr, llvm::Value *SrcPtr,
QualType Ty);
/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
/// make sure it survives garbage collection until this point.
void EmitExtendGCLifetime(llvm::Value *object);
/// EmitComplexExpr - Emit the computation of the specified expression of
/// complex type, returning the result.
ComplexPairTy EmitComplexExpr(const Expr *E,