]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/trans/common.rs
Merge remote-tracking branch 'csouth3/trieset-bitops' into rollup-2014_12_03
[rust.git] / src / librustc_trans / trans / common.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_camel_case_types, non_snake_case)]
12
13 //! Code that is useful in various trans modules.
14
15 pub use self::ExprOrMethodCall::*;
16
17 use session::Session;
18 use llvm;
19 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
20 use llvm::{True, False, Bool};
21 use middle::def;
22 use middle::infer;
23 use middle::lang_items::LangItem;
24 use middle::mem_categorization as mc;
25 use middle::region;
26 use middle::subst;
27 use middle::subst::{Subst, Substs};
28 use trans::base;
29 use trans::build;
30 use trans::cleanup;
31 use trans::datum;
32 use trans::debuginfo;
33 use trans::machine;
34 use trans::type_::Type;
35 use trans::type_of;
36 use middle::traits;
37 use middle::ty::{mod, Ty};
38 use middle::ty_fold;
39 use middle::ty_fold::TypeFoldable;
40 use util::ppaux::Repr;
41 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
42
43 use arena::TypedArena;
44 use libc::{c_uint, c_char};
45 use std::c_str::ToCStr;
46 use std::cell::{Cell, RefCell};
47 use std::rc::Rc;
48 use std::vec::Vec;
49 use syntax::ast::Ident;
50 use syntax::ast;
51 use syntax::ast_map::{PathElem, PathName};
52 use syntax::codemap::Span;
53 use syntax::parse::token::InternedString;
54 use syntax::parse::token;
55
56 pub use trans::context::CrateContext;
57
58 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
59                                        ty: Ty<'tcx>) -> bool {
60     match ty.sty {
61         ty::ty_struct(def_id, ref substs) => {
62             let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
63             fields.len() == 1 &&
64                 fields[0].name ==
65                     token::special_idents::unnamed_field.name &&
66                 type_is_immediate(ccx, fields[0].mt.ty)
67         }
68         _ => false
69     }
70 }
71
72 pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
73     use trans::machine::llsize_of_alloc;
74     use trans::type_of::sizing_type_of;
75
76     let tcx = ccx.tcx();
77     let simple = ty::type_is_scalar(ty) ||
78         ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
79         type_is_newtype_immediate(ccx, ty) ||
80         ty::type_is_simd(tcx, ty);
81     if simple && !ty::type_is_fat_ptr(tcx, ty) {
82         return true;
83     }
84     if !ty::type_is_sized(tcx, ty) {
85         return false;
86     }
87     match ty.sty {
88         ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
89         ty::ty_unboxed_closure(..) => {
90             let llty = sizing_type_of(ccx, ty);
91             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
92         }
93         _ => type_is_zero_size(ccx, ty)
94     }
95 }
96
97 /// Identify types which have size zero at runtime.
98 pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
99     use trans::machine::llsize_of_alloc;
100     use trans::type_of::sizing_type_of;
101     let llty = sizing_type_of(ccx, ty);
102     llsize_of_alloc(ccx, llty) == 0
103 }
104
105 /// Identifies types which we declare to be equivalent to `void` in C for the purpose of function
106 /// return types. These are `()`, bot, and uninhabited enums. Note that all such types are also
107 /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI
108 /// compatibility).
109 pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
110     ty::type_is_nil(ty) || ty::type_is_empty(ccx.tcx(), ty)
111 }
112
113 /// Generates a unique symbol based off the name given. This is used to create
114 /// unique symbols for things like closures.
115 pub fn gensym_name(name: &str) -> PathElem {
116     let num = token::gensym(name).uint();
117     // use one colon which will get translated to a period by the mangler, and
118     // we're guaranteed that `num` is globally unique for this crate.
119     PathName(token::gensym(format!("{}:{}", name, num).as_slice()))
120 }
121
122 pub struct tydesc_info<'tcx> {
123     pub ty: Ty<'tcx>,
124     pub tydesc: ValueRef,
125     pub size: ValueRef,
126     pub align: ValueRef,
127     pub name: ValueRef,
128 }
129
130 /*
131  * A note on nomenclature of linking: "extern", "foreign", and "upcall".
132  *
133  * An "extern" is an LLVM symbol we wind up emitting an undefined external
134  * reference to. This means "we don't have the thing in this compilation unit,
135  * please make sure you link it in at runtime". This could be a reference to
136  * C code found in a C library, or rust code found in a rust crate.
137  *
138  * Most "externs" are implicitly declared (automatically) as a result of a
139  * user declaring an extern _module_ dependency; this causes the rust driver
140  * to locate an extern crate, scan its compilation metadata, and emit extern
141  * declarations for any symbols used by the declaring crate.
142  *
143  * A "foreign" is an extern that references C (or other non-rust ABI) code.
144  * There is no metadata to scan for extern references so in these cases either
145  * a header-digester like bindgen, or manual function prototypes, have to
146  * serve as declarators. So these are usually given explicitly as prototype
147  * declarations, in rust code, with ABI attributes on them noting which ABI to
148  * link via.
149  *
150  * An "upcall" is a foreign call generated by the compiler (not corresponding
151  * to any user-written call in the code) into the runtime library, to perform
152  * some helper task such as bringing a task to life, allocating memory, etc.
153  *
154  */
155
156 pub struct NodeInfo {
157     pub id: ast::NodeId,
158     pub span: Span,
159 }
160
161 pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
162     NodeInfo { id: expr.id, span: expr.span }
163 }
164
165 pub struct BuilderRef_res {
166     pub b: BuilderRef,
167 }
168
169 impl Drop for BuilderRef_res {
170     fn drop(&mut self) {
171         unsafe {
172             llvm::LLVMDisposeBuilder(self.b);
173         }
174     }
175 }
176
177 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
178     BuilderRef_res {
179         b: b
180     }
181 }
182
183 pub type ExternMap = FnvHashMap<String, ValueRef>;
184
185 pub fn validate_substs(substs: &Substs) {
186     assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
187 }
188
189 // work around bizarre resolve errors
190 pub type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
191 pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
192
193 // Function context.  Every LLVM function we create will have one of
194 // these.
195 pub struct FunctionContext<'a, 'tcx: 'a> {
196     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
197     // address of the first instruction in the sequence of
198     // instructions for this function that will go in the .text
199     // section of the executable we're generating.
200     pub llfn: ValueRef,
201
202     // The environment argument in a closure.
203     pub llenv: Option<ValueRef>,
204
205     // A pointer to where to store the return value. If the return type is
206     // immediate, this points to an alloca in the function. Otherwise, it's a
207     // pointer to the hidden first parameter of the function. After function
208     // construction, this should always be Some.
209     pub llretslotptr: Cell<Option<ValueRef>>,
210
211     // These pub elements: "hoisted basic blocks" containing
212     // administrative activities that have to happen in only one place in
213     // the function, due to LLVM's quirks.
214     // A marker for the place where we want to insert the function's static
215     // allocas, so that LLVM will coalesce them into a single alloca call.
216     pub alloca_insert_pt: Cell<Option<ValueRef>>,
217     pub llreturn: Cell<Option<BasicBlockRef>>,
218
219     // If the function has any nested return's, including something like:
220     // fn foo() -> Option<Foo> { Some(Foo { x: return None }) }, then
221     // we use a separate alloca for each return
222     pub needs_ret_allocas: bool,
223
224     // The a value alloca'd for calls to upcalls.rust_personality. Used when
225     // outputting the resume instruction.
226     pub personality: Cell<Option<ValueRef>>,
227
228     // True if the caller expects this fn to use the out pointer to
229     // return. Either way, your code should write into the slot llretslotptr
230     // points to, but if this value is false, that slot will be a local alloca.
231     pub caller_expects_out_pointer: bool,
232
233     // Maps the DefId's for local variables to the allocas created for
234     // them in llallocas.
235     pub lllocals: RefCell<NodeMap<LvalueDatum<'tcx>>>,
236
237     // Same as above, but for closure upvars
238     pub llupvars: RefCell<NodeMap<ValueRef>>,
239
240     // The NodeId of the function, or -1 if it doesn't correspond to
241     // a user-defined function.
242     pub id: ast::NodeId,
243
244     // If this function is being monomorphized, this contains the type
245     // substitutions used.
246     pub param_substs: &'a Substs<'tcx>,
247
248     // The source span and nesting context where this function comes from, for
249     // error reporting and symbol generation.
250     pub span: Option<Span>,
251
252     // The arena that blocks are allocated from.
253     pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
254
255     // This function's enclosing crate context.
256     pub ccx: &'a CrateContext<'a, 'tcx>,
257
258     // Used and maintained by the debuginfo module.
259     pub debug_context: debuginfo::FunctionDebugContext,
260
261     // Cleanup scopes.
262     pub scopes: RefCell<Vec<cleanup::CleanupScope<'a, 'tcx>>>,
263 }
264
265 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
266     pub fn arg_pos(&self, arg: uint) -> uint {
267         let arg = self.env_arg_pos() + arg;
268         if self.llenv.is_some() {
269             arg + 1
270         } else {
271             arg
272         }
273     }
274
275     pub fn env_arg_pos(&self) -> uint {
276         if self.caller_expects_out_pointer {
277             1u
278         } else {
279             0u
280         }
281     }
282
283     pub fn cleanup(&self) {
284         unsafe {
285             llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
286                                                      .get()
287                                                      .unwrap());
288         }
289     }
290
291     pub fn get_llreturn(&self) -> BasicBlockRef {
292         if self.llreturn.get().is_none() {
293
294             self.llreturn.set(Some(unsafe {
295                 "return".with_c_str(|buf| {
296                     llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn, buf)
297                 })
298             }))
299         }
300
301         self.llreturn.get().unwrap()
302     }
303
304     pub fn get_ret_slot(&self, bcx: Block<'a, 'tcx>,
305                         output: ty::FnOutput<'tcx>,
306                         name: &str) -> ValueRef {
307         if self.needs_ret_allocas {
308             base::alloca_no_lifetime(bcx, match output {
309                 ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
310                 ty::FnDiverging => Type::void(bcx.ccx())
311             }, name)
312         } else {
313             self.llretslotptr.get().unwrap()
314         }
315     }
316
317     pub fn new_block(&'a self,
318                      is_lpad: bool,
319                      name: &str,
320                      opt_node_id: Option<ast::NodeId>)
321                      -> Block<'a, 'tcx> {
322         unsafe {
323             let llbb = name.with_c_str(|buf| {
324                     llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
325                                                         self.llfn,
326                                                         buf)
327                 });
328             BlockS::new(llbb, is_lpad, opt_node_id, self)
329         }
330     }
331
332     pub fn new_id_block(&'a self,
333                         name: &str,
334                         node_id: ast::NodeId)
335                         -> Block<'a, 'tcx> {
336         self.new_block(false, name, Some(node_id))
337     }
338
339     pub fn new_temp_block(&'a self,
340                           name: &str)
341                           -> Block<'a, 'tcx> {
342         self.new_block(false, name, None)
343     }
344
345     pub fn join_blocks(&'a self,
346                        id: ast::NodeId,
347                        in_cxs: &[Block<'a, 'tcx>])
348                        -> Block<'a, 'tcx> {
349         let out = self.new_id_block("join", id);
350         let mut reachable = false;
351         for bcx in in_cxs.iter() {
352             if !bcx.unreachable.get() {
353                 build::Br(*bcx, out.llbb);
354                 reachable = true;
355             }
356         }
357         if !reachable {
358             build::Unreachable(out);
359         }
360         return out;
361     }
362 }
363
364 // Basic block context.  We create a block context for each basic block
365 // (single-entry, single-exit sequence of instructions) we generate from Rust
366 // code.  Each basic block we generate is attached to a function, typically
367 // with many basic blocks per function.  All the basic blocks attached to a
368 // function are organized as a directed graph.
369 pub struct BlockS<'blk, 'tcx: 'blk> {
370     // The BasicBlockRef returned from a call to
371     // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
372     // block to the function pointed to by llfn.  We insert
373     // instructions into that block by way of this block context.
374     // The block pointing to this one in the function's digraph.
375     pub llbb: BasicBlockRef,
376     pub terminated: Cell<bool>,
377     pub unreachable: Cell<bool>,
378
379     // Is this block part of a landing pad?
380     pub is_lpad: bool,
381
382     // AST node-id associated with this block, if any. Used for
383     // debugging purposes only.
384     pub opt_node_id: Option<ast::NodeId>,
385
386     // The function context for the function to which this block is
387     // attached.
388     pub fcx: &'blk FunctionContext<'blk, 'tcx>,
389 }
390
391 pub type Block<'blk, 'tcx> = &'blk BlockS<'blk, 'tcx>;
392
393 impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
394     pub fn new(llbb: BasicBlockRef,
395                is_lpad: bool,
396                opt_node_id: Option<ast::NodeId>,
397                fcx: &'blk FunctionContext<'blk, 'tcx>)
398                -> Block<'blk, 'tcx> {
399         fcx.block_arena.alloc(BlockS {
400             llbb: llbb,
401             terminated: Cell::new(false),
402             unreachable: Cell::new(false),
403             is_lpad: is_lpad,
404             opt_node_id: opt_node_id,
405             fcx: fcx
406         })
407     }
408
409     pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
410         self.fcx.ccx
411     }
412     pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
413         self.fcx.ccx.tcx()
414     }
415     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
416
417     pub fn ident(&self, ident: Ident) -> String {
418         token::get_ident(ident).get().to_string()
419     }
420
421     pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
422         self.tcx().map.node_to_string(id).to_string()
423     }
424
425     pub fn expr_to_string(&self, e: &ast::Expr) -> String {
426         e.repr(self.tcx())
427     }
428
429     pub fn def(&self, nid: ast::NodeId) -> def::Def {
430         match self.tcx().def_map.borrow().get(&nid) {
431             Some(v) => v.clone(),
432             None => {
433                 self.tcx().sess.bug(format!(
434                     "no def associated with node id {}", nid).as_slice());
435             }
436         }
437     }
438
439     pub fn val_to_string(&self, val: ValueRef) -> String {
440         self.ccx().tn().val_to_string(val)
441     }
442
443     pub fn llty_str(&self, ty: Type) -> String {
444         self.ccx().tn().type_to_string(ty)
445     }
446
447     pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
448         t.repr(self.tcx())
449     }
450
451     pub fn to_str(&self) -> String {
452         format!("[block {:p}]", self)
453     }
454 }
455
456 impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
457     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
458         self.tcx()
459     }
460
461     fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
462         Ok(node_id_type(self, id))
463     }
464
465     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
466         self.tcx()
467             .method_map
468             .borrow()
469             .get(&method_call)
470             .map(|method| monomorphize_type(self, method.ty))
471     }
472
473     fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
474         &self.tcx().adjustments
475     }
476
477     fn is_method_call(&self, id: ast::NodeId) -> bool {
478         self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
479     }
480
481     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
482         self.tcx().region_maps.temporary_scope(rvalue_id)
483     }
484
485     fn unboxed_closures<'a>(&'a self)
486                         -> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>> {
487         &self.tcx().unboxed_closures
488     }
489
490     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
491         self.tcx().upvar_borrow_map.borrow()[upvar_id].clone()
492     }
493
494     fn capture_mode(&self, closure_expr_id: ast::NodeId)
495                     -> ast::CaptureClause {
496         self.tcx().capture_modes.borrow()[closure_expr_id].clone()
497     }
498 }
499
500 pub struct Result<'blk, 'tcx: 'blk> {
501     pub bcx: Block<'blk, 'tcx>,
502     pub val: ValueRef
503 }
504
505 impl<'b, 'tcx> Result<'b, 'tcx> {
506     pub fn new(bcx: Block<'b, 'tcx>, val: ValueRef) -> Result<'b, 'tcx> {
507         Result {
508             bcx: bcx,
509             val: val,
510         }
511     }
512 }
513
514 pub fn val_ty(v: ValueRef) -> Type {
515     unsafe {
516         Type::from_ref(llvm::LLVMTypeOf(v))
517     }
518 }
519
520 // LLVM constant constructors.
521 pub fn C_null(t: Type) -> ValueRef {
522     unsafe {
523         llvm::LLVMConstNull(t.to_ref())
524     }
525 }
526
527 pub fn C_undef(t: Type) -> ValueRef {
528     unsafe {
529         llvm::LLVMGetUndef(t.to_ref())
530     }
531 }
532
533 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
534     unsafe {
535         llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
536     }
537 }
538
539 pub fn C_floating(s: &str, t: Type) -> ValueRef {
540     unsafe {
541         s.with_c_str(|buf| llvm::LLVMConstRealOfString(t.to_ref(), buf))
542     }
543 }
544
545 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
546     C_struct(ccx, &[], false)
547 }
548
549 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
550     C_integral(Type::i1(ccx), val as u64, false)
551 }
552
553 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
554     C_integral(Type::i32(ccx), i as u64, true)
555 }
556
557 pub fn C_i64(ccx: &CrateContext, i: i64) -> ValueRef {
558     C_integral(Type::i64(ccx), i as u64, true)
559 }
560
561 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
562     C_integral(Type::i64(ccx), i, false)
563 }
564
565 pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
566     let v = i.as_i64();
567
568     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
569         32 => assert!(v < (1<<31) && v >= -(1<<31)),
570         64 => {},
571         n => panic!("unsupported target size: {}", n)
572     }
573
574     C_integral(ccx.int_type(), v as u64, true)
575 }
576
577 pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
578     let v = i.as_u64();
579
580     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
581         32 => assert!(v < (1<<32)),
582         64 => {},
583         n => panic!("unsupported target size: {}", n)
584     }
585
586     C_integral(ccx.int_type(), v, false)
587 }
588
589 pub trait AsI64 { fn as_i64(self) -> i64; }
590 pub trait AsU64 { fn as_u64(self) -> u64; }
591
592 // FIXME: remove the intptr conversions, because they
593 // are host-architecture-dependent
594 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
595 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
596 impl AsI64 for int { fn as_i64(self) -> i64 { self as i64 }}
597
598 impl AsU64 for u64  { fn as_u64(self) -> u64 { self as u64 }}
599 impl AsU64 for u32  { fn as_u64(self) -> u64 { self as u64 }}
600 impl AsU64 for uint { fn as_u64(self) -> u64 { self as u64 }}
601
602 pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
603     C_integral(Type::i8(ccx), i as u64, false)
604 }
605
606
607 // This is a 'c-like' raw string, which differs from
608 // our boxed-and-length-annotated strings.
609 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
610     unsafe {
611         match cx.const_cstr_cache().borrow().get(&s) {
612             Some(&llval) => return llval,
613             None => ()
614         }
615
616         let sc = llvm::LLVMConstStringInContext(cx.llcx(),
617                                                 s.get().as_ptr() as *const c_char,
618                                                 s.get().len() as c_uint,
619                                                 !null_terminated as Bool);
620
621         let gsym = token::gensym("str");
622         let g = format!("str{}", gsym.uint()).with_c_str(|buf| {
623             llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf)
624         });
625         llvm::LLVMSetInitializer(g, sc);
626         llvm::LLVMSetGlobalConstant(g, True);
627         llvm::SetLinkage(g, llvm::InternalLinkage);
628
629         cx.const_cstr_cache().borrow_mut().insert(s, g);
630         g
631     }
632 }
633
634 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
635 // you will be kicked off fast isel. See issue #4352 for an example of this.
636 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
637     unsafe {
638         let len = s.get().len();
639         let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false),
640                                             Type::i8p(cx).to_ref());
641         C_named_struct(cx.tn().find_type("str_slice").unwrap(), &[cs, C_uint(cx, len)])
642     }
643 }
644
645 pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
646     unsafe {
647         let len = data.len();
648         let lldata = C_bytes(cx, data);
649
650         let gsym = token::gensym("binary");
651         let g = format!("binary{}", gsym.uint()).with_c_str(|buf| {
652             llvm::LLVMAddGlobal(cx.llmod(), val_ty(lldata).to_ref(), buf)
653         });
654         llvm::LLVMSetInitializer(g, lldata);
655         llvm::LLVMSetGlobalConstant(g, True);
656         llvm::SetLinkage(g, llvm::InternalLinkage);
657
658         let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
659         C_struct(cx, &[cs, C_uint(cx, len)], false)
660     }
661 }
662
663 pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
664     C_struct_in_context(cx.llcx(), elts, packed)
665 }
666
667 pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef {
668     unsafe {
669         llvm::LLVMConstStructInContext(llcx,
670                                        elts.as_ptr(), elts.len() as c_uint,
671                                        packed as Bool)
672     }
673 }
674
675 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
676     unsafe {
677         llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
678     }
679 }
680
681 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
682     unsafe {
683         return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
684     }
685 }
686
687 pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef {
688     C_bytes_in_context(cx.llcx(), bytes)
689 }
690
691 pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef {
692     unsafe {
693         let ptr = bytes.as_ptr() as *const c_char;
694         return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
695     }
696 }
697
698 pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
699                   -> ValueRef {
700     unsafe {
701         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
702
703         debug!("const_get_elt(v={}, us={}, r={})",
704                cx.tn().val_to_string(v), us, cx.tn().val_to_string(r));
705
706         return r;
707     }
708 }
709
710 pub fn is_const(v: ValueRef) -> bool {
711     unsafe {
712         llvm::LLVMIsConstant(v) == True
713     }
714 }
715
716 pub fn const_to_int(v: ValueRef) -> i64 {
717     unsafe {
718         llvm::LLVMConstIntGetSExtValue(v)
719     }
720 }
721
722 pub fn const_to_uint(v: ValueRef) -> u64 {
723     unsafe {
724         llvm::LLVMConstIntGetZExtValue(v)
725     }
726 }
727
728 pub fn is_undef(val: ValueRef) -> bool {
729     unsafe {
730         llvm::LLVMIsUndef(val) != False
731     }
732 }
733
734 pub fn is_null(val: ValueRef) -> bool {
735     unsafe {
736         llvm::LLVMIsNull(val) != False
737     }
738 }
739
740 pub fn monomorphize_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, t: Ty<'tcx>) -> Ty<'tcx> {
741     t.subst(bcx.tcx(), bcx.fcx.param_substs)
742 }
743
744 pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> {
745     let tcx = bcx.tcx();
746     let t = ty::node_id_to_type(tcx, id);
747     monomorphize_type(bcx, t)
748 }
749
750 pub fn expr_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
751     node_id_type(bcx, ex.id)
752 }
753
754 pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
755     monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex))
756 }
757
758 /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
759 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
760 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
761 pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
762                                     span: Span,
763                                     trait_ref: Rc<ty::TraitRef<'tcx>>)
764                                     -> traits::Vtable<'tcx, ()>
765 {
766     let tcx = ccx.tcx();
767
768     // Remove any references to regions; this helps improve caching.
769     let trait_ref = ty_fold::erase_regions(tcx, trait_ref);
770
771     // First check the cache.
772     match ccx.trait_cache().borrow().get(&trait_ref) {
773         Some(vtable) => {
774             info!("Cache hit: {}", trait_ref.repr(ccx.tcx()));
775             return (*vtable).clone();
776         }
777         None => { }
778     }
779
780     debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx()));
781
782     ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id);
783     let infcx = infer::new_infer_ctxt(tcx);
784
785     // Parameter environment is used to give details about type parameters,
786     // but since we are in trans, everything is fully monomorphized.
787     let param_env = ty::empty_parameter_environment();
788
789     // Do the initial selection for the obligation. This yields the
790     // shallow result we are looking for -- that is, what specific impl.
791     let mut selcx = traits::SelectionContext::new(&infcx, &param_env, tcx);
792     let obligation = traits::Obligation::misc(span, trait_ref.clone());
793     let selection = match selcx.select(&obligation) {
794         Ok(Some(selection)) => selection,
795         Ok(None) => {
796             // Ambiguity can happen when monomorphizing during trans
797             // expands to some humongo type that never occurred
798             // statically -- this humongo type can then overflow,
799             // leading to an ambiguous result. So report this as an
800             // overflow bug, since I believe this is the only case
801             // where ambiguity can result.
802             debug!("Encountered ambiguity selecting `{}` during trans, \
803                     presuming due to overflow",
804                    trait_ref.repr(tcx));
805             ccx.sess().span_fatal(
806                 span,
807                 "reached the recursion limit during monomorphization");
808         }
809         Err(e) => {
810             tcx.sess.span_bug(
811                 span,
812                 format!("Encountered error `{}` selecting `{}` during trans",
813                         e.repr(tcx),
814                         trait_ref.repr(tcx)).as_slice())
815         }
816     };
817
818     // Currently, we use a fulfillment context to completely resolve
819     // all nested obligations. This is because they can inform the
820     // inference of the impl's type parameters. However, in principle,
821     // we only need to do this until the impl's type parameters are
822     // fully bound. It could be a slight optimization to stop
823     // iterating early.
824     let mut fulfill_cx = traits::FulfillmentContext::new();
825     let vtable = selection.map_move_nested(|obligation| {
826         fulfill_cx.register_obligation(tcx, obligation);
827     });
828     match fulfill_cx.select_all_or_error(&infcx, &param_env, tcx) {
829         Ok(()) => { }
830         Err(errors) => {
831             if errors.iter().all(|e| e.is_overflow()) {
832                 // See Ok(None) case above.
833                 ccx.sess().span_fatal(
834                     span,
835                     "reached the recursion limit during monomorphization");
836             } else {
837                 tcx.sess.span_bug(
838                     span,
839                     format!("Encountered errors `{}` fulfilling `{}` during trans",
840                             errors.repr(tcx),
841                             trait_ref.repr(tcx)).as_slice());
842             }
843         }
844     }
845
846     // Use skolemize to simultaneously replace all type variables with
847     // their bindings and replace all regions with 'static.  This is
848     // sort of overkill because we do not expect there to be any
849     // unbound type variables, hence no skolemized types should ever
850     // be inserted.
851     let vtable = vtable.fold_with(&mut infcx.skolemizer());
852
853     info!("Cache miss: {}", trait_ref.repr(ccx.tcx()));
854     ccx.trait_cache().borrow_mut().insert(trait_ref,
855                                           vtable.clone());
856
857     vtable
858 }
859
860 // Key used to lookup values supplied for type parameters in an expr.
861 #[deriving(PartialEq, Show)]
862 pub enum ExprOrMethodCall {
863     // Type parameters for a path like `None::<int>`
864     ExprId(ast::NodeId),
865
866     // Type parameters for a method call like `a.foo::<int>()`
867     MethodCall(ty::MethodCall)
868 }
869
870 pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
871                                   node: ExprOrMethodCall)
872                                   -> subst::Substs<'tcx>
873 {
874     let tcx = bcx.tcx();
875
876     let substs = match node {
877         ExprId(id) => {
878             ty::node_id_item_substs(tcx, id).substs
879         }
880         MethodCall(method_call) => {
881             (*tcx.method_map.borrow())[method_call].substs.clone()
882         }
883     };
884
885     if substs.types.any(|t| ty::type_needs_infer(*t)) {
886         bcx.sess().bug(
887             format!("type parameters for node {} include inference types: \
888                      {}",
889                     node,
890                     substs.repr(bcx.tcx())).as_slice());
891     }
892
893     let substs = substs.erase_regions();
894     substs.subst(tcx, bcx.fcx.param_substs)
895 }
896
897 pub fn langcall(bcx: Block,
898                 span: Option<Span>,
899                 msg: &str,
900                 li: LangItem)
901                 -> ast::DefId {
902     match bcx.tcx().lang_items.require(li) {
903         Ok(id) => id,
904         Err(s) => {
905             let msg = format!("{} {}", msg, s);
906             match span {
907                 Some(span) => bcx.tcx().sess.span_fatal(span, msg.as_slice()),
908                 None => bcx.tcx().sess.fatal(msg.as_slice()),
909             }
910         }
911     }
912 }