]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/common.rs
Auto merge of #35856 - phimuemue:master, r=brson
[rust.git] / src / librustc_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 use session::Session;
16 use llvm;
17 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef, TypeKind};
18 use llvm::{True, False, Bool, OperandBundleDef};
19 use rustc::hir::def::Def;
20 use rustc::hir::def_id::DefId;
21 use rustc::infer::TransNormalize;
22 use rustc::util::common::MemoizationMap;
23 use middle::lang_items::LangItem;
24 use rustc::ty::subst::Substs;
25 use abi::{Abi, FnType};
26 use base;
27 use build;
28 use builder::Builder;
29 use callee::Callee;
30 use cleanup;
31 use consts;
32 use debuginfo::{self, DebugLoc};
33 use declare;
34 use machine;
35 use mir::CachedMir;
36 use monomorphize;
37 use type_::Type;
38 use value::Value;
39 use rustc::ty::{self, Ty, TyCtxt};
40 use rustc::ty::layout::Layout;
41 use rustc::traits::{self, SelectionContext, Reveal};
42 use rustc::ty::fold::TypeFoldable;
43 use rustc::hir;
44
45 use arena::TypedArena;
46 use libc::{c_uint, c_char};
47 use std::ops::Deref;
48 use std::ffi::CString;
49 use std::cell::{Cell, RefCell};
50
51 use syntax::ast;
52 use syntax::parse::token::InternedString;
53 use syntax::parse::token;
54 use syntax_pos::{DUMMY_SP, Span};
55
56 pub use context::{CrateContext, SharedCrateContext};
57
58 /// Is the type's representation size known at compile time?
59 pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
60     ty.is_sized(tcx, &tcx.empty_parameter_environment(), DUMMY_SP)
61 }
62
63 pub fn type_is_fat_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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(tcx, ty)
69         }
70         _ => {
71             false
72         }
73     }
74 }
75
76 pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
77     use machine::llsize_of_alloc;
78     use type_of::sizing_type_of;
79
80     let tcx = ccx.tcx();
81     let simple = ty.is_scalar() ||
82         ty.is_unique() || ty.is_region_ptr() ||
83         ty.is_simd();
84     if simple && !type_is_fat_ptr(tcx, ty) {
85         return true;
86     }
87     if !type_is_sized(tcx, ty) {
88         return false;
89     }
90     match ty.sty {
91         ty::TyStruct(..) | ty::TyEnum(..) | ty::TyTuple(..) | ty::TyArray(_, _) |
92         ty::TyClosure(..) => {
93             let llty = sizing_type_of(ccx, ty);
94             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
95         }
96         _ => type_is_zero_size(ccx, ty)
97     }
98 }
99
100 /// Returns Some([a, b]) if the type has a pair of fields with types a and b.
101 pub fn type_pair_fields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
102                                   -> Option<[Ty<'tcx>; 2]> {
103     match ty.sty {
104         ty::TyEnum(adt, substs) | ty::TyStruct(adt, substs) => {
105             assert_eq!(adt.variants.len(), 1);
106             let fields = &adt.variants[0].fields;
107             if fields.len() != 2 {
108                 return None;
109             }
110             Some([monomorphize::field_ty(ccx.tcx(), substs, &fields[0]),
111                   monomorphize::field_ty(ccx.tcx(), substs, &fields[1])])
112         }
113         ty::TyClosure(_, ty::ClosureSubsts { upvar_tys: tys, .. }) |
114         ty::TyTuple(tys) => {
115             if tys.len() != 2 {
116                 return None;
117             }
118             Some([tys[0], tys[1]])
119         }
120         _ => None
121     }
122 }
123
124 /// Returns true if the type is represented as a pair of immediates.
125 pub fn type_is_imm_pair<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
126                                   -> bool {
127     match *ccx.layout_of(ty) {
128         Layout::FatPointer { .. } => true,
129         Layout::Univariant { ref variant, .. } => {
130             // There must be only 2 fields.
131             if variant.offset_after_field.len() != 2 {
132                 return false;
133             }
134
135             match type_pair_fields(ccx, ty) {
136                 Some([a, b]) => {
137                     type_is_immediate(ccx, a) && type_is_immediate(ccx, b)
138                 }
139                 None => false
140             }
141         }
142         _ => false
143     }
144 }
145
146 /// Identify types which have size zero at runtime.
147 pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
148     use machine::llsize_of_alloc;
149     use type_of::sizing_type_of;
150     let llty = sizing_type_of(ccx, ty);
151     llsize_of_alloc(ccx, llty) == 0
152 }
153
154 /// Generates a unique symbol based off the name given. This is used to create
155 /// unique symbols for things like closures.
156 pub fn gensym_name(name: &str) -> ast::Name {
157     let num = token::gensym(name).0;
158     // use one colon which will get translated to a period by the mangler, and
159     // we're guaranteed that `num` is globally unique for this crate.
160     token::gensym(&format!("{}:{}", name, num))
161 }
162
163 /*
164 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
165 *
166 * An "extern" is an LLVM symbol we wind up emitting an undefined external
167 * reference to. This means "we don't have the thing in this compilation unit,
168 * please make sure you link it in at runtime". This could be a reference to
169 * C code found in a C library, or rust code found in a rust crate.
170 *
171 * Most "externs" are implicitly declared (automatically) as a result of a
172 * user declaring an extern _module_ dependency; this causes the rust driver
173 * to locate an extern crate, scan its compilation metadata, and emit extern
174 * declarations for any symbols used by the declaring crate.
175 *
176 * A "foreign" is an extern that references C (or other non-rust ABI) code.
177 * There is no metadata to scan for extern references so in these cases either
178 * a header-digester like bindgen, or manual function prototypes, have to
179 * serve as declarators. So these are usually given explicitly as prototype
180 * declarations, in rust code, with ABI attributes on them noting which ABI to
181 * link via.
182 *
183 * An "upcall" is a foreign call generated by the compiler (not corresponding
184 * to any user-written call in the code) into the runtime library, to perform
185 * some helper task such as bringing a task to life, allocating memory, etc.
186 *
187 */
188
189 use Disr;
190
191 /// The concrete version of ty::FieldDef. The name is the field index if
192 /// the field is numeric.
193 pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
194
195 /// The concrete version of ty::VariantDef
196 pub struct VariantInfo<'tcx> {
197     pub discr: Disr,
198     pub fields: Vec<Field<'tcx>>
199 }
200
201 impl<'a, 'tcx> VariantInfo<'tcx> {
202     pub fn from_ty(tcx: TyCtxt<'a, 'tcx, 'tcx>,
203                    ty: Ty<'tcx>,
204                    opt_def: Option<Def>)
205                    -> Self
206     {
207         match ty.sty {
208             ty::TyStruct(adt, substs) | ty::TyEnum(adt, substs) => {
209                 let variant = match opt_def {
210                     None => adt.struct_variant(),
211                     Some(def) => adt.variant_of_def(def)
212                 };
213
214                 VariantInfo {
215                     discr: Disr::from(variant.disr_val),
216                     fields: variant.fields.iter().map(|f| {
217                         Field(f.name, monomorphize::field_ty(tcx, substs, f))
218                     }).collect()
219                 }
220             }
221
222             ty::TyTuple(ref v) => {
223                 VariantInfo {
224                     discr: Disr(0),
225                     fields: v.iter().enumerate().map(|(i, &t)| {
226                         Field(token::intern(&i.to_string()), t)
227                     }).collect()
228                 }
229             }
230
231             _ => {
232                 bug!("cannot get field types from the type {:?}", ty);
233             }
234         }
235     }
236 }
237
238 pub struct BuilderRef_res {
239     pub b: BuilderRef,
240 }
241
242 impl Drop for BuilderRef_res {
243     fn drop(&mut self) {
244         unsafe {
245             llvm::LLVMDisposeBuilder(self.b);
246         }
247     }
248 }
249
250 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
251     BuilderRef_res {
252         b: b
253     }
254 }
255
256 pub fn validate_substs(substs: &Substs) {
257     assert!(!substs.needs_infer());
258 }
259
260 // Function context.  Every LLVM function we create will have one of
261 // these.
262 pub struct FunctionContext<'a, 'tcx: 'a> {
263     // The MIR for this function. At present, this is optional because
264     // we only have MIR available for things that are local to the
265     // crate.
266     pub mir: Option<CachedMir<'a, 'tcx>>,
267
268     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
269     // address of the first instruction in the sequence of
270     // instructions for this function that will go in the .text
271     // section of the executable we're generating.
272     pub llfn: ValueRef,
273
274     // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv
275     pub param_env: ty::ParameterEnvironment<'tcx>,
276
277     // A pointer to where to store the return value. If the return type is
278     // immediate, this points to an alloca in the function. Otherwise, it's a
279     // pointer to the hidden first parameter of the function. After function
280     // construction, this should always be Some.
281     pub llretslotptr: Cell<Option<ValueRef>>,
282
283     // These pub elements: "hoisted basic blocks" containing
284     // administrative activities that have to happen in only one place in
285     // the function, due to LLVM's quirks.
286     // A marker for the place where we want to insert the function's static
287     // allocas, so that LLVM will coalesce them into a single alloca call.
288     pub alloca_insert_pt: Cell<Option<ValueRef>>,
289
290     // When working with landingpad-based exceptions this value is alloca'd and
291     // later loaded when using the resume instruction. This ends up being
292     // critical to chaining landing pads and resuing already-translated
293     // cleanups.
294     //
295     // Note that for cleanuppad-based exceptions this is not used.
296     pub landingpad_alloca: Cell<Option<ValueRef>>,
297
298     // Describes the return/argument LLVM types and their ABI handling.
299     pub fn_ty: FnType,
300
301     // If this function is being monomorphized, this contains the type
302     // substitutions used.
303     pub param_substs: &'tcx Substs<'tcx>,
304
305     // The source span and nesting context where this function comes from, for
306     // error reporting and symbol generation.
307     pub span: Option<Span>,
308
309     // The arena that blocks are allocated from.
310     pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
311
312     // The arena that landing pads are allocated from.
313     pub lpad_arena: TypedArena<LandingPad>,
314
315     // This function's enclosing crate context.
316     pub ccx: &'a CrateContext<'a, 'tcx>,
317
318     // Used and maintained by the debuginfo module.
319     pub debug_context: debuginfo::FunctionDebugContext,
320
321     // Cleanup scopes.
322     pub scopes: RefCell<Vec<cleanup::CleanupScope<'tcx>>>,
323 }
324
325 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
326     pub fn mir(&self) -> CachedMir<'a, 'tcx> {
327         self.mir.clone().expect("fcx.mir was empty")
328     }
329
330     pub fn cleanup(&self) {
331         unsafe {
332             llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
333                                                      .get()
334                                                      .unwrap());
335         }
336     }
337
338     pub fn new_block(&'a self,
339                      name: &str)
340                      -> Block<'a, 'tcx> {
341         unsafe {
342             let name = CString::new(name).unwrap();
343             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
344                                                            self.llfn,
345                                                            name.as_ptr());
346             BlockS::new(llbb, self)
347         }
348     }
349
350     pub fn monomorphize<T>(&self, value: &T) -> T
351         where T: TransNormalize<'tcx>
352     {
353         monomorphize::apply_param_substs(self.ccx.shared(),
354                                          self.param_substs,
355                                          value)
356     }
357
358     /// This is the same as `common::type_needs_drop`, except that it
359     /// may use or update caches within this `FunctionContext`.
360     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
361         self.ccx.tcx().type_needs_drop_given_env(ty, &self.param_env)
362     }
363
364     pub fn eh_personality(&self) -> ValueRef {
365         // The exception handling personality function.
366         //
367         // If our compilation unit has the `eh_personality` lang item somewhere
368         // within it, then we just need to translate that. Otherwise, we're
369         // building an rlib which will depend on some upstream implementation of
370         // this function, so we just codegen a generic reference to it. We don't
371         // specify any of the types for the function, we just make it a symbol
372         // that LLVM can later use.
373         //
374         // Note that MSVC is a little special here in that we don't use the
375         // `eh_personality` lang item at all. Currently LLVM has support for
376         // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
377         // *name of the personality function* to decide what kind of unwind side
378         // tables/landing pads to emit. It looks like Dwarf is used by default,
379         // injecting a dependency on the `_Unwind_Resume` symbol for resuming
380         // an "exception", but for MSVC we want to force SEH. This means that we
381         // can't actually have the personality function be our standard
382         // `rust_eh_personality` function, but rather we wired it up to the
383         // CRT's custom personality function, which forces LLVM to consider
384         // landing pads as "landing pads for SEH".
385         let ccx = self.ccx;
386         let tcx = ccx.tcx();
387         match tcx.lang_items.eh_personality() {
388             Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => {
389                 Callee::def(ccx, def_id, Substs::empty(tcx)).reify(ccx)
390             }
391             _ => {
392                 if let Some(llpersonality) = ccx.eh_personality().get() {
393                     return llpersonality
394                 }
395                 let name = if base::wants_msvc_seh(ccx.sess()) {
396                     "__CxxFrameHandler3"
397                 } else {
398                     "rust_eh_personality"
399                 };
400                 let fty = Type::variadic_func(&[], &Type::i32(ccx));
401                 let f = declare::declare_cfn(ccx, name, fty);
402                 ccx.eh_personality().set(Some(f));
403                 f
404             }
405         }
406     }
407
408     // Returns a ValueRef of the "eh_unwind_resume" lang item if one is defined,
409     // otherwise declares it as an external function.
410     pub fn eh_unwind_resume(&self) -> Callee<'tcx> {
411         use attributes;
412         let ccx = self.ccx;
413         let tcx = ccx.tcx();
414         assert!(ccx.sess().target.target.options.custom_unwind_resume);
415         if let Some(def_id) = tcx.lang_items.eh_unwind_resume() {
416             return Callee::def(ccx, def_id, Substs::empty(tcx));
417         }
418
419         let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
420             unsafety: hir::Unsafety::Unsafe,
421             abi: Abi::C,
422             sig: ty::Binder(ty::FnSig {
423                 inputs: vec![tcx.mk_mut_ptr(tcx.types.u8)],
424                 output: tcx.types.never,
425                 variadic: false
426             }),
427         }));
428
429         let unwresume = ccx.eh_unwind_resume();
430         if let Some(llfn) = unwresume.get() {
431             return Callee::ptr(llfn, ty);
432         }
433         let llfn = declare::declare_fn(ccx, "rust_eh_unwind_resume", ty);
434         attributes::unwind(llfn, true);
435         unwresume.set(Some(llfn));
436         Callee::ptr(llfn, ty)
437     }
438 }
439
440 // Basic block context.  We create a block context for each basic block
441 // (single-entry, single-exit sequence of instructions) we generate from Rust
442 // code.  Each basic block we generate is attached to a function, typically
443 // with many basic blocks per function.  All the basic blocks attached to a
444 // function are organized as a directed graph.
445 pub struct BlockS<'blk, 'tcx: 'blk> {
446     // The BasicBlockRef returned from a call to
447     // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
448     // block to the function pointed to by llfn.  We insert
449     // instructions into that block by way of this block context.
450     // The block pointing to this one in the function's digraph.
451     pub llbb: BasicBlockRef,
452     pub terminated: Cell<bool>,
453     pub unreachable: Cell<bool>,
454
455     // If this block part of a landing pad, then this is `Some` indicating what
456     // kind of landing pad its in, otherwise this is none.
457     pub lpad: Cell<Option<&'blk LandingPad>>,
458
459     // The function context for the function to which this block is
460     // attached.
461     pub fcx: &'blk FunctionContext<'blk, 'tcx>,
462 }
463
464 pub type Block<'blk, 'tcx> = &'blk BlockS<'blk, 'tcx>;
465
466 impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
467     pub fn new(llbb: BasicBlockRef,
468                fcx: &'blk FunctionContext<'blk, 'tcx>)
469                -> Block<'blk, 'tcx> {
470         fcx.block_arena.alloc(BlockS {
471             llbb: llbb,
472             terminated: Cell::new(false),
473             unreachable: Cell::new(false),
474             lpad: Cell::new(None),
475             fcx: fcx
476         })
477     }
478
479     pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
480         self.fcx.ccx
481     }
482     pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
483         self.fcx
484     }
485     pub fn tcx(&self) -> TyCtxt<'blk, 'tcx, 'tcx> {
486         self.fcx.ccx.tcx()
487     }
488     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
489
490     pub fn lpad(&self) -> Option<&'blk LandingPad> {
491         self.lpad.get()
492     }
493
494     pub fn set_lpad_ref(&self, lpad: Option<&'blk LandingPad>) {
495         // FIXME: use an IVar?
496         self.lpad.set(lpad);
497     }
498
499     pub fn set_lpad(&self, lpad: Option<LandingPad>) {
500         self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
501     }
502
503     pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
504         self.fcx.mir()
505     }
506
507     pub fn name(&self, name: ast::Name) -> String {
508         name.to_string()
509     }
510
511     pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
512         self.tcx().map.node_to_string(id).to_string()
513     }
514
515     pub fn to_str(&self) -> String {
516         format!("[block {:p}]", self)
517     }
518
519     pub fn monomorphize<T>(&self, value: &T) -> T
520         where T: TransNormalize<'tcx>
521     {
522         monomorphize::apply_param_substs(self.fcx.ccx.shared(),
523                                          self.fcx.param_substs,
524                                          value)
525     }
526
527     pub fn build(&'blk self) -> BlockAndBuilder<'blk, 'tcx> {
528         BlockAndBuilder::new(self, OwnedBuilder::new_with_ccx(self.ccx()))
529     }
530 }
531
532 pub struct OwnedBuilder<'blk, 'tcx: 'blk> {
533     builder: Builder<'blk, 'tcx>
534 }
535
536 impl<'blk, 'tcx> OwnedBuilder<'blk, 'tcx> {
537     pub fn new_with_ccx(ccx: &'blk CrateContext<'blk, 'tcx>) -> Self {
538         // Create a fresh builder from the crate context.
539         let llbuilder = unsafe {
540             llvm::LLVMCreateBuilderInContext(ccx.llcx())
541         };
542         OwnedBuilder {
543             builder: Builder {
544                 llbuilder: llbuilder,
545                 ccx: ccx,
546             }
547         }
548     }
549 }
550
551 impl<'blk, 'tcx> Drop for OwnedBuilder<'blk, 'tcx> {
552     fn drop(&mut self) {
553         unsafe {
554             llvm::LLVMDisposeBuilder(self.builder.llbuilder);
555         }
556     }
557 }
558
559 pub struct BlockAndBuilder<'blk, 'tcx: 'blk> {
560     bcx: Block<'blk, 'tcx>,
561     owned_builder: OwnedBuilder<'blk, 'tcx>,
562 }
563
564 impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
565     pub fn new(bcx: Block<'blk, 'tcx>, owned_builder: OwnedBuilder<'blk, 'tcx>) -> Self {
566         // Set the builder's position to this block's end.
567         owned_builder.builder.position_at_end(bcx.llbb);
568         BlockAndBuilder {
569             bcx: bcx,
570             owned_builder: owned_builder,
571         }
572     }
573
574     pub fn with_block<F, R>(&self, f: F) -> R
575         where F: FnOnce(Block<'blk, 'tcx>) -> R
576     {
577         let result = f(self.bcx);
578         self.position_at_end(self.bcx.llbb);
579         result
580     }
581
582     pub fn map_block<F>(self, f: F) -> Self
583         where F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>
584     {
585         let BlockAndBuilder { bcx, owned_builder } = self;
586         let bcx = f(bcx);
587         BlockAndBuilder::new(bcx, owned_builder)
588     }
589
590     pub fn at_start<F, R>(&self, f: F) -> R
591         where F: FnOnce(&BlockAndBuilder<'blk, 'tcx>) -> R
592     {
593         self.position_at_start(self.bcx.llbb);
594         let r = f(self);
595         self.position_at_end(self.bcx.llbb);
596         r
597     }
598
599     // Methods delegated to bcx
600
601     pub fn is_unreachable(&self) -> bool {
602         self.bcx.unreachable.get()
603     }
604
605     pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
606         self.bcx.ccx()
607     }
608     pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
609         self.bcx.fcx()
610     }
611     pub fn tcx(&self) -> TyCtxt<'blk, 'tcx, 'tcx> {
612         self.bcx.tcx()
613     }
614     pub fn sess(&self) -> &'blk Session {
615         self.bcx.sess()
616     }
617
618     pub fn llbb(&self) -> BasicBlockRef {
619         self.bcx.llbb
620     }
621
622     pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
623         self.bcx.mir()
624     }
625
626     pub fn monomorphize<T>(&self, value: &T) -> T
627         where T: TransNormalize<'tcx>
628     {
629         self.bcx.monomorphize(value)
630     }
631
632     pub fn set_lpad(&self, lpad: Option<LandingPad>) {
633         self.bcx.set_lpad(lpad)
634     }
635
636     pub fn set_lpad_ref(&self, lpad: Option<&'blk LandingPad>) {
637         // FIXME: use an IVar?
638         self.bcx.set_lpad_ref(lpad);
639     }
640
641     pub fn lpad(&self) -> Option<&'blk LandingPad> {
642         self.bcx.lpad()
643     }
644 }
645
646 impl<'blk, 'tcx> Deref for BlockAndBuilder<'blk, 'tcx> {
647     type Target = Builder<'blk, 'tcx>;
648     fn deref(&self) -> &Self::Target {
649         &self.owned_builder.builder
650     }
651 }
652
653 /// A structure representing an active landing pad for the duration of a basic
654 /// block.
655 ///
656 /// Each `Block` may contain an instance of this, indicating whether the block
657 /// is part of a landing pad or not. This is used to make decision about whether
658 /// to emit `invoke` instructions (e.g. in a landing pad we don't continue to
659 /// use `invoke`) and also about various function call metadata.
660 ///
661 /// For GNU exceptions (`landingpad` + `resume` instructions) this structure is
662 /// just a bunch of `None` instances (not too interesting), but for MSVC
663 /// exceptions (`cleanuppad` + `cleanupret` instructions) this contains data.
664 /// When inside of a landing pad, each function call in LLVM IR needs to be
665 /// annotated with which landing pad it's a part of. This is accomplished via
666 /// the `OperandBundleDef` value created for MSVC landing pads.
667 pub struct LandingPad {
668     cleanuppad: Option<ValueRef>,
669     operand: Option<OperandBundleDef>,
670 }
671
672 impl LandingPad {
673     pub fn gnu() -> LandingPad {
674         LandingPad { cleanuppad: None, operand: None }
675     }
676
677     pub fn msvc(cleanuppad: ValueRef) -> LandingPad {
678         LandingPad {
679             cleanuppad: Some(cleanuppad),
680             operand: Some(OperandBundleDef::new("funclet", &[cleanuppad])),
681         }
682     }
683
684     pub fn bundle(&self) -> Option<&OperandBundleDef> {
685         self.operand.as_ref()
686     }
687
688     pub fn cleanuppad(&self) -> Option<ValueRef> {
689         self.cleanuppad
690     }
691 }
692
693 impl Clone for LandingPad {
694     fn clone(&self) -> LandingPad {
695         LandingPad {
696             cleanuppad: self.cleanuppad,
697             operand: self.cleanuppad.map(|p| {
698                 OperandBundleDef::new("funclet", &[p])
699             }),
700         }
701     }
702 }
703
704 pub struct Result<'blk, 'tcx: 'blk> {
705     pub bcx: Block<'blk, 'tcx>,
706     pub val: ValueRef
707 }
708
709 impl<'b, 'tcx> Result<'b, 'tcx> {
710     pub fn new(bcx: Block<'b, 'tcx>, val: ValueRef) -> Result<'b, 'tcx> {
711         Result {
712             bcx: bcx,
713             val: val,
714         }
715     }
716 }
717
718 pub fn val_ty(v: ValueRef) -> Type {
719     unsafe {
720         Type::from_ref(llvm::LLVMTypeOf(v))
721     }
722 }
723
724 // LLVM constant constructors.
725 pub fn C_null(t: Type) -> ValueRef {
726     unsafe {
727         llvm::LLVMConstNull(t.to_ref())
728     }
729 }
730
731 pub fn C_undef(t: Type) -> ValueRef {
732     unsafe {
733         llvm::LLVMGetUndef(t.to_ref())
734     }
735 }
736
737 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
738     unsafe {
739         llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
740     }
741 }
742
743 pub fn C_floating_f64(f: f64, t: Type) -> ValueRef {
744     unsafe {
745         llvm::LLVMConstReal(t.to_ref(), f)
746     }
747 }
748
749 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
750     C_struct(ccx, &[], false)
751 }
752
753 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
754     C_integral(Type::i1(ccx), val as u64, false)
755 }
756
757 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
758     C_integral(Type::i32(ccx), i as u64, true)
759 }
760
761 pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef {
762     C_integral(Type::i32(ccx), i as u64, false)
763 }
764
765 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
766     C_integral(Type::i64(ccx), i, false)
767 }
768
769 pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
770     let v = i.as_u64();
771
772     let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type());
773
774     if bit_size < 64 {
775         // make sure it doesn't overflow
776         assert!(v < (1<<bit_size));
777     }
778
779     C_integral(ccx.int_type(), v, false)
780 }
781
782 pub trait AsI64 { fn as_i64(self) -> i64; }
783 pub trait AsU64 { fn as_u64(self) -> u64; }
784
785 // FIXME: remove the intptr conversions, because they
786 // are host-architecture-dependent
787 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
788 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
789 impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }}
790
791 impl AsU64 for u64  { fn as_u64(self) -> u64 { self as u64 }}
792 impl AsU64 for u32  { fn as_u64(self) -> u64 { self as u64 }}
793 impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }}
794
795 pub fn C_u8(ccx: &CrateContext, i: u8) -> ValueRef {
796     C_integral(Type::i8(ccx), i as u64, false)
797 }
798
799
800 // This is a 'c-like' raw string, which differs from
801 // our boxed-and-length-annotated strings.
802 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
803     unsafe {
804         if let Some(&llval) = cx.const_cstr_cache().borrow().get(&s) {
805             return llval;
806         }
807
808         let sc = llvm::LLVMConstStringInContext(cx.llcx(),
809                                                 s.as_ptr() as *const c_char,
810                                                 s.len() as c_uint,
811                                                 !null_terminated as Bool);
812
813         let gsym = token::gensym("str");
814         let sym = format!("str{}", gsym.0);
815         let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
816             bug!("symbol `{}` is already defined", sym);
817         });
818         llvm::LLVMSetInitializer(g, sc);
819         llvm::LLVMSetGlobalConstant(g, True);
820         llvm::LLVMSetLinkage(g, llvm::InternalLinkage);
821
822         cx.const_cstr_cache().borrow_mut().insert(s, g);
823         g
824     }
825 }
826
827 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
828 // you will be kicked off fast isel. See issue #4352 for an example of this.
829 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
830     let len = s.len();
831     let cs = consts::ptrcast(C_cstr(cx, s, false), Type::i8p(cx));
832     C_named_struct(cx.tn().find_type("str_slice").unwrap(), &[cs, C_uint(cx, len)])
833 }
834
835 pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
836     C_struct_in_context(cx.llcx(), elts, packed)
837 }
838
839 pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef {
840     unsafe {
841         llvm::LLVMConstStructInContext(llcx,
842                                        elts.as_ptr(), elts.len() as c_uint,
843                                        packed as Bool)
844     }
845 }
846
847 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
848     unsafe {
849         llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
850     }
851 }
852
853 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
854     unsafe {
855         return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
856     }
857 }
858
859 pub fn C_vector(elts: &[ValueRef]) -> ValueRef {
860     unsafe {
861         return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint);
862     }
863 }
864
865 pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef {
866     C_bytes_in_context(cx.llcx(), bytes)
867 }
868
869 pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef {
870     unsafe {
871         let ptr = bytes.as_ptr() as *const c_char;
872         return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
873     }
874 }
875
876 pub fn const_get_elt(v: ValueRef, us: &[c_uint])
877               -> ValueRef {
878     unsafe {
879         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
880
881         debug!("const_get_elt(v={:?}, us={:?}, r={:?})",
882                Value(v), us, Value(r));
883
884         r
885     }
886 }
887
888 pub fn const_to_int(v: ValueRef) -> i64 {
889     unsafe {
890         llvm::LLVMConstIntGetSExtValue(v)
891     }
892 }
893
894 pub fn const_to_uint(v: ValueRef) -> u64 {
895     unsafe {
896         llvm::LLVMConstIntGetZExtValue(v)
897     }
898 }
899
900 fn is_const_integral(v: ValueRef) -> bool {
901     unsafe {
902         !llvm::LLVMIsAConstantInt(v).is_null()
903     }
904 }
905
906 pub fn const_to_opt_int(v: ValueRef) -> Option<i64> {
907     unsafe {
908         if is_const_integral(v) {
909             Some(llvm::LLVMConstIntGetSExtValue(v))
910         } else {
911             None
912         }
913     }
914 }
915
916 pub fn const_to_opt_uint(v: ValueRef) -> Option<u64> {
917     unsafe {
918         if is_const_integral(v) {
919             Some(llvm::LLVMConstIntGetZExtValue(v))
920         } else {
921             None
922         }
923     }
924 }
925
926 pub fn is_undef(val: ValueRef) -> bool {
927     unsafe {
928         llvm::LLVMIsUndef(val) != False
929     }
930 }
931
932 #[allow(dead_code)] // potentially useful
933 pub fn is_null(val: ValueRef) -> bool {
934     unsafe {
935         llvm::LLVMIsNull(val) != False
936     }
937 }
938
939 /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
940 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
941 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
942 pub fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
943                                     span: Span,
944                                     trait_ref: ty::PolyTraitRef<'tcx>)
945                                     -> traits::Vtable<'tcx, ()>
946 {
947     let tcx = scx.tcx();
948
949     // Remove any references to regions; this helps improve caching.
950     let trait_ref = tcx.erase_regions(&trait_ref);
951
952     scx.trait_cache().memoize(trait_ref, || {
953         debug!("trans::fulfill_obligation(trait_ref={:?}, def_id={:?})",
954                trait_ref, trait_ref.def_id());
955
956         // Do the initial selection for the obligation. This yields the
957         // shallow result we are looking for -- that is, what specific impl.
958         tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
959             let mut selcx = SelectionContext::new(&infcx);
960
961             let obligation_cause = traits::ObligationCause::misc(span,
962                                                              ast::DUMMY_NODE_ID);
963             let obligation = traits::Obligation::new(obligation_cause,
964                                                      trait_ref.to_poly_trait_predicate());
965
966             let selection = match selcx.select(&obligation) {
967                 Ok(Some(selection)) => selection,
968                 Ok(None) => {
969                     // Ambiguity can happen when monomorphizing during trans
970                     // expands to some humongo type that never occurred
971                     // statically -- this humongo type can then overflow,
972                     // leading to an ambiguous result. So report this as an
973                     // overflow bug, since I believe this is the only case
974                     // where ambiguity can result.
975                     debug!("Encountered ambiguity selecting `{:?}` during trans, \
976                             presuming due to overflow",
977                            trait_ref);
978                     tcx.sess.span_fatal(span,
979                         "reached the recursion limit during monomorphization \
980                          (selection ambiguity)");
981                 }
982                 Err(e) => {
983                     span_bug!(span, "Encountered error `{:?}` selecting `{:?}` during trans",
984                               e, trait_ref)
985                 }
986             };
987
988             debug!("fulfill_obligation: selection={:?}", selection);
989
990             // Currently, we use a fulfillment context to completely resolve
991             // all nested obligations. This is because they can inform the
992             // inference of the impl's type parameters.
993             let mut fulfill_cx = traits::FulfillmentContext::new();
994             let vtable = selection.map(|predicate| {
995                 debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate);
996                 fulfill_cx.register_predicate_obligation(&infcx, predicate);
997             });
998             let vtable = infcx.drain_fulfillment_cx_or_panic(span, &mut fulfill_cx, &vtable);
999
1000             info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
1001             vtable
1002         })
1003     })
1004 }
1005
1006 /// Normalizes the predicates and checks whether they hold.  If this
1007 /// returns false, then either normalize encountered an error or one
1008 /// of the predicates did not hold. Used when creating vtables to
1009 /// check for unsatisfiable methods.
1010 pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1011                                                predicates: Vec<ty::Predicate<'tcx>>)
1012                                                -> bool
1013 {
1014     debug!("normalize_and_test_predicates(predicates={:?})",
1015            predicates);
1016
1017     tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
1018         let mut selcx = SelectionContext::new(&infcx);
1019         let mut fulfill_cx = traits::FulfillmentContext::new();
1020         let cause = traits::ObligationCause::dummy();
1021         let traits::Normalized { value: predicates, obligations } =
1022             traits::normalize(&mut selcx, cause.clone(), &predicates);
1023         for obligation in obligations {
1024             fulfill_cx.register_predicate_obligation(&infcx, obligation);
1025         }
1026         for predicate in predicates {
1027             let obligation = traits::Obligation::new(cause.clone(), predicate);
1028             fulfill_cx.register_predicate_obligation(&infcx, obligation);
1029         }
1030
1031         fulfill_cx.select_all_or_error(&infcx).is_ok()
1032     })
1033 }
1034
1035 pub fn langcall(tcx: TyCtxt,
1036                 span: Option<Span>,
1037                 msg: &str,
1038                 li: LangItem)
1039                 -> DefId {
1040     match tcx.lang_items.require(li) {
1041         Ok(id) => id,
1042         Err(s) => {
1043             let msg = format!("{} {}", msg, s);
1044             match span {
1045                 Some(span) => tcx.sess.span_fatal(span, &msg[..]),
1046                 None => tcx.sess.fatal(&msg[..]),
1047             }
1048         }
1049     }
1050 }
1051
1052 // To avoid UB from LLVM, these two functions mask RHS with an
1053 // appropriate mask unconditionally (i.e. the fallback behavior for
1054 // all shifts). For 32- and 64-bit types, this matches the semantics
1055 // of Java. (See related discussion on #1877 and #10183.)
1056
1057 pub fn build_unchecked_lshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1058                                           lhs: ValueRef,
1059                                           rhs: ValueRef,
1060                                           binop_debug_loc: DebugLoc) -> ValueRef {
1061     let rhs = base::cast_shift_expr_rhs(bcx, hir::BinOp_::BiShl, lhs, rhs);
1062     // #1877, #10183: Ensure that input is always valid
1063     let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc);
1064     build::Shl(bcx, lhs, rhs, binop_debug_loc)
1065 }
1066
1067 pub fn build_unchecked_rshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1068                                           lhs_t: Ty<'tcx>,
1069                                           lhs: ValueRef,
1070                                           rhs: ValueRef,
1071                                           binop_debug_loc: DebugLoc) -> ValueRef {
1072     let rhs = base::cast_shift_expr_rhs(bcx, hir::BinOp_::BiShr, lhs, rhs);
1073     // #1877, #10183: Ensure that input is always valid
1074     let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc);
1075     let is_signed = lhs_t.is_signed();
1076     if is_signed {
1077         build::AShr(bcx, lhs, rhs, binop_debug_loc)
1078     } else {
1079         build::LShr(bcx, lhs, rhs, binop_debug_loc)
1080     }
1081 }
1082
1083 fn shift_mask_rhs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1084                               rhs: ValueRef,
1085                               debug_loc: DebugLoc) -> ValueRef {
1086     let rhs_llty = val_ty(rhs);
1087     build::And(bcx, rhs, shift_mask_val(bcx, rhs_llty, rhs_llty, false), debug_loc)
1088 }
1089
1090 pub fn shift_mask_val<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1091                               llty: Type,
1092                               mask_llty: Type,
1093                               invert: bool) -> ValueRef {
1094     let kind = llty.kind();
1095     match kind {
1096         TypeKind::Integer => {
1097             // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
1098             let val = llty.int_width() - 1;
1099             if invert {
1100                 C_integral(mask_llty, !val, true)
1101             } else {
1102                 C_integral(mask_llty, val, false)
1103             }
1104         },
1105         TypeKind::Vector => {
1106             let mask = shift_mask_val(bcx, llty.element_type(), mask_llty.element_type(), invert);
1107             build::VectorSplat(bcx, mask_llty.vector_length(), mask)
1108         },
1109         _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
1110     }
1111 }