|
@@ -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;
|
|
|
|
- break;
|
|
|
|
|
|
+ return destroyCXXObject;
|
|
case QualType::DK_objc_strong_lifetime:
|
|
case QualType::DK_objc_strong_lifetime:
|
|
- destroyer = &destroyARCStrongPrecise;
|
|
|
|
- break;
|
|
|
|
|
|
+ return destroyARCStrongPrecise;
|
|
case QualType::DK_objc_weak_lifetime:
|
|
case QualType::DK_objc_weak_lifetime:
|
|
- destroyer = &destroyARCWeak;
|
|
|
|
- break;
|
|
|
|
|
|
+ return destroyARCWeak;
|
|
}
|
|
}
|
|
- 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 {
|