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.
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.
11 #![allow(non_camel_case_types, non_snake_case)]
13 //! Code that is useful in various trans modules.
15 pub use self::ExprOrMethodCall::*;
19 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
20 use llvm::{True, False, Bool};
24 use middle::lang_items::LangItem;
25 use middle::subst::{self, Substs};
32 use trans::debuginfo::{self, DebugLoc};
35 use trans::monomorphize;
36 use trans::type_::Type;
39 use middle::ty::{self, HasTypeFlags, Ty};
41 use middle::ty_fold::{TypeFolder, TypeFoldable};
42 use rustc::ast_map::{PathElem, PathName};
43 use util::nodemap::{FnvHashMap, NodeMap};
45 use arena::TypedArena;
46 use libc::{c_uint, c_char};
47 use std::ffi::CString;
48 use std::cell::{Cell, RefCell};
49 use std::result::Result as StdResult;
52 use syntax::codemap::{DUMMY_SP, Span};
53 use syntax::parse::token::InternedString;
54 use syntax::parse::token;
56 pub use trans::context::CrateContext;
58 /// Returns an equivalent value with all free regions removed (note
59 /// that late-bound regions remain, because they are important for
60 /// subtyping, but they are anonymized and normalized as well). This
61 /// is a stronger, caching version of `ty_fold::erase_regions`.
62 pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
63 where T : TypeFoldable<'tcx>
65 let value1 = value.fold_with(&mut RegionEraser(cx));
66 debug!("erase_regions({:?}) = {:?}",
70 struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>);
72 impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
73 fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 }
75 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
76 match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
81 let t_norm = ty_fold::super_fold_ty(self, ty);
82 self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm);
86 fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
87 where T : TypeFoldable<'tcx>
89 let u = self.tcx().anonymize_late_bound_regions(t);
90 ty_fold::super_fold_binder(self, &u)
93 fn fold_region(&mut self, r: ty::Region) -> ty::Region {
94 // because late-bound regions affect subtyping, we can't
95 // erase the bound/free distinction, but we can replace
96 // all free regions with 'static.
98 // Note that we *CAN* replace early-bound regions -- the
99 // type system never "sees" those, they get substituted
100 // away. In trans, they will always be erased to 'static
101 // whenever a substitution occurs.
103 ty::ReLateBound(..) => r,
108 fn fold_substs(&mut self,
109 substs: &subst::Substs<'tcx>)
110 -> subst::Substs<'tcx> {
111 subst::Substs { regions: subst::ErasedRegions,
112 types: substs.types.fold_with(self) }
117 /// Is the type's representation size known at compile time?
118 pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
119 ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP)
122 pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
124 ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
125 ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
127 !type_is_sized(cx, ty)
135 /// If `type_needs_drop` returns true, then `ty` is definitely
136 /// non-copy and *might* have a destructor attached; if it returns
137 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
139 /// (Note that this implies that if `ty` has a destructor attached,
140 /// then `type_needs_drop` will definitely return `true` for `ty`.)
141 pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
142 type_needs_drop_given_env(cx, ty, &cx.empty_parameter_environment())
145 /// Core implementation of type_needs_drop, potentially making use of
146 /// and/or updating caches held in the `param_env`.
147 fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
149 param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
150 // Issue #22536: We first query type_moves_by_default. It sees a
151 // normalized version of the type, and therefore will definitely
152 // know whether the type implements Copy (and thus needs no
153 // cleanup/drop/zeroing) ...
154 let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP);
156 if implements_copy { return false; }
158 // ... (issue #22536 continued) but as an optimization, still use
159 // prior logic of asking if the `needs_drop` bit is set; we need
160 // not zero non-Copy types if they have no destructor.
162 // FIXME(#22815): Note that calling `ty::type_contents` is a
163 // conservative heuristic; it may report that `needs_drop` is set
164 // when actual type does not actually have a destructor associated
165 // with it. But since `ty` absolutely did not have the `Copy`
166 // bound attached (see above), it is sound to treat it as having a
167 // destructor (e.g. zero its memory on move).
169 let contents = ty.type_contents(cx);
170 debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
171 contents.needs_drop(cx)
174 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
176 ty::TyStruct(def_id, substs) => {
177 let fields = ccx.tcx().lookup_struct_fields(def_id);
178 fields.len() == 1 && {
179 let ty = ccx.tcx().lookup_field_type(def_id, fields[0].id, substs);
180 let ty = monomorphize::normalize_associated_type(ccx.tcx(), &ty);
181 type_is_immediate(ccx, ty)
188 pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
189 use trans::machine::llsize_of_alloc;
190 use trans::type_of::sizing_type_of;
193 let simple = ty.is_scalar() ||
194 ty.is_unique() || ty.is_region_ptr() ||
195 type_is_newtype_immediate(ccx, ty) ||
197 if simple && !type_is_fat_ptr(tcx, ty) {
200 if !type_is_sized(tcx, ty) {
204 ty::TyStruct(..) | ty::TyEnum(..) | ty::TyTuple(..) | ty::TyArray(_, _) |
205 ty::TyClosure(..) => {
206 let llty = sizing_type_of(ccx, ty);
207 llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
209 _ => type_is_zero_size(ccx, ty)
213 /// Identify types which have size zero at runtime.
214 pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
215 use trans::machine::llsize_of_alloc;
216 use trans::type_of::sizing_type_of;
217 let llty = sizing_type_of(ccx, ty);
218 llsize_of_alloc(ccx, llty) == 0
221 /// Identifies types which we declare to be equivalent to `void` in C for the purpose of function
222 /// return types. These are `()`, bot, and uninhabited enums. Note that all such types are also
223 /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI
225 pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
226 ty.is_nil() || ty.is_empty(ccx.tcx())
229 /// Generates a unique symbol based off the name given. This is used to create
230 /// unique symbols for things like closures.
231 pub fn gensym_name(name: &str) -> PathElem {
232 let num = token::gensym(name).usize();
233 // use one colon which will get translated to a period by the mangler, and
234 // we're guaranteed that `num` is globally unique for this crate.
235 PathName(token::gensym(&format!("{}:{}", name, num)))
239 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
241 * An "extern" is an LLVM symbol we wind up emitting an undefined external
242 * reference to. This means "we don't have the thing in this compilation unit,
243 * please make sure you link it in at runtime". This could be a reference to
244 * C code found in a C library, or rust code found in a rust crate.
246 * Most "externs" are implicitly declared (automatically) as a result of a
247 * user declaring an extern _module_ dependency; this causes the rust driver
248 * to locate an extern crate, scan its compilation metadata, and emit extern
249 * declarations for any symbols used by the declaring crate.
251 * A "foreign" is an extern that references C (or other non-rust ABI) code.
252 * There is no metadata to scan for extern references so in these cases either
253 * a header-digester like bindgen, or manual function prototypes, have to
254 * serve as declarators. So these are usually given explicitly as prototype
255 * declarations, in rust code, with ABI attributes on them noting which ABI to
258 * An "upcall" is a foreign call generated by the compiler (not corresponding
259 * to any user-written call in the code) into the runtime library, to perform
260 * some helper task such as bringing a task to life, allocating memory, etc.
264 #[derive(Copy, Clone)]
265 pub struct NodeIdAndSpan {
270 pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan {
271 NodeIdAndSpan { id: expr.id, span: expr.span }
274 pub struct BuilderRef_res {
278 impl Drop for BuilderRef_res {
281 llvm::LLVMDisposeBuilder(self.b);
286 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
292 pub type ExternMap = FnvHashMap<String, ValueRef>;
294 pub fn validate_substs(substs: &Substs) {
295 assert!(!substs.types.needs_infer());
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>;
302 // Function context. Every LLVM function we create will have one of
304 pub struct FunctionContext<'a, 'tcx: 'a> {
305 // The ValueRef returned from a call to llvm::LLVMAddFunction; the
306 // address of the first instruction in the sequence of
307 // instructions for this function that will go in the .text
308 // section of the executable we're generating.
311 // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv
312 pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
314 // The environment argument in a closure.
315 pub llenv: Option<ValueRef>,
317 // A pointer to where to store the return value. If the return type is
318 // immediate, this points to an alloca in the function. Otherwise, it's a
319 // pointer to the hidden first parameter of the function. After function
320 // construction, this should always be Some.
321 pub llretslotptr: Cell<Option<ValueRef>>,
323 // These pub elements: "hoisted basic blocks" containing
324 // administrative activities that have to happen in only one place in
325 // the function, due to LLVM's quirks.
326 // A marker for the place where we want to insert the function's static
327 // allocas, so that LLVM will coalesce them into a single alloca call.
328 pub alloca_insert_pt: Cell<Option<ValueRef>>,
329 pub llreturn: Cell<Option<BasicBlockRef>>,
331 // If the function has any nested return's, including something like:
332 // fn foo() -> Option<Foo> { Some(Foo { x: return None }) }, then
333 // we use a separate alloca for each return
334 pub needs_ret_allocas: bool,
336 // The a value alloca'd for calls to upcalls.rust_personality. Used when
337 // outputting the resume instruction.
338 pub personality: Cell<Option<ValueRef>>,
340 // True if the caller expects this fn to use the out pointer to
341 // return. Either way, your code should write into the slot llretslotptr
342 // points to, but if this value is false, that slot will be a local alloca.
343 pub caller_expects_out_pointer: bool,
345 // Maps the DefId's for local variables to the allocas created for
346 // them in llallocas.
347 pub lllocals: RefCell<NodeMap<LvalueDatum<'tcx>>>,
349 // Same as above, but for closure upvars
350 pub llupvars: RefCell<NodeMap<ValueRef>>,
352 // The NodeId of the function, or -1 if it doesn't correspond to
353 // a user-defined function.
356 // If this function is being monomorphized, this contains the type
357 // substitutions used.
358 pub param_substs: &'tcx Substs<'tcx>,
360 // The source span and nesting context where this function comes from, for
361 // error reporting and symbol generation.
362 pub span: Option<Span>,
364 // The arena that blocks are allocated from.
365 pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
367 // This function's enclosing crate context.
368 pub ccx: &'a CrateContext<'a, 'tcx>,
370 // Used and maintained by the debuginfo module.
371 pub debug_context: debuginfo::FunctionDebugContext,
374 pub scopes: RefCell<Vec<cleanup::CleanupScope<'a, 'tcx>>>,
376 pub cfg: Option<cfg::CFG>,
379 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
380 pub fn arg_offset(&self) -> usize {
381 self.env_arg_pos() + if self.llenv.is_some() { 1 } else { 0 }
384 pub fn env_arg_pos(&self) -> usize {
385 if self.caller_expects_out_pointer {
392 pub fn cleanup(&self) {
394 llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
400 pub fn get_llreturn(&self) -> BasicBlockRef {
401 if self.llreturn.get().is_none() {
403 self.llreturn.set(Some(unsafe {
404 llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn,
405 "return\0".as_ptr() as *const _)
409 self.llreturn.get().unwrap()
412 pub fn get_ret_slot(&self, bcx: Block<'a, 'tcx>,
413 output: ty::FnOutput<'tcx>,
414 name: &str) -> ValueRef {
415 if self.needs_ret_allocas {
416 base::alloca_no_lifetime(bcx, match output {
417 ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
418 ty::FnDiverging => Type::void(bcx.ccx())
421 self.llretslotptr.get().unwrap()
425 pub fn new_block(&'a self,
428 opt_node_id: Option<ast::NodeId>)
431 let name = CString::new(name).unwrap();
432 let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
435 BlockS::new(llbb, is_lpad, opt_node_id, self)
439 pub fn new_id_block(&'a self,
441 node_id: ast::NodeId)
443 self.new_block(false, name, Some(node_id))
446 pub fn new_temp_block(&'a self,
449 self.new_block(false, name, None)
452 pub fn join_blocks(&'a self,
454 in_cxs: &[Block<'a, 'tcx>])
456 let out = self.new_id_block("join", id);
457 let mut reachable = false;
459 if !bcx.unreachable.get() {
460 build::Br(*bcx, out.llbb, DebugLoc::None);
465 build::Unreachable(out);
470 pub fn monomorphize<T>(&self, value: &T) -> T
471 where T : TypeFoldable<'tcx> + HasTypeFlags
473 monomorphize::apply_param_substs(self.ccx.tcx(),
478 /// This is the same as `common::type_needs_drop`, except that it
479 /// may use or update caches within this `FunctionContext`.
480 pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
481 type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
484 pub fn eh_personality(&self) -> ValueRef {
485 // The exception handling personality function.
487 // If our compilation unit has the `eh_personality` lang item somewhere
488 // within it, then we just need to translate that. Otherwise, we're
489 // building an rlib which will depend on some upstream implementation of
490 // this function, so we just codegen a generic reference to it. We don't
491 // specify any of the types for the function, we just make it a symbol
492 // that LLVM can later use.
494 // Note that MSVC is a little special here in that we don't use the
495 // `eh_personality` lang item at all. Currently LLVM has support for
496 // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
497 // *name of the personality function* to decide what kind of unwind side
498 // tables/landing pads to emit. It looks like Dwarf is used by default,
499 // injecting a dependency on the `_Unwind_Resume` symbol for resuming
500 // an "exception", but for MSVC we want to force SEH. This means that we
501 // can't actually have the personality function be our standard
502 // `rust_eh_personality` function, but rather we wired it up to the
503 // CRT's custom personality function, which forces LLVM to consider
504 // landing pads as "landing pads for SEH".
505 let target = &self.ccx.sess().target.target;
506 match self.ccx.tcx().lang_items.eh_personality() {
507 Some(def_id) if !target.options.is_like_msvc => {
508 callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
509 self.param_substs).val
512 let mut personality = self.ccx.eh_personality().borrow_mut();
514 Some(llpersonality) => llpersonality,
516 let name = if !target.options.is_like_msvc {
517 "rust_eh_personality"
518 } else if target.arch == "x86" {
521 "__C_specific_handler"
523 let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
524 let f = declare::declare_cfn(self.ccx, name, fty,
525 self.ccx.tcx().types.i32);
526 *personality = Some(f);
535 // Basic block context. We create a block context for each basic block
536 // (single-entry, single-exit sequence of instructions) we generate from Rust
537 // code. Each basic block we generate is attached to a function, typically
538 // with many basic blocks per function. All the basic blocks attached to a
539 // function are organized as a directed graph.
540 pub struct BlockS<'blk, 'tcx: 'blk> {
541 // The BasicBlockRef returned from a call to
542 // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
543 // block to the function pointed to by llfn. We insert
544 // instructions into that block by way of this block context.
545 // The block pointing to this one in the function's digraph.
546 pub llbb: BasicBlockRef,
547 pub terminated: Cell<bool>,
548 pub unreachable: Cell<bool>,
550 // Is this block part of a landing pad?
553 // AST node-id associated with this block, if any. Used for
554 // debugging purposes only.
555 pub opt_node_id: Option<ast::NodeId>,
557 // The function context for the function to which this block is
559 pub fcx: &'blk FunctionContext<'blk, 'tcx>,
562 pub type Block<'blk, 'tcx> = &'blk BlockS<'blk, 'tcx>;
564 impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
565 pub fn new(llbb: BasicBlockRef,
567 opt_node_id: Option<ast::NodeId>,
568 fcx: &'blk FunctionContext<'blk, 'tcx>)
569 -> Block<'blk, 'tcx> {
570 fcx.block_arena.alloc(BlockS {
572 terminated: Cell::new(false),
573 unreachable: Cell::new(false),
575 opt_node_id: opt_node_id,
580 pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
583 pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
586 pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
588 pub fn name(&self, name: ast::Name) -> String {
589 token::get_name(name).to_string()
592 pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
593 self.tcx().map.node_to_string(id).to_string()
596 pub fn def(&self, nid: ast::NodeId) -> def::Def {
597 match self.tcx().def_map.borrow().get(&nid) {
598 Some(v) => v.full_def(),
600 self.tcx().sess.bug(&format!(
601 "no def associated with node id {}", nid));
606 pub fn val_to_string(&self, val: ValueRef) -> String {
607 self.ccx().tn().val_to_string(val)
610 pub fn llty_str(&self, ty: Type) -> String {
611 self.ccx().tn().type_to_string(ty)
614 pub fn to_str(&self) -> String {
615 format!("[block {:p}]", self)
618 pub fn monomorphize<T>(&self, value: &T) -> T
619 where T : TypeFoldable<'tcx> + HasTypeFlags
621 monomorphize::apply_param_substs(self.tcx(),
622 self.fcx.param_substs,
627 pub struct Result<'blk, 'tcx: 'blk> {
628 pub bcx: Block<'blk, 'tcx>,
632 impl<'b, 'tcx> Result<'b, 'tcx> {
633 pub fn new(bcx: Block<'b, 'tcx>, val: ValueRef) -> Result<'b, 'tcx> {
641 pub fn val_ty(v: ValueRef) -> Type {
643 Type::from_ref(llvm::LLVMTypeOf(v))
647 // LLVM constant constructors.
648 pub fn C_null(t: Type) -> ValueRef {
650 llvm::LLVMConstNull(t.to_ref())
654 pub fn C_undef(t: Type) -> ValueRef {
656 llvm::LLVMGetUndef(t.to_ref())
660 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
662 llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
666 pub fn C_floating(s: &str, t: Type) -> ValueRef {
668 let s = CString::new(s).unwrap();
669 llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
673 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
674 C_struct(ccx, &[], false)
677 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
678 C_integral(Type::i1(ccx), val as u64, false)
681 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
682 C_integral(Type::i32(ccx), i as u64, true)
685 pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef {
686 C_integral(Type::i32(ccx), i as u64, false)
689 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
690 C_integral(Type::i64(ccx), i, false)
693 pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
696 match machine::llbitsize_of_real(ccx, ccx.int_type()) {
697 32 => assert!(v < (1<<31) && v >= -(1<<31)),
699 n => panic!("unsupported target size: {}", n)
702 C_integral(ccx.int_type(), v as u64, true)
705 pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
708 match machine::llbitsize_of_real(ccx, ccx.int_type()) {
709 32 => assert!(v < (1<<32)),
711 n => panic!("unsupported target size: {}", n)
714 C_integral(ccx.int_type(), v, false)
717 pub trait AsI64 { fn as_i64(self) -> i64; }
718 pub trait AsU64 { fn as_u64(self) -> u64; }
720 // FIXME: remove the intptr conversions, because they
721 // are host-architecture-dependent
722 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
723 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
724 impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }}
726 impl AsU64 for u64 { fn as_u64(self) -> u64 { self as u64 }}
727 impl AsU64 for u32 { fn as_u64(self) -> u64 { self as u64 }}
728 impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }}
730 pub fn C_u8(ccx: &CrateContext, i: usize) -> ValueRef {
731 C_integral(Type::i8(ccx), i as u64, false)
735 // This is a 'c-like' raw string, which differs from
736 // our boxed-and-length-annotated strings.
737 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
739 match cx.const_cstr_cache().borrow().get(&s) {
740 Some(&llval) => return llval,
744 let sc = llvm::LLVMConstStringInContext(cx.llcx(),
745 s.as_ptr() as *const c_char,
747 !null_terminated as Bool);
749 let gsym = token::gensym("str");
750 let sym = format!("str{}", gsym.usize());
751 let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
752 cx.sess().bug(&format!("symbol `{}` is already defined", sym));
754 llvm::LLVMSetInitializer(g, sc);
755 llvm::LLVMSetGlobalConstant(g, True);
756 llvm::SetLinkage(g, llvm::InternalLinkage);
758 cx.const_cstr_cache().borrow_mut().insert(s, g);
763 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
764 // you will be kicked off fast isel. See issue #4352 for an example of this.
765 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
767 let cs = consts::ptrcast(C_cstr(cx, s, false), Type::i8p(cx));
768 C_named_struct(cx.tn().find_type("str_slice").unwrap(), &[cs, C_uint(cx, len)])
771 pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
772 C_struct_in_context(cx.llcx(), elts, packed)
775 pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef {
777 llvm::LLVMConstStructInContext(llcx,
778 elts.as_ptr(), elts.len() as c_uint,
783 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
785 llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
789 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
791 return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
795 pub fn C_vector(elts: &[ValueRef]) -> ValueRef {
797 return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint);
801 pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef {
802 C_bytes_in_context(cx.llcx(), bytes)
805 pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef {
807 let ptr = bytes.as_ptr() as *const c_char;
808 return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
812 pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
815 let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
817 debug!("const_get_elt(v={}, us={:?}, r={})",
818 cx.tn().val_to_string(v), us, cx.tn().val_to_string(r));
824 pub fn const_to_int(v: ValueRef) -> i64 {
826 llvm::LLVMConstIntGetSExtValue(v)
830 pub fn const_to_uint(v: ValueRef) -> u64 {
832 llvm::LLVMConstIntGetZExtValue(v)
836 fn is_const_integral(v: ValueRef) -> bool {
838 !llvm::LLVMIsAConstantInt(v).is_null()
842 pub fn const_to_opt_int(v: ValueRef) -> Option<i64> {
844 if is_const_integral(v) {
845 Some(llvm::LLVMConstIntGetSExtValue(v))
852 pub fn const_to_opt_uint(v: ValueRef) -> Option<u64> {
854 if is_const_integral(v) {
855 Some(llvm::LLVMConstIntGetZExtValue(v))
862 pub fn is_undef(val: ValueRef) -> bool {
864 llvm::LLVMIsUndef(val) != False
868 #[allow(dead_code)] // potentially useful
869 pub fn is_null(val: ValueRef) -> bool {
871 llvm::LLVMIsNull(val) != False
875 pub fn monomorphize_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, t: Ty<'tcx>) -> Ty<'tcx> {
876 bcx.fcx.monomorphize(&t)
879 pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> {
881 let t = tcx.node_id_to_type(id);
882 monomorphize_type(bcx, t)
885 pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
886 node_id_type(bcx, ex.id)
889 pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
890 monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex))
893 /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
894 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
895 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
896 pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
898 trait_ref: ty::PolyTraitRef<'tcx>)
899 -> traits::Vtable<'tcx, ()>
903 // Remove any references to regions; this helps improve caching.
904 let trait_ref = erase_regions(tcx, &trait_ref);
906 // First check the cache.
907 match ccx.trait_cache().borrow().get(&trait_ref) {
909 info!("Cache hit: {:?}", trait_ref);
910 return (*vtable).clone();
915 debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}",
916 trait_ref, trait_ref.def_id());
919 // Do the initial selection for the obligation. This yields the
920 // shallow result we are looking for -- that is, what specific impl.
921 let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
922 let mut selcx = traits::SelectionContext::new(&infcx);
925 traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
926 trait_ref.to_poly_trait_predicate());
927 let selection = match selcx.select(&obligation) {
928 Ok(Some(selection)) => selection,
930 // Ambiguity can happen when monomorphizing during trans
931 // expands to some humongo type that never occurred
932 // statically -- this humongo type can then overflow,
933 // leading to an ambiguous result. So report this as an
934 // overflow bug, since I believe this is the only case
935 // where ambiguity can result.
936 debug!("Encountered ambiguity selecting `{:?}` during trans, \
937 presuming due to overflow",
939 ccx.sess().span_fatal(
941 "reached the recursion limit during monomorphization");
946 &format!("Encountered error `{:?}` selecting `{:?}` during trans",
952 // Currently, we use a fulfillment context to completely resolve
953 // all nested obligations. This is because they can inform the
954 // inference of the impl's type parameters.
955 let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
956 let vtable = selection.map(|predicate| {
957 fulfill_cx.register_predicate_obligation(&infcx, predicate);
959 let vtable = erase_regions(tcx,
960 &drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable)
963 info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
965 ccx.trait_cache().borrow_mut().insert(trait_ref, vtable.clone());
970 /// Normalizes the predicates and checks whether they hold. If this
971 /// returns false, then either normalize encountered an error or one
972 /// of the predicates did not hold. Used when creating vtables to
973 /// check for unsatisfiable methods.
974 pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
975 predicates: Vec<ty::Predicate<'tcx>>)
978 debug!("normalize_and_test_predicates(predicates={:?})",
982 let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
983 let mut selcx = traits::SelectionContext::new(&infcx);
984 let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
985 let cause = traits::ObligationCause::dummy();
986 let traits::Normalized { value: predicates, obligations } =
987 traits::normalize(&mut selcx, cause.clone(), &predicates);
988 for obligation in obligations {
989 fulfill_cx.register_predicate_obligation(&infcx, obligation);
991 for predicate in predicates {
992 let obligation = traits::Obligation::new(cause.clone(), predicate);
993 fulfill_cx.register_predicate_obligation(&infcx, obligation);
995 drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
998 pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
999 infcx: &infer::InferCtxt<'a,'tcx>,
1000 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
1003 where T : TypeFoldable<'tcx>
1005 match drain_fulfillment_cx(infcx, fulfill_cx, result) {
1008 infcx.tcx.sess.span_bug(
1010 &format!("Encountered errors `{:?}` fulfilling during trans",
1016 /// Finishes processes any obligations that remain in the fulfillment
1017 /// context, and then "freshens" and returns `result`. This is
1018 /// primarily used during normalization and other cases where
1019 /// processing the obligations in `fulfill_cx` may cause type
1020 /// inference variables that appear in `result` to be unified, and
1021 /// hence we need to process those obligations to get the complete
1022 /// picture of the type.
1023 pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>,
1024 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
1026 -> StdResult<T,Vec<traits::FulfillmentError<'tcx>>>
1027 where T : TypeFoldable<'tcx>
1029 debug!("drain_fulfillment_cx(result={:?})",
1032 // In principle, we only need to do this so long as `result`
1033 // contains unbound type parameters. It could be a slight
1034 // optimization to stop iterating early.
1035 match fulfill_cx.select_all_or_error(infcx) {
1042 // Use freshen to simultaneously replace all type variables with
1043 // their bindings and replace all regions with 'static. This is
1044 // sort of overkill because we do not expect there to be any
1045 // unbound type variables, hence no `TyFresh` types should ever be
1047 Ok(result.fold_with(&mut infcx.freshener()))
1050 // Key used to lookup values supplied for type parameters in an expr.
1051 #[derive(Copy, Clone, PartialEq, Debug)]
1052 pub enum ExprOrMethodCall {
1053 // Type parameters for a path like `None::<int>`
1054 ExprId(ast::NodeId),
1056 // Type parameters for a method call like `a.foo::<int>()`
1057 MethodCallKey(ty::MethodCall)
1060 pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1061 node: ExprOrMethodCall,
1062 param_substs: &subst::Substs<'tcx>)
1063 -> subst::Substs<'tcx> {
1064 let tcx = ccx.tcx();
1066 let substs = match node {
1068 tcx.node_id_item_substs(id).substs
1070 MethodCallKey(method_call) => {
1071 tcx.tables.borrow().method_map[&method_call].substs.clone()
1075 if substs.types.needs_infer() {
1076 tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}",
1080 monomorphize::apply_param_substs(tcx,
1082 &substs.erase_regions())
1085 pub fn langcall(bcx: Block,
1090 match bcx.tcx().lang_items.require(li) {
1093 let msg = format!("{} {}", msg, s);
1095 Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]),
1096 None => bcx.tcx().sess.fatal(&msg[..]),