]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/trans/common.rs
Tell LLVM when a match is exhaustive
[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::cfg;
22 use middle::def;
23 use middle::def_id::DefId;
24 use middle::infer;
25 use middle::lang_items::LangItem;
26 use middle::subst::{self, Substs};
27 use trans::base;
28 use trans::build;
29 use trans::callee;
30 use trans::cleanup;
31 use trans::consts;
32 use trans::datum;
33 use trans::debuginfo::{self, DebugLoc};
34 use trans::declare;
35 use trans::machine;
36 use trans::monomorphize;
37 use trans::type_::Type;
38 use trans::type_of;
39 use middle::traits;
40 use middle::ty::{self, HasTypeFlags, Ty};
41 use middle::ty::fold::{TypeFolder, TypeFoldable};
42 use rustc::front::map::{PathElem, PathName};
43 use rustc_front::hir;
44 use util::nodemap::{FnvHashMap, NodeMap};
45
46 use arena::TypedArena;
47 use libc::{c_uint, c_char};
48 use std::ffi::CString;
49 use std::cell::{Cell, RefCell};
50 use std::vec::Vec;
51 use syntax::ast;
52 use syntax::codemap::{DUMMY_SP, Span};
53 use syntax::parse::token::InternedString;
54 use syntax::parse::token;
55
56 pub use trans::context::CrateContext;
57
58 /// Is the type's representation size known at compile time?
59 pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
60     ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP)
61 }
62
63 pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
64     match ty.sty {
65         ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
66         ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
67         ty::TyBox(ty) => {
68             !type_is_sized(cx, ty)
69         }
70         _ => {
71             false
72         }
73     }
74 }
75
76 /// If `type_needs_drop` returns true, then `ty` is definitely
77 /// non-copy and *might* have a destructor attached; if it returns
78 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
79 ///
80 /// (Note that this implies that if `ty` has a destructor attached,
81 /// then `type_needs_drop` will definitely return `true` for `ty`.)
82 pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
83     type_needs_drop_given_env(cx, ty, &cx.empty_parameter_environment())
84 }
85
86 /// Core implementation of type_needs_drop, potentially making use of
87 /// and/or updating caches held in the `param_env`.
88 fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
89                                       ty: Ty<'tcx>,
90                                       param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
91     // Issue #22536: We first query type_moves_by_default.  It sees a
92     // normalized version of the type, and therefore will definitely
93     // know whether the type implements Copy (and thus needs no
94     // cleanup/drop/zeroing) ...
95     let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP);
96
97     if implements_copy { return false; }
98
99     // ... (issue #22536 continued) but as an optimization, still use
100     // prior logic of asking if the `needs_drop` bit is set; we need
101     // not zero non-Copy types if they have no destructor.
102
103     // FIXME(#22815): Note that calling `ty::type_contents` is a
104     // conservative heuristic; it may report that `needs_drop` is set
105     // when actual type does not actually have a destructor associated
106     // with it. But since `ty` absolutely did not have the `Copy`
107     // bound attached (see above), it is sound to treat it as having a
108     // destructor (e.g. zero its memory on move).
109
110     let contents = ty.type_contents(cx);
111     debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
112     contents.needs_drop(cx)
113 }
114
115 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
116     match ty.sty {
117         ty::TyStruct(def, substs) => {
118             let fields = &def.struct_variant().fields;
119             fields.len() == 1 && {
120                 type_is_immediate(ccx, monomorphize::field_ty(ccx.tcx(), substs, &fields[0]))
121             }
122         }
123         _ => false
124     }
125 }
126
127 pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
128     use trans::machine::llsize_of_alloc;
129     use trans::type_of::sizing_type_of;
130
131     let tcx = ccx.tcx();
132     let simple = ty.is_scalar() ||
133         ty.is_unique() || ty.is_region_ptr() ||
134         type_is_newtype_immediate(ccx, ty) ||
135         ty.is_simd();
136     if simple && !type_is_fat_ptr(tcx, ty) {
137         return true;
138     }
139     if !type_is_sized(tcx, ty) {
140         return false;
141     }
142     match ty.sty {
143         ty::TyStruct(..) | ty::TyEnum(..) | ty::TyTuple(..) | ty::TyArray(_, _) |
144         ty::TyClosure(..) => {
145             let llty = sizing_type_of(ccx, ty);
146             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
147         }
148         _ => type_is_zero_size(ccx, ty)
149     }
150 }
151
152 /// Identify types which have size zero at runtime.
153 pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
154     use trans::machine::llsize_of_alloc;
155     use trans::type_of::sizing_type_of;
156     let llty = sizing_type_of(ccx, ty);
157     llsize_of_alloc(ccx, llty) == 0
158 }
159
160 /// Identifies types which we declare to be equivalent to `void` in C for the purpose of function
161 /// return types. These are `()`, bot, and uninhabited enums. Note that all such types are also
162 /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI
163 /// compatibility).
164 pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
165     ty.is_nil() || ty.is_empty(ccx.tcx())
166 }
167
168 /// Generates a unique symbol based off the name given. This is used to create
169 /// unique symbols for things like closures.
170 pub fn gensym_name(name: &str) -> PathElem {
171     let num = token::gensym(name).usize();
172     // use one colon which will get translated to a period by the mangler, and
173     // we're guaranteed that `num` is globally unique for this crate.
174     PathName(token::gensym(&format!("{}:{}", name, num)))
175 }
176
177 /*
178 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
179 *
180 * An "extern" is an LLVM symbol we wind up emitting an undefined external
181 * reference to. This means "we don't have the thing in this compilation unit,
182 * please make sure you link it in at runtime". This could be a reference to
183 * C code found in a C library, or rust code found in a rust crate.
184 *
185 * Most "externs" are implicitly declared (automatically) as a result of a
186 * user declaring an extern _module_ dependency; this causes the rust driver
187 * to locate an extern crate, scan its compilation metadata, and emit extern
188 * declarations for any symbols used by the declaring crate.
189 *
190 * A "foreign" is an extern that references C (or other non-rust ABI) code.
191 * There is no metadata to scan for extern references so in these cases either
192 * a header-digester like bindgen, or manual function prototypes, have to
193 * serve as declarators. So these are usually given explicitly as prototype
194 * declarations, in rust code, with ABI attributes on them noting which ABI to
195 * link via.
196 *
197 * An "upcall" is a foreign call generated by the compiler (not corresponding
198 * to any user-written call in the code) into the runtime library, to perform
199 * some helper task such as bringing a task to life, allocating memory, etc.
200 *
201 */
202
203 #[derive(Copy, Clone)]
204 pub struct NodeIdAndSpan {
205     pub id: ast::NodeId,
206     pub span: Span,
207 }
208
209 pub fn expr_info(expr: &hir::Expr) -> NodeIdAndSpan {
210     NodeIdAndSpan { id: expr.id, span: expr.span }
211 }
212
213 /// The concrete version of ty::FieldDef. The name is the field index if
214 /// the field is numeric.
215 pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
216
217 /// The concrete version of ty::VariantDef
218 pub struct VariantInfo<'tcx> {
219     pub discr: ty::Disr,
220     pub fields: Vec<Field<'tcx>>
221 }
222
223 impl<'tcx> VariantInfo<'tcx> {
224     pub fn from_ty(tcx: &ty::ctxt<'tcx>,
225                    ty: Ty<'tcx>,
226                    opt_def: Option<def::Def>)
227                    -> Self
228     {
229         match ty.sty {
230             ty::TyStruct(adt, substs) | ty::TyEnum(adt, substs) => {
231                 let variant = match opt_def {
232                     None => adt.struct_variant(),
233                     Some(def) => adt.variant_of_def(def)
234                 };
235
236                 VariantInfo {
237                     discr: variant.disr_val,
238                     fields: variant.fields.iter().map(|f| {
239                         Field(f.name, monomorphize::field_ty(tcx, substs, f))
240                     }).collect()
241                 }
242             }
243
244             ty::TyTuple(ref v) => {
245                 VariantInfo {
246                     discr: 0,
247                     fields: v.iter().enumerate().map(|(i, &t)| {
248                         Field(token::intern(&i.to_string()), t)
249                     }).collect()
250                 }
251             }
252
253             _ => {
254                 tcx.sess.bug(&format!(
255                     "cannot get field types from the type {:?}",
256                     ty));
257             }
258         }
259     }
260
261     /// Return the variant corresponding to a given node (e.g. expr)
262     pub fn of_node(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self {
263         let node_def = tcx.def_map.borrow().get(&id).map(|v| v.full_def());
264         Self::from_ty(tcx, ty, node_def)
265     }
266
267     pub fn field_index(&self, name: ast::Name) -> usize {
268         self.fields.iter().position(|&Field(n,_)| n == name).unwrap_or_else(|| {
269             panic!("unknown field `{}`", name)
270         })
271     }
272 }
273
274 pub struct BuilderRef_res {
275     pub b: BuilderRef,
276 }
277
278 impl Drop for BuilderRef_res {
279     fn drop(&mut self) {
280         unsafe {
281             llvm::LLVMDisposeBuilder(self.b);
282         }
283     }
284 }
285
286 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
287     BuilderRef_res {
288         b: b
289     }
290 }
291
292 pub type ExternMap = FnvHashMap<String, ValueRef>;
293
294 pub fn validate_substs(substs: &Substs) {
295     assert!(!substs.types.needs_infer());
296 }
297
298 // work around bizarre resolve errors
299 type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
300 pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
301
302 #[derive(Clone, Debug)]
303 struct HintEntry<'tcx> {
304     // The datum for the dropflag-hint itself; note that many
305     // source-level Lvalues will be associated with the same
306     // dropflag-hint datum.
307     datum: cleanup::DropHintDatum<'tcx>,
308 }
309
310 pub struct DropFlagHintsMap<'tcx> {
311     // Maps NodeId for expressions that read/write unfragmented state
312     // to that state's drop-flag "hint."  (A stack-local hint
313     // indicates either that (1.) it is certain that no-drop is
314     // needed, or (2.)  inline drop-flag must be consulted.)
315     node_map: NodeMap<HintEntry<'tcx>>,
316 }
317
318 impl<'tcx> DropFlagHintsMap<'tcx> {
319     pub fn new() -> DropFlagHintsMap<'tcx> { DropFlagHintsMap { node_map: NodeMap() } }
320     pub fn has_hint(&self, id: ast::NodeId) -> bool { self.node_map.contains_key(&id) }
321     pub fn insert(&mut self, id: ast::NodeId, datum: cleanup::DropHintDatum<'tcx>) {
322         self.node_map.insert(id, HintEntry { datum: datum });
323     }
324     pub fn hint_datum(&self, id: ast::NodeId) -> Option<cleanup::DropHintDatum<'tcx>> {
325         self.node_map.get(&id).map(|t|t.datum)
326     }
327 }
328
329 // Function context.  Every LLVM function we create will have one of
330 // these.
331 pub struct FunctionContext<'a, 'tcx: 'a> {
332     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
333     // address of the first instruction in the sequence of
334     // instructions for this function that will go in the .text
335     // section of the executable we're generating.
336     pub llfn: ValueRef,
337
338     // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv
339     pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
340
341     // The environment argument in a closure.
342     pub llenv: Option<ValueRef>,
343
344     // A pointer to where to store the return value. If the return type is
345     // immediate, this points to an alloca in the function. Otherwise, it's a
346     // pointer to the hidden first parameter of the function. After function
347     // construction, this should always be Some.
348     pub llretslotptr: Cell<Option<ValueRef>>,
349
350     // These pub elements: "hoisted basic blocks" containing
351     // administrative activities that have to happen in only one place in
352     // the function, due to LLVM's quirks.
353     // A marker for the place where we want to insert the function's static
354     // allocas, so that LLVM will coalesce them into a single alloca call.
355     pub alloca_insert_pt: Cell<Option<ValueRef>>,
356     pub llreturn: Cell<Option<BasicBlockRef>>,
357
358     // If the function has any nested return's, including something like:
359     // fn foo() -> Option<Foo> { Some(Foo { x: return None }) }, then
360     // we use a separate alloca for each return
361     pub needs_ret_allocas: bool,
362
363     // The a value alloca'd for calls to upcalls.rust_personality. Used when
364     // outputting the resume instruction.
365     pub personality: Cell<Option<ValueRef>>,
366
367     // True if the caller expects this fn to use the out pointer to
368     // return. Either way, your code should write into the slot llretslotptr
369     // points to, but if this value is false, that slot will be a local alloca.
370     pub caller_expects_out_pointer: bool,
371
372     // Maps the DefId's for local variables to the allocas created for
373     // them in llallocas.
374     pub lllocals: RefCell<NodeMap<LvalueDatum<'tcx>>>,
375
376     // Same as above, but for closure upvars
377     pub llupvars: RefCell<NodeMap<ValueRef>>,
378
379     // Carries info about drop-flags for local bindings (longer term,
380     // paths) for the code being compiled.
381     pub lldropflag_hints: RefCell<DropFlagHintsMap<'tcx>>,
382
383     // The NodeId of the function, or -1 if it doesn't correspond to
384     // a user-defined function.
385     pub id: ast::NodeId,
386
387     // If this function is being monomorphized, this contains the type
388     // substitutions used.
389     pub param_substs: &'tcx Substs<'tcx>,
390
391     // The source span and nesting context where this function comes from, for
392     // error reporting and symbol generation.
393     pub span: Option<Span>,
394
395     // The arena that blocks are allocated from.
396     pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
397
398     // This function's enclosing crate context.
399     pub ccx: &'a CrateContext<'a, 'tcx>,
400
401     // Used and maintained by the debuginfo module.
402     pub debug_context: debuginfo::FunctionDebugContext,
403
404     // Cleanup scopes.
405     pub scopes: RefCell<Vec<cleanup::CleanupScope<'a, 'tcx>>>,
406
407     pub cfg: Option<cfg::CFG>,
408 }
409
410 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
411     pub fn arg_offset(&self) -> usize {
412         self.env_arg_pos() + if self.llenv.is_some() { 1 } else { 0 }
413     }
414
415     pub fn env_arg_pos(&self) -> usize {
416         if self.caller_expects_out_pointer {
417             1
418         } else {
419             0
420         }
421     }
422
423     pub fn cleanup(&self) {
424         unsafe {
425             llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
426                                                      .get()
427                                                      .unwrap());
428         }
429     }
430
431     pub fn get_llreturn(&self) -> BasicBlockRef {
432         if self.llreturn.get().is_none() {
433
434             self.llreturn.set(Some(unsafe {
435                 llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn,
436                                                     "return\0".as_ptr() as *const _)
437             }))
438         }
439
440         self.llreturn.get().unwrap()
441     }
442
443     pub fn get_ret_slot(&self, bcx: Block<'a, 'tcx>,
444                         output: ty::FnOutput<'tcx>,
445                         name: &str) -> ValueRef {
446         if self.needs_ret_allocas {
447             base::alloca(bcx, match output {
448                 ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
449                 ty::FnDiverging => Type::void(bcx.ccx())
450             }, name)
451         } else {
452             self.llretslotptr.get().unwrap()
453         }
454     }
455
456     pub fn new_block(&'a self,
457                      is_lpad: bool,
458                      name: &str,
459                      opt_node_id: Option<ast::NodeId>)
460                      -> Block<'a, 'tcx> {
461         unsafe {
462             let name = CString::new(name).unwrap();
463             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
464                                                            self.llfn,
465                                                            name.as_ptr());
466             BlockS::new(llbb, is_lpad, opt_node_id, self)
467         }
468     }
469
470     pub fn new_id_block(&'a self,
471                         name: &str,
472                         node_id: ast::NodeId)
473                         -> Block<'a, 'tcx> {
474         self.new_block(false, name, Some(node_id))
475     }
476
477     pub fn new_temp_block(&'a self,
478                           name: &str)
479                           -> Block<'a, 'tcx> {
480         self.new_block(false, name, None)
481     }
482
483     pub fn join_blocks(&'a self,
484                        id: ast::NodeId,
485                        in_cxs: &[Block<'a, 'tcx>])
486                        -> Block<'a, 'tcx> {
487         let out = self.new_id_block("join", id);
488         let mut reachable = false;
489         for bcx in in_cxs {
490             if !bcx.unreachable.get() {
491                 build::Br(*bcx, out.llbb, DebugLoc::None);
492                 reachable = true;
493             }
494         }
495         if !reachable {
496             build::Unreachable(out);
497         }
498         return out;
499     }
500
501     pub fn monomorphize<T>(&self, value: &T) -> T
502         where T : TypeFoldable<'tcx> + HasTypeFlags
503     {
504         monomorphize::apply_param_substs(self.ccx.tcx(),
505                                          self.param_substs,
506                                          value)
507     }
508
509     /// This is the same as `common::type_needs_drop`, except that it
510     /// may use or update caches within this `FunctionContext`.
511     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
512         type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
513     }
514
515     pub fn eh_personality(&self) -> ValueRef {
516         // The exception handling personality function.
517         //
518         // If our compilation unit has the `eh_personality` lang item somewhere
519         // within it, then we just need to translate that. Otherwise, we're
520         // building an rlib which will depend on some upstream implementation of
521         // this function, so we just codegen a generic reference to it. We don't
522         // specify any of the types for the function, we just make it a symbol
523         // that LLVM can later use.
524         //
525         // Note that MSVC is a little special here in that we don't use the
526         // `eh_personality` lang item at all. Currently LLVM has support for
527         // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
528         // *name of the personality function* to decide what kind of unwind side
529         // tables/landing pads to emit. It looks like Dwarf is used by default,
530         // injecting a dependency on the `_Unwind_Resume` symbol for resuming
531         // an "exception", but for MSVC we want to force SEH. This means that we
532         // can't actually have the personality function be our standard
533         // `rust_eh_personality` function, but rather we wired it up to the
534         // CRT's custom personality function, which forces LLVM to consider
535         // landing pads as "landing pads for SEH".
536         let target = &self.ccx.sess().target.target;
537         match self.ccx.tcx().lang_items.eh_personality() {
538             Some(def_id) if !base::wants_msvc_seh(self.ccx.sess()) => {
539                 callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
540                                      self.param_substs).val
541             }
542             _ => {
543                 let mut personality = self.ccx.eh_personality().borrow_mut();
544                 match *personality {
545                     Some(llpersonality) => llpersonality,
546                     None => {
547                         let name = if !base::wants_msvc_seh(self.ccx.sess()) {
548                             "rust_eh_personality"
549                         } else if target.arch == "x86" {
550                             "_except_handler3"
551                         } else {
552                             "__C_specific_handler"
553                         };
554                         let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
555                         let f = declare::declare_cfn(self.ccx, name, fty,
556                                                      self.ccx.tcx().types.i32);
557                         *personality = Some(f);
558                         f
559                     }
560                 }
561             }
562         }
563     }
564
565     /// By default, LLVM lowers `resume` instructions into calls to `_Unwind_Resume`
566     /// defined in libgcc, however, unlike personality routines, there is no easy way to
567     /// override that symbol.  This method injects a local-scoped `_Unwind_Resume` function
568     /// which immediately defers to the user-defined `eh_unwind_resume` lang item.
569     pub fn inject_unwind_resume_hook(&self) {
570         let ccx = self.ccx;
571         if !ccx.sess().target.target.options.custom_unwind_resume ||
572            ccx.unwind_resume_hooked().get() {
573             return;
574         }
575
576         let new_resume = match ccx.tcx().lang_items.eh_unwind_resume() {
577             Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0), &self.param_substs).val,
578             None => {
579                 let fty = Type::variadic_func(&[], &Type::void(self.ccx));
580                 declare::declare_cfn(self.ccx, "rust_eh_unwind_resume", fty,
581                                      self.ccx.tcx().mk_nil())
582             }
583         };
584
585         unsafe {
586             let resume_type = Type::func(&[Type::i8(ccx).ptr_to()], &Type::void(ccx));
587             let old_resume = llvm::LLVMAddFunction(ccx.llmod(),
588                                                    "_Unwind_Resume\0".as_ptr() as *const _,
589                                                    resume_type.to_ref());
590             llvm::SetLinkage(old_resume, llvm::InternalLinkage);
591             let llbb = llvm::LLVMAppendBasicBlockInContext(ccx.llcx(),
592                                                            old_resume,
593                                                            "\0".as_ptr() as *const _);
594             let builder = ccx.builder();
595             builder.position_at_end(llbb);
596             builder.call(new_resume, &[llvm::LLVMGetFirstParam(old_resume)], None);
597             builder.unreachable(); // it should never return
598
599             // Until DwarfEHPrepare pass has run, _Unwind_Resume is not referenced by any live code
600             // and is subject to dead code elimination.  Here we add _Unwind_Resume to @llvm.globals
601             // to prevent that.
602             let i8p_ty = Type::i8p(ccx);
603             let used_ty = Type::array(&i8p_ty, 1);
604             let used = llvm::LLVMAddGlobal(ccx.llmod(), used_ty.to_ref(),
605                                            "llvm.used\0".as_ptr() as *const _);
606             let old_resume = llvm::LLVMConstBitCast(old_resume, i8p_ty.to_ref());
607             llvm::LLVMSetInitializer(used, C_array(i8p_ty, &[old_resume]));
608             llvm::SetLinkage(used, llvm::AppendingLinkage);
609             llvm::LLVMSetSection(used, "llvm.metadata\0".as_ptr() as *const _)
610         }
611         ccx.unwind_resume_hooked().set(true);
612     }
613 }
614
615 // Basic block context.  We create a block context for each basic block
616 // (single-entry, single-exit sequence of instructions) we generate from Rust
617 // code.  Each basic block we generate is attached to a function, typically
618 // with many basic blocks per function.  All the basic blocks attached to a
619 // function are organized as a directed graph.
620 pub struct BlockS<'blk, 'tcx: 'blk> {
621     // The BasicBlockRef returned from a call to
622     // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
623     // block to the function pointed to by llfn.  We insert
624     // instructions into that block by way of this block context.
625     // The block pointing to this one in the function's digraph.
626     pub llbb: BasicBlockRef,
627     pub terminated: Cell<bool>,
628     pub unreachable: Cell<bool>,
629
630     // Is this block part of a landing pad?
631     pub is_lpad: bool,
632
633     // AST node-id associated with this block, if any. Used for
634     // debugging purposes only.
635     pub opt_node_id: Option<ast::NodeId>,
636
637     // The function context for the function to which this block is
638     // attached.
639     pub fcx: &'blk FunctionContext<'blk, 'tcx>,
640 }
641
642 pub type Block<'blk, 'tcx> = &'blk BlockS<'blk, 'tcx>;
643
644 impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
645     pub fn new(llbb: BasicBlockRef,
646                is_lpad: bool,
647                opt_node_id: Option<ast::NodeId>,
648                fcx: &'blk FunctionContext<'blk, 'tcx>)
649                -> Block<'blk, 'tcx> {
650         fcx.block_arena.alloc(BlockS {
651             llbb: llbb,
652             terminated: Cell::new(false),
653             unreachable: Cell::new(false),
654             is_lpad: is_lpad,
655             opt_node_id: opt_node_id,
656             fcx: fcx
657         })
658     }
659
660     pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
661         self.fcx.ccx
662     }
663     pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
664         self.fcx.ccx.tcx()
665     }
666     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
667
668     pub fn name(&self, name: ast::Name) -> String {
669         name.to_string()
670     }
671
672     pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
673         self.tcx().map.node_to_string(id).to_string()
674     }
675
676     pub fn def(&self, nid: ast::NodeId) -> def::Def {
677         match self.tcx().def_map.borrow().get(&nid) {
678             Some(v) => v.full_def(),
679             None => {
680                 self.tcx().sess.bug(&format!(
681                     "no def associated with node id {}", nid));
682             }
683         }
684     }
685
686     pub fn val_to_string(&self, val: ValueRef) -> String {
687         self.ccx().tn().val_to_string(val)
688     }
689
690     pub fn llty_str(&self, ty: Type) -> String {
691         self.ccx().tn().type_to_string(ty)
692     }
693
694     pub fn to_str(&self) -> String {
695         format!("[block {:p}]", self)
696     }
697
698     pub fn monomorphize<T>(&self, value: &T) -> T
699         where T : TypeFoldable<'tcx> + HasTypeFlags
700     {
701         monomorphize::apply_param_substs(self.tcx(),
702                                          self.fcx.param_substs,
703                                          value)
704     }
705 }
706
707 pub struct Result<'blk, 'tcx: 'blk> {
708     pub bcx: Block<'blk, 'tcx>,
709     pub val: ValueRef
710 }
711
712 impl<'b, 'tcx> Result<'b, 'tcx> {
713     pub fn new(bcx: Block<'b, 'tcx>, val: ValueRef) -> Result<'b, 'tcx> {
714         Result {
715             bcx: bcx,
716             val: val,
717         }
718     }
719 }
720
721 pub fn val_ty(v: ValueRef) -> Type {
722     unsafe {
723         Type::from_ref(llvm::LLVMTypeOf(v))
724     }
725 }
726
727 // LLVM constant constructors.
728 pub fn C_null(t: Type) -> ValueRef {
729     unsafe {
730         llvm::LLVMConstNull(t.to_ref())
731     }
732 }
733
734 pub fn C_undef(t: Type) -> ValueRef {
735     unsafe {
736         llvm::LLVMGetUndef(t.to_ref())
737     }
738 }
739
740 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
741     unsafe {
742         llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
743     }
744 }
745
746 pub fn C_floating(s: &str, t: Type) -> ValueRef {
747     unsafe {
748         let s = CString::new(s).unwrap();
749         llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
750     }
751 }
752
753 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
754     C_struct(ccx, &[], false)
755 }
756
757 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
758     C_integral(Type::i1(ccx), val as u64, false)
759 }
760
761 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
762     C_integral(Type::i32(ccx), i as u64, true)
763 }
764
765 pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef {
766     C_integral(Type::i32(ccx), i as u64, false)
767 }
768
769 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
770     C_integral(Type::i64(ccx), i, false)
771 }
772
773 pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
774     let v = i.as_i64();
775
776     let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type());
777
778     if bit_size < 64 {
779         // make sure it doesn't overflow
780         assert!(v < (1<<(bit_size-1)) && v >= -(1<<(bit_size-1)));
781     }
782
783     C_integral(ccx.int_type(), v as u64, true)
784 }
785
786 pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
787     let v = i.as_u64();
788
789     let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type());
790
791     if bit_size < 64 {
792         // make sure it doesn't overflow
793         assert!(v < (1<<bit_size));
794     }
795
796     C_integral(ccx.int_type(), v, false)
797 }
798
799 pub trait AsI64 { fn as_i64(self) -> i64; }
800 pub trait AsU64 { fn as_u64(self) -> u64; }
801
802 // FIXME: remove the intptr conversions, because they
803 // are host-architecture-dependent
804 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
805 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
806 impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }}
807
808 impl AsU64 for u64  { fn as_u64(self) -> u64 { self as u64 }}
809 impl AsU64 for u32  { fn as_u64(self) -> u64 { self as u64 }}
810 impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }}
811
812 pub fn C_u8(ccx: &CrateContext, i: u8) -> ValueRef {
813     C_integral(Type::i8(ccx), i as u64, false)
814 }
815
816
817 // This is a 'c-like' raw string, which differs from
818 // our boxed-and-length-annotated strings.
819 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
820     unsafe {
821         match cx.const_cstr_cache().borrow().get(&s) {
822             Some(&llval) => return llval,
823             None => ()
824         }
825
826         let sc = llvm::LLVMConstStringInContext(cx.llcx(),
827                                                 s.as_ptr() as *const c_char,
828                                                 s.len() as c_uint,
829                                                 !null_terminated as Bool);
830
831         let gsym = token::gensym("str");
832         let sym = format!("str{}", gsym.usize());
833         let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
834             cx.sess().bug(&format!("symbol `{}` is already defined", sym));
835         });
836         llvm::LLVMSetInitializer(g, sc);
837         llvm::LLVMSetGlobalConstant(g, True);
838         llvm::SetLinkage(g, llvm::InternalLinkage);
839
840         cx.const_cstr_cache().borrow_mut().insert(s, g);
841         g
842     }
843 }
844
845 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
846 // you will be kicked off fast isel. See issue #4352 for an example of this.
847 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
848     let len = s.len();
849     let cs = consts::ptrcast(C_cstr(cx, s, false), Type::i8p(cx));
850     C_named_struct(cx.tn().find_type("str_slice").unwrap(), &[cs, C_uint(cx, len)])
851 }
852
853 pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
854     C_struct_in_context(cx.llcx(), elts, packed)
855 }
856
857 pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef {
858     unsafe {
859         llvm::LLVMConstStructInContext(llcx,
860                                        elts.as_ptr(), elts.len() as c_uint,
861                                        packed as Bool)
862     }
863 }
864
865 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
866     unsafe {
867         llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
868     }
869 }
870
871 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
872     unsafe {
873         return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
874     }
875 }
876
877 pub fn C_vector(elts: &[ValueRef]) -> ValueRef {
878     unsafe {
879         return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint);
880     }
881 }
882
883 pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef {
884     C_bytes_in_context(cx.llcx(), bytes)
885 }
886
887 pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef {
888     unsafe {
889         let ptr = bytes.as_ptr() as *const c_char;
890         return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
891     }
892 }
893
894 pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
895               -> ValueRef {
896     unsafe {
897         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
898
899         debug!("const_get_elt(v={}, us={:?}, r={})",
900                cx.tn().val_to_string(v), us, cx.tn().val_to_string(r));
901
902         return r;
903     }
904 }
905
906 pub fn const_to_int(v: ValueRef) -> i64 {
907     unsafe {
908         llvm::LLVMConstIntGetSExtValue(v)
909     }
910 }
911
912 pub fn const_to_uint(v: ValueRef) -> u64 {
913     unsafe {
914         llvm::LLVMConstIntGetZExtValue(v)
915     }
916 }
917
918 fn is_const_integral(v: ValueRef) -> bool {
919     unsafe {
920         !llvm::LLVMIsAConstantInt(v).is_null()
921     }
922 }
923
924 pub fn const_to_opt_int(v: ValueRef) -> Option<i64> {
925     unsafe {
926         if is_const_integral(v) {
927             Some(llvm::LLVMConstIntGetSExtValue(v))
928         } else {
929             None
930         }
931     }
932 }
933
934 pub fn const_to_opt_uint(v: ValueRef) -> Option<u64> {
935     unsafe {
936         if is_const_integral(v) {
937             Some(llvm::LLVMConstIntGetZExtValue(v))
938         } else {
939             None
940         }
941     }
942 }
943
944 pub fn is_undef(val: ValueRef) -> bool {
945     unsafe {
946         llvm::LLVMIsUndef(val) != False
947     }
948 }
949
950 #[allow(dead_code)] // potentially useful
951 pub fn is_null(val: ValueRef) -> bool {
952     unsafe {
953         llvm::LLVMIsNull(val) != False
954     }
955 }
956
957 pub fn monomorphize_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, t: Ty<'tcx>) -> Ty<'tcx> {
958     bcx.fcx.monomorphize(&t)
959 }
960
961 pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> {
962     let tcx = bcx.tcx();
963     let t = tcx.node_id_to_type(id);
964     monomorphize_type(bcx, t)
965 }
966
967 pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> Ty<'tcx> {
968     node_id_type(bcx, ex.id)
969 }
970
971 pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> Ty<'tcx> {
972     monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex))
973 }
974
975 /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
976 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
977 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
978 pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
979                                     span: Span,
980                                     trait_ref: ty::PolyTraitRef<'tcx>)
981                                     -> traits::Vtable<'tcx, ()>
982 {
983     let tcx = ccx.tcx();
984
985     // Remove any references to regions; this helps improve caching.
986     let trait_ref = tcx.erase_regions(&trait_ref);
987
988     // First check the cache.
989     match ccx.trait_cache().borrow().get(&trait_ref) {
990         Some(vtable) => {
991             info!("Cache hit: {:?}", trait_ref);
992             return (*vtable).clone();
993         }
994         None => { }
995     }
996
997     debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}",
998            trait_ref, trait_ref.def_id());
999
1000
1001     // Do the initial selection for the obligation. This yields the
1002     // shallow result we are looking for -- that is, what specific impl.
1003     let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
1004     let mut selcx = traits::SelectionContext::new(&infcx);
1005
1006     let obligation =
1007         traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
1008                                 trait_ref.to_poly_trait_predicate());
1009     let selection = match selcx.select(&obligation) {
1010         Ok(Some(selection)) => selection,
1011         Ok(None) => {
1012             // Ambiguity can happen when monomorphizing during trans
1013             // expands to some humongo type that never occurred
1014             // statically -- this humongo type can then overflow,
1015             // leading to an ambiguous result. So report this as an
1016             // overflow bug, since I believe this is the only case
1017             // where ambiguity can result.
1018             debug!("Encountered ambiguity selecting `{:?}` during trans, \
1019                     presuming due to overflow",
1020                    trait_ref);
1021             ccx.sess().span_fatal(
1022                 span,
1023                 "reached the recursion limit during monomorphization");
1024         }
1025         Err(e) => {
1026             tcx.sess.span_bug(
1027                 span,
1028                 &format!("Encountered error `{:?}` selecting `{:?}` during trans",
1029                         e,
1030                         trait_ref))
1031         }
1032     };
1033
1034     // Currently, we use a fulfillment context to completely resolve
1035     // all nested obligations. This is because they can inform the
1036     // inference of the impl's type parameters.
1037     let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
1038     let vtable = selection.map(|predicate| {
1039         fulfill_cx.register_predicate_obligation(&infcx, predicate);
1040     });
1041     let vtable = infer::drain_fulfillment_cx_or_panic(
1042         span, &infcx, &mut fulfill_cx, &vtable
1043     );
1044
1045     info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
1046
1047     ccx.trait_cache().borrow_mut().insert(trait_ref, vtable.clone());
1048
1049     vtable
1050 }
1051
1052 /// Normalizes the predicates and checks whether they hold.  If this
1053 /// returns false, then either normalize encountered an error or one
1054 /// of the predicates did not hold. Used when creating vtables to
1055 /// check for unsatisfiable methods.
1056 pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1057                                                predicates: Vec<ty::Predicate<'tcx>>)
1058                                                -> bool
1059 {
1060     debug!("normalize_and_test_predicates(predicates={:?})",
1061            predicates);
1062
1063     let tcx = ccx.tcx();
1064     let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
1065     let mut selcx = traits::SelectionContext::new(&infcx);
1066     let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
1067     let cause = traits::ObligationCause::dummy();
1068     let traits::Normalized { value: predicates, obligations } =
1069         traits::normalize(&mut selcx, cause.clone(), &predicates);
1070     for obligation in obligations {
1071         fulfill_cx.register_predicate_obligation(&infcx, obligation);
1072     }
1073     for predicate in predicates {
1074         let obligation = traits::Obligation::new(cause.clone(), predicate);
1075         fulfill_cx.register_predicate_obligation(&infcx, obligation);
1076     }
1077
1078     infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
1079 }
1080
1081 // Key used to lookup values supplied for type parameters in an expr.
1082 #[derive(Copy, Clone, PartialEq, Debug)]
1083 pub enum ExprOrMethodCall {
1084     // Type parameters for a path like `None::<int>`
1085     ExprId(ast::NodeId),
1086
1087     // Type parameters for a method call like `a.foo::<int>()`
1088     MethodCallKey(ty::MethodCall)
1089 }
1090
1091 pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1092                             node: ExprOrMethodCall,
1093                             param_substs: &subst::Substs<'tcx>)
1094                             -> subst::Substs<'tcx> {
1095     let tcx = ccx.tcx();
1096
1097     let substs = match node {
1098         ExprId(id) => {
1099             tcx.node_id_item_substs(id).substs
1100         }
1101         MethodCallKey(method_call) => {
1102             tcx.tables.borrow().method_map[&method_call].substs.clone()
1103         }
1104     };
1105
1106     if substs.types.needs_infer() {
1107             tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}",
1108                                  node, substs));
1109         }
1110
1111         monomorphize::apply_param_substs(tcx,
1112                                          param_substs,
1113                                          &substs.erase_regions())
1114 }
1115
1116 pub fn langcall(bcx: Block,
1117                 span: Option<Span>,
1118                 msg: &str,
1119                 li: LangItem)
1120                 -> DefId {
1121     match bcx.tcx().lang_items.require(li) {
1122         Ok(id) => id,
1123         Err(s) => {
1124             let msg = format!("{} {}", msg, s);
1125             match span {
1126                 Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]),
1127                 None => bcx.tcx().sess.fatal(&msg[..]),
1128             }
1129         }
1130     }
1131 }
1132
1133 /// Return the VariantDef corresponding to an inlined variant node
1134 pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1135                                      inlined_vid: ast::NodeId)
1136                                      -> ty::VariantDef<'tcx>
1137 {
1138
1139     let ctor_ty = ccx.tcx().node_id_to_type(inlined_vid);
1140     debug!("inlined_variant_def: ctor_ty={:?} inlined_vid={:?}", ctor_ty,
1141            inlined_vid);
1142     let adt_def = match ctor_ty.sty {
1143         ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
1144             output: ty::FnConverging(ty), ..
1145         }), ..}) => ty,
1146         _ => ctor_ty
1147     }.ty_adt_def().unwrap();
1148     adt_def.variants.iter().find(|v| {
1149         DefId::local(inlined_vid) == v.did ||
1150             ccx.external().borrow().get(&v.did) == Some(&Some(inlined_vid))
1151     }).unwrap_or_else(|| {
1152         ccx.sess().bug(&format!("no variant for {:?}::{}", adt_def, inlined_vid))
1153     })
1154 }