From 8b776834a447f6c346130172e9d6d492b3b4e77d Mon Sep 17 00:00:00 2001 From: Piotr Czarnecki Date: Mon, 1 Feb 2016 11:04:49 +0100 Subject: [PATCH] Implement OwnedBuilder and BlockAndBuilder --- src/librustc_trans/trans/common.rs | 108 +++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 303fc17ce81b4..a23d879bba924 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -26,6 +26,7 @@ use middle::lang_items::LangItem; use middle::subst::{self, Substs}; use trans::base; use trans::build; +use trans::builder::Builder; use trans::callee; use trans::cleanup; use trans::consts; @@ -45,6 +46,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; 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; @@ -613,6 +615,9 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { 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() } @@ -659,6 +664,109 @@ impl<'blk, 'tcx> BlockS<'blk, '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(&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(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(&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