]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/trans/common.rs
use TotalEq for HashMap
[rust.git] / src / librustc / middle / trans / common.rs
index e3a996e33d392d62f3e5f5cfce730e1cb9edfcac..78700bab3f24d55a81bd3f1c6b75898fe22a5464 100644 (file)
@@ -18,7 +18,6 @@
 use lib::llvm::llvm;
 use lib;
 use middle::lang_items::LangItem;
-use middle::trans::base;
 use middle::trans::build;
 use middle::trans::cleanup;
 use middle::trans::datum;
@@ -36,7 +35,6 @@
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
 use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
-use std::vec_ng::Vec;
 use syntax::ast::Ident;
 use syntax::ast;
 use syntax::ast_map::{PathElem, PathName};
@@ -49,7 +47,7 @@
 fn type_is_newtype_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
     match ty::get(ty).sty {
         ty::ty_struct(def_id, ref substs) => {
-            let fields = ty::struct_fields(ccx.tcx, def_id, substs);
+            let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
             fields.len() == 1 &&
                 fields.get(0).ident.name ==
                     token::special_idents::unnamed_field.name &&
@@ -62,7 +60,7 @@ fn type_is_newtype_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
 pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
     use middle::trans::machine::llsize_of_alloc;
     use middle::trans::type_of::sizing_type_of;
-    let tcx = ccx.tcx;
+    let tcx = ccx.tcx();
     let simple = ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
         ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
         type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
@@ -100,11 +98,16 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
      * return type (in order to aid with C ABI compatibility).
      */
 
-    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
+    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx(), ty)
 }
 
+/// Generates a unique symbol based off the name given. This is used to create
+/// unique symbols for things like closures.
 pub fn gensym_name(name: &str) -> PathElem {
-    PathName(token::gensym(name))
+    let num = token::gensym(name);
+    // use one colon which will get translated to a period by the mangler, and
+    // we're guaranteed that `num` is globally unique for this crate.
+    PathName(token::gensym(format!("{}:{}", name, num)))
 }
 
 pub struct tydesc_info {
@@ -202,14 +205,14 @@ pub fn validate(&self) {
     }
 }
 
-fn param_substs_to_str(this: &param_substs, tcx: ty::ctxt) -> ~str {
+fn param_substs_to_str(this: &param_substs, tcx: &ty::ctxt) -> ~str {
     format!("param_substs \\{tys:{}, vtables:{}\\}",
          this.tys.repr(tcx),
          this.vtables.repr(tcx))
 }
 
 impl Repr for param_substs {
-    fn repr(&self, tcx: ty::ctxt) -> ~str {
+    fn repr(&self, tcx: &ty::ctxt) -> ~str {
         param_substs_to_str(self, tcx)
     }
 }
@@ -281,7 +284,7 @@ pub struct FunctionContext<'a> {
     block_arena: &'a TypedArena<Block<'a>>,
 
     // This function's enclosing crate context.
-    ccx: @CrateContext,
+    ccx: &'a CrateContext,
 
     // Used and maintained by the debuginfo module.
     debug_context: debuginfo::FunctionDebugContext,
@@ -325,7 +328,12 @@ pub fn cleanup(&self) {
 
     pub fn get_llreturn(&self) -> BasicBlockRef {
         if self.llreturn.get().is_none() {
-            self.llreturn.set(Some(base::mk_return_basic_block(self.llfn)));
+
+            self.llreturn.set(Some(unsafe {
+                "return".with_c_str(|buf| {
+                    llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx, self.llfn, buf)
+                })
+            }))
         }
 
         self.llreturn.get().unwrap()
@@ -378,13 +386,6 @@ pub fn join_blocks(&'a self,
     }
 }
 
-pub fn warn_not_to_commit(ccx: &mut CrateContext, msg: &str) {
-    if !ccx.do_not_commit_warning_issued.get() {
-        ccx.do_not_commit_warning_issued.set(true);
-        ccx.sess.warn(msg.to_str() + " -- do not commit like this!");
-    }
-}
-
 // Heap selectors. Indicate which heap something should go on.
 #[deriving(Eq)]
 pub enum heap {
@@ -437,11 +438,11 @@ pub fn new<'a>(
         })
     }
 
-    pub fn ccx(&self) -> @CrateContext { self.fcx.ccx }
-    pub fn tcx(&self) -> ty::ctxt {
-        self.fcx.ccx.tcx
+    pub fn ccx(&self) -> &'a CrateContext { self.fcx.ccx }
+    pub fn tcx(&self) -> &'a ty::ctxt {
+        &self.fcx.ccx.tcx
     }
-    pub fn sess(&self) -> Session { self.fcx.ccx.sess }
+    pub fn sess(&self) -> &'a Session { self.fcx.ccx.sess() }
 
     pub fn ident(&self, ident: Ident) -> ~str {
         token::get_ident(ident).get().to_str()
@@ -464,8 +465,7 @@ pub fn expr_kind(&self, e: &ast::Expr) -> ty::ExprKind {
     }
 
     pub fn def(&self, nid: ast::NodeId) -> ast::Def {
-        let def_map = self.tcx().def_map.borrow();
-        match def_map.get().find(&nid) {
+        match self.tcx().def_map.borrow().find(&nid) {
             Some(&v) => v,
             None => {
                 self.tcx().sess.bug(format!(
@@ -542,40 +542,40 @@ pub fn C_floating(s: &str, t: Type) -> ValueRef {
     }
 }
 
-pub fn C_nil() -> ValueRef {
-    C_struct([], false)
+pub fn C_nil(ccx: &CrateContext) -> ValueRef {
+    C_struct(ccx, [], false)
 }
 
-pub fn C_bool(val: bool) -> ValueRef {
-    C_integral(Type::bool(), val as u64, false)
+pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
+    C_integral(Type::bool(ccx), val as u64, false)
 }
 
-pub fn C_i1(val: bool) -> ValueRef {
-    C_integral(Type::i1(), val as u64, false)
+pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
+    C_integral(Type::i1(ccx), val as u64, false)
 }
 
-pub fn C_i32(i: i32) -> ValueRef {
-    return C_integral(Type::i32(), i as u64, true);
+pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
+    C_integral(Type::i32(ccx), i as u64, true)
 }
 
-pub fn C_i64(i: i64) -> ValueRef {
-    return C_integral(Type::i64(), i as u64, true);
+pub fn C_i64(ccx: &CrateContext, i: i64) -> ValueRef {
+    C_integral(Type::i64(ccx), i as u64, true)
 }
 
-pub fn C_u64(i: u64) -> ValueRef {
-    return C_integral(Type::i64(), i, false);
+pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
+    C_integral(Type::i64(ccx), i, false)
 }
 
-pub fn C_int(cx: &CrateContext, i: int) -> ValueRef {
-    return C_integral(cx.int_type, i as u64, true);
+pub fn C_int(ccx: &CrateContext, i: int) -> ValueRef {
+    C_integral(ccx.int_type, i as u64, true)
 }
 
-pub fn C_uint(cx: &CrateContext, i: uint) -> ValueRef {
-    return C_integral(cx.int_type, i as u64, false);
+pub fn C_uint(ccx: &CrateContext, i: uint) -> ValueRef {
+    C_integral(ccx.int_type, i as u64, false)
 }
 
-pub fn C_u8(i: uint) -> ValueRef {
-    return C_integral(Type::i8(), i as u64, false);
+pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
+    C_integral(Type::i8(ccx), i as u64, false)
 }
 
 
@@ -583,12 +583,9 @@ pub fn C_u8(i: uint) -> ValueRef {
 // our boxed-and-length-annotated strings.
 pub fn C_cstr(cx: &CrateContext, s: InternedString) -> ValueRef {
     unsafe {
-        {
-            let const_cstr_cache = cx.const_cstr_cache.borrow();
-            match const_cstr_cache.get().find(&s) {
-                Some(&llval) => return llval,
-                None => ()
-            }
+        match cx.const_cstr_cache.borrow().find(&s) {
+            Some(&llval) => return llval,
+            None => ()
         }
 
         let sc = llvm::LLVMConstStringInContext(cx.llcx,
@@ -604,8 +601,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString) -> ValueRef {
         llvm::LLVMSetGlobalConstant(g, True);
         lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
 
-        let mut const_cstr_cache = cx.const_cstr_cache.borrow_mut();
-        const_cstr_cache.get().insert(s, g);
+        cx.const_cstr_cache.borrow_mut().insert(s, g);
         g
     }
 }
@@ -615,15 +611,15 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString) -> ValueRef {
 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
     unsafe {
         let len = s.get().len();
-        let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p().to_ref());
-        C_struct([cs, C_uint(cx, len)], false)
+        let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p(cx).to_ref());
+        C_struct(cx, [cs, C_uint(cx, len)], false)
     }
 }
 
 pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
     unsafe {
         let len = data.len();
-        let lldata = C_bytes(data);
+        let lldata = C_bytes(cx, data);
 
         let gsym = token::gensym("binary");
         let g = format!("binary{}", gsym).with_c_str(|buf| {
@@ -633,25 +629,14 @@ pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
         llvm::LLVMSetGlobalConstant(g, True);
         lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
 
-        let cs = llvm::LLVMConstPointerCast(g, Type::i8p().to_ref());
-        C_struct([cs, C_uint(cx, len)], false)
+        let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
+        C_struct(cx, [cs, C_uint(cx, len)], false)
     }
 }
 
-pub fn C_zero_byte_arr(size: uint) -> ValueRef {
+pub fn C_struct(ccx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
     unsafe {
-        let mut i = 0u;
-        let mut elts: Vec<ValueRef> = Vec::new();
-        while i < size { elts.push(C_u8(0u)); i += 1u; }
-        return llvm::LLVMConstArray(Type::i8().to_ref(),
-                                    elts.as_ptr(), elts.len() as c_uint);
-    }
-}
-
-pub fn C_struct(elts: &[ValueRef], packed: bool) -> ValueRef {
-    unsafe {
-
-        llvm::LLVMConstStructInContext(base::task_llcx(),
+        llvm::LLVMConstStructInContext(ccx.llcx,
                                        elts.as_ptr(), elts.len() as c_uint,
                                        packed as Bool)
     }
@@ -669,10 +654,10 @@ pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
     }
 }
 
-pub fn C_bytes(bytes: &[u8]) -> ValueRef {
+pub fn C_bytes(ccx: &CrateContext, bytes: &[u8]) -> ValueRef {
     unsafe {
         let ptr = bytes.as_ptr() as *c_char;
-        return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint, True);
+        return llvm::LLVMConstStringInContext(ccx.llcx, ptr, bytes.len() as c_uint, True);
     }
 }
 
@@ -725,7 +710,7 @@ pub fn is_null(val: ValueRef) -> bool {
 }
 
 // Used to identify cached monomorphized functions and vtables
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum mono_param_id {
     mono_precise(ty::t, Option<@Vec<mono_id> >),
     mono_any,
@@ -735,7 +720,7 @@ pub enum mono_param_id {
               datum::RvalueMode),
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum MonoDataClass {
     MonoBits,    // Anything not treated differently from arbitrary integer data
     MonoNonNull, // Non-null pointers (used for optional-pointer optimization)
@@ -757,7 +742,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
     }
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct mono_id_ {
     def: ast::DefId,
     params: Vec<mono_param_id> }
@@ -805,7 +790,7 @@ pub fn expr_ty(bcx: &Block, ex: &ast::Expr) -> ty::t {
 
 pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
     let tcx = bcx.tcx();
-    let t = ty::expr_ty_adjusted(tcx, ex, bcx.ccx().maps.method_map.borrow().get());
+    let t = ty::expr_ty_adjusted(tcx, ex, &*bcx.ccx().maps.method_map.borrow());
     monomorphize_type(bcx, t)
 }
 
@@ -824,7 +809,7 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
     let params = match node {
         ExprId(id) => ty::node_id_to_type_params(tcx, id),
         MethodCall(method_call) => {
-            bcx.ccx().maps.method_map.borrow().get().get(&method_call).substs.tps.clone()
+            bcx.ccx().maps.method_map.borrow().get(&method_call).substs.tps.clone()
         }
     };
 
@@ -844,10 +829,10 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
     }
 }
 
-pub fn node_vtables(bcx: &Block, id: ast::NodeId)
+pub fn node_vtables(bcx: &Block, id: typeck::MethodCall)
                  -> Option<typeck::vtable_res> {
     let vtable_map = bcx.ccx().maps.vtable_map.borrow();
-    let raw_vtables = vtable_map.get().find(&id);
+    let raw_vtables = vtable_map.find(&id);
     raw_vtables.map(|vts| resolve_vtables_in_fn_ctxt(bcx.fcx, *vts))
 }
 
@@ -855,12 +840,12 @@ pub fn node_vtables(bcx: &Block, id: ast::NodeId)
 // vtables. This should eliminate any vtable_params.
 pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res)
     -> typeck::vtable_res {
-    resolve_vtables_under_param_substs(fcx.ccx.tcx,
+    resolve_vtables_under_param_substs(fcx.ccx.tcx(),
                                        fcx.param_substs,
                                        vts)
 }
 
-pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
+pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt,
                                           param_substs: Option<@param_substs>,
                                           vts: typeck::vtable_res)
     -> typeck::vtable_res {
@@ -872,7 +857,7 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
 }
 
 pub fn resolve_param_vtables_under_param_substs(
-    tcx: ty::ctxt,
+    tcx: &ty::ctxt,
     param_substs: Option<@param_substs>,
     ds: typeck::vtable_param_res)
     -> typeck::vtable_param_res {
@@ -885,7 +870,7 @@ pub fn resolve_param_vtables_under_param_substs(
 
 
 
-pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
+pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
                                          param_substs: Option<@param_substs>,
                                          vt: &typeck::vtable_origin)
                                          -> typeck::vtable_origin {
@@ -921,7 +906,7 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
     }
 }
 
-pub fn find_vtable(tcx: ty::ctxt,
+pub fn find_vtable(tcx: &ty::ctxt,
                    ps: &param_substs,
                    n_param: typeck::param_index,
                    n_bound: uint)
@@ -950,17 +935,17 @@ pub fn dummy_substs(tps: Vec<ty::t> ) -> ty::substs {
 
 pub fn filename_and_line_num_from_span(bcx: &Block, span: Span)
                                        -> (ValueRef, ValueRef) {
-    let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo);
+    let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
     let filename_cstr = C_cstr(bcx.ccx(),
                                token::intern_and_get_ident(loc.file.name));
-    let filename = build::PointerCast(bcx, filename_cstr, Type::i8p());
+    let filename = build::PointerCast(bcx, filename_cstr, Type::i8p(bcx.ccx()));
     let line = C_int(bcx.ccx(), loc.line as int);
     (filename, line)
 }
 
 // Casts a Rust bool value to an i1.
 pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
-    build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false))
+    build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
 }
 
 pub fn langcall(bcx: &Block,