1
Fork 0

Store item paths in ast_map, get rid of trans::local_ctxt

The direct motivation for this was that the monomorphizer needs to be
able to generate sane symbols for random items. The typechecker can
probably also use this in the future to provide more useful error
messages.
This commit is contained in:
Marijn Haverbeke 2012-02-03 09:53:37 +01:00
parent c1b075d042
commit 43ce38375d
18 changed files with 383 additions and 400 deletions

View file

@ -18,6 +18,7 @@ import syntax::ast;
import syntax::print::pprust; import syntax::print::pprust;
import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False}; import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False};
import util::filesearch; import util::filesearch;
import middle::ast_map::{path, path_mod, path_name};
enum output_type { enum output_type {
output_type_none, output_type_none,
@ -514,25 +515,27 @@ fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> str {
ret hash; ret hash;
} }
fn mangle(ss: [str]) -> str { fn mangle(ss: path) -> str {
// Follow C++ namespace-mangling style // Follow C++ namespace-mangling style
let n = "_ZN"; // Begin name-sequence. let n = "_ZN"; // Begin name-sequence.
for s: str in ss { n += #fmt["%u%s", str::byte_len(s), s]; } for s in ss {
alt s { path_name(s) | path_mod(s) {
n += #fmt["%u%s", str::byte_len(s), s];
} }
}
n += "E"; // End name-sequence. n += "E"; // End name-sequence.
n
ret n;
} }
fn exported_name(path: [str], hash: str, _vers: str) -> str { fn exported_name(path: path, hash: str, _vers: str) -> str {
// FIXME: versioning isn't working yet // FIXME: versioning isn't working yet
ret mangle(path + [path_name(hash)]); // + "@" + vers;
ret mangle(path + [hash]); // + "@" + vers;
} }
fn mangle_exported_name(ccx: @crate_ctxt, path: [str], t: ty::t) -> str { fn mangle_exported_name(ccx: @crate_ctxt, path: path, t: ty::t) -> str {
let hash = get_symbol_hash(ccx, t); let hash = get_symbol_hash(ccx, t);
ret exported_name(path, hash, ccx.link_meta.vers); ret exported_name(path, hash, ccx.link_meta.vers);
} }
@ -541,15 +544,15 @@ fn mangle_internal_name_by_type_only(ccx: @crate_ctxt, t: ty::t, name: str) ->
str { str {
let s = util::ppaux::ty_to_short_str(ccx.tcx, t); let s = util::ppaux::ty_to_short_str(ccx.tcx, t);
let hash = get_symbol_hash(ccx, t); let hash = get_symbol_hash(ccx, t);
ret mangle([name, s, hash]); ret mangle([path_name(name), path_name(s), path_name(hash)]);
} }
fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: [str], fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: path,
flav: str) -> str { flav: str) -> str {
ret mangle(path + [ccx.names(flav)]); ret mangle(path + [path_name(ccx.names(flav))]);
} }
fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str { fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: path) -> str {
ret mangle(path); ret mangle(path);
} }

View file

@ -447,11 +447,11 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, ""); encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, "");
ecx.ccx.ast_map.items {|key, val| ecx.ccx.ast_map.items {|key, val|
alt val { alt val {
middle::ast_map::node_item(i) { middle::ast_map::node_item(i, _) {
index += [{val: key, pos: ebml_w.writer.tell()}]; index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_item(ecx, ebml_w, i, index); encode_info_for_item(ecx, ebml_w, i, index);
} }
middle::ast_map::node_native_item(i) { middle::ast_map::node_native_item(i, _) {
index += [{val: key, pos: ebml_w.writer.tell()}]; index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_native_item(ecx, ebml_w, i); encode_info_for_native_item(ecx, ebml_w, i);
} }

View file

@ -4,10 +4,13 @@ import syntax::ast::*;
import syntax::ast_util; import syntax::ast_util;
import syntax::{visit, codemap}; import syntax::{visit, codemap};
enum path_elt { path_mod(str), path_name(str) }
type path = [path_elt];
enum ast_node { enum ast_node {
node_item(@item), node_item(@item, @path),
node_native_item(@native_item), node_native_item(@native_item, @path),
node_method(@method), node_method(@method, @path),
node_expr(@expr), node_expr(@expr),
// Locals are numbered, because the alias analysis needs to know in which // Locals are numbered, because the alias analysis needs to know in which
// order they are introduced. // order they are introduced.
@ -17,66 +20,78 @@ enum ast_node {
} }
type map = std::map::map<node_id, ast_node>; type map = std::map::map<node_id, ast_node>;
type ctx = @{map: map, mutable local_id: uint}; type ctx = {map: map, mutable path: path, mutable local_id: uint};
type vt = visit::vt<ctx>;
fn map_crate(c: crate) -> map { fn map_crate(c: crate) -> map {
let cx = @{map: std::map::new_int_hash(), let cx = {map: std::map::new_int_hash(),
mutable path: [],
mutable local_id: 0u}; mutable local_id: 0u};
visit::visit_crate(c, cx, visit::mk_vt(@{
let v_map = visit::mk_simple_visitor visit_item: map_item,
(@{visit_item: bind map_item(cx, _), visit_native_item: map_native_item,
visit_native_item: bind map_native_item(cx, _), visit_expr: map_expr,
visit_expr: bind map_expr(cx, _), visit_fn: map_fn,
visit_fn: bind map_fn(cx, _, _, _, _, _), visit_local: map_local,
visit_local: bind map_local(cx, _), visit_arm: map_arm
visit_arm: bind map_arm(cx, _) with *visit::default_visitor()
with *visit::default_simple_visitor()}); }));
visit::visit_crate(c, (), v_map);
ret cx.map; ret cx.map;
} }
fn map_fn(cx: ctx, _fk: visit::fn_kind, decl: fn_decl, _body: blk, fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
_sp: codemap::span, _id: node_id) { sp: codemap::span, id: node_id, cx: ctx, v: vt) {
for a in decl.inputs { for a in decl.inputs {
cx.map.insert(a.id, node_arg(a, cx.local_id)); cx.map.insert(a.id, node_arg(a, cx.local_id));
cx.local_id += 1u; cx.local_id += 1u;
} }
visit::visit_fn(fk, decl, body, sp, id, cx, v);
} }
fn map_local(cx: ctx, loc: @local) { fn map_local(loc: @local, cx: ctx, v: vt) {
pat_util::pat_bindings(loc.node.pat) {|p_id, _s, _p| pat_util::pat_bindings(loc.node.pat) {|p_id, _s, _p|
cx.map.insert(p_id, node_local(cx.local_id)); cx.map.insert(p_id, node_local(cx.local_id));
cx.local_id += 1u; cx.local_id += 1u;
}; };
visit::visit_local(loc, cx, v);
} }
fn map_arm(cx: ctx, arm: arm) { fn map_arm(arm: arm, cx: ctx, v: vt) {
pat_util::pat_bindings(arm.pats[0]) {|p_id, _s, _p| pat_util::pat_bindings(arm.pats[0]) {|p_id, _s, _p|
cx.map.insert(p_id, node_local(cx.local_id)); cx.map.insert(p_id, node_local(cx.local_id));
cx.local_id += 1u; cx.local_id += 1u;
}; };
visit::visit_arm(arm, cx, v);
} }
fn map_item(cx: ctx, i: @item) { fn map_item(i: @item, cx: ctx, v: vt) {
cx.map.insert(i.id, node_item(i)); cx.map.insert(i.id, node_item(i, @cx.path));
alt i.node { alt i.node {
item_impl(_, _, _, ms) { item_impl(_, _, _, ms) {
for m in ms { cx.map.insert(m.id, node_method(m)); } for m in ms { cx.map.insert(m.id, node_method(m, @cx.path)); }
} }
item_res(_, _, _, dtor_id, ctor_id) { item_res(_, _, _, dtor_id, ctor_id) {
cx.map.insert(ctor_id, node_res_ctor(i)); cx.map.insert(ctor_id, node_res_ctor(i));
cx.map.insert(dtor_id, node_item(i)); cx.map.insert(dtor_id, node_item(i, @cx.path));
} }
_ { } _ { }
} }
alt i.node {
item_mod(_) | item_native_mod(_) { cx.path += [path_mod(i.ident)]; }
_ { cx.path += [path_name(i.ident)]; }
}
visit::visit_item(i, cx, v);
vec::pop(cx.path);
} }
fn map_native_item(cx: ctx, i: @native_item) { fn map_native_item(i: @native_item, cx: ctx, v: vt) {
cx.map.insert(i.id, node_native_item(i)); cx.map.insert(i.id, node_native_item(i, @cx.path));
visit::visit_native_item(i, cx, v);
} }
fn map_expr(cx: ctx, ex: @expr) { fn map_expr(ex: @expr, cx: ctx, v: vt) {
cx.map.insert(ex.id, node_expr(ex)); cx.map.insert(ex.id, node_expr(ex));
visit::visit_expr(ex, cx, v);
} }
// Local Variables: // Local Variables:

View file

@ -761,7 +761,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
log(debug, codemap::span_to_str(sp, cx.sess.codemap)); log(debug, codemap::span_to_str(sp, cx.sess.codemap));
let (ident, ret_ty, id) = alt cx.ast_map.get(fcx.id) { let (ident, ret_ty, id) = alt cx.ast_map.get(fcx.id) {
ast_map::node_item(item) { ast_map::node_item(item, _) {
alt item.node { alt item.node {
ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _) { ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _) {
(item.ident, decl.output, item.id) (item.ident, decl.output, item.id)
@ -770,7 +770,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
bound to non-function"); } bound to non-function"); }
} }
} }
ast_map::node_method(method) { ast_map::node_method(method, _) {
(method.ident, method.decl.output, method.id) (method.ident, method.decl.output, method.id)
} }
ast_map::node_res_ctor(item) { ast_map::node_res_ctor(item) {
@ -808,7 +808,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
option::none {} option::none {}
} }
let path = str::connect(fcx.lcx.path + [ident], "::"); let path = path_str(fcx.path);
let loc = codemap::lookup_char_pos(cx.sess.codemap, let loc = codemap::lookup_char_pos(cx.sess.codemap,
sp.lo); sp.lo);

View file

@ -480,7 +480,8 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
// is this a main fn declaration? // is this a main fn declaration?
alt fk { alt fk {
visit::fk_item_fn(nm, _) { visit::fk_item_fn(nm, _) {
if is_main_name([nm]) && !e.sess.building_library { if is_main_name([ast_map::path_name(nm)]) &&
!e.sess.building_library {
// This is a main function -- set it in the session // This is a main function -- set it in the session
// as the main ID // as the main ID
e.sess.main_fn = some((id, sp)); e.sess.main_fn = some((id, sp));

View file

@ -470,15 +470,6 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info,
ret s; ret s;
} }
//fn variant_names(ccx: @crate_ctxt, tag_id: ast::def_id) -> [str] {
// assert ast::local_crate == tag_id.crate;
// alt ccx.tcx.items.get(tag_id.node) {
// ast_map::node_item(@{node: ast::item_tag(variants, _), _}) {
// vec::map(variants) {|variant| variant.node.name}
// }
// }
//}
fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef { fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
// Loop over all the enum variants and write their shapes into a // Loop over all the enum variants and write their shapes into a
// data buffer. As we do this, it's possible for us to discover // data buffer. As we do this, it's possible for us to discover

View file

@ -265,7 +265,7 @@ fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] {
fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id, fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
vdefs: {enm: def_id, var: def_id}, val: ValueRef) -> vdefs: {enm: def_id, var: def_id}, val: ValueRef) ->
{vals: [ValueRef], bcx: @block_ctxt} { {vals: [ValueRef], bcx: @block_ctxt} {
let ccx = bcx.fcx.lcx.ccx, bcx = bcx; let ccx = bcx.fcx.ccx, bcx = bcx;
// invariant: // invariant:
// pat_id must have the same length ty_param_substs as vdefs? // pat_id must have the same length ty_param_substs as vdefs?
let ty_param_substs = ty::node_id_to_type_params(ccx.tcx, pat_id); let ty_param_substs = ty::node_id_to_type_params(ccx.tcx, pat_id);
@ -412,7 +412,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
let vals_left = let vals_left =
vec::slice(vals, 0u, col) + vec::slice(vals, 0u, col) +
vec::slice(vals, col + 1u, vec::len(vals)); vec::slice(vals, col + 1u, vec::len(vals));
let ccx = bcx.fcx.lcx.ccx; let ccx = bcx.fcx.ccx;
let pat_id = 0; let pat_id = 0;
for br: match_branch in m { for br: match_branch in m {
// Find a real id (we're adding placeholder wildcard patterns, but // Find a real id (we're adding placeholder wildcard patterns, but
@ -692,7 +692,7 @@ fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms_: [ast::arm],
} }
let exit_map = []; let exit_map = [];
let t = base::node_id_type(cx.fcx.lcx.ccx, expr.id); let t = base::node_id_type(cx.fcx.ccx, expr.id);
let vr = base::spill_if_immediate(er.bcx, er.val, t); let vr = base::spill_if_immediate(er.bcx, er.val, t);
compile_submatch(vr.bcx, match, [vr.val], compile_submatch(vr.bcx, match, [vr.val],
bind mk_fail(alt_cx, expr.span, fail_cx), exit_map); bind mk_fail(alt_cx, expr.span, fail_cx), exit_map);
@ -719,7 +719,7 @@ fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms_: [ast::arm],
// Not alt-related, but similar to the pattern-munging code above // Not alt-related, but similar to the pattern-munging code above
fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef, fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
make_copy: bool) -> @block_ctxt { make_copy: bool) -> @block_ctxt {
let ccx = bcx.fcx.lcx.ccx, bcx = bcx; let ccx = bcx.fcx.ccx, bcx = bcx;
// Necessary since bind_irrefutable_pat is called outside trans_alt // Necessary since bind_irrefutable_pat is called outside trans_alt
alt normalize_pat(bcx_tcx(bcx), pat).node { alt normalize_pat(bcx_tcx(bcx), pat).node {

View file

@ -24,6 +24,7 @@ import front::attr;
import middle::freevars::*; import middle::freevars::*;
import back::{link, abi, upcall}; import back::{link, abi, upcall};
import syntax::{ast, ast_util, codemap}; import syntax::{ast, ast_util, codemap};
import ast_util::local_def;
import syntax::visit; import syntax::visit;
import syntax::codemap::span; import syntax::codemap::span;
import syntax::print::pprust::{expr_to_str, stmt_to_str, path_to_str}; import syntax::print::pprust::{expr_to_str, stmt_to_str, path_to_str};
@ -44,6 +45,7 @@ import util::ppaux::{ty_to_str, ty_to_short_str};
import shape::static_size_of_enum; import shape::static_size_of_enum;
import common::*; import common::*;
import build::*; import build::*;
import ast_map::{path, path_mod, path_name};
fn type_of_1(bcx: @block_ctxt, t: ty::t) -> TypeRef { fn type_of_1(bcx: @block_ctxt, t: ty::t) -> TypeRef {
let cx = bcx_ccx(bcx); let cx = bcx_ccx(bcx);
@ -222,13 +224,12 @@ fn type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t)
} }
} }
fn type_of_ty_param_bounds_and_ty(lcx: @local_ctxt, fn type_of_ty_param_bounds_and_ty
tpt: ty::ty_param_bounds_and_ty) -> TypeRef { (ccx: @crate_ctxt, tpt: ty::ty_param_bounds_and_ty) -> TypeRef {
let cx = lcx.ccx;
let t = tpt.ty; let t = tpt.ty;
alt ty::struct(cx.tcx, t) { alt ty::struct(ccx.tcx, t) {
ty::ty_fn(_) { ty::ty_fn(_) {
ret type_of_fn_from_ty(cx, t, *tpt.bounds); ret type_of_fn_from_ty(ccx, t, *tpt.bounds);
} }
_ { _ {
// fall through // fall through
@ -237,8 +238,8 @@ fn type_of_ty_param_bounds_and_ty(lcx: @local_ctxt,
// FIXME: could have a precondition on tpt, but that // FIXME: could have a precondition on tpt, but that
// doesn't work right now because one predicate can't imply // doesn't work right now because one predicate can't imply
// another // another
check (type_has_static_size(cx, t)); check type_has_static_size(ccx, t);
type_of(cx, t) type_of(ccx, t)
} }
fn type_of_or_i8(bcx: @block_ctxt, typ: ty::t) -> TypeRef { fn type_of_or_i8(bcx: @block_ctxt, typ: ty::t) -> TypeRef {
@ -329,7 +330,7 @@ fn get_simple_extern_fn(cx: @block_ctxt,
externs: hashmap<str, ValueRef>, externs: hashmap<str, ValueRef>,
llmod: ModuleRef, llmod: ModuleRef,
name: str, n_args: int) -> ValueRef { name: str, n_args: int) -> ValueRef {
let ccx = cx.fcx.lcx.ccx; let ccx = cx.fcx.ccx;
let inputs = vec::init_elt::<TypeRef>(n_args as uint, ccx.int_type); let inputs = vec::init_elt::<TypeRef>(n_args as uint, ccx.int_type);
let output = ccx.int_type; let output = ccx.int_type;
let t = T_fn(inputs, output); let t = T_fn(inputs, output);
@ -975,7 +976,7 @@ fn get_static_tydesc(cx: @block_ctxt, t: ty::t, ty_params: [uint])
some(info) { ret info; } some(info) { ret info; }
none { none {
bcx_ccx(cx).stats.n_static_tydescs += 1u; bcx_ccx(cx).stats.n_static_tydescs += 1u;
let info = declare_tydesc(cx.fcx.lcx, t, ty_params); let info = declare_tydesc(cx.fcx.ccx, t, ty_params);
bcx_ccx(cx).tydescs.insert(t, info); bcx_ccx(cx).tydescs.insert(t, info);
ret info; ret info;
} }
@ -1004,18 +1005,17 @@ fn set_custom_stack_growth_fn(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, 0u as c_uint, 1u as c_uint); llvm::LLVMAddFunctionAttr(f, 0u as c_uint, 1u as c_uint);
} }
fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) { fn set_glue_inlining(ccx: @crate_ctxt, f: ValueRef, t: ty::t) {
if ty::type_is_structural(cx.ccx.tcx, t) { if ty::type_is_structural(ccx.tcx, t) {
set_no_inline(f); set_no_inline(f);
} else { set_always_inline(f); } } else { set_always_inline(f); }
} }
// Generates the declaration for (but doesn't emit) a type descriptor. // Generates the declaration for (but doesn't emit) a type descriptor.
fn declare_tydesc(cx: @local_ctxt, t: ty::t, ty_params: [uint]) fn declare_tydesc(ccx: @crate_ctxt, t: ty::t, ty_params: [uint])
-> @tydesc_info { -> @tydesc_info {
log(debug, "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t)); log(debug, "+++ declare_tydesc " + ty_to_str(ccx.tcx, t));
let ccx = cx.ccx;
let llsize; let llsize;
let llalign; let llalign;
if check type_has_static_size(ccx, t) { if check type_has_static_size(ccx, t) {
@ -1030,13 +1030,11 @@ fn declare_tydesc(cx: @local_ctxt, t: ty::t, ty_params: [uint])
llalign = C_int(ccx, 0); llalign = C_int(ccx, 0);
} }
let name; let name;
if cx.ccx.sess.opts.debuginfo { if ccx.sess.opts.debuginfo {
name = mangle_internal_name_by_type_only(cx.ccx, t, "tydesc"); name = mangle_internal_name_by_type_only(ccx, t, "tydesc");
name = sanitize(name); name = sanitize(name);
} else { name = mangle_internal_name_by_seq(cx.ccx, "tydesc"); } } else { name = mangle_internal_name_by_seq(ccx, "tydesc"); }
let gvar = let gvar = str::as_buf(name, {|buf|
str::as_buf(name,
{|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf) llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
}); });
let info = let info =
@ -1044,49 +1042,47 @@ fn declare_tydesc(cx: @local_ctxt, t: ty::t, ty_params: [uint])
tydesc: gvar, tydesc: gvar,
size: llsize, size: llsize,
align: llalign, align: llalign,
mutable take_glue: none::<ValueRef>, mutable take_glue: none,
mutable drop_glue: none::<ValueRef>, mutable drop_glue: none,
mutable free_glue: none::<ValueRef>, mutable free_glue: none,
mutable cmp_glue: none::<ValueRef>, mutable cmp_glue: none,
ty_params: ty_params}; ty_params: ty_params};
log(debug, "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t)); log(debug, "--- declare_tydesc " + ty_to_str(ccx.tcx, t));
ret info; ret info;
} }
type glue_helper = fn@(@block_ctxt, ValueRef, ty::t); type glue_helper = fn@(@block_ctxt, ValueRef, ty::t);
fn declare_generic_glue(cx: @local_ctxt, t: ty::t, llfnty: TypeRef, name: str) fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
-> ValueRef { name: str) -> ValueRef {
let name = name; let name = name;
let fn_nm; let fn_nm;
if cx.ccx.sess.opts.debuginfo { if ccx.sess.opts.debuginfo {
fn_nm = mangle_internal_name_by_type_only(cx.ccx, t, "glue_" + name); fn_nm = mangle_internal_name_by_type_only(ccx, t, "glue_" + name);
fn_nm = sanitize(fn_nm); fn_nm = sanitize(fn_nm);
} else { fn_nm = mangle_internal_name_by_seq(cx.ccx, "glue_" + name); } } else { fn_nm = mangle_internal_name_by_seq(ccx, "glue_" + name); }
let llfn = decl_cdecl_fn(cx.ccx.llmod, fn_nm, llfnty); let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
set_glue_inlining(cx, llfn, t); set_glue_inlining(ccx, llfn, t);
ret llfn; ret llfn;
} }
// FIXME: was this causing the leak? // FIXME: was this causing the leak?
fn make_generic_glue_inner(cx: @local_ctxt, t: ty::t, fn make_generic_glue_inner(ccx: @crate_ctxt, t: ty::t,
llfn: ValueRef, helper: glue_helper, llfn: ValueRef, helper: glue_helper,
ty_params: [uint]) -> ValueRef { ty_params: [uint]) -> ValueRef {
let fcx = new_fn_ctxt(cx, llfn, none); let fcx = new_fn_ctxt(ccx, [], llfn, none);
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
cx.ccx.stats.n_glues_created += 1u; ccx.stats.n_glues_created += 1u;
// Any nontrivial glue is with values passed *by alias*; this is a // Any nontrivial glue is with values passed *by alias*; this is a
// requirement since in many contexts glue is invoked indirectly and // requirement since in many contexts glue is invoked indirectly and
// the caller has no idea if it's dealing with something that can be // the caller has no idea if it's dealing with something that can be
// passed by value. // passed by value.
let ccx = cx.ccx; let llty = if check type_has_static_size(ccx, t) {
let llty =
if check type_has_static_size(ccx, t) {
T_ptr(type_of(ccx, t)) T_ptr(type_of(ccx, t))
} else { T_ptr(T_i8()) }; } else { T_ptr(T_i8()) };
let ty_param_count = vec::len::<uint>(ty_params); let ty_param_count = vec::len(ty_params);
let lltyparams = llvm::LLVMGetParam(llfn, 2u as c_uint); let lltyparams = llvm::LLVMGetParam(llfn, 2u as c_uint);
let load_env_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv); let load_env_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
let lltydescs = [mutable]; let lltydescs = [mutable];
@ -1109,17 +1105,17 @@ fn make_generic_glue_inner(cx: @local_ctxt, t: ty::t,
ret llfn; ret llfn;
} }
fn make_generic_glue(cx: @local_ctxt, t: ty::t, llfn: ValueRef, fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
helper: glue_helper, ty_params: [uint], name: str) -> helper: glue_helper, ty_params: [uint], name: str)
ValueRef { -> ValueRef {
if !cx.ccx.sess.opts.stats { if !ccx.sess.opts.stats {
ret make_generic_glue_inner(cx, t, llfn, helper, ty_params); ret make_generic_glue_inner(ccx, t, llfn, helper, ty_params);
} }
let start = time::get_time(); let start = time::get_time();
let llval = make_generic_glue_inner(cx, t, llfn, helper, ty_params); let llval = make_generic_glue_inner(ccx, t, llfn, helper, ty_params);
let end = time::get_time(); let end = time::get_time();
log_fn_time(cx.ccx, "glue " + name + " " + ty_to_short_str(cx.ccx.tcx, t), log_fn_time(ccx, "glue " + name + " " + ty_to_short_str(ccx.tcx, t),
start, end); start, end);
ret llval; ret llval;
} }
@ -1646,6 +1642,7 @@ fn lazily_emit_all_generic_info_tydesc_glues(cx: @block_ctxt,
fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int, fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
static_ti: option<@tydesc_info>) { static_ti: option<@tydesc_info>) {
let ccx = cx.fcx.ccx;
alt static_ti { alt static_ti {
none { } none { }
some(ti) { some(ti) {
@ -1655,12 +1652,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none { none {
#debug("+++ lazily_emit_tydesc_glue TAKE %s", #debug("+++ lazily_emit_tydesc_glue TAKE %s",
ty_to_str(bcx_tcx(cx), ti.ty)); ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx; let glue_fn = declare_generic_glue
let glue_fn = (ccx, ti.ty, T_glue_fn(ccx), "take");
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx), ti.take_glue = some(glue_fn);
"take"); make_generic_glue(ccx, ti.ty, glue_fn,
ti.take_glue = some::<ValueRef>(glue_fn);
make_generic_glue(lcx, ti.ty, glue_fn,
make_take_glue, make_take_glue,
ti.ty_params, "take"); ti.ty_params, "take");
#debug("--- lazily_emit_tydesc_glue TAKE %s", #debug("--- lazily_emit_tydesc_glue TAKE %s",
@ -1673,12 +1668,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none { none {
#debug("+++ lazily_emit_tydesc_glue DROP %s", #debug("+++ lazily_emit_tydesc_glue DROP %s",
ty_to_str(bcx_tcx(cx), ti.ty)); ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx;
let glue_fn = let glue_fn =
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx), declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
"drop"); ti.drop_glue = some(glue_fn);
ti.drop_glue = some::<ValueRef>(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn,
make_generic_glue(lcx, ti.ty, glue_fn,
make_drop_glue, make_drop_glue,
ti.ty_params, "drop"); ti.ty_params, "drop");
#debug("--- lazily_emit_tydesc_glue DROP %s", #debug("--- lazily_emit_tydesc_glue DROP %s",
@ -1691,12 +1684,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none { none {
#debug("+++ lazily_emit_tydesc_glue FREE %s", #debug("+++ lazily_emit_tydesc_glue FREE %s",
ty_to_str(bcx_tcx(cx), ti.ty)); ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx;
let glue_fn = let glue_fn =
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx), declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
"free"); ti.free_glue = some(glue_fn);
ti.free_glue = some::<ValueRef>(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn,
make_generic_glue(lcx, ti.ty, glue_fn,
make_free_glue, make_free_glue,
ti.ty_params, "free"); ti.ty_params, "free");
#debug("--- lazily_emit_tydesc_glue FREE %s", #debug("--- lazily_emit_tydesc_glue FREE %s",
@ -2541,10 +2532,10 @@ fn lval_no_env(bcx: @block_ctxt, val: ValueRef, kind: lval_kind)
fn trans_external_path(cx: @block_ctxt, did: ast::def_id, fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
tpt: ty::ty_param_bounds_and_ty) -> ValueRef { tpt: ty::ty_param_bounds_and_ty) -> ValueRef {
let lcx = cx.fcx.lcx; let ccx = cx.fcx.ccx;
let name = csearch::get_symbol(lcx.ccx.sess.cstore, did); let name = csearch::get_symbol(ccx.sess.cstore, did);
ret get_extern_const(lcx.ccx.externs, lcx.ccx.llmod, name, ret get_extern_const(ccx.externs, ccx.llmod, name,
type_of_ty_param_bounds_and_ty(lcx, tpt)); type_of_ty_param_bounds_and_ty(ccx, tpt));
} }
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id) fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
@ -2580,19 +2571,18 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen}; ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen};
} }
fn lookup_discriminant(lcx: @local_ctxt, vid: ast::def_id) -> ValueRef { fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
let ccx = lcx.ccx;
alt ccx.discrims.find(vid) { alt ccx.discrims.find(vid) {
none { none {
// It's an external discriminant that we haven't seen yet. // It's an external discriminant that we haven't seen yet.
assert (vid.crate != ast::local_crate); assert (vid.crate != ast::local_crate);
let sym = csearch::get_symbol(lcx.ccx.sess.cstore, vid); let sym = csearch::get_symbol(ccx.sess.cstore, vid);
let gvar = str::as_buf(sym, {|buf| let gvar = str::as_buf(sym, {|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
}); });
lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage); lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
llvm::LLVMSetGlobalConstant(gvar, True); llvm::LLVMSetGlobalConstant(gvar, True);
lcx.ccx.discrims.insert(vid, gvar); ccx.discrims.insert(vid, gvar);
ret gvar; ret gvar;
} }
some(llval) { ret llval; } some(llval) { ret llval; }
@ -2657,7 +2647,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
let bcx = alloc_result.bcx; let bcx = alloc_result.bcx;
let llenumptr = PointerCast(bcx, llenumblob, T_ptr(llenumty)); let llenumptr = PointerCast(bcx, llenumblob, T_ptr(llenumty));
let lldiscrimptr = GEPi(bcx, llenumptr, [0, 0]); let lldiscrimptr = GEPi(bcx, llenumptr, [0, 0]);
let lldiscrim_gv = lookup_discriminant(bcx.fcx.lcx, vid); let lldiscrim_gv = lookup_discriminant(bcx.fcx.ccx, vid);
let lldiscrim = Load(bcx, lldiscrim_gv); let lldiscrim = Load(bcx, lldiscrim_gv);
Store(bcx, lldiscrim, lldiscrimptr); Store(bcx, lldiscrim, lldiscrimptr);
ret lval_no_env(bcx, llenumptr, temporary); ret lval_no_env(bcx, llenumptr, temporary);
@ -3339,7 +3329,7 @@ fn trans_landing_pad(bcx: @block_ctxt,
fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id, fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
dest: dest) -> @block_ctxt { dest: dest) -> @block_ctxt {
let t = node_id_type(bcx.fcx.lcx.ccx, id); let t = node_id_type(bcx.fcx.ccx, id);
let bcx = bcx; let bcx = bcx;
let addr = alt dest { let addr = alt dest {
ignore { ignore {
@ -3728,27 +3718,28 @@ fn load_if_immediate(cx: @block_ctxt, v: ValueRef, t: ty::t) -> ValueRef {
} }
fn trans_log(lvl: @ast::expr, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt { fn trans_log(lvl: @ast::expr, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt {
let ccx = bcx_ccx(cx); let ccx = bcx_ccx(cx), tcx = ccx.tcx;
let lcx = cx.fcx.lcx;
let tcx = ccx.tcx;
let modname = str::connect(lcx.module_path, "::");
if ty::type_is_bot(tcx, ty::expr_ty(tcx, lvl)) { if ty::type_is_bot(tcx, ty::expr_ty(tcx, lvl)) {
ret trans_expr(cx, lvl, ignore); ret trans_expr(cx, lvl, ignore);
} }
let global = if lcx.ccx.module_data.contains_key(modname) { let modpath = vec::filter(cx.fcx.path, {|e|
lcx.ccx.module_data.get(modname) alt e { path_mod(_) { true } _ { false } }
});
let modname = path_str(modpath);
let global = if ccx.module_data.contains_key(modname) {
ccx.module_data.get(modname)
} else { } else {
let s = link::mangle_internal_name_by_path_and_seq( let s = link::mangle_internal_name_by_path_and_seq(
lcx.ccx, lcx.module_path, "loglevel"); ccx, modpath, "loglevel");
let global = str::as_buf(s, {|buf| let global = str::as_buf(s, {|buf|
llvm::LLVMAddGlobal(lcx.ccx.llmod, T_i32(), buf) llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
}); });
llvm::LLVMSetGlobalConstant(global, False); llvm::LLVMSetGlobalConstant(global, False);
llvm::LLVMSetInitializer(global, C_null(T_i32())); llvm::LLVMSetInitializer(global, C_null(T_i32()));
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
lcx.ccx.module_data.insert(modname, global); ccx.module_data.insert(modname, global);
global global
}; };
let level_cx = new_scope_block_ctxt(cx, "level"); let level_cx = new_scope_block_ctxt(cx, "level");
@ -4033,7 +4024,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt {
} }
} }
} }
ast::decl_item(i) { trans_item(cx.fcx.lcx, *i); } ast::decl_item(i) { trans_item(cx.fcx.ccx, *i); }
} }
} }
_ { bcx_ccx(cx).sess.unimpl("stmt variant"); } _ { bcx_ccx(cx).sess.unimpl("stmt variant"); }
@ -4047,9 +4038,8 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt {
fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
name: str, block_span: option<span>) -> @block_ctxt { name: str, block_span: option<span>) -> @block_ctxt {
let s = ""; let s = "";
if cx.lcx.ccx.sess.opts.save_temps || if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
cx.lcx.ccx.sess.opts.debuginfo { s = cx.ccx.names(name);
s = cx.lcx.ccx.names(name);
} }
let llbb: BasicBlockRef = let llbb: BasicBlockRef =
str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) }); str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) });
@ -4278,14 +4268,6 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest)
ret rv; ret rv;
} }
fn new_local_ctxt(ccx: @crate_ctxt) -> @local_ctxt {
let pth: [str] = [];
ret @{path: pth,
module_path: [ccx.link_meta.name],
ccx: ccx};
}
// Creates the standard quartet of basic blocks: static allocas, copy args, // Creates the standard quartet of basic blocks: static allocas, copy args,
// derived tydescs, and dynamic allocas. // derived tydescs, and dynamic allocas.
fn mk_standard_basic_blocks(llfn: ValueRef) -> fn mk_standard_basic_blocks(llfn: ValueRef) ->
@ -4318,8 +4300,8 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
// - create_llargs_for_fn_args. // - create_llargs_for_fn_args.
// - new_fn_ctxt // - new_fn_ctxt
// - trans_args // - trans_args
fn new_fn_ctxt_w_id(cx: @local_ctxt, llfndecl: ValueRef, fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path,
id: ast::node_id, rstyle: ast::ret_style, llfndecl: ValueRef, id: ast::node_id,
sp: option<span>) -> @fn_ctxt { sp: option<span>) -> @fn_ctxt {
let llbbs = mk_standard_basic_blocks(llfndecl); let llbbs = mk_standard_basic_blocks(llfndecl);
ret @{llfn: llfndecl, ret @{llfn: llfndecl,
@ -4339,14 +4321,14 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, llfndecl: ValueRef,
mutable lltyparams: [], mutable lltyparams: [],
derived_tydescs: ty::new_ty_hash(), derived_tydescs: ty::new_ty_hash(),
id: id, id: id,
ret_style: rstyle,
span: sp, span: sp,
lcx: cx}; path: path,
ccx: ccx};
} }
fn new_fn_ctxt(cx: @local_ctxt, llfndecl: ValueRef, sp: option<span>) fn new_fn_ctxt(ccx: @crate_ctxt, path: path, llfndecl: ValueRef,
-> @fn_ctxt { sp: option<span>) -> @fn_ctxt {
ret new_fn_ctxt_w_id(cx, llfndecl, -1, ast::return_val, sp); ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, sp);
} }
// NB: must keep 4 fns in sync: // NB: must keep 4 fns in sync:
@ -4472,23 +4454,23 @@ enum self_arg { impl_self(ty::t), no_self, }
// trans_closure: Builds an LLVM function out of a source function. // trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be // If the function closes over its environment a closure will be
// returned. // returned.
fn trans_closure(cx: @local_ctxt, decl: ast::fn_decl, fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
body: ast::blk, llfndecl: ValueRef, body: ast::blk, llfndecl: ValueRef,
ty_self: self_arg, ty_params: [ast::ty_param], ty_self: self_arg, ty_params: [ast::ty_param],
id: ast::node_id, maybe_load_env: fn(@fn_ctxt)) { id: ast::node_id, maybe_load_env: fn(@fn_ctxt)) {
set_uwtable(llfndecl); set_uwtable(llfndecl);
// Set up arguments to the function. // Set up arguments to the function.
let fcx = new_fn_ctxt_w_id(cx, llfndecl, id, decl.cf, some(body.span)); let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, some(body.span));
create_llargs_for_fn_args(fcx, ty_self, decl.inputs, ty_params); create_llargs_for_fn_args(fcx, ty_self, decl.inputs, ty_params);
// Create the first basic block in the function and keep a handle on it to // Create the first basic block in the function and keep a handle on it to
// pass to finish_fn later. // pass to finish_fn later.
let bcx = new_top_block_ctxt(fcx, some(body.span)); let bcx = new_top_block_ctxt(fcx, some(body.span));
let lltop = bcx.llbb; let lltop = bcx.llbb;
let block_ty = node_id_type(cx.ccx, body.node.id); let block_ty = node_id_type(ccx, body.node.id);
let arg_tys = arg_tys_of_fn(fcx.lcx.ccx, id); let arg_tys = arg_tys_of_fn(fcx.ccx, id);
bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, arg_tys); bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, arg_tys);
maybe_load_env(fcx); maybe_load_env(fcx);
@ -4498,8 +4480,8 @@ fn trans_closure(cx: @local_ctxt, decl: ast::fn_decl,
// trans_mod, trans_item, et cetera) and those that do // trans_mod, trans_item, et cetera) and those that do
// (trans_block, trans_expr, et cetera). // (trans_block, trans_expr, et cetera).
if option::is_none(body.node.expr) || if option::is_none(body.node.expr) ||
ty::type_is_bot(cx.ccx.tcx, block_ty) || ty::type_is_bot(ccx.tcx, block_ty) ||
ty::type_is_nil(cx.ccx.tcx, block_ty) { ty::type_is_nil(ccx.tcx, block_ty) {
bcx = trans_block(bcx, body); bcx = trans_block(bcx, body);
} else { } else {
bcx = trans_block_dps(bcx, body, save_in(fcx.llretptr)); bcx = trans_block_dps(bcx, body, save_in(fcx.llretptr));
@ -4514,35 +4496,33 @@ fn trans_closure(cx: @local_ctxt, decl: ast::fn_decl,
// trans_fn: creates an LLVM function corresponding to a source language // trans_fn: creates an LLVM function corresponding to a source language
// function. // function.
fn trans_fn(cx: @local_ctxt, decl: ast::fn_decl, body: ast::blk, fn trans_fn(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
llfndecl: ValueRef, ty_self: self_arg, ty_params: [ast::ty_param], body: ast::blk, llfndecl: ValueRef, ty_self: self_arg,
id: ast::node_id) { ty_params: [ast::ty_param], id: ast::node_id) {
let do_time = cx.ccx.sess.opts.stats; let do_time = ccx.sess.opts.stats;
let start = if do_time { let start = if do_time {
time::get_time() time::get_time()
} else { } else {
{sec: 0u32, usec: 0u32} {sec: 0u32, usec: 0u32}
}; };
let fcx = option::none; let fcx = option::none;
trans_closure(cx, decl, body, llfndecl, ty_self, ty_params, id, trans_closure(ccx, path, decl, body, llfndecl, ty_self, ty_params, id,
{|new_fcx| fcx = option::some(new_fcx);}); {|new_fcx| fcx = option::some(new_fcx);});
if cx.ccx.sess.opts.extra_debuginfo { if ccx.sess.opts.extra_debuginfo {
debuginfo::create_function(option::get(fcx)); debuginfo::create_function(option::get(fcx));
} }
if do_time { if do_time {
let end = time::get_time(); let end = time::get_time();
log_fn_time(cx.ccx, str::connect(cx.path, "::"), start, end); log_fn_time(ccx, path_str(path), start, end);
} }
} }
fn trans_res_ctor(cx: @local_ctxt, dtor: ast::fn_decl, fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
ctor_id: ast::node_id, ty_params: [ast::ty_param]) { ctor_id: ast::node_id, ty_params: [ast::ty_param]) {
let ccx = cx.ccx;
// Create a function for the constructor // Create a function for the constructor
let llctor_decl = ccx.item_ids.get(ctor_id); let llctor_decl = ccx.item_ids.get(ctor_id);
let fcx = new_fn_ctxt(cx, llctor_decl, none); let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, none);
let ret_t = ty::ret_ty_of_fn(cx.ccx.tcx, ctor_id); let ret_t = ty::ret_ty_of_fn(ccx.tcx, ctor_id);
create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params); create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
let bcx = new_top_block_ctxt(fcx, none); let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb; let lltop = bcx.llbb;
@ -4574,22 +4554,18 @@ fn trans_res_ctor(cx: @local_ctxt, dtor: ast::fn_decl,
} }
fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id, fn trans_enum_variant(ccx: @crate_ctxt,
enum_id: ast::node_id,
variant: ast::variant, disr: int, is_degen: bool, variant: ast::variant, disr: int, is_degen: bool,
ty_params: [ast::ty_param]) { ty_params: [ast::ty_param]) {
let ccx = cx.ccx; if vec::len(variant.node.args) == 0u {
if vec::len::<ast::variant_arg>(variant.node.args) == 0u {
ret; // nullary constructors are just constants ret; // nullary constructors are just constants
} }
// Translate variant arguments to function arguments.
let fn_args: [ast::arg] = []; // Translate variant arguments to function arguments.
let i = 0u; let fn_args = [], i = 0u;
for varg: ast::variant_arg in variant.node.args { for varg in variant.node.args {
fn_args += fn_args += [{mode: ast::by_copy,
[{mode: ast::by_copy,
ty: varg.ty, ty: varg.ty,
ident: "arg" + uint::to_str(i, 10u), ident: "arg" + uint::to_str(i, 10u),
id: varg.id}]; id: varg.id}];
@ -4603,13 +4579,12 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
"unbound variant id in trans_enum_variant"); "unbound variant id in trans_enum_variant");
} }
} }
let fcx = new_fn_ctxt(cx, llfndecl, none); let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, none);
create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params); create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params);
let ty_param_substs: [ty::t] = []; let ty_param_substs = [], i = 0u;
i = 0u;
for tp: ast::ty_param in ty_params { for tp: ast::ty_param in ty_params {
ty_param_substs += [ty::mk_param(ccx.tcx, i, ty_param_substs += [ty::mk_param(ccx.tcx, i,
ast_util::local_def(tp.id))]; local_def(tp.id))];
i += 1u; i += 1u;
} }
let arg_tys = arg_tys_of_fn(ccx, variant.node.id); let arg_tys = arg_tys_of_fn(ccx, variant.node.id);
@ -4618,8 +4593,7 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys); bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys);
// Cast the enum to a type we can GEP into. // Cast the enum to a type we can GEP into.
let llblobptr = let llblobptr = if is_degen {
if is_degen {
fcx.llretptr fcx.llretptr
} else { } else {
let llenumptr = let llenumptr =
@ -4628,9 +4602,9 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
Store(bcx, C_int(ccx, disr), lldiscrimptr); Store(bcx, C_int(ccx, disr), lldiscrimptr);
GEPi(bcx, llenumptr, [0, 1]) GEPi(bcx, llenumptr, [0, 1])
}; };
i = 0u; let i = 0u;
let t_id = ast_util::local_def(enum_id); let t_id = local_def(enum_id);
let v_id = ast_util::local_def(variant.node.id); let v_id = local_def(variant.node.id);
for va: ast::variant_arg in variant.node.args { for va: ast::variant_arg in variant.node.args {
check (valid_variant_index(i, bcx, t_id, v_id)); check (valid_variant_index(i, bcx, t_id, v_id));
let rslt = GEP_enum(bcx, llblobptr, t_id, v_id, ty_param_substs, i); let rslt = GEP_enum(bcx, llblobptr, t_id, v_id, ty_param_substs, i);
@ -4813,14 +4787,13 @@ fn c_stack_tys(ccx: @crate_ctxt,
// stack pointer appropriately to avoid a round of copies. (In fact, the shim // stack pointer appropriately to avoid a round of copies. (In fact, the shim
// function itself is unnecessary). We used to do this, in fact, and will // function itself is unnecessary). We used to do this, in fact, and will
// perhaps do so in the future. // perhaps do so in the future.
fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod, fn trans_native_mod(ccx: @crate_ctxt,
abi: ast::native_abi) { native_mod: ast::native_mod, abi: ast::native_abi) {
fn build_shim_fn(lcx: @local_ctxt, fn build_shim_fn(ccx: @crate_ctxt,
native_item: @ast::native_item, native_item: @ast::native_item,
tys: @c_stack_tys, tys: @c_stack_tys,
cc: lib::llvm::CallConv) -> ValueRef { cc: lib::llvm::CallConv) -> ValueRef {
let lname = link_name(native_item); let lname = link_name(native_item);
let ccx = lcx_ccx(lcx);
// Declare the "prototype" for the base function F: // Declare the "prototype" for the base function F:
let llbasefn = decl_fn(ccx.llmod, lname, cc, tys.base_fn_ty); let llbasefn = decl_fn(ccx.llmod, lname, cc, tys.base_fn_ty);
@ -4831,7 +4804,7 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
ccx.llmod, shim_name, tys.shim_fn_ty); ccx.llmod, shim_name, tys.shim_fn_ty);
// Declare the body of the shim function: // Declare the body of the shim function:
let fcx = new_fn_ctxt(lcx, llshimfn, none); let fcx = new_fn_ctxt(ccx, [], llshimfn, none);
let bcx = new_top_block_ctxt(fcx, none); let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb; let lltop = bcx.llbb;
let llargbundle = llvm::LLVMGetParam(llshimfn, 0 as c_uint); let llargbundle = llvm::LLVMGetParam(llshimfn, 0 as c_uint);
@ -4862,13 +4835,12 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
ret llshimfn; ret llshimfn;
} }
fn build_wrap_fn(lcx: @local_ctxt, fn build_wrap_fn(ccx: @crate_ctxt,
tys: @c_stack_tys, tys: @c_stack_tys,
num_tps: uint, num_tps: uint,
llshimfn: ValueRef, llshimfn: ValueRef,
llwrapfn: ValueRef) { llwrapfn: ValueRef) {
let ccx = lcx_ccx(lcx); let fcx = new_fn_ctxt(ccx, [], llwrapfn, none);
let fcx = new_fn_ctxt(lcx, llwrapfn, none);
let bcx = new_top_block_ctxt(fcx, none); let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb; let lltop = bcx.llbb;
@ -4894,7 +4866,6 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
finish_fn(fcx, lltop); finish_fn(fcx, lltop);
} }
let ccx = lcx_ccx(lcx);
let cc = lib::llvm::CCallConv; let cc = lib::llvm::CCallConv;
alt abi { alt abi {
ast::native_abi_rust_intrinsic { ret; } ast::native_abi_rust_intrinsic { ret; }
@ -4909,10 +4880,9 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
let tys = c_stack_tys(ccx, id); let tys = c_stack_tys(ccx, id);
alt ccx.item_ids.find(id) { alt ccx.item_ids.find(id) {
some(llwrapfn) { some(llwrapfn) {
let llshimfn = build_shim_fn(lcx, native_item, tys, cc); let llshimfn = build_shim_fn(ccx, native_item, tys, cc);
build_wrap_fn(lcx, tys, vec::len(tps), llshimfn, llwrapfn); build_wrap_fn(ccx, tys, vec::len(tps), llshimfn, llwrapfn);
} }
none { none {
ccx.sess.span_fatal( ccx.sess.span_fatal(
native_item.span, native_item.span,
@ -4924,63 +4894,61 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
} }
} }
fn trans_item(cx: @local_ctxt, item: ast::item) { fn trans_item(ccx: @crate_ctxt, item: ast::item) {
let path = alt ccx.tcx.items.get(item.id) {
ast_map::node_item(_, p) { p }
_ { fail; }
};
alt item.node { alt item.node {
ast::item_fn(decl, tps, body) { ast::item_fn(decl, tps, body) {
let sub_cx = extend_path(cx, item.ident); alt ccx.item_ids.find(item.id) {
alt cx.ccx.item_ids.find(item.id) {
some(llfndecl) { some(llfndecl) {
trans_fn(sub_cx, decl, body, llfndecl, no_self, tps, trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
item.id); llfndecl, no_self, tps, item.id);
} }
_ { _ {
cx.ccx.sess.span_fatal(item.span, ccx.sess.span_fatal(item.span,
"unbound function item in trans_item"); "unbound function item in trans_item");
} }
} }
} }
ast::item_impl(tps, _, _, ms) { ast::item_impl(tps, _, _, ms) {
impl::trans_impl(cx, item.ident, ms, item.id, tps); impl::trans_impl(ccx, *path, item.ident, ms, item.id, tps);
} }
ast::item_res(decl, tps, body, dtor_id, ctor_id) { ast::item_res(decl, tps, body, dtor_id, ctor_id) {
trans_res_ctor(cx, decl, ctor_id, tps); trans_res_ctor(ccx, *path, decl, ctor_id, tps);
// Create a function for the destructor // Create a function for the destructor
alt cx.ccx.item_ids.find(item.id) { alt ccx.item_ids.find(item.id) {
some(lldtor_decl) { some(lldtor_decl) {
trans_fn(cx, decl, body, lldtor_decl, no_self, trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
tps, dtor_id); lldtor_decl, no_self, tps, dtor_id);
} }
_ { _ {
cx.ccx.sess.span_fatal(item.span, "unbound dtor in trans_item"); ccx.sess.span_fatal(item.span, "unbound dtor in trans_item");
} }
} }
} }
ast::item_mod(m) { ast::item_mod(m) {
let sub_cx = trans_mod(ccx, m);
@{path: cx.path + [item.ident],
module_path: cx.module_path + [item.ident] with *cx};
trans_mod(sub_cx, m);
} }
ast::item_enum(variants, tps) { ast::item_enum(variants, tps) {
let sub_cx = extend_path(cx, item.ident);
let degen = vec::len(variants) == 1u; let degen = vec::len(variants) == 1u;
let vi = ty::enum_variants(cx.ccx.tcx, {crate: ast::local_crate, let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
node: item.id});
let i = 0; let i = 0;
for variant: ast::variant in variants { for variant: ast::variant in variants {
trans_enum_variant(sub_cx, item.id, variant, trans_enum_variant(ccx, item.id, variant,
vi[i].disr_val, degen, tps); vi[i].disr_val, degen, tps);
i += 1; i += 1;
} }
} }
ast::item_const(_, expr) { trans_const(cx.ccx, expr, item.id); } ast::item_const(_, expr) { trans_const(ccx, expr, item.id); }
ast::item_native_mod(native_mod) { ast::item_native_mod(native_mod) {
let abi = alt attr::native_abi(item.attrs) { let abi = alt attr::native_abi(item.attrs) {
either::right(abi_) { abi_ } either::right(abi_) { abi_ }
either::left(msg) { cx.ccx.sess.span_fatal(item.span, msg) } either::left(msg) { ccx.sess.span_fatal(item.span, msg) }
}; };
trans_native_mod(cx, native_mod, abi); trans_native_mod(ccx, native_mod, abi);
} }
_ {/* fall through */ } _ {/* fall through */ }
} }
@ -4991,8 +4959,8 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
// separate modules in the compiled program. That's because modules exist // separate modules in the compiled program. That's because modules exist
// only as a convenience for humans working with the code, to organize names // only as a convenience for humans working with the code, to organize names
// and control visibility. // and control visibility.
fn trans_mod(cx: @local_ctxt, m: ast::_mod) { fn trans_mod(ccx: @crate_ctxt, m: ast::_mod) {
for item: @ast::item in m.items { trans_item(cx, *item); } for item in m.items { trans_item(ccx, *item); }
} }
fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef { fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
@ -5001,7 +4969,7 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
ret struct_elt(llpairty, 0u); ret struct_elt(llpairty, 0u);
} }
fn register_fn(ccx: @crate_ctxt, sp: span, path: [str], flav: str, fn register_fn(ccx: @crate_ctxt, sp: span, path: path, flav: str,
ty_params: [ast::ty_param], node_id: ast::node_id) { ty_params: [ast::ty_param], node_id: ast::node_id) {
// FIXME: pull this out // FIXME: pull this out
let t = node_id_type(ccx, node_id); let t = node_id_type(ccx, node_id);
@ -5013,11 +4981,10 @@ fn param_bounds(ccx: @crate_ctxt, tp: ast::ty_param) -> ty::param_bounds {
ccx.tcx.ty_param_bounds.get(tp.id) ccx.tcx.ty_param_bounds.get(tp.id)
} }
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str, fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path, _flav: str,
tps: [ast::ty_param], node_id: ast::node_id, tps: [ast::ty_param], node_id: ast::node_id,
node_type: ty::t) node_type: ty::t)
: returns_non_ty_var(ccx, node_type) { : returns_non_ty_var(ccx, node_type) {
let path = path;
let llfty = type_of_fn_from_ty(ccx, node_type, let llfty = type_of_fn_from_ty(ccx, node_type,
vec::map(tps, {|p| param_bounds(ccx, p)})); vec::map(tps, {|p| param_bounds(ccx, p)}));
let ps: str = mangle_exported_name(ccx, path, node_type); let ps: str = mangle_exported_name(ccx, path, node_type);
@ -5025,7 +4992,7 @@ fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
ccx.item_ids.insert(node_id, llfn); ccx.item_ids.insert(node_id, llfn);
ccx.item_symbols.insert(node_id, ps); ccx.item_symbols.insert(node_id, ps);
let is_main: bool = is_main_name(path) && !ccx.sess.building_library; let is_main = is_main_name(path) && !ccx.sess.building_library;
if is_main { create_main_wrapper(ccx, sp, llfn, node_type); } if is_main { create_main_wrapper(ccx, sp, llfn, node_type); }
} }
@ -5061,7 +5028,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
let llfdecl = decl_fn(ccx.llmod, "_rust_main", let llfdecl = decl_fn(ccx.llmod, "_rust_main",
lib::llvm::CCallConv, llfty); lib::llvm::CCallConv, llfty);
let fcx = new_fn_ctxt(new_local_ctxt(ccx), llfdecl, none); let fcx = new_fn_ctxt(ccx, [], llfdecl, none);
let bcx = new_top_block_ctxt(fcx, none); let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb; let lltop = bcx.llbb;
@ -5115,9 +5082,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
// on the stack). // on the stack).
fn create_real_fn_pair(cx: @block_ctxt, llfnty: TypeRef, llfn: ValueRef, fn create_real_fn_pair(cx: @block_ctxt, llfnty: TypeRef, llfn: ValueRef,
llenvptr: ValueRef) -> ValueRef { llenvptr: ValueRef) -> ValueRef {
let lcx = cx.fcx.lcx; let pair = alloca(cx, T_fn_pair(bcx_ccx(cx), llfnty));
let pair = alloca(cx, T_fn_pair(lcx.ccx, llfnty));
fill_fn_pair(cx, pair, llfn, llenvptr); fill_fn_pair(cx, pair, llfn, llenvptr);
ret pair; ret pair;
} }
@ -5137,8 +5102,9 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
let count; let count;
let native_item = let native_item =
// invariant?! // invariant?!
alt cx.ast_map.find(id) { some(ast_map::node_native_item(i)) { i } alt cx.ast_map.find(id) {
_ { cx.sess.bug("native_fn_ty_param_count\ some(ast_map::node_native_item(i, _)) { i }
_ { cx.sess.bug("native_fn_ty_param_count \
given a non-native item"); } }; given a non-native item"); } };
alt native_item.node { alt native_item.node {
ast::native_item_fn(_, tps) { ast::native_item_fn(_, tps) {
@ -5177,9 +5143,7 @@ fn link_name(i: @ast::native_item) -> str {
fn collect_native_item(ccx: @crate_ctxt, fn collect_native_item(ccx: @crate_ctxt,
abi: @mutable option<ast::native_abi>, abi: @mutable option<ast::native_abi>,
i: @ast::native_item, i: @ast::native_item) {
&&pt: [str],
_v: vt<[str]>) {
alt i.node { alt i.node {
ast::native_item_fn(_, tps) { ast::native_item_fn(_, tps) {
let id = i.id; let id = i.id;
@ -5217,8 +5181,10 @@ fn collect_native_item(ccx: @crate_ctxt,
// For true external functions: create a rust wrapper // For true external functions: create a rust wrapper
// and link to that. The rust wrapper will handle // and link to that. The rust wrapper will handle
// switching to the C stack. // switching to the C stack.
let new_pt = pt + [i.ident]; let path = *alt ccx.tcx.items.get(i.id) {
register_fn(ccx, i.span, new_pt, "native fn", tps, i.id); ast_map::node_native_item(_, p) { p } _ { fail; }
} + [path_name(i.ident)];
register_fn(ccx, i.span, path, "native fn", tps, i.id);
} }
} }
} }
@ -5226,14 +5192,19 @@ fn collect_native_item(ccx: @crate_ctxt,
} }
} }
fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
*alt ccx.tcx.items.get(i.id) {
ast_map::node_item(_, p) { p } _ { fail; }
} + [path_name(i.ident)]
}
fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>, fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>,
i: @ast::item, &&pt: [str], v: vt<[str]>) { i: @ast::item) {
let new_pt = pt + [i.ident]; let my_path = item_path(ccx, i);
alt i.node { alt i.node {
ast::item_const(_, _) { ast::item_const(_, _) {
let typ = node_id_type(ccx, i.id); let typ = node_id_type(ccx, i.id);
let s = let s = mangle_exported_name(ccx, my_path,
mangle_exported_name(ccx, pt + [i.ident],
node_id_type(ccx, i.id)); node_id_type(ccx, i.id));
// FIXME: Could follow from a constraint on types of const // FIXME: Could follow from a constraint on types of const
// items // items
@ -5248,23 +5219,23 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>,
// Propagate the native ABI down to collect_native_item(), // Propagate the native ABI down to collect_native_item(),
alt attr::native_abi(i.attrs) { alt attr::native_abi(i.attrs) {
either::left(msg) { ccx.sess.span_fatal(i.span, msg); } either::left(msg) { ccx.sess.span_fatal(i.span, msg); }
either::right(abi_) { either::right(abi_) { *abi = option::some(abi_); }
*abi = option::some(abi_);
}
} }
} }
ast::item_fn(_, tps, _) { ast::item_fn(_, tps, _) {
register_fn(ccx, i.span, new_pt, "fn", tps, i.id); register_fn(ccx, i.span, my_path, "fn", tps,
i.id);
} }
ast::item_impl(tps, _, _, methods) { ast::item_impl(tps, _, _, methods) {
let name = i.ident + int::str(i.id); let path = my_path + [path_name(int::str(i.id))];
for m in methods { for m in methods {
register_fn(ccx, i.span, pt + [name, m.ident], register_fn(ccx, i.span,
path + [path_name(m.ident)],
"impl_method", tps + m.tps, m.id); "impl_method", tps + m.tps, m.id);
} }
} }
ast::item_res(_, tps, _, dtor_id, ctor_id) { ast::item_res(_, tps, _, dtor_id, ctor_id) {
register_fn(ccx, i.span, new_pt, "res_ctor", tps, ctor_id); register_fn(ccx, i.span, my_path, "res_ctor", tps, ctor_id);
// Note that the destructor is associated with the item's id, not // Note that the destructor is associated with the item's id, not
// the dtor_id. This is a bit counter-intuitive, but simplifies // the dtor_id. This is a bit counter-intuitive, but simplifies
// ty_res, which would have to carry around two def_ids otherwise // ty_res, which would have to carry around two def_ids otherwise
@ -5272,42 +5243,41 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>,
let t = node_id_type(ccx, dtor_id); let t = node_id_type(ccx, dtor_id);
// FIXME: how to get rid of this check? // FIXME: how to get rid of this check?
check returns_non_ty_var(ccx, t); check returns_non_ty_var(ccx, t);
register_fn_full(ccx, i.span, new_pt, "res_dtor", tps, i.id, t); register_fn_full(ccx, i.span, my_path + [path_name("dtor")],
"res_dtor", tps, i.id, t);
} }
ast::item_enum(variants, tps) { ast::item_enum(variants, tps) {
for variant in variants { for variant in variants {
if vec::len(variant.node.args) != 0u { if vec::len(variant.node.args) != 0u {
register_fn(ccx, i.span, new_pt + [variant.node.name], register_fn(ccx, i.span,
my_path + [path_name(variant.node.name)],
"enum", tps, variant.node.id); "enum", tps, variant.node.id);
} }
} }
} }
_ { } _ { }
} }
visit::visit_item(i, new_pt, v);
} }
fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) { fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) {
let abi = @mutable none::<ast::native_abi>; let abi = @mutable none::<ast::native_abi>;
visit::visit_crate(*crate, [], visit::mk_vt(@{ visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
visit_native_item: bind collect_native_item(ccx, abi, _, _, _), visit_native_item: bind collect_native_item(ccx, abi, _),
visit_item: bind collect_item(ccx, abi, _, _, _) visit_item: bind collect_item(ccx, abi, _)
with *visit::default_visitor() with *visit::default_simple_visitor()
})); }));
} }
// The constant translation pass. // The constant translation pass.
fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str], fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
v: vt<[str]>) {
let new_pt = pt + [it.ident];
visit::visit_item(it, new_pt, v);
alt it.node { alt it.node {
ast::item_enum(variants, _) { ast::item_enum(variants, _) {
let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate, let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate,
node: it.id}); node: it.id});
let i = 0; let i = 0, path = item_path(ccx, it);
for variant in variants { for variant in variants {
let p = new_pt + [variant.node.name, "discrim"]; let p = path + [path_name(variant.node.name),
path_name("discrim")];
let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx)); let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));
let disr_val = vi[i].disr_val; let disr_val = vi[i].disr_val;
let discrim_gvar = str::as_buf(s, {|buf| let discrim_gvar = str::as_buf(s, {|buf|
@ -5316,27 +5286,27 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val)); llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
llvm::LLVMSetGlobalConstant(discrim_gvar, True); llvm::LLVMSetGlobalConstant(discrim_gvar, True);
ccx.discrims.insert( ccx.discrims.insert(
ast_util::local_def(variant.node.id), discrim_gvar); local_def(variant.node.id), discrim_gvar);
ccx.discrim_symbols.insert(variant.node.id, s); ccx.discrim_symbols.insert(variant.node.id, s);
i += 1; i += 1;
} }
} }
ast::item_impl(tps, some(@{node: ast::ty_path(_, id), _}), _, ms) { ast::item_impl(tps, some(@{node: ast::ty_path(_, id), _}), _, ms) {
let i_did = ast_util::def_id_of_def(ccx.tcx.def_map.get(id)); let i_did = ast_util::def_id_of_def(ccx.tcx.def_map.get(id));
impl::trans_impl_vtable(ccx, pt, i_did, ms, tps, it); impl::trans_impl_vtable(ccx, item_path(ccx, it), i_did, ms, tps, it);
} }
ast::item_iface(_, _) { ast::item_iface(_, _) {
impl::trans_iface_vtable(ccx, pt, it); impl::trans_iface_vtable(ccx, item_path(ccx, it), it);
} }
_ { } _ { }
} }
} }
fn trans_constants(ccx: @crate_ctxt, crate: @ast::crate) { fn trans_constants(ccx: @crate_ctxt, crate: @ast::crate) {
let visitor = visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
@{visit_item: bind trans_constant(ccx, _, _, _) visit_item: bind trans_constant(ccx, _)
with *visit::default_visitor()}; with *visit::default_simple_visitor()
visit::visit_crate(*crate, [], visit::mk_vt(visitor)); }));
} }
fn vp2i(cx: @block_ctxt, v: ValueRef) -> ValueRef { fn vp2i(cx: @block_ctxt, v: ValueRef) -> ValueRef {
@ -5597,17 +5567,16 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
crate_map: crate_map, crate_map: crate_map,
dbg_cx: dbg_cx, dbg_cx: dbg_cx,
mutable do_not_commit_warning_issued: false}; mutable do_not_commit_warning_issued: false};
let cx = new_local_ctxt(ccx);
collect_items(ccx, crate); collect_items(ccx, crate);
trans_constants(ccx, crate); trans_constants(ccx, crate);
trans_mod(cx, crate.node.module); trans_mod(ccx, crate.node.module);
fill_crate_map(ccx, crate_map); fill_crate_map(ccx, crate_map);
emit_tydescs(ccx); emit_tydescs(ccx);
shape::gen_shape_tables(ccx); shape::gen_shape_tables(ccx);
write_abi_version(ccx); write_abi_version(ccx);
// Translate the metadata. // Translate the metadata.
write_metadata(cx.ccx, crate); write_metadata(ccx, crate);
if ccx.sess.opts.stats { if ccx.sess.opts.stats {
#error("--- trans stats ---"); #error("--- trans stats ---");
#error("n_static_tydescs: %u", ccx.stats.n_static_tydescs); #error("n_static_tydescs: %u", ccx.stats.n_static_tydescs);

View file

@ -11,7 +11,7 @@ import common::{block_ctxt, T_ptr, T_nil, T_i8, T_i1, T_void,
T_fn, val_ty, bcx_ccx, C_i32, val_str}; T_fn, val_ty, bcx_ccx, C_i32, val_str};
fn B(cx: @block_ctxt) -> BuilderRef { fn B(cx: @block_ctxt) -> BuilderRef {
let b = *cx.fcx.lcx.ccx.builder; let b = *cx.fcx.ccx.builder;
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb); llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
ret b; ret b;
} }
@ -312,7 +312,7 @@ fn Free(cx: @block_ctxt, PointerVal: ValueRef) {
} }
fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
let ccx = cx.fcx.lcx.ccx; let ccx = cx.fcx.ccx;
if cx.unreachable { if cx.unreachable {
let ty = val_ty(PointerVal); let ty = val_ty(PointerVal);
let eltty = if llvm::LLVMGetTypeKind(ty) == 11 as c_int { let eltty = if llvm::LLVMGetTypeKind(ty) == 11 as c_int {
@ -511,7 +511,7 @@ fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
} }
fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef { fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef {
let ccx = cx.fcx.lcx.ccx; let ccx = cx.fcx.ccx;
let ty = val_ty(Fn); let ty = val_ty(Fn);
let retty = if llvm::LLVMGetTypeKind(ty) == 8 as c_int { let retty = if llvm::LLVMGetTypeKind(ty) == 8 as c_int {
llvm::LLVMGetReturnType(ty) } else { ccx.int_type }; llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
@ -625,7 +625,7 @@ fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
} }
fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
let ccx = cx.fcx.lcx.ccx; let ccx = cx.fcx.ccx;
if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); } if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); }
ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
} }

View file

@ -16,6 +16,7 @@ import back::link::{
mangle_internal_name_by_path_and_seq}; mangle_internal_name_by_path_and_seq};
import util::ppaux::ty_to_str; import util::ppaux::ty_to_str;
import shape::{size_of}; import shape::{size_of};
import ast_map::{path, path_mod, path_name};
// ___Good to know (tm)__________________________________________________ // ___Good to know (tm)__________________________________________________
// //
@ -458,16 +459,16 @@ fn trans_expr_fn(bcx: @block_ctxt,
let ccx = bcx_ccx(bcx), bcx = bcx; let ccx = bcx_ccx(bcx), bcx = bcx;
let fty = node_id_type(ccx, id); let fty = node_id_type(ccx, id);
let llfnty = type_of_fn_from_ty(ccx, fty, []); let llfnty = type_of_fn_from_ty(ccx, fty, []);
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names("anon")); let sub_path = bcx.fcx.path + [path_name("anon")];
let s = mangle_internal_name_by_path(ccx, sub_cx.path); let s = mangle_internal_name_by_path(ccx, sub_path);
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
register_fn(ccx, sp, sub_cx.path, "anon fn", [], id); register_fn(ccx, sp, sub_path, "anon fn", [], id);
let trans_closure_env = fn@(ck: ty::closure_kind) -> ValueRef { let trans_closure_env = fn@(ck: ty::closure_kind) -> ValueRef {
let cap_vars = capture::compute_capture_vars( let cap_vars = capture::compute_capture_vars(
ccx.tcx, id, proto, cap_clause); ccx.tcx, id, proto, cap_clause);
let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck); let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck);
trans_closure(sub_cx, decl, body, llfn, no_self, [], id, {|fcx| trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], id, {|fcx|
load_environment(bcx, fcx, cdata_ty, cap_vars, ck); load_environment(bcx, fcx, cdata_ty, cap_vars, ck);
}); });
llbox llbox
@ -479,7 +480,8 @@ fn trans_expr_fn(bcx: @block_ctxt,
ast::proto_uniq { trans_closure_env(ty::ck_uniq) } ast::proto_uniq { trans_closure_env(ty::ck_uniq) }
ast::proto_bare { ast::proto_bare {
let closure = C_null(T_opaque_box_ptr(ccx)); let closure = C_null(T_opaque_box_ptr(ccx));
trans_closure(sub_cx, decl, body, llfn, no_self, [], id, {|_fcx|}); trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], id,
{|_fcx|});
closure closure
} }
}; };
@ -569,8 +571,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
ty::ck_box); ty::ck_box);
// Make thunk // Make thunk
let llthunk = let llthunk = trans_bind_thunk(
trans_bind_thunk(cx.fcx.lcx, pair_ty, outgoing_fty_real, args, cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty_real, args,
cdata_ty, *param_bounds, target_res); cdata_ty, *param_bounds, target_res);
// Fill the function pair // Fill the function pair
@ -727,7 +729,8 @@ fn make_opaque_cbox_free_glue(
} }
// pth is cx.path // pth is cx.path
fn trans_bind_thunk(cx: @local_ctxt, fn trans_bind_thunk(ccx: @crate_ctxt,
path: path,
incoming_fty: ty::t, incoming_fty: ty::t,
outgoing_fty: ty::t, outgoing_fty: ty::t,
args: [option<@ast::expr>], args: [option<@ast::expr>],
@ -743,8 +746,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
type_has_static_size(ccx, incoming_fty) -> type_has_static_size(ccx, incoming_fty) ->
*/ */
// but since we don't, we have to do the checks at the beginning. // but since we don't, we have to do the checks at the beginning.
let ccx = cx.ccx; let tcx = ccx.tcx;
let tcx = ccx_tcx(ccx);
check type_has_static_size(ccx, incoming_fty); check type_has_static_size(ccx, incoming_fty);
#debug["trans_bind_thunk[incoming_fty=%s,outgoing_fty=%s,\ #debug["trans_bind_thunk[incoming_fty=%s,outgoing_fty=%s,\
@ -776,13 +778,13 @@ fn trans_bind_thunk(cx: @local_ctxt,
// construct and return that thunk. // construct and return that thunk.
// Give the thunk a name, type, and value. // Give the thunk a name, type, and value.
let s: str = mangle_internal_name_by_path_and_seq(ccx, cx.path, "thunk"); let s = mangle_internal_name_by_path_and_seq(ccx, path, "thunk");
let llthunk_ty: TypeRef = get_pair_fn_ty(type_of(ccx, incoming_fty)); let llthunk_ty = get_pair_fn_ty(type_of(ccx, incoming_fty));
let llthunk: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty); let llthunk = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty);
// Create a new function context and block context for the thunk, and hold // Create a new function context and block context for the thunk, and hold
// onto a pointer to the first block in the function for later use. // onto a pointer to the first block in the function for later use.
let fcx = new_fn_ctxt(cx, llthunk, none); let fcx = new_fn_ctxt(ccx, path, llthunk, none);
let bcx = new_top_block_ctxt(fcx, none); let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb; let lltop = bcx.llbb;
// Since we might need to construct derived tydescs that depend on // Since we might need to construct derived tydescs that depend on
@ -828,15 +830,14 @@ fn trans_bind_thunk(cx: @local_ctxt,
// Get f's return type, which will also be the return type of the entire // Get f's return type, which will also be the return type of the entire
// bind expression. // bind expression.
let outgoing_ret_ty = ty::ty_fn_ret(cx.ccx.tcx, outgoing_fty); let outgoing_ret_ty = ty::ty_fn_ret(ccx.tcx, outgoing_fty);
// Get the types of the arguments to f. // Get the types of the arguments to f.
let outgoing_args = ty::ty_fn_args(cx.ccx.tcx, outgoing_fty); let outgoing_args = ty::ty_fn_args(ccx.tcx, outgoing_fty);
// The 'llretptr' that will arrive in the thunk we're creating also needs // The 'llretptr' that will arrive in the thunk we're creating also needs
// to be the correct type. Cast it to f's return type, if necessary. // to be the correct type. Cast it to f's return type, if necessary.
let llretptr = fcx.llretptr; let llretptr = fcx.llretptr;
let ccx = cx.ccx;
if ty::type_contains_params(ccx.tcx, outgoing_ret_ty) { if ty::type_contains_params(ccx.tcx, outgoing_ret_ty) {
check non_ty_var(ccx, outgoing_ret_ty); check non_ty_var(ccx, outgoing_ret_ty);
let llretty = type_of_inner(ccx, outgoing_ret_ty); let llretty = type_of_inner(ccx, outgoing_ret_ty);
@ -879,7 +880,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
let b: int = starting_idx; let b: int = starting_idx;
let outgoing_arg_index: uint = 0u; let outgoing_arg_index: uint = 0u;
let llout_arg_tys: [TypeRef] = let llout_arg_tys: [TypeRef] =
type_of_explicit_args(cx.ccx, outgoing_args); type_of_explicit_args(ccx, outgoing_args);
for arg: option<@ast::expr> in args { for arg: option<@ast::expr> in args {
let out_arg = outgoing_args[outgoing_arg_index]; let out_arg = outgoing_args[outgoing_arg_index];
let llout_arg_ty = llout_arg_tys[outgoing_arg_index]; let llout_arg_ty = llout_arg_tys[outgoing_arg_index];
@ -903,7 +904,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
} }
// If the type is parameterized, then we need to cast the // If the type is parameterized, then we need to cast the
// type we actually have to the parameterized out type. // type we actually have to the parameterized out type.
if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) { if ty::type_contains_params(ccx.tcx, out_arg.ty) {
val = PointerCast(bcx, val, llout_arg_ty); val = PointerCast(bcx, val, llout_arg_ty);
} }
llargs += [val]; llargs += [val];
@ -913,7 +914,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
// Arg will be provided when the thunk is invoked. // Arg will be provided when the thunk is invoked.
none { none {
let arg: ValueRef = llvm::LLVMGetParam(llthunk, a as c_uint); let arg: ValueRef = llvm::LLVMGetParam(llthunk, a as c_uint);
if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) { if ty::type_contains_params(ccx.tcx, out_arg.ty) {
arg = PointerCast(bcx, arg, llout_arg_ty); arg = PointerCast(bcx, arg, llout_arg_ty);
} }
llargs += [arg]; llargs += [arg];
@ -927,8 +928,6 @@ fn trans_bind_thunk(cx: @local_ctxt,
// This is necessary because the type of the function that we have // This is necessary because the type of the function that we have
// in the closure does not know how many type descriptors the function // in the closure does not know how many type descriptors the function
// needs to take. // needs to take.
let ccx = bcx_ccx(bcx);
let lltargetty = let lltargetty =
type_of_fn_from_ty(ccx, outgoing_fty, param_bounds); type_of_fn_from_ty(ccx, outgoing_fty, param_bounds);
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty)); lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));

View file

@ -19,7 +19,8 @@ import lib::llvm::{llvm, target_data, type_names, associate_type,
name_has_type}; name_has_type};
import lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef}; import lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef};
import lib::llvm::{True, False, Bool}; import lib::llvm::{True, False, Bool};
import metadata::{csearch}; import metadata::csearch;
import ast_map::path;
// FIXME: These should probably be pulled in here too. // FIXME: These should probably be pulled in here too.
import base::{type_of_fn, drop_ty}; import base::{type_of_fn, drop_ty};
@ -124,11 +125,6 @@ type crate_ctxt =
dbg_cx: option<@debuginfo::debug_ctxt>, dbg_cx: option<@debuginfo::debug_ctxt>,
mutable do_not_commit_warning_issued: bool}; mutable do_not_commit_warning_issued: bool};
type local_ctxt =
{path: [str],
module_path: [str],
ccx: @crate_ctxt};
// Types used for llself. // Types used for llself.
type val_self_pair = {v: ValueRef, t: ty::t}; type val_self_pair = {v: ValueRef, t: ty::t};
@ -239,9 +235,9 @@ type fn_ctxt =
mutable lltyparams: [fn_ty_param], mutable lltyparams: [fn_ty_param],
derived_tydescs: hashmap<ty::t, derived_tydesc_info>, derived_tydescs: hashmap<ty::t, derived_tydesc_info>,
id: ast::node_id, id: ast::node_id,
ret_style: ast::ret_style,
span: option<span>, span: option<span>,
lcx: @local_ctxt}; path: path,
ccx: @crate_ctxt};
fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) { fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
if !ccx.do_not_commit_warning_issued { if !ccx.do_not_commit_warning_issued {
@ -392,10 +388,6 @@ enum block_parent { parent_none, parent_some(@block_ctxt), }
type result = {bcx: @block_ctxt, val: ValueRef}; type result = {bcx: @block_ctxt, val: ValueRef};
type result_t = {bcx: @block_ctxt, val: ValueRef, ty: ty::t}; type result_t = {bcx: @block_ctxt, val: ValueRef, ty: ty::t};
fn extend_path(cx: @local_ctxt, name: str) -> @local_ctxt {
ret @{path: cx.path + [name] with *cx};
}
fn rslt(bcx: @block_ctxt, val: ValueRef) -> result { fn rslt(bcx: @block_ctxt, val: ValueRef) -> result {
{bcx: bcx, val: val} {bcx: bcx, val: val}
} }
@ -430,13 +422,11 @@ fn find_scope_cx(cx: @block_ctxt) -> @block_ctxt {
// Accessors // Accessors
// TODO: When we have overloading, simplify these names! // TODO: When we have overloading, simplify these names!
pure fn bcx_tcx(bcx: @block_ctxt) -> ty::ctxt { ret bcx.fcx.lcx.ccx.tcx; } pure fn bcx_tcx(bcx: @block_ctxt) -> ty::ctxt { ret bcx.fcx.ccx.tcx; }
pure fn bcx_ccx(bcx: @block_ctxt) -> @crate_ctxt { ret bcx.fcx.lcx.ccx; } pure fn bcx_ccx(bcx: @block_ctxt) -> @crate_ctxt { ret bcx.fcx.ccx; }
pure fn bcx_lcx(bcx: @block_ctxt) -> @local_ctxt { ret bcx.fcx.lcx; }
pure fn bcx_fcx(bcx: @block_ctxt) -> @fn_ctxt { ret bcx.fcx; } pure fn bcx_fcx(bcx: @block_ctxt) -> @fn_ctxt { ret bcx.fcx; }
pure fn fcx_ccx(fcx: @fn_ctxt) -> @crate_ctxt { ret fcx.lcx.ccx; } pure fn fcx_ccx(fcx: @fn_ctxt) -> @crate_ctxt { ret fcx.ccx; }
pure fn fcx_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.lcx.ccx.tcx; } pure fn fcx_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.ccx.tcx; }
pure fn lcx_ccx(lcx: @local_ctxt) -> @crate_ctxt { ret lcx.ccx; }
pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; } pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; }
// LLVM type constructors. // LLVM type constructors.
@ -943,6 +933,18 @@ fn align_to(cx: @block_ctxt, off: ValueRef, align: ValueRef) -> ValueRef {
ret build::And(cx, bumped, build::Not(cx, mask)); ret build::And(cx, bumped, build::Not(cx, mask));
} }
fn path_str(p: path) -> str {
let r = "", first = true;
for e in p {
alt e { ast_map::path_name(s) | ast_map::path_mod(s) {
if first { first = false; }
else { r += "::"; }
r += s;
} }
}
r
}
// //
// Local Variables: // Local Variables:
// mode: rust // mode: rust

View file

@ -10,6 +10,7 @@ import back::{link, abi};
import lib::llvm::llvm; import lib::llvm::llvm;
import lib::llvm::{ValueRef, TypeRef}; import lib::llvm::{ValueRef, TypeRef};
import lib::llvm::llvm::LLVMGetParam; import lib::llvm::llvm::LLVMGetParam;
import ast_map::{path, path_mod, path_name};
// Translation functionality related to impls and ifaces // Translation functionality related to impls and ifaces
// //
@ -41,18 +42,19 @@ import lib::llvm::llvm::LLVMGetParam;
// annotates notes with information about the methods and dicts that // annotates notes with information about the methods and dicts that
// are referenced (ccx.method_map and ccx.dict_map). // are referenced (ccx.method_map and ccx.dict_map).
fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method], fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
id: ast::node_id, tps: [ast::ty_param]) { methods: [@ast::method], id: ast::node_id,
let sub_cx = extend_path(cx, name); tps: [ast::ty_param]) {
let sub_path = path + [path_name(name)];
for m in methods { for m in methods {
alt cx.ccx.item_ids.find(m.id) { alt ccx.item_ids.find(m.id) {
some(llfn) { some(llfn) {
trans_fn(extend_path(sub_cx, m.ident), m.decl, m.body, trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body,
llfn, impl_self(ty::node_id_to_type(cx.ccx.tcx, id)), llfn, impl_self(ty::node_id_to_type(ccx.tcx, id)),
tps + m.tps, m.id); tps + m.tps, m.id);
} }
_ { _ {
cx.ccx.tcx.sess.bug("Unbound id in trans_impl"); ccx.tcx.sess.bug("Unbound id in trans_impl");
} }
} }
} }
@ -180,13 +182,12 @@ fn trans_vtable(ccx: @crate_ctxt, id: ast::node_id, name: str,
ccx.item_symbols.insert(id, name); ccx.item_symbols.insert(id, name);
} }
fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident], llfty: TypeRef, fn trans_wrapper(ccx: @crate_ctxt, pt: path, llfty: TypeRef,
fill: fn(ValueRef, @block_ctxt) -> @block_ctxt) fill: fn(ValueRef, @block_ctxt) -> @block_ctxt)
-> ValueRef { -> ValueRef {
let lcx = @{path: pt, module_path: [], ccx: ccx};
let name = link::mangle_internal_name_by_path(ccx, pt); let name = link::mangle_internal_name_by_path(ccx, pt);
let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfty); let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfty);
let fcx = new_fn_ctxt(lcx, llfn, none); let fcx = new_fn_ctxt(ccx, [], llfn, none);
let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb; let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb;
let bcx = fill(llfn, bcx); let bcx = fill(llfn, bcx);
build_return(bcx); build_return(bcx);
@ -194,7 +195,7 @@ fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident], llfty: TypeRef,
ret llfn; ret llfn;
} }
fn trans_impl_wrapper(ccx: @crate_ctxt, pt: [ast::ident], fn trans_impl_wrapper(ccx: @crate_ctxt, pt: path,
extra_tps: [ty::param_bounds], real_fn: ValueRef) extra_tps: [ty::param_bounds], real_fn: ValueRef)
-> ValueRef { -> ValueRef {
let {inputs: real_args, output: real_ret} = let {inputs: real_args, output: real_ret} =
@ -238,16 +239,18 @@ fn trans_impl_wrapper(ccx: @crate_ctxt, pt: [ast::ident],
}) })
} }
fn trans_impl_vtable(ccx: @crate_ctxt, pt: [ast::ident], fn trans_impl_vtable(ccx: @crate_ctxt, pt: path,
iface_id: ast::def_id, ms: [@ast::method], iface_id: ast::def_id, ms: [@ast::method],
tps: [ast::ty_param], it: @ast::item) { tps: [ast::ty_param], it: @ast::item) {
let new_pt = pt + [it.ident + int::str(it.id), "wrap"]; let new_pt = pt + [path_name(it.ident), path_name(int::str(it.id)),
path_name("wrap")];
let extra_tps = vec::map(tps, {|p| param_bounds(ccx, p)}); let extra_tps = vec::map(tps, {|p| param_bounds(ccx, p)});
let ptrs = vec::map(*ty::iface_methods(ccx.tcx, iface_id), {|im| let ptrs = vec::map(*ty::iface_methods(ccx.tcx, iface_id), {|im|
alt vec::find(ms, {|m| m.ident == im.ident}) { alt vec::find(ms, {|m| m.ident == im.ident}) {
some(m) { some(m) {
let target = ccx.item_ids.get(m.id); let target = ccx.item_ids.get(m.id);
trans_impl_wrapper(ccx, new_pt + [m.ident], extra_tps, target) trans_impl_wrapper(ccx, new_pt + [path_name(m.ident)], extra_tps,
target)
} }
_ { _ {
ccx.tcx.sess.span_bug(it.span, "No matching method \ ccx.tcx.sess.span_bug(it.span, "No matching method \
@ -255,11 +258,12 @@ fn trans_impl_vtable(ccx: @crate_ctxt, pt: [ast::ident],
} }
} }
}); });
let s = link::mangle_internal_name_by_path(ccx, new_pt + ["!vtable"]); let s = link::mangle_internal_name_by_path(
ccx, new_pt + [path_name("!vtable")]);
trans_vtable(ccx, it.id, s, ptrs); trans_vtable(ccx, it.id, s, ptrs);
} }
fn trans_iface_wrapper(ccx: @crate_ctxt, pt: [ast::ident], m: ty::method, fn trans_iface_wrapper(ccx: @crate_ctxt, pt: path, m: ty::method,
n: uint) -> ValueRef { n: uint) -> ValueRef {
let {llty: llfty, _} = wrapper_fn_ty(ccx, T_ptr(T_i8()), m); let {llty: llfty, _} = wrapper_fn_ty(ccx, T_ptr(T_i8()), m);
trans_wrapper(ccx, pt, llfty, {|llfn, bcx| trans_wrapper(ccx, pt, llfty, {|llfn, bcx|
@ -287,15 +291,16 @@ fn trans_iface_wrapper(ccx: @crate_ctxt, pt: [ast::ident], m: ty::method,
}) })
} }
fn trans_iface_vtable(ccx: @crate_ctxt, pt: [ast::ident], it: @ast::item) { fn trans_iface_vtable(ccx: @crate_ctxt, pt: path, it: @ast::item) {
let new_pt = pt + [it.ident + int::str(it.id)]; let new_pt = pt + [path_name(it.ident), path_name(int::str(it.id))];
let i_did = ast_util::local_def(it.id), i = 0u; let i_did = ast_util::local_def(it.id), i = 0u;
let ptrs = vec::map(*ty::iface_methods(ccx.tcx, i_did), {|m| let ptrs = vec::map(*ty::iface_methods(ccx.tcx, i_did), {|m|
let w = trans_iface_wrapper(ccx, new_pt + [m.ident], m, i); let w = trans_iface_wrapper(ccx, new_pt + [path_name(m.ident)], m, i);
i += 1u; i += 1u;
w w
}); });
let s = link::mangle_internal_name_by_path(ccx, new_pt + ["!vtable"]); let s = link::mangle_internal_name_by_path(
ccx, new_pt + [path_name("!vtable")]);
trans_vtable(ccx, it.id, s, ptrs); trans_vtable(ccx, it.id, s, ptrs);
} }

View file

@ -2531,7 +2531,7 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
// check the disr_expr if it exists), this code should likely be // check the disr_expr if it exists), this code should likely be
// moved there to avoid having to call eval_const_expr twice. // moved there to avoid having to call eval_const_expr twice.
alt cx.items.get(id.node) { alt cx.items.get(id.node) {
ast_map::node_item(@{node: ast::item_enum(variants, _), _}) { ast_map::node_item(@{node: ast::item_enum(variants, _), _}, _) {
let disr_val = -1; let disr_val = -1;
@vec::map(variants, {|variant| @vec::map(variants, {|variant|
let ctor_ty = node_id_to_type(cx, variant.node.id); let ctor_ty = node_id_to_type(cx, variant.node.id);

View file

@ -245,10 +245,10 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
if id.crate != ast::local_crate { csearch::get_type(tcx, id) } if id.crate != ast::local_crate { csearch::get_type(tcx, id) }
else { else {
alt tcx.items.find(id.node) { alt tcx.items.find(id.node) {
some(ast_map::node_item(item)) { some(ast_map::node_item(item, _)) {
ty_of_item(tcx, mode, item) ty_of_item(tcx, mode, item)
} }
some(ast_map::node_native_item(native_item)) { some(ast_map::node_native_item(native_item, _)) {
ty_of_native_item(tcx, mode, native_item) ty_of_native_item(tcx, mode, native_item)
} }
_ { _ {
@ -1415,7 +1415,7 @@ fn impl_self_ty(tcx: ty::ctxt, did: ast::def_id) -> {n_tps: uint, ty: ty::t} {
if did.crate == ast::local_crate { if did.crate == ast::local_crate {
alt tcx.items.get(did.node) { alt tcx.items.get(did.node) {
ast_map::node_item(@{node: ast::item_impl(ts, _, st, _), ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
_}) { _}, _) {
{n_tps: vec::len(ts), ty: ast_ty_to_ty(tcx, m_check, st)} {n_tps: vec::len(ts), ty: ast_ty_to_ty(tcx, m_check, st)}
} }
an_item { an_item {
@ -1484,7 +1484,7 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
fn ty_from_did(tcx: ty::ctxt, did: ast::def_id) -> ty::t { fn ty_from_did(tcx: ty::ctxt, did: ast::def_id) -> ty::t {
if did.crate == ast::local_crate { if did.crate == ast::local_crate {
alt tcx.items.get(did.node) { alt tcx.items.get(did.node) {
ast_map::node_method(m) { ast_map::node_method(m, _) {
let mt = ty_of_method(tcx, m_check, m); let mt = ty_of_method(tcx, m_check, m);
ty::mk_fn(tcx, mt.fty) ty::mk_fn(tcx, mt.fty)
} }

View file

@ -89,12 +89,10 @@ fn local_rhs_span(l: @ast::local, def: span) -> span {
alt l.node.init { some(i) { ret i.expr.span; } _ { ret def; } } alt l.node.init { some(i) { ret i.expr.span; } _ { ret def; } }
} }
fn is_main_name(path: [ast::ident]) -> bool { fn is_main_name(path: middle::ast_map::path) -> bool {
str::eq(option::get(vec::last(path)), "main") option::get(vec::last(path)) == middle::ast_map::path_name("main")
} }
// //
// Local Variables: // Local Variables:
// mode: rust // mode: rust

View file

@ -67,7 +67,7 @@ fn parse_item_attrs<T>(
parse_attrs: fn~([ast::attribute]) -> T) -> T { parse_attrs: fn~([ast::attribute]) -> T) -> T {
astsrv::exec(srv) {|ctxt| astsrv::exec(srv) {|ctxt|
let attrs = alt ctxt.ast_map.get(id) { let attrs = alt ctxt.ast_map.get(id) {
ast_map::node_item(item) { item.attrs } ast_map::node_item(item, _) { item.attrs }
_ { _ {
fail "parse_item_attrs: not an item"; fail "parse_item_attrs: not an item";
} }
@ -246,7 +246,7 @@ fn fold_enum(
alt ctxt.ast_map.get(doc.id) { alt ctxt.ast_map.get(doc.id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_enum(ast_variants, _), _ node: ast::item_enum(ast_variants, _), _
}) { }, _) {
let ast_variant = option::get( let ast_variant = option::get(
vec::find(ast_variants) {|v| vec::find(ast_variants) {|v|
v.node.name == variant.name v.node.name == variant.name
@ -351,14 +351,14 @@ fn merge_method_attrs(
alt ctxt.ast_map.get(item_id) { alt ctxt.ast_map.get(item_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_iface(_, methods), _ node: ast::item_iface(_, methods), _
}) { }, _) {
vec::map(methods) {|method| vec::map(methods) {|method|
(method.ident, attr_parser::parse_method(method.attrs)) (method.ident, attr_parser::parse_method(method.attrs))
} }
} }
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, _, _, methods), _ node: ast::item_impl(_, _, _, methods), _
}) { }, _) {
vec::map(methods) {|method| vec::map(methods) {|method|
(method.ident, attr_parser::parse_method(method.attrs)) (method.ident, attr_parser::parse_method(method.attrs))
} }

View file

@ -106,7 +106,7 @@ fn is_exported_from_mod(
) -> bool { ) -> bool {
astsrv::exec(srv) {|ctxt| astsrv::exec(srv) {|ctxt|
alt ctxt.ast_map.get(mod_id) { alt ctxt.ast_map.get(mod_id) {
ast_map::node_item(item) { ast_map::node_item(item, _) {
alt item.node { alt item.node {
ast::item_mod(m) { ast::item_mod(m) {
ast_util::is_exported(item_name, m) ast_util::is_exported(item_name, m)

View file

@ -49,7 +49,7 @@ fn get_fn_sig(srv: astsrv::srv, fn_id: doc::ast_id) -> option<str> {
ast_map::node_item(@{ ast_map::node_item(@{
ident: ident, ident: ident,
node: ast::item_fn(decl, _, blk), _ node: ast::item_fn(decl, _, blk), _
}) { }, _) {
some(pprust::fun_to_str(decl, ident, [])) some(pprust::fun_to_str(decl, ident, []))
} }
_ { _ {
@ -86,7 +86,7 @@ fn get_ret_ty(srv: astsrv::srv, fn_id: doc::ast_id) -> option<str> {
alt ctxt.ast_map.get(fn_id) { alt ctxt.ast_map.get(fn_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_fn(decl, _, _), _ node: ast::item_fn(decl, _, _), _
}) { }, _) {
ret_ty_to_str(decl) ret_ty_to_str(decl)
} }
_ { fail "get_ret_ty: undocumented invariant"; } _ { fail "get_ret_ty: undocumented invariant"; }
@ -136,10 +136,10 @@ fn get_arg_tys(srv: astsrv::srv, fn_id: doc::ast_id) -> [(str, str)] {
alt ctxt.ast_map.get(fn_id) { alt ctxt.ast_map.get(fn_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_fn(decl, _, _), _ node: ast::item_fn(decl, _, _), _
}) | }, _) |
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_res(decl, _, _, _, _), _ node: ast::item_res(decl, _, _, _, _), _
}) { }, _) {
decl_arg_tys(decl) decl_arg_tys(decl)
} }
_ { _ {
@ -174,7 +174,7 @@ fn fold_const(
alt ctxt.ast_map.get(doc.id) { alt ctxt.ast_map.get(doc.id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_const(ty, _), _ node: ast::item_const(ty, _), _
}) { }, _) {
pprust::ty_to_str(ty) pprust::ty_to_str(ty)
} }
_ { _ {
@ -204,7 +204,7 @@ fn fold_enum(
alt ctxt.ast_map.get(doc.id) { alt ctxt.ast_map.get(doc.id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_enum(ast_variants, _), _ node: ast::item_enum(ast_variants, _), _
}) { }, _) {
let ast_variant = option::get( let ast_variant = option::get(
vec::find(ast_variants) {|v| vec::find(ast_variants) {|v|
v.node.name == variant.name v.node.name == variant.name
@ -243,7 +243,7 @@ fn fold_res(
alt ctxt.ast_map.get(doc.id) { alt ctxt.ast_map.get(doc.id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_res(decl, _, _, _, _), _ node: ast::item_res(decl, _, _, _, _), _
}) { }, _) {
pprust::res_to_str(decl, doc.name, []) pprust::res_to_str(decl, doc.name, [])
} }
_ { fail "fold_res: undocumented invariant"; } _ { fail "fold_res: undocumented invariant"; }
@ -324,7 +324,7 @@ fn get_method_ret_ty(
alt ctxt.ast_map.get(item_id) { alt ctxt.ast_map.get(item_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_iface(_, methods), _ node: ast::item_iface(_, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -336,7 +336,7 @@ fn get_method_ret_ty(
} }
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, _, _, methods), _ node: ast::item_impl(_, _, _, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -360,7 +360,7 @@ fn get_method_sig(
alt ctxt.ast_map.get(item_id) { alt ctxt.ast_map.get(item_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_iface(_, methods), _ node: ast::item_iface(_, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -372,7 +372,7 @@ fn get_method_sig(
} }
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, _, _, methods), _ node: ast::item_impl(_, _, _, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -412,7 +412,7 @@ fn get_method_arg_tys(
alt ctxt.ast_map.get(item_id) { alt ctxt.ast_map.get(item_id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_iface(_, methods), _ node: ast::item_iface(_, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -424,7 +424,7 @@ fn get_method_arg_tys(
} }
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, _, _, methods), _ node: ast::item_impl(_, _, _, methods), _
}) { }, _) {
alt vec::find(methods) {|method| alt vec::find(methods) {|method|
method.ident == method_name method.ident == method_name
} { } {
@ -476,7 +476,7 @@ fn fold_impl(
alt ctxt.ast_map.get(doc.id) { alt ctxt.ast_map.get(doc.id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, iface_ty, self_ty, _), _ node: ast::item_impl(_, iface_ty, self_ty, _), _
}) { }, _) {
let iface_ty = option::map(iface_ty) {|iface_ty| let iface_ty = option::map(iface_ty) {|iface_ty|
pprust::ty_to_str(iface_ty) pprust::ty_to_str(iface_ty)
}; };
@ -551,7 +551,7 @@ fn fold_type(
ast_map::node_item(@{ ast_map::node_item(@{
ident: ident, ident: ident,
node: ast::item_ty(ty, params), _ node: ast::item_ty(ty, params), _
}) { }, _) {
some(#fmt( some(#fmt(
"type %s%s = %s", "type %s%s = %s",
ident, ident,