use middle::subst::{self, Substs};
use trans::base;
use trans::build;
+use trans::builder::Builder;
use trans::callee;
use trans::cleanup;
use trans::consts;
use arena::TypedArena;
use libc::{c_uint, c_char};
+use std::ops::Deref;
use std::ffi::CString;
use std::cell::{Cell, RefCell};
use std::vec::Vec;
pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
self.fcx.ccx
}
+ pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
+ self.fcx
+ }
pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
self.fcx.ccx.tcx()
}
self.fcx.param_substs,
value)
}
+
+ pub fn build(&'blk self) -> BlockAndBuilder<'blk, 'tcx> {
+ BlockAndBuilder::new(self, OwnedBuilder::new_with_ccx(self.ccx()))
+ }
+}
+
+pub struct OwnedBuilder<'blk, 'tcx: 'blk> {
+ builder: Builder<'blk, 'tcx>
+}
+
+impl<'blk, 'tcx> OwnedBuilder<'blk, 'tcx> {
+ pub fn new_with_ccx(ccx: &'blk CrateContext<'blk, 'tcx>) -> Self {
+ // Create a fresh builder from the crate context.
+ let llbuilder = unsafe {
+ llvm::LLVMCreateBuilderInContext(ccx.llcx())
+ };
+ OwnedBuilder {
+ builder: Builder {
+ llbuilder: llbuilder,
+ ccx: ccx,
+ }
+ }
+ }
+}
+
+impl<'blk, 'tcx> Drop for OwnedBuilder<'blk, 'tcx> {
+ fn drop(&mut self) {
+ unsafe {
+ llvm::LLVMDisposeBuilder(self.builder.llbuilder);
+ }
+ }
+}
+
+pub struct BlockAndBuilder<'blk, 'tcx: 'blk> {
+ bcx: Block<'blk, 'tcx>,
+ owned_builder: OwnedBuilder<'blk, 'tcx>,
+}
+
+impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
+ pub fn new(bcx: Block<'blk, 'tcx>, owned_builder: OwnedBuilder<'blk, 'tcx>) -> Self {
+ // Set the builder's position to this block's end.
+ owned_builder.builder.position_at_end(bcx.llbb);
+ BlockAndBuilder {
+ bcx: bcx,
+ owned_builder: owned_builder,
+ }
+ }
+
+ pub fn with_block<F, R>(&self, f: F) -> R
+ where F: FnOnce(Block<'blk, 'tcx>) -> R
+ {
+ let result = f(self.bcx);
+ self.position_at_end(self.bcx.llbb);
+ result
+ }
+
+ pub fn map_block<F>(self, f: F) -> Self
+ where F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>
+ {
+ let BlockAndBuilder { bcx, owned_builder } = self;
+ let bcx = f(bcx);
+ BlockAndBuilder::new(bcx, owned_builder)
+ }
+
+ // Methods delegated to bcx
+
+ pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
+ self.bcx.ccx()
+ }
+ pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
+ self.bcx.fcx()
+ }
+ pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
+ self.bcx.tcx()
+ }
+ pub fn sess(&self) -> &'blk Session {
+ self.bcx.sess()
+ }
+
+ pub fn llbb(&self) -> BasicBlockRef {
+ self.bcx.llbb
+ }
+
+ pub fn mir(&self) -> &'blk Mir<'tcx> {
+ self.bcx.mir()
+ }
+
+ pub fn val_to_string(&self, val: ValueRef) -> String {
+ self.bcx.val_to_string(val)
+ }
+
+ pub fn monomorphize<T>(&self, value: &T) -> T
+ where T: TypeFoldable<'tcx>
+ {
+ self.bcx.monomorphize(value)
+ }
+}
+
+impl<'blk, 'tcx> Deref for BlockAndBuilder<'blk, 'tcx> {
+ type Target = Builder<'blk, 'tcx>;
+ fn deref(&self) -> &Self::Target {
+ &self.owned_builder.builder
+ }
}
/// A structure representing an active landing pad for the duration of a basic