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)]
12
13 //! Code that is useful in various trans modules.
14
15 use driver::session::Session;
16 use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef};
17 use lib::llvm::{True, False, Bool};
18 use lib::llvm::llvm;
19 use lib;
20 use middle::lang_items::LangItem;
21 use middle::trans::build;
22 use middle::trans::cleanup;
23 use middle::trans::datum;
24 use middle::trans::datum::{Datum, Lvalue};
25 use middle::trans::debuginfo;
26 use middle::trans::type_::Type;
27 use middle::ty;
28 use middle::typeck;
29 use util::ppaux::Repr;
30 use util::nodemap::NodeMap;
31
32 use arena::TypedArena;
33 use collections::HashMap;
34 use libc::{c_uint, c_longlong, c_ulonglong, c_char};
35 use std::c_str::ToCStr;
36 use std::cell::{Cell, RefCell};
37 use std::vec::Vec;
38 use syntax::ast::Ident;
39 use syntax::ast;
40 use syntax::ast_map::{PathElem, PathName};
41 use syntax::codemap::Span;
42 use syntax::parse::token::InternedString;
43 use syntax::parse::token;
44
45 pub use middle::trans::context::CrateContext;
46
47 fn type_is_newtype_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
48 match ty::get(ty).sty {
49 ty::ty_struct(def_id, ref substs) => {
50 let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
51 fields.len() == 1 &&
52 fields.get(0).ident.name ==
53 token::special_idents::unnamed_field.name &&
54 type_is_immediate(ccx, fields.get(0).mt.ty)
55 }
56 _ => false
57 }
58 }
59
60 pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
61 use middle::trans::machine::llsize_of_alloc;
62 use middle::trans::type_of::sizing_type_of;
63 let tcx = ccx.tcx();
64 let simple = ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
65 ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
66 type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
67 ty::type_is_simd(tcx, ty);
68 if simple {
69 return true;
70 }
71 match ty::get(ty).sty {
72 ty::ty_bot => true,
73 ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) => {
74 let llty = sizing_type_of(ccx, ty);
75 llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
76 }
77 _ => type_is_zero_size(ccx, ty)
78 }
79 }
80
81 pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
82 /*!
83 * Identify types which have size zero at runtime.
84 */
85
86 use middle::trans::machine::llsize_of_alloc;
87 use middle::trans::type_of::sizing_type_of;
88 let llty = sizing_type_of(ccx, ty);
89 llsize_of_alloc(ccx, llty) == 0
90 }
91
92 pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
93 /*!
94 * Identifies types which we declare to be equivalent to `void`
95 * in C for the purpose of function return types. These are
96 * `()`, bot, and uninhabited enums. Note that all such types
97 * are also zero-size, but not all zero-size types use a `void`
98 * return type (in order to aid with C ABI compatibility).
99 */
100
101 ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx(), ty)
102 }
103
104 /// Generates a unique symbol based off the name given. This is used to create
105 /// unique symbols for things like closures.
106 pub fn gensym_name(name: &str) -> PathElem {
107 let num = token::gensym(name);
108 // use one colon which will get translated to a period by the mangler, and
109 // we're guaranteed that `num` is globally unique for this crate.
110 PathName(token::gensym(format!("{}:{}", name, num)))
111 }
112
113 pub struct tydesc_info {
114 pub ty: ty::t,
115 pub tydesc: ValueRef,
116 pub size: ValueRef,
117 pub align: ValueRef,
118 pub name: ValueRef,
119 pub visit_glue: Cell<Option<ValueRef>>,
120 }
121
122 /*
123 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
124 *
125 * An "extern" is an LLVM symbol we wind up emitting an undefined external
126 * reference to. This means "we don't have the thing in this compilation unit,
127 * please make sure you link it in at runtime". This could be a reference to
128 * C code found in a C library, or rust code found in a rust crate.
129 *
130 * Most "externs" are implicitly declared (automatically) as a result of a
131 * user declaring an extern _module_ dependency; this causes the rust driver
132 * to locate an extern crate, scan its compilation metadata, and emit extern
133 * declarations for any symbols used by the declaring crate.
134 *
135 * A "foreign" is an extern that references C (or other non-rust ABI) code.
136 * There is no metadata to scan for extern references so in these cases either
137 * a header-digester like bindgen, or manual function prototypes, have to
138 * serve as declarators. So these are usually given explicitly as prototype
139 * declarations, in rust code, with ABI attributes on them noting which ABI to
140 * link via.
141 *
142 * An "upcall" is a foreign call generated by the compiler (not corresponding
143 * to any user-written call in the code) into the runtime library, to perform
144 * some helper task such as bringing a task to life, allocating memory, etc.
145 *
146 */
147
148 pub struct NodeInfo {
149 pub id: ast::NodeId,
150 pub span: Span,
151 }
152
153 pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
154 NodeInfo { id: expr.id, span: expr.span }
155 }
156
157 pub struct BuilderRef_res {
158 pub b: BuilderRef,
159 }
160
161 impl Drop for BuilderRef_res {
162 fn drop(&mut self) {
163 unsafe {
164 llvm::LLVMDisposeBuilder(self.b);
165 }
166 }
167 }
168
169 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
170 BuilderRef_res {
171 b: b
172 }
173 }
174
175 pub type ExternMap = HashMap<~str, ValueRef>;
176
177 // Here `self_ty` is the real type of the self parameter to this method. It
178 // will only be set in the case of default methods.
179 pub struct param_substs {
180 pub tys: Vec<ty::t> ,
181 pub self_ty: Option<ty::t>,
182 pub vtables: Option<typeck::vtable_res>,
183 pub self_vtables: Option<typeck::vtable_param_res>
184 }
185
186 impl param_substs {
187 pub fn validate(&self) {
188 for t in self.tys.iter() { assert!(!ty::type_needs_infer(*t)); }
189 for t in self.self_ty.iter() { assert!(!ty::type_needs_infer(*t)); }
190 }
191 }
192
193 fn param_substs_to_str(this: ¶m_substs, tcx: &ty::ctxt) -> ~str {
194 format!("param_substs \\{tys:{}, vtables:{}\\}",
195 this.tys.repr(tcx),
196 this.vtables.repr(tcx))
197 }
198
199 impl Repr for param_substs {
200 fn repr(&self, tcx: &ty::ctxt) -> ~str {
201 param_substs_to_str(self, tcx)
202 }
203 }
204
205 // work around bizarre resolve errors
206 pub type RvalueDatum = datum::Datum<datum::Rvalue>;
207 pub type LvalueDatum = datum::Datum<datum::Lvalue>;
208
209 // Function context. Every LLVM function we create will have one of
210 // these.
211 pub struct FunctionContext<'a> {
212 // The ValueRef returned from a call to llvm::LLVMAddFunction; the
213 // address of the first instruction in the sequence of
214 // instructions for this function that will go in the .text
215 // section of the executable we're generating.
216 pub llfn: ValueRef,
217
218 // The environment argument in a closure.
219 pub llenv: Option<ValueRef>,
220
221 // The place to store the return value. If the return type is immediate,
222 // this is an alloca in the function. Otherwise, it's the hidden first
223 // parameter to the function. After function construction, this should
224 // always be Some.
225 pub llretptr: Cell<Option<ValueRef>>,
226
227 pub entry_bcx: RefCell<Option<&'a Block<'a>>>,
228
229 // These pub elements: "hoisted basic blocks" containing
230 // administrative activities that have to happen in only one place in
231 // the function, due to LLVM's quirks.
232 // A marker for the place where we want to insert the function's static
233 // allocas, so that LLVM will coalesce them into a single alloca call.
234 pub alloca_insert_pt: Cell<Option<ValueRef>>,
235 pub llreturn: Cell<Option<BasicBlockRef>>,
236
237 // The a value alloca'd for calls to upcalls.rust_personality. Used when
238 // outputting the resume instruction.
239 pub personality: Cell<Option<ValueRef>>,
240
241 // True if the caller expects this fn to use the out pointer to
242 // return. Either way, your code should write into llretptr, but if
243 // this value is false, llretptr will be a local alloca.
244 pub caller_expects_out_pointer: bool,
245
246 // Maps arguments to allocas created for them in llallocas.
247 pub llargs: RefCell<NodeMap<LvalueDatum>>,
248
249 // Maps the def_ids for local variables to the allocas created for
250 // them in llallocas.
251 pub lllocals: RefCell<NodeMap<LvalueDatum>>,
252
253 // Same as above, but for closure upvars
254 pub llupvars: RefCell<NodeMap<ValueRef>>,
255
256 // The NodeId of the function, or -1 if it doesn't correspond to
257 // a user-defined function.
258 pub id: ast::NodeId,
259
260 // If this function is being monomorphized, this contains the type
261 // substitutions used.
262 pub param_substs: Option<&'a param_substs>,
263
264 // The source span and nesting context where this function comes from, for
265 // error reporting and symbol generation.
266 pub span: Option<Span>,
267
268 // The arena that blocks are allocated from.
269 pub block_arena: &'a TypedArena<Block<'a>>,
270
271 // This function's enclosing crate context.
272 pub ccx: &'a CrateContext,
273
274 // Used and maintained by the debuginfo module.
275 pub debug_context: debuginfo::FunctionDebugContext,
276
277 // Cleanup scopes.
278 pub scopes: RefCell<Vec<cleanup::CleanupScope<'a>> >,
279 }
280
281 impl<'a> FunctionContext<'a> {
282 pub fn arg_pos(&self, arg: uint) -> uint {
283 let arg = self.env_arg_pos() + arg;
284 if self.llenv.is_some() {
285 arg + 1
286 } else {
287 arg
288 }
289 }
290
291 pub fn out_arg_pos(&self) -> uint {
292 assert!(self.caller_expects_out_pointer);
293 0u
294 }
295
296 pub fn env_arg_pos(&self) -> uint {
297 if self.caller_expects_out_pointer {
298 1u
299 } else {
300 0u
301 }
302 }
303
304 pub fn cleanup(&self) {
305 unsafe {
306 llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
307 .get()
308 .unwrap());
309 }
310 // Remove the cycle between fcx and bcx, so memory can be freed
311 *self.entry_bcx.borrow_mut() = None;
312 }
313
314 pub fn get_llreturn(&self) -> BasicBlockRef {
315 if self.llreturn.get().is_none() {
316
317 self.llreturn.set(Some(unsafe {
318 "return".with_c_str(|buf| {
319 llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx, self.llfn, buf)
320 })
321 }))
322 }
323
324 self.llreturn.get().unwrap()
325 }
326
327 pub fn new_block(&'a self,
328 is_lpad: bool,
329 name: &str,
330 opt_node_id: Option<ast::NodeId>)
331 -> &'a Block<'a> {
332 unsafe {
333 let llbb = name.with_c_str(|buf| {
334 llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx,
335 self.llfn,
336 buf)
337 });
338 Block::new(llbb, is_lpad, opt_node_id, self)
339 }
340 }
341
342 pub fn new_id_block(&'a self,
343 name: &str,
344 node_id: ast::NodeId)
345 -> &'a Block<'a> {
346 self.new_block(false, name, Some(node_id))
347 }
348
349 pub fn new_temp_block(&'a self,
350 name: &str)
351 -> &'a Block<'a> {
352 self.new_block(false, name, None)
353 }
354
355 pub fn join_blocks(&'a self,
356 id: ast::NodeId,
357 in_cxs: &[&'a Block<'a>])
358 -> &'a Block<'a> {
359 let out = self.new_id_block("join", id);
360 let mut reachable = false;
361 for bcx in in_cxs.iter() {
362 if !bcx.unreachable.get() {
363 build::Br(*bcx, out.llbb);
364 reachable = true;
365 }
366 }
367 if !reachable {
368 build::Unreachable(out);
369 }
370 return out;
371 }
372 }
373
374 // Basic block context. We create a block context for each basic block
375 // (single-entry, single-exit sequence of instructions) we generate from Rust
376 // code. Each basic block we generate is attached to a function, typically
377 // with many basic blocks per function. All the basic blocks attached to a
378 // function are organized as a directed graph.
379 pub struct Block<'a> {
380 // The BasicBlockRef returned from a call to
381 // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
382 // block to the function pointed to by llfn. We insert
383 // instructions into that block by way of this block context.
384 // The block pointing to this one in the function's digraph.
385 pub llbb: BasicBlockRef,
386 pub terminated: Cell<bool>,
387 pub unreachable: Cell<bool>,
388
389 // Is this block part of a landing pad?
390 pub is_lpad: bool,
391
392 // AST node-id associated with this block, if any. Used for
393 // debugging purposes only.
394 pub opt_node_id: Option<ast::NodeId>,
395
396 // The function context for the function to which this block is
397 // attached.
398 pub fcx: &'a FunctionContext<'a>,
399 }
400
401 impl<'a> Block<'a> {
402 pub fn new<'a>(
403 llbb: BasicBlockRef,
404 is_lpad: bool,
405 opt_node_id: Option<ast::NodeId>,
406 fcx: &'a FunctionContext<'a>)
407 -> &'a Block<'a> {
408 fcx.block_arena.alloc(Block {
409 llbb: llbb,
410 terminated: Cell::new(false),
411 unreachable: Cell::new(false),
412 is_lpad: is_lpad,
413 opt_node_id: opt_node_id,
414 fcx: fcx
415 })
416 }
417
418 pub fn ccx(&self) -> &'a CrateContext { self.fcx.ccx }
419 pub fn tcx(&self) -> &'a ty::ctxt {
420 &self.fcx.ccx.tcx
421 }
422 pub fn sess(&self) -> &'a Session { self.fcx.ccx.sess() }
423
424 pub fn ident(&self, ident: Ident) -> ~str {
425 token::get_ident(ident).get().to_str()
426 }
427
428 pub fn node_id_to_str(&self, id: ast::NodeId) -> ~str {
429 self.tcx().map.node_to_str(id).to_owned()
430 }
431
432 pub fn expr_to_str(&self, e: &ast::Expr) -> ~str {
433 e.repr(self.tcx())
434 }
435
436 pub fn def(&self, nid: ast::NodeId) -> ast::Def {
437 match self.tcx().def_map.borrow().find(&nid) {
438 Some(&v) => v,
439 None => {
440 self.tcx().sess.bug(format!(
441 "no def associated with node id {:?}", nid));
442 }
443 }
444 }
445
446 pub fn val_to_str(&self, val: ValueRef) -> ~str {
447 self.ccx().tn.val_to_str(val)
448 }
449
450 pub fn llty_str(&self, ty: Type) -> ~str {
451 self.ccx().tn.type_to_str(ty)
452 }
453
454 pub fn ty_to_str(&self, t: ty::t) -> ~str {
455 t.repr(self.tcx())
456 }
457
458 pub fn to_str(&self) -> ~str {
459 let blk: *Block = self;
460 format!("[block {}]", blk)
461 }
462 }
463
464 pub struct Result<'a> {
465 pub bcx: &'a Block<'a>,
466 pub val: ValueRef
467 }
468
469 impl<'a> Result<'a> {
470 pub fn new(bcx: &'a Block<'a>, val: ValueRef) -> Result<'a> {
471 Result {
472 bcx: bcx,
473 val: val,
474 }
475 }
476 }
477
478 pub fn val_ty(v: ValueRef) -> Type {
479 unsafe {
480 Type::from_ref(llvm::LLVMTypeOf(v))
481 }
482 }
483
484 // LLVM constant constructors.
485 pub fn C_null(t: Type) -> ValueRef {
486 unsafe {
487 llvm::LLVMConstNull(t.to_ref())
488 }
489 }
490
491 pub fn C_undef(t: Type) -> ValueRef {
492 unsafe {
493 llvm::LLVMGetUndef(t.to_ref())
494 }
495 }
496
497 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
498 unsafe {
499 llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
500 }
501 }
502
503 pub fn C_floating(s: &str, t: Type) -> ValueRef {
504 unsafe {
505 s.with_c_str(|buf| llvm::LLVMConstRealOfString(t.to_ref(), buf))
506 }
507 }
508
509 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
510 C_struct(ccx, [], false)
511 }
512
513 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
514 C_integral(Type::bool(ccx), val as u64, false)
515 }
516
517 pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
518 C_integral(Type::i1(ccx), val as u64, false)
519 }
520
521 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
522 C_integral(Type::i32(ccx), i as u64, true)
523 }
524
525 pub fn C_i64(ccx: &CrateContext, i: i64) -> ValueRef {
526 C_integral(Type::i64(ccx), i as u64, true)
527 }
528
529 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
530 C_integral(Type::i64(ccx), i, false)
531 }
532
533 pub fn C_int(ccx: &CrateContext, i: int) -> ValueRef {
534 C_integral(ccx.int_type, i as u64, true)
535 }
536
537 pub fn C_uint(ccx: &CrateContext, i: uint) -> ValueRef {
538 C_integral(ccx.int_type, i as u64, false)
539 }
540
541 pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
542 C_integral(Type::i8(ccx), i as u64, false)
543 }
544
545
546 // This is a 'c-like' raw string, which differs from
547 // our boxed-and-length-annotated strings.
548 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
549 unsafe {
550 match cx.const_cstr_cache.borrow().find(&s) {
551 Some(&llval) => return llval,
552 None => ()
553 }
554
555 let sc = llvm::LLVMConstStringInContext(cx.llcx,
556 s.get().as_ptr() as *c_char,
557 s.get().len() as c_uint,
558 !null_terminated as Bool);
559
560 let gsym = token::gensym("str");
561 let g = format!("str{}", gsym).with_c_str(|buf| {
562 llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
563 });
564 llvm::LLVMSetInitializer(g, sc);
565 llvm::LLVMSetGlobalConstant(g, True);
566 lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
567
568 cx.const_cstr_cache.borrow_mut().insert(s, g);
569 g
570 }
571 }
572
573 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
574 // you will be kicked off fast isel. See issue #4352 for an example of this.
575 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
576 unsafe {
577 let len = s.get().len();
578 let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false), Type::i8p(cx).to_ref());
579 C_struct(cx, [cs, C_uint(cx, len)], false)
580 }
581 }
582
583 pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
584 unsafe {
585 let len = data.len();
586 let lldata = C_bytes(cx, data);
587
588 let gsym = token::gensym("binary");
589 let g = format!("binary{}", gsym).with_c_str(|buf| {
590 llvm::LLVMAddGlobal(cx.llmod, val_ty(lldata).to_ref(), buf)
591 });
592 llvm::LLVMSetInitializer(g, lldata);
593 llvm::LLVMSetGlobalConstant(g, True);
594 lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
595
596 let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
597 C_struct(cx, [cs, C_uint(cx, len)], false)
598 }
599 }
600
601 pub fn C_struct(ccx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
602 unsafe {
603 llvm::LLVMConstStructInContext(ccx.llcx,
604 elts.as_ptr(), elts.len() as c_uint,
605 packed as Bool)
606 }
607 }
608
609 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
610 unsafe {
611 llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
612 }
613 }
614
615 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
616 unsafe {
617 return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
618 }
619 }
620
621 pub fn C_bytes(ccx: &CrateContext, bytes: &[u8]) -> ValueRef {
622 unsafe {
623 let ptr = bytes.as_ptr() as *c_char;
624 return llvm::LLVMConstStringInContext(ccx.llcx, ptr, bytes.len() as c_uint, True);
625 }
626 }
627
628 pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef {
629 unsafe {
630 llvm::LLVMGetParam(fndecl, param as c_uint)
631 }
632 }
633
634 pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
635 -> ValueRef {
636 unsafe {
637 let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
638
639 debug!("const_get_elt(v={}, us={:?}, r={})",
640 cx.tn.val_to_str(v), us, cx.tn.val_to_str(r));
641
642 return r;
643 }
644 }
645
646 pub fn is_const(v: ValueRef) -> bool {
647 unsafe {
648 llvm::LLVMIsConstant(v) == True
649 }
650 }
651
652 pub fn const_to_int(v: ValueRef) -> c_longlong {
653 unsafe {
654 llvm::LLVMConstIntGetSExtValue(v)
655 }
656 }
657
658 pub fn const_to_uint(v: ValueRef) -> c_ulonglong {
659 unsafe {
660 llvm::LLVMConstIntGetZExtValue(v)
661 }
662 }
663
664 pub fn is_undef(val: ValueRef) -> bool {
665 unsafe {
666 llvm::LLVMIsUndef(val) != False
667 }
668 }
669
670 pub fn is_null(val: ValueRef) -> bool {
671 unsafe {
672 llvm::LLVMIsNull(val) != False
673 }
674 }
675
676 pub fn monomorphize_type(bcx: &Block, t: ty::t) -> ty::t {
677 match bcx.fcx.param_substs {
678 Some(ref substs) => {
679 ty::subst_tps(bcx.tcx(), substs.tys.as_slice(), substs.self_ty, t)
680 }
681 _ => {
682 assert!(!ty::type_has_params(t));
683 assert!(!ty::type_has_self(t));
684 t
685 }
686 }
687 }
688
689 pub fn node_id_type(bcx: &Block, id: ast::NodeId) -> ty::t {
690 let tcx = bcx.tcx();
691 let t = ty::node_id_to_type(tcx, id);
692 monomorphize_type(bcx, t)
693 }
694
695 pub fn expr_ty(bcx: &Block, ex: &ast::Expr) -> ty::t {
696 node_id_type(bcx, ex.id)
697 }
698
699 pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
700 monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex))
701 }
702
703 // Key used to lookup values supplied for type parameters in an expr.
704 #[deriving(Eq)]
705 pub enum ExprOrMethodCall {
706 // Type parameters for a path like `None::<int>`
707 ExprId(ast::NodeId),
708
709 // Type parameters for a method call like `a.foo::<int>()`
710 MethodCall(typeck::MethodCall)
711 }
712
713 pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
714 let tcx = bcx.tcx();
715 let params = match node {
716 ExprId(id) => ty::node_id_to_type_params(tcx, id),
717 MethodCall(method_call) => {
718 tcx.method_map.borrow().get(&method_call).substs.tps.clone()
719 }
720 };
721
722 if !params.iter().all(|t| !ty::type_needs_infer(*t)) {
723 bcx.sess().bug(
724 format!("type parameters for node {:?} include inference types: {}",
725 node, params.iter()
726 .map(|t| bcx.ty_to_str(*t))
727 .collect::<Vec<~str>>()
728 .connect(",")));
729 }
730
731 match bcx.fcx.param_substs {
732 Some(ref substs) => {
733 params.iter().map(|t| {
734 ty::subst_tps(tcx, substs.tys.as_slice(), substs.self_ty, *t)
735 }).collect()
736 }
737 _ => params
738 }
739 }
740
741 pub fn node_vtables(bcx: &Block, id: typeck::MethodCall)
742 -> Option<typeck::vtable_res> {
743 bcx.tcx().vtable_map.borrow().find(&id).map(|vts| {
744 resolve_vtables_in_fn_ctxt(bcx.fcx, vts.as_slice())
745 })
746 }
747
748 // Apply the typaram substitutions in the FunctionContext to some
749 // vtables. This should eliminate any vtable_params.
750 pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext,
751 vts: &[typeck::vtable_param_res])
752 -> typeck::vtable_res {
753 resolve_vtables_under_param_substs(fcx.ccx.tcx(),
754 fcx.param_substs,
755 vts)
756 }
757
758 pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt,
759 param_substs: Option<¶m_substs>,
760 vts: &[typeck::vtable_param_res])
761 -> typeck::vtable_res {
762 vts.iter().map(|ds| {
763 resolve_param_vtables_under_param_substs(tcx,
764 param_substs,
765 ds.as_slice())
766 }).collect()
767 }
768
769 pub fn resolve_param_vtables_under_param_substs(
770 tcx: &ty::ctxt,
771 param_substs: Option<¶m_substs>,
772 ds: &[typeck::vtable_origin])
773 -> typeck::vtable_param_res {
774 ds.iter().map(|d| {
775 resolve_vtable_under_param_substs(tcx,
776 param_substs,
777 d)
778 }).collect()
779 }
780
781
782
783 pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
784 param_substs: Option<¶m_substs>,
785 vt: &typeck::vtable_origin)
786 -> typeck::vtable_origin {
787 match *vt {
788 typeck::vtable_static(trait_id, ref tys, ref sub) => {
789 let tys = match param_substs {
790 Some(substs) => {
791 tys.iter().map(|t| {
792 ty::subst_tps(tcx,
793 substs.tys.as_slice(),
794 substs.self_ty,
795 *t)
796 }).collect()
797 }
798 _ => Vec::from_slice(tys.as_slice())
799 };
800 typeck::vtable_static(
801 trait_id, tys,
802 resolve_vtables_under_param_substs(tcx, param_substs, sub.as_slice()))
803 }
804 typeck::vtable_param(n_param, n_bound) => {
805 match param_substs {
806 Some(substs) => {
807 find_vtable(tcx, substs, n_param, n_bound)
808 }
809 _ => {
810 tcx.sess.bug(format!(
811 "resolve_vtable_under_param_substs: asked to lookup \
812 but no vtables in the fn_ctxt!"))
813 }
814 }
815 }
816 }
817 }
818
819 pub fn find_vtable(tcx: &ty::ctxt,
820 ps: ¶m_substs,
821 n_param: typeck::param_index,
822 n_bound: uint)
823 -> typeck::vtable_origin {
824 debug!("find_vtable(n_param={:?}, n_bound={}, ps={})",
825 n_param, n_bound, ps.repr(tcx));
826
827 let param_bounds = match n_param {
828 typeck::param_self => ps.self_vtables.as_ref().expect("self vtables missing"),
829 typeck::param_numbered(n) => {
830 let tables = ps.vtables.as_ref()
831 .expect("vtables missing where they are needed");
832 tables.get(n)
833 }
834 };
835 param_bounds.get(n_bound).clone()
836 }
837
838 pub fn filename_and_line_num_from_span(bcx: &Block, span: Span)
839 -> (ValueRef, ValueRef) {
840 let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
841 let filename_cstr = C_cstr(bcx.ccx(),
842 token::intern_and_get_ident(loc.file
843 .name
844 .as_slice()),
845 true);
846 let filename = build::PointerCast(bcx, filename_cstr, Type::i8p(bcx.ccx()));
847 let line = C_int(bcx.ccx(), loc.line as int);
848 (filename, line)
849 }
850
851 // Casts a Rust bool value to an i1.
852 pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
853 build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
854 }
855
856 pub fn langcall(bcx: &Block,
857 span: Option<Span>,
858 msg: &str,
859 li: LangItem)
860 -> ast::DefId {
861 match bcx.tcx().lang_items.require(li) {
862 Ok(id) => id,
863 Err(s) => {
864 let msg = format!("{} {}", msg, s);
865 match span {
866 Some(span) => { bcx.tcx().sess.span_fatal(span, msg); }
867 None => { bcx.tcx().sess.fatal(msg); }
868 }
869 }
870 }
871 }
librustc/middle/trans/common.rs:206:52-206:52 -NK_AS_STR_TODO- definition:
pub type RvalueDatum = datum::Datum<datum::Rvalue>;
pub type LvalueDatum = datum::Datum<datum::Lvalue>;
// Function context. Every LLVM function we create will have one of
references:- 2246: // Maps arguments to allocas created for them in llallocas.
247: pub llargs: RefCell<NodeMap<LvalueDatum>>,
--
250: // them in llallocas.
251: pub lllocals: RefCell<NodeMap<LvalueDatum>>,
librustc/middle/trans/common.rs:851:37-851:37 -fn- definition:
// Casts a Rust bool value to an i1.
pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
references:- 5librustc/middle/trans/_match.rs:
1237: bcx: result.bcx,
1238: val: bool_to_i1(result.bcx, result.val)
1239: }
librustc/middle/trans/reflect.rs:
108: ArgVals(args), None));
109: let result = bool_to_i1(bcx, result);
110: let next_bcx = fcx.new_temp_block("next");
librustc/middle/trans/datum.rs:
661: let cond_val = self.to_llscalarish(bcx);
662: bool_to_i1(bcx, cond_val)
663: }
librustc/middle/trans/expr.rs:
1374: let lhs_i1 = bool_to_i1(past_lhs, lhs);
1375: match op {
librustc/middle/trans/_match.rs:
1260: bcx: result.bcx,
1261: val: bool_to_i1(result.bcx, result.val)
1262: }
librustc/middle/trans/common.rs:463:1-463:1 -struct- definition:
pub struct Result<'a> {
pub bcx: &'a Block<'a>,
pub val: ValueRef
references:- 37librustc/middle/trans/_match.rs:
librustc/middle/trans/common.rs:
librustc/middle/trans/base.rs:
librustc/middle/trans/_match.rs:
librustc/middle/trans/closure.rs:
librustc/middle/trans/tvec.rs:
librustc/middle/trans/controlflow.rs:
librustc/middle/trans/datum.rs:
librustc/middle/trans/callee.rs:
librustc/middle/trans/expr.rs:
librustc/middle/trans/base.rs:
librustc/middle/trans/common.rs:152:1-152:1 -fn- definition:
pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
NodeInfo { id: expr.id, span: expr.span }
}
references:- 3librustc/middle/trans/callee.rs:
465: trans_call_inner(in_cx,
466: Some(common::expr_info(call_ex)),
467: expr_ty(in_cx, f),
librustc/middle/trans/expr.rs:
1445: callee::trans_call_inner(bcx,
1446: Some(expr_info(expr)),
1447: monomorphize_type(bcx, method_ty),
librustc/middle/trans/callee.rs:
485: bcx,
486: Some(common::expr_info(call_ex)),
487: monomorphize_type(bcx, method_ty),
librustc/middle/trans/common.rs:484:31-484:31 -fn- definition:
// LLVM constant constructors.
pub fn C_null(t: Type) -> ValueRef {
unsafe {
references:- 17librustc/middle/trans/consts.rs:
202: is_local);
203: llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
204: }
librustc/middle/trans/build.rs:
118: if cx.unreachable.get() {
119: return C_null(Type::i8(cx.ccx()));
120: }
librustc/middle/trans/builder.rs:
869: let vec_i32_ty = Type::vector(&Type::i32(self.ccx), num_elts as u64);
870: self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
871: }
librustc/middle/trans/base.rs:
890: if bcx.unreachable.get() {
891: return (C_null(Type::i8(bcx.ccx())), bcx);
892: }
--
1209: fcx.alloca_insert_pt.set(Some(unsafe {
1210: Load(entry_bcx, C_null(Type::i8p(fcx.ccx)));
1211: llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
librustc/middle/trans/closure.rs:
472: let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def, fn_ptr, true);
473: fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p(bcx.ccx())));
librustc/middle/trans/tvec.rs:
158: // Zero-length array: just use NULL as the data pointer
159: llfixed = C_null(vt.llunit_ty.ptr_to());
160: } else {
librustc/middle/trans/meth.rs:
515: token::get_ident(ident));
516: C_null(Type::nil(ccx).ptr_to())
517: } else {
librustc/middle/trans/intrinsic.rs:
359: match bcx.fcx.llretptr.get() {
360: Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); }
361: None if ty::type_is_nil(tp_ty) => RetVoid(bcx),
362: None => Ret(bcx, C_null(lltp_ty)),
363: }
librustc/middle/trans/reflect.rs:
330: let bcx = this.bcx;
331: let null = C_null(llptrty);
332: let ptr = adt::trans_field_ptr(bcx, &*repr, null, v.disr_val, j);
librustc/middle/trans/adt.rs:
546: let llptrty = type_of::type_of(bcx.ccx(), *nonnull.fields.get(ptrfield));
547: ICmp(bcx, cmp, llptr, C_null(llptrty))
548: }
--
628: *nonnull.fields.get(ptrfield));
629: Store(bcx, C_null(llptrty), llptrptr)
630: }
--
771: // field; see #8506.
772: C_null(type_of::sizing_type_of(ccx, ty))
773: }).collect::<Vec<ValueRef>>();
librustc/middle/trans/glue.rs:
499: 1u);
500: C_null(glue_fn_ty)
501: }
librustc/middle/trans/consts.rs:
641: let llty = type_of::type_of(cx, ety);
642: (C_null(llty), true)
643: }
librustc/middle/trans/common.rs:688:1-688:1 -fn- definition:
pub fn node_id_type(bcx: &Block, id: ast::NodeId) -> ty::t {
let tcx = bcx.tcx();
let t = ty::node_id_to_type(tcx, id);
references:- 29695: pub fn expr_ty(bcx: &Block, ex: &ast::Expr) -> ty::t {
696: node_id_type(bcx, ex.id)
697: }
librustc/middle/trans/base.rs:
1398: let mut bcx = bcx_top;
1399: let block_ty = node_id_type(bcx, body.id);
--
1401: // Set up arguments to the function.
1402: let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
1403: let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
librustc/middle/trans/_match.rs:
1061: ast::PatStruct(_, ref fs, _) => {
1062: match ty::get(node_id_type(bcx, br.pats.get(col).id)).sty {
1063: ty::ty_struct(..) => {
--
1548: if any_tuple_struct_pat(bcx, m, col) {
1549: let struct_ty = node_id_type(bcx, pat_id);
1550: let struct_element_count;
--
2065: // like `x: T`
2066: let arg_ty = node_id_type(bcx, pat.id);
2067: if type_of::arg_is_indirect(bcx.ccx(), arg_ty)
--
2101: -> &'a Block<'a> {
2102: let var_ty = node_id_type(bcx, p_id);
2103: let ident = ast_util::path_to_ident(path);
--
2242: let tcx = bcx.tcx();
2243: let pat_ty = node_id_type(bcx, pat.id);
2244: let pat_repr = adt::represent_type(bcx.ccx(), pat_ty);
librustc/middle/trans/closure.rs:
342: let ccx = bcx.ccx();
343: let fty = node_id_type(bcx, id);
344: let f = match ty::get(fty).sty {
librustc/middle/trans/tvec.rs:
268: let vec_ty = node_id_type(bcx, vstore_expr.id);
269: let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
--
407: pub fn vec_types_from_expr(bcx: &Block, vec_expr: &ast::Expr) -> VecTypes {
408: let vec_ty = node_id_type(bcx, vec_expr.id);
409: vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty))
librustc/middle/trans/meth.rs:
213: let callee_ty = node_id_type(bcx, expr_id);
214: let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
librustc/middle/trans/debuginfo.rs:
443: let variable_type = node_id_type(bcx, node_id);
444: let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
librustc/middle/trans/adt.rs:
120: pub fn represent_node(bcx: &Block, node: ast::NodeId) -> Rc<Repr> {
121: represent_type(bcx.ccx(), node_id_type(bcx, node))
122: }
librustc/middle/trans/controlflow.rs:
99: if dest != expr::Ignore {
100: let block_ty = node_id_type(bcx, b.id);
101: if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
librustc/middle/trans/callee.rs:
397: let ref_ty = match node {
398: ExprId(id) => node_id_type(bcx, id),
399: MethodCall(method_call) => {
librustc/middle/trans/expr.rs:
862: // Can't move upvars, so this is never a ZeroMemLastUse.
863: let local_ty = node_id_type(bcx, nid);
864: match bcx.fcx.llupvars.borrow().find(&nid) {
--
1530: let t_in = expr_ty(bcx, expr);
1531: let t_out = node_id_type(bcx, id);
1532: let k_in = cast_type_kind(t_in);
librustc/middle/trans/_match.rs:
1011: let (base, len) = vec_datum.get_vec_base_and_len(bcx);
1012: let vec_ty = node_id_type(bcx, pat_id);
1013: let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
librustc/middle/trans/common.rs:620:1-620:1 -fn- definition:
pub fn C_bytes(ccx: &CrateContext, bytes: &[u8]) -> ValueRef {
unsafe {
let ptr = bytes.as_ptr() as *c_char;
references:- 2librustc/middle/trans/base.rs:
2117: }.as_slice());
2118: let llmeta = C_bytes(cx, compressed.as_slice());
2119: let llconst = C_struct(cx, [llmeta], false);
librustc/middle/trans/common.rs:
585: let len = data.len();
586: let lldata = C_bytes(cx, data);
librustc/middle/trans/common.rs:675:1-675:1 -fn- definition:
pub fn monomorphize_type(bcx: &Block, t: ty::t) -> ty::t {
match bcx.fcx.param_substs {
Some(ref substs) => {
references:- 7691: let t = ty::node_id_to_type(tcx, id);
692: monomorphize_type(bcx, t)
693: }
--
699: pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
700: monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex))
701: }
librustc/middle/trans/meth.rs:
136: trans_trait_callee(bcx,
137: monomorphize_type(bcx, method_ty),
138: mt.real_index,
librustc/middle/trans/callee.rs:
400: let t = bcx.tcx().method_map.borrow().get(&method_call).ty;
401: monomorphize_type(bcx, t)
402: }
--
486: Some(common::expr_info(call_ex)),
487: monomorphize_type(bcx, method_ty),
488: |cx, arg_cleanup_scope| {
librustc/middle/trans/expr.rs:
1707: datum, None, None));
1708: let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
1709: Datum(val, ref_ty, RvalueExpr(Rvalue(ByValue)))
librustc/middle/trans/common.rs:147:1-147:1 -struct- definition:
pub struct NodeInfo {
pub id: ast::NodeId,
pub span: Span,
references:- 4153: pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
154: NodeInfo { id: expr.id, span: expr.span }
155: }
librustc/middle/trans/base.rs:
886: attributes: &[(uint, lib::llvm::Attribute)],
887: call_info: Option<NodeInfo>)
888: -> (ValueRef, &'a Block<'a>) {
librustc/middle/trans/callee.rs:
521: bcx: &'a Block<'a>,
522: call_info: Option<NodeInfo>,
523: callee_ty: ty::t,
librustc/middle/trans/common.rs:
153: pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
154: NodeInfo { id: expr.id, span: expr.span }
librustc/middle/trans/common.rs:818:1-818:1 -fn- definition:
pub fn find_vtable(tcx: &ty::ctxt,
ps: ¶m_substs,
n_param: typeck::param_index,
references:- 2806: Some(substs) => {
807: find_vtable(tcx, substs, n_param, n_bound)
808: }
librustc/middle/trans/meth.rs:
118: let vtbl = find_vtable(bcx.tcx(), substs, p, b);
119: trans_monomorphized_callee(bcx, method_call,
librustc/middle/trans/common.rs:80:1-80:1 -fn- definition:
pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
/*!
* Identify types which have size zero at runtime.
references:- 1376: }
77: _ => type_is_zero_size(ccx, ty)
78: }
librustc/middle/trans/base.rs:
1420: None => {
1421: assert!(type_is_zero_size(bcx.ccx(), block_ty))
1422: expr::Ignore
librustc/middle/trans/closure.rs:
452: let retval = Call(bcx, fn_ptr, llargs.as_slice(), []);
453: if type_is_zero_size(ccx, f.sig.output) || fcx.llretptr.get().is_some() {
454: RetVoid(bcx);
librustc/middle/trans/controlflow.rs:
100: let block_ty = node_id_type(bcx, b.id);
101: if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
102: dest = expr::Ignore;
librustc/middle/trans/datum.rs:
595: if type_is_zero_size(bcx.ccx(), self.ty) {
596: return bcx;
librustc/middle/trans/callee.rs:
594: Some(expr::Ignore) => {
595: if !type_is_zero_size(ccx, ret_ty) {
596: Some(alloc_ty(bcx, ret_ty, "__llret"))
--
706: if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
707: !type_is_zero_size(bcx.ccx(), ret_ty)
708: {
librustc/middle/trans/expr.rs:
339: let ty = expr_ty(bcx, expr);
340: if type_is_zero_size(bcx.ccx(), ty) {
341: bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
--
1795: let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
1796: if !type_is_zero_size(bcx.ccx(), content_ty) {
1797: bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange);
librustc/middle/trans/base.rs:
1543: if !type_is_zero_size(fcx.ccx, result_ty) {
1544: let repr = adt::represent_type(ccx, result_ty);
librustc/middle/trans/common.rs:657:1-657:1 -fn- definition:
pub fn const_to_uint(v: ValueRef) -> c_ulonglong {
unsafe {
llvm::LLVMConstIntGetZExtValue(v)
references:- 5librustc/middle/trans/adt.rs:
859: attr::SignedInt(..) => const_to_int(val) as Disr,
860: attr::UnsignedInt(..) => const_to_uint(val) as Disr
861: }
--
865: attr::SignedInt(..) => const_to_int(const_get_elt(ccx, val, [0])) as Disr,
866: attr::UnsignedInt(..) => const_to_uint(const_get_elt(ccx, val, [0])) as Disr
867: }
librustc/middle/trans/controlflow.rs:
136: if is_const(cond_val) && !is_undef(cond_val) {
137: if const_to_uint(cond_val) == 1 {
138: match els {
librustc/middle/trans/common.rs:516:1-516:1 -fn- definition:
pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
C_integral(Type::i1(ccx), val as u64, false)
}
references:- 9librustc/middle/trans/base.rs:
1067: let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
1068: let volatile = C_i1(ccx, false);
1069: b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
librustc/middle/trans/intrinsic.rs:
178: let llfn = ccx.get_intrinsic(&name);
179: Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
180: RetVoid(bcx);
--
184: let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
185: let y = C_i1(bcx.ccx(), false);
186: let llfn = bcx.ccx().get_intrinsic(&name);
librustc/middle/trans/adt.rs:
594: assert!(discr == 0 || discr == 1);
595: _match::single_result(Result::new(bcx, C_i1(bcx.ccx(), discr != 0)))
596: }
librustc/middle/trans/expr.rs:
490: let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
491: let expected = Call(bcx, expect, [bounds_check, C_i1(ccx, false)], []);
492: let bcx = with_cond(bcx, expected, |bcx| {
librustc/middle/trans/base.rs:
1022: let align = C_i32(ccx, align as i32);
1023: let volatile = C_i1(ccx, false);
1024: Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
librustc/middle/trans/common.rs:477:1-477:1 -fn- definition:
pub fn val_ty(v: ValueRef) -> Type {
unsafe {
Type::from_ref(llvm::LLVMTypeOf(v))
references:- 30librustc/middle/trans/consts.rs:
librustc/middle/trans/build.rs:
librustc/middle/trans/builder.rs:
librustc/middle/trans/base.rs:
librustc/middle/trans/_match.rs:
librustc/middle/trans/tvec.rs:
librustc/middle/trans/meth.rs:
librustc/middle/trans/foreign.rs:
librustc/middle/trans/adt.rs:
librustc/middle/trans/cleanup.rs:
librustc/middle/trans/callee.rs:
librustc/middle/trans/expr.rs:
librustc/middle/trans/common.rs:
librustc/middle/trans/common.rs:704:16-704:16 -enum- definition:
pub enum ExprOrMethodCall {
// Type parameters for a path like `None::<int>`
ExprId(ast::NodeId),
references:- 7703: // Key used to lookup values supplied for type parameters in an expr.
705: pub enum ExprOrMethodCall {
--
713: pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
714: let tcx = bcx.tcx();
librustc/middle/trans/callee.rs:
160: pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, node: ExprOrMethodCall) -> ValueRef {
161: /*!
--
242: def_id: ast::DefId, // def id of fn
243: node: ExprOrMethodCall, // node id of use of fn; may be zero if N/A
244: type_params: Vec<ty::t>, // values for fn's ty params
librustc/middle/trans/meth.rs:
278: mth_did: ast::DefId,
279: node: ExprOrMethodCall,
280: rcvr_substs: Vec<ty::t>,
librustc/middle/trans/common.rs:694:1-694:1 -fn- definition:
pub fn expr_ty(bcx: &Block, ex: &ast::Expr) -> ty::t {
node_id_type(bcx, ex.id)
}
references:- 26librustc/middle/trans/_match.rs:
2010: unpack_datum!(bcx, expr::trans_to_lvalue(bcx, init_expr, "let"));
2011: if ty::type_is_bot(expr_ty(bcx, init_expr)) {
2012: create_dummy_locals(bcx, pat)
librustc/middle/trans/asm.rs:
55: callee::trans_arg_datum(bcx,
56: expr_ty(bcx, input),
57: in_datum,
librustc/middle/trans/controlflow.rs:
76: let _icx = push_ctxt("trans_stmt_semi");
77: let ty = expr_ty(cx, e);
78: if ty::type_needs_drop(cx.tcx(), ty) {
librustc/middle/trans/callee.rs:
720: let arg_tys = match args {
721: ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, *x)).collect(),
722: _ => fail!("expected arg exprs.")
librustc/middle/trans/expr.rs:
402: let box_ty = expr_ty(bcx, expr);
403: let contents_ty = expr_ty(bcx, contents);
404: trans_uniq_expr(bcx, box_ty, contents, contents_ty)
--
1219: let sub_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, subexpr, "addr_of"));
1220: let ty = expr_ty(bcx, expr);
1221: return immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock();
--
1360: let _icx = push_ctxt("trans_lazy_binop");
1361: let binop_ty = expr_ty(bcx, binop_expr);
1362: let fcx = bcx.fcx;
--
1530: let t_in = expr_ty(bcx, expr);
1531: let t_out = node_id_type(bcx, id);
librustc/middle/trans/common.rs:608:1-608:1 -fn- definition:
pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
unsafe {
llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
references:- 2librustc/middle/trans/glue.rs:
511: let tydesc = C_named_struct(ccx.tydesc_type(),
512: [ti.size, // size
librustc/middle/trans/intrinsic.rs:
345: // libstd/unstable/intrinsics.rs
346: let val = C_named_struct(type_of::type_of(ccx, output_type),
347: [C_u64(ccx, hash)]);
librustc/middle/trans/common.rs:156:1-156:1 -struct- definition:
pub struct BuilderRef_res {
pub b: BuilderRef,
}
references:- 4161: impl Drop for BuilderRef_res {
162: fn drop(&mut self) {
--
169: pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
170: BuilderRef_res {
librustc/middle/trans/context.rs:
117: pub opaque_vec_type: Type,
118: pub builder: BuilderRef_res,
119: /// Set when at least one function uses GC. Needed so that
librustc/middle/trans/common.rs:
169: pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
170: BuilderRef_res {
171: b: b
librustc/middle/trans/common.rs:749:53-749:53 -fn- definition:
// vtables. This should eliminate any vtable_params.
pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext,
vts: &[typeck::vtable_param_res])
references:- 2743: bcx.tcx().vtable_map.borrow().find(&id).map(|vts| {
744: resolve_vtables_in_fn_ctxt(bcx.fcx, vts.as_slice())
745: })
librustc/middle/trans/meth.rs:
195: let vtable_key = MethodCall::expr(expr_id);
196: let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, ccx.tcx.vtable_map.borrow()
197: .get(&vtable_key).as_slice());
librustc/middle/trans/common.rs:768:1-768:1 -fn- definition:
pub fn resolve_param_vtables_under_param_substs(
tcx: &ty::ctxt,
param_substs: Option<¶m_substs>,
references:- 3762: vts.iter().map(|ds| {
763: resolve_param_vtables_under_param_substs(tcx,
764: param_substs,
librustc/middle/trans/callee.rs:
233: let self_vtables = resolve_param_vtables_under_param_substs(
234: bcx.tcx(), Some(¶m_substs), impl_res.self_vtables.as_slice());
librustc/middle/trans/meth.rs:
557: let vtable_map = ccx.tcx.vtable_map.borrow();
558: resolve_param_vtables_under_param_substs(ccx.tcx(),
559: bcx.fcx.param_substs,
librustc/middle/trans/common.rs:712:1-712:1 -fn- definition:
pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
let tcx = bcx.tcx();
let params = match node {
references:- 2librustc/middle/trans/meth.rs:
302: let n_m_tps = method.generics.type_param_defs().len();
303: let node_substs = node_id_type_params(bcx, node);
304: debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx()));
librustc/middle/trans/callee.rs:
169: let type_params = node_id_type_params(bcx, node);
170: let vtable_key = match node {
librustc/middle/trans/common.rs:174:1-174:1 -NK_AS_STR_TODO- definition:
pub type ExternMap = HashMap<~str, ValueRef>;
// Here `self_ty` is the real type of the self parameter to this method. It
// will only be set in the case of default methods.
references:- 3librustc/middle/trans/context.rs:
58: pub tn: TypeNames,
59: pub externs: RefCell<ExternMap>,
60: pub item_vals: RefCell<NodeMap<ValueRef>>,
librustc/middle/trans/base.rs:
307: pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
308: name: &str, ty: Type) -> ValueRef {
librustc/middle/trans/common.rs:178:52-178:52 -struct- definition:
// will only be set in the case of default methods.
pub struct param_substs {
pub tys: Vec<ty::t> ,
references:- 20librustc/middle/trans/monomorphize.rs:
87: let psubsts = param_substs {
88: tys: real_substs.tps.clone(),
librustc/middle/trans/common.rs:
186: impl param_substs {
187: pub fn validate(&self) {
--
783: pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
784: param_substs: Option<¶m_substs>,
785: vt: &typeck::vtable_origin)
--
819: pub fn find_vtable(tcx: &ty::ctxt,
820: ps: ¶m_substs,
821: n_param: typeck::param_index,
librustc/middle/trans/callee.rs:
205: // trait_vtables under.
206: let param_substs = param_substs {
207: tys: substs.tps.clone(),
librustc/middle/trans/base.rs:
1478: disr: ty::Disr,
1479: param_substs: Option<¶m_substs>,
1480: llfndecl: ValueRef) {
--
1493: ctor_id: ast::NodeId,
1494: param_substs: Option<¶m_substs>,
1495: llfndecl: ValueRef) {
--
1508: disr: ty::Disr,
1509: param_substs: Option<¶m_substs>,
1510: llfndecl: ValueRef) {
librustc/middle/trans/intrinsic.rs:
87: item: &ast::ForeignItem,
88: substs: ¶m_substs,
89: ref_id: Option<ast::NodeId>) {
librustc/middle/trans/debuginfo.rs:
831: generics: &ast::Generics,
832: param_substs: Option<¶m_substs>,
833: file_metadata: DIFile,
librustc/middle/trans/base.rs:
1141: output_type: ty::t,
1142: param_substs: Option<&'a param_substs>,
1143: sp: Option<Span>,
librustc/middle/trans/common.rs:512:1-512:1 -fn- definition:
pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
C_integral(Type::bool(ccx), val as u64, false)
}
references:- 10852: pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
853: build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
854: }
librustc/middle/trans/consts.rs:
76: }
77: ast::LitBool(b) => C_bool(cx, b),
78: ast::LitNil => C_nil(cx),
librustc/middle/trans/intrinsic.rs:
451: let tp_ty = *substs.tys.get(0);
452: Ret(bcx, C_bool(ccx, ty::type_contents(ccx.tcx(), tp_ty).owns_managed()));
453: }
librustc/middle/trans/reflect.rs:
50: pub fn c_bool(&mut self, b: bool) -> ValueRef {
51: C_bool(self.bcx.ccx(), b)
52: }
librustc/middle/trans/adt.rs:
617: assert_eq!(discr, 0);
618: Store(bcx, C_bool(bcx.ccx(), true),
619: GEPi(bcx, val, [0, st.fields.len() - 1]))
librustc/middle/trans/expr.rs:
1130: val,
1131: C_bool(ccx, false));
1132: Select(bcx, llcond, C_bool(ccx, true), C_bool(ccx, false))
1133: } else {
--
1327: if ty::type_is_bot(rhs_t) {
1328: C_bool(bcx.ccx(), false)
1329: } else if ty::type_is_scalar(rhs_t) {
librustc/middle/trans/common.rs:663:1-663:1 -fn- definition:
pub fn is_undef(val: ValueRef) -> bool {
unsafe {
llvm::LLVMIsUndef(val) != False
references:- 3librustc/middle/trans/adt.rs:
831: }
832: assert!(!is_undef(val));
833: cfields.push(val);
librustc/middle/trans/controlflow.rs:
135: // Drop branches that are known to be impossible
136: if is_const(cond_val) && !is_undef(cond_val) {
137: if const_to_uint(cond_val) == 1 {
librustc/middle/trans/adt.rs:
907: field = const_get_elt(ccx, val, [real_ix]);
908: if !is_undef(field) {
909: break;
librustc/middle/trans/common.rs:574:77-574:77 -fn- definition:
// you will be kicked off fast isel. See issue #4352 for an example of this.
pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
unsafe {
references:- 2librustc/middle/trans/glue.rs:
423: let ty_name = token::intern_and_get_ident(ppaux::ty_to_str(ccx.tcx(), t));
424: let ty_name = C_str_slice(ccx, ty_name);
librustc/middle/trans/consts.rs:
78: ast::LitNil => C_nil(cx),
79: ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
80: ast::LitBinary(ref data) => C_binary_slice(cx, data.as_slice()),
librustc/middle/trans/common.rs:547:43-547:43 -fn- definition:
// our boxed-and-length-annotated strings.
pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
unsafe {
references:- 8577: let len = s.get().len();
578: let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false), Type::i8p(cx).to_ref());
579: C_struct(cx, [cs, C_uint(cx, len)], false)
--
840: let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
841: let filename_cstr = C_cstr(bcx.ccx(),
842: token::intern_and_get_ident(loc.file
librustc/middle/trans/tvec.rs:
328: let llbytes = C_uint(bcx.ccx(), bytes);
329: let llcstr = C_cstr(bcx.ccx(), (*s).clone(), false);
330: base::call_memcpy(bcx,
librustc/middle/trans/reflect.rs:
60: let len = C_uint(bcx.ccx(), s.get().len());
61: let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s, false), Type::i8p(bcx.ccx()));
62: Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ]));
librustc/middle/trans/controlflow.rs:
344: let ccx = bcx.ccx();
345: let v_fail_str = C_cstr(ccx, fail_str, true);
346: let _icx = push_ctxt("trans_fail_value");
347: let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
348: let v_filename = C_cstr(ccx,
349: token::intern_and_get_ident(loc.file
librustc/middle/trans/tvec.rs:
212: let llbytes = C_uint(bcx.ccx(), bytes);
213: let llcstr = C_cstr(bcx.ccx(), str_lit, false);
214: let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p(bcx.ccx()).to_ref());
librustc/middle/trans/common.rs:210:10-210:10 -struct- definition:
// these.
pub struct FunctionContext<'a> {
// The ValueRef returned from a call to llvm::LLVMAddFunction; the
references:- 24librustc/middle/trans/base.rs:
1168: let mut fcx = FunctionContext {
1169: llfn: llfndecl,
librustc/middle/trans/common.rs:
749: // vtables. This should eliminate any vtable_params.
750: pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext,
751: vts: &[typeck::vtable_param_res])
librustc/middle/trans/build.rs:
327: pub fn AllocaFcx(fcx: &FunctionContext, ty: Type, name: &str) -> ValueRef {
328: let b = fcx.ccx.builder();
librustc/middle/trans/base.rs:
1245: fn arg_kind(cx: &FunctionContext, t: ty::t) -> datum::Rvalue {
1246: use middle::trans::datum::{ByRef, ByValue};
--
1327: // Builds the return block for a function.
1328: pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
1329: // Return the value if this function immediate; otherwise, return void.
librustc/middle/trans/debuginfo.rs:
582: /// Instructions generated hereafter won't be assigned a source location.
583: pub fn clear_source_location(fcx: &FunctionContext) {
584: if fn_should_be_ignored(fcx) {
--
596: /// translated.
597: pub fn start_emitting_source_locations(fcx: &FunctionContext) {
598: match fcx.debug_context.repr {
--
2348: fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
2349: match fcx.debug_context.repr {
librustc/middle/trans/cleanup.rs:
401: impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
402: fn top_ast_scope(&self) -> Option<ast::NodeId> {
librustc/middle/trans/datum.rs:
293: pub fn add_clean(self,
294: fcx: &FunctionContext,
295: scope: cleanup::ScopeId)
librustc/middle/trans/common.rs:
281: impl<'a> FunctionContext<'a> {
282: pub fn arg_pos(&self, arg: uint) -> uint {
librustc/middle/trans/common.rs:490:1-490:1 -fn- definition:
pub fn C_undef(t: Type) -> ValueRef {
unsafe {
llvm::LLVMGetUndef(t.to_ref())
references:- 7librustc/middle/trans/foreign.rs:
350: match arg_tys[i].pad {
351: Some(ty) => llargs_foreign.push(C_undef(ty)),
352: None => ()
librustc/middle/trans/intrinsic.rs:
101: let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
102: let ret = C_undef(type_of::type_of(bcx.ccx(), t));
103: let ret = InsertValue(bcx, ret, result, 0);
librustc/middle/trans/adt.rs:
845: fn padding(ccx: &CrateContext, size: u64) -> ValueRef {
846: C_undef(Type::array(&Type::i8(ccx), size))
847: }
librustc/middle/trans/datum.rs:
536: if type_is_zero_size(bcx.ccx(), ty) {
537: C_undef(type_of::type_of(bcx.ccx(), ty))
538: } else if ty::type_is_bool(ty) {
librustc/middle/trans/callee.rs:
598: let llty = type_of::type_of(ccx, ret_ty);
599: Some(C_undef(llty.ptr_to()))
600: }
librustc/middle/trans/expr.rs:
365: fn nil<'a>(bcx: &'a Block<'a>, ty: ty::t) -> DatumBlock<'a, Expr> {
366: let llval = C_undef(type_of::type_of(bcx.ccx(), ty));
367: let datum = immediate_rvalue(llval, ty);
librustc/middle/trans/consts.rs:
279: llvm::LLVMDumpValue(llconst);
280: llvm::LLVMDumpValue(C_undef(llty));
281: }
librustc/middle/trans/common.rs:651:1-651:1 -fn- definition:
pub fn const_to_int(v: ValueRef) -> c_longlong {
unsafe {
llvm::LLVMConstIntGetSExtValue(v)
references:- 4librustc/middle/trans/adt.rs:
864: match ity {
865: attr::SignedInt(..) => const_to_int(const_get_elt(ccx, val, [0])) as Disr,
866: attr::UnsignedInt(..) => const_to_uint(const_get_elt(ccx, val, [0])) as Disr
librustc/middle/trans/common.rs:91:1-91:1 -fn- definition:
pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
/*!
* Identifies types which we declare to be equivalent to `void`
references:- 6librustc/middle/trans/base.rs:
1226: if !return_type_is_void(fcx.ccx, substd_output_type) {
1227: // If the function returns nil/bot, there is no real return
librustc/middle/trans/foreign.rs:
840: let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs.as_slice());
841: let ret_def = !return_type_is_void(ccx, fn_sig.output);
842: let fn_ty = cabi::compute_abi_info(ccx,
librustc/middle/trans/intrinsic.rs:
367: let retty = *substs.tys.get(0);
368: if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
369: unsafe {
--
401: if !return_type_is_void(ccx, out_type) {
402: let llsrcval = get_param(decl, first_real_arg);
librustc/middle/trans/type_of.rs:
64: // Use the output as the actual return value if it's immediate.
65: if use_out_pointer || return_type_is_void(cx, output) {
66: Type::func(atys.as_slice(), &Type::void(cx))
librustc/middle/trans/common.rs:855:1-855:1 -fn- definition:
pub fn langcall(bcx: &Block,
span: Option<Span>,
msg: &str,
references:- 8librustc/middle/trans/_match.rs:
1231: -> Result<'a> {
1232: let did = langcall(cx, None,
1233: format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
--
1254: Store(cx, rhs, scratch_rhs);
1255: let did = langcall(cx, None,
1256: format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
librustc/middle/trans/tvec.rs:
250: "");
251: let alloc_fn = langcall(bcx,
252: Some(lit.span),
librustc/middle/trans/cleanup.rs:
665: // The exception handling personality function.
666: let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem);
667: let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, ExprId(0));
librustc/middle/trans/controlflow.rs:
374: let args = vec!(filename, line, index, len);
375: let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
376: let bcx = callee::trans_lang_call(bcx,
librustc/middle/trans/glue.rs:
56: callee::trans_lang_call(cx,
57: langcall(cx, None, "", ExchangeFreeFnLangItem),
58: [PointerCast(cx, v, Type::i8p(cx.ccx()))],
librustc/middle/trans/controlflow.rs:
356: let args = vec!(v_str, v_filename, C_int(ccx, v_line));
357: let did = langcall(bcx, Some(sp), "", FailFnLangItem);
358: let bcx = callee::trans_lang_call(bcx,
librustc/middle/trans/common.rs:112:1-112:1 -struct- definition:
pub struct tydesc_info {
pub ty: ty::t,
pub tydesc: ValueRef,
references:- 6librustc/middle/trans/glue.rs:
426: debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t));
427: tydesc_info {
428: ty: t,
librustc/middle/trans/context.rs:
65: pub drop_glues: RefCell<HashMap<ty::t, ValueRef>>,
66: pub tydescs: RefCell<HashMap<ty::t, Rc<tydesc_info>>>,
67: /// Set when running emit_tydescs to enforce that no more tydescs are
librustc/middle/trans/base.rs:
395: pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> Rc<tydesc_info> {
396: match ccx.tydescs.borrow().find(&t) {
librustc/middle/trans/glue.rs:
148: pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef {
149: let _icx = push_ctxt("lazily_emit_visit_glue");
--
399: // Generates the declaration for (but doesn't emit) a type descriptor.
400: pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
401: // If emit_tydescs already ran, then we shouldn't be creating any new
librustc/middle/trans/common.rs:740:1-740:1 -fn- definition:
pub fn node_vtables(bcx: &Block, id: typeck::MethodCall)
-> Option<typeck::vtable_res> {
bcx.tcx().vtable_map.borrow().find(&id).map(|vts| {
references:- 2librustc/middle/trans/callee.rs:
173: };
174: let vtables = node_vtables(bcx, vtable_key);
175: debug!("trans_fn_ref(def_id={}, node={:?}, type_params={}, vtables={})",
librustc/middle/trans/meth.rs:
321: let mut vtables = rcvr_origins;
322: match node_vtables(bcx, vtable_key) {
323: Some(vt) => {
librustc/middle/trans/common.rs:528:1-528:1 -fn- definition:
pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
C_integral(Type::i64(ccx), i, false)
}
references:- 2librustc/middle/trans/intrinsic.rs:
346: let val = C_named_struct(type_of::type_of(ccx, output_type),
347: [C_u64(ccx, hash)]);
348: match bcx.fcx.llretptr.get() {
librustc/middle/trans/reflect.rs:
322: let variant_args = [this.c_uint(i),
323: C_u64(ccx, v.disr_val),
324: this.c_uint(v.args.len()),
librustc/middle/trans/common.rs:105:45-105:45 -fn- definition:
/// unique symbols for things like closures.
pub fn gensym_name(name: &str) -> PathElem {
let num = token::gensym(name);
references:- 2librustc/back/link.rs:
726: let path = [PathName(token::intern(s)),
727: gensym_name(name)];
728: let hash = get_symbol_hash(ccx, t);
--
732: pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> ~str {
733: mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
734: }
librustc/middle/trans/common.rs:627:1-627:1 -fn- definition:
pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef {
unsafe {
llvm::LLVMGetParam(fndecl, param as c_uint)
references:- 30librustc/middle/trans/foreign.rs:
librustc/middle/trans/intrinsic.rs:
librustc/middle/trans/common.rs:698:1-698:1 -fn- definition:
pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex))
}
references:- 4librustc/middle/trans/callee.rs:
792: assert!(variadic);
793: expr_ty_adjusted(cx, arg_expr)
794: } else {
librustc/middle/trans/expr.rs:
1066: let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
1067: let e_ty = expr_ty_adjusted(bcx, e);
1068: bcx = trans_into(bcx, e, SaveIn(dest));
librustc/middle/trans/common.rs:378:47-378:47 -struct- definition:
// function are organized as a directed graph.
pub struct Block<'a> {
// The BasicBlockRef returned from a call to
references:- 474librustc/middle/trans/build.rs:
librustc/middle/trans/base.rs:
librustc/middle/trans/_match.rs:
librustc/middle/trans/closure.rs:
librustc/middle/trans/tvec.rs:
librustc/middle/trans/meth.rs:
librustc/middle/trans/foreign.rs:
librustc/middle/trans/intrinsic.rs:
librustc/middle/trans/reflect.rs:
librustc/middle/trans/debuginfo.rs:
librustc/middle/trans/adt.rs:
librustc/middle/trans/asm.rs:
librustc/middle/trans/value.rs:
librustc/middle/trans/cleanup.rs:
librustc/middle/trans/controlflow.rs:
librustc/middle/trans/glue.rs:
librustc/middle/trans/datum.rs:
librustc/middle/trans/callee.rs:
librustc/middle/trans/expr.rs:
librustc/middle/trans/common.rs:536:1-536:1 -fn- definition:
pub fn C_uint(ccx: &CrateContext, i: uint) -> ValueRef {
C_integral(ccx.int_type, i as u64, false)
}
references:- 25578: let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false), Type::i8p(cx).to_ref());
579: C_struct(cx, [cs, C_uint(cx, len)], false)
580: }
--
596: let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
597: C_struct(cx, [cs, C_uint(cx, len)], false)
598: }
librustc/middle/trans/consts.rs:
251: llptr,
252: C_uint(cx, len)
253: ], false);
--
434: let (arr, len) = match ty::get(bt).sty {
435: ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)),
436: ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
--
590: let p = const_ptrcast(cx, gv, llunitty);
591: (C_struct(cx, [p, C_uint(cx, es.len())], false), false)
592: }
librustc/middle/trans/base.rs:
376: let llty = type_of(ccx, box_ptr_ty);
377: let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);
librustc/middle/trans/_match.rs:
1028: let n = slice.unwrap();
1029: let slice_byte_offset = Mul(bcx, vt.llunit_size, C_uint(bcx.ccx(), n));
1030: let slice_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset);
1031: let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
1032: let slice_len = Sub(bcx, len, slice_len_offset);
librustc/middle/trans/tvec.rs:
461: let base = GEPi(bcx, llval, [0u, 0u]);
462: let len = Mul(bcx, C_uint(ccx, vec_length), vt.llunit_size);
463: (base, len)
--
558: let i = Load(inc_bcx, loop_counter);
559: let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1));
560: Store(inc_bcx, plusone, loop_counter);
librustc/middle/trans/foreign.rs:
425: base::call_memcpy(bcx, llretptr_i8, llscratch_i8,
426: C_uint(ccx, llrust_size as uint), llalign as u32);
427: }
librustc/middle/trans/intrinsic.rs:
299: let lltp_ty = type_of::type_of(ccx, tp_ty);
300: Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint));
301: }
--
323: let lltp_ty = type_of::type_of(ccx, tp_ty);
324: Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint));
325: }
librustc/middle/trans/reflect.rs:
59: let scratch = rvalue_scratch_datum(bcx, str_ty, "");
60: let len = C_uint(bcx.ccx(), s.get().len());
61: let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s, false), Type::i8p(bcx.ccx()));
librustc/middle/trans/machine.rs:
73: // constant of the type's alloc size, so let's save it some work.
74: return C_uint(cx, llsize_of_alloc(cx, ty) as uint);
75: }
librustc/middle/trans/tvec.rs:
275: let fill = Mul(bcx, C_uint(ccx, count), unit_sz);
276: let alloc = if count < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
librustc/middle/trans/common.rs:532:1-532:1 -fn- definition:
pub fn C_int(ccx: &CrateContext, i: int) -> ValueRef {
C_integral(ccx.int_type, i as u64, true)
}
references:- 10846: let filename = build::PointerCast(bcx, filename_cstr, Type::i8p(bcx.ccx()));
847: let line = C_int(bcx.ccx(), loc.line as int);
848: (filename, line)
librustc/middle/trans/_match.rs:
329: vec_len(n, vec_len_ge(_), _) => {
330: return lower_bound(Result::new(bcx, C_int(ccx, n as int)));
331: }
--
1634: } else {
1635: C_int(ccx, 0) // Placeholder for when not using a switch
1636: };
librustc/middle/trans/tvec.rs:
601: AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
602: [C_int(bcx.ccx(), 1)]),
603: body_bcx.llbb);
librustc/middle/trans/controlflow.rs:
355: let v_filename = PointerCast(bcx, v_filename, Type::i8p(ccx));
356: let args = vec!(v_str, v_filename, C_int(ccx, v_line));
357: let did = langcall(bcx, Some(sp), "", FailFnLangItem);
librustc/middle/trans/glue.rs:
392: let rc = Load(bcx, rc_ptr);
393: let rc = Add(bcx, rc, C_int(ccx, 1));
394: Store(bcx, rc, rc_ptr);
librustc/middle/trans/tvec.rs:
275: let fill = Mul(bcx, C_uint(ccx, count), unit_sz);
276: let alloc = if count < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
277: else { fill };
librustc/middle/trans/common.rs:520:1-520:1 -fn- definition:
pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
C_integral(Type::i32(ccx), i as u64, true)
}
references:- 10librustc/middle/trans/builder.rs:
546: } else {
547: let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::<Vec<ValueRef>>();
548: self.count_insn("gepi");
--
867: let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref());
868: let vec = self.insert_element(undef, elt, C_i32(self.ccx, 0));
869: let vec_i32_ty = Type::vector(&Type::i32(self.ccx), num_elts as u64);
librustc/middle/trans/base.rs:
1066: let size = machine::llsize_of(ccx, ty);
1067: let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
1068: let volatile = C_i1(ccx, false);
librustc/middle/trans/intrinsic.rs:
164: let lltp_ty = type_of::type_of(ccx, tp_ty);
165: let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
166: let size = machine::llsize_of(ccx, lltp_ty);
librustc/middle/trans/debuginfo.rs:
2286: debug!("setting debug location to {} {}", line, col);
2287: let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32), scope, ptr::null()];
2288: unsafe {
librustc/middle/trans/base.rs:
1021: let size = IntCast(cx, n_bytes, ccx.int_type);
1022: let align = C_i32(ccx, align as i32);
1023: let volatile = C_i1(ccx, false);
librustc/middle/trans/common.rs:540:1-540:1 -fn- definition:
pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
C_integral(Type::i8(ccx), i as u64, false)
}
references:- 2librustc/middle/trans/base.rs:
1064: let llptr = b.pointercast(llptr, Type::i8(ccx).ptr_to());
1065: let llzeroval = C_u8(ccx, 0);
1066: let size = machine::llsize_of(ccx, ty);
librustc/middle/trans/adt.rs:
527: Univariant(..) => {
528: val = C_u8(bcx.ccx(), 0);
529: signed = false;
librustc/middle/trans/common.rs:757:1-757:1 -fn- definition:
pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt,
param_substs: Option<¶m_substs>,
vts: &[typeck::vtable_param_res])
references:- 3752: -> typeck::vtable_res {
753: resolve_vtables_under_param_substs(fcx.ccx.tcx(),
754: fcx.param_substs,
librustc/middle/trans/callee.rs:
213: let mut param_vtables = resolve_vtables_under_param_substs(
214: bcx.tcx(), Some(¶m_substs), impl_res.trait_vtables.as_slice());
librustc/middle/trans/common.rs:
801: trait_id, tys,
802: resolve_vtables_under_param_substs(tcx, param_substs, sub.as_slice()))
803: }
librustc/middle/trans/common.rs:600:1-600:1 -fn- definition:
pub fn C_struct(ccx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
unsafe {
llvm::LLVMConstStructInContext(ccx.llcx,
references:- 14578: let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false), Type::i8p(cx).to_ref());
579: C_struct(cx, [cs, C_uint(cx, len)], false)
580: }
--
596: let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
597: C_struct(cx, [cs, C_uint(cx, len)], false)
598: }
librustc/middle/trans/consts.rs:
590: let p = const_ptrcast(cx, gv, llunitty);
591: (C_struct(cx, [p, C_uint(cx, es.len())], false), false)
592: }
--
606: let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
607: C_struct(cx, vs.as_slice(), false)
608: } else {
librustc/middle/trans/base.rs:
2118: let llmeta = C_bytes(cx, compressed.as_slice());
2119: let llconst = C_struct(cx, [llmeta], false);
2120: let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
librustc/middle/trans/meth.rs:
473: unsafe {
474: let tbl = C_struct(ccx, components.as_slice(), false);
475: let sym = token::gensym("vtable");
librustc/middle/trans/adt.rs:
759: let contents = build_const_struct(ccx, st, vals);
760: C_struct(ccx, contents.as_slice(), st.packed)
761: }
--
773: }).collect::<Vec<ValueRef>>();
774: C_struct(ccx, build_const_struct(ccx,
775: nonnull,
librustc/middle/trans/common.rs:496:1-496:1 -fn- definition:
pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
unsafe {
llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
references:- 26517: pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
518: C_integral(Type::i1(ccx), val as u64, false)
519: }
--
541: pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
542: C_integral(Type::i8(ccx), i as u64, false)
543: }
librustc/middle/trans/consts.rs:
51: ty::ty_int(t) => {
52: C_integral(Type::int_from_ty(cx, t), i as u64, true)
53: }
--
496: let discr = adt::const_get_discrim(cx, &*repr, v);
497: let iv = C_integral(cx.int_type, discr, false);
498: let ety_cast = expr::cast_type_kind(ety);
librustc/middle/trans/base.rs:
827: ty::ty_int(t) => {
828: let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
829: ICmp(cx, lib::llvm::IntEQ, rhs, zero)
--
831: ty::ty_uint(t) => {
832: let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
833: ICmp(cx, lib::llvm::IntEQ, rhs, zero)
librustc/middle/trans/adt.rs:
749: let max_sz = cases.iter().map(|x| x.size).max().unwrap();
750: let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
751: let contents = build_const_struct(ccx,
librustc/middle/trans/common.rs:
537: pub fn C_uint(ccx: &CrateContext, i: uint) -> ValueRef {
538: C_integral(ccx.int_type, i as u64, false)
539: }
librustc/middle/trans/common.rs:633:1-633:1 -fn- definition:
pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
-> ValueRef {
unsafe {
references:- 6librustc/middle/trans/consts.rs:
438: let e1 = const_get_elt(cx, bv, [0]);
439: (const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
440: },
--
464: }
465: (const_get_elt(cx, arr, [iv as c_uint]), inlineable)
466: }
librustc/middle/trans/adt.rs:
906: loop {
907: field = const_get_elt(ccx, val, [real_ix]);
908: if !is_undef(field) {
librustc/middle/trans/consts.rs:
437: ty::ty_vec(_, None) | ty::ty_str => {
438: let e1 = const_get_elt(cx, bv, [0]);
439: (const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
librustc/middle/trans/common.rs:502:1-502:1 -fn- definition:
pub fn C_floating(s: &str, t: Type) -> ValueRef {
unsafe {
s.with_c_str(|buf| llvm::LLVMConstRealOfString(t.to_ref(), buf))
references:- 2librustc/middle/trans/consts.rs:
62: ast::LitFloat(ref fs, t) => {
63: C_floating(fs.get(), Type::float_from_ty(cx, t))
64: }
--
68: ty::ty_float(t) => {
69: C_floating(fs.get(), Type::float_from_ty(cx, t))
70: }
librustc/middle/trans/common.rs:59:1-59:1 -fn- definition:
pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
use middle::trans::machine::llsize_of_alloc;
use middle::trans::type_of::sizing_type_of;
references:- 1353: token::special_idents::unnamed_field.name &&
54: type_is_immediate(ccx, fields.get(0).mt.ty)
55: }
librustc/middle/trans/type_of.rs:
30: pub fn return_uses_outptr(ccx: &CrateContext, ty: ty::t) -> bool {
31: !type_is_immediate(ccx, ty)
32: }
librustc/middle/trans/base.rs:
953: let _icx = push_ctxt("load_if_immediate");
954: if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
955: return v;
librustc/middle/trans/tvec.rs:
495: ty::ty_vec(_, None) | ty::ty_str => {
496: assert!(type_is_immediate(bcx.ccx(), vec_ty));
497: let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
librustc/middle/trans/intrinsic.rs:
106: if type_is_immediate(bcx.ccx(), t) {
107: Ret(bcx, ret);
--
367: let retty = *substs.tys.get(0);
368: if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
369: unsafe {
--
402: let llsrcval = get_param(decl, first_real_arg);
403: if type_is_immediate(ccx, in_type) {
404: match fcx.llretptr.get() {
--
425: }
426: } else if type_is_immediate(ccx, out_type) {
427: let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
librustc/middle/trans/datum.rs:
169: ByValue
170: } else if type_is_immediate(ccx, ty) {
171: ByValue
librustc/middle/trans/callee.rs:
673: use middle::ty::{BrAnon, ReLateBound};
674: if !type_is_immediate(ccx, t) {
675: // if it's not immediate, we have a program-invisible pointer,
librustc/middle/trans/type_of.rs:
26: pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: ty::t) -> bool {
27: !type_is_immediate(ccx, arg_ty)
28: }
librustc/middle/trans/common.rs:614:1-614:1 -fn- definition:
pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
unsafe {
return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
references:- 2librustc/middle/trans/consts.rs:
608: } else {
609: C_array(llunitty, vs.as_slice())
610: };