Пример #1
0
static void EmitCleanup(CodeGenFunction &CGF,
                        EHScopeStack::Cleanup *Fn,
                        EHScopeStack::Cleanup::Flags flags,
                        llvm::Value *ActiveFlag) {
  // EH cleanups always occur within a terminate scope.
  if (flags.isForEHCleanup()) CGF.EHStack.pushTerminate();

  // If there's an active flag, load it and skip the cleanup if it's
  // false.
  llvm::BasicBlock *ContBB = nullptr;
  if (ActiveFlag) {
    ContBB = CGF.createBasicBlock("cleanup.done");
    llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");
    llvm::Value *IsActive
      = CGF.Builder.CreateLoad(ActiveFlag, "cleanup.is_active");
    CGF.Builder.CreateCondBr(IsActive, CleanupBB, ContBB);
    CGF.EmitBlock(CleanupBB);
  }

  // Ask the cleanup to emit itself.
  Fn->Emit(CGF, flags);
  assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");

  // Emit the continuation block if there was an active flag.
  if (ActiveFlag)
    CGF.EmitBlock(ContBB);

  // Leave the terminate scope.
  if (flags.isForEHCleanup()) CGF.EHStack.popTerminate();
}
Пример #2
0
static void EmitCleanup(CodeGenFunction &CGF,
                        EHScopeStack::Cleanup *Fn,
                        EHScopeStack::Cleanup::Flags flags,
                        llvm::Value *ActiveFlag) {
  // Itanium EH cleanups occur within a terminate scope. Microsoft SEH doesn't
  // have this behavior, and the Microsoft C++ runtime will call terminate for
  // us if the cleanup throws.
  bool PushedTerminate = false;
  if (flags.isForEHCleanup() && !CGF.getTarget().getCXXABI().isMicrosoft()) {
    CGF.EHStack.pushTerminate();
    PushedTerminate = true;
  }

  // If there's an active flag, load it and skip the cleanup if it's
  // false.
  llvm::BasicBlock *ContBB = nullptr;
  if (ActiveFlag) {
    ContBB = CGF.createBasicBlock("cleanup.done");
    llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");
    llvm::Value *IsActive
      = CGF.Builder.CreateLoad(ActiveFlag, "cleanup.is_active");
    CGF.Builder.CreateCondBr(IsActive, CleanupBB, ContBB);
    CGF.EmitBlock(CleanupBB);
  }

  // Ask the cleanup to emit itself.
  Fn->Emit(CGF, flags);
  assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");

  // Emit the continuation block if there was an active flag.
  if (ActiveFlag)
    CGF.EmitBlock(ContBB);

  // Leave the terminate scope.
  if (PushedTerminate)
    CGF.EHStack.popTerminate();
}