# code, make sure that these common warnings are denied by default. These can
# be overridden during development temporarily. For stage0, we allow all these
# to suppress warnings which may be bugs in stage0 (should be fixed in stage1+)
-# NOTE: add "-A warnings" after snapshot to WFLAGS_ST0
-WFLAGS_ST0 = -A unrecognized-lint
+WFLAGS_ST0 = -A warnings
WFLAGS_ST1 = -D warnings
WFLAGS_ST2 = -D warnings
if not re.search(r"\bextern mod extra\b", block):
block = "extern mod extra;\n" + block
block = """#[ forbid(ctypes) ];
-#[ forbid(deprecated_pattern) ];
-#[ forbid(implicit_copies) ];
-#[ forbid(non_implicitly_copyable_typarams) ];
#[ forbid(path_statement) ];
#[ forbid(type_limits) ];
#[ forbid(unrecognized_lint) ];
)
_rustc_opts_lint=(
'path-statement[path statements with no effect]'
- 'deprecated-pattern[warn about deprecated uses of pattern bindings]'
- 'non-implicitly-copyable-typarams[passing non implicitly copyable types as copy type params]'
'missing-trait-doc[detects missing documentation for traits]'
'missing-struct-doc[detects missing documentation for structs]'
'ctypes[proper use of core::libc types in foreign modules]'
- 'implicit-copies[implicit copies of non implicitly copyable data]'
"unused-mut[detect mut variables which don't need to be mutable]"
'unused-imports[imports that are never used]'
'heap-memory[use of any (~ type or @ type) heap memory]'
*
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
*/
-#[mutable] // XXX remove after snap
#[no_freeze]
struct RWARC<T> {
priv x: UnsafeAtomicRcBox<RWARCInner<T>>,
use std::uint;
use std::vec;
use std::unstable::intrinsics;
-use std::unstable::intrinsics::{TyDesc};
-
-#[cfg(not(stage0))]
-use std::unstable::intrinsics::{get_tydesc};
-
-#[cfg(stage0)]
-unsafe fn get_tydesc<T>() -> *TyDesc {
- intrinsics::get_tydesc::<T>() as *TyDesc
-}
+use std::unstable::intrinsics::{TyDesc, get_tydesc};
// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
is_pod: bool,
}
-#[mutable] // XXX remove after snap
#[no_freeze]
pub struct Arena {
// The head is separated out from the list as a unbenchmarked
(base + (align - 1)) & !(align - 1)
}
-#[inline]
-#[cfg(not(stage0))]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- // This function should be inlined when stage0 is gone
- ((*tydesc).drop_glue)(data);
-}
-
-#[inline]
-#[cfg(stage0)]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- ((*tydesc).drop_glue)(0 as **TyDesc, data);
-}
-
// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: &Chunk) {
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
// start, size, align, is_done);
if is_done {
- call_drop_glue(tydesc, ptr::offset(buf, start) as *i8);
+ ((*tydesc).drop_glue)(ptr::offset(buf, start) as *i8);
}
// Find where the next tydesc lives
#[allow(missing_doc)];
use std::cast::transmute;
-#[cfg(stage0)]
-use intrinsic::{get_tydesc};
-#[cfg(not(stage0))]
use std::unstable::intrinsics::{get_tydesc};
pub mod rustrt {
- #[cfg(stage0)]
- use intrinsic::{TyDesc};
- #[cfg(not(stage0))]
use std::unstable::intrinsics::{TyDesc};
#[abi = "cdecl"]
}
/// Mutable reference counted pointer type
-#[non_owned]
#[no_send]
-#[mutable] // XXX remove after snap
#[no_freeze]
#[unsafe_no_drop_flag]
pub struct RcMut<T> {
pub type CompletionCb = @fn(~str, @fn(~str));
-#[cfg(not(stage0))]
static complete_key: local_data::Key<@CompletionCb> = &local_data::Key;
-#[cfg(stage0)]
-fn complete_key(_: @CompletionCb) {}
/// Bind to the main completion callback
pub unsafe fn complete(cb: CompletionCb) {
use std::cmp;
-use std::iterator::{Iterator,IteratorUtil,ZipIterator,Counter,EnumerateIterator,FilterMapIterator};
+use std::iterator::{Iterator, IteratorUtil, EnumerateIterator, FilterMapIterator, InvertIterator};
use std::uint;
use std::util::replace;
-use std::vec::{VecIterator,VecMutIterator,VecRevIterator,VecMutRevIterator};
-use std::vec::VecConsumeIterator;
+use std::vec::{VecIterator, VecMutIterator, VecConsumeIterator};
#[allow(missing_doc)]
pub struct SmallIntMap<T> {
/// Iterator element type is (uint, &'r V)
pub fn iter<'r>(&'r self) -> SmallIntMapIterator<'r, V> {
SmallIntMapIterator {
- iter: Counter::new(0,1).zip(self.v.iter())
+ front: 0,
+ back: self.v.len(),
+ iter: self.v.iter()
}
}
/// Iterator element type is (uint, &'r mut V)
pub fn mut_iter<'r>(&'r mut self) -> SmallIntMapMutIterator<'r, V> {
SmallIntMapMutIterator {
- iter: Counter::new(0,1).zip(self.v.mut_iter())
+ front: 0,
+ back: self.v.len(),
+ iter: self.v.mut_iter()
}
}
/// An iterator visiting all key-value pairs in descending order by the keys.
/// Iterator element type is (uint, &'r V)
pub fn rev_iter<'r>(&'r self) -> SmallIntMapRevIterator<'r, V> {
- SmallIntMapRevIterator {
- iter: Counter::new(self.len() as int - 1, -1).zip(self.v.rev_iter())
- }
+ self.iter().invert()
}
/// An iterator visiting all key-value pairs in descending order by the keys,
/// with mutable references to the values
/// Iterator element type is (uint, &'r mut V)
pub fn mut_rev_iter<'r>(&'r mut self) -> SmallIntMapMutRevIterator <'r, V> {
- SmallIntMapMutRevIterator {
- iter: Counter::new(self.len() as int - 1, -1).zip(self.v.mut_rev_iter())
- }
+ self.mut_iter().invert()
}
/// Empties the hash map, moving all values into the specified closure
macro_rules! iterator {
- /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
- (struct $name:ident -> $ptr:ty, $elem:ty) => {
- pub struct $name<'self, T> {
- priv ptr: $ptr,
- priv end: $ptr,
- priv lifetime: $elem // FIXME: #5922
- }
- };*/
- (impl $name:ident -> $elem:ty) => {
- impl<'self, T> Iterator<(uint, $elem)> for $name<'self, T> {
+ (impl $name:ident -> $elem:ty, $getter:ident) => {
+ impl<'self, T> Iterator<$elem> for $name<'self, T> {
#[inline]
- pub fn next(&mut self) -> Option<(uint, $elem)> {
- for self.iter.advance |(idx, elem)| {
- match elem {
- &None => {}
- &Some(ref e) => { return Some((idx as uint, e)) }
+ fn next(&mut self) -> Option<$elem> {
+ while self.front < self.back {
+ match self.iter.next() {
+ Some(elem) => {
+ if elem.is_some() {
+ let index = self.front;
+ self.front += 1;
+ return Some((index, elem. $getter ()));
+ }
+ }
+ _ => ()
}
+ self.front += 1;
}
-
None
}
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (0, Some(self.back - self.front))
+ }
}
}
}
-macro_rules! mut_iterator {
- /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
- (struct $name:ident -> $ptr:ty, $elem:ty) => {
- pub struct $name<'self, T> {
- priv ptr: $ptr,
- priv end: $ptr,
- priv lifetime: $elem // FIXME: #5922
- }
- };*/
- (impl $name:ident -> $elem:ty) => {
- impl<'self, T> Iterator<(uint, $elem)> for $name<'self, T> {
+macro_rules! double_ended_iterator {
+ (impl $name:ident -> $elem:ty, $getter:ident) => {
+ impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
#[inline]
- pub fn next(&mut self) -> Option<(uint, $elem)> {
- for self.iter.advance |(idx, elem)| {
- match elem {
- &None => {}
- &Some(ref mut e) => { return Some((idx as uint, e)) }
+ fn next_back(&mut self) -> Option<$elem> {
+ while self.front < self.back {
+ match self.iter.next_back() {
+ Some(elem) => {
+ if elem.is_some() {
+ self.back -= 1;
+ return Some((self.back, elem. $getter ()));
+ }
+ }
+ _ => ()
}
+ self.back -= 1;
}
-
None
}
}
}
pub struct SmallIntMapIterator<'self, T> {
- priv iter: ZipIterator<int,
- Counter<int>,
- &'self Option<T>,
- VecIterator<'self, Option<T> > >
+ priv front: uint,
+ priv back: uint,
+ priv iter: VecIterator<'self, Option<T>>
}
-iterator!{impl SmallIntMapIterator -> &'self T}
+iterator!(impl SmallIntMapIterator -> (uint, &'self T), get_ref)
+double_ended_iterator!(impl SmallIntMapIterator -> (uint, &'self T), get_ref)
+pub type SmallIntMapRevIterator<'self, T> = InvertIterator<(uint, &'self T),
+ SmallIntMapIterator<'self, T>>;
pub struct SmallIntMapMutIterator<'self, T> {
- priv iter: ZipIterator<int,
- Counter<int>,
- &'self mut Option<T>,
- VecMutIterator<'self, Option<T> > >
+ priv front: uint,
+ priv back: uint,
+ priv iter: VecMutIterator<'self, Option<T>>
}
-mut_iterator!{impl SmallIntMapMutIterator -> &'self mut T}
-
-pub struct SmallIntMapRevIterator<'self, T> {
- priv iter: ZipIterator<int,
- Counter<int>,
- &'self Option<T>,
- VecRevIterator<'self, Option<T> > >
-}
-
-iterator!{impl SmallIntMapRevIterator -> &'self T}
-
-pub struct SmallIntMapMutRevIterator<'self, T> {
- priv iter: ZipIterator<int,
- Counter<int>,
- &'self mut Option<T>,
- VecMutRevIterator<'self, Option<T> > >
-}
+iterator!(impl SmallIntMapMutIterator -> (uint, &'self mut T), get_mut_ref)
+double_ended_iterator!(impl SmallIntMapMutIterator -> (uint, &'self mut T), get_mut_ref)
+pub type SmallIntMapMutRevIterator<'self, T> = InvertIterator<(uint, &'self mut T),
+ SmallIntMapMutIterator<'self, T>>;
-mut_iterator!{impl SmallIntMapMutRevIterator -> &'self mut T}
/// A set implemented on top of the SmallIntMap type. This set is always a set
/// of integers, and the space requirements are on the order of the highest
/// An iterator visiting all set members in descending order.
/// Iterator element type is uint
pub fn rev_iter<'r>(&'r mut self) -> SmallIntSetRevIterator<'r> {
- SmallIntSetRevIterator {
- iter: self.map.rev_iter()
- }
+ self.iter().invert()
}
}
priv iter: SmallIntMapIterator<'self, ()>
}
-pub struct SmallIntSetRevIterator<'self> {
- priv iter: SmallIntMapRevIterator<'self,()>
-}
-
impl<'self> Iterator<uint> for SmallIntSetIterator<'self> {
#[inline]
- pub fn next(&mut self) -> Option<uint> {
+ fn next(&mut self) -> Option<uint> {
let next_opt = self.iter.next();
match next_opt {
None => { None }
Some((idx, _)) => { Some(idx) }
}
}
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.iter.size_hint()
+ }
}
-impl<'self> Iterator<uint> for SmallIntSetRevIterator<'self> {
+impl<'self> DoubleEndedIterator<uint> for SmallIntSetIterator<'self> {
#[inline]
- pub fn next(&mut self) -> Option<uint> {
- let next_opt = self.iter.next();
+ fn next_back(&mut self) -> Option<uint> {
+ let next_opt = self.iter.next_back();
match next_opt {
None => { None }
Some((idx, _)) => { Some(idx) }
}
}
+pub type SmallIntSetRevIterator<'self> = InvertIterator<uint, SmallIntSetIterator<'self>>;
#[cfg(test)]
-mod tests {
+mod test_map {
use super::SmallIntMap;
#[test]
fn test_iterator() {
- let mut a = SmallIntMap::new();
+ let mut m = SmallIntMap::new();
- assert!(a.insert(0,1));
- assert!(a.insert(1,2));
- assert!(a.insert(2,5));
- assert!(a.insert(3,10));
- assert!(a.insert(4,11));
+ assert!(m.insert(0, 1));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
- let mut it = a.iter();
+ let mut it = m.iter();
+ assert_eq!(it.size_hint(), (0, Some(11)));
assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.size_hint(), (0, Some(10)));
assert_eq!(it.next().unwrap(), (1, &2));
- assert_eq!(it.next().unwrap(), (2, &5));
- assert_eq!(it.next().unwrap(), (3, &10));
- assert_eq!(it.next().unwrap(), (4, &11));
+ assert_eq!(it.size_hint(), (0, Some(9)));
+ assert_eq!(it.next().unwrap(), (3, &5));
+ assert_eq!(it.size_hint(), (0, Some(7)));
+ assert_eq!(it.next().unwrap(), (6, &10));
+ assert_eq!(it.size_hint(), (0, Some(4)));
+ assert_eq!(it.next().unwrap(), (10, &11));
+ assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
+ #[test]
+ fn test_iterator_size_hints() {
+ let mut m = SmallIntMap::new();
+
+ assert!(m.insert(0, 1));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ assert_eq!(m.iter().size_hint(), (0, Some(11)));
+ assert_eq!(m.rev_iter().size_hint(), (0, Some(11)));
+ assert_eq!(m.mut_iter().size_hint(), (0, Some(11)));
+ assert_eq!(m.mut_rev_iter().size_hint(), (0, Some(11)));
+ }
+
#[test]
fn test_mut_iterator() {
- let mut a = SmallIntMap::new();
+ let mut m = SmallIntMap::new();
- assert!(a.insert(0,1));
- assert!(a.insert(1,1));
- assert!(a.insert(2,1));
- assert!(a.insert(3,1));
- assert!(a.insert(4,1));
+ assert!(m.insert(0, 1));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
- for a.mut_iter().advance |(_,v)| {
- *v += 1;
+ for m.mut_iter().advance |(k, v)| {
+ *v += k as int;
}
- assert!(a.iter().all(|(_,v)| *v == 2));
+ let mut it = m.iter();
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.next().unwrap(), (1, &3));
+ assert_eq!(it.next().unwrap(), (3, &8));
+ assert_eq!(it.next().unwrap(), (6, &16));
+ assert_eq!(it.next().unwrap(), (10, &21));
+ assert!(it.next().is_none());
}
#[test]
fn test_rev_iterator() {
- let mut a = SmallIntMap::new();
-
- assert!(a.insert(0,1));
- assert!(a.insert(1,2));
- assert!(a.insert(2,5));
- assert!(a.insert(3,10));
- assert!(a.insert(4,11));
-
- let mut b = SmallIntMap::new();
-
- assert!(b.insert(0,11));
- assert!(b.insert(1,10));
- assert!(b.insert(2,5));
- assert!(b.insert(3,2));
- assert!(b.insert(4,1));
+ let mut m = SmallIntMap::new();
- let (a_it, b_it) = (a.iter(), b.rev_iter());
+ assert!(m.insert(0, 1));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
- assert!(a_it.zip(b_it).all(|( (_ ,v1), (_, v2) )| *v1 == *v2));
+ let mut it = m.rev_iter();
+ assert_eq!(it.next().unwrap(), (10, &11));
+ assert_eq!(it.next().unwrap(), (6, &10));
+ assert_eq!(it.next().unwrap(), (3, &5));
+ assert_eq!(it.next().unwrap(), (1, &2));
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert!(it.next().is_none());
}
#[test]
fn test_mut_rev_iterator() {
- let mut a = SmallIntMap::new();
+ let mut m = SmallIntMap::new();
- assert!(a.insert(0,5));
- assert!(a.insert(1,4));
- assert!(a.insert(2,3));
- assert!(a.insert(3,2));
- assert!(a.insert(4,1));
+ assert!(m.insert(0, 1));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
- for a.mut_rev_iter().advance |(i,v)| {
- *v += i as int;
+ for m.mut_rev_iter().advance |(k, v)| {
+ *v += k as int;
}
- assert!(a.iter().all(|(_,v)| *v == 5 ));
+ let mut it = m.iter();
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.next().unwrap(), (1, &3));
+ assert_eq!(it.next().unwrap(), (3, &8));
+ assert_eq!(it.next().unwrap(), (6, &16));
+ assert_eq!(it.next().unwrap(), (10, &21));
+ assert!(it.next().is_none());
}
#[test]
assert!(a.insert(0));
assert!(a.insert(1));
- assert!(a.insert(2));
assert!(a.insert(3));
- assert!(a.insert(4));
+ assert!(a.insert(6));
+ assert!(a.insert(10));
let mut it = a.iter();
+ assert_eq!(it.size_hint(), (0, Some(11)));
assert_eq!(it.next().unwrap(), 0);
+ assert_eq!(it.size_hint(), (0, Some(10)));
assert_eq!(it.next().unwrap(), 1);
- assert_eq!(it.next().unwrap(), 2);
+ assert_eq!(it.size_hint(), (0, Some(9)));
assert_eq!(it.next().unwrap(), 3);
- assert_eq!(it.next().unwrap(), 4);
+ assert_eq!(it.size_hint(), (0, Some(7)));
+ assert_eq!(it.next().unwrap(), 6);
+ assert_eq!(it.size_hint(), (0, Some(4)));
+ assert_eq!(it.next().unwrap(), 10);
+ assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
+ #[test]
+ fn test_iterator_size_hints() {
+ let mut a = SmallIntSet::new();
+
+ assert!(a.insert(0));
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(6));
+ assert!(a.insert(10));
+
+ assert_eq!(a.iter().size_hint(), (0, Some(11)));
+ assert_eq!(a.rev_iter().size_hint(), (0, Some(11)));
+ }
+
#[test]
fn test_rev_iterator() {
let mut a = SmallIntSet::new();
assert!(a.insert(0));
assert!(a.insert(1));
- assert!(a.insert(2));
assert!(a.insert(3));
- assert!(a.insert(4));
+ assert!(a.insert(6));
+ assert!(a.insert(10));
- let a_it = a.rev_iter();
-
- assert!(do a_it.enumerate().all |( i, v2 )| {
- i + v2 == 4
- });
+ let mut it = a.rev_iter();
+ assert_eq!(it.next().unwrap(), 10);
+ assert_eq!(it.next().unwrap(), 6);
+ assert_eq!(it.next().unwrap(), 3);
+ assert_eq!(it.next().unwrap(), 1);
+ assert_eq!(it.next().unwrap(), 0);
+ assert!(it.next().is_none());
}
}
use metadata::cstore;
use std::cast;
- #[cfg(not(stage0))]
use std::local_data;
use std::unstable::intrinsics;
// The stage1 compiler won't work, but that doesn't really matter. TLS
// changed only very recently to allow storage of owned values.
- #[cfg(not(stage0))]
static engine_key: local_data::Key<~Engine> = &local_data::Key;
- #[cfg(not(stage0))]
fn set_engine(engine: ~Engine) {
local_data::set(engine_key, engine)
}
- #[cfg(stage0)]
- fn set_engine(_: ~Engine) {}
- #[cfg(not(stage0))]
pub fn consume_engine() -> Option<~Engine> {
local_data::pop(engine_key)
}
- #[cfg(stage0)]
- pub fn consume_engine() -> Option<~Engine> { None }
}
pub mod write {
*/
pub fn build_link_meta(sess: Session,
- c: &ast::crate,
+ c: &ast::Crate,
output: &Path,
symbol_hasher: &mut hash::State)
-> LinkMeta {
cmh_items: ~[@ast::MetaItem]
}
- fn provided_link_metas(sess: Session, c: &ast::crate) ->
+ fn provided_link_metas(sess: Session, c: &ast::Crate) ->
ProvidedMetas {
let mut name = None;
let mut vers = None;
let mut cmh_items = ~[];
- let linkage_metas = attr::find_linkage_metas(c.node.attrs);
+ let linkage_metas = attr::find_linkage_metas(c.attrs);
attr::require_unique_names(sess.diagnostic(), linkage_metas);
for linkage_metas.iter().advance |meta| {
match meta.name_str_pair() {
}
pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
- ast::crate_cfg {
+ ast::CrateConfig {
let (libc, tos) = match sess.targ_cfg.os {
session::os_win32 => (@"msvcrt.dll", @"win32"),
session::os_macos => (@"libc.dylib", @"macos"),
mk(@"build_input", source_name(input))];
}
-pub fn append_configuration(cfg: &mut ast::crate_cfg, name: @str) {
+pub fn append_configuration(cfg: &mut ast::CrateConfig, name: @str) {
if !cfg.iter().any(|mi| mi.name() == name) {
cfg.push(attr::mk_word_item(name))
}
}
pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
- ast::crate_cfg {
+ ast::CrateConfig {
// Combine the configuration requested by the session (command line) with
// some default and generated configuration items
let default_cfg = default_configuration(sess, argv0, input);
// Convert strings provided as --cfg [cfgspec] into a crate_cfg
fn parse_cfgspecs(cfgspecs: ~[~str],
- demitter: diagnostic::Emitter) -> ast::crate_cfg {
+ demitter: diagnostic::Emitter) -> ast::CrateConfig {
do cfgspecs.consume_iter().transform |s| {
let sess = parse::new_parse_sess(Some(demitter));
parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess)
- }.collect::<ast::crate_cfg>()
+ }.collect::<ast::CrateConfig>()
}
pub enum input {
str_input(@str)
}
-pub fn parse_input(sess: Session, cfg: ast::crate_cfg, input: &input)
- -> @ast::crate {
+pub fn parse_input(sess: Session, cfg: ast::CrateConfig, input: &input)
+ -> @ast::Crate {
match *input {
file_input(ref file) => {
parse::parse_crate_from_file(&(*file), cfg, sess.parse_sess)
#[fixed_stack_segment]
pub fn compile_rest(sess: Session,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
phases: compile_upto,
outputs: Option<@OutputFilenames>,
- curr: Option<@ast::crate>)
- -> (Option<@ast::crate>, Option<ty::ctxt>) {
+ curr: Option<@ast::Crate>)
+ -> (Option<@ast::Crate>, Option<ty::ctxt>) {
let time_passes = sess.time_passes();
}
pub fn compile_upto(sess: Session,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
input: &input,
upto: compile_phase,
outputs: Option<@OutputFilenames>)
- -> (Option<@ast::crate>, Option<ty::ctxt>) {
+ -> (Option<@ast::Crate>, Option<ty::ctxt>) {
let time_passes = sess.time_passes();
let crate = time(time_passes,
~"parsing",
Some(crate))
}
-pub fn compile_input(sess: Session, cfg: ast::crate_cfg, input: &input,
+pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
outdir: &Option<Path>, output: &Option<Path>) {
let upto = if sess.opts.parse_only { cu_parse }
else if sess.opts.no_trans { cu_no_trans }
compile_upto(sess, cfg, input, upto, Some(outputs));
}
-pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input,
+pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
ppm: pp_mode) {
fn ann_paren_for_expr(node: pprust::ann_node) {
match node {
// items to the crate config, and during parsing the entire crate config
// will be added to the crate AST node. This should not be used for
// anything except building the full crate config prior to parsing.
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
binary: @str,
test: bool,
parse_only: bool,
}
pub fn building_library(req_crate_type: crate_type,
- crate: &ast::crate,
+ crate: &ast::Crate,
testing: bool) -> bool {
match req_crate_type {
bin_crate => false,
false
} else {
match syntax::attr::first_attr_value_str_by_name(
- crate.node.attrs,
+ crate.attrs,
"crate_type") {
Some(s) => "lib" == s,
_ => false
attr::mk_attr(attr::mk_name_value_item_str(@"crate_type", t))
}
- fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate {
+ fn make_crate(with_bin: bool, with_lib: bool) -> @ast::Crate {
let mut attrs = ~[];
if with_bin {
attrs.push(make_crate_type_attr(@"bin"));
if with_lib {
attrs.push(make_crate_type_attr(@"lib"));
}
- @codemap::respan(codemap::dummy_sp(), ast::crate_ {
+ @ast::Crate {
module: ast::_mod { view_items: ~[], items: ~[] },
attrs: attrs,
- config: ~[]
- })
+ config: ~[],
+ span: codemap::dummy_sp(),
+ }
}
#[test]
// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
-pub fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
+pub fn strip_unconfigured_items(crate: @ast::Crate) -> @ast::Crate {
do strip_items(crate) |attrs| {
- in_cfg(crate.node.config, attrs)
+ in_cfg(crate.config, attrs)
}
}
-pub fn strip_items(crate: &ast::crate, in_cfg: in_cfg_pred)
- -> @ast::crate {
+pub fn strip_items(crate: &ast::Crate, in_cfg: in_cfg_pred)
+ -> @ast::Crate {
let ctxt = @Context { in_cfg: in_cfg };
fn fold_block(
cx: @Context,
- b: &ast::blk,
+ b: &ast::Block,
fld: @fold::ast_fold
-) -> ast::blk {
+) -> ast::Block {
let resulting_stmts = do b.stmts.iter().filter_map |a| {
filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt))
}.collect();
let filtered_view_items = do b.view_items.iter().filter_map |a| {
filter_view_item(cx, a).map(|&x| fld.fold_view_item(x))
}.collect();
- ast::blk {
+ ast::Block {
view_items: filtered_view_items,
stmts: resulting_stmts,
expr: b.expr.map(|x| fld.fold_expr(*x)),
static STD_VERSION: &'static str = "0.8-pre";
-pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate)
- -> @ast::crate {
+pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::Crate)
+ -> @ast::Crate {
if use_std(crate) {
inject_libstd_ref(sess, crate)
} else {
}
}
-fn use_std(crate: &ast::crate) -> bool {
- !attr::contains_name(crate.node.attrs, "no_std")
+fn use_std(crate: &ast::Crate) -> bool {
+ !attr::contains_name(crate.attrs, "no_std")
}
+
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
attr::contains_name(attrs, "no_implicit_prelude")
}
-fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
+fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
fn spanned<T>(x: T) -> codemap::spanned<T> {
codemap::spanned { node: x, span: dummy_sp() }
}
let precursor = @fold::AstFoldFns {
- fold_crate: |crate, span, fld| {
+ fold_crate: |crate, fld| {
let n1 = sess.next_node_id();
let vi1 = ast::view_item {
node: ast::view_item_extern_mod(
}
// FIXME #2543: Bad copy.
- let new_crate = ast::crate_ {
+ ast::Crate {
module: new_module,
..(*crate).clone()
- };
- (new_crate, span)
+ }
},
fold_item: |item, fld| {
if !no_prelude(item.attrs) {
struct TestCtxt {
sess: session::Session,
- crate: @ast::crate,
+ crate: @ast::Crate,
path: ~[ast::ident],
ext_cx: @ExtCtxt,
testfns: ~[Test]
// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
pub fn modify_for_testing(sess: session::Session,
- crate: @ast::crate)
- -> @ast::crate {
+ crate: @ast::Crate)
+ -> @ast::Crate {
// We generate the test harness when building in the 'test'
// configuration, either with the '--test' or '--cfg test'
// command line options.
- let should_test = attr::contains_name(crate.node.config, "test");
+ let should_test = attr::contains_name(crate.config, "test");
if should_test {
generate_test_harness(sess, crate)
}
fn generate_test_harness(sess: session::Session,
- crate: @ast::crate)
- -> @ast::crate {
+ crate: @ast::Crate)
+ -> @ast::Crate {
let cx: @mut TestCtxt = @mut TestCtxt {
sess: sess,
crate: crate,
});
let precursor = @fold::AstFoldFns {
- fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ),
+ fold_crate: |a,b| fold_crate(cx, a, b),
fold_item: |a,b| fold_item(cx, a, b),
fold_mod: |a,b| fold_mod(cx, a, b),.. *fold::default_ast_fold()};
return res;
}
-fn strip_test_functions(crate: &ast::crate) -> @ast::crate {
+fn strip_test_functions(crate: &ast::Crate) -> @ast::Crate {
// When not compiling with --test we should not compile the
// #[test] functions
do config::strip_items(crate) |attrs| {
fold::noop_fold_mod(&mod_nomain, fld)
}
-fn fold_crate(cx: @mut TestCtxt, c: &ast::crate_, fld: @fold::ast_fold)
- -> ast::crate_ {
+fn fold_crate(cx: @mut TestCtxt, c: &ast::Crate, fld: @fold::ast_fold)
+ -> ast::Crate {
let folded = fold::noop_fold_crate(c, fld);
// Add a special __test module to the crate that will contain code
// generated for the test harness
- ast::crate_ {
+ ast::Crate {
module: add_test_module(cx, &folded.module),
.. folded
}
do i.attrs.iter().any |attr| {
// check ignore(cfg(foo, bar))
"ignore" == attr.name() && match attr.meta_item_list() {
- Some(ref cfgs) => attr::test_cfg(cx.crate.node.config, cfgs.iter().transform(|x| *x)),
+ Some(ref cfgs) => attr::test_cfg(cx.crate.config, cfgs.iter().transform(|x| *x)),
None => true
}
}
}
fn is_extra(cx: &TestCtxt) -> bool {
- let items = attr::find_linkage_metas(cx.crate.node.attrs);
+ let items = attr::find_linkage_metas(cx.crate.attrs);
match attr::last_meta_item_value_str_by_name(items, "name") {
Some(s) if "extra" == s => true,
_ => false
pub unsafe fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+ #[fast_ffi]
+ pub unsafe fn LLVMInstructionEraseFromParent(Inst: ValueRef);
/* Operations on call sites */
#[fast_ffi]
// Traverses an AST, reading all the information about use'd crates and extern
// libraries necessary for later resolving, typechecking, linking, etc.
pub fn read_crates(diag: @span_handler,
- crate: &ast::crate,
+ crate: &ast::Crate,
cstore: @mut cstore::CStore,
filesearch: @FileSearch,
os: loader::os,
os: loader::os,
statik: bool,
crate_cache: @mut ~[cache_entry],
- next_crate_num: ast::crate_num,
+ next_crate_num: ast::CrateNum,
intr: @ident_interner
}
-fn visit_crate(e: &Env, c: &ast::crate) {
+fn visit_crate(e: &Env, c: &ast::Crate) {
let cstore = e.cstore;
- for c.node.attrs.iter().filter(|m| "link_args" == m.name()).advance |a| {
+ for c.attrs.iter().filter(|m| "link_args" == m.name()).advance |a| {
match a.value_str() {
Some(ref linkarg) => {
cstore::add_used_link_args(cstore, *linkarg);
metas: ~[@ast::MetaItem],
hash: @str,
span: span)
- -> ast::crate_num {
+ -> ast::CrateNum {
let metas = metas_with_ident(token::ident_to_str(&ident), metas);
match existing_match(e, metas, hash) {
/// Iterates over all the language items in the given crate.
pub fn each_lang_item(cstore: @mut cstore::CStore,
- cnum: ast::crate_num,
+ cnum: ast::CrateNum,
f: &fn(ast::node_id, uint) -> bool) -> bool {
let crate_data = cstore::get_crate_data(cstore, cnum);
decoder::each_lang_item(crate_data, f)
/// Iterates over all the paths in the given crate.
pub fn each_path(cstore: @mut cstore::CStore,
- cnum: ast::crate_num,
+ cnum: ast::CrateNum,
f: &fn(&str, decoder::def_like, ast::visibility) -> bool)
-> bool {
let crate_data = cstore::get_crate_data(cstore, cnum);
}
pub fn get_link_args_for_crate(cstore: @mut cstore::CStore,
- crate_num: ast::crate_num)
+ crate_num: ast::CrateNum)
-> ~[~str] {
let cdata = cstore::get_crate_data(cstore, crate_num);
decoder::get_link_args_for_crate(cdata)
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
-pub type cnum_map = @mut HashMap<ast::crate_num, ast::crate_num>;
+pub type cnum_map = @mut HashMap<ast::CrateNum, ast::CrateNum>;
pub struct crate_metadata {
name: @str,
data: @~[u8],
cnum_map: cnum_map,
- cnum: ast::crate_num
+ cnum: ast::CrateNum
}
pub struct CStore {
- priv metas: HashMap <ast::crate_num, @crate_metadata>,
+ priv metas: HashMap <ast::CrateNum, @crate_metadata>,
priv extern_mod_crate_map: extern_mod_crate_map,
priv used_crate_files: ~[Path],
priv used_libraries: ~[@str],
}
// Map from node_id's of local extern mod statements to crate numbers
-type extern_mod_crate_map = HashMap<ast::node_id, ast::crate_num>;
+type extern_mod_crate_map = HashMap<ast::node_id, ast::CrateNum>;
pub fn mk_cstore(intr: @ident_interner) -> CStore {
return CStore {
};
}
-pub fn get_crate_data(cstore: &CStore, cnum: ast::crate_num)
+pub fn get_crate_data(cstore: &CStore, cnum: ast::CrateNum)
-> @crate_metadata {
return *cstore.metas.get(&cnum);
}
-pub fn get_crate_hash(cstore: &CStore, cnum: ast::crate_num) -> @str {
+pub fn get_crate_hash(cstore: &CStore, cnum: ast::CrateNum) -> @str {
let cdata = get_crate_data(cstore, cnum);
decoder::get_crate_hash(cdata.data)
}
-pub fn get_crate_vers(cstore: &CStore, cnum: ast::crate_num) -> @str {
+pub fn get_crate_vers(cstore: &CStore, cnum: ast::CrateNum) -> @str {
let cdata = get_crate_data(cstore, cnum);
decoder::get_crate_vers(cdata.data)
}
pub fn set_crate_data(cstore: &mut CStore,
- cnum: ast::crate_num,
+ cnum: ast::CrateNum,
data: @crate_metadata) {
cstore.metas.insert(cnum, data);
}
-pub fn have_crate_data(cstore: &CStore, cnum: ast::crate_num) -> bool {
+pub fn have_crate_data(cstore: &CStore, cnum: ast::CrateNum) -> bool {
cstore.metas.contains_key(&cnum)
}
pub fn iter_crate_data(cstore: &CStore,
- i: &fn(ast::crate_num, @crate_metadata)) {
+ i: &fn(ast::CrateNum, @crate_metadata)) {
for cstore.metas.iter().advance |(&k, &v)| {
i(k, v);
}
pub fn add_extern_mod_stmt_cnum(cstore: &mut CStore,
emod_id: ast::node_id,
- cnum: ast::crate_num) {
+ cnum: ast::CrateNum) {
cstore.extern_mod_crate_map.insert(emod_id, cnum);
}
pub fn find_extern_mod_stmt_cnum(cstore: &CStore,
emod_id: ast::node_id)
- -> Option<ast::crate_num> {
+ -> Option<ast::CrateNum> {
cstore.extern_mod_crate_map.find(&emod_id).map_consume(|x| *x)
}
None
}
-pub type GetCrateDataCb<'self> = &'self fn(ast::crate_num) -> cmd;
+pub type GetCrateDataCb<'self> = &'self fn(ast::CrateNum) -> cmd;
pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
fn eq_item(bytes: &[u8], item_id: int) -> bool {
None
}
-fn item_reqd_and_translated_parent_item(cnum: ast::crate_num,
+fn item_reqd_and_translated_parent_item(cnum: ast::CrateNum,
d: ebml::Doc) -> ast::def_id {
let trait_did = item_parent_item(d).expect("item without parent");
ast::def_id { crate: cnum, node: trait_did.node }
}
}
-fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
+fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::CrateNum)
-> def_like {
let fam = item_family(item);
match fam {
}
}
-pub fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
+pub fn lookup_def(cnum: ast::CrateNum, data: @~[u8], did_: ast::def_id) ->
ast::def {
let item = lookup_item(did_.node, data);
let did = ast::def_id { crate: cnum, node: did_.node };
#[deriving(Clone)]
pub struct crate_dep {
- cnum: ast::crate_num,
+ cnum: ast::CrateNum,
name: ast::ident,
vers: @str,
hash: @str
fn encode_info_for_items(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
- crate: &crate)
+ crate: &Crate)
-> ~[entry<int>] {
let index = @mut ~[];
ebml_w.start_tag(tag_items_data);
index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() });
encode_info_for_mod(ecx,
ebml_w,
- &crate.node.module,
+ &crate.module,
crate_node_id,
[],
syntax::parse::token::special_idents::invalid,
// 'name' and 'vers' items, so if the user didn't provide them we will throw
// them in anyway with default values.
fn synthesize_crate_attrs(ecx: &EncodeContext,
- crate: &crate) -> ~[Attribute] {
+ crate: &Crate) -> ~[Attribute] {
fn synthesize_link_attr(ecx: &EncodeContext, items: ~[@MetaItem]) ->
Attribute {
let mut attrs = ~[];
let mut found_link_attr = false;
- for crate.node.attrs.iter().advance |attr| {
+ for crate.attrs.iter().advance |attr| {
attrs.push(
if "link" != attr.name() {
*attr
}
fn encode_misc_info(ecx: &EncodeContext,
- crate: &crate,
+ crate: &Crate,
ebml_w: &mut writer::Encoder) {
ebml_w.start_tag(tag_misc_info);
ebml_w.start_tag(tag_misc_info_crate_items);
- for crate.node.module.items.iter().advance |&item| {
+ for crate.module.items.iter().advance |&item| {
ebml_w.start_tag(tag_mod_child);
ebml_w.wr_str(def_to_str(local_def(item.id)));
ebml_w.end_tag();
0x74, //'t' as u8,
0, 0, 0, 1 ];
-pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
+pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
let wr = @io::BytesWriter::new();
let stats = Stats {
inline_bytes: 0,
// nested items, as otherwise it would get confused when translating
// inlined items.
fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
- fn drop_nested_items(blk: &ast::blk, fld: @fold::ast_fold) -> ast::blk {
+ fn drop_nested_items(blk: &ast::Block, fld: @fold::ast_fold) -> ast::Block {
let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| {
match stmt.node {
ast::stmt_expr(_, _) | ast::stmt_semi(_, _) |
ast::stmt_mac(*) => fail!("unexpanded macro in astencode")
}
}.collect();
- let blk_sans_items = ast::blk {
+ let blk_sans_items = ast::Block {
view_items: ~[], // I don't know if we need the view_items here,
// but it doesn't break tests!
stmts: stmts_sans_items,
#[cfg(test)]
trait fake_ext_ctxt {
- fn cfg(&self) -> ast::crate_cfg;
+ fn cfg(&self) -> ast::CrateConfig;
fn parse_sess(&self) -> @mut parse::ParseSess;
fn call_site(&self) -> span;
fn ident_of(&self, st: &str) -> ast::ident;
#[cfg(test)]
impl fake_ext_ctxt for fake_session {
- fn cfg(&self) -> ast::crate_cfg { ~[] }
+ fn cfg(&self) -> ast::CrateConfig { ~[] }
fn parse_sess(&self) -> @mut parse::ParseSess { *self }
fn call_site(&self) -> span {
codemap::span {
dfcx_loans: &LoanDataFlow,
move_data: move_data::FlowedMoveData,
all_loans: &[Loan],
- body: &ast::blk) {
+ body: &ast::Block) {
debug!("check_loans(body id=%?)", body.id);
let clcx = CheckLoanCtxt {
fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
sp: span,
id: ast::node_id,
(this, visitor): (CheckLoanCtxt<'a>,
}
}
-fn check_loans_in_local<'a>(local: @ast::local,
+fn check_loans_in_local<'a>(local: @ast::Local,
(this, vt): (CheckLoanCtxt<'a>,
visit::vt<CheckLoanCtxt<'a>>)) {
visit::visit_local(local, (this, vt));
visit::visit_pat(pat, (this, vt));
}
-fn check_loans_in_block<'a>(blk: &ast::blk,
+fn check_loans_in_block<'a>(blk: &ast::Block,
(this, vt): (CheckLoanCtxt<'a>,
visit::vt<CheckLoanCtxt<'a>>))
{
pub fn gather_loans(bccx: @BorrowckCtxt,
decl: &ast::fn_decl,
- body: &ast::blk)
+ body: &ast::Block)
-> (id_range, @mut ~[Loan], @mut move_data::MoveData) {
let glcx = @mut GatherLoanCtxt {
bccx: bccx,
fn gather_loans_in_fn(fk: &visit::fn_kind,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
sp: span,
id: ast::node_id,
(this, v): (@mut GatherLoanCtxt,
}
}
-fn gather_loans_in_block(blk: &ast::blk,
+fn gather_loans_in_block(blk: &ast::Block,
(this, vt): (@mut GatherLoanCtxt,
visit::vt<@mut GatherLoanCtxt>)) {
this.id_range.add(blk.id);
visit::visit_block(blk, (this, vt));
}
-fn gather_loans_in_local(local: @ast::local,
+fn gather_loans_in_local(local: @ast::Local,
(this, vt): (@mut GatherLoanCtxt,
visit::vt<@mut GatherLoanCtxt>)) {
- match local.node.init {
+ match local.init {
None => {
// Variable declarations without initializers are considered "moves":
let tcx = this.bccx.tcx;
- do pat_util::pat_bindings(tcx.def_map, local.node.pat)
+ do pat_util::pat_bindings(tcx.def_map, local.pat)
|_, id, span, _| {
gather_moves::gather_decl(this.bccx,
this.move_data,
Some(init) => {
// Variable declarations with initializers are considered "assigns":
let tcx = this.bccx.tcx;
- do pat_util::pat_bindings(tcx.def_map, local.node.pat)
+ do pat_util::pat_bindings(tcx.def_map, local.pat)
|_, id, span, _| {
gather_moves::gather_assignment(this.bccx,
this.move_data,
id);
}
let init_cmt = this.bccx.cat_expr(init);
- this.gather_pat(init_cmt, local.node.pat, None);
+ this.gather_pat(init_cmt, local.pat, None);
}
}
fn gather_fn_arg_patterns(&mut self,
decl: &ast::fn_decl,
- body: &ast::blk) {
+ body: &ast::Block) {
/*!
* Walks the patterns for fn arguments, checking that they
* do not attempt illegal moves or create refs that outlive
moves_map: moves::MovesMap,
moved_variables_set: moves::MovedVariablesSet,
capture_map: moves::CaptureMap,
- crate: &ast::crate) -> (root_map, write_guard_map)
+ crate: &ast::Crate) -> (root_map, write_guard_map)
{
let bccx = @BorrowckCtxt {
tcx: tcx,
fn borrowck_fn(fk: &visit::fn_kind,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
sp: span,
id: ast::node_id,
(this, v): (@BorrowckCtxt,
tcx: ty::ctxt,
method_map: typeck::method_map,
id_range: ast_util::id_range,
- body: &ast::blk)
+ body: &ast::Block)
-> FlowedMoveData
{
let mut dfcx_moves =
pub fn construct(tcx: ty::ctxt,
method_map: typeck::method_map,
- blk: &ast::blk) -> CFG {
+ blk: &ast::Block) -> CFG {
let mut cfg_builder = CFGBuilder {
exit_map: HashMap::new(),
graph: graph::Graph::new(),
}
impl CFGBuilder {
- fn block(&mut self, blk: &ast::blk, pred: CFGIndex) -> CFGIndex {
+ fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
let mut stmts_exit = pred;
for blk.stmts.iter().advance |&stmt| {
stmts_exit = self.stmt(stmt, stmts_exit);
fn decl(&mut self, decl: @ast::decl, pred: CFGIndex) -> CFGIndex {
match decl.node {
ast::decl_local(local) => {
- let init_exit = self.opt_expr(local.node.init, pred);
- self.pat(local.node.pat, init_exit)
+ let init_exit = self.opt_expr(local.init, pred);
+ self.pat(local.pat, init_exit)
}
ast::decl_item(_) => {
ast::expr_struct(_, ref fields, base) => {
let base_exit = self.opt_expr(base, pred);
let field_exprs: ~[@ast::expr] =
- fields.iter().transform(|f| f.node.expr).collect();
+ fields.iter().transform(|f| f.expr).collect();
self.straightline(expr, base_exit, field_exprs)
}
impl CFG {
pub fn new(tcx: ty::ctxt,
method_map: typeck::method_map,
- blk: &ast::blk) -> CFG {
+ blk: &ast::Block) -> CFG {
construct::construct(tcx, method_map, blk)
}
}
\ No newline at end of file
use syntax::{visit, ast_util, ast_map};
pub fn check_crate(sess: Session,
- crate: &crate,
+ crate: &Crate,
ast_map: ast_map::map,
def_map: resolve::DefMap,
method_map: typeck::method_map,
can_ret: bool
}
-pub fn check_crate(tcx: ty::ctxt, crate: &crate) {
+pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
visit::visit_crate(crate,
(Context { in_loop: false, can_ret: true },
visit::mk_vt(@visit::Visitor {
pub fn check_crate(tcx: ty::ctxt,
method_map: method_map,
moves_map: moves::MovesMap,
- crate: &crate) {
+ crate: &Crate) {
let cx = @MatchCheckCtxt {tcx: tcx,
method_map: method_map,
moves_map: moves_map};
}
pub fn check_local(cx: &MatchCheckCtxt,
- loc: @local,
+ loc: @Local,
(s, v): ((),
visit::vt<()>)) {
visit::visit_local(loc, (s, v));
- if is_refutable(cx, loc.node.pat) {
- cx.tcx.sess.span_err(loc.node.pat.span,
+ if is_refutable(cx, loc.pat) {
+ cx.tcx.sess.span_err(loc.pat.span,
"refutable pattern in local binding");
}
// Check legality of move bindings.
- check_legality_of_move_bindings(cx, false, [ loc.node.pat ]);
+ check_legality_of_move_bindings(cx, false, [ loc.pat ]);
}
pub fn check_fn(cx: &MatchCheckCtxt,
kind: &visit::fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
sp: span,
id: node_id,
(s, v): ((),
ast::expr_struct(_, ref fs, None) => {
let cs = do fs.iter().transform |f| {
- classify(f.node.expr, tcx)
+ classify(f.expr, tcx)
};
join_all(cs)
}
}
}
-pub fn process_crate(crate: &ast::crate,
+pub fn process_crate(crate: &ast::Crate,
tcx: ty::ctxt) {
let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
visit_expr_post: |e| { classify(e, tcx); },
impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
// ^^^^^^^^^^^^^ only needed for pretty printing
- pub fn propagate(&mut self, blk: &ast::blk) {
+ pub fn propagate(&mut self, blk: &ast::Block) {
//! Performs the data flow analysis.
if self.bits_per_id == 0 {
});
}
- fn pretty_print_to(@self, wr: @io::Writer, blk: &ast::blk) {
+ fn pretty_print_to(@self, wr: @io::Writer, blk: &ast::Block) {
let pre: @fn(pprust::ann_node) = |node| {
let (ps, id) = match node {
pprust::node_expr(ps, expr) => (ps, expr.id),
}
fn walk_block(&mut self,
- blk: &ast::blk,
+ blk: &ast::Block,
in_out: &mut [uint],
loop_scopes: &mut ~[LoopScope]) {
debug!("DataFlowContext::walk_block(blk.id=%?, in_out=%s)",
loop_scopes: &mut ~[LoopScope]) {
match decl.node {
ast::decl_local(local) => {
- self.walk_opt_expr(local.node.init, in_out, loop_scopes);
- self.walk_pat(local.node.pat, in_out, loop_scopes);
+ self.walk_opt_expr(local.init, in_out, loop_scopes);
+ self.walk_pat(local.pat, in_out, loop_scopes);
}
ast::decl_item(_) => {}
ast::expr_struct(_, ref fields, with_expr) => {
for fields.iter().advance |field| {
- self.walk_expr(field.node.expr, in_out, loop_scopes);
+ self.walk_expr(field.expr, in_out, loop_scopes);
}
self.walk_opt_expr(with_expr, in_out, loop_scopes);
}
pub fn check_crate(tcx: ty::ctxt,
method_map: method_map,
- crate: &ast::crate) {
+ crate: &ast::Crate) {
let context = @mut Context {
method_map: method_map,
unsafe_context: SafeContext,
use driver::session;
use driver::session::Session;
use syntax::parse::token::special_idents;
-use syntax::ast::{crate, node_id, item, item_fn};
+use syntax::ast::{Crate, node_id, item, item_fn};
use syntax::attr;
use syntax::codemap::span;
use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item};
type EntryVisitor = vt<@mut EntryContext>;
-pub fn find_entry_point(session: Session, crate: &crate, ast_map: ast_map::map) {
+pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map) {
// FIXME #4404 android JNI hacks
if *session.building_library &&
// Since we want to be able to collect upvars in some arbitrary piece
// of the AST, we take a walker function that we invoke with a visitor
// in order to start the search.
-fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk)
+fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block)
-> freevar_info {
let seen = @mut HashMap::new();
let refs = @mut ~[];
// efficient as it fully recomputes the free variables at every
// node of interest rather than building up the free variables in
// one pass. This could be improved upon if it turns out to matter.
-pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::crate) ->
+pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::Crate) ->
freevar_map {
let freevars = @mut HashMap::new();
let walk_fn: @fn(&visit::fn_kind,
&ast::fn_decl,
- &ast::blk,
+ &ast::Block,
span,
ast::node_id) = |_, _, blk, _, nid| {
let vars = collect_freevars(def_map, blk);
pub fn check_crate(tcx: ty::ctxt,
method_map: typeck::method_map,
- crate: &crate) {
+ crate: &Crate) {
let ctx = Context {
tcx: tcx,
method_map: method_map,
}
}
-fn check_block(block: &blk, (cx, visitor): (Context, visit::vt<Context>)) {
+fn check_block(block: &Block, (cx, visitor): (Context, visit::vt<Context>)) {
visit::visit_block(block, (cx, visitor));
}
fn check_fn(
fk: &visit::fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
sp: span,
fn_id: node_id,
(cx, v): (Context,
use driver::session::Session;
use metadata::csearch::each_lang_item;
use metadata::cstore::iter_crate_data;
-use syntax::ast::{crate, def_id, MetaItem};
+use syntax::ast::{Crate, def_id, MetaItem};
use syntax::ast_util::local_def;
use syntax::attr::AttrMetaMethods;
use syntax::visit::{default_simple_visitor, mk_simple_visitor, SimpleVisitor};
struct LanguageItemCollector<'self> {
items: LanguageItems,
- crate: &'self crate,
+ crate: &'self Crate,
session: Session,
item_refs: HashMap<@str, uint>,
}
impl<'self> LanguageItemCollector<'self> {
- pub fn new<'a>(crate: &'a crate, session: Session)
+ pub fn new<'a>(crate: &'a Crate, session: Session)
-> LanguageItemCollector<'a> {
let mut item_refs = HashMap::new();
}
}
-pub fn collect_language_items(crate: &crate,
+pub fn collect_language_items(crate: &Crate,
session: Session)
-> LanguageItems {
let mut collector = LanguageItemCollector::new(crate, session);
unnecessary_qualification,
while_true,
path_statement,
- implicit_copies,
unrecognized_lint,
- deprecated_pattern,
non_camel_case_types,
non_uppercase_statics,
type_limits,
enum AttributedNode<'self> {
Item(@ast::item),
Method(&'self ast::method),
- Crate(@ast::crate),
+ Crate(@ast::Crate),
}
#[deriving(Eq)]
default: warn
}),
- ("implicit_copies",
- LintSpec {
- lint: implicit_copies,
- desc: "implicit copies of non implicitly copyable data",
- default: warn
- }),
-
- ("deprecated_pattern",
- LintSpec {
- lint: deprecated_pattern,
- desc: "warn about deprecated uses of pattern bindings",
- default: allow
- }),
-
("non_camel_case_types",
LintSpec {
lint: non_camel_case_types,
visit::mk_vt(@visit::Visitor {
visit_local: |l, (cx, vt): (@mut Context, visit::vt<@mut Context>)| {
- if l.node.is_mutbl {
- check_pat(cx, l.node.pat);
+ if l.is_mutbl {
+ check_pat(cx, l.pat);
}
visit::visit_local(l, (cx, vt));
},
})
}
-pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
+pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) {
let cx = @mut Context {
dict: @get_lint_dict(),
curr: SmallIntMap::new(),
cx.add_lint(lint_missing_doc());
// Actually perform the lint checks (iterating the ast)
- do cx.with_lint_attrs(crate.node.attrs) {
+ do cx.with_lint_attrs(crate.attrs) {
cx.process(Crate(crate));
visit::visit_crate(crate, (cx, visit::mk_vt(@visit::Visitor {
pub fn check_crate(tcx: ty::ctxt,
method_map: typeck::method_map,
capture_map: moves::CaptureMap,
- crate: &crate) {
+ crate: &Crate) {
let visitor = visit::mk_vt(@visit::Visitor {
visit_fn: visit_fn,
visit_local: visit_local,
fn visit_fn(fk: &visit::fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
sp: span,
id: node_id,
(this, v): (@mut IrMaps,
lsets.warn_about_unused_args(decl, entry_ln);
}
-fn visit_local(local: @local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
+fn visit_local(local: @Local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
let def_map = this.tcx.def_map;
- do pat_util::pat_bindings(def_map, local.node.pat) |_bm, p_id, sp, path| {
+ do pat_util::pat_bindings(def_map, local.pat) |_bm, p_id, sp, path| {
debug!("adding local variable %d", p_id);
let name = ast_util::path_to_ident(path);
this.add_live_node_for_node(p_id, VarDefNode(sp));
- let kind = match local.node.init {
+ let kind = match local.init {
Some(_) => FromLetWithInitializer,
None => FromLetNoInitializer
};
this.add_variable(Local(LocalInfo {
id: p_id,
ident: name,
- is_mutbl: local.node.is_mutbl,
+ is_mutbl: local.is_mutbl,
kind: kind
}));
}
// _______________________________________________________________________
- pub fn compute(&self, decl: &fn_decl, body: &blk) -> LiveNode {
+ pub fn compute(&self, decl: &fn_decl, body: &Block) -> LiveNode {
// if there is a `break` or `again` at the top level, then it's
// effectively a return---this only occurs in `for` loops,
// where the body is really a closure.
entry_ln
}
- pub fn propagate_through_fn_block(&self, _: &fn_decl, blk: &blk)
+ pub fn propagate_through_fn_block(&self, _: &fn_decl, blk: &Block)
-> LiveNode {
// the fallthrough exit is only for those cases where we do not
// explicitly return:
self.propagate_through_block(blk, self.s.fallthrough_ln)
}
- pub fn propagate_through_block(&self, blk: &blk, succ: LiveNode)
+ pub fn propagate_through_block(&self, blk: &Block, succ: LiveNode)
-> LiveNode {
let succ = self.propagate_through_opt_expr(blk.expr, succ);
do blk.stmts.rev_iter().fold(succ) |succ, stmt| {
}
}
- pub fn propagate_through_local(&self, local: &local, succ: LiveNode)
+ pub fn propagate_through_local(&self, local: &Local, succ: LiveNode)
-> LiveNode {
// Note: we mark the variable as defined regardless of whether
// there is an initializer. Initially I had thought to only mark
// initialization, which is mildly more complex than checking
// once at the func header but otherwise equivalent.
- let succ = self.propagate_through_opt_expr(local.node.init, succ);
- self.define_bindings_in_pat(local.node.pat, succ)
+ let succ = self.propagate_through_opt_expr(local.init, succ);
+ self.define_bindings_in_pat(local.pat, succ)
}
pub fn propagate_through_exprs(&self, exprs: &[@expr], succ: LiveNode)
expr_struct(_, ref fields, with_expr) => {
let succ = self.propagate_through_opt_expr(with_expr, succ);
do fields.rev_iter().fold(succ) |succ, field| {
- self.propagate_through_expr(field.node.expr, succ)
+ self.propagate_through_expr(field.expr, succ)
}
}
pub fn propagate_through_loop(&self,
expr: &expr,
cond: Option<@expr>,
- body: &blk,
+ body: &Block,
succ: LiveNode)
-> LiveNode {
// _______________________________________________________________________
// Checking for error conditions
-fn check_local(local: @local, (this, vt): (@Liveness, vt<@Liveness>)) {
- match local.node.init {
+fn check_local(local: @Local, (this, vt): (@Liveness, vt<@Liveness>)) {
+ match local.init {
Some(_) => {
- this.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
+ this.warn_about_unused_or_dead_vars_in_pat(local.pat);
}
None => {
// should not be live at this point.
debug!("check_local() with no initializer");
- do this.pat_bindings(local.node.pat) |ln, var, sp, id| {
+ do this.pat_bindings(local.pat) |ln, var, sp, id| {
if !this.warn_about_unused(sp, id, ln, var) {
match this.live_on_exit(ln, var) {
None => { /* not live: good */ }
}
fn check_fn(_fk: &visit::fn_kind, _decl: &fn_decl,
- _body: &blk, _sp: span, _id: node_id,
+ _body: &Block, _sp: span, _id: node_id,
(_self, _v): (@Liveness, vt<@Liveness>)) {
// do not check contents of nested fns
}
pub fn compute_moves(tcx: ty::ctxt,
method_map: method_map,
- crate: &crate) -> MoveMaps
+ crate: &Crate) -> MoveMaps
{
let visitor = visit::mk_vt(@visit::Visitor {
visit_fn: compute_modes_for_fn,
///////////////////////////////////////////////////////////////////////////
// Expressions
-fn compute_modes_for_local<'a>(local: @local,
+fn compute_modes_for_local<'a>(local: @Local,
(cx, v): (VisitContext,
vt<VisitContext>)) {
- cx.use_pat(local.node.pat);
- for local.node.init.iter().advance |&init| {
+ cx.use_pat(local.pat);
+ for local.init.iter().advance |&init| {
cx.use_expr(init, Read, v);
}
}
fn compute_modes_for_fn(fk: &visit::fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
span: span,
id: node_id,
(cx, v): (VisitContext,
};
}
- pub fn consume_block(&self, blk: &blk, visitor: vt<VisitContext>) {
+ pub fn consume_block(&self, blk: &Block, visitor: vt<VisitContext>) {
/*!
* Indicates that the value of `blk` will be consumed,
* meaning either copied or moved depending on its type.
expr_struct(_, ref fields, opt_with) => {
for fields.iter().advance |field| {
- self.consume_expr(field.node.expr, visitor);
+ self.consume_expr(field.expr, visitor);
}
for opt_with.iter().advance |with_expr| {
// specified and (2) have a type that
// moves-by-default:
let consume_with = with_fields.iter().any(|tf| {
- !fields.iter().any(|f| f.node.ident == tf.ident) &&
+ !fields.iter().any(|f| f.ident == tf.ident) &&
ty::type_moves_by_default(self.tcx, tf.mt.ty)
});
pub fn check_crate<'mm>(tcx: ty::ctxt,
method_map: &'mm method_map,
- crate: &ast::crate) {
+ crate: &ast::Crate) {
let privileged_items = @mut ~[];
// Adds an item to its scope.
Some(ref entry) => {
debug!("(privacy checking) checking \
impl method");
- check_method(expr.span,
- &entry.origin,
- ident);
+ check_method(expr.span, &entry.origin, ident);
}
}
}
for (*fields).iter().advance |field| {
debug!("(privacy checking) checking \
field in struct literal");
- check_field(expr.span, id,
- field.node.ident);
+ check_field(expr.span, id, field.ident);
}
}
}
checking field in \
struct variant \
literal");
- check_field(expr.span, variant_id,
- field.node.ident);
+ check_field(expr.span, variant_id, field.ident);
}
}
_ => {
for fields.iter().advance |field| {
debug!("(privacy checking) checking \
struct pattern");
- check_field(pattern.span, id,
- field.ident);
+ check_field(pattern.span, id, field.ident);
}
}
}
debug!("(privacy checking) \
checking field in \
struct variant pattern");
- check_field(pattern.span,
- variant_id,
- field.ident);
+ check_field(pattern.span, variant_id, field.ident);
}
}
_ => {
// Step 1: Mark all public symbols, and add all public symbols that might
// be inlined to a worklist.
- fn mark_public_symbols(&self, crate: @crate) {
+ fn mark_public_symbols(&self, crate: @Crate) {
let reachable_symbols = self.reachable_symbols;
let worklist = self.worklist;
let visitor = visit::mk_vt(@Visitor {
pub fn find_reachable(tcx: ty::ctxt,
method_map: typeck::method_map,
- crate: @crate)
+ crate: @Crate)
-> @mut HashSet<node_id> {
// XXX(pcwalton): We only need to mark symbols that are exported. But this
// is more complicated than just looking at whether the symbol is `pub`,
}
}
-fn resolve_block(blk: &ast::blk, (cx, visitor): (Context, visit::vt<Context>)) {
+fn resolve_block(blk: &ast::Block, (cx, visitor): (Context, visit::vt<Context>)) {
// Record the parent of this block.
parent_to_expr(cx, blk.id, blk.span);
visit::visit_expr(expr, (new_cx, visitor));
}
-fn resolve_local(local: @ast::local,
+fn resolve_local(local: @ast::Local,
(cx, visitor) : (Context,
visit::vt<Context>)) {
assert_eq!(cx.var_parent, cx.parent);
- parent_to_expr(cx, local.node.id, local.span);
+ parent_to_expr(cx, local.id, local.span);
visit::visit_local(local, (cx, visitor));
}
fn resolve_fn(fk: &visit::fn_kind,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
sp: span,
id: ast::node_id,
(cx, visitor): (Context,
pub fn resolve_crate(sess: Session,
def_map: resolve::DefMap,
- crate: &ast::crate) -> @mut RegionMaps
+ crate: &ast::Crate) -> @mut RegionMaps
{
let region_maps = @mut RegionMaps {
scope_map: HashMap::new(),
fn determine_rp_in_fn(fk: &visit::fn_kind,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
_: span,
_: ast::node_id,
(cx, visitor): (@mut DetermineRpCtxt,
pub fn determine_rp_in_crate(sess: Session,
ast_map: ast_map::map,
def_map: resolve::DefMap,
- crate: &ast::crate)
+ crate: &ast::Crate)
-> region_paramd_items {
let cx = @mut DetermineRpCtxt {
sess: sess,
pub fn Resolver(session: Session,
lang_items: LanguageItems,
- crate: @crate)
+ crate: @Crate)
-> Resolver {
let graph_root = @mut NameBindings();
pub struct Resolver {
session: @Session,
lang_items: LanguageItems,
- crate: @crate,
+ crate: @Crate,
intr: @ident_interner,
}
}
- pub fn block_needs_anonymous_module(@mut self, block: &blk) -> bool {
+ pub fn block_needs_anonymous_module(@mut self, block: &Block) -> bool {
// If the block has view items, we need an anonymous module.
if block.view_items.len() > 0 {
return true;
}
pub fn build_reduced_graph_for_block(@mut self,
- block: &blk,
+ block: &Block,
(parent, visitor):
(ReducedGraphParent,
vt<ReducedGraphParent>)) {
rib_kind: RibKind,
optional_declaration: Option<&fn_decl>,
type_parameters: TypeParameters,
- block: &blk,
+ block: &Block,
self_binding: SelfBinding,
visitor: ResolveVisitor) {
// Create a value rib for the function.
visit_mod(module_, span, id, ((), visitor));
}
- pub fn resolve_local(@mut self, local: @local, visitor: ResolveVisitor) {
- let mutability = if local.node.is_mutbl {Mutable} else {Immutable};
+ pub fn resolve_local(@mut self, local: @Local, visitor: ResolveVisitor) {
+ let mutability = if local.is_mutbl {Mutable} else {Immutable};
// Resolve the type.
- self.resolve_type(&local.node.ty, visitor);
+ self.resolve_type(&local.ty, visitor);
// Resolve the initializer, if necessary.
- match local.node.init {
+ match local.init {
None => {
// Nothing to do.
}
}
// Resolve the pattern.
- self.resolve_pattern(local.node.pat, LocalIrrefutableMode, mutability,
+ self.resolve_pattern(local.pat, LocalIrrefutableMode, mutability,
None, visitor);
}
self.value_ribs.pop();
}
- pub fn resolve_block(@mut self, block: &blk, visitor: ResolveVisitor) {
+ pub fn resolve_block(@mut self, block: &Block, visitor: ResolveVisitor) {
debug!("(resolving block) entering block");
self.value_ribs.push(@Rib(NormalRibKind));
i -= 1;
match this.type_ribs[i].kind {
MethodRibKind(node_id, _) =>
- for this.crate.node.module.items.iter().advance |item| {
+ for this.crate.module.items.iter().advance |item| {
if item.id == node_id {
match item.node {
item_struct(class_def, _) => {
/// Entry point to crate resolution.
pub fn resolve_crate(session: Session,
lang_items: LanguageItems,
- crate: @crate)
+ crate: @Crate)
-> CrateMap {
let resolver = @mut Resolver(session, lang_items, crate);
resolver.resolve();
use middle::trans::adt;
use middle::trans::base;
use middle::trans::build::*;
+use middle::trans::builder::{Builder, noname};
use middle::trans::callee;
use middle::trans::common::*;
use middle::trans::consts;
pub use middle::trans::context::task_llcx;
-#[cfg(not(stage0))]
static task_local_insn_key: local_data::Key<@~[&'static str]> = &local_data::Key;
-#[cfg(stage0)]
-fn task_local_insn_key(_: @~[&'static str]) {}
pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
let opt = local_data::get(task_local_insn_key, |k| k.map(|&k| *k));
Call(bcx, ccx.upcalls.trace, args);
}
-pub fn ignore_lhs(_bcx: block, local: &ast::local) -> bool {
- match local.node.pat.node {
+pub fn ignore_lhs(_bcx: block, local: &ast::Local) -> bool {
+ match local.pat.node {
ast::pat_wild => true, _ => false
}
}
-pub fn init_local(bcx: block, local: &ast::local) -> block {
+pub fn init_local(bcx: block, local: &ast::Local) -> block {
debug!("init_local(bcx=%s, local.id=%?)",
- bcx.to_str(), local.node.id);
+ bcx.to_str(), local.id);
let _indenter = indenter();
let _icx = push_ctxt("init_local");
if ignore_lhs(bcx, local) {
// Handle let _ = e; just like e;
- match local.node.init {
+ match local.init {
Some(init) => {
return expr::trans_into(bcx, init, expr::Ignore);
}
}
}
- _match::store_local(bcx, local.node.pat, local.node.init)
+ _match::store_local(bcx, local.pat, local.init)
}
pub fn trans_stmt(cx: block, s: &ast::stmt) -> block {
DatumBlock {bcx: leave_block(bcx, scope_cx), datum: datum}
}
-pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) {
+pub fn block_locals(b: &ast::Block, it: &fn(@ast::Local)) {
for b.stmts.iter().advance |s| {
match s.node {
ast::stmt_decl(d, _) => {
}
pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
+ if cx.unreachable { return; }
let _icx = push_ctxt("zero_mem");
let bcx = cx;
let ccx = cx.ccx();
let llty = type_of::type_of(ccx, t);
- memzero(bcx, llptr, llty);
+ memzero(&B(bcx), llptr, llty);
}
// Always use this function instead of storing a zero constant to the memory
// allocation for large data structures, and the generated code will be
// awful. (A telltale sign of this is large quantities of
// `mov [byte ptr foo],0` in the generated code.)
-pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
+pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
let _icx = push_ctxt("memzero");
- let ccx = cx.ccx();
+ let ccx = b.ccx;
let intrinsic_key = match ccx.sess.targ_cfg.arch {
X86 | Arm | Mips => "llvm.memset.p0i8.i32",
};
let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key);
- let llptr = PointerCast(cx, llptr, Type::i8().ptr_to());
+ let llptr = b.pointercast(llptr, Type::i8().ptr_to());
let llzeroval = C_u8(0);
- let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type);
+ let size = machine::llsize_of(ccx, ty);
let align = C_i32(llalign_of_min(ccx, ty) as i32);
let volatile = C_i1(false);
- Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
+ b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
}
pub fn alloc_ty(bcx: block, t: ty::t, name: &str) -> ValueRef {
return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
}
}
- let initcx = base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas());
- let p = Alloca(initcx, ty, name);
- if zero { memzero(initcx, p, ty); }
+ let p = Alloca(cx, ty, name);
+ if zero {
+ let b = cx.fcx.ccx.builder();
+ b.position_before(cx.fcx.alloca_insert_pt.get());
+ memzero(&b, p, ty);
+ }
p
}
return llvm::LLVMGetUndef(ty.to_ref());
}
}
- return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas()), ty, v);
+ return ArrayAlloca(cx, ty, v);
}
pub struct BasicBlocks {
llvm::LLVMGetParam(fcx.llfn, 0)
} else {
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
- alloca(raw_block(fcx, false, fcx.get_llstaticallocas()), lloutputtype,
- "__make_return_pointer")
+ let bcx = fcx.entry_bcx.get();
+ Alloca(bcx, lloutputtype, "__make_return_pointer")
}
}
}
output_type: ty::t,
skip_retptr: bool,
param_substs: Option<@param_substs>,
+ opt_node_info: Option<NodeInfo>,
sp: Option<span>)
-> fn_ctxt {
for param_substs.iter().advance |p| { p.validate(); }
llvm::LLVMGetUndef(Type::i8p().to_ref())
},
llretptr: None,
- llstaticallocas: None,
- llloadenv: None,
+ entry_bcx: None,
+ alloca_insert_pt: None,
llreturn: None,
llself: None,
personality: None,
fcx.llenv = unsafe {
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
};
+
+ unsafe {
+ let entry_bcx = top_scope_block(fcx, opt_node_info);
+ Load(entry_bcx, C_null(Type::i8p()));
+
+ fcx.entry_bcx = Some(entry_bcx);
+ fcx.alloca_insert_pt = Some(llvm::LLVMGetFirstInstruction(entry_bcx.llbb));
+ }
+
if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) {
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
}
output_type: ty::t,
sp: Option<span>)
-> fn_ctxt {
- new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp)
+ new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp)
}
// NB: must keep 4 fns in sync:
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
// and builds the return block.
-pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
+pub fn finish_fn(fcx: fn_ctxt, last_bcx: block) {
let _icx = push_ctxt("finish_fn");
- tie_up_header_blocks(fcx, lltop);
let ret_cx = match fcx.llreturn {
Some(llreturn) => {
None => last_bcx
};
build_return_block(fcx, ret_cx);
+ fcx.cleanup();
}
// Builds the return block for a function.
}
}
-pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) {
- let _icx = push_ctxt("tie_up_header_blocks");
- let llnext = match fcx.llloadenv {
- Some(ll) => {
- unsafe {
- llvm::LLVMMoveBasicBlockBefore(ll, lltop);
- }
- Br(raw_block(fcx, false, ll), lltop);
- ll
- }
- None => lltop
- };
- match fcx.llstaticallocas {
- Some(ll) => {
- unsafe {
- llvm::LLVMMoveBasicBlockBefore(ll, llnext);
- }
- Br(raw_block(fcx, false, ll), llnext);
- }
- None => ()
- }
-}
-
pub enum self_arg { impl_self(ty::t, ty::SelfMode), no_self, }
// trans_closure: Builds an LLVM function out of a source function.
pub fn trans_closure(ccx: @mut CrateContext,
path: path,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
llfndecl: ValueRef,
self_arg: self_arg,
param_substs: Option<@param_substs>,
output_type,
false,
param_substs,
+ body.info(),
Some(body.span));
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
// Create the first basic block in the function and keep a handle on it to
// pass to finish_fn later.
- let bcx_top = top_scope_block(fcx, body.info());
+ let bcx_top = fcx.entry_bcx.get();
let mut bcx = bcx_top;
- let lltop = bcx.llbb;
let block_ty = node_id_type(bcx, body.id);
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
}
// Insert the mandatory first few basic blocks before lltop.
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
}
// trans_fn: creates an LLVM function corresponding to a source language
pub fn trans_fn(ccx: @mut CrateContext,
path: path,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
llfndecl: ValueRef,
self_arg: self_arg,
param_substs: Option<@param_substs>,
result_ty,
false,
param_substs,
+ None,
None);
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
+ let bcx = fcx.entry_bcx.get();
let arg_tys = ty::ty_fn_args(ctor_ty);
insert_synthetic_type_entries(bcx, fn_args, arg_tys);
let arg_ty = arg_tys[i];
memcpy_ty(bcx, lldestptr, llarg, arg_ty);
}
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
}
pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
// be updated if this assertion starts to fail.
assert!(fcx.has_immediate_return_value);
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
-
+ let bcx = fcx.entry_bcx.get();
// Call main.
let llenvarg = unsafe {
let env_arg = fcx.env_arg_pos();
let args = ~[llenvarg];
Call(bcx, main_llfn, args);
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
return llfdecl;
}
}
}
-pub fn trans_constants(ccx: @mut CrateContext, crate: &ast::crate) {
+pub fn trans_constants(ccx: @mut CrateContext, crate: &ast::Crate) {
visit::visit_crate(
crate, ((),
visit::mk_simple_visitor(@visit::SimpleVisitor {
}
}
-pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
+pub fn write_metadata(cx: &mut CrateContext, crate: &ast::Crate) {
if !*cx.sess.building_library { return; }
let encode_inlined_item: encoder::encode_inlined_item =
}
pub fn trans_crate(sess: session::Session,
- crate: &ast::crate,
+ crate: &ast::Crate,
tcx: ty::ctxt,
output: &Path,
emap2: resolve::ExportMap2,
{
let _icx = push_ctxt("text");
- trans_mod(ccx, &crate.node.module);
+ trans_mod(ccx, &crate.module);
}
decl_gc_metadata(ccx, llmod_id);
use lib::llvm::llvm;
use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
-use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
-use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
+use lib::llvm::{Opcode, IntPredicate, RealPredicate};
+use lib::llvm::{ValueRef, BasicBlockRef};
use lib;
use middle::trans::common::*;
-use middle::trans::machine::llalign_of_min;
use syntax::codemap::span;
-use middle::trans::base;
+use middle::trans::builder::Builder;
use middle::trans::type_::Type;
use std::cast;
use std::libc::{c_uint, c_ulonglong, c_char};
-use std::hashmap::HashMap;
-use std::str;
-use std::vec;
pub fn terminate(cx: block, _: &str) {
cx.terminated = true;
}
}
-pub fn B(cx: block) -> BuilderRef {
- unsafe {
- let b = cx.fcx.ccx.builder.B;
- llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
- return b;
- }
-}
-
-pub fn count_insn(cx: block, category: &str) {
- if cx.ccx().sess.trans_stats() {
- cx.ccx().stats.n_llvm_insns += 1;
- }
- do base::with_insn_ctxt |v| {
- let h = &mut cx.ccx().stats.llvm_insns;
-
- // Build version of path with cycles removed.
-
- // Pass 1: scan table mapping str -> rightmost pos.
- let mut mm = HashMap::new();
- let len = v.len();
- let mut i = 0u;
- while i < len {
- mm.insert(v[i], i);
- i += 1u;
- }
-
- // Pass 2: concat strings for each elt, skipping
- // forwards over any cycles by advancing to rightmost
- // occurrence of each element in path.
- let mut s = ~".";
- i = 0u;
- while i < len {
- i = *mm.get(&v[i]);
- s.push_char('/');
- s.push_str(v[i]);
- i += 1u;
- }
-
- s.push_char('/');
- s.push_str(category);
-
- let n = match h.find(&s) {
- Some(&n) => n,
- _ => 0u
- };
- h.insert(s, n+1u);
- }
+pub fn B(cx: block) -> Builder {
+ let b = cx.fcx.ccx.builder();
+ b.position_at_end(cx.llbb);
+ b
}
-
// The difference between a block being unreachable and being terminated is
// somewhat obscure, and has to do with error checking. When a block is
// terminated, we're saying that trying to add any further statements in the
// further instructions to the block should simply be ignored.
pub fn RetVoid(cx: block) {
- unsafe {
- if cx.unreachable { return; }
- check_not_terminated(cx);
- terminate(cx, "RetVoid");
- count_insn(cx, "retvoid");
- llvm::LLVMBuildRetVoid(B(cx));
- }
+ if cx.unreachable { return; }
+ check_not_terminated(cx);
+ terminate(cx, "RetVoid");
+ B(cx).ret_void();
}
pub fn Ret(cx: block, V: ValueRef) {
- unsafe {
- if cx.unreachable { return; }
- check_not_terminated(cx);
- terminate(cx, "Ret");
- count_insn(cx, "ret");
- llvm::LLVMBuildRet(B(cx), V);
- }
+ if cx.unreachable { return; }
+ check_not_terminated(cx);
+ terminate(cx, "Ret");
+ B(cx).ret(V);
}
pub fn AggregateRet(cx: block, RetVals: &[ValueRef]) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "AggregateRet");
- unsafe {
- llvm::LLVMBuildAggregateRet(B(cx), vec::raw::to_ptr(RetVals),
- RetVals.len() as c_uint);
- }
+ B(cx).aggregate_ret(RetVals);
}
pub fn Br(cx: block, Dest: BasicBlockRef) {
- unsafe {
- if cx.unreachable { return; }
- check_not_terminated(cx);
- terminate(cx, "Br");
- count_insn(cx, "br");
- llvm::LLVMBuildBr(B(cx), Dest);
- }
+ if cx.unreachable { return; }
+ check_not_terminated(cx);
+ terminate(cx, "Br");
+ B(cx).br(Dest);
}
pub fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
Else: BasicBlockRef) {
- unsafe {
- if cx.unreachable { return; }
- check_not_terminated(cx);
- terminate(cx, "CondBr");
- count_insn(cx, "condbr");
- llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
- }
+ if cx.unreachable { return; }
+ check_not_terminated(cx);
+ terminate(cx, "CondBr");
+ B(cx).cond_br(If, Then, Else);
}
pub fn Switch(cx: block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
-> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- check_not_terminated(cx);
- terminate(cx, "Switch");
- return llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases as c_uint);
- }
+ if cx.unreachable { return _Undef(V); }
+ check_not_terminated(cx);
+ terminate(cx, "Switch");
+ B(cx).switch(V, Else, NumCases)
}
pub fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
}
pub fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
- unsafe {
- if cx.unreachable { return; }
- check_not_terminated(cx);
- terminate(cx, "IndirectBr");
- count_insn(cx, "indirectbr");
- llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
- }
-}
-
-// This is a really awful way to get a zero-length c-string, but better (and a
-// lot more efficient) than doing str::as_c_str("", ...) every time.
-pub fn noname() -> *c_char {
- unsafe {
- static cnull: uint = 0u;
- return cast::transmute(&cnull);
- }
+ if cx.unreachable { return; }
+ check_not_terminated(cx);
+ terminate(cx, "IndirectBr");
+ B(cx).indirect_br(Addr, NumDests);
}
pub fn Invoke(cx: block,
debug!("Invoke(%s with arguments (%s))",
cx.val_to_str(Fn),
Args.map(|a| cx.val_to_str(*a)).connect(", "));
- unsafe {
- count_insn(cx, "invoke");
- llvm::LLVMBuildInvoke(B(cx),
- Fn,
- vec::raw::to_ptr(Args),
- Args.len() as c_uint,
- Then,
- Catch,
- noname())
- }
+ B(cx).invoke(Fn, Args, Then, Catch)
}
pub fn FastInvoke(cx: block, Fn: ValueRef, Args: &[ValueRef],
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "FastInvoke");
- unsafe {
- count_insn(cx, "fastinvoke");
- let v = llvm::LLVMBuildInvoke(B(cx), Fn, vec::raw::to_ptr(Args),
- Args.len() as c_uint,
- Then, Catch, noname());
- lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv);
- }
+ B(cx).fast_invoke(Fn, Args, Then, Catch);
}
pub fn Unreachable(cx: block) {
- unsafe {
- if cx.unreachable { return; }
- cx.unreachable = true;
- if !cx.terminated {
- count_insn(cx, "unreachable");
- llvm::LLVMBuildUnreachable(B(cx));
- }
+ if cx.unreachable { return; }
+ cx.unreachable = true;
+ if !cx.terminated {
+ B(cx).unreachable();
}
}
/* Arithmetic */
pub fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "add");
- return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).add(LHS, RHS)
}
pub fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nswadd");
- return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nswadd(LHS, RHS)
}
pub fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nuwadd");
- return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nuwadd(LHS, RHS)
}
pub fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "fadd");
- return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).fadd(LHS, RHS)
}
pub fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "sub");
- return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).sub(LHS, RHS)
}
pub fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nwsub");
- return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nswsub(LHS, RHS)
}
pub fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nuwsub");
- return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nuwsub(LHS, RHS)
}
pub fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "sub");
- return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).fsub(LHS, RHS)
}
pub fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "mul");
- return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).mul(LHS, RHS)
}
pub fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nswmul");
- return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nswmul(LHS, RHS)
}
pub fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "nuwmul");
- return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).nuwmul(LHS, RHS)
}
pub fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "fmul");
- return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).fmul(LHS, RHS)
}
pub fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "udiv");
- return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).udiv(LHS, RHS)
}
pub fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "sdiv");
- return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).sdiv(LHS, RHS)
}
pub fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "extractsdiv");
- return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).exactsdiv(LHS, RHS)
}
pub fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "fdiv");
- return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).fdiv(LHS, RHS)
}
pub fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "urem");
- return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).urem(LHS, RHS)
}
pub fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "srem");
- return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).srem(LHS, RHS)
}
pub fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "frem");
- return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).frem(LHS, RHS)
}
pub fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "shl");
- return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).shl(LHS, RHS)
}
pub fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "lshr");
- return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).lshr(LHS, RHS)
}
pub fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "ashr");
- return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).ashr(LHS, RHS)
}
pub fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "and");
- return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).and(LHS, RHS)
}
pub fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "or");
- return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).or(LHS, RHS)
}
pub fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "xor");
- return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).xor(LHS, RHS)
}
pub fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(LHS); }
- count_insn(cx, "binop");
- return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
- }
+ if cx.unreachable { return _Undef(LHS); }
+ B(cx).binop(Op, LHS, RHS)
}
pub fn Neg(cx: block, V: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- count_insn(cx, "neg");
- return llvm::LLVMBuildNeg(B(cx), V, noname());
- }
+ if cx.unreachable { return _Undef(V); }
+ B(cx).neg(V)
}
pub fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- count_insn(cx, "nswneg");
- return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
- }
+ if cx.unreachable { return _Undef(V); }
+ B(cx).nswneg(V)
}
pub fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- count_insn(cx, "nuwneg");
- return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
- }
+ if cx.unreachable { return _Undef(V); }
+ B(cx).nuwneg(V)
}
pub fn FNeg(cx: block, V: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- count_insn(cx, "fneg");
- return llvm::LLVMBuildFNeg(B(cx), V, noname());
- }
+ if cx.unreachable { return _Undef(V); }
+ B(cx).fneg(V)
}
pub fn Not(cx: block, V: ValueRef) -> ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(V); }
- count_insn(cx, "not");
- return llvm::LLVMBuildNot(B(cx), V, noname());
- }
+ if cx.unreachable { return _Undef(V); }
+ B(cx).not(V)
}
/* Memory */
pub fn Malloc(cx: block, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
- count_insn(cx, "malloc");
- return llvm::LLVMBuildMalloc(B(cx), Ty.to_ref(), noname());
+ B(cx).malloc(Ty)
}
}
pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
- count_insn(cx, "arraymalloc");
- return llvm::LLVMBuildArrayMalloc(B(cx), Ty.to_ref(), Val, noname());
+ B(cx).array_malloc(Ty, Val)
}
}
pub fn Alloca(cx: block, Ty: Type, name: &str) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
- count_insn(cx, "alloca");
- if name.is_empty() {
- llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname())
- } else {
- str::as_c_str(
- name,
- |c| llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), c))
- }
+ let b = cx.fcx.ccx.builder();
+ b.position_before(cx.fcx.alloca_insert_pt.get());
+ b.alloca(Ty, name)
}
}
pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
- count_insn(cx, "arrayalloca");
- return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname());
+ let b = cx.fcx.ccx.builder();
+ b.position_before(cx.fcx.alloca_insert_pt.get());
+ b.array_alloca(Ty, Val)
}
}
pub fn Free(cx: block, PointerVal: ValueRef) {
- unsafe {
- if cx.unreachable { return; }
- count_insn(cx, "free");
- llvm::LLVMBuildFree(B(cx), PointerVal);
- }
+ if cx.unreachable { return; }
+ B(cx).free(PointerVal)
}
pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
};
return llvm::LLVMGetUndef(eltty.to_ref());
}
- count_insn(cx, "load");
- return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
+ B(cx).load(PointerVal)
}
}
if cx.unreachable {
return llvm::LLVMGetUndef(ccx.int_type.to_ref());
}
- count_insn(cx, "load.atomic");
- let align = llalign_of_min(ccx, ccx.int_type);
- return llvm::LLVMBuildAtomicLoad(B(cx), PointerVal, noname(), order, align as c_uint);
+ B(cx).atomic_load(PointerVal, order)
}
}
pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
- let value = Load(cx, PointerVal);
-
- if !cx.unreachable {
+ if cx.unreachable {
+ let ccx = cx.fcx.ccx;
+ let ty = val_ty(PointerVal);
+ let eltty = if ty.kind() == lib::llvm::Array {
+ ty.element_type()
+ } else {
+ ccx.int_type
+ };
unsafe {
- let t = llvm::LLVMGetElementType(llvm::LLVMTypeOf(PointerVal));
- let min = llvm::LLVMConstInt(t, lo, signed);
- let max = llvm::LLVMConstInt(t, hi, signed);
-
- do [min, max].as_imm_buf |ptr, len| {
- llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
- llvm::LLVMMDNodeInContext(cx.fcx.ccx.llcx,
- ptr, len as c_uint));
- }
+ llvm::LLVMGetUndef(eltty.to_ref())
}
+ } else {
+ B(cx).load_range_assert(PointerVal, lo, hi, signed)
}
-
- value
}
pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
- unsafe {
- if cx.unreachable { return; }
- debug!("Store %s -> %s",
- cx.val_to_str(Val),
- cx.val_to_str(Ptr));
- count_insn(cx, "store");
- llvm::LLVMBuildStore(B(cx), Val, Ptr);
- }
+ if cx.unreachable { return; }
+ B(cx).store(Val, Ptr)
}
pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrdering) {
- unsafe {
- if cx.unreachable { return; }
- debug!("Store %s -> %s",
- cx.val_to_str(Val),
- cx.val_to_str(Ptr));
- count_insn(cx, "store.atomic");
- let align = llalign_of_min(cx.ccx(), cx.ccx().int_type);
- llvm::LLVMBuildAtomicStore(B(cx), Val, Ptr, order, align as c_uint);
- }
+ if cx.unreachable { return; }
+ B(cx).atomic_store(Val, Ptr, order)
}
pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
- count_insn(cx, "gep");
- return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices),
- Indices.len() as c_uint, noname());
+ B(cx).gep(Pointer, Indices)
}
}
// in C_i32()
#[inline]
pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef {
- // Small vector optimization. This should catch 100% of the cases that
- // we care about.
- if ixs.len() < 16 {
- let mut small_vec = [ C_i32(0), ..16 ];
- for small_vec.mut_iter().zip(ixs.iter()).advance |(small_vec_e, &ix)| {
- *small_vec_e = C_i32(ix as i32);
- }
- InBoundsGEP(cx, base, small_vec.slice(0, ixs.len()))
- } else {
- let v = do ixs.iter().transform |i| { C_i32(*i as i32) }.collect::<~[ValueRef]>();
- count_insn(cx, "gepi");
- InBoundsGEP(cx, base, v)
+ unsafe {
+ if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
+ B(cx).gepi(base, ixs)
}
}
pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
- count_insn(cx, "inboundsgep");
- return llvm::LLVMBuildInBoundsGEP(
- B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname());
+ B(cx).inbounds_gep(Pointer, Indices)
}
}
pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
- count_insn(cx, "structgep");
- return llvm::LLVMBuildStructGEP(B(cx),
- Pointer,
- Idx as c_uint,
- noname());
+ B(cx).struct_gep(Pointer, Idx)
}
}
pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
- count_insn(cx, "globalstring");
- return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
+ B(cx).global_string(_Str)
}
}
pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
- count_insn(cx, "globalstringptr");
- return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
+ B(cx).global_string_ptr(_Str)
}
}
pub fn Trunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "trunc");
- return llvm::LLVMBuildTrunc(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).trunc(Val, DestTy)
}
}
pub fn ZExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "zext");
- return llvm::LLVMBuildZExt(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).zext(Val, DestTy)
}
}
pub fn SExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "sext");
- return llvm::LLVMBuildSExt(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).sext(Val, DestTy)
}
}
pub fn FPToUI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "fptoui");
- return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).fptoui(Val, DestTy)
}
}
pub fn FPToSI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "fptosi");
- return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy.to_ref(),noname());
+ B(cx).fptosi(Val, DestTy)
}
}
pub fn UIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "uitofp");
- return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).uitofp(Val, DestTy)
}
}
pub fn SIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "sitofp");
- return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).sitofp(Val, DestTy)
}
}
pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "fptrunc");
- return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).fptrunc(Val, DestTy)
}
}
pub fn FPExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "fpext");
- return llvm::LLVMBuildFPExt(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).fpext(Val, DestTy)
}
}
pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "ptrtoint");
- return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).ptrtoint(Val, DestTy)
}
}
pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "inttoptr");
- return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).inttoptr(Val, DestTy)
}
}
pub fn BitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "bitcast");
- return llvm::LLVMBuildBitCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).bitcast(Val, DestTy)
}
}
pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "zextorbitcast");
- return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).zext_or_bitcast(Val, DestTy)
}
}
pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "sextorbitcast");
- return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).sext_or_bitcast(Val, DestTy)
}
}
pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "truncorbitcast");
- return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).trunc_or_bitcast(Val, DestTy)
}
}
pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8)
-> ValueRef {
unsafe {
- count_insn(cx, "cast");
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy.to_ref(), noname());
+ B(cx).cast(Op, Val, DestTy)
}
}
pub fn PointerCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "pointercast");
- return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).pointercast(Val, DestTy)
}
}
pub fn IntCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "intcast");
- return llvm::LLVMBuildIntCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).intcast(Val, DestTy)
}
}
pub fn FPCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
- count_insn(cx, "fpcast");
- return llvm::LLVMBuildFPCast(B(cx), Val, DestTy.to_ref(), noname());
+ B(cx).fpcast(Val, DestTy)
}
}
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
- count_insn(cx, "icmp");
- return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
+ B(cx).icmp(Op, LHS, RHS)
}
}
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
- count_insn(cx, "fcmp");
- return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
+ B(cx).fcmp(Op, LHS, RHS)
}
}
pub fn EmptyPhi(cx: block, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
- count_insn(cx, "emptyphi");
- return llvm::LLVMBuildPhi(B(cx), Ty.to_ref(), noname());
+ B(cx).empty_phi(Ty)
}
}
-pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef])
- -> ValueRef {
+pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
- assert_eq!(vals.len(), bbs.len());
- let phi = EmptyPhi(cx, Ty);
- count_insn(cx, "addincoming");
- llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals),
- vec::raw::to_ptr(bbs),
- vals.len() as c_uint);
- return phi;
+ B(cx).phi(Ty, vals, bbs)
}
}
} else {
ccx.int_type
};
- count_insn(cx, "ret_undef");
- return llvm::LLVMGetUndef(retty.to_ref());
+ B(cx).count_insn("ret_undef");
+ llvm::LLVMGetUndef(retty.to_ref())
}
}
-pub fn add_span_comment(bcx: block, sp: span, text: &str) {
- let ccx = bcx.ccx();
- if ccx.sess.asm_comments() {
- let s = fmt!("%s (%s)", text, ccx.sess.codemap.span_to_str(sp));
- debug!("%s", s);
- add_comment(bcx, s);
- }
+pub fn add_span_comment(cx: block, sp: span, text: &str) {
+ B(cx).add_span_comment(sp, text)
}
-pub fn add_comment(bcx: block, text: &str) {
- unsafe {
- let ccx = bcx.ccx();
- if ccx.sess.asm_comments() {
- let sanitized = text.replace("$", "");
- let comment_text = ~"# " +
- sanitized.replace("\n", "\n\t# ");
- count_insn(bcx, "inlineasm");
- let asm = do comment_text.as_c_str |c| {
- llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
- c, noname(), False, False)
- };
- Call(bcx, asm, []);
- }
- }
+pub fn add_comment(cx: block, text: &str) {
+ B(cx).add_comment(text)
}
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
inputs: &[ValueRef], output: Type,
volatile: bool, alignstack: bool,
dia: AsmDialect) -> ValueRef {
- unsafe {
- count_insn(cx, "inlineasm");
-
- let volatile = if volatile { lib::llvm::True }
- else { lib::llvm::False };
- let alignstack = if alignstack { lib::llvm::True }
- else { lib::llvm::False };
-
- let argtys = do inputs.map |v| {
- debug!("Asm Input Type: %?", cx.val_to_str(*v));
- val_ty(*v)
- };
-
- debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output));
- let fty = Type::func(argtys, &output);
- let v = llvm::LLVMInlineAsm(fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
-
- Call(cx, v, inputs)
- }
+ B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia)
}
pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
- unsafe {
- count_insn(cx, "call");
-
- debug!("Call(Fn=%s, Args=%?)",
- cx.val_to_str(Fn),
- Args.map(|arg| cx.val_to_str(*arg)));
-
- do Args.as_imm_buf |ptr, len| {
- llvm::LLVMBuildCall(B(cx), Fn, ptr, len as c_uint, noname())
- }
- }
+ B(cx).call(Fn, Args)
}
pub fn FastCall(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
- unsafe {
- count_insn(cx, "fastcall");
- let v = llvm::LLVMBuildCall(B(cx), Fn, vec::raw::to_ptr(Args),
- Args.len() as c_uint, noname());
- lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv);
- return v;
- }
+ B(cx).call(Fn, Args)
}
pub fn CallWithConv(cx: block, Fn: ValueRef, Args: &[ValueRef],
Conv: CallConv) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
- unsafe {
- count_insn(cx, "callwithconv");
- let v = llvm::LLVMBuildCall(B(cx), Fn, vec::raw::to_ptr(Args),
- Args.len() as c_uint, noname());
- lib::llvm::SetInstructionCallConv(v, Conv);
- return v;
- }
+ B(cx).call_with_conv(Fn, Args, Conv)
}
-pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
- ValueRef {
- unsafe {
- if cx.unreachable { return _Undef(Then); }
- count_insn(cx, "select");
- return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
- }
+pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef {
+ if cx.unreachable { return _Undef(Then); }
+ B(cx).select(If, Then, Else)
}
pub fn VAArg(cx: block, list: ValueRef, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
- count_insn(cx, "vaarg");
- return llvm::LLVMBuildVAArg(B(cx), list, Ty.to_ref(), noname());
+ B(cx).va_arg(list, Ty)
}
}
-pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
- ValueRef {
+pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
- count_insn(cx, "extractelement");
- return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
+ B(cx).extract_element(VecVal, Index)
}
}
Index: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
- count_insn(cx, "insertelement");
- llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname())
+ B(cx).insert_element(VecVal, EltVal, Index)
}
}
Mask: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
- count_insn(cx, "shufflevector");
- llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname())
+ B(cx).shuffle_vector(V1, V2, Mask)
}
}
pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
unsafe {
- let elt_ty = val_ty(EltVal);
- let Undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, NumElts as u64).to_ref());
- let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0));
- ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(&Type::i32(), NumElts as u64)))
+ if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
+ B(cx).vector_splat(NumElts, EltVal)
}
}
pub fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
- count_insn(cx, "extractvalue");
- return llvm::LLVMBuildExtractValue(
- B(cx), AggVal, Index as c_uint, noname());
+ B(cx).extract_value(AggVal, Index)
}
}
-pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef,
- Index: uint) {
- unsafe {
- if cx.unreachable { return; }
- count_insn(cx, "insertvalue");
- llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
- noname());
- }
+pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef, Index: uint) {
+ if cx.unreachable { return; }
+ B(cx).insert_value(AggVal, EltVal, Index)
}
pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
- count_insn(cx, "isnull");
- return llvm::LLVMBuildIsNull(B(cx), Val, noname());
+ B(cx).is_null(Val)
}
}
pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
- count_insn(cx, "isnotnull");
- return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
+ B(cx).is_not_null(Val)
}
}
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type.to_ref()); }
- count_insn(cx, "ptrdiff");
- return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
+ B(cx).ptrdiff(LHS, RHS)
}
}
pub fn Trap(cx: block) {
- unsafe {
- if cx.unreachable { return; }
- let b = B(cx);
- let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
- let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
- let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
- let T: ValueRef = str::as_c_str("llvm.trap", |buf| {
- llvm::LLVMGetNamedFunction(M, buf)
- });
- assert!((T as int != 0));
- let Args: ~[ValueRef] = ~[];
- count_insn(cx, "trap");
- llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), Args.len() as c_uint, noname());
- }
+ if cx.unreachable { return; }
+ B(cx).trap();
}
pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef,
NumClauses: uint) -> ValueRef {
- unsafe {
- check_not_terminated(cx);
- assert!(!cx.unreachable);
- count_insn(cx, "landingpad");
- return llvm::LLVMBuildLandingPad(
- B(cx), Ty.to_ref(), PersFn, NumClauses as c_uint, noname());
- }
+ check_not_terminated(cx);
+ assert!(!cx.unreachable);
+ B(cx).landing_pad(Ty, PersFn, NumClauses)
}
pub fn SetCleanup(cx: block, LandingPad: ValueRef) {
- unsafe {
- count_insn(cx, "setcleanup");
- llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
- }
+ B(cx).set_cleanup(LandingPad)
}
pub fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
- unsafe {
- check_not_terminated(cx);
- terminate(cx, "Resume");
- count_insn(cx, "resume");
- return llvm::LLVMBuildResume(B(cx), Exn);
- }
+ check_not_terminated(cx);
+ terminate(cx, "Resume");
+ B(cx).resume(Exn)
}
// Atomic Operations
pub fn AtomicCmpXchg(cx: block, dst: ValueRef,
cmp: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
- unsafe {
- llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
- }
+ B(cx).atomic_cmpxchg(dst, cmp, src, order)
}
pub fn AtomicRMW(cx: block, op: AtomicBinOp,
dst: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
- unsafe {
- llvm::LLVMBuildAtomicRMW(B(cx), op, dst, src, order)
- }
+ B(cx).atomic_rmw(op, dst, src, order)
}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use lib;
+use lib::llvm::llvm;
+use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
+use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
+use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
+use middle::trans::base;
+use middle::trans::common::*;
+use middle::trans::machine::llalign_of_min;
+use middle::trans::type_::Type;
+use std::cast;
+use std::hashmap::HashMap;
+use std::libc::{c_uint, c_ulonglong, c_char};
+use std::str;
+use std::vec;
+use syntax::codemap::span;
+
+pub struct Builder {
+ llbuilder: BuilderRef,
+ ccx: @mut CrateContext,
+}
+
+// This is a really awful way to get a zero-length c-string, but better (and a
+// lot more efficient) than doing str::as_c_str("", ...) every time.
+pub fn noname() -> *c_char {
+ unsafe {
+ static cnull: uint = 0u;
+ cast::transmute(&cnull)
+ }
+}
+
+impl Builder {
+ pub fn new(ccx: @mut CrateContext) -> Builder {
+ Builder {
+ llbuilder: ccx.builder.B,
+ ccx: ccx,
+ }
+ }
+
+ pub fn count_insn(&self, category: &str) {
+ if self.ccx.sess.trans_stats() {
+ self.ccx.stats.n_llvm_insns += 1;
+ }
+ if self.ccx.sess.count_llvm_insns() {
+ do base::with_insn_ctxt |v| {
+ let h = &mut self.ccx.stats.llvm_insns;
+
+ // Build version of path with cycles removed.
+
+ // Pass 1: scan table mapping str -> rightmost pos.
+ let mut mm = HashMap::new();
+ let len = v.len();
+ let mut i = 0u;
+ while i < len {
+ mm.insert(v[i], i);
+ i += 1u;
+ }
+
+ // Pass 2: concat strings for each elt, skipping
+ // forwards over any cycles by advancing to rightmost
+ // occurrence of each element in path.
+ let mut s = ~".";
+ i = 0u;
+ while i < len {
+ i = *mm.get(&v[i]);
+ s.push_char('/');
+ s.push_str(v[i]);
+ i += 1u;
+ }
+
+ s.push_char('/');
+ s.push_str(category);
+
+ let n = match h.find(&s) {
+ Some(&n) => n,
+ _ => 0u
+ };
+ h.insert(s, n+1u);
+ }
+ }
+ }
+
+ pub fn position_before(&self, insn: ValueRef) {
+ unsafe {
+ llvm::LLVMPositionBuilderBefore(self.llbuilder, insn);
+ }
+ }
+
+ pub fn position_at_end(&self, llbb: BasicBlockRef) {
+ unsafe {
+ llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
+ }
+ }
+
+ pub fn ret_void(&self) {
+ self.count_insn("retvoid");
+ unsafe {
+ llvm::LLVMBuildRetVoid(self.llbuilder);
+ }
+ }
+
+ pub fn ret(&self, v: ValueRef) {
+ self.count_insn("ret");
+ unsafe {
+ llvm::LLVMBuildRet(self.llbuilder, v);
+ }
+ }
+
+ pub fn aggregate_ret(&self, ret_vals: &[ValueRef]) {
+ unsafe {
+ llvm::LLVMBuildAggregateRet(self.llbuilder,
+ vec::raw::to_ptr(ret_vals),
+ ret_vals.len() as c_uint);
+ }
+ }
+
+ pub fn br(&self, dest: BasicBlockRef) {
+ self.count_insn("br");
+ unsafe {
+ llvm::LLVMBuildBr(self.llbuilder, dest);
+ }
+ }
+
+ pub fn cond_br(&self, cond: ValueRef, then_llbb: BasicBlockRef, else_llbb: BasicBlockRef) {
+ self.count_insn("condbr");
+ unsafe {
+ llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb);
+ }
+ }
+
+ pub fn switch(&self, v: ValueRef, else_llbb: BasicBlockRef, num_cases: uint) -> ValueRef {
+ unsafe {
+ llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint)
+ }
+ }
+
+ pub fn indirect_br(&self, addr: ValueRef, num_dests: uint) {
+ self.count_insn("indirectbr");
+ unsafe {
+ llvm::LLVMBuildIndirectBr(self.llbuilder, addr, num_dests as c_uint);
+ }
+ }
+
+ pub fn invoke(&self,
+ llfn: ValueRef,
+ args: &[ValueRef],
+ then: BasicBlockRef,
+ catch: BasicBlockRef)
+ -> ValueRef {
+ self.count_insn("invoke");
+ unsafe {
+ llvm::LLVMBuildInvoke(self.llbuilder,
+ llfn,
+ vec::raw::to_ptr(args),
+ args.len() as c_uint,
+ then,
+ catch,
+ noname())
+ }
+ }
+
+ pub fn fast_invoke(&self,
+ llfn: ValueRef,
+ args: &[ValueRef],
+ then: BasicBlockRef,
+ catch: BasicBlockRef) {
+ self.count_insn("fastinvoke");
+ let v = self.invoke(llfn, args, then, catch);
+ lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv);
+ }
+
+ pub fn unreachable(&self) {
+ self.count_insn("unreachable");
+ unsafe {
+ llvm::LLVMBuildUnreachable(self.llbuilder);
+ }
+ }
+
+ /* Arithmetic */
+ pub fn add(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("add");
+ unsafe {
+ llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nswadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nswadd");
+ unsafe {
+ llvm::LLVMBuildNSWAdd(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nuwadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nuwadd");
+ unsafe {
+ llvm::LLVMBuildNUWAdd(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn fadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("fadd");
+ unsafe {
+ llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn sub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("sub");
+ unsafe {
+ llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nswsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nwsub");
+ unsafe {
+ llvm::LLVMBuildNSWSub(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nuwsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nuwsub");
+ unsafe {
+ llvm::LLVMBuildNUWSub(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn fsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("sub");
+ unsafe {
+ llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn mul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("mul");
+ unsafe {
+ llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nswmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nswmul");
+ unsafe {
+ llvm::LLVMBuildNSWMul(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn nuwmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("nuwmul");
+ unsafe {
+ llvm::LLVMBuildNUWMul(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn fmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("fmul");
+ unsafe {
+ llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn udiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("udiv");
+ unsafe {
+ llvm::LLVMBuildUDiv(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn sdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("sdiv");
+ unsafe {
+ llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn exactsdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("exactsdiv");
+ unsafe {
+ llvm::LLVMBuildExactSDiv(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn fdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("fdiv");
+ unsafe {
+ llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn urem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("urem");
+ unsafe {
+ llvm::LLVMBuildURem(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn srem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("srem");
+ unsafe {
+ llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn frem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("frem");
+ unsafe {
+ llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn shl(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("shl");
+ unsafe {
+ llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn lshr(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("lshr");
+ unsafe {
+ llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn ashr(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("ashr");
+ unsafe {
+ llvm::LLVMBuildAShr(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn and(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("and");
+ unsafe {
+ llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn or(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("or");
+ unsafe {
+ llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn xor(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("xor");
+ unsafe {
+ llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn binop(&self, op: Opcode, lhs: ValueRef, rhs: ValueRef)
+ -> ValueRef {
+ self.count_insn("binop");
+ unsafe {
+ llvm::LLVMBuildBinOp(self.llbuilder, op, lhs, rhs, noname())
+ }
+ }
+
+ pub fn neg(&self, V: ValueRef) -> ValueRef {
+ self.count_insn("neg");
+ unsafe {
+ llvm::LLVMBuildNeg(self.llbuilder, V, noname())
+ }
+ }
+
+ pub fn nswneg(&self, V: ValueRef) -> ValueRef {
+ self.count_insn("nswneg");
+ unsafe {
+ llvm::LLVMBuildNSWNeg(self.llbuilder, V, noname())
+ }
+ }
+
+ pub fn nuwneg(&self, V: ValueRef) -> ValueRef {
+ self.count_insn("nuwneg");
+ unsafe {
+ llvm::LLVMBuildNUWNeg(self.llbuilder, V, noname())
+ }
+ }
+ pub fn fneg(&self, V: ValueRef) -> ValueRef {
+ self.count_insn("fneg");
+ unsafe {
+ llvm::LLVMBuildFNeg(self.llbuilder, V, noname())
+ }
+ }
+
+ pub fn not(&self, V: ValueRef) -> ValueRef {
+ self.count_insn("not");
+ unsafe {
+ llvm::LLVMBuildNot(self.llbuilder, V, noname())
+ }
+ }
+
+ /* Memory */
+ pub fn malloc(&self, ty: Type) -> ValueRef {
+ self.count_insn("malloc");
+ unsafe {
+ llvm::LLVMBuildMalloc(self.llbuilder, ty.to_ref(), noname())
+ }
+ }
+
+ pub fn array_malloc(&self, ty: Type, val: ValueRef) -> ValueRef {
+ self.count_insn("arraymalloc");
+ unsafe {
+ llvm::LLVMBuildArrayMalloc(self.llbuilder, ty.to_ref(), val, noname())
+ }
+ }
+
+ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
+ self.count_insn("alloca");
+ unsafe {
+ if name.is_empty() {
+ llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
+ } else {
+ str::as_c_str(
+ name,
+ |c| llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c))
+ }
+ }
+ }
+
+ pub fn array_alloca(&self, ty: Type, val: ValueRef) -> ValueRef {
+ self.count_insn("arrayalloca");
+ unsafe {
+ llvm::LLVMBuildArrayAlloca(self.llbuilder, ty.to_ref(), val, noname())
+ }
+ }
+
+ pub fn free(&self, ptr: ValueRef) {
+ self.count_insn("free");
+ unsafe {
+ llvm::LLVMBuildFree(self.llbuilder, ptr);
+ }
+ }
+
+ pub fn load(&self, ptr: ValueRef) -> ValueRef {
+ self.count_insn("load");
+ unsafe {
+ llvm::LLVMBuildLoad(self.llbuilder, ptr, noname())
+ }
+ }
+
+ pub fn atomic_load(&self, ptr: ValueRef, order: AtomicOrdering) -> ValueRef {
+ self.count_insn("load.atomic");
+ unsafe {
+ let align = llalign_of_min(self.ccx, self.ccx.int_type);
+ llvm::LLVMBuildAtomicLoad(self.llbuilder, ptr, noname(), order, align as c_uint)
+ }
+ }
+
+
+ pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
+ hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
+ let value = self.load(ptr);
+
+ unsafe {
+ let t = llvm::LLVMGetElementType(llvm::LLVMTypeOf(ptr));
+ let min = llvm::LLVMConstInt(t, lo, signed);
+ let max = llvm::LLVMConstInt(t, hi, signed);
+
+ do [min, max].as_imm_buf |ptr, len| {
+ llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
+ llvm::LLVMMDNodeInContext(self.ccx.llcx,
+ ptr, len as c_uint));
+ }
+ }
+
+ value
+ }
+
+ pub fn store(&self, val: ValueRef, ptr: ValueRef) {
+ debug!("Store %s -> %s",
+ self.ccx.tn.val_to_str(val),
+ self.ccx.tn.val_to_str(ptr));
+ self.count_insn("store");
+ unsafe {
+ llvm::LLVMBuildStore(self.llbuilder, val, ptr);
+ }
+ }
+
+ pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
+ debug!("Store %s -> %s",
+ self.ccx.tn.val_to_str(val),
+ self.ccx.tn.val_to_str(ptr));
+ self.count_insn("store.atomic");
+ let align = llalign_of_min(self.ccx, self.ccx.int_type);
+ unsafe {
+ llvm::LLVMBuildAtomicStore(self.llbuilder, val, ptr, order, align as c_uint);
+ }
+ }
+
+ pub fn gep(&self, ptr: ValueRef, indices: &[ValueRef]) -> ValueRef {
+ self.count_insn("gep");
+ unsafe {
+ llvm::LLVMBuildGEP(self.llbuilder, ptr, vec::raw::to_ptr(indices),
+ indices.len() as c_uint, noname())
+ }
+ }
+
+ // Simple wrapper around GEP that takes an array of ints and wraps them
+ // in C_i32()
+ #[inline]
+ pub fn gepi(&self, base: ValueRef, ixs: &[uint]) -> ValueRef {
+ // Small vector optimization. This should catch 100% of the cases that
+ // we care about.
+ if ixs.len() < 16 {
+ let mut small_vec = [ C_i32(0), ..16 ];
+ for small_vec.mut_iter().zip(ixs.iter()).advance |(small_vec_e, &ix)| {
+ *small_vec_e = C_i32(ix as i32);
+ }
+ self.inbounds_gep(base, small_vec.slice(0, ixs.len()))
+ } else {
+ let v = do ixs.iter().transform |i| { C_i32(*i as i32) }.collect::<~[ValueRef]>();
+ self.count_insn("gepi");
+ self.inbounds_gep(base, v)
+ }
+ }
+
+ pub fn inbounds_gep(&self, ptr: ValueRef, indices: &[ValueRef]) -> ValueRef {
+ self.count_insn("inboundsgep");
+ unsafe {
+ llvm::LLVMBuildInBoundsGEP(
+ self.llbuilder, ptr, vec::raw::to_ptr(indices), indices.len() as c_uint, noname())
+ }
+ }
+
+ pub fn struct_gep(&self, ptr: ValueRef, idx: uint) -> ValueRef {
+ self.count_insn("structgep");
+ unsafe {
+ llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
+ }
+ }
+
+ pub fn global_string(&self, _Str: *c_char) -> ValueRef {
+ self.count_insn("globalstring");
+ unsafe {
+ llvm::LLVMBuildGlobalString(self.llbuilder, _Str, noname())
+ }
+ }
+
+ pub fn global_string_ptr(&self, _Str: *c_char) -> ValueRef {
+ self.count_insn("globalstringptr");
+ unsafe {
+ llvm::LLVMBuildGlobalStringPtr(self.llbuilder, _Str, noname())
+ }
+ }
+
+ /* Casts */
+ pub fn trunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("trunc");
+ unsafe {
+ llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn zext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("zext");
+ unsafe {
+ llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn sext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("sext");
+ unsafe {
+ llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn fptoui(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("fptoui");
+ unsafe {
+ llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn fptosi(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("fptosi");
+ unsafe {
+ llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty.to_ref(),noname())
+ }
+ }
+
+ pub fn uitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("uitofp");
+ unsafe {
+ llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn sitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("sitofp");
+ unsafe {
+ llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn fptrunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("fptrunc");
+ unsafe {
+ llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn fpext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("fpext");
+ unsafe {
+ llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn ptrtoint(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("ptrtoint");
+ unsafe {
+ llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn inttoptr(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("inttoptr");
+ unsafe {
+ llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("bitcast");
+ unsafe {
+ llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("zextorbitcast");
+ unsafe {
+ llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("sextorbitcast");
+ unsafe {
+ llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("truncorbitcast");
+ unsafe {
+ llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("cast");
+ unsafe {
+ llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn pointercast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("pointercast");
+ unsafe {
+ llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn intcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("intcast");
+ unsafe {
+ llvm::LLVMBuildIntCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+ pub fn fpcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
+ self.count_insn("fpcast");
+ unsafe {
+ llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ }
+ }
+
+
+ /* Comparisons */
+ pub fn icmp(&self, op: IntPredicate, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("icmp");
+ unsafe {
+ llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
+ }
+ }
+
+ pub fn fcmp(&self, op: RealPredicate, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("fcmp");
+ unsafe {
+ llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
+ }
+ }
+
+ /* Miscellaneous instructions */
+ pub fn empty_phi(&self, ty: Type) -> ValueRef {
+ self.count_insn("emptyphi");
+ unsafe {
+ llvm::LLVMBuildPhi(self.llbuilder, ty.to_ref(), noname())
+ }
+ }
+
+ pub fn phi(&self, ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
+ assert_eq!(vals.len(), bbs.len());
+ let phi = self.empty_phi(ty);
+ self.count_insn("addincoming");
+ unsafe {
+ llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals),
+ vec::raw::to_ptr(bbs),
+ vals.len() as c_uint);
+ phi
+ }
+ }
+
+ pub fn add_span_comment(&self, sp: span, text: &str) {
+ if self.ccx.sess.asm_comments() {
+ let s = fmt!("%s (%s)", text, self.ccx.sess.codemap.span_to_str(sp));
+ debug!("%s", s);
+ self.add_comment(s);
+ }
+ }
+
+ pub fn add_comment(&self, text: &str) {
+ if self.ccx.sess.asm_comments() {
+ let sanitized = text.replace("$", "");
+ let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# "));
+ self.count_insn("inlineasm");
+ let asm = do comment_text.as_c_str |c| {
+ unsafe {
+ llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
+ c, noname(), False, False)
+ }
+ };
+ self.call(asm, []);
+ }
+ }
+
+ pub fn inline_asm_call(&self, asm: *c_char, cons: *c_char,
+ inputs: &[ValueRef], output: Type,
+ volatile: bool, alignstack: bool,
+ dia: AsmDialect) -> ValueRef {
+ self.count_insn("inlineasm");
+
+ let volatile = if volatile { lib::llvm::True }
+ else { lib::llvm::False };
+ let alignstack = if alignstack { lib::llvm::True }
+ else { lib::llvm::False };
+
+ let argtys = do inputs.map |v| {
+ debug!("Asm Input Type: %?", self.ccx.tn.val_to_str(*v));
+ val_ty(*v)
+ };
+
+ debug!("Asm Output Type: %?", self.ccx.tn.type_to_str(output));
+ let fty = Type::func(argtys, &output);
+ unsafe {
+ let v = llvm::LLVMInlineAsm(
+ fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
+ self.call(v, inputs)
+ }
+ }
+
+ pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
+ self.count_insn("call");
+
+ debug!("Call(llfn=%s, args=%?)",
+ self.ccx.tn.val_to_str(llfn),
+ args.map(|arg| self.ccx.tn.val_to_str(*arg)));
+
+ do args.as_imm_buf |ptr, len| {
+ unsafe {
+ llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
+ }
+ }
+ }
+
+ pub fn fastcall(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
+ self.count_insn("fastcall");
+ unsafe {
+ let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
+ args.len() as c_uint, noname());
+ lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv);
+ v
+ }
+ }
+
+ pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
+ conv: CallConv) -> ValueRef {
+ self.count_insn("callwithconv");
+ unsafe {
+ let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
+ args.len() as c_uint, noname());
+ lib::llvm::SetInstructionCallConv(v, conv);
+ v
+ }
+ }
+
+ pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef {
+ self.count_insn("select");
+ unsafe {
+ llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, noname())
+ }
+ }
+
+ pub fn va_arg(&self, list: ValueRef, ty: Type) -> ValueRef {
+ self.count_insn("vaarg");
+ unsafe {
+ llvm::LLVMBuildVAArg(self.llbuilder, list, ty.to_ref(), noname())
+ }
+ }
+
+ pub fn extract_element(&self, vec: ValueRef, idx: ValueRef) -> ValueRef {
+ self.count_insn("extractelement");
+ unsafe {
+ llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, noname())
+ }
+ }
+
+ pub fn insert_element(&self, vec: ValueRef, elt: ValueRef, idx: ValueRef) -> ValueRef {
+ self.count_insn("insertelement");
+ unsafe {
+ llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname())
+ }
+ }
+
+ pub fn shuffle_vector(&self, v1: ValueRef, v2: ValueRef, mask: ValueRef) -> ValueRef {
+ self.count_insn("shufflevector");
+ unsafe {
+ llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
+ }
+ }
+
+ pub fn vector_splat(&self, num_elts: uint, elt: ValueRef) -> ValueRef {
+ unsafe {
+ let elt_ty = val_ty(elt);
+ let Undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref());
+ let vec = self.insert_element(Undef, elt, C_i32(0));
+ self.shuffle_vector(vec, Undef, C_null(Type::vector(&Type::i32(), num_elts as u64)))
+ }
+ }
+
+ pub fn extract_value(&self, agg_val: ValueRef, idx: uint) -> ValueRef {
+ self.count_insn("extractvalue");
+ unsafe {
+ llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, noname())
+ }
+ }
+
+ pub fn insert_value(&self, agg_val: ValueRef, elt: ValueRef,
+ idx: uint) {
+ self.count_insn("insertvalue");
+ unsafe {
+ llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint,
+ noname());
+ }
+ }
+
+ pub fn is_null(&self, val: ValueRef) -> ValueRef {
+ self.count_insn("isnull");
+ unsafe {
+ llvm::LLVMBuildIsNull(self.llbuilder, val, noname())
+ }
+ }
+
+ pub fn is_not_null(&self, val: ValueRef) -> ValueRef {
+ self.count_insn("isnotnull");
+ unsafe {
+ llvm::LLVMBuildIsNotNull(self.llbuilder, val, noname())
+ }
+ }
+
+ pub fn ptrdiff(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+ self.count_insn("ptrdiff");
+ unsafe {
+ llvm::LLVMBuildPtrDiff(self.llbuilder, lhs, rhs, noname())
+ }
+ }
+
+ pub fn trap(&self) {
+ unsafe {
+ let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
+ let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
+ let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
+ let T: ValueRef = str::as_c_str("llvm.trap", |buf| {
+ llvm::LLVMGetNamedFunction(M, buf)
+ });
+ assert!((T as int != 0));
+ let args: &[ValueRef] = [];
+ self.count_insn("trap");
+ llvm::LLVMBuildCall(
+ self.llbuilder, T, vec::raw::to_ptr(args), args.len() as c_uint, noname());
+ }
+ }
+
+ pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, num_clauses: uint) -> ValueRef {
+ self.count_insn("landingpad");
+ unsafe {
+ llvm::LLVMBuildLandingPad(
+ self.llbuilder, ty.to_ref(), pers_fn, num_clauses as c_uint, noname())
+ }
+ }
+
+ pub fn set_cleanup(&self, landing_pad: ValueRef) {
+ self.count_insn("setcleanup");
+ unsafe {
+ llvm::LLVMSetCleanup(landing_pad, lib::llvm::True);
+ }
+ }
+
+ pub fn resume(&self, exn: ValueRef) -> ValueRef {
+ self.count_insn("resume");
+ unsafe {
+ llvm::LLVMBuildResume(self.llbuilder, exn)
+ }
+ }
+
+ // Atomic Operations
+ pub fn atomic_cmpxchg(&self, dst: ValueRef,
+ cmp: ValueRef, src: ValueRef,
+ order: AtomicOrdering) -> ValueRef {
+ unsafe {
+ llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order)
+ }
+ }
+ pub fn atomic_rmw(&self, op: AtomicBinOp,
+ dst: ValueRef, src: ValueRef,
+ order: AtomicOrdering) -> ValueRef {
+ unsafe {
+ llvm::LLVMBuildAtomicRMW(self.llbuilder, op, dst, src, order)
+ }
+ }
+}
ArgVals(args), Some(dest), DontAutorefArg).bcx;
}
-pub fn body_contains_ret(body: &ast::blk) -> bool {
+pub fn body_contains_ret(body: &ast::Block) -> bool {
let cx = @mut false;
visit::visit_block(body, (cx, visit::mk_vt(@visit::Visitor {
visit_item: |_i, (_cx, _v)| { },
use back::abi;
use back::link::{mangle_internal_name_by_path_and_seq};
-use lib::llvm::{llvm, ValueRef};
+use lib::llvm::ValueRef;
use middle::moves;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::type_::Type;
-use std::str;
use std::vec;
use syntax::ast;
use syntax::ast_map::path_name;
sigil: ast::Sigil) {
let _icx = push_ctxt("closure::load_environment");
- let llloadenv = match fcx.llloadenv {
- Some(ll) => ll,
- None => {
- let ll =
- str::as_c_str("load_env",
- |buf|
- unsafe {
- llvm::LLVMAppendBasicBlockInContext(fcx.ccx.llcx,
- fcx.llfn,
- buf)
- });
- fcx.llloadenv = Some(ll);
- ll
- }
- };
+ // Don't bother to create the block if there's nothing to load
+ if cap_vars.len() == 0 && !load_ret_handle {
+ return;
+ }
- let bcx = raw_block(fcx, false, llloadenv);
+ let bcx = fcx.entry_bcx.get();
// Load a pointer to the closure data, skipping over the box header:
let llcdata = opaque_box_body(bcx, cdata_ty, fcx.llenv);
pub fn trans_expr_fn(bcx: block,
sigil: ast::Sigil,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
outer_id: ast::node_id,
user_id: ast::node_id,
is_loop_body: Option<Option<ValueRef>>,
// always be Some.
llretptr: Option<ValueRef>,
+ entry_bcx: Option<block>,
+
// These elements: "hoisted basic blocks" containing
// administrative activities that have to happen in only one place in
// the function, due to LLVM's quirks.
- // A block for all the function's static allocas, so that LLVM
- // will coalesce them into a single alloca call.
- llstaticallocas: Option<BasicBlockRef>,
- // A block containing code that copies incoming arguments to space
- // already allocated by code in one of the llallocas blocks.
- // (LLVM requires that arguments be copied to local allocas before
- // allowing most any operation to be performed on them.)
- llloadenv: Option<BasicBlockRef>,
+ // A marker for the place where we want to insert the function's static
+ // allocas, so that LLVM will coalesce them into a single alloca call.
+ alloca_insert_pt: Option<ValueRef>,
llreturn: Option<BasicBlockRef>,
// The 'self' value currently in use in this function, if there
// is one.
}
}
- pub fn get_llstaticallocas(&mut self) -> BasicBlockRef {
- if self.llstaticallocas.is_none() {
- self.llstaticallocas = Some(base::mk_staticallocas_basic_block(self.llfn));
+ pub fn cleanup(&mut self) {
+ unsafe {
+ llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.get());
}
-
- self.llstaticallocas.get()
+ // Remove the cycle between fcx and bcx, so memory can be freed
+ self.entry_bcx = None;
}
pub fn get_llreturn(&mut self) -> BasicBlockRef {
}
}
-impl get_node_info for ast::blk {
+impl get_node_info for ast::Block {
fn info(&self) -> Option<NodeInfo> {
Some(NodeInfo {id: self.id,
callee_id: None,
do expr::with_field_tys(tcx, ety, Some(e.id))
|discr, field_tys| {
let cs = field_tys.map(|field_ty| {
- match fs.iter().find_(|f| field_ty.ident == f.node.ident) {
- Some(f) => const_expr(cx, (*f).node.expr),
+ match fs.iter().find_(|f| field_ty.ident == f.ident) {
+ Some(f) => const_expr(cx, (*f).expr),
None => {
cx.tcx.sess.span_bug(e.span, "missing struct field");
}
use middle::resolve;
use middle::trans::adt;
use middle::trans::base;
+use middle::trans::builder::Builder;
use middle::trans::debuginfo;
use middle::trans::type_use;
use middle::ty;
}
}
}
+
+ pub fn builder(@mut self) -> Builder {
+ Builder::new(self)
+ }
}
#[unsafe_destructor]
}
}
-#[cfg(stage0)]
-fn task_local_llcx_key(_v: @ContextRef) {}
-#[cfg(not(stage0))]
static task_local_llcx_key: local_data::Key<@ContextRef> = &local_data::Key;
pub fn task_llcx() -> ContextRef {
use syntax::ast_util;
use syntax::codemap::span;
-pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block {
+pub fn trans_block(bcx: block, b: &ast::Block, dest: expr::Dest) -> block {
let _icx = push_ctxt("trans_block");
let mut bcx = bcx;
for b.stmts.iter().advance |s| {
pub fn trans_if(bcx: block,
cond: @ast::expr,
- thn: &ast::blk,
+ thn: &ast::Block,
els: Option<@ast::expr>,
dest: expr::Dest)
-> block {
return out;
}
-pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::blk) -> block {
+pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::Block) -> block {
let _icx = push_ctxt("trans_while");
let next_bcx = sub_block(bcx, "while next");
}
pub fn trans_loop(bcx:block,
- body: &ast::blk,
+ body: &ast::Block,
opt_label: Option<ident>)
-> block {
let _icx = push_ctxt("trans_loop");
///
/// Adds the created metadata nodes directly to the crate's IR.
/// The return value should be ignored if called from outside of the debuginfo module.
-pub fn create_local_var_metadata(bcx: block, local: @ast::local) -> DIVariable {
+pub fn create_local_var_metadata(bcx: block, local: @ast::Local) -> DIVariable {
let cx = bcx.ccx();
- let ident = match local.node.pat.node {
+ let ident = match local.pat.node {
ast::pat_ident(_, ref pth, _) => ast_util::path_to_ident(pth),
// FIXME this should be handled (#2533)
_ => {
debug!("create_local_var_metadata: %s", name);
let loc = span_start(cx, local.span);
- let ty = node_id_type(bcx, local.node.id);
- let type_metadata = type_metadata(cx, ty, local.node.ty.span);
+ let ty = node_id_type(bcx, local.id);
+ let type_metadata = type_metadata(cx, ty, local.ty.span);
let file_metadata = file_metadata(cx, loc.file.name);
let context = match bcx.parent {
};
// FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc
- let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) {
+ let llptr = match bcx.fcx.lllocals.find_copy(&local.pat.id) {
Some(v) => v,
None => {
bcx.tcx().sess.span_bug(
local.span,
- fmt!("No entry in lllocals table for %?", local.node.id));
+ fmt!("No entry in lllocals table for %?", local.id));
}
};
set_debug_location(cx, lexical_block_metadata(bcx), loc.line, loc.col.to_uint());
unsafe {
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_metadata, bcx.llbb);
- llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
+ llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
}
return var_metadata;
unsafe {
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
DIB(cx), llptr, var_metadata, bcx.llbb);
- llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
+ llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
}
return Some(var_metadata);
}
span);
}
-// The stage0 snapshot does not yet support the fixes from PR #7557, so there are two versions of
-// following function for now
-#[cfg(not(stage0))]
fn enum_metadata(cx: &mut CrateContext,
enum_type: ty::t,
enum_def_id: ast::def_id,
}
}
-#[cfg(stage0)]
-fn enum_metadata(cx: &mut CrateContext,
- enum_type: ty::t,
- enum_def_id: ast::def_id,
- substs: &ty::substs,
- span: span)
- -> DIType {
-
- let enum_name = ty_to_str(cx.tcx, enum_type);
-
- // For empty enums there is an early exit. Just describe it as an empty struct with the
- // appropriate type name
- if ty::type_is_empty(cx.tcx, enum_type) {
- return composite_type_metadata(cx, Type::nil(), enum_name, &[], &[], &[], span);
- }
-
- // Prepare some data (llvm type, size, align, ...) about the discriminant. This data will be
- // needed in all of the following cases.
- let discriminant_llvm_type = Type::enum_discrim(cx);
- let (discriminant_size, discriminant_align) = size_and_align_of(cx, discriminant_llvm_type);
-
- assert!(Type::enum_discrim(cx) == cx.int_type);
- let discriminant_type_metadata = type_metadata(cx, ty::mk_int(), span);
-
- let variants: &[@ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
-
- let enumerators_metadata: ~[DIDescriptor] = variants
- .iter()
- .transform(|v| {
- let name: &str = cx.sess.str_of(v.name);
- let discriminant_value = v.disr_val as c_ulonglong;
-
- do name.as_c_str |name| {
- unsafe {
- llvm::LLVMDIBuilderCreateEnumerator(
- DIB(cx),
- name,
- discriminant_value)
- }
- }
- })
- .collect();
-
- let loc = span_start(cx, span);
- let file_metadata = file_metadata(cx, loc.file.name);
-
- let discriminant_type_metadata = do enum_name.as_c_str |enum_name| {
- unsafe {
- llvm::LLVMDIBuilderCreateEnumerationType(
- DIB(cx),
- file_metadata,
- enum_name,
- file_metadata,
- loc.line as c_uint,
- bytes_to_bits(discriminant_size),
- bytes_to_bits(discriminant_align),
- create_DIArray(DIB(cx), enumerators_metadata),
- discriminant_type_metadata)
- }
- };
-
- if ty::type_is_c_like_enum(cx.tcx, enum_type) {
- return discriminant_type_metadata;
- }
-
- let is_univariant = variants.len() == 1;
-
- let variants_metadata = do variants.map |&vi| {
-
- let raw_types: &[ty::t] = vi.args;
- let arg_types = do raw_types.map |&raw_type| { ty::subst(cx.tcx, substs, raw_type) };
-
- let mut arg_llvm_types = do arg_types.map |&ty| { type_of::type_of(cx, ty) };
- let mut arg_names = match vi.arg_names {
- Some(ref names) => do names.map |ident| { cx.sess.str_of(*ident).to_owned() },
- None => do arg_types.map |_| { ~"" }
- };
-
- let mut arg_metadata = do arg_types.map |&ty| { type_metadata(cx, ty, span) };
-
- if !is_univariant {
- arg_llvm_types.insert(0, discriminant_llvm_type);
- arg_names.insert(0, ~"");
- arg_metadata.insert(0, discriminant_type_metadata);
- }
-
- let variant_llvm_type = Type::struct_(arg_llvm_types, false);
- let (variant_type_size, variant_type_align) = size_and_align_of(cx, variant_llvm_type);
-
- let variant_type_metadata = composite_type_metadata(
- cx,
- variant_llvm_type,
- &"",
- arg_llvm_types,
- arg_names,
- arg_metadata,
- span);
-
- do "".as_c_str |name| {
- unsafe {
- llvm::LLVMDIBuilderCreateMemberType(
- DIB(cx),
- file_metadata,
- name,
- file_metadata,
- loc.line as c_uint,
- bytes_to_bits(variant_type_size),
- bytes_to_bits(variant_type_align),
- bytes_to_bits(0),
- 0,
- variant_type_metadata)
- }
- }
- };
-
- let enum_llvm_type = type_of::type_of(cx, enum_type);
- let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
-
- return do enum_name.as_c_str |enum_name| {
- unsafe {
- llvm::LLVMDIBuilderCreateUnionType(
- DIB(cx),
- file_metadata,
- enum_name,
- file_metadata,
- loc.line as c_uint,
- bytes_to_bits(enum_type_size),
- bytes_to_bits(enum_type_align),
- 0, // Flags
- create_DIArray(DIB(cx), variants_metadata),
- 0) // RuntimeLang
- }
- };
-}
-
-
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
///
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
}
fn trans_rec_or_struct(bcx: block,
- fields: &[ast::field],
+ fields: &[ast::Field],
base: Option<@ast::expr>,
expr_span: codemap::span,
id: ast::node_id,
let mut need_base = vec::from_elem(field_tys.len(), true);
let numbered_fields = do fields.map |field| {
- let opt_pos = field_tys.iter().position(|field_ty| field_ty.ident == field.node.ident);
+ let opt_pos = field_tys.iter().position(|field_ty| field_ty.ident == field.ident);
match opt_pos {
Some(i) => {
need_base[i] = false;
- (i, field.node.expr)
+ (i, field.expr)
}
None => {
tcx.sess.span_bug(field.span,
// Declare the body of the shim function:
let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
+ let bcx = fcx.entry_bcx.get();
let llargbundle = get_param(llshimfn, 0u);
let llargvals = arg_builder(bcx, tys, llargbundle);
// Don't finish up the function in the usual way, because this doesn't
// follow the normal Rust calling conventions.
- tie_up_header_blocks(fcx, lltop);
-
let ret_cx = match fcx.llreturn {
Some(llreturn) => raw_block(fcx, false, llreturn),
None => bcx
};
RetVoid(ret_cx);
+ fcx.cleanup();
return llshimfn;
}
ret_builder: wrap_ret_builder) {
let _icx = push_ctxt("foreign::build_wrap_fn_");
let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
+ let bcx = fcx.entry_bcx.get();
// Patch up the return type if it's not immediate and we're returning via
// the C ABI.
if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) {
let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output);
- fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.get_llstaticallocas()),
- lloutputtype,
- ""));
+ fcx.llretptr = Some(alloca(bcx, lloutputtype, ""));
}
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
-
// Allocate the struct and write the arguments into it.
let llargbundle = alloca(bcx, tys.bundle_ty, "__llargbundle");
arg_builder(bcx, tys, llwrapfn, llargbundle);
Call(bcx, shim_upcall, [llrawargbundle, llshimfnptr]);
ret_builder(bcx, tys, llargbundle);
- // Perform a custom version of `finish_fn`. First, tie up the header
- // blocks.
- tie_up_header_blocks(fcx, lltop);
-
// Then return according to the C ABI.
let return_context = match fcx.llreturn {
Some(llreturn) => raw_block(fcx, false, llreturn),
let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to());
Ret(return_context, Load(return_context, llretptr));
}
+ fcx.cleanup();
}
// For each foreign function F, we generate a wrapper function W and a shim
debug!("build_direct_fn(%s)", link_name(ccx, item));
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
+ let bcx = fcx.entry_bcx.get();
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
let ty = ty::lookup_item_type(ccx.tcx,
ast_util::local_def(item.id)).ty;
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
Store(bcx, retval, fcx.llretptr.get());
}
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
}
// FIXME (#2535): this is very shaky and probably gets ABIs wrong all
debug!("build_fast_ffi_fn(%s)", link_name(ccx, item));
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
+ let bcx = fcx.entry_bcx.get();
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
set_no_inline(fcx.llfn);
set_fixed_stack_segment(fcx.llfn);
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
Store(bcx, retval, fcx.llretptr.get());
}
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
}
fn build_wrap_fn(ccx: @mut CrateContext,
output_type,
true,
Some(substs),
+ None,
Some(item.span));
set_always_inline(fcx.llfn);
set_fixed_stack_segment(fcx.llfn);
}
- let mut bcx = top_scope_block(fcx, None);
+ let mut bcx = fcx.entry_bcx.get();
let first_real_arg = fcx.arg_pos(0u);
let nm = ccx.sess.str_of(item.ident);
}
}
+ fcx.cleanup();
return;
}
ccx.sess.span_bug(item.span, "unknown intrinsic");
}
}
+ fcx.cleanup();
}
/**
pub fn trans_foreign_fn(ccx: @mut CrateContext,
path: ast_map::path,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
llwrapfn: ValueRef,
id: ast::node_id) {
let _icx = push_ctxt("foreign::build_foreign_fn");
fn build_rust_fn(ccx: @mut CrateContext,
path: &ast_map::path,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
id: ast::node_id)
-> ValueRef {
let _icx = push_ctxt("foreign::foreign::build_rust_fn");
let _icx = push_ctxt("decr_refcnt_maybe_free");
let ccx = bcx.ccx();
- do with_cond(bcx, IsNotNull(bcx, box_ptr)) |bcx| {
- let rc_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_refcnt]);
- let rc = Sub(bcx, Load(bcx, rc_ptr), C_int(ccx, 1));
- Store(bcx, rc, rc_ptr);
- let zero_test = ICmp(bcx, lib::llvm::IntEQ, C_int(ccx, 0), rc);
- do with_cond(bcx, zero_test) |bcx| {
- match box_ptr_ptr {
- Some(p) => free_ty(bcx, p, t),
- None => free_ty_immediate(bcx, box_ptr, t)
- }
- }
- }
+ let decr_bcx = sub_block(bcx, "decr");
+ let free_bcx = sub_block(decr_bcx, "free");
+ let next_bcx = sub_block(bcx, "next");
+ CondBr(bcx, IsNotNull(bcx, box_ptr), decr_bcx.llbb, next_bcx.llbb);
+
+ let rc_ptr = GEPi(decr_bcx, box_ptr, [0u, abi::box_field_refcnt]);
+ let rc = Sub(decr_bcx, Load(decr_bcx, rc_ptr), C_int(ccx, 1));
+ Store(decr_bcx, rc, rc_ptr);
+ CondBr(decr_bcx, IsNull(decr_bcx, rc), free_bcx.llbb, next_bcx.llbb);
+
+ let free_bcx = match box_ptr_ptr {
+ Some(p) => free_ty(free_bcx, p, t),
+ None => free_ty_immediate(free_bcx, box_ptr, t)
+ };
+ Br(free_bcx, next_bcx.llbb);
+
+ next_bcx
}
// Zero out the struct
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(v));
- memzero(bcx, v, ty);
+ memzero(&B(bcx), v, ty);
}
}
// llfn is expected be declared to take a parameter of the appropriate
// type, so we don't need to explicitly cast the function parameter.
- let bcx = top_scope_block(fcx, None);
- let lltop = bcx.llbb;
+ let bcx = fcx.entry_bcx.get();
let rawptr0_arg = fcx.arg_pos(0u);
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
let bcx = helper(bcx, llrawptr0, t);
- finish_fn(fcx, lltop, bcx);
+ finish_fn(fcx, bcx);
return llfn;
}
pub mod consts;
pub mod type_of;
pub mod build;
+pub mod builder;
pub mod base;
pub mod _match;
pub mod uniq;
//
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
};
- let mut bcx = top_scope_block(fcx, None);
+ let mut bcx = fcx.entry_bcx.get();
let arg = BitCast(bcx, arg, llptrty);
let ret = adt::trans_get_discr(bcx, repr, arg);
Store(bcx, ret, fcx.llretptr.get());
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
None => bcx = cleanup_block(bcx, Some(bcx.llbb))
};
- finish_fn(fcx, bcx.llbb, bcx);
+ finish_fn(fcx, bcx);
llfdecl
};
}
}
-pub fn handle_body(cx: &Context, body: &blk) {
+pub fn handle_body(cx: &Context, body: &Block) {
let v = visit::mk_vt(@visit::Visitor {
visit_expr: |e, (cx, v)| {
visit::visit_expr(e, (cx, v));
},
visit_local: |l, (cx, v)| {
visit::visit_local(l, (cx, v));
- node_type_needs(cx, use_repr, l.node.id);
+ node_type_needs(cx, use_repr, l.id);
},
visit_pat: |p, (cx, v)| {
visit::visit_pat(p, (cx, v));
}
// Type accessors for AST nodes
-pub fn block_ty(cx: ctxt, b: &ast::blk) -> t {
+pub fn block_ty(cx: ctxt, b: &ast::Block) -> t {
return node_id_to_type(cx, b.id);
}
PurityState { def: def, purity: purity, from_fn: true }
}
- pub fn recurse(&mut self, blk: &ast::blk) -> PurityState {
+ pub fn recurse(&mut self, blk: &ast::Block) -> PurityState {
match self.purity {
// If this unsafe, then if the outer function was already marked as
// unsafe we shouldn't attribute the unsafe'ness to the block. This
}
}
-pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) {
+pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
let visit = visit::mk_simple_visitor(@visit::SimpleVisitor {
visit_item: |a| check_item(ccx, a),
.. *visit::default_simple_visitor()
pub fn check_bare_fn(ccx: @mut CrateCtxt,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
id: ast::node_id,
self_info: Option<SelfInfo>) {
let fty = ty::node_id_to_type(ccx.tcx, id);
fn_sig: &ty::FnSig,
decl: &ast::fn_decl,
id: ast::node_id,
- body: &ast::blk,
+ body: &ast::Block,
fn_kind: FnKind,
inherited_isr: isr_alist,
inherited: @inherited) -> @mut FnCtxt
fn gather_locals(fcx: @mut FnCtxt,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
arg_tys: &[ty::t],
opt_self_info: Option<SelfInfo>) {
let tcx = fcx.ccx.tcx;
}
// Add explicitly-declared locals.
- let visit_local: @fn(@ast::local, ((), visit::vt<()>)) =
+ let visit_local: @fn(@ast::Local, ((), visit::vt<()>)) =
|local, (e, v)| {
- let o_ty = match local.node.ty.node {
+ let o_ty = match local.ty.node {
ast::ty_infer => None,
- _ => Some(fcx.to_ty(&local.node.ty))
+ _ => Some(fcx.to_ty(&local.ty))
};
- assign(local.node.id, o_ty);
+ assign(local.id, o_ty);
debug!("Local variable %s is assigned type %s",
- fcx.pat_to_str(local.node.pat),
+ fcx.pat_to_str(local.pat),
fcx.infcx().ty_to_str(
- fcx.inh.locals.get_copy(&local.node.id)));
+ fcx.inh.locals.get_copy(&local.id)));
visit::visit_local(local, (e, v));
};
visit::visit_pat(p, (e, v));
};
- let visit_block: @fn(&ast::blk, ((), visit::vt<()>)) = |b, (e, v)| {
+ let visit_block: @fn(&ast::Block, ((), visit::vt<()>)) = |b, (e, v)| {
// non-obvious: the `blk` variable maps to region lb, so
// we have to keep this up-to-date. This
// is... unfortunate. It'd be nice to not need this.
// Don't descend into fns and items
fn visit_fn(_fk: &visit::fn_kind, _decl: &ast::fn_decl,
- _body: &ast::blk, _sp: span,
+ _body: &ast::Block, _sp: span,
_id: ast::node_id, (_t,_v): ((), visit::vt<()>)) {
}
fn visit_item(_i: @ast::item, (_e,_v): ((), visit::vt<()>)) { }
// or if-check
fn check_then_else(fcx: @mut FnCtxt,
cond_expr: @ast::expr,
- then_blk: &ast::blk,
+ then_blk: &ast::Block,
opt_else_expr: Option<@ast::expr>,
id: ast::node_id,
sp: span,
expr: @ast::expr,
ast_sigil_opt: Option<ast::Sigil>,
decl: &ast::fn_decl,
- body: &ast::blk,
+ body: &ast::Block,
fn_kind: FnKind,
expected: Option<ty::t>) {
let tcx = fcx.ccx.tcx;
node_id: ast::node_id,
substitutions: ty::substs,
field_types: &[ty::field_ty],
- ast_fields: &[ast::field],
+ ast_fields: &[ast::Field],
check_completeness: bool) {
let tcx = fcx.ccx.tcx;
for ast_fields.iter().advance |field| {
let mut expected_field_type = ty::mk_err();
- let pair = class_field_map.find(&field.node.ident).
+ let pair = class_field_map.find(&field.ident).
map_consume(|x| *x);
match pair {
None => {
tcx.sess.span_err(
field.span,
fmt!("structure has no field named `%s`",
- tcx.sess.str_of(field.node.ident)));
+ tcx.sess.str_of(field.ident)));
error_happened = true;
}
Some((_, true)) => {
tcx.sess.span_err(
field.span,
fmt!("field `%s` specified more than once",
- tcx.sess.str_of(field.node.ident)));
+ tcx.sess.str_of(field.ident)));
error_happened = true;
}
Some((field_id, false)) => {
ty::lookup_field_type(
tcx, class_id, field_id, &substitutions);
class_field_map.insert(
- field.node.ident, (field_id, true));
+ field.ident, (field_id, true));
fields_found += 1;
}
}
// an error, so we can continue typechecking
check_expr_coercable_to_type(
fcx,
- field.node.expr,
+ field.expr,
expected_field_type);
}
id: ast::node_id,
span: codemap::span,
class_id: ast::def_id,
- fields: &[ast::field],
+ fields: &[ast::Field],
base_expr: Option<@ast::expr>) {
let tcx = fcx.ccx.tcx;
span: codemap::span,
enum_id: ast::def_id,
variant_id: ast::def_id,
- fields: &[ast::field]) {
+ fields: &[ast::Field]) {
let tcx = fcx.ccx.tcx;
// Look up the number of type parameters and the raw type, and
check_expr_coercable_to_type(fcx, init, local_ty)
}
-pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) {
+pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::Local) {
let tcx = fcx.ccx.tcx;
- let t = fcx.local_ty(local.span, local.node.id);
- fcx.write_ty(local.node.id, t);
+ let t = fcx.local_ty(local.span, local.id);
+ fcx.write_ty(local.id, t);
- match local.node.init {
+ match local.init {
Some(init) => {
- check_decl_initializer(fcx, local.node.id, init);
+ check_decl_initializer(fcx, local.id, init);
let init_ty = fcx.expr_ty(init);
if ty::type_is_error(init_ty) || ty::type_is_bot(init_ty) {
- fcx.write_ty(local.node.id, init_ty);
+ fcx.write_ty(local.id, init_ty);
}
}
_ => {}
let pcx = pat_ctxt {
fcx: fcx,
- map: pat_id_map(tcx.def_map, local.node.pat),
+ map: pat_id_map(tcx.def_map, local.pat),
};
- _match::check_pat(&pcx, local.node.pat, t);
- let pat_ty = fcx.node_ty(local.node.pat.id);
+ _match::check_pat(&pcx, local.pat, t);
+ let pat_ty = fcx.node_ty(local.pat.id);
if ty::type_is_error(pat_ty) || ty::type_is_bot(pat_ty) {
- fcx.write_ty(local.node.id, pat_ty);
+ fcx.write_ty(local.id, pat_ty);
}
}
match decl.node {
ast::decl_local(ref l) => {
check_decl_local(fcx, *l);
- let l_t = fcx.node_ty(l.node.id);
+ let l_t = fcx.node_ty(l.id);
saw_bot = saw_bot || ty::type_is_bot(l_t);
saw_err = saw_err || ty::type_is_error(l_t);
}
}
}
-pub fn check_block_no_value(fcx: @mut FnCtxt, blk: &ast::blk) {
+pub fn check_block_no_value(fcx: @mut FnCtxt, blk: &ast::Block) {
check_block_with_expected(fcx, blk, Some(ty::mk_nil()));
let blkty = fcx.node_ty(blk.id);
if ty::type_is_error(blkty) {
}
}
-pub fn check_block(fcx0: @mut FnCtxt, blk: &ast::blk) {
+pub fn check_block(fcx0: @mut FnCtxt, blk: &ast::Block) {
check_block_with_expected(fcx0, blk, None)
}
pub fn check_block_with_expected(fcx: @mut FnCtxt,
- blk: &ast::blk,
+ blk: &ast::Block,
expected: Option<ty::t>) {
let purity_state = fcx.ps.recurse(blk);
let prev = replace(&mut fcx.ps, purity_state);
}
// Returns true if b contains a break that can exit from b
-pub fn may_break(cx: ty::ctxt, id: ast::node_id, b: &ast::blk) -> bool {
+pub fn may_break(cx: ty::ctxt, id: ast::node_id, b: &ast::Block) -> bool {
// First: is there an unlabeled break immediately
// inside the loop?
(loop_query(b, |e| {
fcx.infcx().resolve_regions();
}
-pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::blk) {
+pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) {
let rcx = @mut Rcx { fcx: fcx, errors_reported: 0,
repeating_scope: blk.id };
if fcx.err_count_since_creation() == 0 {
// Ignore items
}
-fn visit_block(b: &ast::blk, (rcx, v): (@mut Rcx, rvt)) {
+fn visit_block(b: &ast::Block, (rcx, v): (@mut Rcx, rvt)) {
rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
visit::visit_block(b, (rcx, v));
}
visit::visit_arm(arm, (rcx, v));
}
-fn visit_local(l: @ast::local, (rcx, v): (@mut Rcx, rvt)) {
+fn visit_local(l: @ast::Local, (rcx, v): (@mut Rcx, rvt)) {
// see above
- constrain_bindings_in_pat(l.node.pat, rcx);
+ constrain_bindings_in_pat(l.pat, rcx);
visit::visit_local(l, (rcx, v));
}
// Detect points where a trait-bounded type parameter is
// instantiated, resolve the impls for the parameters.
-pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::blk) {
+pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) {
visit::visit_block(bl, (fcx, visit::mk_vt(@visit::Visitor {
visit_expr: resolve_expr,
visit_item: |_,_| {},
visit::visit_expr(e, (wbcx, v));
}
-fn visit_block(b: &ast::blk, (wbcx, v): (@mut WbCtxt, wb_vt)) {
+fn visit_block(b: &ast::Block, (wbcx, v): (@mut WbCtxt, wb_vt)) {
if !wbcx.success {
return;
}
visit::visit_pat(p, (wbcx, v));
}
-fn visit_local(l: @ast::local, (wbcx, v): (@mut WbCtxt, wb_vt)) {
+fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, wb_vt)) {
if !wbcx.success { return; }
- let var_ty = wbcx.fcx.local_ty(l.span, l.node.id);
+ let var_ty = wbcx.fcx.local_ty(l.span, l.id);
match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) {
Ok(lty) => {
debug!("Type for local %s (id %d) resolved to %s",
- pat_to_str(l.node.pat, wbcx.fcx.tcx().sess.intr()),
- l.node.id,
+ pat_to_str(l.pat, wbcx.fcx.tcx().sess.intr()),
+ l.id,
wbcx.fcx.infcx().ty_to_str(lty));
- write_ty_to_tcx(wbcx.fcx.ccx.tcx, l.node.id, lty);
+ write_ty_to_tcx(wbcx.fcx.ccx.tcx, l.id, lty);
}
Err(e) => {
wbcx.fcx.ccx.tcx.sess.span_err(
pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt,
decl: &ast::fn_decl,
- blk: &ast::blk,
+ blk: &ast::Block,
self_info: Option<SelfInfo>) -> bool {
let wbcx = @mut WbCtxt { fcx: fcx, success: true };
let visit = mk_visitor();
use middle::typeck::infer::InferCtxt;
use middle::typeck::infer::{new_infer_ctxt, resolve_ivar, resolve_type};
use middle::typeck::infer;
-use syntax::ast::{crate, def_id, def_struct, def_ty};
+use syntax::ast::{Crate, def_id, def_struct, def_ty};
use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct};
use syntax::ast::{local_crate, trait_ref, ty_path};
use syntax::ast;
}
impl CoherenceChecker {
- pub fn check_coherence(self, crate: &crate) {
+ pub fn check_coherence(self, crate: &Crate) {
// Check implementations and traits. This populates the tables
// containing the inherent methods and extension methods. It also
// builds up the trait inheritance table.
}
// Privileged scope checking
- pub fn check_privileged_scopes(self, crate: &crate) {
+ pub fn check_privileged_scopes(self, crate: &Crate) {
visit_crate(crate, ((), mk_vt(@Visitor {
visit_item: |item, (_context, visitor)| {
match item.node {
)
}
-pub fn check_coherence(crate_context: @mut CrateCtxt, crate: &crate) {
+pub fn check_coherence(crate_context: @mut CrateCtxt, crate: &Crate) {
let coherence_checker = CoherenceChecker(crate_context);
coherence_checker.check_coherence(crate);
}
use syntax::opt_vec;
use syntax::parse::token::special_idents;
-pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) {
+pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
fn collect_intrinsic_type(ccx: &CrateCtxt,
lang_item: ast::def_id) {
let ty::ty_param_bounds_and_ty { ty: ty, _ } =
use syntax::{ast, attr, parse};
struct Env {
- crate: @ast::crate,
+ crate: @ast::Crate,
tcx: ty::ctxt,
infcx: infer::infer_ctxt,
err_messages: @DVec<~str>
pub fn check_crate(tcx: ty::ctxt,
trait_map: resolve::TraitMap,
- crate: &ast::crate)
+ crate: &ast::Crate)
-> (method_map, vtable_map) {
let time_passes = tcx.sess.time_passes();
let ccx = @mut CrateCtxt {
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
-#[deny(deprecated_pattern)];
-
extern mod extra;
extern mod syntax;
_indenter(())
}
-pub fn field_expr(f: ast::field) -> @ast::expr { return f.node.expr; }
+pub fn field_expr(f: ast::Field) -> @ast::expr { return f.expr; }
-pub fn field_exprs(fields: ~[ast::field]) -> ~[@ast::expr] {
- fields.map(|f| f.node.expr)
+pub fn field_exprs(fields: ~[ast::Field]) -> ~[@ast::expr] {
+ fields.map(|f| f.expr)
}
// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query(b: &ast::blk, p: @fn(&ast::expr_) -> bool) -> bool {
+pub fn loop_query(b: &ast::Block, p: @fn(&ast::expr_) -> bool) -> bool {
let rs = @mut false;
let visit_expr: @fn(@ast::expr,
(@mut bool,
// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query(b: &ast::blk, p: @fn(@ast::expr) -> bool) -> bool {
+pub fn block_query(b: &ast::Block, p: @fn(@ast::expr) -> bool) -> bool {
let rs = @mut false;
let visit_expr: @fn(@ast::expr,
(@mut bool,
return *rs;
}
-pub fn local_rhs_span(l: @ast::local, def: span) -> span {
- match l.node.init {
+pub fn local_rhs_span(l: @ast::Local, def: span) -> span {
+ match l.init {
Some(i) => return i.span,
_ => return def
}
use syntax;
pub struct Ctxt {
- ast: @ast::crate,
+ ast: @ast::Crate,
ast_map: ast_map::map
}
type SrvOwner<'self,T> = &'self fn(srv: Srv) -> T;
pub type CtxtHandler<T> = ~fn(ctxt: Ctxt) -> T;
-type Parser = ~fn(Session, s: @str) -> @ast::crate;
+type Parser = ~fn(Session, s: @str) -> @ast::Crate;
enum Msg {
HandleRequest(~fn(Ctxt)),
}
fn build_ctxt(sess: Session,
- ast: @ast::crate) -> Ctxt {
+ ast: @ast::Crate) -> Ctxt {
use rustc::front::config;
do from_str(source) |srv| {
do exec(srv) |ctxt| {
// one item: the __std_macros secret module
- assert_eq!(ctxt.ast.node.module.items.len(), 1);
+ assert_eq!(ctxt.ast.module.items.len(), 1);
}
}
}
let doc = fold::default_seq_fold_crate(fold, doc);
let attrs = do astsrv::exec(srv) |ctxt| {
- let attrs = ctxt.ast.node.attrs.clone();
+ let attrs = ctxt.ast.attrs.clone();
attr_parser::parse_crate(attrs)
};
let desc = if doc.id == ast::crate_node_id {
// This is the top-level mod, use the crate attributes
do astsrv::exec(srv) |ctxt| {
- attr_parser::parse_desc(ctxt.ast.node.attrs.clone())
+ attr_parser::parse_desc(ctxt.ast.attrs.clone())
}
} else {
parse_item_attrs(srv, doc.id, attr_parser::parse_desc)
}
pub fn extract(
- crate: @ast::crate,
+ crate: @ast::Crate,
default_name: ~str
) -> doc::Doc {
doc::Doc {
}
fn top_moddoc_from_crate(
- crate: @ast::crate,
+ crate: @ast::Crate,
default_name: ~str
) -> doc::ModDoc {
moddoc_from_mod(mk_itemdoc(ast::crate_node_id, default_name),
- crate.node.module.clone())
+ crate.module.clone())
}
fn mk_itemdoc(id: ast::node_id, name: ~str) -> doc::ItemDoc {
use syntax::ast;
use syntax::parse;
-pub fn from_file(file: &Path) -> @ast::crate {
+pub fn from_file(file: &Path) -> @ast::Crate {
parse::parse_crate_from_file(
file, ~[], parse::new_parse_sess(None))
}
-pub fn from_str(source: @str) -> @ast::crate {
+pub fn from_str(source: @str) -> @ast::Crate {
parse::parse_crate_from_source_str(
@"-", source, ~[], parse::new_parse_sess(None))
}
-pub fn from_file_sess(sess: session::Session, file: &Path) -> @ast::crate {
+pub fn from_file_sess(sess: session::Session, file: &Path) -> @ast::Crate {
parse::parse_crate_from_file(
file, cfg(sess, file_input((*file).clone())), sess.parse_sess)
}
-pub fn from_str_sess(sess: session::Session, source: @str) -> @ast::crate {
+pub fn from_str_sess(sess: session::Session, source: @str) -> @ast::Crate {
parse::parse_crate_from_source_str(
@"-", source, cfg(sess, str_input(source)), sess.parse_sess)
}
-fn cfg(sess: session::Session, input: driver::input) -> ast::crate_cfg {
+fn cfg(sess: session::Session, input: driver::input) -> ast::CrateConfig {
driver::build_configuration(sess, @"rustdoc", &input)
}
///
/// Once the types are known, they are inserted into the local_vars map in
/// this Program (to be deserialized later on
- pub fn register_new_vars(&mut self, blk: &ast::blk, tcx: ty::ctxt) {
+ pub fn register_new_vars(&mut self, blk: &ast::Block, tcx: ty::ctxt) {
debug!("looking for new variables");
let newvars = @mut HashMap::new();
do each_user_local(blk) |local| {
- let mutable = local.node.is_mutbl;
+ let mutable = local.is_mutbl;
do each_binding(local) |path, id| {
let name = do with_pp(token::get_ident_interner()) |pp, _| {
pprust::print_path(pp, path, false);
}
// helper functions to perform ast iteration
- fn each_user_local(blk: &ast::blk, f: &fn(@ast::local)) {
+ fn each_user_local(blk: &ast::Block, f: &fn(@ast::Local)) {
do find_user_block(blk) |blk| {
for blk.stmts.iter().advance |stmt| {
match stmt.node {
}
}
- fn find_user_block(blk: &ast::blk, f: &fn(&ast::blk)) {
+ fn find_user_block(blk: &ast::Block, f: &fn(&ast::Block)) {
for blk.stmts.iter().advance |stmt| {
match stmt.node {
ast::stmt_semi(e, _) => {
// Local declarations must be specially dealt with,
// record all local declarations for use later on
ast::decl_local(l) => {
- let mutbl = l.node.is_mutbl;
+ let mutbl = l.is_mutbl;
do each_binding(l) |path, _| {
let s = do with_pp(intr) |pp, _| {
pprust::print_path(pp, path, false);
return (program, jit::consume_engine());
fn parse_input(sess: session::Session, binary: @str,
- input: &str) -> @ast::crate {
+ input: &str) -> @ast::Crate {
let code = fmt!("fn main() {\n %s \n}", input);
let input = driver::str_input(code.to_managed());
let cfg = driver::build_configuration(sess, binary, &input);
crate.expect("parsing should return a crate")
}
- fn find_main(crate: @ast::crate, sess: session::Session,
- f: &fn(&ast::blk)) {
- for crate.node.module.items.iter().advance |item| {
+ fn find_main(crate: @ast::Crate, sess: session::Session,
+ f: &fn(&ast::Block)) {
+ for crate.module.items.iter().advance |item| {
match item.node {
ast::item_fn(_, _, _, _, ref blk) => {
if item.ident == sess.ident_of("main") {
use syntax::print::pprust;
use syntax::parse::token;
-pub fn each_binding(l: @ast::local, f: @fn(&ast::Path, ast::node_id)) {
+pub fn each_binding(l: @ast::Local, f: @fn(&ast::Path, ast::node_id)) {
use syntax::visit;
let vt = visit::mk_simple_visitor(
.. *visit::default_simple_visitor()
}
);
- (vt.visit_pat)(l.node.pat, ((), vt));
+ (vt.visit_pat)(l.pat, ((), vt));
}
/// A utility function that hands off a pretty printer to a callback.
/// build script
sess: session::Session,
/// The config for compiling the custom build script
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
/// The crate for the custom build script
- crate: @ast::crate,
+ crate: @ast::Crate,
/// Directory in which to store build output
build_dir: Path
}
// Tests above should (maybe) be converted to shell out to rustpkg, too
-#[test] #[ignore(cfg(target_arch = "x86"))]
+// FIXME: #7956: temporarily disabled
+#[ignore(cfg(target_arch = "x86"))]
fn test_install_git() {
let sysroot = test_sysroot();
debug!("sysroot = %s", sysroot.to_str());
}
-#[test] #[ignore(cfg(target_arch = "x86"))]
+// FIXME: #7956: temporarily disabled
+#[ignore(cfg(target_arch = "x86"))]
fn test_package_version() {
let local_path = "mockgithub.com/catamorphism/test_pkg_version";
let repo = init_git_repo(&Path(local_path));
&temp_dir);
}
-#[test]
+// FIXME: #7956: temporarily disabled
fn rustpkg_library_target() {
let foo_repo = init_git_repo(&Path("foo"));
let package_dir = foo_repo.push("foo");
struct ReadyCtx {
sess: session::Session,
- crate: @ast::crate,
+ crate: @ast::Crate,
ext_cx: @ExtCtxt,
path: ~[ast::ident],
fns: ~[ListenerFn]
/// Generate/filter main function, add the list of commands, etc.
pub fn ready_crate(sess: session::Session,
- crate: @ast::crate) -> @ast::crate {
+ crate: @ast::Crate) -> @ast::Crate {
let ctx = @mut ReadyCtx {
sess: sess,
crate: crate,
});
// Inject the link attributes so we get the right package name and version
- if attr::find_linkage_metas(crate.node.attrs).is_empty() {
+ if attr::find_linkage_metas(crate.attrs).is_empty() {
let short_name_to_use = match what {
Test => fmt!("%stest", pkg_id.short_name),
Bench => fmt!("%sbench", pkg_id.short_name),
~[attr::mk_name_value_item_str(@"name", short_name_to_use.to_managed()),
attr::mk_name_value_item_str(@"vers", pkg_id.version.to_str().to_managed())];
- crate = @codemap::respan(crate.span, ast::crate_ {
+ crate = @ast::Crate {
attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))],
- .. crate.node.clone()});
+ .. (*crate).clone()
+ };
}
debug!("calling compile_crate_from_input, out_dir = %s,
pub fn compile_crate_from_input(input: &driver::input,
build_dir: &Path,
sess: session::Session,
- crate: @ast::crate,
- cfg: ast::crate_cfg,
+ crate: @ast::Crate,
+ cfg: ast::CrateConfig,
compile_from: driver::compile_phase) {
debug!("Calling build_output_filenames with %s, building library? %?",
build_dir.to_str(), sess.building_library);
// bad copy
let outputs = driver::build_output_filenames(input, &Some((*build_dir).clone()), &None,
- crate.node.attrs, sess);
+ crate.attrs, sess);
debug!("Outputs are %? and output type = %?", outputs, sess.opts.output_type);
debug!("additional libraries:");
pub fn find_and_install_dependencies(ctxt: &Ctx,
sess: session::Session,
workspace: &Path,
- c: &ast::crate,
+ c: &ast::Crate,
save: @fn(Path)
) {
// :-(
Similar to a mutable option type, but friendlier.
*/
-#[mutable] // XXX remove after snap
#[no_freeze]
#[deriving(Clone, DeepClone, Eq)]
#[allow(missing_doc)]
false
}
-#[inline]
-#[cfg(not(stage0))]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- // This function should be inlined when stage0 is gone
- ((*tydesc).drop_glue)(data);
-}
-
-#[inline]
-#[cfg(stage0)]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- ((*tydesc).drop_glue)(0 as **TyDesc, data);
-}
-
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
pub unsafe fn annihilate() {
use rt::local_heap::local_free;
if !uniq {
let tydesc: *TyDesc = transmute((*box).header.type_desc);
let data = transmute(&(*box).data);
- call_drop_glue(tydesc, data);
+ ((*tydesc).drop_glue)(data);
}
}
prev: Option<@Handler<T, U>>,
}
-#[cfg(stage0)]
-pub struct Condition<'self, T, U> {
- name: &'static str,
- key: local_data::Key<'self, @Handler<T, U>>
-}
-#[cfg(not(stage0))]
pub struct Condition<T, U> {
name: &'static str,
key: local_data::Key<@Handler<T, U>>
}
-#[cfg(not(stage0))]
impl<T, U> Condition<T, U> {
pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
unsafe {
}
}
}
-#[cfg(stage0)]
-impl<'self, T, U> Condition<'self, T, U> {
- pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
- unsafe {
- let p : *RustClosure = ::cast::transmute(&h);
- let prev = local_data::get(::cast::unsafe_copy(&self.key),
- |k| k.map(|&x| *x));
- let h = @Handler { handle: *p, prev: prev };
- Trap { cond: self, handler: h }
- }
- }
-
- pub fn raise(&self, t: T) -> U {
- let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
- self.raise_default(t, || fail!(msg.clone()))
- }
-
- pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
- unsafe {
- match local_data::pop(::cast::unsafe_copy(&self.key)) {
- None => {
- debug!("Condition.raise: found no handler");
- default()
- }
- Some(handler) => {
- debug!("Condition.raise: found handler");
- match handler.prev {
- None => {}
- Some(hp) => {
- local_data::set(::cast::unsafe_copy(&self.key),
- hp)
- }
- }
- let handle : &fn(T) -> U =
- ::cast::transmute(handler.handle);
- let u = handle(t);
- local_data::set(::cast::unsafe_copy(&self.key), handler);
- u
- }
- }
- }
- }
-}
-#[cfg(stage0)]
-struct Trap<'self, T, U> {
- cond: &'self Condition<'self, T, U>,
- handler: @Handler<T, U>
-}
-#[cfg(not(stage0))]
struct Trap<'self, T, U> {
cond: &'self Condition<T, U>,
handler: @Handler<T, U>
}
}
-#[cfg(stage0)]
-struct Guard<'self, T, U> {
- cond: &'self Condition<'self, T, U>
-}
-#[cfg(not(stage0))]
struct Guard<'self, T, U> {
cond: &'self Condition<T, U>
}
#[cfg(nogc)]
fn expect_sentinel() -> bool { false }
-#[inline]
-#[cfg(not(stage0))]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- // This function should be inlined when stage0 is gone
- ((*tydesc).drop_glue)(data);
-}
-
-#[inline]
-#[cfg(stage0)]
-unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
- ((*tydesc).drop_glue)(0 as **TyDesc, data);
-}
-
// Entry point for GC-based cleanup. Walks stack looking for exchange
// heap and stack allocations requiring drop, and runs all
// destructors.
// FIXME #4420: Destroy this box
// FIXME #4330: Destroy this box
} else {
- call_drop_glue(tydesc, *root as *i8);
+ ((*tydesc).drop_glue)(*root as *i8);
}
}
}
#[allow(missing_doc)];
-#[cfg(stage0)]
-#[lang="copy"]
-pub trait Copy {
- // Empty.
-}
-
-#[cfg(stage0)]
-#[lang="owned"]
-pub trait Send {
- // empty.
-}
-
-#[cfg(not(stage0))]
#[lang="send"]
pub trait Send {
// empty.
}
-#[cfg(stage0)]
-#[lang="const"]
-pub trait Freeze {
- // empty.
-}
-
-#[cfg(not(stage0))]
#[lang="freeze"]
pub trait Freeze {
// empty.
* sections to ensure that each value of the `Key` type points to a unique
* location.
*/
-#[cfg(not(stage0))]
pub type Key<T> = &'static KeyValue<T>;
-#[cfg(stage0)]
-pub type Key<'self,T> = &'self fn(v: T);
pub enum KeyValue<T> { Key }
* Remove a task-local data value from the table, returning the
* reference that was originally created to insert it.
*/
-#[cfg(stage0)]
-pub fn pop<T: 'static>(key: Key<@T>) -> Option<@T> {
- unsafe { local_pop(Handle::new(), key) }
-}
-/**
- * Remove a task-local data value from the table, returning the
- * reference that was originally created to insert it.
- */
-#[cfg(not(stage0))]
pub fn pop<T: 'static>(key: Key<T>) -> Option<T> {
unsafe { local_pop(Handle::new(), key) }
}
+
/**
* Retrieve a task-local data value. It will also be kept alive in the
* table until explicitly removed.
*/
-#[cfg(stage0)]
-pub fn get<T: 'static, U>(key: Key<@T>, f: &fn(Option<&@T>) -> U) -> U {
- unsafe { local_get(Handle::new(), key, f) }
-}
-/**
- * Retrieve a task-local data value. It will also be kept alive in the
- * table until explicitly removed.
- */
-#[cfg(not(stage0))]
pub fn get<T: 'static, U>(key: Key<T>, f: &fn(Option<&T>) -> U) -> U {
unsafe { local_get(Handle::new(), key, f) }
}
+
/**
* Retrieve a mutable borrowed pointer to a task-local data value.
*/
-#[cfg(not(stage0))]
pub fn get_mut<T: 'static, U>(key: Key<T>, f: &fn(Option<&mut T>) -> U) -> U {
unsafe { local_get_mut(Handle::new(), key, f) }
}
+
/**
* Store a value in task-local data. If this key already has a value,
* that value is overwritten (and its destructor is run).
*/
-#[cfg(stage0)]
-pub fn set<T: 'static>(key: Key<@T>, data: @T) {
- unsafe { local_set(Handle::new(), key, data) }
-}
-/**
- * Store a value in task-local data. If this key already has a value,
- * that value is overwritten (and its destructor is run).
- */
-#[cfg(not(stage0))]
pub fn set<T: 'static>(key: Key<T>, data: T) {
unsafe { local_set(Handle::new(), key, data) }
}
+
/**
* Modify a task-local data value. If the function returns 'None', the
* data is removed (and its reference dropped).
*/
-#[cfg(stage0)]
-pub fn modify<T: 'static>(key: Key<@T>, f: &fn(Option<@T>) -> Option<@T>) {
- match f(pop(key)) {
- Some(next) => { set(key, next); }
- None => {}
- }
-}
-/**
- * Modify a task-local data value. If the function returns 'None', the
- * data is removed (and its reference dropped).
- */
-#[cfg(not(stage0))]
pub fn modify<T: 'static>(key: Key<T>, f: &fn(Option<T>) -> Option<T>) {
unsafe {
match f(pop(::cast::unsafe_copy(&key))) {
val: ~[~str]
}
-#[cfg(stage0)]
-fn overridden_arg_key(_v: @OverriddenArgs) {}
-#[cfg(not(stage0))]
static overridden_arg_key: local_data::Key<@OverriddenArgs> = &local_data::Key;
/// Returns the arguments which this program was started with (normally passed
}
// used to make space in TLS for a random number generator
-#[cfg(stage0)]
-fn tls_rng_state(_v: @@mut IsaacRng) {}
-#[cfg(not(stage0))]
static tls_rng_state: local_data::Key<@@mut IsaacRng> = &local_data::Key;
/**
#[allow(missing_doc)];
-#[cfg(stage0)]
-use intrinsic::{Opaque, TyDesc, TyVisitor};
-#[cfg(not(stage0))]
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
use libc::c_void;
use sys;
true
}
- #[cfg(stage0)]
- fn visit_str(&self) -> bool {
- self.align_to::<~str>();
- if ! self.inner.visit_str() { return false; }
- self.bump_past::<~str>();
- true
- }
-
fn visit_estr_box(&self) -> bool {
self.align_to::<@str>();
if ! self.inner.visit_estr_box() { return false; }
true
}
- #[cfg(not(stage0))]
fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<~u8>();
if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; }
true
}
- #[cfg(not(stage0))]
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<~[@u8]>();
if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
use vec::raw::{VecRepr, SliceRepr};
use vec;
use vec::{OwnedVector, UnboxedVecRepr};
-#[cfg(stage0)]
-use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
-#[cfg(not(stage0))]
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
#[cfg(test)] use io;
}
}
- // Type no longer exists, vestigial function.
- #[cfg(stage0)]
- fn visit_str(&self) -> bool { fail!(); }
-
fn visit_estr_box(&self) -> bool {
do self.get::<@str> |s| {
self.writer.write_char('@');
}
}
- #[cfg(not(stage0))]
fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
self.writer.write_char('~');
do self.get::<&managed::raw::BoxRepr> |b| {
}
}
- #[cfg(stage0)]
- fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
- do self.get::<&VecRepr> |b| {
- self.writer.write_char('~');
- self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
- }
- }
-
- #[cfg(not(stage0))]
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&UnboxedVecRepr> |b| {
self.writer.write_char('~');
}
}
- #[cfg(not(stage0))]
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&VecRepr> |b| {
self.writer.write_char('~');
fn visit_self(&self) -> bool { true }
fn visit_type(&self) -> bool { true }
- #[cfg(not(stage0))]
fn visit_opaque_box(&self) -> bool {
self.writer.write_char('@');
do self.get::<&managed::raw::BoxRepr> |b| {
self.visit_ptr_inner(p, b.header.type_desc);
}
}
- #[cfg(stage0)]
- fn visit_opaque_box(&self) -> bool {
- self.writer.write_char('@');
- do self.get::<&managed::raw::BoxRepr> |b| {
- let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
- unsafe {
- self.visit_ptr_inner(p, transmute(b.header.type_desc));
- }
- }
- }
// Type no longer exists, vestigial function.
fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); }
}
#[cfg(test)]
-#[allow(non_implicitly_copyable_typarams)]
mod tests {
use result::{Err, Ok, Result, chain, get, get_err};
use result;
p
}
-// FIXME #4942: Make these signatures agree with exchange_alloc's signatures
-#[cfg(stage0, not(test))]
-#[lang="exchange_malloc"]
-#[inline]
-pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
- let td = td as *TyDesc;
- let size = size as uint;
-
- assert!(td.is_not_null());
-
- let total_size = get_box_size(size, (*td).align);
- let p = malloc_raw(total_size as uint);
-
- let box: *mut BoxRepr = p as *mut BoxRepr;
- (*box).header.ref_count = -1;
- (*box).header.type_desc = td;
-
- box as *c_char
-}
-
/// The allocator for unique pointers without contained managed pointers.
-#[cfg(not(stage0), not(test))]
+#[cfg(not(test))]
#[lang="exchange_malloc"]
#[inline]
pub unsafe fn exchange_malloc(size: uintptr_t) -> *c_char {
use char;
use char::Char;
use clone::Clone;
-use container::Container;
+use container::{Container, Mutable};
use iter::Times;
use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIterator};
use libc;
/// Sets the length of the string and adds the null terminator
#[inline]
- #[cfg(stage0)]
- pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
- let v: **mut vec::raw::VecRepr = cast::transmute(v);
- let repr: *mut vec::raw::VecRepr = *v;
- (*repr).unboxed.fill = new_len + 1u;
- let null = ptr::mut_offset(cast::transmute(&((*repr).unboxed.data)),
- new_len);
- *null = 0u8;
- }
-
- /// Sets the length of the string and adds the null terminator
- #[inline]
- #[cfg(not(stage0))]
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
let repr: *mut vec::UnboxedVecRepr = *v;
}
}
+impl Container for ~str {
+ #[inline]
+ fn len(&self) -> uint { self.as_slice().len() }
+ #[inline]
+ fn is_empty(&self) -> bool { self.len() == 0 }
+}
+
+impl Container for @str {
+ #[inline]
+ fn len(&self) -> uint { self.as_slice().len() }
+ #[inline]
+ fn is_empty(&self) -> bool { self.len() == 0 }
+}
+
+impl Mutable for ~str {
+ /// Remove all content, make the string empty
+ #[inline]
+ fn clear(&mut self) {
+ unsafe {
+ raw::set_len(self, 0)
+ }
+ }
+}
+
+
#[allow(missing_doc)]
pub trait StrSlice<'self> {
fn contains<'a>(&self, needle: &'a str) -> bool;
assert_eq!(~"华ประเทศไทย中", data);
}
+ #[test]
+ fn test_clear() {
+ let mut empty = ~"";
+ empty.clear();
+ assert_eq!("", empty.as_slice());
+ let mut data = ~"ประเทศไทย中";
+ data.clear();
+ assert_eq!("", data.as_slice());
+ data.push_char('华');
+ assert_eq!("华", data.as_slice());
+ }
+
#[test]
fn test_split_within() {
fn t(s: &str, i: uint, u: &[~str]) {
t::<@str>();
t::<~str>();
}
+
+ #[test]
+ fn test_str_container() {
+ fn sum_len<S: Container>(v: &[S]) -> uint {
+ v.iter().transform(|x| x.len()).sum()
+ }
+
+ let s = ~"01234";
+ assert_eq!(5, sum_len(["012", "", "34"]));
+ assert_eq!(5, sum_len([@"01", @"2", @"34", @""]));
+ assert_eq!(5, sum_len([~"01", ~"2", ~"34", ~""]));
+ assert_eq!(5, sum_len([s.as_slice()]));
+ }
}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[allow(missing_doc)];
-
-use cast;
-use cmp::Eq;
-use libc;
-use local_data;
-use prelude::*;
-use sys;
-use task::rt;
-
-use super::rt::rust_task;
-use rt::task::{Task, LocalStorage};
-
-pub enum Handle {
- OldHandle(*rust_task),
- NewHandle(*mut LocalStorage)
-}
-
-impl Handle {
- pub fn new() -> Handle {
- use rt::{context, OldTaskContext};
- use rt::local::Local;
- unsafe {
- match context() {
- OldTaskContext => {
- OldHandle(rt::rust_get_task())
- }
- _ => {
- let task = Local::unsafe_borrow::<Task>();
- NewHandle(&mut (*task).storage)
- }
- }
- }
- }
-}
-
-pub trait LocalData { }
-impl<T: 'static> LocalData for @T { }
-
-impl Eq for @LocalData {
- fn eq(&self, other: &@LocalData) -> bool {
- unsafe {
- let ptr_a: &(uint, uint) = cast::transmute(self);
- let ptr_b: &(uint, uint) = cast::transmute(other);
- return ptr_a == ptr_b;
- }
- }
- fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) }
-}
-
-// If TLS is used heavily in future, this could be made more efficient with a
-// proper map.
-type TaskLocalElement = (*libc::c_void, *libc::c_void, @LocalData);
-// Has to be a pointer at outermost layer; the foreign call returns void *.
-type TaskLocalMap = ~[Option<TaskLocalElement>];
-
-fn cleanup_task_local_map(map_ptr: *libc::c_void) {
- unsafe {
- assert!(!map_ptr.is_null());
- // Get and keep the single reference that was created at the
- // beginning.
- let _map: TaskLocalMap = cast::transmute(map_ptr);
- // All local_data will be destroyed along with the map.
- }
-}
-
-// Gets the map from the runtime. Lazily initialises if not done so already.
-unsafe fn get_local_map(handle: Handle) -> &mut TaskLocalMap {
- match handle {
- OldHandle(task) => get_task_local_map(task),
- NewHandle(local_storage) => get_newsched_local_map(local_storage)
- }
-}
-
-unsafe fn get_task_local_map(task: *rust_task) -> &mut TaskLocalMap {
-
- extern fn cleanup_task_local_map_extern_cb(map_ptr: *libc::c_void) {
- cleanup_task_local_map(map_ptr);
- }
-
- // Relies on the runtime initialising the pointer to null.
- // Note: the map is an owned pointer and is "owned" by TLS. It is moved
- // into the tls slot for this task, and then mutable loans are taken from
- // this slot to modify the map.
- let map_ptr = rt::rust_get_task_local_data(task);
- if (*map_ptr).is_null() {
- // First time TLS is used, create a new map and set up the necessary
- // TLS information for its safe destruction
- let map: TaskLocalMap = ~[];
- *map_ptr = cast::transmute(map);
- rt::rust_task_local_data_atexit(task, cleanup_task_local_map_extern_cb);
- }
- return cast::transmute(map_ptr);
-}
-
-unsafe fn get_newsched_local_map(local: *mut LocalStorage) -> &mut TaskLocalMap {
- // This is based on the same idea as the oldsched code above.
- match &mut *local {
- // If the at_exit function is already set, then we just need to take a
- // loan out on the TLS map stored inside
- &LocalStorage(ref mut map_ptr, Some(_)) => {
- assert!(map_ptr.is_not_null());
- return cast::transmute(map_ptr);
- }
- // If this is the first time we've accessed TLS, perform similar
- // actions to the oldsched way of doing things.
- &LocalStorage(ref mut map_ptr, ref mut at_exit) => {
- assert!(map_ptr.is_null());
- assert!(at_exit.is_none());
- let map: TaskLocalMap = ~[];
- *map_ptr = cast::transmute(map);
- *at_exit = Some(cleanup_task_local_map);
- return cast::transmute(map_ptr);
- }
- }
-}
-
-unsafe fn key_to_key_value<T: 'static>(key: local_data::Key<@T>) -> *libc::c_void {
- let pair: sys::Closure = cast::transmute(key);
- return pair.code as *libc::c_void;
-}
-
-// If returning Some(..), returns with @T with the map's reference. Careful!
-unsafe fn local_data_lookup<T: 'static>(
- map: &mut TaskLocalMap, key: local_data::Key<@T>)
- -> Option<(uint, *libc::c_void)> {
-
- let key_value = key_to_key_value(key);
- for map.iter().enumerate().advance |(i, entry)| {
- match *entry {
- Some((k, data, _)) if k == key_value => { return Some((i, data)); }
- _ => {}
- }
- }
- return None;
-}
-
-unsafe fn local_get_helper<T: 'static>(
- handle: Handle, key: local_data::Key<@T>,
- do_pop: bool) -> Option<@T> {
-
- let map = get_local_map(handle);
- // Interpreturn our findings from the map
- do local_data_lookup(map, key).map |result| {
- // A reference count magically appears on 'data' out of thin air. It
- // was referenced in the local_data box, though, not here, so before
- // overwriting the local_data_box we need to give an extra reference.
- // We must also give an extra reference when not removing.
- let (index, data_ptr) = *result;
- let data: @T = cast::transmute(data_ptr);
- cast::bump_box_refcount(data);
- if do_pop {
- map[index] = None;
- }
- data
- }
-}
-
-
-pub unsafe fn local_pop<T: 'static>(
- handle: Handle,
- key: local_data::Key<@T>) -> Option<@T> {
-
- local_get_helper(handle, key, true)
-}
-
-pub unsafe fn local_get<T: 'static, U>(
- handle: Handle,
- key: local_data::Key<@T>,
- f: &fn(Option<&@T>) -> U) -> U {
-
- match local_get_helper(handle, key, false) {
- Some(ref x) => f(Some(x)),
- None => f(None)
- }
-}
-
-pub unsafe fn local_set<T: 'static>(
- handle: Handle, key: local_data::Key<@T>, data: @T) {
-
- let map = get_local_map(handle);
- // Store key+data as *voids. Data is invisibly referenced once; key isn't.
- let keyval = key_to_key_value(key);
- // We keep the data in two forms: one as an unsafe pointer, so we can get
- // it back by casting; another in an existential box, so the reference we
- // own on it can be dropped when the box is destroyed. The unsafe pointer
- // does not have a reference associated with it, so it may become invalid
- // when the box is destroyed.
- let data_ptr = *cast::transmute::<&@T, &*libc::c_void>(&data);
- let data_box = @data as @LocalData;
- // Construct new entry to store in the map.
- let new_entry = Some((keyval, data_ptr, data_box));
- // Find a place to put it.
- match local_data_lookup(map, key) {
- Some((index, _old_data_ptr)) => {
- // Key already had a value set, _old_data_ptr, whose reference
- // will get dropped when the local_data box is overwritten.
- map[index] = new_entry;
- }
- None => {
- // Find an empty slot. If not, grow the vector.
- match map.iter().position(|x| x.is_none()) {
- Some(empty_index) => { map[empty_index] = new_entry; }
- None => { map.push(new_entry); }
- }
- }
- }
-}
-
-pub unsafe fn local_modify<T: 'static>(
- handle: Handle, key: local_data::Key<@T>,
- modify_fn: &fn(Option<@T>) -> Option<@T>) {
-
- // Could be more efficient by doing the lookup work, but this is easy.
- let newdata = modify_fn(local_pop(handle, key));
- if newdata.is_some() {
- local_set(handle, key, newdata.unwrap());
- }
-}
#[cfg(test)] use ptr;
#[cfg(test)] use task;
-#[cfg(stage0)]
-#[path="local_data_priv_stage0.rs"]
-mod local_data_priv;
-#[cfg(not(stage0))]
mod local_data_priv;
pub mod rt;
pub mod spawn;
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
// a proper closure because the #[test]s won't understand. Have to fake it.
-#[cfg(not(stage0))]
fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
unsafe { cast::transmute(-2) }
}
-#[cfg(stage0)]
-fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
- unsafe { cast::transmute((-2, 0)) }
-}
// Transitionary.
struct RuntimeGlue;
}
#[test]
- #[allow(non_implicitly_copyable_typarams)]
fn test_tuple() {
assert_eq!((948, 4039.48).first(), 948);
assert_eq!((34.5, ~"foo").second(), ~"foo");
#[cfg(test)]
pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
-#[cfg(not(stage0))]
pub type GlueFn = extern "Rust" fn(*i8);
-#[cfg(stage0)]
-pub type GlueFn = extern "Rust" fn(**TyDesc, *i8);
-
// NB: this has to be kept in sync with the Rust ABI.
#[lang="ty_desc"]
#[cfg(not(test))]
pub fn pref_align_of<T>() -> uint;
/// Get a static pointer to a type descriptor.
- #[cfg(not(stage0))]
pub fn get_tydesc<T>() -> *TyDesc;
- #[cfg(stage0)]
- pub fn get_tydesc<T>() -> *();
/// Create a value initialized to zero.
///
pub fn needs_drop<T>() -> bool;
/// Returns `true` if a type is managed (will be allocated on the local heap)
- #[cfg(not(stage0))]
pub fn contains_managed<T>() -> bool;
- #[cfg(not(stage0))]
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
pub fn frame_address(f: &once fn(*u8));
// verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
- // NOTE: uncomment after snapshot, will not parse yet
- //static mut did_run: bool = false;
+ static mut did_run: bool = false;
struct Foo { five: int }
impl Drop for Foo {
fn drop(&self) {
assert_eq!(self.five, 5);
- // NOTE: uncomment after snapshot, will not parse yet
- //unsafe {
- //did_run = true;
- //}
+ unsafe {
+ did_run = true;
+ }
}
}
let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
}
- // NOTE: uncomment after snapshot, will not parse yet
- //unsafe { assert_eq!(did_run, true); }
+ unsafe { assert_eq!(did_run, true); }
}
}
use ptr::to_unsafe_ptr;
use ptr;
use ptr::RawPtr;
-#[cfg(not(stage0))]
use rt::global_heap::malloc_raw;
use rt::global_heap::realloc_raw;
use sys;
use sys::size_of;
use uint;
use unstable::intrinsics;
-#[cfg(stage0)]
-use intrinsic::{get_tydesc};
-#[cfg(not(stage0))]
use unstable::intrinsics::{get_tydesc, contains_managed};
use vec;
use util;
}
/// Creates a new vector with a capacity of `capacity`
-#[cfg(stage0)]
-pub fn with_capacity<T>(capacity: uint) -> ~[T] {
- let mut vec = ~[];
- vec.reserve(capacity);
- vec
-}
-
-/// Creates a new vector with a capacity of `capacity`
-#[cfg(not(stage0))]
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
unsafe {
if contains_managed::<T>() {
*
* * n - The number of elements to reserve space for
*/
- #[cfg(stage0)]
- fn reserve(&mut self, n: uint) {
- // Only make the (slow) call into the runtime if we have to
- use managed;
- if self.capacity() < n {
- unsafe {
- let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
- let td = get_tydesc::<T>();
- if ((**ptr).box_header.ref_count ==
- managed::raw::RC_MANAGED_UNIQUE) {
- // XXX transmute shouldn't be necessary
- let td = cast::transmute(td);
- ::at_vec::raw::reserve_raw(td, ptr, n);
- } else {
- let alloc = n * sys::nonzero_size_of::<T>();
- *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
- as *mut raw::VecRepr;
- (**ptr).unboxed.alloc = alloc;
- }
- }
- }
- }
-
- /**
- * Reserves capacity for exactly `n` elements in the given vector.
- *
- * If the capacity for `self` is already equal to or greater than the requested
- * capacity, then no action is taken.
- *
- * # Arguments
- *
- * * n - The number of elements to reserve space for
- */
- #[cfg(not(stage0))]
fn reserve(&mut self, n: uint) {
// Only make the (slow) call into the runtime if we have to
if self.capacity() < n {
/// Returns the number of elements the vector can hold without reallocating.
#[inline]
- #[cfg(stage0)]
- fn capacity(&self) -> uint {
- unsafe {
- let repr: **raw::VecRepr = transmute(self);
- (**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
- }
- }
-
- /// Returns the number of elements the vector can hold without reallocating.
- #[inline]
- #[cfg(not(stage0))]
fn capacity(&self) -> uint {
unsafe {
if contains_managed::<T>() {
/// Append an element to a vector
#[inline]
- #[cfg(stage0)]
- fn push(&mut self, t: T) {
- unsafe {
- let repr: **raw::VecRepr = transmute(&mut *self);
- let fill = (**repr).unboxed.fill;
- if (**repr).unboxed.alloc <= fill {
- let new_len = self.len() + 1;
- self.reserve_at_least(new_len);
- }
-
- self.push_fast(t);
- }
- }
-
- /// Append an element to a vector
- #[inline]
- #[cfg(not(stage0))]
fn push(&mut self, t: T) {
unsafe {
if contains_managed::<T>() {
// This doesn't bother to make sure we have space.
#[inline] // really pretty please
- #[cfg(stage0)]
- unsafe fn push_fast(&mut self, t: T) {
- let repr: **mut raw::VecRepr = transmute(self);
- let fill = (**repr).unboxed.fill;
- (**repr).unboxed.fill += sys::nonzero_size_of::<T>();
- let p = to_unsafe_ptr(&((**repr).unboxed.data));
- let p = ptr::offset(p, fill) as *mut T;
- intrinsics::move_val_init(&mut(*p), t);
- }
-
- // This doesn't bother to make sure we have space.
- #[inline] // really pretty please
- #[cfg(not(stage0))]
unsafe fn push_fast(&mut self, t: T) {
if contains_managed::<T>() {
let repr: **mut raw::VecRepr = transmute(self);
use sys;
use unstable::intrinsics;
use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
- #[cfg(not(stage0))]
use unstable::intrinsics::contains_managed;
/// The internal representation of a (boxed) vector
* the vector is actually the specified size.
*/
#[inline]
- #[cfg(stage0)]
- pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
- let repr: **mut VecRepr = transmute(v);
- (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
- }
-
- /**
- * Sets the length of a vector
- *
- * This will explicitly set the size of the vector, without actually
- * modifing its buffers, so it is up to the caller to ensure that
- * the vector is actually the specified size.
- */
- #[inline]
- #[cfg(not(stage0))]
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
if contains_managed::<T>() {
let repr: **mut VecRepr = transmute(v);
}
}
-#[cfg(stage0)]
-impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
- pub fn from_iterator(iterator: &mut T) -> ~[A] {
- let mut xs = ~[];
- for iterator.advance |x| {
- xs.push(x);
- }
- xs
- }
-}
-
-
-#[cfg(not(stage0))]
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
pub fn from_iterator(iterator: &mut T) -> ~[A] {
let (lower, _) = iterator.size_hint();
types: ~[Ty],
}
-pub type crate_num = int;
+pub type CrateNum = int;
pub type node_id = int;
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub struct def_id {
- crate: crate_num,
+ crate: CrateNum,
node: node_id,
}
-pub static local_crate: crate_num = 0;
+pub static local_crate: CrateNum = 0;
pub static crate_node_id: node_id = 0;
// The AST represents all type param bounds as types.
// The set of MetaItems that define the compilation environment of the crate,
// used to drive conditional compilation
-pub type crate_cfg = ~[@MetaItem];
-
-pub type crate = spanned<crate_>;
+pub type CrateConfig = ~[@MetaItem];
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
-pub struct crate_ {
+pub struct Crate {
module: _mod,
attrs: ~[Attribute],
- config: crate_cfg,
+ config: CrateConfig,
+ span: span,
}
pub type MetaItem = spanned<MetaItem_>;
}
}
-//pub type blk = spanned<blk_>;
-
#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
-pub struct blk {
+pub struct Block {
view_items: ~[view_item],
stmts: ~[@stmt],
expr: Option<@expr>,
// FIXME (pending discussion of #1697, #2178...): local should really be
// a refinement on pat.
#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub struct local_ {
+pub struct Local {
is_mutbl: bool,
ty: Ty,
pat: @pat,
init: Option<@expr>,
id: node_id,
+ span: span,
}
-pub type local = spanned<local_>;
-
pub type decl = spanned<decl_>;
#[deriving(Eq, Encodable, Decodable,IterBytes)]
pub enum decl_ {
// a local (let) binding:
- decl_local(@local),
+ decl_local(@Local),
// an item binding:
decl_item(@item),
}
pub struct arm {
pats: ~[@pat],
guard: Option<@expr>,
- body: blk,
+ body: Block,
}
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
-pub struct field_ {
+pub struct Field {
ident: ident,
expr: @expr,
+ span: span,
}
-pub type field = spanned<field_>;
-
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum blk_check_mode {
default_blk,
expr_unary(node_id, unop, @expr),
expr_lit(@lit),
expr_cast(@expr, Ty),
- expr_if(@expr, blk, Option<@expr>),
- expr_while(@expr, blk),
+ expr_if(@expr, Block, Option<@expr>),
+ expr_while(@expr, Block),
/* Conditionless loop (can be exited with break, cont, or ret)
Same semantics as while(true) { body }, but typestate knows that the
(implicit) condition is always true. */
- expr_loop(blk, Option<ident>),
+ expr_loop(Block, Option<ident>),
expr_match(@expr, ~[arm]),
- expr_fn_block(fn_decl, blk),
+ expr_fn_block(fn_decl, Block),
// Inner expr is always an expr_fn_block. We need the wrapping node to
// easily type this (a function returning nil on the inside but bool on
// the outside).
expr_loop_body(@expr),
// Like expr_loop_body but for 'do' blocks
expr_do_body(@expr),
- expr_block(blk),
+ expr_block(Block),
expr_assign(@expr, @expr),
expr_assign_op(node_id, binop, @expr, @expr),
expr_mac(mac),
// A struct literal expression.
- expr_struct(Path, ~[field], Option<@expr>),
+ expr_struct(Path, ~[Field], Option<@expr>),
// A vector literal constructed from one repeated element.
expr_repeat(@expr /* element */, @expr /* count */, mutability),
explicit_self: explicit_self,
purity: purity,
decl: fn_decl,
- body: blk,
+ body: Block,
id: node_id,
span: span,
self_id: node_id,
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum item_ {
item_static(Ty, mutability, @expr),
- item_fn(fn_decl, purity, AbiSet, Generics, blk),
+ item_fn(fn_decl, purity, AbiSet, Generics, Block),
item_mod(_mod),
item_foreign_mod(foreign_mod),
item_ty(Ty, Generics),
node_stmt(@stmt),
node_arg,
node_local(ident),
- node_block(blk),
+ node_block(Block),
node_struct_ctor(@struct_def, @item, @path),
node_callee_scope(@expr)
}
});
}
-pub fn map_crate(diag: @span_handler, c: &crate) -> map {
+pub fn map_crate(diag: @span_handler, c: &Crate) -> map {
let cx = @mut Ctx {
map: @mut HashMap::new(),
path: ~[],
pub fn map_fn(
fk: &visit::fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
sp: codemap::span,
id: node_id,
(cx,v): (@mut Ctx,
visit::visit_fn(fk, decl, body, sp, id, (cx, v));
}
-pub fn map_block(b: &blk, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) {
+pub fn map_block(b: &Block, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) {
cx.map.insert(b.id, node_block(/* FIXME (#2543) */ (*b).clone()));
visit::visit_block(b, (cx, v));
}
match e.node { expr_call(*) => true, _ => false }
}
-pub fn block_from_expr(e: @expr) -> blk {
+pub fn block_from_expr(e: @expr) -> Block {
let mut blk = default_block(~[], option::Some::<@expr>(e), e.id);
blk.span = e.span;
return blk;
stmts1: ~[@stmt],
expr1: Option<@expr>,
id1: node_id
-) -> blk {
- ast::blk {
+) -> Block {
+ ast::Block {
view_items: ~[],
stmts: stmts1,
expr: expr1,
},
visit_local: |l, (t, vt)| {
- vfn(l.node.id, t.clone());
+ vfn(l.id, t.clone());
visit::visit_local(l, (t, vt));
},
visit_block: |b, (t, vt)| {
pub fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool;
}
-impl EachViewItem for ast::crate {
+impl EachViewItem for ast::Crate {
fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool {
let broke = @mut false;
let vtor: visit::vt<()> = visit::mk_simple_visitor(@visit::SimpleVisitor {
// fetch the SCTable from TLS, create one if it doesn't yet exist.
pub fn get_sctable() -> @mut SCTable {
- #[cfg(not(stage0))]
static sctable_key: local_data::Key<@@mut SCTable> = &local_data::Key;
- #[cfg(stage0)]
- fn sctable_key(_: @@mut SCTable) {}
match local_data::get(sctable_key, |k| k.map(|&k| *k)) {
None => {
let new_table = @@mut new_sctable_internal();
}
fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
- #[cfg(not(stage0))]
static tls_terminal: local_data::Key<@Option<term::Terminal>> = &local_data::Key;
- #[cfg(stage0)]
- fn tls_terminal(_: @Option<term::Terminal>) {}
let stderr = io::stderr();
// -> expn_info of their expansion context stored into their span.
pub struct ExtCtxt {
parse_sess: @mut parse::ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
backtrace: @mut Option<@ExpnInfo>,
// These two @mut's should really not be here,
}
impl ExtCtxt {
- pub fn new(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
+ pub fn new(parse_sess: @mut parse::ParseSess, cfg: ast::CrateConfig)
-> @ExtCtxt {
@ExtCtxt {
parse_sess: parse_sess,
pub fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
pub fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
- pub fn cfg(&self) -> ast::crate_cfg { self.cfg.clone() }
+ pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
pub fn call_site(&self) -> span {
match *self.backtrace {
Some(@ExpnInfo {call_site: cs, _}) => cs,
fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
// blocks
- fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk;
- fn blk_expr(&self, expr: @ast::expr) -> ast::blk;
+ fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block;
+ fn blk_expr(&self, expr: @ast::expr) -> ast::Block;
fn blk_all(&self, span: span,
view_items: ~[ast::view_item],
stmts: ~[@ast::stmt],
- expr: Option<@ast::expr>) -> ast::blk;
+ expr: Option<@ast::expr>) -> ast::Block;
// expressions
fn expr(&self, span: span, node: ast::expr_) -> @ast::expr;
fn expr_method_call(&self, span: span,
expr: @ast::expr, ident: ast::ident,
args: ~[@ast::expr]) -> @ast::expr;
- fn expr_blk(&self, b: ast::blk) -> @ast::expr;
+ fn expr_blk(&self, b: ast::Block) -> @ast::expr;
- fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field;
- fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr;
- fn expr_struct_ident(&self, span: span, id: ast::ident, fields: ~[ast::field]) -> @ast::expr;
+ fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::Field;
+ fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::Field]) -> @ast::expr;
+ fn expr_struct_ident(&self, span: span, id: ast::ident, fields: ~[ast::Field]) -> @ast::expr;
fn expr_lit(&self, sp: span, lit: ast::lit_) -> @ast::expr;
fn expr_if(&self, span: span,
cond: @ast::expr, then: @ast::expr, els: Option<@ast::expr>) -> @ast::expr;
- fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::blk) -> @ast::expr;
+ fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::Block) -> @ast::expr;
- fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::blk) -> @ast::expr;
- fn lambda0(&self, span: span, blk: ast::blk) -> @ast::expr;
- fn lambda1(&self, span: span, blk: ast::blk, ident: ast::ident) -> @ast::expr;
+ fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::Block) -> @ast::expr;
+ fn lambda0(&self, span: span, blk: ast::Block) -> @ast::expr;
+ fn lambda1(&self, span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr;
fn lambda_expr(&self, span: span, ids: ~[ast::ident], blk: @ast::expr) -> @ast::expr;
fn lambda_expr_0(&self, span: span, expr: @ast::expr) -> @ast::expr;
inputs: ~[ast::arg],
output: ast::Ty,
generics: Generics,
- body: ast::blk) -> @ast::item;
+ body: ast::Block) -> @ast::item;
fn item_fn(&self,
span: span,
name: ident,
inputs: ~[ast::arg],
output: ast::Ty,
- body: ast::blk) -> @ast::item;
+ body: ast::Block) -> @ast::item;
fn variant(&self, span: span, name: ident, tys: ~[ast::Ty]) -> ast::variant;
fn item_enum_poly(&self,
fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt {
let pat = self.pat_ident(sp, ident);
- let local = @respan(sp,
- ast::local_ {
- is_mutbl: mutbl,
- ty: self.ty_infer(sp),
- pat: pat,
- init: Some(ex),
- id: self.next_id(),
- });
+ let local = @ast::Local {
+ is_mutbl: mutbl,
+ ty: self.ty_infer(sp),
+ pat: pat,
+ init: Some(ex),
+ id: self.next_id(),
+ span: sp,
+ };
let decl = respan(sp, ast::decl_local(local));
@respan(sp, ast::stmt_decl(@decl, self.next_id()))
}
- fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::blk {
+ fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block {
self.blk_all(span, ~[], stmts, expr)
}
- fn blk_expr(&self, expr: @ast::expr) -> ast::blk {
+ fn blk_expr(&self, expr: @ast::expr) -> ast::Block {
self.blk_all(expr.span, ~[], ~[], Some(expr))
}
fn blk_all(&self,
span: span,
view_items: ~[ast::view_item],
stmts: ~[@ast::stmt],
- expr: Option<@ast::expr>) -> ast::blk {
- ast::blk {
+ expr: Option<@ast::expr>) -> ast::Block {
+ ast::Block {
view_items: view_items,
stmts: stmts,
expr: expr,
self.expr(span,
ast::expr_method_call(self.next_id(), expr, ident, ~[], args, ast::NoSugar))
}
- fn expr_blk(&self, b: ast::blk) -> @ast::expr {
+ fn expr_blk(&self, b: ast::Block) -> @ast::expr {
self.expr(b.span, ast::expr_block(b))
}
- fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field {
- respan(span, ast::field_ { ident: name, expr: e })
+ fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::Field {
+ ast::Field { ident: name, expr: e, span: span }
}
- fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr {
+ fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::Field]) -> @ast::expr {
self.expr(span, ast::expr_struct(path, fields, None))
}
fn expr_struct_ident(&self, span: span,
- id: ast::ident, fields: ~[ast::field]) -> @ast::expr {
+ id: ast::ident, fields: ~[ast::Field]) -> @ast::expr {
self.expr_struct(span, self.path_ident(span, id), fields)
}
self.expr(span, ast::expr_if(cond, self.blk_expr(then), els))
}
- fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::blk) -> @ast::expr {
+ fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::Block) -> @ast::expr {
self.expr(span, ast::expr_fn_block(fn_decl, blk))
}
- fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::blk) -> @ast::expr {
+ fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::Block) -> @ast::expr {
let fn_decl = self.fn_decl(
ids.map(|id| self.arg(span, *id, self.ty_infer(span))),
self.ty_infer(span));
self.expr(span, ast::expr_fn_block(fn_decl, blk))
}
- fn lambda0(&self, _span: span, blk: ast::blk) -> @ast::expr {
+ fn lambda0(&self, _span: span, blk: ast::Block) -> @ast::expr {
let ext_cx = *self;
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(|| $blk_e )
}
- fn lambda1(&self, _span: span, blk: ast::blk, ident: ast::ident) -> @ast::expr {
+ fn lambda1(&self, _span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr {
let ext_cx = *self;
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(|$ident| $blk_e )
inputs: ~[ast::arg],
output: ast::Ty,
generics: Generics,
- body: ast::blk) -> @ast::item {
+ body: ast::Block) -> @ast::item {
self.item(span,
name,
~[],
name: ident,
inputs: ~[ast::arg],
output: ast::Ty,
- body: ast::blk
+ body: ast::Block
) -> @ast::item {
self.item_fn_poly(
span,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast::{blk, crate, expr_, expr_mac, mac_invoc_tt};
+use ast::{Block, Crate, expr_, expr_mac, mac_invoc_tt};
use ast::{item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
use ast::{illegal_ctxt};
use ast;
pub fn expand_block(extsbox: @mut SyntaxEnv,
_cx: @ExtCtxt,
- blk: &blk,
+ blk: &Block,
fld: @ast_fold,
- orig: @fn(&blk, @ast_fold) -> blk)
- -> blk {
+ orig: @fn(&Block, @ast_fold) -> Block)
+ -> Block {
// see note below about treatment of exts table
with_exts_frame!(extsbox,false,orig(blk,fld))
}
// add a bunch of macros as though they were placed at the head of the
// program (ick). This should run before cfg stripping.
pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
- cfg: ast::crate_cfg, c: &crate) -> @crate {
+ cfg: ast::CrateConfig, c: &Crate) -> @Crate {
let sm = match parse_item_from_source_str(@"<std-macros>",
std_macros(),
cfg.clone(),
}
pub fn expand_crate(parse_sess: @mut parse::ParseSess,
- cfg: ast::crate_cfg, c: &crate) -> @crate {
+ cfg: ast::CrateConfig, c: &Crate) -> @Crate {
// adding *another* layer of indirection here so that the block
// visitor can swap out one exts table for another for the duration
// of the block. The cleaner alternative would be to thread the
}
}
- impl ToSource for ast::blk {
+ impl ToSource for ast::Block {
fn to_source(&self) -> @str {
pprust::block_to_str(self, get_ident_interner()).to_managed()
}
}
}
- impl ToTokens for ast::blk {
+ impl ToTokens for ast::Block {
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
cx.parse_tts(self.to_source())
}
pub fn parse_or_else(
sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
rdr: @reader,
ms: ~[matcher]
) -> HashMap<ident, @named_match> {
pub fn parse(
sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
rdr: @reader,
ms: &[matcher]
) -> parse_result {
use opt_vec::OptVec;
pub trait ast_fold {
- fn fold_crate(@self, &crate) -> crate;
+ fn fold_crate(@self, &Crate) -> Crate;
fn fold_view_item(@self, &view_item) -> view_item;
fn fold_foreign_item(@self, @foreign_item) -> @foreign_item;
fn fold_item(@self, @item) -> Option<@item>;
fn fold_struct_field(@self, @struct_field) -> @struct_field;
fn fold_item_underscore(@self, &item_) -> item_;
fn fold_method(@self, @method) -> @method;
- fn fold_block(@self, &blk) -> blk;
+ fn fold_block(@self, &Block) -> Block;
fn fold_stmt(@self, &stmt) -> Option<@stmt>;
fn fold_arm(@self, &arm) -> arm;
fn fold_pat(@self, @pat) -> @pat;
fn fold_variant(@self, &variant) -> variant;
fn fold_ident(@self, ident) -> ident;
fn fold_path(@self, &Path) -> Path;
- fn fold_local(@self, @local) -> @local;
+ fn fold_local(@self, @Local) -> @Local;
fn map_exprs(@self, @fn(@expr) -> @expr, &[@expr]) -> ~[@expr];
fn new_id(@self, node_id) -> node_id;
fn new_span(@self, span) -> span;
pub struct AstFoldFns {
//unlike the others, item_ is non-trivial
- fold_crate: @fn(&crate_, span, @ast_fold) -> (crate_, span),
+ fold_crate: @fn(&Crate, @ast_fold) -> Crate,
fold_view_item: @fn(&view_item_, @ast_fold) -> view_item_,
fold_foreign_item: @fn(@foreign_item, @ast_fold) -> @foreign_item,
fold_item: @fn(@item, @ast_fold) -> Option<@item>,
fold_struct_field: @fn(@struct_field, @ast_fold) -> @struct_field,
fold_item_underscore: @fn(&item_, @ast_fold) -> item_,
fold_method: @fn(@method, @ast_fold) -> @method,
- fold_block: @fn(&blk, @ast_fold) -> blk,
+ fold_block: @fn(&Block, @ast_fold) -> Block,
fold_stmt: @fn(&stmt_, span, @ast_fold) -> (Option<stmt_>, span),
fold_arm: @fn(&arm, @ast_fold) -> arm,
fold_pat: @fn(&pat_, span, @ast_fold) -> (pat_, span),
fold_variant: @fn(&variant_, span, @ast_fold) -> (variant_, span),
fold_ident: @fn(ident, @ast_fold) -> ident,
fold_path: @fn(&Path, @ast_fold) -> Path,
- fold_local: @fn(&local_, span, @ast_fold) -> (local_, span),
+ fold_local: @fn(@Local, @ast_fold) -> @Local,
map_exprs: @fn(@fn(@expr) -> @expr, &[@expr]) -> ~[@expr],
new_id: @fn(node_id) -> node_id,
new_span: @fn(span) -> span
lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
}
-pub fn noop_fold_crate(c: &crate_, fld: @ast_fold) -> crate_ {
+pub fn noop_fold_crate(c: &Crate, fld: @ast_fold) -> Crate {
let fold_meta_item = |x| fold_meta_item_(x, fld);
let fold_attribute = |x| fold_attribute_(x, fld);
- crate_ {
+ Crate {
module: fld.fold_mod(&c.module),
attrs: c.attrs.map(|x| fold_attribute(*x)),
config: c.config.map(|x| fold_meta_item(*x)),
+ span: fld.new_span(c.span),
}
}
}
-pub fn noop_fold_block(b: &blk, fld: @ast_fold) -> blk {
+pub fn noop_fold_block(b: &Block, fld: @ast_fold) -> Block {
let view_items = b.view_items.map(|x| fld.fold_view_item(x));
let mut stmts = ~[];
for b.stmts.iter().advance |stmt| {
Some(stmt) => stmts.push(stmt)
}
}
- ast::blk {
+ ast::Block {
view_items: view_items,
stmts: stmts,
expr: b.expr.map(|x| fld.fold_expr(*x)),
}
pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
- fn fold_field_(field: field, fld: @ast_fold) -> field {
- spanned {
- node: ast::field_ {
- ident: fld.fold_ident(field.node.ident),
- expr: fld.fold_expr(field.node.expr),
- },
+ fn fold_field_(field: Field, fld: @ast_fold) -> Field {
+ ast::Field {
+ ident: fld.fold_ident(field.ident),
+ expr: fld.fold_expr(field.expr),
span: fld.new_span(field.span),
}
}
}
}
-fn noop_fold_local(l: &local_, fld: @ast_fold) -> local_ {
- local_ {
+fn noop_fold_local(l: @Local, fld: @ast_fold) -> @Local {
+ @Local {
is_mutbl: l.is_mutbl,
ty: fld.fold_ty(&l.ty),
pat: fld.fold_pat(l.pat),
init: l.init.map(|e| fld.fold_expr(*e)),
id: fld.new_id(l.id),
+ span: fld.new_span(l.span),
}
}
pub fn default_ast_fold() -> ast_fold_fns {
@AstFoldFns {
- fold_crate: wrap(noop_fold_crate),
+ fold_crate: noop_fold_crate,
fold_view_item: noop_fold_view_item,
fold_foreign_item: noop_fold_foreign_item,
fold_item: noop_fold_item,
fold_variant: wrap(noop_fold_variant),
fold_ident: noop_fold_ident,
fold_path: noop_fold_path,
- fold_local: wrap(noop_fold_local),
+ fold_local: noop_fold_local,
map_exprs: noop_map_exprs,
new_id: noop_id,
new_span: noop_span,
impl ast_fold for AstFoldFns {
/* naturally, a macro to write these would be nice */
- fn fold_crate(@self, c: &crate) -> crate {
- let (n, s) = (self.fold_crate)(&c.node, c.span, self as @ast_fold);
- spanned { node: n, span: (self.new_span)(s) }
+ fn fold_crate(@self, c: &Crate) -> Crate {
+ (self.fold_crate)(c, self as @ast_fold)
}
fn fold_view_item(@self, x: &view_item) -> view_item {
ast::view_item {
fn fold_method(@self, x: @method) -> @method {
(self.fold_method)(x, self as @ast_fold)
}
- fn fold_block(@self, x: &blk) -> blk {
+ fn fold_block(@self, x: &Block) -> Block {
(self.fold_block)(x, self as @ast_fold)
}
fn fold_stmt(@self, x: &stmt) -> Option<@stmt> {
fn fold_path(@self, x: &Path) -> Path {
(self.fold_path)(x, self as @ast_fold)
}
- fn fold_local(@self, x: @local) -> @local {
- let (n, s) = (self.fold_local)(&x.node, x.span, self as @ast_fold);
- @spanned { node: n, span: (self.new_span)(s) }
+ fn fold_local(@self, x: @Local) -> @Local {
+ (self.fold_local)(x, self as @ast_fold)
}
fn map_exprs(@self,
f: @fn(@expr) -> @expr,
}
// this version doesn't care about getting comments or docstrings in.
- fn fake_print_crate(s: @pprust::ps, crate: &ast::crate) {
- pprust::print_mod(s, &crate.node.module, crate.node.attrs);
+ fn fake_print_crate(s: @pprust::ps, crate: &ast::Crate) {
+ pprust::print_mod(s, &crate.module, crate.attrs);
}
// change every identifier to "zz"
pub fn expr_is_simple_block(e: @ast::expr) -> bool {
match e.node {
ast::expr_block(
- ast::blk { rules: ast::default_blk, _ }
+ ast::Block { rules: ast::default_blk, _ }
) => true,
_ => false
}
pub fn parse_crate_from_file(
input: &Path,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
-) -> @ast::crate {
+) -> @ast::Crate {
new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod()
// why is there no p.abort_if_errors here?
}
pub fn parse_crate_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
-) -> @ast::crate {
+) -> @ast::Crate {
let p = new_parser_from_source_str(sess,
/*bad*/ cfg.clone(),
name,
pub fn parse_expr_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> @ast::expr {
let p = new_parser_from_source_str(
pub fn parse_item_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
attrs: ~[ast::Attribute],
sess: @mut ParseSess
) -> Option<@ast::item> {
pub fn parse_meta_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> @ast::MetaItem {
let p = new_parser_from_source_str(
pub fn parse_stmt_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
attrs: ~[ast::Attribute],
sess: @mut ParseSess
) -> @ast::stmt {
pub fn parse_tts_from_source_str(
name: @str,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> ~[ast::token_tree] {
let p = new_parser_from_source_str(
f: &fn(&Parser) -> T,
name: @str, ss: codemap::FileSubstr,
source: @str,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> T {
let p = new_parser_from_source_substr(
// Create a new parser from a source string
pub fn new_parser_from_source_str(sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
name: @str,
source: @str)
-> Parser {
// Create a new parser from a source string where the origin
// is specified as a substring of another file.
pub fn new_parser_from_source_substr(sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
name: @str,
ss: codemap::FileSubstr,
source: @str)
/// if the file doesn't exist
pub fn new_parser_from_file(
sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
path: &Path
) -> Parser {
filemap_to_parser(sess,file_to_filemap(sess,path,None),cfg)
/// On an error, use the given span as the source of the problem.
pub fn new_sub_parser_from_file(
sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
path: &Path,
sp: span
) -> Parser {
/// Given a filemap and config, return a parser
pub fn filemap_to_parser(sess: @mut ParseSess,
filemap: @FileMap,
- cfg: ast::crate_cfg) -> Parser {
+ cfg: ast::CrateConfig) -> Parser {
tts_to_parser(sess,filemap_to_tts(sess,filemap),cfg)
}
// must preserve old name for now, because quote! from the *existing*
// compiler expands into it
pub fn new_parser_from_tts(sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
tts: ~[ast::token_tree]) -> Parser {
tts_to_parser(sess,tts,cfg)
}
// given tts and cfg, produce a parser
pub fn tts_to_parser(sess: @mut ParseSess,
tts: ~[ast::token_tree],
- cfg: ast::crate_cfg) -> Parser {
+ cfg: ast::CrateConfig) -> Parser {
let trdr = lexer::new_tt_reader(sess.span_diagnostic, None, tts);
Parser(sess, cfg, trdr as @reader)
}
lifetimes: opt_vec::Empty,
ty_params: opt_vec::Empty,
},
- ast::blk {
+ ast::Block {
view_items: ~[],
stmts: ~[@spanned{
node: ast::stmt_semi(@ast::expr{
use ast::{RegionTyParamBound, TraitTyParamBound};
use ast::{provided, public, purity};
use ast::{_mod, add, arg, arm, Attribute, bind_by_ref, bind_infer};
-use ast::{bitand, bitor, bitxor, blk};
+use ast::{bitand, bitor, bitxor, Block};
use ast::{blk_check_mode, box};
-use ast::{crate, crate_cfg, decl, decl_item};
+use ast::{Crate, CrateConfig, decl, decl_item};
use ast::{decl_local, default_blk, deref, div, enum_def, explicit_self};
use ast::{expr, expr_, expr_addr_of, expr_match, expr_again};
use ast::{expr_assign, expr_assign_op, expr_binary, expr_block};
use ast::{expr_ret, expr_self, expr_struct, expr_tup, expr_unary};
use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
use ast::{expr_vstore_slice, expr_vstore_box};
-use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
+use ast::{expr_vstore_mut_slice, expr_while, extern_fn, Field, fn_decl};
use ast::{expr_vstore_uniq, Onceness, Once, Many};
use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod};
use ast::{ident, impure_fn, inherited, item, item_, item_static};
use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
-use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const};
+use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local, m_const};
use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
use ast::{match_seq, match_tok, method, mt, mul, mutability};
use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum};
/* ident is handled by common.rs */
pub fn Parser(sess: @mut ParseSess,
- cfg: ast::crate_cfg,
+ cfg: ast::CrateConfig,
rdr: @reader)
-> Parser {
let tok0 = rdr.next_token();
// ooh, nasty mutable fields everywhere....
pub struct Parser {
sess: @mut ParseSess,
- cfg: crate_cfg,
+ cfg: CrateConfig,
// the current token:
token: @mut token::Token,
// the span of the current token:
}
// parse ident COLON expr
- pub fn parse_field(&self) -> field {
+ pub fn parse_field(&self) -> Field {
let lo = self.span.lo;
let i = self.parse_ident();
self.expect(&token::COLON);
let e = self.parse_expr();
- spanned(lo, e.span.hi, ast::field_ {
+ ast::Field {
ident: i,
- expr: e
- })
+ expr: e,
+ span: mk_sp(lo, e.span.hi),
+ }
}
pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: expr_) -> @expr {
let lo = self.last_span.lo;
let decl = parse_decl();
let body = parse_body();
- let fakeblock = ast::blk {
+ let fakeblock = ast::Block {
view_items: ~[],
stmts: ~[],
expr: Some(body),
self.eat(&token::COMMA);
}
- let blk = ast::blk {
+ let blk = ast::Block {
view_items: ~[],
stmts: ~[],
expr: Some(expr),
}
// parse a local variable declaration
- fn parse_local(&self, is_mutbl: bool) -> @local {
+ fn parse_local(&self, is_mutbl: bool) -> @Local {
let lo = self.span.lo;
let pat = self.parse_pat();
};
if self.eat(&token::COLON) { ty = self.parse_ty(false); }
let init = self.parse_initializer();
- @spanned(
- lo,
- self.last_span.hi,
- ast::local_ {
- is_mutbl: is_mutbl,
- ty: ty,
- pat: pat,
- init: init,
- id: self.get_id(),
- }
- )
+ @ast::Local {
+ is_mutbl: is_mutbl,
+ ty: ty,
+ pat: pat,
+ init: init,
+ id: self.get_id(),
+ span: mk_sp(lo, self.last_span.hi),
+ }
}
// parse a "let" stmt
}
// parse a block. No inner attrs are allowed.
- pub fn parse_block(&self) -> blk {
+ pub fn parse_block(&self) -> Block {
maybe_whole!(self, nt_block);
let lo = self.span.lo;
// parse a block. Inner attrs are allowed.
fn parse_inner_attrs_and_block(&self)
- -> (~[Attribute], blk) {
+ -> (~[Attribute], Block) {
maybe_whole!(pair_empty self, nt_block);
// I guess that also means "already parsed the 'impure'" if
// necessary, and this should take a qualifier.
// some blocks start with "#{"...
- fn parse_block_tail(&self, lo: BytePos, s: blk_check_mode) -> blk {
+ fn parse_block_tail(&self, lo: BytePos, s: blk_check_mode) -> Block {
self.parse_block_tail_(lo, s, ~[])
}
// parse the rest of a block expression or function body
fn parse_block_tail_(&self, lo: BytePos, s: blk_check_mode,
- first_item_attrs: ~[Attribute]) -> blk {
+ first_item_attrs: ~[Attribute]) -> Block {
let mut stmts = ~[];
let mut expr = None;
let hi = self.span.hi;
self.bump();
- ast::blk {
+ ast::Block {
view_items: view_items,
stmts: stmts,
expr: expr,
let prefix = prefix.dir_path();
let mod_path_stack = &*self.mod_path_stack;
let mod_path = Path(".").push_many(*mod_path_stack);
+ let dir_path = prefix.push_many(mod_path.components);
let file_path = match ::attr::first_attr_value_str_by_name(
outer_attrs, "path") {
Some(d) => {
let path = Path(d);
if !path.is_absolute {
- mod_path.push(d)
+ dir_path.push(d)
} else {
path
}
}
- None => mod_path.push(token::interner_get(id.name) + ".rs") // default
+ None => {
+ let mod_name = token::interner_get(id.name).to_owned();
+ let default_path_str = mod_name + ".rs";
+ let secondary_path_str = mod_name + "/mod.rs";
+ let default_path = dir_path.push(default_path_str);
+ let secondary_path = dir_path.push(secondary_path_str);
+ let default_exists = default_path.exists();
+ let secondary_exists = secondary_path.exists();
+ match (default_exists, secondary_exists) {
+ (true, false) => default_path,
+ (false, true) => secondary_path,
+ (false, false) => {
+ self.span_fatal(id_sp, fmt!("file not found for module `%s`", mod_name));
+ }
+ (true, true) => {
+ self.span_fatal(id_sp,
+ fmt!("file for module `%s` found at both %s and %s",
+ mod_name, default_path_str, secondary_path_str));
+ }
+ }
+ }
};
- self.eval_src_mod_from_path(prefix,
- file_path,
+ self.eval_src_mod_from_path(file_path,
outer_attrs.to_owned(),
id_sp)
}
fn eval_src_mod_from_path(&self,
- prefix: Path,
path: Path,
outer_attrs: ~[ast::Attribute],
id_sp: span) -> (ast::item_, ~[ast::Attribute]) {
-
- let full_path = if path.is_absolute {
- path
- } else {
- prefix.push_many(path.components)
- };
- let full_path = full_path.normalize();
+ let full_path = path.normalize();
let maybe_i = do self.sess.included_mod_stack.iter().position |p| { *p == full_path };
match maybe_i {
// Parses a source module as a crate. This is the main
// entry point for the parser.
- pub fn parse_crate_mod(&self) -> @crate {
+ pub fn parse_crate_mod(&self) -> @Crate {
let lo = self.span.lo;
// parse the crate's inner attrs, maybe (oops) one
// of the attrs of an item:
let first_item_outer_attrs = next;
// parse the items inside the crate:
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
- @spanned(lo, self.span.lo,
- ast::crate_ { module: m,
- attrs: inner,
- config: self.cfg.clone() })
+
+ @ast::Crate {
+ module: m,
+ attrs: inner,
+ config: self.cfg.clone(),
+ span: mk_sp(lo, self.span.lo)
+ }
}
pub fn parse_str(&self) -> @str {
/// For interpolation during macro expansion.
pub enum nonterminal {
nt_item(@ast::item),
- nt_block(ast::blk),
+ nt_block(ast::Block),
nt_stmt(@ast::stmt),
nt_pat( @ast::pat),
nt_expr(@ast::expr),
// if an interner exists in TLS, return it. Otherwise, prepare a
// fresh one.
pub fn get_ident_interner() -> @ident_interner {
- #[cfg(not(stage0))]
static key: local_data::Key<@@::parse::token::ident_interner> =
&local_data::Key;
- #[cfg(stage0)]
- fn key(_: @@::parse::token::ident_interner) {}
match local_data::get(key, |k| k.map(|&k| *k)) {
Some(interner) => *interner,
None => {
// The @ps is stored here to prevent recursive type.
pub enum ann_node<'self> {
- node_block(@ps, &'self ast::blk),
+ node_block(@ps, &'self ast::Block),
node_item(@ps, &'self ast::item),
node_expr(@ps, &'self ast::expr),
node_pat(@ps, &'self ast::pat),
pub fn print_crate(cm: @CodeMap,
intr: @ident_interner,
span_diagnostic: @diagnostic::span_handler,
- crate: &ast::crate,
+ crate: &ast::Crate,
filename: @str,
in: @io::Reader,
out: @io::Writer,
print_crate_(s, crate);
}
-pub fn print_crate_(s: @ps, crate: &ast::crate) {
- print_mod(s, &crate.node.module, crate.node.attrs);
+pub fn print_crate_(s: @ps, crate: &ast::Crate) {
+ print_mod(s, &crate.module, crate.attrs);
print_remaining_comments(s);
eof(s.s);
}
}
}
-pub fn block_to_str(blk: &ast::blk, intr: @ident_interner) -> ~str {
+pub fn block_to_str(blk: &ast::Block, intr: @ident_interner) -> ~str {
do io::with_str_writer |wr| {
let s = rust_printer(wr, intr);
// containing cbox, will be closed by print-block at }
match item.node {
ast::foreign_item_fn(ref decl, purity, ref generics) => {
print_fn(s, decl, Some(purity), AbiSet::Rust(), item.ident, generics, None,
- ast::inherited);
+ item.vis);
end(s); // end head-ibox
word(s.s, ";");
end(s); // end the outer fn box
}
ast::foreign_item_static(ref t, m) => {
- head(s, "static");
+ head(s, visibility_qualified(item.vis, "static"));
if m {
word_space(s, "mut");
}
maybe_print_trailing_comment(s, st.span, None);
}
-pub fn print_block(s: @ps, blk: &ast::blk) {
+pub fn print_block(s: @ps, blk: &ast::Block) {
print_possibly_embedded_block(s, blk, block_normal, indent_unit);
}
-pub fn print_block_unclosed(s: @ps, blk: &ast::blk) {
+pub fn print_block_unclosed(s: @ps, blk: &ast::Block) {
print_possibly_embedded_block_(s, blk, block_normal, indent_unit, &[],
false);
}
-pub fn print_block_unclosed_indent(s: @ps, blk: &ast::blk, indented: uint) {
+pub fn print_block_unclosed_indent(s: @ps, blk: &ast::Block, indented: uint) {
print_possibly_embedded_block_(s, blk, block_normal, indented, &[],
false);
}
pub fn print_block_with_attrs(s: @ps,
- blk: &ast::blk,
+ blk: &ast::Block,
attrs: &[ast::Attribute]) {
print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs,
true);
pub enum embed_type { block_block_fn, block_normal, }
pub fn print_possibly_embedded_block(s: @ps,
- blk: &ast::blk,
+ blk: &ast::Block,
embedded: embed_type,
indented: uint) {
print_possibly_embedded_block_(
}
pub fn print_possibly_embedded_block_(s: @ps,
- blk: &ast::blk,
+ blk: &ast::Block,
embedded: embed_type,
indented: uint,
attrs: &[ast::Attribute],
(s.ann.post)(ann_node);
}
-pub fn print_if(s: @ps, test: &ast::expr, blk: &ast::blk,
+pub fn print_if(s: @ps, test: &ast::expr, blk: &ast::Block,
elseopt: Option<@ast::expr>, chk: bool) {
head(s, "if");
if chk { word_nbsp(s, "check"); }
}
pub fn print_expr(s: @ps, expr: &ast::expr) {
- fn print_field(s: @ps, field: &ast::field) {
+ fn print_field(s: @ps, field: &ast::Field) {
ibox(s, indent_unit);
- print_ident(s, field.node.ident);
+ print_ident(s, field.ident);
word_space(s, ":");
- print_expr(s, field.node.expr);
+ print_expr(s, field.expr);
end(s);
}
- fn get_span(field: &ast::field) -> codemap::span { return field.span; }
+ fn get_span(field: &ast::Field) -> codemap::span { return field.span; }
maybe_print_comment(s, expr.span.lo);
ibox(s, indent_unit);
end(s);
}
-pub fn print_local_decl(s: @ps, loc: &ast::local) {
- print_pat(s, loc.node.pat);
- match loc.node.ty.node {
+pub fn print_local_decl(s: @ps, loc: &ast::Local) {
+ print_pat(s, loc.pat);
+ match loc.ty.node {
ast::ty_infer => (),
- _ => { word_space(s, ":"); print_type(s, &loc.node.ty); }
+ _ => { word_space(s, ":"); print_type(s, &loc.ty); }
}
}
ibox(s, indent_unit);
word_nbsp(s, "let");
- if loc.node.is_mutbl {
+ if loc.is_mutbl {
word_nbsp(s, "mut");
}
- fn print_local(s: @ps, loc: &ast::local) {
+ fn print_local(s: @ps, loc: &ast::Local) {
ibox(s, indent_unit);
print_local_decl(s, loc);
end(s);
- match loc.node.init {
+ match loc.init {
Some(init) => {
nbsp(s);
word_space(s, "=");
word(s.s, ident_to_str(&ident));
}
-pub fn print_for_decl(s: @ps, loc: &ast::local, coll: &ast::expr) {
+pub fn print_for_decl(s: @ps, loc: &ast::Local, coll: &ast::expr) {
print_local_decl(s, loc);
space(s.s);
word_space(s, "in");
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
-#[deny(deprecated_pattern)];
-
extern mod extra;
pub mod util {
p
}
-pub fn string_to_crate (source_str : @str) -> @ast::crate {
+pub fn string_to_crate (source_str : @str) -> @ast::Crate {
string_to_parser(source_str).parse_crate_mod()
}
visit_view_item: @fn(&view_item, (E, vt<E>)),
visit_foreign_item: @fn(@foreign_item, (E, vt<E>)),
visit_item: @fn(@item, (E, vt<E>)),
- visit_local: @fn(@local, (E, vt<E>)),
- visit_block: @fn(&blk, (E, vt<E>)),
+ visit_local: @fn(@Local, (E, vt<E>)),
+ visit_block: @fn(&Block, (E, vt<E>)),
visit_stmt: @fn(@stmt, (E, vt<E>)),
visit_arm: @fn(&arm, (E, vt<E>)),
visit_pat: @fn(@pat, (E, vt<E>)),
visit_expr_post: @fn(@expr, (E, vt<E>)),
visit_ty: @fn(&Ty, (E, vt<E>)),
visit_generics: @fn(&Generics, (E, vt<E>)),
- visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id, (E, vt<E>)),
+ visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, node_id, (E, vt<E>)),
visit_ty_method: @fn(&ty_method, (E, vt<E>)),
visit_trait_method: @fn(&trait_method, (E, vt<E>)),
visit_struct_def: @fn(@struct_def, ident, &Generics, node_id, (E, vt<E>)),
};
}
-pub fn visit_crate<E:Clone>(c: &crate, (e, v): (E, vt<E>)) {
- (v.visit_mod)(&c.node.module, c.span, crate_node_id, (e, v));
+pub fn visit_crate<E:Clone>(c: &Crate, (e, v): (E, vt<E>)) {
+ (v.visit_mod)(&c.module, c.span, crate_node_id, (e, v));
}
pub fn visit_mod<E:Clone>(m: &_mod,
pub fn visit_view_item<E>(_vi: &view_item, (_e, _v): (E, vt<E>)) { }
-pub fn visit_local<E:Clone>(loc: &local, (e, v): (E, vt<E>)) {
- (v.visit_pat)(loc.node.pat, (e.clone(), v));
- (v.visit_ty)(&loc.node.ty, (e.clone(), v));
- match loc.node.init {
+pub fn visit_local<E:Clone>(loc: &Local, (e, v): (E, vt<E>)) {
+ (v.visit_pat)(loc.pat, (e.clone(), v));
+ (v.visit_ty)(&loc.ty, (e.clone(), v));
+ match loc.init {
None => (),
Some(ex) => (v.visit_expr)(ex, (e, v))
}
(e, v));
}
-pub fn visit_fn<E:Clone>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
+pub fn visit_fn<E:Clone>(fk: &fn_kind, decl: &fn_decl, body: &Block, _sp: span,
_id: node_id, (e, v): (E, vt<E>)) {
visit_fn_decl(decl, (e.clone(), v));
let generics = generics_of_fn(fk);
(v.visit_ty)(&sf.node.ty, (e, v));
}
-pub fn visit_block<E:Clone>(b: &blk, (e, v): (E, vt<E>)) {
+pub fn visit_block<E:Clone>(b: &Block, (e, v): (E, vt<E>)) {
for b.view_items.iter().advance |vi| {
(v.visit_view_item)(vi, (e.clone(), v));
}
expr_struct(ref p, ref flds, base) => {
visit_path(p, (e.clone(), v));
for flds.iter().advance |f| {
- (v.visit_expr)(f.node.expr, (e.clone(), v));
+ (v.visit_expr)(f.expr, (e.clone(), v));
}
visit_expr_opt(base, (e.clone(), v));
}
visit_view_item: @fn(&view_item),
visit_foreign_item: @fn(@foreign_item),
visit_item: @fn(@item),
- visit_local: @fn(@local),
- visit_block: @fn(&blk),
+ visit_local: @fn(@Local),
+ visit_block: @fn(&Block),
visit_stmt: @fn(@stmt),
visit_arm: @fn(&arm),
visit_pat: @fn(@pat),
visit_expr_post: @fn(@expr),
visit_ty: @fn(&Ty),
visit_generics: @fn(&Generics),
- visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id),
+ visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, node_id),
visit_ty_method: @fn(&ty_method),
visit_trait_method: @fn(&trait_method),
visit_struct_def: @fn(@struct_def, ident, &Generics, node_id),
f(i);
visit_item(i, (e, v));
}
- fn v_local(f: @fn(@local), l: @local, (e, v): ((), vt<()>)) {
+ fn v_local(f: @fn(@Local), l: @Local, (e, v): ((), vt<()>)) {
f(l);
visit_local(l, (e, v));
}
- fn v_block(f: @fn(&ast::blk), bl: &ast::blk, (e, v): ((), vt<()>)) {
+ fn v_block(f: @fn(&ast::Block), bl: &ast::Block, (e, v): ((), vt<()>)) {
f(bl);
visit_block(bl, (e, v));
}
visit_generics(ps, (e, v));
}
fn v_fn(
- f: @fn(&fn_kind, &fn_decl, &blk, span, node_id),
+ f: @fn(&fn_kind, &fn_decl, &Block, span, node_id),
fk: &fn_kind,
decl: &fn_decl,
- body: &blk,
+ body: &Block,
sp: span,
id: node_id,
(e, v): ((), vt<()>)
// free the environment (which should be a unique closure).
const type_desc *td = env->td;
td->drop_glue(NULL,
-#ifdef _RUST_STAGE0
- NULL,
-#endif
box_body(env));
task->kernel->region()->free(env);
}
struct type_desc;
typedef void CDECL (glue_fn)(void *,
-#ifdef _RUST_STAGE0
- const type_desc **,
-#endif
void *);
// Corresponds to the boxed data in the @ region. The body follows the
LLVMInsertBasicBlockInContext
LLVMInsertIntoBuilder
LLVMInsertIntoBuilderWithName
+LLVMInstructionEraseFromParent
LLVMInt16Type
LLVMInt16TypeInContext
LLVMInt1Type
+S 2013-07-21 e336cbf
+ macos-i386 d9666dccc1040ebe298a54acb378902a7472ad0f
+ macos-x86_64 808f68916444e3857ef2aab20f8db9db8f4b0b4a
+ winnt-i386 f9a5f891fd24e9446acb2a1b5d697461665c4388
+ freebsd-x86_64 8e79f6e970bc33ea6a3b9329bc4526d89ca63d47
+ linux-i386 054a0229b9cbdadf013868ba01a8277883f83a6d
+ linux-x86_64 2c53a72e9c9bb547df248a2d4b857d480ce0b910
+
S 2013-06-23 f827561
macos-i386 63ffbcf99b6853d7840bdfe01380068518d0e466
macos-x86_64 b34fdf3845f8ef4760817007d8ef820cd32f2e07
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:error opening
-
-mod doesnotexist;
\ No newline at end of file
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` found at both
+
+fn main() {
+ assert_eq!(mod_file_aux::bar(), 10);
+}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test not a test. aux file
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test not a test. aux file
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-mod not_a_real_file; //~ ERROR not_a_real_file.rs
+mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
fn main() {
assert_eq!(mod_file_aux::bar(), 10);
trait fake_ext_ctxt {
- fn cfg() -> ast::crate_cfg;
+ fn cfg() -> ast::Crate_cfg;
fn parse_sess() -> parse::parse_sess;
fn call_site() -> span;
fn ident_of(st: &str) -> ast::ident;
type fake_session = parse::parse_sess;
impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::crate_cfg { ~[] }
+ fn cfg() -> ast::Crate_cfg { ~[] }
fn parse_sess() -> parse::parse_sess { self }
fn call_site() -> span {
codemap::span {
use syntax::print::*;
trait fake_ext_ctxt {
- fn cfg() -> ast::crate_cfg;
+ fn cfg() -> ast::Crate_cfg;
fn parse_sess() -> parse::parse_sess;
fn call_site() -> span;
fn ident_of(st: &str) -> ast::ident;
type fake_session = parse::parse_sess;
impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::crate_cfg { ~[] }
+ fn cfg() -> ast::Crate_cfg { ~[] }
fn parse_sess() -> parse::parse_sess { self }
fn call_site() -> span {
codemap::span {
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:nonzero
+// exec-env:RUST_NEWRT=1
+
+use std::os;
+
+fn main() {
+ os::args();
+ fail!("please have a nonzero exit status");
+}
trait fake_ext_ctxt {
fn session() -> fake_session;
- fn cfg() -> ast::crate_cfg;
+ fn cfg() -> ast::Crate_cfg;
fn parse_sess() -> parser::parse_sess;
}
-type fake_options = {cfg: ast::crate_cfg};
+type fake_options = {cfg: ast::Crate_cfg};
type fake_session = {opts: @fake_options,
parse_sess: parser::parse_sess};
impl of fake_ext_ctxt for fake_session {
fn session() -> fake_session {self}
- fn cfg() -> ast::crate_cfg { self.opts.cfg }
+ fn cfg() -> ast::Crate_cfg { self.opts.cfg }
fn parse_sess() -> parser::parse_sess { self.parse_sess }
}
trait fake_ext_ctxt {
- fn cfg() -> ast::crate_cfg;
+ fn cfg() -> ast::Crate_cfg;
fn parse_sess() -> parse::parse_sess;
fn call_site() -> span;
fn ident_of(st: &str) -> ast::ident;
type fake_session = parse::parse_sess;
impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::crate_cfg { ~[] }
+ fn cfg() -> ast::Crate_cfg { ~[] }
fn parse_sess() -> parse::parse_sess { self }
fn call_site() -> span {
codemap::span {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#[allow(non_implicitly_copyable_typarams)];
-
extern mod syntax;
use syntax::ext::base::ExtCtxt;
// xfail-test #6122
-#[forbid(deprecated_pattern)];
-
extern mod extra;
// These tests used to be separate files, but I wanted to refactor all
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
-// error on implicit copies to check fixed length vectors
-// are implicitly copyable
-#[deny(implicit_copies)]
pub fn main() {
let arr = [1,2,3];
let arr2 = arr;
fn f<T>(_x: T) {
}
-#[deny(non_implicitly_copyable_typarams)]
pub fn main() {
f(C(1u));
}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for issue #5275
+
+fn foo(self_: &A) -> int {
+ if true {
+ fail!()
+ } else {
+ *bar(self_.bar)
+ }
+}
+
+fn bar<'r>(_: &'r mut int) -> &'r int {
+ fail!()
+}
+
+struct A {
+ bar: @mut int,
+}
+
+pub fn main() {}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-pretty
+// xfail-fast
+
+mod mod_dir_implicit_aux;
+
+pub fn main() {
+ assert_eq!(mod_dir_implicit_aux::foo(), 10);
+}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() -> int { 10 }