forked from OSchip/llvm-project
Use function pointers, rather than references, to pass Destroyers
around, in the process cleaning up the various gcc/msvc compiler workarounds. llvm-svn: 149036
This commit is contained in:
parent
e67bb67a9b
commit
1425b4556a
|
@ -535,9 +535,9 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
|
||||||
// Block captures count as local values and have imprecise semantics.
|
// Block captures count as local values and have imprecise semantics.
|
||||||
// They also can't be arrays, so need to worry about that.
|
// They also can't be arrays, so need to worry about that.
|
||||||
if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
||||||
destroyer = &CodeGenFunction::destroyARCStrongImprecise;
|
destroyer = CodeGenFunction::destroyARCStrongImprecise;
|
||||||
} else {
|
} else {
|
||||||
destroyer = &CGF.getDestroyer(dtorKind);
|
destroyer = CGF.getDestroyer(dtorKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GEP down to the address.
|
// GEP down to the address.
|
||||||
|
@ -554,7 +554,7 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
|
||||||
cleanupKind = InactiveNormalAndEHCleanup;
|
cleanupKind = InactiveNormalAndEHCleanup;
|
||||||
|
|
||||||
CGF.pushDestroy(cleanupKind, addr, variable->getType(),
|
CGF.pushDestroy(cleanupKind, addr, variable->getType(),
|
||||||
*destroyer, useArrayEHCleanup);
|
destroyer, useArrayEHCleanup);
|
||||||
|
|
||||||
// Remember where that cleanup was.
|
// Remember where that cleanup was.
|
||||||
capture.setCleanup(CGF.EHStack.stable_begin());
|
capture.setCleanup(CGF.EHStack.stable_begin());
|
||||||
|
|
|
@ -945,13 +945,13 @@ namespace {
|
||||||
|
|
||||||
class DestroyField : public EHScopeStack::Cleanup {
|
class DestroyField : public EHScopeStack::Cleanup {
|
||||||
const FieldDecl *field;
|
const FieldDecl *field;
|
||||||
CodeGenFunction::Destroyer &destroyer;
|
CodeGenFunction::Destroyer *destroyer;
|
||||||
bool useEHCleanupForArray;
|
bool useEHCleanupForArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
|
DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray)
|
bool useEHCleanupForArray)
|
||||||
: field(field), destroyer(*destroyer),
|
: field(field), destroyer(destroyer),
|
||||||
useEHCleanupForArray(useEHCleanupForArray) {}
|
useEHCleanupForArray(useEHCleanupForArray) {}
|
||||||
|
|
||||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||||
|
|
|
@ -1098,8 +1098,6 @@ llvm::Value *CodeGenFunction::getNormalCleanupDestSlot() {
|
||||||
void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
|
void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
|
||||||
QualType TempType,
|
QualType TempType,
|
||||||
llvm::Value *Ptr) {
|
llvm::Value *Ptr) {
|
||||||
// This local is a GCC and MSVC compiler workaround.
|
pushDestroy(NormalAndEHCleanup, Ptr, TempType, destroyCXXObject,
|
||||||
Destroyer *destroyer = &destroyCXXObject;
|
|
||||||
pushDestroy(NormalAndEHCleanup, Ptr, TempType, *destroyer,
|
|
||||||
/*useEHCleanup*/ true);
|
/*useEHCleanup*/ true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,12 +310,12 @@ namespace {
|
||||||
DestroyObject(llvm::Value *addr, QualType type,
|
DestroyObject(llvm::Value *addr, QualType type,
|
||||||
CodeGenFunction::Destroyer *destroyer,
|
CodeGenFunction::Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray)
|
bool useEHCleanupForArray)
|
||||||
: addr(addr), type(type), destroyer(*destroyer),
|
: addr(addr), type(type), destroyer(destroyer),
|
||||||
useEHCleanupForArray(useEHCleanupForArray) {}
|
useEHCleanupForArray(useEHCleanupForArray) {}
|
||||||
|
|
||||||
llvm::Value *addr;
|
llvm::Value *addr;
|
||||||
QualType type;
|
QualType type;
|
||||||
CodeGenFunction::Destroyer &destroyer;
|
CodeGenFunction::Destroyer *destroyer;
|
||||||
bool useEHCleanupForArray;
|
bool useEHCleanupForArray;
|
||||||
|
|
||||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||||
|
@ -430,7 +430,7 @@ static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qualifiers::OCL_Strong: {
|
case Qualifiers::OCL_Strong: {
|
||||||
CodeGenFunction::Destroyer &destroyer =
|
CodeGenFunction::Destroyer *destroyer =
|
||||||
(var.hasAttr<ObjCPreciseLifetimeAttr>()
|
(var.hasAttr<ObjCPreciseLifetimeAttr>()
|
||||||
? CodeGenFunction::destroyARCStrongPrecise
|
? CodeGenFunction::destroyARCStrongPrecise
|
||||||
: CodeGenFunction::destroyARCStrongImprecise);
|
: CodeGenFunction::destroyARCStrongImprecise);
|
||||||
|
@ -1111,7 +1111,7 @@ void CodeGenFunction::emitAutoVarTypeCleanup(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we haven't chosen a more specific destroyer, use the default.
|
// If we haven't chosen a more specific destroyer, use the default.
|
||||||
if (!destroyer) destroyer = &getDestroyer(dtorKind);
|
if (!destroyer) destroyer = getDestroyer(dtorKind);
|
||||||
|
|
||||||
// Use an EH cleanup in array destructors iff the destructor itself
|
// Use an EH cleanup in array destructors iff the destructor itself
|
||||||
// is being pushed as an EH cleanup.
|
// is being pushed as an EH cleanup.
|
||||||
|
@ -1155,25 +1155,17 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
|
||||||
enterByrefCleanup(emission);
|
enterByrefCleanup(emission);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGenFunction::Destroyer &
|
CodeGenFunction::Destroyer *
|
||||||
CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
|
CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
|
||||||
// This is surprisingly compiler-dependent. GCC 4.2 can't bind
|
|
||||||
// references to functions directly in returns, and using '*&foo'
|
|
||||||
// confuses MSVC. Luckily, the following code pattern works in both.
|
|
||||||
Destroyer *destroyer = 0;
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
|
case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
|
||||||
case QualType::DK_cxx_destructor:
|
case QualType::DK_cxx_destructor:
|
||||||
destroyer = &destroyCXXObject;
|
return destroyCXXObject;
|
||||||
break;
|
|
||||||
case QualType::DK_objc_strong_lifetime:
|
case QualType::DK_objc_strong_lifetime:
|
||||||
destroyer = &destroyARCStrongPrecise;
|
return destroyARCStrongPrecise;
|
||||||
break;
|
|
||||||
case QualType::DK_objc_weak_lifetime:
|
case QualType::DK_objc_weak_lifetime:
|
||||||
destroyer = &destroyARCWeak;
|
return destroyARCWeak;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return *destroyer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pushDestroy - Push the standard destructor for the given type.
|
/// pushDestroy - Push the standard destructor for the given type.
|
||||||
|
@ -1187,7 +1179,7 @@ void CodeGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, llvm::Value *addr,
|
void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, llvm::Value *addr,
|
||||||
QualType type, Destroyer &destroyer,
|
QualType type, Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray) {
|
bool useEHCleanupForArray) {
|
||||||
pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type,
|
pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type,
|
||||||
destroyer, useEHCleanupForArray);
|
destroyer, useEHCleanupForArray);
|
||||||
|
@ -1205,7 +1197,7 @@ void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, llvm::Value *addr,
|
||||||
/// used when destroying array elements, in case one of the
|
/// used when destroying array elements, in case one of the
|
||||||
/// destructions throws an exception
|
/// destructions throws an exception
|
||||||
void CodeGenFunction::emitDestroy(llvm::Value *addr, QualType type,
|
void CodeGenFunction::emitDestroy(llvm::Value *addr, QualType type,
|
||||||
Destroyer &destroyer,
|
Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray) {
|
bool useEHCleanupForArray) {
|
||||||
const ArrayType *arrayType = getContext().getAsArrayType(type);
|
const ArrayType *arrayType = getContext().getAsArrayType(type);
|
||||||
if (!arrayType)
|
if (!arrayType)
|
||||||
|
@ -1242,7 +1234,7 @@ void CodeGenFunction::emitDestroy(llvm::Value *addr, QualType type,
|
||||||
void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
|
void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
|
||||||
llvm::Value *end,
|
llvm::Value *end,
|
||||||
QualType type,
|
QualType type,
|
||||||
Destroyer &destroyer,
|
Destroyer *destroyer,
|
||||||
bool checkZeroLength,
|
bool checkZeroLength,
|
||||||
bool useEHCleanup) {
|
bool useEHCleanup) {
|
||||||
assert(!type->isArrayType());
|
assert(!type->isArrayType());
|
||||||
|
@ -1293,7 +1285,7 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
|
||||||
static void emitPartialArrayDestroy(CodeGenFunction &CGF,
|
static void emitPartialArrayDestroy(CodeGenFunction &CGF,
|
||||||
llvm::Value *begin, llvm::Value *end,
|
llvm::Value *begin, llvm::Value *end,
|
||||||
QualType type,
|
QualType type,
|
||||||
CodeGenFunction::Destroyer &destroyer) {
|
CodeGenFunction::Destroyer *destroyer) {
|
||||||
// If the element type is itself an array, drill down.
|
// If the element type is itself an array, drill down.
|
||||||
unsigned arrayDepth = 0;
|
unsigned arrayDepth = 0;
|
||||||
while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) {
|
while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) {
|
||||||
|
@ -1326,13 +1318,13 @@ namespace {
|
||||||
llvm::Value *ArrayBegin;
|
llvm::Value *ArrayBegin;
|
||||||
llvm::Value *ArrayEnd;
|
llvm::Value *ArrayEnd;
|
||||||
QualType ElementType;
|
QualType ElementType;
|
||||||
CodeGenFunction::Destroyer &Destroyer;
|
CodeGenFunction::Destroyer *Destroyer;
|
||||||
public:
|
public:
|
||||||
RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
|
RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
CodeGenFunction::Destroyer *destroyer)
|
CodeGenFunction::Destroyer *destroyer)
|
||||||
: ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
|
: ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
|
||||||
ElementType(elementType), Destroyer(*destroyer) {}
|
ElementType(elementType), Destroyer(destroyer) {}
|
||||||
|
|
||||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||||
emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
|
emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
|
||||||
|
@ -1347,14 +1339,14 @@ namespace {
|
||||||
llvm::Value *ArrayBegin;
|
llvm::Value *ArrayBegin;
|
||||||
llvm::Value *ArrayEndPointer;
|
llvm::Value *ArrayEndPointer;
|
||||||
QualType ElementType;
|
QualType ElementType;
|
||||||
CodeGenFunction::Destroyer &Destroyer;
|
CodeGenFunction::Destroyer *Destroyer;
|
||||||
public:
|
public:
|
||||||
IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
|
IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
|
||||||
llvm::Value *arrayEndPointer,
|
llvm::Value *arrayEndPointer,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
CodeGenFunction::Destroyer *destroyer)
|
CodeGenFunction::Destroyer *destroyer)
|
||||||
: ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
|
: ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
|
||||||
ElementType(elementType), Destroyer(*destroyer) {}
|
ElementType(elementType), Destroyer(destroyer) {}
|
||||||
|
|
||||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||||
llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
|
llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
|
||||||
|
@ -1377,10 +1369,10 @@ namespace {
|
||||||
void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
||||||
llvm::Value *arrayEndPointer,
|
llvm::Value *arrayEndPointer,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
Destroyer &destroyer) {
|
Destroyer *destroyer) {
|
||||||
pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
|
pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
|
||||||
arrayBegin, arrayEndPointer,
|
arrayBegin, arrayEndPointer,
|
||||||
elementType, &destroyer);
|
elementType, destroyer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
|
/// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
|
||||||
|
@ -1396,10 +1388,10 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
||||||
void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
|
void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
|
||||||
llvm::Value *arrayEnd,
|
llvm::Value *arrayEnd,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
Destroyer &destroyer) {
|
Destroyer *destroyer) {
|
||||||
pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup,
|
pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup,
|
||||||
arrayBegin, arrayEnd,
|
arrayBegin, arrayEnd,
|
||||||
elementType, &destroyer);
|
elementType, destroyer);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -343,7 +343,7 @@ void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
|
||||||
llvm::Function *
|
llvm::Function *
|
||||||
CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
|
CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
|
||||||
QualType type,
|
QualType type,
|
||||||
Destroyer &destroyer,
|
Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray) {
|
bool useEHCleanupForArray) {
|
||||||
FunctionArgList args;
|
FunctionArgList args;
|
||||||
ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
|
ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
|
||||||
|
|
|
@ -487,21 +487,17 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
|
||||||
case Qualifiers::OCL_Strong: {
|
case Qualifiers::OCL_Strong: {
|
||||||
bool precise = VD && VD->hasAttr<ObjCPreciseLifetimeAttr>();
|
bool precise = VD && VD->hasAttr<ObjCPreciseLifetimeAttr>();
|
||||||
CleanupKind cleanupKind = getARCCleanupKind();
|
CleanupKind cleanupKind = getARCCleanupKind();
|
||||||
// This local is a GCC and MSVC compiler workaround.
|
|
||||||
Destroyer *destroyer = precise ? &destroyARCStrongPrecise :
|
|
||||||
&destroyARCStrongImprecise;
|
|
||||||
pushDestroy(cleanupKind, ReferenceTemporary, ObjCARCReferenceLifetimeType,
|
pushDestroy(cleanupKind, ReferenceTemporary, ObjCARCReferenceLifetimeType,
|
||||||
*destroyer, cleanupKind & EHCleanup);
|
precise ? destroyARCStrongPrecise : destroyARCStrongImprecise,
|
||||||
|
cleanupKind & EHCleanup);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qualifiers::OCL_Weak: {
|
case Qualifiers::OCL_Weak: {
|
||||||
// This local is a GCC and MSVC compiler workaround.
|
|
||||||
Destroyer *destroyer = &destroyARCWeak;
|
|
||||||
// __weak objects always get EH cleanups; otherwise, exceptions
|
// __weak objects always get EH cleanups; otherwise, exceptions
|
||||||
// could cause really nasty crashes instead of mere leaks.
|
// could cause really nasty crashes instead of mere leaks.
|
||||||
pushDestroy(NormalAndEHCleanup, ReferenceTemporary,
|
pushDestroy(NormalAndEHCleanup, ReferenceTemporary,
|
||||||
ObjCARCReferenceLifetimeType, *destroyer, true);
|
ObjCARCReferenceLifetimeType, destroyARCWeak, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1047,13 +1047,13 @@ namespace {
|
||||||
private:
|
private:
|
||||||
llvm::Value *addr;
|
llvm::Value *addr;
|
||||||
const ObjCIvarDecl *ivar;
|
const ObjCIvarDecl *ivar;
|
||||||
CodeGenFunction::Destroyer &destroyer;
|
CodeGenFunction::Destroyer *destroyer;
|
||||||
bool useEHCleanupForArray;
|
bool useEHCleanupForArray;
|
||||||
public:
|
public:
|
||||||
DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
|
DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
|
||||||
CodeGenFunction::Destroyer *destroyer,
|
CodeGenFunction::Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray)
|
bool useEHCleanupForArray)
|
||||||
: addr(addr), ivar(ivar), destroyer(*destroyer),
|
: addr(addr), ivar(ivar), destroyer(destroyer),
|
||||||
useEHCleanupForArray(useEHCleanupForArray) {}
|
useEHCleanupForArray(useEHCleanupForArray) {}
|
||||||
|
|
||||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||||
|
@ -1093,11 +1093,11 @@ static void emitCXXDestructMethod(CodeGenFunction &CGF,
|
||||||
// Use a call to objc_storeStrong to destroy strong ivars, for the
|
// Use a call to objc_storeStrong to destroy strong ivars, for the
|
||||||
// general benefit of the tools.
|
// general benefit of the tools.
|
||||||
if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
||||||
destroyer = &destroyARCStrongWithStore;
|
destroyer = destroyARCStrongWithStore;
|
||||||
|
|
||||||
// Otherwise use the default for the destruction kind.
|
// Otherwise use the default for the destruction kind.
|
||||||
} else {
|
} else {
|
||||||
destroyer = &CGF.getDestroyer(dtorKind);
|
destroyer = CGF.getDestroyer(dtorKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
|
CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
|
||||||
|
|
|
@ -1244,27 +1244,27 @@ public:
|
||||||
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
||||||
llvm::Value *arrayEndPointer,
|
llvm::Value *arrayEndPointer,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
Destroyer &destroyer);
|
Destroyer *destroyer);
|
||||||
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
|
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
|
||||||
llvm::Value *arrayEnd,
|
llvm::Value *arrayEnd,
|
||||||
QualType elementType,
|
QualType elementType,
|
||||||
Destroyer &destroyer);
|
Destroyer *destroyer);
|
||||||
|
|
||||||
void pushDestroy(QualType::DestructionKind dtorKind,
|
void pushDestroy(QualType::DestructionKind dtorKind,
|
||||||
llvm::Value *addr, QualType type);
|
llvm::Value *addr, QualType type);
|
||||||
void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type,
|
void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type,
|
||||||
Destroyer &destroyer, bool useEHCleanupForArray);
|
Destroyer *destroyer, bool useEHCleanupForArray);
|
||||||
void emitDestroy(llvm::Value *addr, QualType type, Destroyer &destroyer,
|
void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray);
|
bool useEHCleanupForArray);
|
||||||
llvm::Function *generateDestroyHelper(llvm::Constant *addr,
|
llvm::Function *generateDestroyHelper(llvm::Constant *addr,
|
||||||
QualType type,
|
QualType type,
|
||||||
Destroyer &destroyer,
|
Destroyer *destroyer,
|
||||||
bool useEHCleanupForArray);
|
bool useEHCleanupForArray);
|
||||||
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
|
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
|
||||||
QualType type, Destroyer &destroyer,
|
QualType type, Destroyer *destroyer,
|
||||||
bool checkZeroLength, bool useEHCleanup);
|
bool checkZeroLength, bool useEHCleanup);
|
||||||
|
|
||||||
Destroyer &getDestroyer(QualType::DestructionKind destructionKind);
|
Destroyer *getDestroyer(QualType::DestructionKind destructionKind);
|
||||||
|
|
||||||
/// Determines whether an EH cleanup is required to destroy a type
|
/// Determines whether an EH cleanup is required to destroy a type
|
||||||
/// with the given destruction kind.
|
/// with the given destruction kind.
|
||||||
|
|
Loading…
Reference in New Issue