зеркало из https://github.com/microsoft/clang-1.git
Generalize Cleanup::Emit's "isForEH" parameter into a set
of flags. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134997 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bb52786da8
Коммит
ad346f4f67
|
@ -1799,7 +1799,7 @@ namespace {
|
|||
llvm::Value *Addr;
|
||||
CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Should we be passing FIELD_IS_WEAK here?
|
||||
CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF);
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace {
|
|||
CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual)
|
||||
: BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const CXXRecordDecl *DerivedClass =
|
||||
cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
|
||||
|
||||
|
@ -511,7 +511,7 @@ namespace {
|
|||
CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
|
||||
: Field(Field), Dtor(Dtor) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// FIXME: Is this OK for C++0x delegating constructors?
|
||||
llvm::Value *ThisPtr = CGF.LoadCXXThis();
|
||||
LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
|
||||
|
@ -921,7 +921,7 @@ namespace {
|
|||
struct CallDtorDelete : EHScopeStack::Cleanup {
|
||||
CallDtorDelete() {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
|
||||
const CXXRecordDecl *ClassDecl = Dtor->getParent();
|
||||
CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(),
|
||||
|
@ -940,14 +940,14 @@ namespace {
|
|||
: field(field), destroyer(*destroyer),
|
||||
useEHCleanupForArray(useEHCleanupForArray) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Find the address of the field.
|
||||
llvm::Value *thisValue = CGF.LoadCXXThis();
|
||||
LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0);
|
||||
assert(LV.isSimple());
|
||||
|
||||
CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer,
|
||||
!isForEH && useEHCleanupForArray);
|
||||
flags.isForNormalCleanup() && useEHCleanupForArray);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1356,7 +1356,7 @@ namespace {
|
|||
CXXDtorType Type)
|
||||
: Dtor(D), Addr(Addr), Type(Type) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
|
||||
Addr);
|
||||
}
|
||||
|
@ -1411,7 +1411,7 @@ namespace {
|
|||
CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr)
|
||||
: Dtor(D), Addr(Addr) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
|
||||
/*ForVirtualBase=*/false, Addr);
|
||||
}
|
||||
|
|
|
@ -436,10 +436,10 @@ static llvm::BasicBlock *SimplifyCleanupEntry(CodeGenFunction &CGF,
|
|||
|
||||
static void EmitCleanup(CodeGenFunction &CGF,
|
||||
EHScopeStack::Cleanup *Fn,
|
||||
bool ForEH,
|
||||
EHScopeStack::Cleanup::Flags flags,
|
||||
llvm::Value *ActiveFlag) {
|
||||
// EH cleanups always occur within a terminate scope.
|
||||
if (ForEH) CGF.EHStack.pushTerminate();
|
||||
if (flags.isForEHCleanup()) CGF.EHStack.pushTerminate();
|
||||
|
||||
// If there's an active flag, load it and skip the cleanup if it's
|
||||
// false.
|
||||
|
@ -454,7 +454,7 @@ static void EmitCleanup(CodeGenFunction &CGF,
|
|||
}
|
||||
|
||||
// Ask the cleanup to emit itself.
|
||||
Fn->Emit(CGF, ForEH);
|
||||
Fn->Emit(CGF, flags);
|
||||
assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");
|
||||
|
||||
// Emit the continuation block if there was an active flag.
|
||||
|
@ -462,7 +462,7 @@ static void EmitCleanup(CodeGenFunction &CGF,
|
|||
CGF.EmitBlock(ContBB);
|
||||
|
||||
// Leave the terminate scope.
|
||||
if (ForEH) CGF.EHStack.popTerminate();
|
||||
if (flags.isForEHCleanup()) CGF.EHStack.popTerminate();
|
||||
}
|
||||
|
||||
static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit,
|
||||
|
@ -537,6 +537,12 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
|
|||
RequiresNormalCleanup = true;
|
||||
}
|
||||
|
||||
EHScopeStack::Cleanup::Flags cleanupFlags;
|
||||
if (Scope.isNormalCleanup())
|
||||
cleanupFlags.setIsNormalCleanupKind();
|
||||
if (Scope.isEHCleanup())
|
||||
cleanupFlags.setIsEHCleanupKind();
|
||||
|
||||
// Even if we don't need the normal cleanup, we might still have
|
||||
// prebranched fallthrough to worry about.
|
||||
if (Scope.isNormalCleanup() && !RequiresNormalCleanup &&
|
||||
|
@ -660,7 +666,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
|
|||
|
||||
EHStack.popCleanup();
|
||||
|
||||
EmitCleanup(*this, Fn, /*ForEH*/ false, NormalActiveFlag);
|
||||
EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
|
||||
|
||||
// Otherwise, the best approach is to thread everything through
|
||||
// the cleanup block and then try to clean up after ourselves.
|
||||
|
@ -771,7 +777,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
|
|||
EHStack.popCleanup();
|
||||
assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);
|
||||
|
||||
EmitCleanup(*this, Fn, /*ForEH*/ false, NormalActiveFlag);
|
||||
EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
|
||||
|
||||
// Append the prepared cleanup prologue from above.
|
||||
llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();
|
||||
|
@ -854,7 +860,9 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
|
|||
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
|
||||
|
||||
EmitBlock(EHEntry);
|
||||
EmitCleanup(*this, Fn, /*ForEH*/ true, EHActiveFlag);
|
||||
|
||||
cleanupFlags.setIsForEHCleanup();
|
||||
EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);
|
||||
|
||||
// Append the prepared cleanup prologue from above.
|
||||
llvm::BasicBlock *EHExit = Builder.GetInsertBlock();
|
||||
|
|
|
@ -316,9 +316,10 @@ namespace {
|
|||
CodeGenFunction::Destroyer &destroyer;
|
||||
bool useEHCleanupForArray;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Don't use an EH cleanup recursively from an EH cleanup.
|
||||
bool useEHCleanupForArray = !isForEH && this->useEHCleanupForArray;
|
||||
bool useEHCleanupForArray =
|
||||
flags.isForNormalCleanup() && this->useEHCleanupForArray;
|
||||
|
||||
CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);
|
||||
}
|
||||
|
@ -334,9 +335,9 @@ namespace {
|
|||
llvm::Value *NRVOFlag;
|
||||
llvm::Value *Loc;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Along the exceptions path we always execute the dtor.
|
||||
bool NRVO = !IsForEH && NRVOFlag;
|
||||
bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
|
||||
|
||||
llvm::BasicBlock *SkipDtorBB = 0;
|
||||
if (NRVO) {
|
||||
|
@ -358,7 +359,7 @@ namespace {
|
|||
struct CallStackRestore : EHScopeStack::Cleanup {
|
||||
llvm::Value *Stack;
|
||||
CallStackRestore(llvm::Value *Stack) : Stack(Stack) {}
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
llvm::Value *V = CGF.Builder.CreateLoad(Stack, "tmp");
|
||||
llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
|
||||
CGF.Builder.CreateCall(F, V);
|
||||
|
@ -369,7 +370,7 @@ namespace {
|
|||
const VarDecl &Var;
|
||||
ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool forEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// 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,
|
||||
|
@ -388,7 +389,7 @@ namespace {
|
|||
const VarDecl *Var)
|
||||
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
DeclRefExpr DRE(const_cast<VarDecl*>(&Var), Var.getType(), VK_LValue,
|
||||
SourceLocation());
|
||||
// Compute the address of the local variable, in case it's a byref
|
||||
|
@ -1301,7 +1302,7 @@ namespace {
|
|||
: ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
|
||||
ElementType(elementType), Destroyer(*destroyer) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
|
||||
ElementType, Destroyer);
|
||||
}
|
||||
|
@ -1323,7 +1324,7 @@ namespace {
|
|||
: ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
|
||||
ElementType(elementType), Destroyer(*destroyer) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
|
||||
emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd,
|
||||
ElementType, Destroyer);
|
||||
|
@ -1379,7 +1380,7 @@ namespace {
|
|||
|
||||
llvm::Value *Param;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitARCRelease(Param, /*precise*/ false);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace {
|
|||
struct FreeException : EHScopeStack::Cleanup {
|
||||
llvm::Value *exn;
|
||||
FreeException(llvm::Value *exn) : exn(exn) {}
|
||||
void Emit(CodeGenFunction &CGF, bool forEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.Builder.CreateCall(getFreeExceptionFn(CGF), exn)
|
||||
->setDoesNotThrow();
|
||||
}
|
||||
|
@ -922,7 +922,7 @@ namespace {
|
|||
CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
|
||||
bool MightThrow;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
if (!MightThrow) {
|
||||
CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow();
|
||||
return;
|
||||
|
@ -1140,7 +1140,7 @@ static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {
|
|||
|
||||
namespace {
|
||||
struct CallRethrow : EHScopeStack::Cleanup {
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitCallOrInvoke(getReThrowFn(CGF), 0, 0);
|
||||
}
|
||||
};
|
||||
|
@ -1212,7 +1212,7 @@ namespace {
|
|||
CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
|
||||
: ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
|
||||
llvm::BasicBlock *CleanupContBB =
|
||||
CGF.createBasicBlock("finally.cleanup.cont");
|
||||
|
@ -1239,7 +1239,7 @@ namespace {
|
|||
: Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
|
||||
RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Enter a cleanup to call the end-catch function if one was provided.
|
||||
if (EndCatchFn)
|
||||
CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
|
||||
|
|
|
@ -874,7 +874,7 @@ namespace {
|
|||
getPlacementArgs()[I] = Arg;
|
||||
}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const FunctionProtoType *FPT
|
||||
= OperatorDelete->getType()->getAs<FunctionProtoType>();
|
||||
assert(FPT->getNumArgs() == NumPlacementArgs + 1 ||
|
||||
|
@ -931,7 +931,7 @@ namespace {
|
|||
getPlacementArgs()[I] = Arg;
|
||||
}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const FunctionProtoType *FPT
|
||||
= OperatorDelete->getType()->getAs<FunctionProtoType>();
|
||||
assert(FPT->getNumArgs() == NumPlacementArgs + 1 ||
|
||||
|
@ -1201,7 +1201,7 @@ namespace {
|
|||
QualType ElementType)
|
||||
: Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType);
|
||||
}
|
||||
};
|
||||
|
@ -1289,7 +1289,7 @@ namespace {
|
|||
: Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
|
||||
ElementType(ElementType), CookieSize(CookieSize) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const FunctionProtoType *DeleteFTy =
|
||||
OperatorDelete->getType()->getAs<FunctionProtoType>();
|
||||
assert(DeleteFTy->getNumArgs() == 1 || DeleteFTy->getNumArgs() == 2);
|
||||
|
|
|
@ -218,7 +218,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
|
|||
|
||||
namespace {
|
||||
struct FinishARCDealloc : EHScopeStack::Cleanup {
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl);
|
||||
const ObjCImplementationDecl *impl
|
||||
= cast<ObjCImplementationDecl>(method->getDeclContext());
|
||||
|
@ -691,11 +691,11 @@ namespace {
|
|||
: addr(addr), ivar(ivar), destroyer(*destroyer),
|
||||
useEHCleanupForArray(useEHCleanupForArray) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
LValue lvalue
|
||||
= CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
|
||||
CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
|
||||
!isForEH && useEHCleanupForArray);
|
||||
flags.isForNormalCleanup() && useEHCleanupForArray);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1213,7 +1213,7 @@ namespace {
|
|||
llvm::Value *ptr;
|
||||
llvm::Value *condition;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool forEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
llvm::Value *object;
|
||||
|
||||
// If we're in a conditional branch, we had to stash away in an
|
||||
|
@ -1802,7 +1802,7 @@ namespace {
|
|||
|
||||
CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitObjCAutoreleasePoolPop(Token);
|
||||
}
|
||||
};
|
||||
|
@ -1811,7 +1811,7 @@ namespace {
|
|||
|
||||
CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool isForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitObjCMRRAutoreleasePoolPop(Token);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2581,7 +2581,7 @@ namespace {
|
|||
: S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
|
||||
ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
// Check whether we need to call objc_exception_try_exit.
|
||||
// In optimized code, this branch will always be folded.
|
||||
llvm::BasicBlock *FinallyCallExit =
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace {
|
|||
bool MightThrow;
|
||||
llvm::Value *Fn;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
if (!MightThrow) {
|
||||
CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
|
||||
return;
|
||||
|
@ -279,7 +279,7 @@ namespace {
|
|||
CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
|
||||
: SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
|||
llvm::Value *addr;
|
||||
DestroyTemporary(const CXXDestructorDecl *dtor, llvm::Value *addr)
|
||||
: dtor(dtor), addr(addr) {}
|
||||
void Emit(CodeGenFunction &CGF, bool forEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*ForVirtualBase=*/false,
|
||||
addr);
|
||||
}
|
||||
|
|
|
@ -184,6 +184,32 @@ public:
|
|||
// Anchor the construction vtable.
|
||||
virtual void anchor();
|
||||
public:
|
||||
/// Generation flags.
|
||||
class Flags {
|
||||
enum {
|
||||
F_IsForEH = 0x1,
|
||||
F_IsNormalCleanupKind = 0x2,
|
||||
F_IsEHCleanupKind = 0x4
|
||||
};
|
||||
unsigned flags;
|
||||
|
||||
public:
|
||||
Flags() : flags(0) {}
|
||||
|
||||
/// isForEH - true if the current emission is for an EH cleanup.
|
||||
bool isForEHCleanup() const { return flags & F_IsForEH; }
|
||||
bool isForNormalCleanup() const { return !isForEHCleanup(); }
|
||||
void setIsForEHCleanup() { flags |= F_IsForEH; }
|
||||
|
||||
bool isNormalCleanupKind() const { return flags & F_IsNormalCleanupKind; }
|
||||
void setIsNormalCleanupKind() { flags |= F_IsNormalCleanupKind; }
|
||||
|
||||
/// isEHCleanupKind - true if the cleanup was pushed as an EH
|
||||
/// cleanup.
|
||||
bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
|
||||
void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
|
||||
};
|
||||
|
||||
// Provide a virtual destructor to suppress a very common warning
|
||||
// that unfortunately cannot be suppressed without this. Cleanups
|
||||
// should not rely on this destructor ever being called.
|
||||
|
@ -196,7 +222,7 @@ public:
|
|||
///
|
||||
// \param IsForEHCleanup true if this is for an EH cleanup, false
|
||||
/// if for a normal cleanup.
|
||||
virtual void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) = 0;
|
||||
virtual void Emit(CodeGenFunction &CGF, Flags flags) = 0;
|
||||
};
|
||||
|
||||
/// ConditionalCleanupN stores the saved form of its N parameters,
|
||||
|
@ -206,9 +232,9 @@ public:
|
|||
typedef typename DominatingValue<A0>::saved_type A0_saved;
|
||||
A0_saved a0_saved;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
|
||||
T(a0).Emit(CGF, IsForEHCleanup);
|
||||
T(a0).Emit(CGF, flags);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -223,10 +249,10 @@ public:
|
|||
A0_saved a0_saved;
|
||||
A1_saved a1_saved;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
|
||||
A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
|
||||
T(a0, a1).Emit(CGF, IsForEHCleanup);
|
||||
T(a0, a1).Emit(CGF, flags);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -243,11 +269,11 @@ public:
|
|||
A1_saved a1_saved;
|
||||
A2_saved a2_saved;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
|
||||
A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
|
||||
A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
|
||||
T(a0, a1, a2).Emit(CGF, IsForEHCleanup);
|
||||
T(a0, a1, a2).Emit(CGF, flags);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -266,12 +292,12 @@ public:
|
|||
A2_saved a2_saved;
|
||||
A3_saved a3_saved;
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
|
||||
A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
|
||||
A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
|
||||
A3 a3 = DominatingValue<A3>::restore(CGF, a3_saved);
|
||||
T(a0, a1, a2, a3).Emit(CGF, IsForEHCleanup);
|
||||
T(a0, a1, a2, a3).Emit(CGF, flags);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -1071,7 +1071,7 @@ namespace {
|
|||
llvm::GlobalVariable *Guard;
|
||||
CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
void Emit(CodeGenFunction &CGF, Flags flags) {
|
||||
CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
|
||||
->setDoesNotThrow();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче