withModule :: (MonadBaseControl IO m)
              => ModuleBuilder -> (ModuleIO -> L b m a) -> L b m a
withModule builder f =
  do ctx <- getContext
     case builder of
       MBAST ast ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromAST $
          LL.withModuleFromAST ctx ast)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcode s bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (s,bs))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBVerifiedBitcode bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx ("",bs)) f
       MBAssembly asm ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx asm)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBAssemblyFile file ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcodeFile file ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBLink mb1 mb2 ->
         withModule mb1
         (\mod1 ->
           withModule mb2
           (\mod2 ->
             do liftBase $ errorToIO 'LL.linkModules $
                  LL.linkModules False mod1 mod2
                f mod1))
       MBTransform spec mb ->
         withModule mb
         (\mod1 ->
           do spec' <- pss spec
              liftBaseOp
                (catchCaller 'LL.withPassManager $ LL.withPassManager spec')
                (\pm ->
                  do _ <- catchInternal 'LL.runPassManager $
                          liftBase $ LL.runPassManager pm mod1
                     f mod1))
withModule :: (MonadBaseControl IO m)
              => ModuleBuilder -> (ModuleIO -> L b m a) -> L b m a
withModule builder f =
  do ctx <- getContext
     case builder of
       MBAST ast ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromAST $
          LL.withModuleFromAST ctx ast)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcode s bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (s,bs))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBVerifiedBitcode bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx ("",bs)) f
       MBAssembly asm ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx asm)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBAssemblyFile file ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcodeFile file ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBLink mb1 mb2 ->
         withModule mb1
         (\mod1 ->
           withModule mb2
           (\mod2 ->
             do liftBase $ errorToIO 'LL.linkModules $
                  LL.linkModules False mod1 mod2
                f mod1))
       MBTransform spec mb ->
         withModule mb
         (\mod1 ->
           do spec' <- pss spec
              liftBaseOp
                (catchCaller 'LL.withPassManager $ LL.withPassManager spec')
                (\pm ->
                  do _ <- catchInternal 'LL.runPassManager $
                          liftBase $ LL.runPassManager pm mod1
                     f mod1))
withModule builder f =
  do ctx <- getContext
     case builder of
       MBAST ast ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromAST $
          LL.withModuleFromAST ctx ast)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcode s bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (s,bs))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBVerifiedBitcode bs ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx ("",bs)) f
       MBAssembly asm ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx asm)
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBAssemblyFile file ->
         liftBaseOp
         (catchCallerDiag 'LL.withModuleFromLLVMAssembly $
          LL.withModuleFromLLVMAssembly ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBBitcodeFile file ->
         liftBaseOp
         (catchCallerError 'LL.withModuleFromBitcode $
          LL.withModuleFromBitcode ctx (LL.File file))
         (\moduleIO -> do liftBase $ errorToIO 'LL.verify $ LL.verify moduleIO
                          f moduleIO)
       MBLink mb1 mb2 ->
         withModule mb1
         (\mod1 ->
           withModule mb2
           (\mod2 ->
             do liftBase $ errorToIO 'LL.linkModules $
                  LL.linkModules False mod1 mod2
                f mod1))
       MBTransform spec mb ->
         withModule mb
         (\mod1 ->
           do spec' <- pss spec
              liftBaseOp
                (catchCaller 'LL.withPassManager $ LL.withPassManager spec')
                (\pm ->
                  do _ <- catchInternal 'LL.runPassManager $
                          liftBase $ LL.runPassManager pm mod1
                     f mod1))