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