about summary refs log tree commit diff
path: root/src/librustc_trans/builder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_trans/builder.rs')
-rw-r--r--src/librustc_trans/builder.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs
index 865787f48fc..6ea048d7ed3 100644
--- a/src/librustc_trans/builder.rs
+++ b/src/librustc_trans/builder.rs
@@ -19,12 +19,16 @@ use machine::llalign_of_pref;
 use type_::Type;
 use value::Value;
 use libc::{c_uint, c_char};
+use rustc::ty::{Ty, TypeFoldable};
+use type_of;
 
 use std::borrow::Cow;
 use std::ffi::CString;
 use std::ptr;
 use syntax_pos::Span;
 
+// All Builders must have an llfn associated with them
+#[must_use]
 pub struct Builder<'a, 'tcx: 'a> {
     pub llbuilder: BuilderRef,
     pub ccx: &'a CrateContext<'a, 'tcx>,
@@ -46,6 +50,20 @@ fn noname() -> *const c_char {
 }
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
+    pub fn new_block<'b>(ccx: &'a CrateContext<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
+        let builder = Builder::with_ccx(ccx);
+        let llbb = unsafe {
+            let name = CString::new(name).unwrap();
+            llvm::LLVMAppendBasicBlockInContext(
+                ccx.llcx(),
+                llfn,
+                name.as_ptr()
+            )
+        };
+        builder.position_at_end(llbb);
+        builder
+    }
+
     pub fn with_ccx(ccx: &'a CrateContext<'a, 'tcx>) -> Self {
         // Create a fresh builder from the crate context.
         let llbuilder = unsafe {
@@ -57,6 +75,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    pub fn build_new_block<'b>(&self, name: &'b str) -> Builder<'a, 'tcx> {
+        let builder = Builder::with_ccx(self.ccx);
+        let llbb = unsafe {
+            let name = CString::new(name).unwrap();
+            llvm::LLVMAppendBasicBlockInContext(
+                self.ccx.llcx(),
+                self.llfn(),
+                name.as_ptr()
+            )
+        };
+        builder.position_at_end(llbb);
+        builder
+    }
+
+    pub fn llfn(&self) -> ValueRef {
+        unsafe {
+            llvm::LLVMGetBasicBlockParent(self.llbb())
+        }
+    }
+
+    pub fn llbb(&self) -> BasicBlockRef {
+        unsafe {
+            llvm::LLVMGetInsertBlock(self.llbuilder)
+        }
+    }
+
     fn count_insn(&self, category: &str) {
         if self.ccx.sess().trans_stats() {
             self.ccx.stats().n_llvm_insns.set(self.ccx.stats().n_llvm_insns.get() + 1);
@@ -435,6 +479,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
+        let builder = Builder::with_ccx(self.ccx);
+        builder.position_at_start(unsafe {
+            llvm::LLVMGetFirstBasicBlock(self.llfn())
+        });
+        builder.dynamic_alloca(ty, name)
+    }
+
+    pub fn alloca_ty(&self, ty: Ty<'tcx>, name: &str) -> ValueRef {
+        assert!(!ty.has_param_types());
+        self.alloca(type_of::type_of(self.ccx, ty), name)
+    }
+
     pub fn dynamic_alloca(&self, ty: Type, name: &str) -> ValueRef {
         self.count_insn("alloca");
         unsafe {